(api?: OpenClawPluginApi)
| 1368 | } |
| 1369 | |
| 1370 | function createWalletCommand(api?: OpenClawPluginApi): OpenClawPluginCommandDefinition { |
| 1371 | return { |
| 1372 | name: "wallet", |
| 1373 | description: "Show BlockRun wallet info, balance, chain, or export key", |
| 1374 | acceptsArgs: true, |
| 1375 | requireAuth: true, |
| 1376 | handler: async (ctx: PluginCommandContext) => { |
| 1377 | const subcommand = ctx.args?.trim().toLowerCase() || "status"; |
| 1378 | |
| 1379 | // Read wallet key if it exists |
| 1380 | let walletKey: string | undefined; |
| 1381 | let address: string | undefined; |
| 1382 | try { |
| 1383 | if (existsSync(WALLET_FILE)) { |
| 1384 | walletKey = readTextFileSync(WALLET_FILE).trim(); |
| 1385 | if (walletKey.startsWith("0x") && walletKey.length === 66) { |
| 1386 | const account = privateKeyToAccount(walletKey as `0x${string}`); |
| 1387 | address = account.address; |
| 1388 | } |
| 1389 | } |
| 1390 | } catch { |
| 1391 | // Wallet file doesn't exist or is invalid |
| 1392 | } |
| 1393 | |
| 1394 | if (!walletKey || !address) { |
| 1395 | return { |
| 1396 | text: `No ClawRouter wallet found.\n\nRun \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`, |
| 1397 | isError: true, |
| 1398 | }; |
| 1399 | } |
| 1400 | |
| 1401 | if (subcommand === "export") { |
| 1402 | // Export private key + mnemonic for backup |
| 1403 | const lines = [ |
| 1404 | "**ClawRouter Wallet Export**", |
| 1405 | "", |
| 1406 | "**SECURITY WARNING**: Your private key and mnemonic control your wallet funds.", |
| 1407 | "Never share these. Anyone with them can spend your USDC.", |
| 1408 | "", |
| 1409 | "**EVM (Base):**", |
| 1410 | ` Address: \`${address}\``, |
| 1411 | ` Private Key: \`${walletKey}\``, |
| 1412 | ]; |
| 1413 | |
| 1414 | // Include mnemonic if it exists (Solana wallet derived from it) |
| 1415 | let hasMnemonic = false; |
| 1416 | try { |
| 1417 | if (existsSync(MNEMONIC_FILE)) { |
| 1418 | const mnemonic = readTextFileSync(MNEMONIC_FILE).trim(); |
| 1419 | if (mnemonic) { |
| 1420 | hasMnemonic = true; |
| 1421 | // Derive Solana address for display |
| 1422 | const { deriveSolanaKeyBytes } = await import("./wallet.js"); |
| 1423 | const solKeyBytes = deriveSolanaKeyBytes(mnemonic); |
| 1424 | const { createKeyPairSignerFromPrivateKeyBytes } = await import("@solana/kit"); |
| 1425 | const signer = await createKeyPairSignerFromPrivateKeyBytes(solKeyBytes); |
| 1426 | |
| 1427 | lines.push( |
no test coverage detected