英文:
How can I use Hedera JS SDK to generate a set of ECDSA key-pairs based on a BIP-39 seed phrase and a custom derivation path?
问题
I understand your request. Here's the translated portion:
我目前正在使用Hedera JS SDK来直接将私钥作为输入生成单个ECDSA密钥对,如下所示:
```js
const privateKey = PrivateKey.fromStringECDSA(process.env.TARGET_HEX_PRIVATE_KEY);
相反,我想要像这样做,使用BIP-39种子短语和派生路径作为输入:
const mnemonic = Mnemonic.fromString(process.env.TARGET_SEED_PHRASE);
const privateKey = await mnemonic.toEcdsaPrivateKey('', "m/44'/60'/0'/0/0");
但是,Mnemonic
的toEcdsaPrivateKey
函数似乎根据其JsDoc @param
注释接受一个数字数组作为派生路径的输入,如下所示:
/**
* 从这个助记短语中恢复ECDSA私钥,可选的口令。
*
* @param {string} [passphrase]
* @param {number[]} [path]
* @returns {Promise<PrivateKey>}
*/
async toEcdsaPrivateKey(passphrase = "", path) {
return CACHE.privateKeyConstructor(
await this._mnemonic.toEcdsaPrivateKey(passphrase, path)
);
}
在我的用例中,我想要使用MetaMask,不幸的是,MetaMask目前还不支持根据网络配置进行自定义派生路径,并且硬编码以太坊派生路径为m/44'/60'/0'/0/0
。请注意,前3个段是“hardened”,而后面的2个不是。
如何指定这个派生路径呢?
<details>
<summary>英文:</summary>
I'm currently using the Hedera JS SDK to generate a single ECDSA key-pair using a private key directly as an input, like so:
```js
const privateKey = PrivateKey.fromStringECDSA(process.env.TARGET_HEX_PRIVATE_KEY);
Instead I would like to do something like this instead, where I am using a BIP-39 seed phrase and a derivation path as inputs:
const mnemonic = Mnemonic.fromString(process.env.TARGET_SEED_PHRASE);
const privateKey = await mnemonic.toEcdsaPrivateKey('', "m/44'/60'/0'/0/0");
However, Mnemonic
's toEcdsaPrivateKey
function seems to accept an array of numbers as the input for the derivation path, based on its JsDoc @param
comment, copied below:
/**
* Recover an ECDSA private key from this mnemonic phrase, with an
* optional passphrase.
*
* @param {string} [passphrase]
* @param {number[]} [path]
* @returns {Promise<PrivateKey>}
*/
async toEcdsaPrivateKey(passphrase = "", path) {
return CACHE.privateKeyConstructor(
await this._mnemonic.toEcdsaPrivateKey(passphrase, path)
);
}
In my use case, I would like to work with MetaMask, which unfortunately does not yet support custom derivation paths per network configuration, and hardcodes the Ethereum derivation path of m/44'/60'/0'/0/0
instead. Note that the first 3 segments are "hardened", while the remaining 2 are not.
How can I specify this derivation path?
答案1
得分: 5
In the latest release, v2.24.1,
the Mnemonic
class has been updated to deprecate
toEcdsaPrivateKey
:
/**
* @deprecated - Use `toStandardEd25519PrivateKey()` or `toStandardECDSAsecp256k1PrivateKey()` instead
* Recover an ECDSA private key from this mnemonic phrase, with an
* optional passphrase.
* @param {string} [passphrase]
* @param {number[]} [path]
* @returns {Promise<PrivateKey>}
*/
... so using the methods suggested by @Topaco in the comments,
where each hardened segment is binary OR
-ed with 0x80000000
,
is not going to work.
... and therefore not possible to achieve my intended outcome
using only Hedera JS SDK.
So here's a workaround that uses EthersJs in combination
with the Hedera JS SDK to achieve the intended outcome:
import { PrivateKey } from "@hashgraph/sdk";
import { utils as ethersUtils } from "ethers";
// init a hierarchically deterministic wallet's node using a seed phrase
const hdNodeRoot = ethersUtils.HDNode.fromMnemonic(process.env.TARGET_SEED_PHRASE);
// apply the derivation path, `accountIdx` starts at `0`
const hdNodeX = hdNodeRoot.derivePath(`m/44'/60'/0'/0/${accountIdx}`);
// convert from ethersjs private key to hedera js sdk private key
const privateKeyX = PrivateKey.fromStringECDSA(hdNodeX.privateKey);
// extract the `0x...` address from the private key
const addressX = privateKeyX.publicKey.toEvmAddress();
The significant bit is where utils.HDNode.fromMnemonic
from EthersJs
is used in place of Mnemonic.toEcdsaPrivateKey
from Hedera JS SDK.
Here's a more complete example,
where I create multiple accounts using the above method,
and fund them from an ED22519 account
(originally generated on and funded by the Hedera Testnet Portal,
which sort of functions like a faucet).
英文:
In the latest release, v2.24.1,
the Mnemonic
class has been updated to deprecate
toEcdsaPrivateKey
:
/**
* @deprecated - Use `toStandardEd25519PrivateKey()` or `toStandardECDSAsecp256k1PrivateKey()` instead
* Recover an ECDSA private key from this mnemonic phrase, with an
* optional passphrase.
* @param {string} [passphrase]
* @param {number[]} [path]
* @returns {Promise<PrivateKey>}
*/
... so using the methods suggested by @Topaco in the comments,
where each hardened segment is binary OR
-ed with 0x80000000
,
is not going to work.
... and therefore not possible to achieve my intended outcome
using only Hedera JS SDK.
So here's a workaround that uses EthersJs in combination
with the Hedera JS SDK to achieve the intended outcome:
import { PrivateKey } from "@hashgraph/sdk";
import { utils as ethersUtils } from "ethers";
// init a hierarchically deterministic wallet's node using a seed phrase
const hdNodeRoot = ethersUtils.HDNode.fromMnemonic(process.env.TARGET_SEED_PHRASE);
// apply the derivation path, `accountIdx` starts at `0`
const hdNodeX = hdNodeRoot.derivePath(`m/44'/60'/0'/0/${accountIdx}`);
// convert from ethersjs private key to hedera js sdk private key
const privateKeyX = PrivateKey.fromStringECDSA(hdNodeX.privateKey);
// extract the `0x...` address from the private key
const addressX = privateKeyX.publicKey.toEvmAddress();
The significant bit is where utils.HDNode.fromMnemonic
from EthersJs
is used in place of Mnemonic.toEcdsaPrivateKey
from Hedera JS SDK.
Here's a more complete example,
where I create multiple accounts using the above method,
and fund them from an ED22519 account
(originally generated on and funded by the Hedera Testnet Portal,
which sort of functions like a faucet).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论