2

I have a seed phrase that I used to generate an address with and sent tokens to it. I entered the seed phrase into Solflare wallet but it can't find the address with tokens on it.

How do I create a keypair using a custom derivation path so I can perform transactions with it?

2 Answers 2

3

Using Javascript

This can be done with the ed25519-hd-key and tweetnacl libraries.

Make sure you start the path with m/44'/501', as this is required for Solana addresses.

Setup (run this in your terminal):

npm init -y && npm i @solana/web3.js bip39 tweetnacl buffer ed25519-hd-key

Create a file with this code and run it with node <FILENAME.js>:

import { Keypair } from '@solana/web3.js';
import * as bip39 from 'bip39';
import nacl from 'tweetnacl';
import { Buffer } from 'buffer';
import * as ed25519 from 'ed25519-hd-key';

// Replace with your mnemonic
const mnemonic = 'cabbage together debris chalk hammer novel wire tunnel rubber labor retire prefer';

// Convert the mnemonic to a seed
const seed = bip39.mnemonicToSeedSync(mnemonic).slice(0, 32);

// Define the derivation path
const path = `m/44'/501'/0'/0'`; // Replace with your custom path

// Derive a seed from the given path
const derivedSeed = ed25519.derivePath(path, Buffer.from(seed, 'hex')).key;

// Generate a keypair from the derived seed using tweetnacl (NaCl = Networking and Cryptography library)
const derivedUint8Keypair = nacl.sign.keyPair.fromSeed(derivedSeed);

// This is a Uint8Array, not a Solana web3.js Keypair object, so you will need to convert it
const customPathKeypair = Keypair.fromSecretKey(
  Uint8Array.from(derivedUint8Keypair.secretKey)
);

console.log('Custom Path Keypair address:', customPathKeypair.publicKey.toBase58());

Using wallets

The Backpack wallet supports arbitrary derivation paths, so you can just import your seed phrase into it and set the path.

https://backpack.app/downloads

1
  • Open to improvements or ways this can be done better!
    – Raza
    Commented Jan 9 at 3:54
0

You can do this:

import { Keypair } from "@solana/web3.js";
import * as bip39 from "bip39";
import { HDKey } from "micro-ed25519-hdkey";

/**
 * Generates a keypair from a mnemonic phrase and allows for modification of the derivation path.
 *
 * @param {string} phrase - The mnemonic phrase.
 * @param {string} [path=m/44'/501'/0'/0'] - The derivation path (default value is `m/44'/501'/0'/0'`).
 * @returns {Keypair} - The keypair generated from the mnemonic phrase and path.
 */
const keyPairFromPhrase = (
  phrase: string,
  path = `m/44'/501'/0'/0'`
): Keypair => {
  // generate seed from mnemonic phrase
  const seed = bip39.mnemonicToSeedSync(phrase, "");

  // derive HD key from seed
  const hdKey = HDKey.fromMasterSeed(seed.toString("hex"));

  // derive keypair from HD key and specified path
  const keypair = Keypair.fromSeed(hdKey.derive(path).privateKey);
  return keypair;
};

You will generate (by default) the same keys than Phantom (https://help.phantom.app/hc/en-us/articles/12988493966227-What-derivation-paths-does-Phantom-wallet-support). I leave another reference for seeing how derivation paths are determined there and in Ledger (it could be useful too). I hope this helps!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.