mirror of
https://github.com/zhigang1992/wallet.git
synced 2026-01-12 17:53:19 +08:00
test: bitcoin address generation logic
This commit is contained in:
@@ -137,6 +137,9 @@
|
||||
"@reach/utils": "0.15.3",
|
||||
"@reach/visually-hidden": "0.15.2",
|
||||
"@reduxjs/toolkit": "1.8.4",
|
||||
"@scure/base": "1.1.1",
|
||||
"@scure/bip32": "1.1.1",
|
||||
"@scure/bip39": "1.1.0",
|
||||
"@segment/analytics-next": "1.46.0",
|
||||
"@sentry/react": "7.27.0",
|
||||
"@sentry/tracing": "7.28.0",
|
||||
@@ -265,6 +268,7 @@
|
||||
"audit-ci": "6.3.0",
|
||||
"babel-loader": "9.1.0",
|
||||
"base64-loader": "1.0.0",
|
||||
"bip32": "3.1.0",
|
||||
"bip39": "3.0.4",
|
||||
"blns": "2.0.4",
|
||||
"browserslist": "4.21.4",
|
||||
@@ -303,6 +307,7 @@
|
||||
"speed-measure-webpack-plugin": "1.5.0",
|
||||
"stream-browserify": "3.0.0",
|
||||
"svg-url-loader": "8.0.0",
|
||||
"tiny-secp256k1": "2.2.1",
|
||||
"ts-jest": "29.0.3",
|
||||
"ts-node": "10.9.1",
|
||||
"ts-unused-exports": "7.0.3",
|
||||
|
||||
46
src/shared/crypto/p2wpkh-address-gen.spec.ts
Normal file
46
src/shared/crypto/p2wpkh-address-gen.spec.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { derivePayToWitnessPublicKeyHashAddressFromXpub } from './p2wpkh-address-gen';
|
||||
|
||||
describe('Bitcoin bech32 (P2WPKH address derivation', () => {
|
||||
describe('from extended public key', () => {
|
||||
const accounts = [
|
||||
{
|
||||
path: "m/84'/0'/0'",
|
||||
extended_public_key:
|
||||
'xpub6CwY13JDrzeY2oWjP9dbiyLHQh3JVWCvBTCfD7WREBUpBUmtCu4bgxfSGrvaLDbZaMdw2nsPeTFv6AokWkVqh4rbKpsxg7GgEu543Qwvyff',
|
||||
private_key: 'L1FA9VHZNkgCBW9fS76zDHcjuK72LE4gGVAMnN67onRRCoDJvZJi',
|
||||
public_key: '0211758b68eb9b0e4e9610c49739f2ce039732033ba47e125bbdf64ef6cd586ef3',
|
||||
zeroIndexChildAddress: 'bc1qa4ypkks2kfpawyy5mautjfqc6wv703ckm7puux',
|
||||
},
|
||||
{
|
||||
path: "m/84'/0'/1'",
|
||||
mnemonic:
|
||||
'token spatial butter drill city debate pipe shoot target pencil tonight gallery dog globe copy hybrid convince spell load maximum impose crazy engage way',
|
||||
extended_public_key:
|
||||
'xpub6CwY13JDrzeY55xGbiHxHwZSZpbkmrM7QMag3yVgZi62zaYFsBAUam1kghZZx4hDgDdkDzAMxc8xmpcyGAb1EoXoB7Vn7WTiUEaCEd3CcPq',
|
||||
private_key: 'Kyhx4Zz1iYmCGx1gLnPE5ZFphBf16BoRKokU6B8KbxkJ7tM511de',
|
||||
public_key: '025f6abba7947109c5e5ba0fed5e7b99b0ce5b06ccbca86539e6eca261c4507559',
|
||||
zeroIndexChildAddress: 'bc1q5aptjy5l9q4qcykvccpwlqcvzydg744qkv94d3',
|
||||
},
|
||||
{
|
||||
path: "m/84'/0'/2'",
|
||||
mnemonic:
|
||||
'token spatial butter drill city debate pipe shoot target pencil tonight gallery dog globe copy hybrid convince spell load maximum impose crazy engage way',
|
||||
extended_public_key:
|
||||
'xpub6CwY13JDrzeY7qyP5MCBqA3hmB9oX8mjpbt6YWPfCRb9fus8Yrt84xxzh1Ci2wyW8intyoxmr3MjCHCtbs458uboWZVV8WFeHZBveJHVG71',
|
||||
private_key: 'L1CzwqocLUQgH6GeH6bBKRaRnGLF81249Wbd14uTzLaUGE5qMdD7',
|
||||
public_key: '022b804094c9b74a93d51e6bb3b1ae8378027e810058bbcb34ac54f3a307a225d1',
|
||||
zeroIndexChildAddress: 'bc1q253fdeyzuwx58xxssd3a2xw2gq7khhpmr6vgnh',
|
||||
},
|
||||
];
|
||||
|
||||
describe.each(accounts)('bitcoinjs-lib implementation', account => {
|
||||
describe(account.path, () => {
|
||||
const address = derivePayToWitnessPublicKeyHashAddressFromXpub(
|
||||
account.extended_public_key,
|
||||
0
|
||||
);
|
||||
test('bech 32 address', () => expect(address).toEqual(account.zeroIndexChildAddress));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
12
src/shared/crypto/p2wpkh-address-gen.ts
Normal file
12
src/shared/crypto/p2wpkh-address-gen.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { HDKey } from '@scure/bip32';
|
||||
import * as bitcoin from 'bitcoinjs-lib';
|
||||
|
||||
function deriveBip32KeychainFromExtendedPublicKey(xpub: string) {
|
||||
return HDKey.fromExtendedKey(xpub);
|
||||
}
|
||||
|
||||
export function derivePayToWitnessPublicKeyHashAddressFromXpub(xpub: string, index: number) {
|
||||
const keychain = deriveBip32KeychainFromExtendedPublicKey(xpub);
|
||||
const zeroAddressIndex = keychain.deriveChild(0).deriveChild(index);
|
||||
return bitcoin.payments.p2wpkh({ pubkey: Buffer.from(zeroAddressIndex.publicKey!) }).address;
|
||||
}
|
||||
209
src/shared/crypto/p2wsh-p2sh-address-gen.spec.ts
Normal file
209
src/shared/crypto/p2wsh-p2sh-address-gen.spec.ts
Normal file
@@ -0,0 +1,209 @@
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
import { base58check } from '@scure/base';
|
||||
import { HDKey } from '@scure/bip32';
|
||||
import { hashP2WPKH } from '@stacks/transactions';
|
||||
import bip32Factory from 'bip32';
|
||||
import * as bip39 from 'bip39';
|
||||
import * as bitcoin from 'bitcoinjs-lib';
|
||||
import * as ecc from 'tiny-secp256k1';
|
||||
|
||||
import {
|
||||
decodeCompressedWifPrivateKey,
|
||||
deriveBtcBip49SeedFromMnemonic,
|
||||
deriveRootBtcKeychain,
|
||||
makePayToScriptHashAddress,
|
||||
makePayToScriptHashAddressBytes,
|
||||
makePayToScriptHashKeyHash,
|
||||
payToScriptHashTestnetPrefix,
|
||||
publicKeyToPayToScriptHashAddress,
|
||||
} from './p2wsh-p2sh-address-gen';
|
||||
|
||||
describe('Bitcoin SegWit (P2WPKH-P2SH) address generation', () => {
|
||||
const bip32 = bip32Factory(ecc);
|
||||
//
|
||||
// https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.spec.ts
|
||||
describe('Sanity check tests copied from `bitcoinjs-lib` vs other libs', () => {
|
||||
test('can create a BIP49, bitcoin testnet, account 0, external address', async () => {
|
||||
const mnemonic =
|
||||
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
|
||||
const seed = bip39.mnemonicToSeedSync(mnemonic);
|
||||
expect(seed).toEqual(Buffer.from(await deriveBtcBip49SeedFromMnemonic(mnemonic)));
|
||||
|
||||
const root = bip32.fromSeed(seed);
|
||||
const keychain = deriveRootBtcKeychain(seed);
|
||||
expect(root.privateKey?.toString('hex')).toEqual(
|
||||
Buffer.from(keychain.privateKey!).toString('hex')
|
||||
);
|
||||
|
||||
const path = "m/49'/1'/0'/0/0";
|
||||
const child = root.derivePath(path);
|
||||
|
||||
const bitcoinPayment = bitcoin.payments.p2sh({
|
||||
redeem: bitcoin.payments.p2wpkh({
|
||||
pubkey: child.publicKey,
|
||||
network: bitcoin.networks.testnet,
|
||||
}),
|
||||
network: bitcoin.networks.testnet,
|
||||
});
|
||||
|
||||
expect(bitcoinPayment.address).toEqual('2Mww8dCYPUpKHofjgcXcBCEGmniw9CoaiD2');
|
||||
});
|
||||
});
|
||||
|
||||
const phrase =
|
||||
'above view guide write long gift chimney own guide mirror word ski code monster gauge bracket until stem feed scale smart truth toy limb';
|
||||
|
||||
describe('Verify against wagyu results', () => {
|
||||
// Keys generated with `wagyu`
|
||||
// $ wagyu bitcoin import-hd -m "<phrase>" -d "m/49'/0'/0'/0/0" --format segwit --json
|
||||
const keys = [
|
||||
{
|
||||
path: "m/49'/0'/0'/0/0",
|
||||
extended_private_key:
|
||||
'xprvA2WTEJy9NLu57C55yCCPvXLzGq6mGjL3oc81T7vMv2WYREFuAJV3HT4pJYF4a3JRCnyU95rgq4eY2X6cCJTJQYEHmHrvyfy5pCnPcqeTikK',
|
||||
extended_public_key:
|
||||
'xpub6FVodpW3CiTNKg9Z5DjQHfHiprwFgC3uAq3cFWKyUN3XJ2b3hqoHqFPJ9p9r4QK5f9fs1VztRMrjSy6M6HvVLtpC6KipJ2whmAhk9V3GZZ2',
|
||||
private_key: 'L5iYDFDUDSGnjtWUT8gKDvCcsfMna5fAk6pQo5DZandks5r7Av4Q',
|
||||
public_key: '03715f44ce96a11743c97e4ef5954e78482107a9658f1c5f33bc9e70dc171e56e5',
|
||||
address: '3CTTwjVZ59ykFH2DSQpF3iLWM3fESjFcJ9',
|
||||
format: 'p2sh_p2wpkh',
|
||||
network: 'mainnet',
|
||||
},
|
||||
{
|
||||
path: "m/49'/0'/0'/0/1",
|
||||
extended_private_key:
|
||||
'xprvA2WTEJy9NLu5ANouN242mgeiXNcndxwCRHRj3B3C96zWPj7Cgp22frkXKLGiRK59fg6nkGHHityZkVdjBfp7oLP8gf2jy2iHf21qaTWHQfd',
|
||||
extended_public_key:
|
||||
'xpub6FVodpW3CiTNNrtNU3b38pbT5QTH3Rf3nWMKqZSohSXVGXSMEMLHDf51AZpFphHQXCZzAMXGHraNyBmRXHKbgKQETn8mr6oUTAXBYJJBGEy',
|
||||
private_key: 'L4Xt5Ricu9HAg3t92uyqNpnFXKXCgt6DuUtVMkaTsqgXs7rnxjSY',
|
||||
public_key: '02166ce8acc10a07f877436d673c1876ad2b68d7c78075972d4b2d9f8e1d0d984d',
|
||||
address: '36R4QBx4HqRSiRswcFeCe6KUgk2JY9aP87',
|
||||
format: 'p2sh_p2wpkh',
|
||||
network: 'mainnet',
|
||||
},
|
||||
{
|
||||
path: "m/49'/0'/0'/0/2",
|
||||
extended_private_key:
|
||||
'xprvA2WTEJy9NLu5E4vHyjZWFKoTnibqRqNquBzPR7sRoMn44bvpq6ES7cbRmxmxZAtiTDFvRUFWzpsYqbuNF4WapLdJJzrYTDDY6k4QhqHEkXG',
|
||||
extended_public_key:
|
||||
'xpub6FVodpW3CiTNSYzm5m6WcTkCLkSKqJ6hGQuzDWH3MhK2wQFyNdYgfQuudCnLj4afakVMnLpHBuAY13aHFh3giri7MRZ8gEddLtr9wdgcvpn',
|
||||
private_key: 'L2aBwidPCi2YjxDriNAtxfrMFbS3PsKeUUSnnt8cQQRKvpPciUqo',
|
||||
public_key: '0218e2229c75d57f2a0bd6dfdfa50a1a736d19fb40a1f18a675d34960b088df01e',
|
||||
address: '3BU1wA95ELhgweMSazGh42CHD5K64XGUop',
|
||||
format: 'p2sh_p2wpkh',
|
||||
network: 'mainnet',
|
||||
},
|
||||
{
|
||||
path: "m/49'/0'/0'/0/3",
|
||||
extended_private_key:
|
||||
'xprvA2WTEJy9NLu5FKNrRe3coYxbKXjjzibJ6uouC9v29s6Ut8KJvmqXWmvzPTb9wPfRjYzvcq91QyV6B7P38XmZpTquTDoVyp4vv5baiyf8EZT',
|
||||
extended_public_key:
|
||||
'xpub6FVodpW3CiTNToTKXfadAguKsZaEQBK9U8jVzYKdiCdTkveTUK9n4aFUEiuixKhQeqrrqX9iKTYFmpJXdc2im8y2JzYCuiEZvegLuTAetxJ',
|
||||
private_key: 'L2Mx4mkmuQMnRxf1gCYSSEugDj6TeDS45eYjXYdanJ7MEX9Xp8Fe',
|
||||
public_key: '02bf94312be9021d61d1ed917c5e8542d215180afe5db35c5574e3382b3b8469f0',
|
||||
address: '3MCzNqbNy7k8hnyenwpsdHahY2yBVQJQsz',
|
||||
format: 'p2sh_p2wpkh',
|
||||
network: 'mainnet',
|
||||
},
|
||||
] as const;
|
||||
|
||||
describe.each(keys)('Core libraries: bip32, bip39, bitcoinjs-lib', key => {
|
||||
const seed = bip39.mnemonicToSeedSync(phrase);
|
||||
const root = bip32.fromSeed(seed);
|
||||
const child = root.derivePath(key.path);
|
||||
|
||||
describe(key.path, () => {
|
||||
test(`public key`, () => expect(child.publicKey.toString('hex')).toEqual(key.public_key));
|
||||
|
||||
test(`extended public key`, () =>
|
||||
expect(child.neutered().toBase58()).toEqual(key.extended_public_key));
|
||||
|
||||
test(`private key`, () =>
|
||||
expect(child.privateKey).toEqual(
|
||||
Buffer.from(decodeCompressedWifPrivateKey(key.private_key))
|
||||
));
|
||||
|
||||
test(`extended private key`, () =>
|
||||
expect(child.privateKey).toEqual(bip32.fromBase58(key.extended_private_key).privateKey));
|
||||
|
||||
test(`segwit address`, () => {
|
||||
const bitcoinPayment = bitcoin.payments.p2sh({
|
||||
redeem: bitcoin.payments.p2wpkh({ pubkey: child.publicKey }),
|
||||
});
|
||||
expect(bitcoinPayment.address).toEqual(key.address);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe.each(keys)('@scure/*', key => {
|
||||
let seed: Uint8Array;
|
||||
let root: HDKey;
|
||||
let child: HDKey;
|
||||
|
||||
beforeAll(async () => {
|
||||
seed = await deriveBtcBip49SeedFromMnemonic(phrase);
|
||||
root = deriveRootBtcKeychain(seed);
|
||||
child = root.derive(key.path);
|
||||
});
|
||||
|
||||
describe(key.path, () => {
|
||||
test(`public key`, () =>
|
||||
expect(Buffer.from(child.publicKey!).toString('hex')).toEqual(key.public_key));
|
||||
|
||||
test(`extended public key`, () =>
|
||||
expect(child.publicExtendedKey).toEqual(key.extended_public_key));
|
||||
|
||||
test(`private key`, () =>
|
||||
expect(child.privateKey).toEqual(decodeCompressedWifPrivateKey(key.private_key)));
|
||||
|
||||
test(`extended private key`, () =>
|
||||
expect(child.privateKey).toEqual(
|
||||
HDKey.fromExtendedKey(key.extended_private_key).privateKey
|
||||
));
|
||||
|
||||
test(`extended private key`, () =>
|
||||
expect(child.privateExtendedKey).toEqual(key.extended_private_key));
|
||||
|
||||
test(`segwit address`, () => {
|
||||
expect(publicKeyToPayToScriptHashAddress(child.publicKey!, key.network)).toEqual(
|
||||
key.address
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Replicating test vector from BIP
|
||||
// https://en.bitcoin.it/wiki/BIP_0049
|
||||
test('BIP-0049 test vector', () => {
|
||||
const publicKey = Buffer.from(
|
||||
'03a1af804ac108a8a51782198c2d034b28bf90c8803f5a53f76276fa69a4eae77f',
|
||||
'hex'
|
||||
);
|
||||
const hash = makePayToScriptHashKeyHash(publicKey);
|
||||
|
||||
// stacks.js implementation
|
||||
const addressBytesFromStacks = hashP2WPKH(publicKey);
|
||||
expect(addressBytesFromStacks).toEqual('336caa13e08b96080a32b5d818d59b4ab3b36742');
|
||||
|
||||
// wallet implementation
|
||||
const addressBytes = makePayToScriptHashAddressBytes(hash);
|
||||
const addressBytesHex = Buffer.from(addressBytes).toString('hex');
|
||||
expect(addressBytesHex).toEqual('336caa13e08b96080a32b5d818d59b4ab3b36742');
|
||||
|
||||
// compare lib output
|
||||
expect(addressBytesFromStacks).toEqual(addressBytesHex);
|
||||
|
||||
const address = base58check(sha256).encode(
|
||||
Buffer.concat([
|
||||
Buffer.of(payToScriptHashTestnetPrefix),
|
||||
Buffer.from(addressBytesFromStacks, 'hex'),
|
||||
])
|
||||
);
|
||||
const addressWithLib = makePayToScriptHashAddress(addressBytes, 'testnet');
|
||||
|
||||
expect(address).toEqual(addressWithLib);
|
||||
|
||||
expect(addressWithLib).toEqual('2Mww8dCYPUpKHofjgcXcBCEGmniw9CoaiD2');
|
||||
});
|
||||
});
|
||||
78
src/shared/crypto/p2wsh-p2sh-address-gen.ts
Normal file
78
src/shared/crypto/p2wsh-p2sh-address-gen.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { ripemd160 } from '@noble/hashes/ripemd160';
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
import { base58check } from '@scure/base';
|
||||
import { HDKey } from '@scure/bip32';
|
||||
import { mnemonicToSeed } from '@scure/bip39';
|
||||
import * as bitcoin from 'bitcoinjs-lib';
|
||||
|
||||
export async function deriveBtcBip49SeedFromMnemonic(mnemonic: string) {
|
||||
return mnemonicToSeed(mnemonic);
|
||||
}
|
||||
|
||||
export function deriveRootBtcKeychain(seed: Uint8Array) {
|
||||
return HDKey.fromMasterSeed(seed);
|
||||
}
|
||||
|
||||
// ts-unused-exports:disable-next-line
|
||||
export async function deriveBtcPayment(
|
||||
publicKey: Uint8Array | Buffer,
|
||||
defaultNetwork: 'mainnet' | 'testnet' = 'mainnet'
|
||||
) {
|
||||
const pubkey = Buffer.isBuffer(publicKey) ? publicKey : Buffer.from(publicKey);
|
||||
const network = defaultNetwork === 'mainnet' ? undefined : bitcoin.networks.testnet;
|
||||
return bitcoin.payments.p2sh({
|
||||
redeem: bitcoin.payments.p2wpkh({
|
||||
pubkey,
|
||||
network,
|
||||
}),
|
||||
network,
|
||||
});
|
||||
}
|
||||
|
||||
export function decodeCompressedWifPrivateKey(key: string) {
|
||||
// https://en.bitcoinwiki.org/wiki/Wallet_import_format
|
||||
// Decode Compressed WIF format private key
|
||||
const compressedWifFormatPrivateKey = base58check(sha256).decode(key);
|
||||
// Drop leading network byte, trailing public key SEC format byte
|
||||
return compressedWifFormatPrivateKey.slice(1, compressedWifFormatPrivateKey.length - 1);
|
||||
}
|
||||
|
||||
type BitcoinNetwork = 'mainnet' | 'testnet';
|
||||
|
||||
// https://en.bitcoin.it/wiki/List_of_address_prefixes
|
||||
const payToScriptHashMainnetPrefix = 0x05;
|
||||
export const payToScriptHashTestnetPrefix = 0xc4;
|
||||
|
||||
const payToScriptHashPrefixMap: Record<BitcoinNetwork, number> = {
|
||||
mainnet: payToScriptHashMainnetPrefix,
|
||||
testnet: payToScriptHashTestnetPrefix,
|
||||
};
|
||||
|
||||
function hash160(input: Uint8Array) {
|
||||
return ripemd160(sha256(input));
|
||||
}
|
||||
|
||||
export function makePayToScriptHashKeyHash(publicKey: Uint8Array) {
|
||||
return hash160(publicKey);
|
||||
}
|
||||
|
||||
export function makePayToScriptHashAddressBytes(keyHash: Uint8Array) {
|
||||
const redeemScript = Uint8Array.from([
|
||||
...Uint8Array.of(0x00),
|
||||
...Uint8Array.of(keyHash.length),
|
||||
...keyHash,
|
||||
]);
|
||||
return hash160(redeemScript);
|
||||
}
|
||||
|
||||
export function makePayToScriptHashAddress(addressBytes: Uint8Array, network: BitcoinNetwork) {
|
||||
const networkByte = payToScriptHashPrefixMap[network];
|
||||
const addressWithPrefix = Uint8Array.from([networkByte, ...addressBytes]);
|
||||
return base58check(sha256).encode(addressWithPrefix);
|
||||
}
|
||||
|
||||
export function publicKeyToPayToScriptHashAddress(publicKey: Uint8Array, network: BitcoinNetwork) {
|
||||
const hash = makePayToScriptHashKeyHash(publicKey);
|
||||
const addrBytes = makePayToScriptHashAddressBytes(hash);
|
||||
return makePayToScriptHashAddress(addrBytes, network);
|
||||
}
|
||||
32
yarn.lock
32
yarn.lock
@@ -3238,12 +3238,12 @@
|
||||
resolved "https://registry.yarnpkg.com/@schemastore/web-manifest/-/web-manifest-0.0.5.tgz#97f0b1f14d095189c5672309e4975760278461b2"
|
||||
integrity sha512-3SF3OwzJ+PIqYDVW0MXoUAyypyx7N5RlYj2zek36qVuDUgoiI65q0ietwuxyVtbTRYJyP64KBGKvKqHzbIxdfA==
|
||||
|
||||
"@scure/base@~1.1.0":
|
||||
"@scure/base@1.1.1", "@scure/base@~1.1.0":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"
|
||||
integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==
|
||||
|
||||
"@scure/bip32@^1.1.1":
|
||||
"@scure/bip32@1.1.1", "@scure/bip32@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.1.tgz#f62e4a2f13cc3e5e720ad81b7582b8631ae6835a"
|
||||
integrity sha512-UmI+liY7np2XakaW+6lMB6HZnpczWk1yXZTxvg8TM8MdOcKHCGL1YkraGj8eAjPfMwFNiAyek2hXmS/XFbab8g==
|
||||
@@ -3252,7 +3252,7 @@
|
||||
"@noble/secp256k1" "~1.7.0"
|
||||
"@scure/base" "~1.1.0"
|
||||
|
||||
"@scure/bip39@^1.1.0":
|
||||
"@scure/bip39@1.1.0", "@scure/bip39@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.0.tgz#92f11d095bae025f166bef3defcc5bf4945d419a"
|
||||
integrity sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==
|
||||
@@ -7189,6 +7189,18 @@ bip174@^2.0.1:
|
||||
resolved "https://registry.yarnpkg.com/bip174/-/bip174-2.1.0.tgz#cd3402581feaa5116f0f00a0eaee87a5843a2d30"
|
||||
integrity sha512-lkc0XyiX9E9KiVAS1ZiOqK1xfiwvf4FXDDdkDq5crcDzOq+xGytY+14qCsqz7kCiy8rpN1CRNfacRhf9G3JNSA==
|
||||
|
||||
bip32@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/bip32/-/bip32-3.1.0.tgz#ce90e020d0e6b41e891a0122ff053efabcce1ccc"
|
||||
integrity sha512-eoeajYEzJ4d6yyVtby8C+XkCeKItiC4Mx56a0M9VaqTMC73SWOm4xVZG7SaR8e/yp4eSyky2XcBpH3DApPdu7Q==
|
||||
dependencies:
|
||||
bs58check "^2.1.1"
|
||||
create-hash "^1.2.0"
|
||||
create-hmac "^1.1.7"
|
||||
ripemd160 "^2.0.2"
|
||||
typeforce "^1.11.5"
|
||||
wif "^2.0.6"
|
||||
|
||||
bip32@^2.0.4:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.6.tgz#6a81d9f98c4cd57d05150c60d8f9e75121635134"
|
||||
@@ -15524,7 +15536,7 @@ ripemd160-min@^0.0.6:
|
||||
resolved "https://registry.yarnpkg.com/ripemd160-min/-/ripemd160-min-0.0.6.tgz#a904b77658114474d02503e819dcc55853b67e62"
|
||||
integrity sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A==
|
||||
|
||||
ripemd160@^2.0.0, ripemd160@^2.0.1:
|
||||
ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
|
||||
integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==
|
||||
@@ -16837,6 +16849,13 @@ tiny-hashes@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/tiny-hashes/-/tiny-hashes-1.0.1.tgz#ddbe9060312ddb4efe0a174bb3a27e1331c425a1"
|
||||
integrity sha512-knIN5zj4fl7kW4EBU5sLP20DWUvi/rVouvJezV0UAym2DkQaqm365Nyc8F3QEiOvunNDMxR8UhcXd1d5g+Wg1g==
|
||||
|
||||
tiny-secp256k1@2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-2.2.1.tgz#a61d4791b7031aa08a9453178a131349c3e10f9b"
|
||||
integrity sha512-/U4xfVqnVxJXN4YVsru0E6t5wVncu2uunB8+RVR40fYUxkKYUPS10f+ePQZgFBoE/Jbf9H1NBveupF2VmB58Ng==
|
||||
dependencies:
|
||||
uint8array-tools "0.0.7"
|
||||
|
||||
tiny-secp256k1@^1.1.1, tiny-secp256k1@^1.1.3:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz#7e224d2bee8ab8283f284e40e6b4acb74ffe047c"
|
||||
@@ -17160,6 +17179,11 @@ uid-number@0.0.6:
|
||||
resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
|
||||
integrity sha512-c461FXIljswCuscZn67xq9PpszkPT6RjheWFQTgCyabJrTUozElanb0YEqv2UGgk247YpcJkFBuSGNvBlpXM9w==
|
||||
|
||||
uint8array-tools@0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/uint8array-tools/-/uint8array-tools-0.0.7.tgz#a7a2bb5d8836eae2fade68c771454e6a438b390d"
|
||||
integrity sha512-vrrNZJiusLWoFWBqz5Y5KMCgP9W9hnjZHzZiZRT8oNAkq3d5Z5Oe76jAvVVSRh4U8GGR90N2X1dWtrhvx6L8UQ==
|
||||
|
||||
unbox-primitive@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
|
||||
|
||||
Reference in New Issue
Block a user