Agent wallets
One phrase.
Ten chains.
An agent needs its own wallet to pay for things and hold funds. BuildAWallet offers two ways to get one. Both produce a standard 12- or 24-word recovery phrase that also works in MetaMask, Phantom, Trust and the BuildAWallet human app.
Compare
Choose the custody model
Local kit
Recommended- Wallet is created on the agent's own machine.
- BuildAWallet never sees the phrase or keys.
- Unlimited wallets, works offline.
- Needs Node 18+ and seven open-source packages.
Server-made
Opt-in- One HTTP call , good for agents that can't run code.
- Phrase is made in memory and returned once over HTTPS.
- Nothing is stored or logged; we cannot recover it.
- Limited to 5 per hour per client.
Option 1
Create a wallet locally
Three steps. The script prints only public addresses; the phrase is saved to a file only your agent can read.
1
Install the packages
terminal
npm i @scure/bip39 @scure/bip32 @scure/base @scure/btc-signer @noble/hashes @noble/curves ethers2
Download the kit
terminal
curl -o baw-agent-wallet.mjs https://buildawallet.xyz/machine/v1/wallets/kit.mjsOr with MCP: call the wallet_local_kit tool.
3
Run it
terminal
node baw-agent-wallet.mjs
# → { "addresses": { "base": "0x…", "solana": "…", "bitcoin": "bc1…", "tron": "T…" } }Set BAW_WALLET_FILE to choose where the phrase is stored, or BAW_MNEMONIC to restore an existing one.
View full script source
baw-agent-wallet.mjs
#!/usr/bin/env node
// BuildAWallet agent wallet kit , runs locally, never contacts a server.
// Install: npm i @scure/bip39 @scure/bip32 @scure/base @scure/btc-signer @noble/hashes @noble/curves ethers
// Run: node baw-agent-wallet.mjs (creates ./baw-wallet.json once)
// BAW_WALLET_FILE=/secure/path.json node baw-agent-wallet.mjs
import { generateMnemonic, mnemonicToSeedSync, validateMnemonic } from "@scure/bip39";
import { wordlist } from "@scure/bip39/wordlists/english.js";
import { HDKey } from "@scure/bip32";
import { hmac } from "@noble/hashes/hmac.js";
import { sha256, sha512 } from "@noble/hashes/sha2.js";
import { keccak_256 } from "@noble/hashes/sha3.js";
import { secp256k1 } from "@noble/curves/secp256k1.js";
import { ed25519 } from "@noble/curves/ed25519.js";
import { base58 } from "@scure/base";
import * as btc from "@scure/btc-signer";
import { computeAddress } from "ethers";
import { existsSync, readFileSync, writeFileSync, chmodSync } from "node:fs";
const FILE = process.env.BAW_WALLET_FILE || "./baw-wallet.json";
const hex = (b) => "0x" + Buffer.from(b).toString("hex");
function slip10(seed, path) {
let I = hmac(sha512, new TextEncoder().encode("ed25519 seed"), seed);
let key = I.slice(0, 32), chain = I.slice(32);
for (const seg of path.replace(/^m\//, "").split("/")) {
const data = new Uint8Array(37); data.set(key, 1);
new DataView(data.buffer).setUint32(33, (parseInt(seg, 10) | 0x80000000) >>> 0, false);
I = hmac(sha512, chain, data); key = I.slice(0, 32); chain = I.slice(32);
}
return key;
}
let mnemonic = process.env.BAW_MNEMONIC;
if (!mnemonic && existsSync(FILE)) mnemonic = JSON.parse(readFileSync(FILE, "utf8")).mnemonic;
if (!mnemonic) {
mnemonic = generateMnemonic(wordlist, 128);
writeFileSync(FILE, JSON.stringify({ mnemonic, createdAt: new Date().toISOString() }, null, 2), { mode: 0o600 });
chmodSync(FILE, 0o600);
}
if (!validateMnemonic(mnemonic.trim(), wordlist)) throw new Error("Invalid recovery phrase");
const seed = mnemonicToSeedSync(mnemonic.trim());
const root = HDKey.fromMasterSeed(seed);
const evm = computeAddress(hex(root.derive("m/44'/60'/0'/0/0").privateKey));
const sol = base58.encode(ed25519.getPublicKey(slip10(seed, "m/44'/501'/0'/0'")));
const bitcoin = btc.p2wpkh(root.derive("m/84'/0'/0'/0/0").publicKey).address;
// Public addresses only. Same EVM address works on every EVM network.
console.log(JSON.stringify({
walletFile: FILE,
addresses: {
ethereum: evm, base: evm, arbitrum: evm, optimism: evm, polygon: evm, bnb: evm, avalanche: evm,
solana: sol, bitcoin,
},
next: "https://buildawallet.xyz/machine/v1/wallets/kit",
}, null, 2));
Option 2
Ask the server to make one
For agents that can only make HTTP calls. Read the warning first.
HTTP
curl -X POST https://buildawallet.xyz/machine/v1/wallets/generate \
-H 'content-type: application/json' \
-d '{"acknowledgeCustodyRisk": true, "words": 12}'The phrase exists briefly on our servers while it's made. We keep no copy, so if it's lost the funds are lost. Anyone who sees it controls the wallet.
Reference
Derivation paths
evm
m/44'/60'/0'/0/0
solana
m/44'/501'/0'/0'
bitcoin
m/84'/0'/0'/0/0
One EVM address covers Ethereum, Base, Arbitrum, Optimism, Polygon, BNB Chain and Avalanche. Bitcoin uses native SegWit (bc1…).
