
This is a complete BIP39 wallet manager for local development with Stacks L2 and Bitcoin L1 addresses. It handles the full lifecycle: create or import wallets, encrypt them with AES-GCM at ~/.aibtc/, unlock for transactions, lock when done. You get native SegWit and Taproot addresses alongside Stacks addresses, all derived from one mnemonic. The security model is straightforward: passwords never hit disk, mnemonics stay encrypted, and there's an auto-lock timeout you can configure. Export and delete operations require explicit confirmation strings, which is the right call for something handling keys. If you're building anything that needs to sign Stacks or Bitcoin transactions from Claude, this gives you the primitives without reinventing wallet storage.
npx -y skills add aibtcdev/skills --skill wallet --agent claude-codeInstalls into .claude/skills of the current project.
Manages encrypted BIP39 wallets stored locally at ~/.aibtc/. Provides full lifecycle operations for Stacks L2 and Bitcoin L1 (native SegWit + Taproot) addresses. Wallets are AES-GCM encrypted with a password and never stored in plaintext.
bun run wallet/wallet.ts <subcommand> [options]
Create a new wallet with a generated 24-word BIP39 mnemonic.
bun run wallet/wallet.ts create --name <name> --password <password> [--network mainnet|testnet]
Options:
--name (required) — Label for the wallet (e.g. "main", "trading")--password (required, min 8 chars) — Encryption password (sensitive)--network (optional) — mainnet or testnet (default: testnet)Output:
{
"success": true,
"walletId": "...",
"Bitcoin (L1)": { "Native SegWit": "bc1q...", "Taproot": "bc1p..." },
"Stacks (L2)": { "Address": "SP..." },
"network": "testnet",
"mnemonic": "word1 word2 ... word24",
"warning": "CRITICAL: Save this mnemonic..."
}
Import an existing wallet from a BIP39 mnemonic phrase.
bun run wallet/wallet.ts import --name <name> --mnemonic "<24 words>" --password <password> [--network mainnet|testnet]
Options:
--name (required) — Label for the wallet--mnemonic (required) — 24-word BIP39 mnemonic (sensitive)--password (required, min 8 chars) — Encryption password (sensitive)--network (optional) — mainnet or testnet (default: testnet)Output:
{
"success": true,
"walletId": "...",
"Bitcoin (L1)": { "Native SegWit": "bc1q...", "Taproot": "bc1p..." },
"Stacks (L2)": { "Address": "SP..." },
"network": "testnet"
}
Unlock a wallet to enable transactions. Session persists in-process memory until locked or timeout.
bun run wallet/wallet.ts unlock --password <password> [--wallet-id <id>]
Options:
--password (required) — Wallet password (sensitive)--wallet-id (optional) — Wallet ID to unlock (uses active wallet if omitted)Output:
{
"success": true,
"walletId": "...",
"Bitcoin (L1)": { "Native SegWit": "bc1q...", "Taproot": "bc1p..." },
"Stacks (L2)": { "Address": "SP..." },
"network": "testnet"
}
Lock the wallet, clearing sensitive key material from memory.
bun run wallet/wallet.ts lock
Output:
{ "success": true, "message": "Wallet is now locked." }
List all available wallets with metadata (no sensitive data).
bun run wallet/wallet.ts list
Output:
{
"wallets": [
{
"id": "...",
"name": "main",
"btcAddress": "bc1q...",
"address": "SP...",
"network": "testnet",
"createdAt": "2024-01-01T00:00:00.000Z",
"isActive": true,
"isUnlocked": false
}
],
"totalCount": 1
}
Switch the active wallet (requires unlock after switching).
bun run wallet/wallet.ts switch --wallet-id <id>
Options:
--wallet-id (required) — Wallet ID to activateOutput:
{
"success": true,
"activeWalletId": "...",
"address": "SP...",
"network": "testnet"
}
Permanently delete a wallet (requires password + confirmation).
bun run wallet/wallet.ts delete --wallet-id <id> --password <password> --confirm DELETE
Options:
--wallet-id (required) — Wallet ID to delete--password (required) — Wallet password for verification (sensitive)--confirm (required) — Must be exactly DELETEOutput:
{
"success": true,
"deletedWalletId": "...",
"message": "Wallet deleted permanently."
}
Export the mnemonic phrase for a wallet (requires password + safety acknowledgment).
bun run wallet/wallet.ts export --password <password> --confirm I_UNDERSTAND_THE_RISKS [--wallet-id <id>]
Options:
--password (required) — Wallet password (sensitive)--confirm (required) — Must be exactly I_UNDERSTAND_THE_RISKS--wallet-id (optional) — Wallet ID (uses active wallet if omitted)Output:
{
"walletId": "...",
"mnemonic": "word1 word2 ... word24",
"warning": "SECURITY WARNING: ..."
}
Change the wallet encryption password (atomic with backup/verify/rollback).
bun run wallet/wallet.ts rotate-password --old-password <pass> --new-password <pass> [--wallet-id <id>]
Options:
--old-password (required) — Current password (sensitive)--new-password (required, min 8 chars) — New password (sensitive)--wallet-id (optional) — Wallet ID (uses active wallet if omitted)Output:
{
"success": true,
"walletId": "...",
"message": "Password rotated. Use unlock with the new password."
}
Set the auto-lock timeout in minutes (0 = never auto-lock).
bun run wallet/wallet.ts set-timeout --minutes <n>
Options:
--minutes (required) — Minutes until auto-lock (0 = disabled)Output:
{
"success": true,
"autoLockMinutes": 15,
"message": "Auto-lock set to 15 minutes."
}
Get wallet readiness status: whether a wallet exists, is active, and is unlocked.
bun run wallet/wallet.ts status
Output:
{
"message": "Wallet is locked. Unlock to perform transactions.",
"readyForTransactions": false,
"isUnlocked": false,
"currentNetwork": "testnet",
"wallet": { "id": "...", "address": "SP...", "btcAddress": "bc1q..." }
}
Get the active wallet's address and session info.
bun run wallet/wallet.ts info
Output:
{
"status": "ready",
"network": "testnet",
"Stacks (L2)": { "Address": "SP..." },
"Bitcoin (L1)": { "Native SegWit": "bc1q...", "Taproot": "bc1p..." }
}
Get the STX balance for a wallet address.
bun run wallet/wallet.ts stx-balance [--address <addr>]
Options:
--address (optional) — Stacks address to check (uses active wallet if omitted)Output:
{
"address": "SP...",
"network": "testnet",
"balance": { "stx": "100 STX", "microStx": "100000000" },
"locked": { "stx": "0 STX", "microStx": "0" }
}
lock after sensitive operations to clear keys from memoryexport and delete require explicit confirmation strings to prevent accidentsrotate-password is atomic: original keystore is backed up and restored on failure