我正在尝试在我的react-native测试项目中使用solana-web3.js获取Solana钱包的正确公共地址
import { Keypair} from '@solana/web3.js';
import * as bip39 from 'bip39';
import * as bip32 from 'bip32';
const derivePath = "m/44'/501'/0'/0'";
const mnemonic = "...12 word phrase"
const seed: Buffer = yield bip39.mnemonicToSeed(mnemonic);
// also tried to slice seed.slice(0, 32);
const derivedSeed = bip32.fromSeed(seed).derivePath(derivePath).privateKey;
const keypair = Keypair.fromSeed(derivedSeed);
const publicKey = keypair.publicKey.toString();
我采用了应该用于 Phantom 钱包的派生路径(并且可以在 Solflare 钱包中选择) 但问题是 - 我没有获得与在这些浏览器钱包中获得的相同的公钥。
那么我上面的代码哪里可能出错了?
更新: 当我使用“ed25519-hd-key”lib 而不是“bip32”来获取派生种子时,问题就消失了。
import * as ed25519 from 'ed25519-hd-key';
const derivedSeed = ed25519.derivePath(derivePath, seed.toString('hex')).key;
我的工作变体:
import nacl from 'tweetnacl';
import * as bip39 from 'bip39';
import { derivePath } from 'ed25519-hd-key';
const web3 = require('@solana/web3.js')
const seed = await bip39.mnemonicToSeed(mnemonic);
const seedBuffer = Buffer.from(seed).toString('hex');
const path44Change = `m/44'/501'/0'/0'`;
const derivedSeed = derivePath(path44Change, seedBuffer).key;
keypair = new web3.Account(nacl.sign.keyPair.fromSeed(derivedSeed).secretKey);
您应该使用“m/501'/0'/0'”路径
除了 @dapp-deep 的答案之外,我还想添加一些更新的答案,因为
Account
中的 @solana/web.js
现在已贬值,我们可以使用 KeyPair
。
2.Buffer.from(seed).toString('hex'):然后将种子缓冲区转换为十六进制字符串表示形式。
const path44Change = \m/44'/501'/0'/0'
;:这一行定义了使用BIP44标准的推导路径。路径 m/44'/501'/0'/0'` 特定于 Solana 加密货币,代表以下内容:
m
代表主密钥(派生路径的根)。
44'
是目的字段,表示派生密钥将用于硬币类型的目的。
501'
是币类型字段,指定加密货币(501 是 Solana 的分配值)。
0'
是账户字段,通常用于表示来自同一种子的不同账户。
0'
是找零字段,通常用于区分外部和内部/找零地址。
const derivedSeed = derivePath(path44Change, seedBuffer).key;
:此行使用未指定的 derivePath
函数从提供的导出路径和种子缓冲区导出新种子。返回对象的 key 属性被赋值给 derivedSeed
。
const kp = Keypair.fromSeed(derivedSeed);
:最后,使用 Solana 库中的 Keypair.fromSeed
方法从派生种子创建新的密钥对对象 (kp
)。
return kp;
:函数返回生成的keypair对象,其中包含公钥和私钥。
派生路径是必要的,因为它提供了一种标准化的方法,以确定性和可重复的方式从单个种子(助记词短语)派生多个密钥对。这在加密货币钱包中特别有用,其中可以从相同的助记词生成多个地址,从而可以更好地组织和管理资金。
通过遵循BIP44标准,派生路径确保派生密钥与遵循相同标准的其他钱包和工具兼容。它还在不同类型的硬币或账户之间提供一定程度的隔离,降低意外资金转移或密钥重复使用的风险。
以下是所需的代码:
import * as bip39 from "bip39";
import {
Keypair,
Connection,
} from "@solana/web3.js";
import { derivePath } from 'ed25519-hd-key';
async function getKeyCreatedBySolanaKeygenFromMnemonic(mnemonic: string) {
const seed = await bip39.mnemonicToSeed(mnemonic);
const seedBuffer = Buffer.from(seed).toString('hex');
const path44Change = `m/44'/501'/0'/0'`;
const derivedSeed = derivePath(path44Change, seedBuffer).key;
const kp = Keypair.fromSeed(derivedSeed);
return kp;
}