Skip to content

Commit a4684a9

Browse files
authored
Update wallet.py
1 parent d96793a commit a4684a9

File tree

1 file changed

+147
-33
lines changed

1 file changed

+147
-33
lines changed

main/api/tools/wallet.py

Lines changed: 147 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
from config.config import DatabaseConfig
22
from lib.errors import ValidationError
3+
from tools.agent_templates import get_all_agents
34
import logging
45
from pydantic import BaseModel
56
from fastapi import HTTPException
67
from typing import Dict, Any, List
78
import hashlib
89
import re
910
import uuid
11+
from datetime import datetime
12+
import json
1013

1114
logger = logging.getLogger("mcp.wallet")
1215
logger.setLevel(logging.INFO)
@@ -75,6 +78,18 @@ class WalletQuantumLinkOutput(BaseModel):
7578
class WalletTool:
7679
def __init__(self, db: DatabaseConfig):
7780
self.db = db
81+
self.agents = {agent.get_metadata()["vial_id"]: agent.get_metadata() for agent in get_all_agents()}
82+
83+
async def initialize_new_wallet(self, user_id: str, wallet_address: str, api_key: str, api_secret: str):
84+
await self.db.query(
85+
"INSERT INTO users (user_id, balance, wallet_address, api_key, api_secret, reputation) VALUES ($1, $2, $3, $4, $5, $6)",
86+
[user_id, 0.0, wallet_address, api_key, api_secret, 0]
87+
)
88+
for agent in self.agents.values():
89+
await self.db.query(
90+
"INSERT INTO vials (user_id, vial_id, code, wallet_address, webxos_hash) VALUES ($1, $2, $3, $4, $5)",
91+
[user_id, agent["vial_id"], agent["code"], agent["wallet_address"], agent["webxos_hash"]]
92+
)
7893

7994
async def execute(self, input: Dict[str, Any]) -> Any:
8095
try:
@@ -114,9 +129,10 @@ async def get_vial_balance(self, input: WalletBalanceInput) -> WalletBalanceOutp
114129
user = await self.db.query("SELECT user_id, balance FROM users WHERE user_id = $1", [input.user_id])
115130
if not user.rows:
116131
raise ValidationError(f"User not found: {input.user_id}")
117-
balance = float(user.rows[0]["balance"])
118-
logger.info(f"Retrieved vial balance for {input.user_id}, vial {input.vial_id}: {balance}")
119-
return WalletBalanceOutput(vial_id=input.vial_id, balance=balance)
132+
total_balance = float(user.rows[0]["balance"])
133+
vial_balance = total_balance / 4 # Split evenly across 4 vials
134+
logger.info(f"Retrieved vial balance for {input.user_id}, vial {input.vial_id}: {vial_balance}")
135+
return WalletBalanceOutput(vial_id=input.vial_id, balance=vial_balance)
120136
except Exception as e:
121137
logger.error(f"Get vial balance error: {str(e)}")
122138
raise HTTPException(400, str(e))
@@ -132,9 +148,20 @@ async def import_wallet(self, input: WalletImportInput) -> WalletImportOutput:
132148
raise ValidationError(f"User not found: {input.user_id}")
133149

134150
balances = []
135-
for line in input.markdown.splitlines():
136-
if match := re.match(r".*balance\s*=\s*(\d+\.\d+)", line):
151+
vials = []
152+
for section in input.markdown.split("---"):
153+
if match := re.search(r"Wallet Balance: (\d+\.\d{4}) \$WEBXOS", section):
137154
balances.append(float(match.group(1)))
155+
if match := re.search(r"# Vial Agent: (vial\d+)", section):
156+
vials.append(match.group(1))
157+
if match := re.search(r"```python\n([\s\S]+?)\n```", section):
158+
code = match.group(1)
159+
vial_id = section.split("Vial Agent: ")[1].split("\n")[0]
160+
webxos_hash = hashlib.sha256(f"{vial_id}{uuid.uuid4()}".encode()).hexdigest()
161+
await self.db.query(
162+
"UPDATE vials SET code = $1, webxos_hash = $2 WHERE user_id = $3 AND vial_id = $4",
163+
[code, webxos_hash, input.user_id, vial_id]
164+
)
138165

139166
total_balance = sum(balances)
140167
current_balance = float(user.rows[0]["balance"])
@@ -147,7 +174,7 @@ async def import_wallet(self, input: WalletImportInput) -> WalletImportOutput:
147174

148175
logger.info(f"Imported wallet for {input.user_id}, new balance: {new_balance}")
149176
return WalletImportOutput(
150-
imported_vials=[f"vial{i+1}" for i in range(len(balances))],
177+
imported_vials=vials,
151178
total_balance=new_balance
152179
)
153180
except Exception as e:
@@ -162,6 +189,8 @@ async def batch_sync(self, input: WalletBatchSyncInput) -> WalletBatchSyncOutput
162189

163190
current_balance = float(user.rows[0]["balance"])
164191
results = []
192+
import_vials = []
193+
mining_ops = []
165194

166195
for op in input.operations:
167196
if op["method"] == "importWallet":
@@ -171,30 +200,52 @@ async def batch_sync(self, input: WalletBatchSyncInput) -> WalletBatchSyncOutput
171200
continue
172201

173202
balances = []
174-
for line in op["markdown"].splitlines():
175-
if match := re.match(r".*balance\s*=\s*(\d+\.\d+)", line):
203+
vials = []
204+
for section in op["markdown"].split("---"):
205+
if match := re.search(r"Wallet Balance: (\d+\.\d{4}) \$WEBXOS", section):
176206
balances.append(float(match.group(1)))
207+
if match := re.search(r"# Vial Agent: (vial\d+)", section):
208+
vials.append(match.group(1))
209+
if match := re.search(r"```python\n([\s\S]+?)\n```", section):
210+
code = match.group(1)
211+
vial_id = section.split("Vial Agent: ")[1].split("\n")[0]
212+
webxos_hash = hashlib.sha256(f"{vial_id}{uuid.uuid4()}".encode()).hexdigest()
213+
await self.db.query(
214+
"UPDATE vials SET code = $1, webxos_hash = $2 WHERE user_id = $3 AND vial_id = $4",
215+
[code, webxos_hash, input.user_id, vial_id]
216+
)
177217

178218
total_balance = sum(balances)
179-
current_balance += total_balance
180-
results.append({"imported_vials": [f"vial{i+1}" for i in range(len(balances))], "total_balance": current_balance})
219+
import_vials.append((total_balance, vials))
181220

182221
elif op["method"] == "mineVial":
183-
data = f"{input.user_id}{op['vial_id']}{op['nonce']}"
184-
hash_value = hashlib.sha256(data.encode()).hexdigest()
185-
difficulty = 2
186-
reward = 0.0
187-
188-
if hash_value.startswith("0" * difficulty):
189-
reward = 1.0
190-
current_balance += reward
191-
192-
results.append({"hash": hash_value, "reward": reward, "balance": current_balance})
222+
mining_ops.append((op["vial_id"], op["nonce"]))
193223

194-
await self.db.query(
195-
"UPDATE users SET balance = $1 WHERE user_id = $2",
196-
[current_balance, input.user_id]
197-
)
224+
if import_vials:
225+
total_import_balance = sum(v[0] for v in import_vials)
226+
current_balance += total_import_balance
227+
await self.db.query(
228+
"UPDATE users SET balance = $1 WHERE user_id = $2",
229+
[current_balance, input.user_id]
230+
)
231+
for total_balance, vials in import_vials:
232+
results.append({"imported_vials": vials, "total_balance": current_balance})
233+
234+
for vial_id, nonce in mining_ops:
235+
data = f"{input.user_id}{vial_id}{nonce}"
236+
hash_value = hashlib.sha256(data.encode()).hexdigest()
237+
difficulty = 2
238+
reward = 0.0
239+
240+
if hash_value.startswith("0" * difficulty):
241+
reward = 1.0
242+
current_balance += reward
243+
await self.db.query(
244+
"UPDATE users SET balance = $1 WHERE user_id = $2",
245+
[current_balance, input.user_id]
246+
)
247+
248+
results.append({"hash": hash_value, "reward": reward, "balance": current_balance})
198249

199250
logger.info(f"Batch synced operations for {input.user_id}, new balance: {current_balance}")
200251
return WalletBatchSyncOutput(results=results)
@@ -204,18 +255,81 @@ async def batch_sync(self, input: WalletBatchSyncInput) -> WalletBatchSyncOutput
204255

205256
async def export_vials(self, input: WalletBalanceInput) -> WalletExportOutput:
206257
try:
207-
user = await self.db.query("SELECT user_id, balance FROM users WHERE user_id = $1", [input.user_id])
258+
user = await self.db.query("SELECT user_id, balance, wallet_address, api_key, api_secret, reputation FROM users WHERE user_id = $1", [input.user_id])
208259
if not user.rows:
209260
raise ValidationError(f"User not found: {input.user_id}")
210261

211-
balance = float(user.rows[0]["balance"])
212-
markdown = f"""# Wallet Export for {input.user_id}
213-
## Vial Balances
214-
- {input.vial_id}: {balance}
262+
total_balance = float(user.rows[0]["balance"])
263+
wallet_address = user.rows[0]["wallet_address"]
264+
api_key = user.rows[0]["api_key"]
265+
api_secret = user.rows[0]["api_secret"]
266+
reputation = user.rows[0]["reputation"]
267+
network_id = str(uuid.uuid4())
268+
timestamp = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%fZ")[:-3]
269+
vial_balance = total_balance / 4 # Split evenly across 4 vials
270+
blocks = 1958 # Static for demo
271+
hash_value = hashlib.sha256(f"{input.user_id}{wallet_address}{timestamp}".encode()).hexdigest()
272+
273+
vials = await self.db.query("SELECT vial_id, code, wallet_address, webxos_hash FROM vials WHERE user_id = $1", [input.user_id])
274+
vial_data = {row["vial_id"]: row for row in vials.rows} if vials.rows else self.agents
275+
276+
markdown = f"""# WebXOS Vial and Wallet Export
277+
278+
## Agentic Network
279+
- Network ID: {network_id}
280+
- Session Start: {timestamp}
281+
- Session Duration: 0.00 seconds
282+
- Reputation: {reputation}
283+
284+
## Wallet
285+
- Wallet Key: {str(uuid.uuid4())}
286+
- Session Balance: {total_balance:.4f} $WEBXOS
287+
- Address: {wallet_address}
288+
- Hash: {hash_value}
289+
290+
## API Credentials
291+
- Key: {api_key}
292+
- Secret: {api_secret}
293+
294+
## Blockchain
295+
- Blocks: {blocks}
296+
- Last Hash: {hash_value}
297+
298+
## Vials
299+
"""
300+
for vial_id in ["vial1", "vial2", "vial3", "vial4"]:
301+
agent = vial_data.get(vial_id, self.agents[vial_id])
302+
markdown += f"""# Vial Agent: {vial_id}
303+
- Status: running
304+
- Language: Python
305+
- Code Length: {agent["code_length"]} bytes
306+
- $WEBXOS Hash: {agent["webxos_hash"]}
307+
- Wallet Balance: {vial_balance:.4f} $WEBXOS
308+
- Wallet Address: {agent["wallet_address"]}
309+
- Wallet Hash: {hash_value}
310+
- Tasks: none
311+
- Quantum State: {json.dumps(agent["quantum_state"], indent=6)}
312+
- Training Data: {json.dumps(agent["training_data"], indent=6)}
313+
- Config: {{}}
314+
315+
```python
316+
{agent["code"]}
317+
```
318+
319+
---
320+
"""
321+
markdown += """## Instructions
322+
- **Reuse**: Import this .md file via the "Import" button to resume training.
323+
- **Extend**: Modify agent code externally, then reimport.
324+
- **Share**: Send this .md file to others to continue training with the same wallet.
325+
- **API**: Use API credentials with LangChain to train vials (online mode only).
326+
- **Cash Out**: $WEBXOS balance and reputation are tied to the wallet address and hash for secure verification (online mode only).
327+
328+
Generated by Vial MCP Controller
215329
"""
216-
hash_value = hashlib.sha256(markdown.encode()).hexdigest()
330+
final_hash = hashlib.sha256(markdown.encode()).hexdigest()
217331
logger.info(f"Exported vials for {input.user_id}")
218-
return WalletExportOutput(markdown=markdown, hash=hash_value)
332+
return WalletExportOutput(markdown=markdown, hash=final_hash)
219333
except Exception as e:
220334
logger.error(f"Export vials error: {str(e)}")
221335
raise HTTPException(400, str(e))
@@ -295,8 +409,8 @@ async def quantum_link(self, input: WalletQuantumLinkInput) -> WalletQuantumLink
295409

296410
link_id = str(uuid.uuid4())
297411
await self.db.query(
298-
"INSERT INTO quantum_links (link_id, user_id) VALUES ($1, $2)",
299-
[link_id, input.user_id]
412+
"INSERT INTO quantum_links (link_id, user_id, quantum_state) VALUES ($1, $2, $3)",
413+
[link_id, input.user_id, json.dumps({"qubits": [], "entanglement": "synced"})]
300414
)
301415
logger.info(f"Established quantum link for {input.user_id}: {link_id}")
302416
return WalletQuantumLinkOutput(link_id=link_id)

0 commit comments

Comments
 (0)