derive-solana-key.cjsā¢4.14 kB
// derive-solana-key.cjs
const bip39 = require("bip39");
const { derivePath } = require("ed25519-hd-key");
const { Keypair } = require("@solana/web3.js");
const bs58 = require("bs58").default || require("bs58");
async function createNewWallet() {
console.log("=".repeat(60));
console.log("CREATING NEW SOLANA WALLET");
console.log("=".repeat(60));
// Generate a new 12-word mnemonic
const mnemonic = bip39.generateMnemonic(128); // 128 bits = 12 words
// Convert mnemonic to seed
const seed = await bip39.mnemonicToSeed(mnemonic);
// Use standard Solana derivation path
const path = "m/44'/501'/0'/0'";
const derived = derivePath(path, seed.toString("hex"));
// Create keypair from derived seed
const keypair = Keypair.fromSeed(derived.key);
// Get keys in different formats
const secretKeyBase58 = bs58.encode(Buffer.from(keypair.secretKey));
console.log("\nš NEW WALLET CREATED");
console.log("-".repeat(60));
console.log("\nš MNEMONIC (12 words):");
console.log(mnemonic);
console.log("\nā ļø SAVE THIS MNEMONIC - IT'S YOUR WALLET BACKUP!");
console.log("-".repeat(60));
console.log("\nš Public Key (Address):");
console.log(keypair.publicKey.toBase58());
console.log("\nš Private Key (Base58 - for AGENT_SECRET_KEY):");
console.log(secretKeyBase58);
console.log("\n" + "=".repeat(60));
console.log("š¾ Add this to your .env file:");
console.log("=".repeat(60));
console.log(`AGENT_SECRET_KEY=${secretKeyBase58}`);
console.log(`ENVIRONMENT=DEVNET`);
console.log("=".repeat(60));
console.log("\nš° Get Devnet SOL:");
console.log(`https://faucet.solana.com/`);
console.log(
`Or use: solana airdrop 2 ${keypair.publicKey.toBase58()} --url devnet`,
);
console.log("\n");
}
async function deriveFromMnemonic(mnemonic) {
console.log("=".repeat(60));
console.log("DERIVING WALLET FROM MNEMONIC");
console.log("=".repeat(60));
if (!bip39.validateMnemonic(mnemonic)) {
throw new Error("Invalid mnemonic");
}
// Convert mnemonic to seed
const seed = await bip39.mnemonicToSeed(mnemonic);
// Common Solana derivation path used by Phantom: m/44'/501'/0'/0'
// If you have multiple accounts, increment the third index: m/44'/501'/{account}'/0'
const path = "m/44'/501'/0'/0'";
const derived = derivePath(path, seed.toString("hex"));
// derived.key is 32 bytes, use it as the ed25519 seed
const keypair = Keypair.fromSeed(derived.key);
// secretKey is 64 bytes Uint8Array: first 32 bytes seed, last 32 bytes pubkey
const secretKeyHex = Buffer.from(keypair.secretKey).toString("hex");
const secretKeyBase58 = bs58.encode(Buffer.from(keypair.secretKey));
console.log("\nā
WALLET DERIVED");
console.log("-".repeat(60));
console.log("\nš Public Key (Address):");
console.log(keypair.publicKey.toBase58());
console.log("\nš Private Key (Hex):");
console.log(secretKeyHex);
console.log("\nš Private Key (Base58 - for AGENT_SECRET_KEY):");
console.log(secretKeyBase58);
console.log("\n" + "=".repeat(60));
console.log("š¾ Add this to your .env file:");
console.log("=".repeat(60));
console.log(`AGENT_SECRET_KEY=${secretKeyBase58}`);
console.log("=".repeat(60));
console.log("\n");
}
async function main() {
const args = process.argv.slice(2);
if (args.length === 0 || args[0] === "--new") {
// Create a new wallet
await createNewWallet();
} else if (args[0] === "--mnemonic" && args.length > 1) {
// Derive from provided mnemonic
const mnemonic = args.slice(1).join(" ");
await deriveFromMnemonic(mnemonic);
} else {
console.log("\nš USAGE:");
console.log("-".repeat(60));
console.log("\n1. Create a NEW wallet:");
console.log(" pnpm derive-key");
console.log(" or");
console.log(" pnpm derive-key --new");
console.log("\n2. Derive from EXISTING mnemonic:");
console.log(
' pnpm derive-key --mnemonic "your twelve word mnemonic phrase here"',
);
console.log("\n");
process.exit(1);
}
}
main().catch((err) => {
console.error("\nā ERROR:", err.message);
process.exit(1);
});