MCPcopy Index your code
hub / github.com/BlockRunAI/ClawRouter / generateAndSaveWallet

Function generateAndSaveWallet

src/auth.ts:126–207  ·  view source on GitHub ↗

* Generate a new wallet with BIP-39 mnemonic, save to disk. * New users get both EVM and Solana keys derived from the same mnemonic. * CRITICAL: Verifies the file was actually written after generation.

()

Source from the content-addressed store, hash-verified

124 * CRITICAL: Verifies the file was actually written after generation.
125 */
126async function generateAndSaveWallet(): Promise<{
127 key: string;
128 address: string;
129 mnemonic: string;
130 solanaPrivateKeyBytes: Uint8Array;
131}> {
132 // Safety: if a mnemonic file already exists, a Solana wallet was derived from it.
133 // Generating a new wallet would overwrite the mnemonic and lose Solana funds.
134 const existingMnemonic = await loadMnemonic();
135 if (existingMnemonic) {
136 throw new Error(
137 `Mnemonic file exists at ${MNEMONIC_FILE} but wallet.key is missing.\n` +
138 `Refusing to generate a new wallet to protect existing funds.\n\n` +
139 `Restore your EVM private key using one of:\n` +
140 ` Windows: set BLOCKRUN_WALLET_KEY=0x<your_key>\n` +
141 ` Mac/Linux: export BLOCKRUN_WALLET_KEY=0x<your_key>\n\n` +
142 `Then run: npx @blockrun/clawrouter`,
143 );
144 }
145
146 const mnemonic = generateWalletMnemonic();
147 const derived = deriveAllKeys(mnemonic);
148
149 // Create directory
150 await mkdir(WALLET_DIR, { recursive: true });
151
152 // Write wallet key file (EVM private key)
153 await writeFile(WALLET_FILE, derived.evmPrivateKey + "\n", { mode: 0o600 });
154
155 // Write mnemonic file
156 await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 0o600 });
157
158 // CRITICAL: Verify the file was actually written
159 try {
160 const verification = (await readTextFile(WALLET_FILE)).trim();
161 if (verification !== derived.evmPrivateKey) {
162 throw new Error("Wallet file verification failed - content mismatch");
163 }
164 console.log(`[ClawRouter] Wallet saved and verified at ${WALLET_FILE}`);
165 } catch (err) {
166 throw new Error(
167 `Failed to verify wallet file after creation: ${err instanceof Error ? err.message : String(err)}`,
168 { cause: err },
169 );
170 }
171
172 // Derive Solana address for display
173 let solanaAddress: string | undefined;
174 try {
175 solanaAddress = await getSolanaAddress(derived.solanaPrivateKeyBytes);
176 } catch {
177 // Non-fatal — Solana address display is best-effort
178 }
179
180 // Print prominent backup reminder after generating a new wallet
181 console.log(`[ClawRouter]`);
182 console.log(`[ClawRouter] ════════════════════════════════════════════════`);
183 console.log(`[ClawRouter] NEW WALLET GENERATED — BACK UP YOUR KEY NOW`);

Callers 1

Calls 5

loadMnemonicFunction · 0.85
generateWalletMnemonicFunction · 0.85
deriveAllKeysFunction · 0.85
readTextFileFunction · 0.85
getSolanaAddressFunction · 0.85

Tested by

no test coverage detected