PageSourceSearch

https://cdn.swapkit.dev/widget/latest/index-C5yVRrBw.js

js swapkit.dev collected 2026-10-03 23:17:31 UTC 11,583 bytes, 306 lines download raw bytes

1import { s as secp256k1 } from './secp256k1-DAVU6K9A.js';
2import { cp as concatBytes, cq as abytes, cr as hmac, cs as sha512, ct as createView, cn as createBase58check, co as sha256 } from './wallet-keystore-BVM_ybiA.js';
3import { r as ripemd160 } from './legacy-BHpsF2A2.js';
4
5/**
6 * BIP32 hierarchical deterministic (HD) wallets over secp256k1.
7 * @module
8 * @example
9 * ```js
10 * import { HDKey } from "@scure/bip32";
11 * import { sha256 } from '@noble/hashes/sha2.js';
12 * import { randomBytes } from '@noble/hashes/utils.js';
13 * const seed = randomBytes(32);
14 * const root = HDKey.fromMasterSeed(seed);
15 * const base58key = root.privateExtendedKey;
16 * const restored = HDKey.fromExtendedKey(base58key);
17 * const fromJson = HDKey.fromJSON({ xpriv: base58key });
18 * const child = fromJson.derive("m/0/2147483647'/1");
19 * const msgHash = sha256(new TextEncoder().encode('hello scure-bip32'));
20 *
21 * // props
22 * [root.depth, root.index, root.chainCode];
23 * [restored.privateKey, restored.publicKey];
24 * const sig = child.sign(msgHash);
25 * child.verify(msgHash, sig);
26 * ```
27 */
28/*! scure-bip32 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) */
29const Point = /* @__PURE__ */ (() => secp256k1.Point)();
30const Fn = /* @__PURE__ */ (() => Point.Fn)();
31const base58check = /* @__PURE__ */ createBase58check(sha256);
32const MASTER_SECRET = /* @__PURE__ */ (() => {
33    return Uint8Array.from('Bitcoin seed'.split(''), (char) => char.charCodeAt(0));
34})();
35const BITCOIN_VERSIONS = { private: 0x0488ade4, public: 0x0488b21e };
36/** Hardened child index offset from BIP32. */
37const HARDENED_OFFSET = 0x80000000;
38const hash160 = (data) => ripemd160(sha256(data));
39const fromU32 = (data) => createView(data).getUint32(0, false);
40const toU32 = (n) => {
41    if (typeof n !== 'number')
42        throw new TypeError('invalid number, should be from 0 to 2**32-1, got ' + n);
43    if (!Number.isSafeInteger(n) || n < 0 || n > 2 ** 32 - 1)
44        throw new RangeError('invalid number, should be from 0 to 2**32-1, got ' + n);
45    const buf = new Uint8Array(4);
46    createView(buf).setUint32(0, n, false);
47    return buf;
48};
49/**
50 * HDKey from BIP32
51 * @param opt - Node fields used to construct one HDKey instance.
52 * @example
53 * ```js
54 * import { HDKey } from '@scure/bip32';
55 * import { randomBytes } from '@noble/hashes/utils.js';
56 *
57 * const seed = randomBytes(32);
58 * const root = HDKey.fromMasterSeed(seed);
59 * const account0 = root.derive("m/0/1'");
60 * account0.publicKey;
61 * ```
62 */
63class HDKey {
64    get fingerprint() {
65        if (!this.pubHash) {
66            throw new Error('No publicKey set!');
67        }
68        return fromU32(this.pubHash);
69    }
70    get identifier() {
71        return this.pubHash;
72    }
73    get pubKeyHash() {
74        return this.pubHash;
75    }
76    // Returns the live private key buffer for this instance.
77    // Copy it first if you need an immutable snapshot.
78    get privateKey() {
79        return this._privateKey || null;
80    }
81    get publicKey() {
82        return this._publicKey || null;
83    }
84    get privateExtendedKey() {
85        const priv = this._privateKey;
86        if (!priv) {
87            throw new Error('No private key');
88        }
89        return base58check.encode(this.serialize(this.versions.private, concatBytes(Uint8Array.of(0), priv)));
90    }
91    get publicExtendedKey() {
92        if (!this._publicKey) {
93            throw new Error('No public key');
94        }
95        return base58check.encode(this.serialize(this.versions.public, this._publicKey));
96    }
97    static fromMasterSeed(seed, versions = BITCOIN_VERSIONS) {
98        abytes(seed);
99        if (8 * seed.length < 128 || 8 * seed.length > 512) {
100            throw new RangeError('HDKey: seed length must be between 128 and 512 bits; 256 bits is advised, got ' +
101                seed.length);
102        }
103        const I = hmac(sha512, MASTER_SECRET, seed);
104        const privateKey = I.slice(0, 32);
105        const chainCode = I.slice(32);
106        return new HDKey({ versions, chainCode, privateKey });
107    }
108    static fromExtendedKey(base58key, versions = BITCOIN_VERSIONS) {
109        // => version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
110        const keyBuffer = base58check.decode(base58key);
111        const keyView = createView(keyBuffer);
112        const version = keyView.getUint32(0, false);
113        const opt = {
114            versions,
115            depth: keyBuffer[4],
116            parentFingerprint: keyView.getUint32(5, false),
117            index: keyView.getUint32(9, false),
118            chainCode: keyBuffer.slice(13, 45),
119        };
120        const key = keyBuffer.slice(45);
121        const isPriv = key[0] === 0;
122        if (version !== versions[isPriv ? 'private' : 'public']) {
123            throw new Error('Version mismatch');
124        }
125        if (isPriv) {
126            return new HDKey({ ...opt, privateKey: key.slice(1) });
127        }
128        else {
129            return new HDKey({ ...opt, publicKey: key });
130        }
131    }
132    static fromJSON(json) {
133        return HDKey.fromExtendedKey(json.xpriv);
134    }
135    versions;
136    depth = 0;
137    index = 0;
138    chainCode = null;
139    parentFingerprint = 0;
140    _privateKey;
141    _publicKey;
142    pubHash;
143    constructor(opt) {
144        if (!opt || typeof opt !== 'object') {
145            throw new Error('HDKey.constructor must not be called directly');
146        }
147        this.versions = opt.versions || BITCOIN_VERSIONS;
148        this.depth = opt.depth || 0;
149        this.chainCode = opt.chainCode ? Uint8Array.from(opt.chainCode) : null;
150        this.index = opt.index || 0;
151        this.parentFingerprint = opt.parentFingerprint || 0;
152        if (!this.depth) {
153            if (this.parentFingerprint || this.index) {
154                throw new Error('HDKey: zero depth with non-zero index/parent fingerprint');
155            }
156        }
157        if (this.depth > 255) {
158            throw new Error('HDKey: depth exceeds the serializable value 255');
159        }
160        if (opt.publicKey && opt.privateKey) {
161            throw new Error('HDKey: publicKey and privateKey at same time.');
162        }
163        if (opt.privateKey) {
164            if (!secp256k1.utils.isValidSecretKey(opt.privateKey))
165                throw new Error('Invalid private key');
166            // Don't alias caller-owned secret buffers.
167            this._privateKey = Uint8Array.from(opt.privateKey);
168            this._publicKey = secp256k1.getPublicKey(this._privateKey, true);
169        }
170        else if (opt.publicKey) {
171            this._publicKey = Point.fromBytes(opt.publicKey).toBytes(true); // force compressed point
172        }
173        else {
174            throw new Error('HDKey: no public or private key provided');
175        }
176        this.pubHash = hash160(this._publicKey);
177    }
178    derive(path) {
179        if (!/^[mM]'?/.test(path)) {
180            throw new Error('Path must start with "m" or "M"');
181        }
182        if (/^[mM]'?$/.test(path)) {
183            return this;
184        }
185        const parts = path.replace(/^[mM]'?\//, '').split('/');
186        // tslint:disable-next-line
187        let child = this;
188        for (const c of parts) {
189            const m = /^(\d+)('?)$/.exec(c);
190            const m1 = m && m[1];
191            if (!m || m.length !== 3 || typeof m1 !== 'string')
192                throw new Error('invalid child index: ' + c);
193            let idx = +m1;
194            if (!Number.isSafeInteger(idx) || idx >= HARDENED_OFFSET) {
195                throw new Error('Invalid index');
196            }
197            // hardened key
198            if (m[2] === "'") {
199                idx += HARDENED_OFFSET;
200            }
201            child = child.deriveChild(idx);
202        }
203        return child;
204    }
205    /**
206     * @param _I - Test-only override for the 64-byte HMAC-SHA512 output; normal callers must omit it.
207     */
208    deriveChild(index, _I) {
209        if (!this._publicKey || !this.chainCode) {
210            throw new Error('No publicKey or chainCode set');
211        }
212        let data = toU32(index);
213        if (index >= HARDENED_OFFSET) {
214            // Hardened
215            const priv = this._privateKey;
216            if (!priv) {
217                throw new Error('Could not derive hardened child key');
218            }
219            // Hardened child: 0x00 || ser256(kpar) || ser32(index)
220            data = concatBytes(Uint8Array.of(0), priv, data);
221        }
222        else {
223            // Normal child: serP(point(kpar)) || ser32(index)
224            data = concatBytes(this._publicKey, data);
225        }
226        const out = _I || hmac(sha512, this.chainCode, data);
227        abytes(out, 64);
228        const childTweak = out.slice(0, 32);
229        const chainCode = out.slice(32);
230        const opt = {
231            versions: this.versions,
232            chainCode,
233            depth: this.depth + 1,
234            parentFingerprint: this.fingerprint,
235            index,
236        };
237        // Fail early instead of re-trying different index
238        if (opt.depth > 255) {
239            throw new Error('HDKey: depth exceeds the serializable value 255');
240        }
241        try {
242            const ctweak = Fn.fromBytes(childTweak);
243            // BIP-32 private derivation retries only when parse256(I_L) >= n or k_i = 0.
244            // BIP-32 public derivation retries only when parse256(I_L) >= n or K_i is infinity.
245            // So I_L = 0 is valid here; Fn.fromBytes still rejects parse256(I_L) >= n.
246            if (this._privateKey) {
247                const added = Fn.create(Fn.fromBytes(this._privateKey) + ctweak);
248                if (!Fn.isValidNot0(added)) {
249                    throw new Error('The tweak was out of range or the resulted private key is invali
249d');
250                }
251                opt.privateKey = Fn.toBytes(added);
252            }
253            else {
254                const point = Point.fromBytes(this._publicKey);
255                const added = ctweak === 0n ? point : point.add(Point.BASE.multiply(ctweak));
256                // Cryptographically impossible: hmac-sha512 preimage would need to be found
257                if (added.equals(Point.ZERO)) {
258                    throw new Error('The tweak was equal to negative P, which made the result key invalid');
259                }
260                opt.publicKey = added.toBytes(true);
261            }
262            return new HDKey(opt);
263        }
264        catch (err) {
265            return this.deriveChild(index + 1);
266        }
267    }
268    sign(hash) {
269        if (!this._privateKey) {
270            throw new Error('No privateKey set!');
271        }
272        abytes(hash, 32);
273        return secp256k1.sign(hash, this._privateKey, { prehash: false });
274    }
275    verify(hash, signature) {
276        abytes(hash, 32);
277        abytes(signature, 64);
278        if (!this._publicKey) {
279            throw new Error('No publicKey set!');
280        }
281        return secp256k1.verify(signature, hash, this._publicKey, { prehash: false });
282    }
283    wipePrivateData() {
284        if (this._privateKey) {
285            this._privateKey.fill(0);
286            this._privateKey = undefined;
287        }
288        return this;
289    }
290    toJSON() {
291        return {
292            xpriv: this.privateExtendedKey,
293            xpub: this.publicExtendedKey,
294        };
295    }
296    serialize(version, key) {
297        if (!this.chainCode) {
298            throw new Error('No chainCode set');
299        }
300        abytes(key, 33);
301        // version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
302        return concatBytes(toU32(version), new Uint8Array([this.depth]), toU32(this.parentFingerprint), toU32(this.index), this.chainCode, key);
303    }
304}
305
306export { HARDENED_OFFSET, HDKey };

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.