Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

(code included) Add getHDKeypairs() #1601

Closed
mikemaccana opened this issue Sep 15, 2023 · 7 comments
Closed

(code included) Add getHDKeypairs() #1601

mikemaccana opened this issue Sep 15, 2023 · 7 comments
Labels
enhancement New feature or request

Comments

@mikemaccana
Copy link
Contributor

mikemaccana commented Sep 15, 2023

Motivation

Solana CLI includes a function to get HD keypairs from a seed. web3.js should do the same.

Example use case

A user wishes to get HD keypairs. They hunt around, and end up getting a code snippet from Solana cookbook or similar. The cookbook asks users to use various magic numbers (44, 501 and 0), with no explanation so the user isn't confident in the process.

Rather than ask every user to copypaste the same snippet, it's better we include this in web3.js.

This code is for both browsers and node so belongs in the main web3.js.

Details

As with the new getProgramDerivedAddress we can use get here - avoiding the need to for users to remember a more specific verb like derive.

import { derivePath } from "ed25519-hd-key";

// See https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki 
const PURPOSE = 44;
const SOLANA_COIN_TYPE = 501;
const NON_CHANGE_ADDRESS = 0;

export const getHDKeypairs = async (seed: UInt8Array, count: number): Array<Keypair> => {
  // The seed is the parent to many wallets
  // See https://github.com/solana-labs/solana/blob/master/web3.js/examples/get_account_info.js
  const seed = await bip39.mnemonicToSeed(mnemonic, password);

  const keyPairs: Array<Keypair> = [];

  for (let accountIndex = 0; accountIndex < count; accountIndex++) {
    const path = `m/${PURPOSE}'/${SOLANA_COIN_TYPE}'/${accountIndex}'/${NON_CHANGE_ADDRESS}'`;
    const keypair = Keypair.fromSeed(derivePath(path, seed.toString("hex")).key);
    keyPairs.push(keypair);
  }
  return keyPairs;
};
@mikemaccana mikemaccana added the enhancement New feature or request label Sep 15, 2023
@nickfrosty
Copy link
Contributor

This would be useful, but needs to clarify where derivePath comes from and the other packages

@mikemaccana
Copy link
Contributor Author

Good point Nick. I've updated the example to include the derivePath() dependency. @steveluscher how do you feel about ed25519-hd-key being a web3.js dependency? It's small but depends on Tweetnacl so we might actually want to rebuild ed25519-hd-key using webcrypto per the rest of the new web3.js.

@nickfrosty
Copy link
Contributor

I remember there were loads of efforts to move away from the tweetnacl package, so I don't think anyone wants to add it back in. Do the @noble/curves have the functionality to do this instead?

@steveluscher
Copy link
Contributor

…how do you feel about ed25519-hd-key being a web3.js dependency?

Definitely, definitely not, but someone should absolutely release a package that creates the seed as you've outlined above! You can then use that with crypto.subtle.importKey(). No web3.js required.

What we will likely include in web3.js:

Given those two things, anyone can easily build an HD key generator that produces CryptoKey instances compatible with the new web3.js.

@steveluscher
Copy link
Contributor

If, on the other hand, we can build an HD key generator from the ground up using the SubtleCrypto builtins, then maybe we should consider rolling the whole thing into @solana/keys.

@steveluscher steveluscher added the 1.x Pertains to the v1.x line on the maintenance/v1.x branch label Aug 1, 2024
@steveluscher steveluscher removed the 1.x Pertains to the v1.x line on the maintenance/v1.x branch label Oct 25, 2024
@steveluscher
Copy link
Contributor

Things we won't do:

  • include bip32 as a dependency of web3.js
  • include any HD derivation package as a dependency of web3.js (looks like the contemporary one is micro-key-producer)

Things we could do:

  • create a path helper (ie. getDerivationPathForIndex()) in @solana/keys

Feel free to send a PR for that, but I feel like it won't scratch this itch, given that it only solves 1% of the problem.

@steveluscher steveluscher closed this as not planned Won't fix, can't repro, duplicate, stale Oct 25, 2024
Copy link
Contributor

github-actions bot commented Nov 1, 2024

Because there has been no activity on this issue for 7 days since it was closed, it has been automatically locked. Please open a new issue if it requires a follow up.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants