UNPKG

@alephium/web3-wallet

Version:
154 lines 7.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.HDWallet = void 0; exports.generateMnemonic = generateMnemonic; exports.deriveHDWalletPrivateKey = deriveHDWalletPrivateKey; exports.deriveSecp256K1PrivateKey = deriveSecp256K1PrivateKey; exports.deriveSchnorrPrivateKey = deriveSchnorrPrivateKey; exports.deriveHDWalletPrivateKeyForGroup = deriveHDWalletPrivateKeyForGroup; exports.deriveSecp256K1PrivateKeyForGroup = deriveSecp256K1PrivateKeyForGroup; exports.deriveSchnorrPrivateKeyForGroup = deriveSchnorrPrivateKeyForGroup; exports.getHDWalletPath = getHDWalletPath; exports.getSecp259K1Path = getSecp259K1Path; exports.getSchnorrPath = getSchnorrPath; exports.getGlSecp256K1Path = getGlSecp256K1Path; exports.getGlSecp256R1Path = getGlSecp256R1Path; exports.getGlEd25519Path = getGlEd25519Path; exports.getGlWebauthnPath = getGlWebauthnPath; const web3_1 = require("@alephium/web3"); const web3_2 = require("@alephium/web3"); const web3_3 = require("@alephium/web3"); const web3_4 = require("@alephium/web3"); const bip39_1 = require("@scure/bip39"); const english_1 = require("@scure/bip39/wordlists/english"); const bip32_1 = require("@scure/bip32"); const privatekey_wallet_1 = require("./privatekey-wallet"); function generateMnemonic(wordLength) { return (0, bip39_1.generateMnemonic)(english_1.wordlist, wordLength === 12 ? 128 : 256); } function deriveHDWalletPrivateKey(mnemonic, keyType, _fromAddressIndex, passphrase) { const seed = (0, bip39_1.mnemonicToSeedSync)(mnemonic, passphrase); const masterKey = bip32_1.HDKey.fromMasterSeed(seed); const fromAddressIndex = _fromAddressIndex ?? 0; const child = masterKey.derive(getHDWalletPath(keyType, fromAddressIndex)); if (!child.privateKey) throw new Error('Missing private key'); return web3_1.utils.binToHex(child.privateKey); } function deriveSecp256K1PrivateKey(mnemonic, fromAddressIndex, passphrase) { return deriveHDWalletPrivateKey(mnemonic, 'default', fromAddressIndex, passphrase); } function deriveSchnorrPrivateKey(mnemonic, fromAddressIndex, passphrase) { return deriveHDWalletPrivateKey(mnemonic, 'bip340-schnorr', fromAddressIndex, passphrase); } function deriveHDWalletPrivateKeyForGroup(mnemonic, targetGroup, keyType, _fromAddressIndex, passphrase) { if (targetGroup < 0 || targetGroup > web3_4.TOTAL_NUMBER_OF_GROUPS) { throw Error(`Invalid target group for HD wallet derivation: ${targetGroup}`); } const fromAddressIndex = _fromAddressIndex ?? 0; const privateKey = deriveHDWalletPrivateKey(mnemonic, keyType, fromAddressIndex, passphrase); if ((0, web3_4.groupOfPrivateKey)(privateKey, keyType) === targetGroup) { return [privateKey, fromAddressIndex]; } else { return deriveHDWalletPrivateKeyForGroup(mnemonic, targetGroup, keyType, fromAddressIndex + 1, passphrase); } } function deriveSecp256K1PrivateKeyForGroup(mnemonic, targetGroup, _fromAddressIndex, passphrase) { return deriveHDWalletPrivateKeyForGroup(mnemonic, targetGroup, 'default', _fromAddressIndex, passphrase); } function deriveSchnorrPrivateKeyForGroup(mnemonic, targetGroup, _fromAddressIndex, passphrase) { return deriveHDWalletPrivateKeyForGroup(mnemonic, targetGroup, 'bip340-schnorr', _fromAddressIndex, passphrase); } function getHDWalletPath(keyType, addressIndex) { if (addressIndex < 0 || !Number.isInteger(addressIndex) || addressIndex.toString().includes('e')) { throw new Error('Invalid address index path level'); } const coinType = "1234'"; const keyTypeNum = (() => { switch (keyType) { case 'default': return 0; case 'bip340-schnorr': return 1; case 'gl-secp256k1': return 2; case 'gl-secp256r1': return 3; case 'gl-ed25519': return 4; case 'gl-webauthn': return 5; default: throw new Error(`Unsupported key type: ${keyType}`); } })(); return `m/44'/${coinType}/${keyTypeNum}'/0/${addressIndex}`; } function getSecp259K1Path(addressIndex) { return getHDWalletPath('default', addressIndex); } function getSchnorrPath(addressIndex) { return getHDWalletPath('bip340-schnorr', addressIndex); } function getGlSecp256K1Path(addressIndex) { return getHDWalletPath('gl-secp256k1', addressIndex); } function getGlSecp256R1Path(addressIndex) { return getHDWalletPath('gl-secp256r1', addressIndex); } function getGlEd25519Path(addressIndex) { return getHDWalletPath('gl-ed25519', addressIndex); } function getGlWebauthnPath(addressIndex) { return getHDWalletPath('gl-webauthn', addressIndex); } class HDWallet extends web3_4.SignerProviderWithCachedAccounts { constructor({ mnemonic, keyType, nodeProvider, explorerProvider, passphrase }) { super(); this.mnemonic = mnemonic; this.keyType = keyType ?? 'default'; if (this.keyType !== 'default' && this.keyType !== 'bip340-schnorr' && this.keyType !== 'gl-secp256k1') { throw new Error(`Invalid key type ${keyType}`); } this.passphrase = passphrase; this.nodeProvider = nodeProvider ?? web3_4.web3.getCurrentNodeProvider(); this.explorerProvider = explorerProvider ?? web3_4.web3.getCurrentExplorerProvider(); } getNextFromAddressIndex(targetGroup) { let usedAddressIndex = -1; for (const account of this._accounts.values()) { const accountGroup = (0, web3_1.isGroupedAccount)(account) ? account.group : (0, web3_3.groupOfAddress)(account.address); if ((targetGroup === undefined || accountGroup == targetGroup) && account.addressIndex > usedAddressIndex) { usedAddressIndex = account.addressIndex; } } return usedAddressIndex + 1; } deriveAndAddNewAccount(targetGroup) { const fromAddressIndex = this.getNextFromAddressIndex(targetGroup); let priKey; let addressIndex = fromAddressIndex; if (targetGroup !== undefined) { const [_priKey, _addressIndex] = deriveHDWalletPrivateKeyForGroup(this.mnemonic, targetGroup, this.keyType, fromAddressIndex, this.passphrase); priKey = _priKey; addressIndex = _addressIndex; } else { priKey = deriveHDWalletPrivateKey(this.mnemonic, this.keyType, fromAddressIndex, this.passphrase); } const publicKey = (0, web3_1.publicKeyFromPrivateKey)(priKey, this.keyType); const address = (0, web3_2.addressFromPublicKey)(publicKey, this.keyType); const group = (0, web3_3.groupOfAddress)(address); const account = { keyType: this.keyType, address, group, publicKey, addressIndex }; this._accounts.set(account.address, account); return account; } async signRaw(signerAddress, hexString) { const account = await this.getAccount(signerAddress); const privateKey = deriveHDWalletPrivateKey(this.mnemonic, account.keyType, account.addressIndex, this.passphrase); return privatekey_wallet_1.PrivateKeyWallet.sign(privateKey, hexString, this.keyType); } } exports.HDWallet = HDWallet; //# sourceMappingURL=hd-wallet.js.map