feat: initialize markr nostr bookmark client

- Add project structure with TypeScript, React, and Vite
- Implement nostr authentication using browser extension (NIP-07)
- Add NIP-51 compliant bookmark fetching and display
- Create minimal UI with login and bookmark components
- Integrate applesauce-core and applesauce-react libraries
- Add responsive styling with dark/light mode support
- Include comprehensive README with setup instructions

This is a minimal MVP for a nostr bookmark client that allows users to
view their bookmarks according to NIP-51 specification.
This commit is contained in:
Gigi
2025-10-02 07:17:07 +02:00
commit 5d53a827e0
11194 changed files with 1827829 additions and 0 deletions

21
node_modules/@scure/base/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2022 Paul Miller (https://paulmillr.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

228
node_modules/@scure/base/README.md generated vendored Normal file
View File

@@ -0,0 +1,228 @@
# scure-base
Audited & minimal implementation of bech32, base64, base58, base32 & base16.
- 🔒 [Audited](#security) by an independent security firm
- 🔻 Tree-shakeable: unused code is excluded from your builds
- 📦 ESM and common.js
- ✍️ Written in [functional style](#design-rationale), easily composable
- 💼 Matches specs
- [BIP173](https://en.bitcoin.it/wiki/BIP_0173), [BIP350](https://en.bitcoin.it/wiki/BIP_0350) for bech32 / bech32m
- [RFC 4648](https://datatracker.ietf.org/doc/html/rfc4648) (aka RFC 3548) for Base16, Base32, Base32Hex, Base64, Base64Url
- [Base58](https://www.ietf.org/archive/id/draft-msporny-base58-03.txt),
[Base58check](https://en.bitcoin.it/wiki/Base58Check_encoding),
[Base32 Crockford](https://www.crockford.com/base32.html)
- 🪶 4KB gzipped
Check out [Projects using scure-base](#projects-using-scure-base).
### This library belongs to _scure_
> **scure** — audited micro-libraries.
- Zero or minimal dependencies
- Highly readable TypeScript / JS code
- PGP-signed releases and transparent NPM builds
- Check out [homepage](https://paulmillr.com/noble/#scure) & all libraries:
[base](https://github.com/paulmillr/scure-base),
[bip32](https://github.com/paulmillr/scure-bip32),
[bip39](https://github.com/paulmillr/scure-bip39),
[btc-signer](https://github.com/paulmillr/scure-btc-signer),
[starknet](https://github.com/paulmillr/scure-starknet)
## Usage
> `npm install @scure/base`
> `deno add jsr:@scure/base`
> `deno doc jsr:@scure/base` # command-line documentation
We support all major platforms and runtimes. The library is hybrid ESM / Common.js package.
```js
import { base16, base32, base64, base58 } from '@scure/base';
// Flavors
import {
base58xmr,
base58xrp,
base32nopad,
base32hex,
base32hexnopad,
base32crockford,
base64nopad,
base64url,
base64urlnopad,
} from '@scure/base';
const data = Uint8Array.from([1, 2, 3]);
base64.decode(base64.encode(data));
// Convert utf8 string to Uint8Array
const data2 = new TextEncoder().encode('hello');
base58.encode(data2);
// Everything has the same API except for bech32 and base58check
base32.encode(data);
base16.encode(data);
base32hex.encode(data);
```
base58check is a special case: you need to pass `sha256()` function:
```js
import { createBase58check } from '@scure/base';
createBase58check(sha256).encode(data);
```
## Bech32, Bech32m and Bitcoin
We provide low-level bech32 operations.
If you need high-level methods for BTC (addresses, and others), use
[scure-btc-signer](https://github.com/paulmillr/scure-btc-signer) instead.
Bitcoin addresses use both 5-bit words and bytes representations.
They can't be parsed using `bech32.decodeToBytes`.
Same applies to Lightning Invoice Protocol
[BOLT-11](https://github.com/lightning/bolts/blob/master/11-payment-encoding.md).
We have many tests in `./test/bip173.test.js` that serve as minimal examples of
Bitcoin address and Lightning Invoice Protocol parsers.
Keep in mind that you'll need to verify the examples before using them in your code.
Do something like this:
```ts
const decoded = bech32.decode(address);
// NOTE: words in bitcoin addresses contain version as first element,
// with actual witness program words in rest
// BIP-141: The value of the first push is called the "version byte".
// The following byte vector pushed is called the "witness program".
const [version, ...dataW] = decoded.words;
const program = bech32.fromWords(dataW); // actual witness program
```
## Design rationale
The code may feel unnecessarily complicated; but actually it's much easier to reason about.
Any encoding library consists of two functions:
```
encode(A) -> B
decode(B) -> A
where X = decode(encode(X))
# encode(decode(X)) can be !== X!
# because decoding can normalize input
e.g.
base58checksum = {
encode(): {
// checksum
// radix conversion
// alphabet
},
decode(): {
// alphabet
// radix conversion
// checksum
}
}
```
But instead of creating two big functions for each specific case,
we create them from tiny composable building blocks:
```
base58checksum = chain(checksum(), radix(), alphabet())
```
Which is the same as chain/pipe/sequence function in Functional Programming,
but significantly more useful since it enforces same order of execution of encode/decode.
Basically you only define encode (in declarative way) and get correct decode for free.
So, instead of reasoning about two big functions you need only reason about primitives and encode chain.
The design revealed obvious bug in older version of the lib,
where xmr version of base58 had errors in decode's block processing.
Besides base-encodings, we can reuse the same approach with any encode/decode function
(`bytes2number`, `bytes2u32`, etc).
For example, you can easily encode entropy to mnemonic (BIP-39):
```ts
export function getCoder(wordlist: string[]) {
if (!Array.isArray(wordlist) || wordlist.length !== 2 ** 11 || typeof wordlist[0] !== 'string') {
throw new Error('Wordlist: expected array of 2048 strings');
}
return mbc.chain(mbu.checksum(1, checksum), mbu.radix2(11, true), mbu.alphabet(wordlist));
}
```
### base58 is O(n^2) and radixes
`Uint8Array` is represented as big-endian number:
```
[1, 2, 3, 4, 5] -> 1*(256**4) + 2*(256**3) 3*(256**2) + 4*(256**1) + 5*(256**0)
where 256 = 2**8 (8 bits per byte)
```
which is then converted to a number in another radix/base (16/32/58/64, etc).
However, generic conversion between bases has [quadratic O(n^2) time complexity](https://cs.stackexchange.com/q/21799).
Which means base58 has quadratic time complexity too. Use base58 only when you have small
constant sized input, because variable length sized input from user can cause DoS.
On the other hand, if both bases are power of same number (like `2**8 <-> 2**64`),
there is linear algorithm. For now we have implementation for power-of-two bases only (radix2).
## Security
The library has been independently audited:
- at version 1.0.0, in Jan 2022, by [cure53](https://cure53.de)
- PDFs: [online](https://cure53.de/pentest-report_hashing-libs.pdf), [offline](./audit/2022-01-05-cure53-audit-nbl2.pdf)
- [Changes since audit](https://github.com/paulmillr/scure-base/compare/1.0.0..main).
- The audit has been funded by [Ethereum Foundation](https://ethereum.org/en/) with help of [Nomic Labs](https://nomiclabs.io)
The library was initially developed for [js-ethereum-cryptography](https://github.com/ethereum/js-ethereum-cryptography).
At commit [ae00e6d7](https://github.com/ethereum/js-ethereum-cryptography/commit/ae00e6d7d24fb3c76a1c7fe10039f6ecd120b77e),
it was extracted to a separate package called `micro-base`.
After the audit we've decided to use `@scure` NPM namespace for security.
### Supply chain security
- **Commits** are signed with PGP keys, to prevent forgery. Make sure to verify commit signatures
- **Releases** are transparent and built on GitHub CI. Make sure to verify [provenance](https://docs.npmjs.com/generating-provenance-statements) logs
- Use GitHub CLI to verify single-file builds:
`gh attestation verify --owner paulmillr scure-base.js`
- **Rare releasing** is followed to ensure less re-audit need for end-users
- **Dependencies** are minimized and locked-down: any dependency could get hacked and users will be downloading malware with every install.
- We make sure to use as few dependencies as possible
- Automatic dep updates are prevented by locking-down version ranges; diffs are checked with `npm-diff`
- **Dev Dependencies** are disabled for end-users; they are only used to develop / build the source code
For this package, there are 0 dependencies; and a few dev dependencies:
- micro-bmark, micro-should and jsbt are used for benchmarking / testing / build tooling and developed by the same author
- prettier, fast-check and typescript are used for code quality / test generation / ts compilation. It's hard to audit their source code thoroughly and fully because of their size
## Contributing & testing
- `npm install && npm run build && npm test` will build the code and run tests.
- `npm run lint` / `npm run format` will run linter / fix linter issues.
- `npm run build:release` will build single file
### Projects using scure-base
- [scure-btc-signer](https://github.com/paulmillr/scure-btc-signer)
- [prefixed-api-key](https://github.com/truestamp/prefixed-api-key)
- [coinspace](https://github.com/CoinSpace/CoinSpace) wallet and its modules:
[ada](https://github.com/CoinSpace/cs-cardano-wallet),
[btc](https://github.com/CoinSpace/cs-bitcoin-wallet)
[eos](https://github.com/CoinSpace/cs-eos-wallet),
[sol](https://github.com/CoinSpace/cs-solana-wallet),
[xmr](https://github.com/CoinSpace/cs-monero-wallet)
## License
MIT (c) Paul Miller [(https://paulmillr.com)](https://paulmillr.com), see LICENSE file.

861
node_modules/@scure/base/index.ts generated vendored Normal file
View File

@@ -0,0 +1,861 @@
/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
export interface Coder<F, T> {
encode(from: F): T;
decode(to: T): F;
}
export interface BytesCoder extends Coder<Uint8Array, string> {
encode: (data: Uint8Array) => string;
decode: (str: string) => Uint8Array;
}
function isBytes(a: unknown): a is Uint8Array {
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
}
/** Asserts something is Uint8Array. */
function abytes(b: Uint8Array | undefined, ...lengths: number[]): void {
if (!isBytes(b)) throw new Error('Uint8Array expected');
if (lengths.length > 0 && !lengths.includes(b.length))
throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
}
function isArrayOf(isString: boolean, arr: any[]) {
if (!Array.isArray(arr)) return false;
if (arr.length === 0) return true;
if (isString) {
return arr.every((item) => typeof item === 'string');
} else {
return arr.every((item) => Number.isSafeInteger(item));
}
}
// no abytes: seems to have 10% slowdown. Why?!
function afn(input: Function): input is Function {
if (typeof input !== 'function') throw new Error('function expected');
return true;
}
function astr(label: string, input: unknown): input is string {
if (typeof input !== 'string') throw new Error(`${label}: string expected`);
return true;
}
function anumber(n: number): void {
if (!Number.isSafeInteger(n)) throw new Error(`invalid integer: ${n}`);
}
function aArr(input: any[]) {
if (!Array.isArray(input)) throw new Error('array expected');
}
function astrArr(label: string, input: string[]) {
if (!isArrayOf(true, input)) throw new Error(`${label}: array of strings expected`);
}
function anumArr(label: string, input: number[]) {
if (!isArrayOf(false, input)) throw new Error(`${label}: array of numbers expected`);
}
// TODO: some recusive type inference so it would check correct order of input/output inside rest?
// like <string, number>, <number, bytes>, <bytes, float>
type Chain = [Coder<any, any>, ...Coder<any, any>[]];
// Extract info from Coder type
type Input<F> = F extends Coder<infer T, any> ? T : never;
type Output<F> = F extends Coder<any, infer T> ? T : never;
// Generic function for arrays
type First<T> = T extends [infer U, ...any[]] ? U : never;
type Last<T> = T extends [...any[], infer U] ? U : never;
type Tail<T> = T extends [any, ...infer U] ? U : never;
type AsChain<C extends Chain, Rest = Tail<C>> = {
// C[K] = Coder<Input<C[K]>, Input<Rest[k]>>
[K in keyof C]: Coder<Input<C[K]>, Input<K extends keyof Rest ? Rest[K] : any>>;
};
/**
* @__NO_SIDE_EFFECTS__
*/
function chain<T extends Chain & AsChain<T>>(...args: T): Coder<Input<First<T>>, Output<Last<T>>> {
const id = (a: any) => a;
// Wrap call in closure so JIT can inline calls
const wrap = (a: any, b: any) => (c: any) => a(b(c));
// Construct chain of args[-1].encode(args[-2].encode([...]))
const encode = args.map((x) => x.encode).reduceRight(wrap, id);
// Construct chain of args[0].decode(args[1].decode(...))
const decode = args.map((x) => x.decode).reduce(wrap, id);
return { encode, decode };
}
/**
* Encodes integer radix representation to array of strings using alphabet and back.
* Could also be array of strings.
* @__NO_SIDE_EFFECTS__
*/
function alphabet(letters: string | string[]): Coder<number[], string[]> {
// mapping 1 to "b"
const lettersA = typeof letters === 'string' ? letters.split('') : letters;
const len = lettersA.length;
astrArr('alphabet', lettersA);
// mapping "b" to 1
const indexes = new Map(lettersA.map((l, i) => [l, i]));
return {
encode: (digits: number[]) => {
aArr(digits);
return digits.map((i) => {
if (!Number.isSafeInteger(i) || i < 0 || i >= len)
throw new Error(
`alphabet.encode: digit index outside alphabet "${i}". Allowed: ${letters}`
);
return lettersA[i]!;
});
},
decode: (input: string[]): number[] => {
aArr(input);
return input.map((letter) => {
astr('alphabet.decode', letter);
const i = indexes.get(letter);
if (i === undefined) throw new Error(`Unknown letter: "${letter}". Allowed: ${letters}`);
return i;
});
},
};
}
/**
* @__NO_SIDE_EFFECTS__
*/
function join(separator = ''): Coder<string[], string> {
astr('join', separator);
return {
encode: (from) => {
astrArr('join.decode', from);
return from.join(separator);
},
decode: (to) => {
astr('join.decode', to);
return to.split(separator);
},
};
}
/**
* Pad strings array so it has integer number of bits
* @__NO_SIDE_EFFECTS__
*/
function padding(bits: number, chr = '='): Coder<string[], string[]> {
anumber(bits);
astr('padding', chr);
return {
encode(data: string[]): string[] {
astrArr('padding.encode', data);
while ((data.length * bits) % 8) data.push(chr);
return data;
},
decode(input: string[]): string[] {
astrArr('padding.decode', input);
let end = input.length;
if ((end * bits) % 8)
throw new Error('padding: invalid, string should have whole number of bytes');
for (; end > 0 && input[end - 1] === chr; end--) {
const last = end - 1;
const byte = last * bits;
if (byte % 8 === 0) throw new Error('padding: invalid, string has too much padding');
}
return input.slice(0, end);
},
};
}
/**
* @__NO_SIDE_EFFECTS__
*/
function normalize<T>(fn: (val: T) => T): Coder<T, T> {
afn(fn);
return { encode: (from: T) => from, decode: (to: T) => fn(to) };
}
/**
* Slow: O(n^2) time complexity
*/
function convertRadix(data: number[], from: number, to: number): number[] {
// base 1 is impossible
if (from < 2) throw new Error(`convertRadix: invalid from=${from}, base cannot be less than 2`);
if (to < 2) throw new Error(`convertRadix: invalid to=${to}, base cannot be less than 2`);
aArr(data);
if (!data.length) return [];
let pos = 0;
const res = [];
const digits = Array.from(data, (d) => {
anumber(d);
if (d < 0 || d >= from) throw new Error(`invalid integer: ${d}`);
return d;
});
const dlen = digits.length;
while (true) {
let carry = 0;
let done = true;
for (let i = pos; i < dlen; i++) {
const digit = digits[i]!;
const fromCarry = from * carry;
const digitBase = fromCarry + digit;
if (
!Number.isSafeInteger(digitBase) ||
fromCarry / from !== carry ||
digitBase - digit !== fromCarry
) {
throw new Error('convertRadix: carry overflow');
}
const div = digitBase / to;
carry = digitBase % to;
const rounded = Math.floor(div);
digits[i] = rounded;
if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)
throw new Error('convertRadix: carry overflow');
if (!done) continue;
else if (!rounded) pos = i;
else done = false;
}
res.push(carry);
if (done) break;
}
for (let i = 0; i < data.length - 1 && data[i] === 0; i++) res.push(0);
return res.reverse();
}
const gcd = (a: number, b: number): number => (b === 0 ? a : gcd(b, a % b));
const radix2carry = /* @__NO_SIDE_EFFECTS__ */ (from: number, to: number) =>
from + (to - gcd(from, to));
const powers: number[] = /* @__PURE__ */ (() => {
let res = [];
for (let i = 0; i < 40; i++) res.push(2 ** i);
return res;
})();
/**
* Implemented with numbers, because BigInt is 5x slower
*/
function convertRadix2(data: number[], from: number, to: number, padding: boolean): number[] {
aArr(data);
if (from <= 0 || from > 32) throw new Error(`convertRadix2: wrong from=${from}`);
if (to <= 0 || to > 32) throw new Error(`convertRadix2: wrong to=${to}`);
if (radix2carry(from, to) > 32) {
throw new Error(
`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`
);
}
let carry = 0;
let pos = 0; // bitwise position in current element
const max = powers[from]!;
const mask = powers[to]! - 1;
const res: number[] = [];
for (const n of data) {
anumber(n);
if (n >= max) throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
carry = (carry << from) | n;
if (pos + from > 32) throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
pos += from;
for (; pos >= to; pos -= to) res.push(((carry >> (pos - to)) & mask) >>> 0);
const pow = powers[pos];
if (pow === undefined) throw new Error('invalid carry');
carry &= pow - 1; // clean carry, otherwise it will cause overflow
}
carry = (carry << (to - pos)) & mask;
if (!padding && pos >= from) throw new Error('Excess padding');
if (!padding && carry > 0) throw new Error(`Non-zero padding: ${carry}`);
if (padding && pos > 0) res.push(carry >>> 0);
return res;
}
/**
* @__NO_SIDE_EFFECTS__
*/
function radix(num: number): Coder<Uint8Array, number[]> {
anumber(num);
const _256 = 2 ** 8;
return {
encode: (bytes: Uint8Array) => {
if (!isBytes(bytes)) throw new Error('radix.encode input should be Uint8Array');
return convertRadix(Array.from(bytes), _256, num);
},
decode: (digits: number[]) => {
anumArr('radix.decode', digits);
return Uint8Array.from(convertRadix(digits, num, _256));
},
};
}
/**
* If both bases are power of same number (like `2**8 <-> 2**64`),
* there is a linear algorithm. For now we have implementation for power-of-two bases only.
* @__NO_SIDE_EFFECTS__
*/
function radix2(bits: number, revPadding = false): Coder<Uint8Array, number[]> {
anumber(bits);
if (bits <= 0 || bits > 32) throw new Error('radix2: bits should be in (0..32]');
if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)
throw new Error('radix2: carry overflow');
return {
encode: (bytes: Uint8Array) => {
if (!isBytes(bytes)) throw new Error('radix2.encode input should be Uint8Array');
return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
},
decode: (digits: number[]) => {
anumArr('radix2.decode', digits);
return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
},
};
}
type ArgumentTypes<F extends Function> = F extends (...args: infer A) => any ? A : never;
function unsafeWrapper<T extends (...args: any) => any>(fn: T) {
afn(fn);
return function (...args: ArgumentTypes<T>): ReturnType<T> | void {
try {
return fn.apply(null, args);
} catch (e) {}
};
}
function checksum(
len: number,
fn: (data: Uint8Array) => Uint8Array
): Coder<Uint8Array, Uint8Array> {
anumber(len);
afn(fn);
return {
encode(data: Uint8Array) {
if (!isBytes(data)) throw new Error('checksum.encode: input should be Uint8Array');
const sum = fn(data).slice(0, len);
const res = new Uint8Array(data.length + len);
res.set(data);
res.set(sum, data.length);
return res;
},
decode(data: Uint8Array) {
if (!isBytes(data)) throw new Error('checksum.decode: input should be Uint8Array');
const payload = data.slice(0, -len);
const oldChecksum = data.slice(-len);
const newChecksum = fn(payload).slice(0, len);
for (let i = 0; i < len; i++)
if (newChecksum[i] !== oldChecksum[i]) throw new Error('Invalid checksum');
return payload;
},
};
}
// prettier-ignore
export const utils: { alphabet: typeof alphabet; chain: typeof chain; checksum: typeof checksum; convertRadix: typeof convertRadix; convertRadix2: typeof convertRadix2; radix: typeof radix; radix2: typeof radix2; join: typeof join; padding: typeof padding; } = {
alphabet, chain, checksum, convertRadix, convertRadix2, radix, radix2, join, padding,
};
// RFC 4648 aka RFC 3548
// ---------------------
/**
* base16 encoding from RFC 4648.
* @example
* ```js
* base16.encode(Uint8Array.from([0x12, 0xab]));
* // => '12AB'
* ```
*/
export const base16: BytesCoder = chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));
/**
* base32 encoding from RFC 4648. Has padding.
* Use `base32nopad` for unpadded version.
* Also check out `base32hex`, `base32hexnopad`, `base32crockford`.
* @example
* ```js
* base32.encode(Uint8Array.from([0x12, 0xab]));
* // => 'CKVQ===='
* base32.decode('CKVQ====');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export const base32: BytesCoder = chain(
radix2(5),
alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'),
padding(5),
join('')
);
/**
* base32 encoding from RFC 4648. No padding.
* Use `base32` for padded version.
* Also check out `base32hex`, `base32hexnopad`, `base32crockford`.
* @example
* ```js
* base32nopad.encode(Uint8Array.from([0x12, 0xab]));
* // => 'CKVQ'
* base32nopad.decode('CKVQ');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export const base32nopad: BytesCoder = chain(
radix2(5),
alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'),
join('')
);
/**
* base32 encoding from RFC 4648. Padded. Compared to ordinary `base32`, slightly different alphabet.
* Use `base32hexnopad` for unpadded version.
* @example
* ```js
* base32hex.encode(Uint8Array.from([0x12, 0xab]));
* // => '2ALG===='
* base32hex.decode('2ALG====');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export const base32hex: BytesCoder = chain(
radix2(5),
alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'),
padding(5),
join('')
);
/**
* base32 encoding from RFC 4648. No padding. Compared to ordinary `base32`, slightly different alphabet.
* Use `base32hex` for padded version.
* @example
* ```js
* base32hexnopad.encode(Uint8Array.from([0x12, 0xab]));
* // => '2ALG'
* base32hexnopad.decode('2ALG');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export const base32hexnopad: BytesCoder = chain(
radix2(5),
alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'),
join('')
);
/**
* base32 encoding from RFC 4648. Doug Crockford's version.
* https://www.crockford.com/base32.html
* @example
* ```js
* base32crockford.encode(Uint8Array.from([0x12, 0xab]));
* // => '2ANG'
* base32crockford.decode('2ANG');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export const base32crockford: BytesCoder = chain(
radix2(5),
alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'),
join(''),
normalize((s: string) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1'))
);
// Built-in base64 conversion https://caniuse.com/mdn-javascript_builtins_uint8array_frombase64
// prettier-ignore
const hasBase64Builtin: boolean = /* @__PURE__ */ (() =>
typeof (Uint8Array as any).from([]).toBase64 === 'function' &&
typeof (Uint8Array as any).fromBase64 === 'function')();
const decodeBase64Builtin = (s: string, isUrl: boolean) => {
astr('base64', s);
const re = isUrl ? /^[A-Za-z0-9=_-]+$/ : /^[A-Za-z0-9=+/]+$/;
const alphabet = isUrl ? 'base64url' : 'base64';
if (s.length > 0 && !re.test(s)) throw new Error('invalid base64');
return (Uint8Array as any).fromBase64(s, { alphabet, lastChunkHandling: 'strict' });
};
/**
* base64 from RFC 4648. Padded.
* Use `base64nopad` for unpadded version.
* Also check out `base64url`, `base64urlnopad`.
* Falls back to built-in function, when available.
* @example
* ```js
* base64.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs='
* base64.decode('Eqs=');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
// prettier-ignore
export const base64: BytesCoder = hasBase64Builtin ? {
encode(b) { abytes(b); return (b as any).toBase64(); },
decode(s) { return decodeBase64Builtin(s, false); },
} : chain(
radix2(6),
alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'),
padding(6),
join('')
);
/**
* base64 from RFC 4648. No padding.
* Use `base64` for padded version.
* @example
* ```js
* base64nopad.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs'
* base64nopad.decode('Eqs');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export const base64nopad: BytesCoder = chain(
radix2(6),
alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'),
join('')
);
/**
* base64 from RFC 4648, using URL-safe alphabet. Padded.
* Use `base64urlnopad` for unpadded version.
* Falls back to built-in function, when available.
* @example
* ```js
* base64url.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs='
* base64url.decode('Eqs=');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
// prettier-ignore
export const base64url: BytesCoder = hasBase64Builtin ? {
encode(b) { abytes(b); return (b as any).toBase64({ alphabet: 'base64url' }); },
decode(s) { return decodeBase64Builtin(s, true); },
} : chain(
radix2(6),
alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'),
padding(6),
join('')
);
/**
* base64 from RFC 4648, using URL-safe alphabet. No padding.
* Use `base64url` for padded version.
* @example
* ```js
* base64urlnopad.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs'
* base64urlnopad.decode('Eqs');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export const base64urlnopad: BytesCoder = chain(
radix2(6),
alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'),
join('')
);
// base58 code
// -----------
const genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc: string) =>
chain(radix(58), alphabet(abc), join(''));
/**
* base58: base64 without ambigous characters +, /, 0, O, I, l.
* Quadratic (O(n^2)) - so, can't be used on large inputs.
* @example
* ```js
* base58.decode('01abcdef');
* // => '3UhJW'
* ```
*/
export const base58: BytesCoder = genBase58(
'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
);
/**
* base58: flickr version. Check out `base58`.
*/
export const base58flickr: BytesCoder = genBase58(
'123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'
);
/**
* base58: XRP version. Check out `base58`.
*/
export const base58xrp: BytesCoder = genBase58(
'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz'
);
// Data len (index) -> encoded block len
const XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];
/**
* base58: XMR version. Check out `base58`.
* Done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.
* Block encoding significantly reduces quadratic complexity of base58.
*/
export const base58xmr: BytesCoder = {
encode(data: Uint8Array) {
let res = '';
for (let i = 0; i < data.length; i += 8) {
const block = data.subarray(i, i + 8);
res += base58.encode(block).padStart(XMR_BLOCK_LEN[block.length]!, '1');
}
return res;
},
decode(str: string) {
let res: number[] = [];
for (let i = 0; i < str.length; i += 11) {
const slice = str.slice(i, i + 11);
const blockLen = XMR_BLOCK_LEN.indexOf(slice.length);
const block = base58.decode(slice);
for (let j = 0; j < block.length - blockLen; j++) {
if (block[j] !== 0) throw new Error('base58xmr: wrong padding');
}
res = res.concat(Array.from(block.slice(block.length - blockLen)));
}
return Uint8Array.from(res);
},
};
/**
* Method, which creates base58check encoder.
* Requires function, calculating sha256.
*/
export const createBase58check = (sha256: (data: Uint8Array) => Uint8Array): BytesCoder =>
chain(
checksum(4, (data) => sha256(sha256(data))),
base58
);
/**
* Use `createBase58check` instead.
* @deprecated
*/
export const base58check: (sha256: (data: Uint8Array) => Uint8Array) => BytesCoder =
createBase58check;
// Bech32 code
// -----------
export interface Bech32Decoded<Prefix extends string = string> {
prefix: Prefix;
words: number[];
}
export interface Bech32DecodedWithArray<Prefix extends string = string> {
prefix: Prefix;
words: number[];
bytes: Uint8Array;
}
const BECH_ALPHABET: Coder<number[], string> = chain(
alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'),
join('')
);
const POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
function bech32Polymod(pre: number): number {
const b = pre >> 25;
let chk = (pre & 0x1ffffff) << 5;
for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {
if (((b >> i) & 1) === 1) chk ^= POLYMOD_GENERATORS[i]!;
}
return chk;
}
function bechChecksum(prefix: string, words: number[], encodingConst = 1): string {
const len = prefix.length;
let chk = 1;
for (let i = 0; i < len; i++) {
const c = prefix.charCodeAt(i);
if (c < 33 || c > 126) throw new Error(`Invalid prefix (${prefix})`);
chk = bech32Polymod(chk) ^ (c >> 5);
}
chk = bech32Polymod(chk);
for (let i = 0; i < len; i++) chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);
for (let v of words) chk = bech32Polymod(chk) ^ v;
for (let i = 0; i < 6; i++) chk = bech32Polymod(chk);
chk ^= encodingConst;
return BECH_ALPHABET.encode(convertRadix2([chk % powers[30]!], 30, 5, false));
}
export interface Bech32 {
encode<Prefix extends string>(
prefix: Prefix,
words: number[] | Uint8Array,
limit?: number | false
): `${Lowercase<Prefix>}1${string}`;
decode<Prefix extends string>(
str: `${Prefix}1${string}`,
limit?: number | false
): Bech32Decoded<Prefix>;
encodeFromBytes(prefix: string, bytes: Uint8Array): string;
decodeToBytes(str: string): Bech32DecodedWithArray;
decodeUnsafe(str: string, limit?: number | false): void | Bech32Decoded<string>;
fromWords(to: number[]): Uint8Array;
fromWordsUnsafe(to: number[]): void | Uint8Array;
toWords(from: Uint8Array): number[];
}
/**
* @__NO_SIDE_EFFECTS__
*/
function genBech32(encoding: 'bech32' | 'bech32m'): Bech32 {
const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;
const _words = radix2(5);
const fromWords = _words.decode;
const toWords = _words.encode;
const fromWordsUnsafe = unsafeWrapper(fromWords);
function encode<Prefix extends string>(
prefix: Prefix,
words: number[] | Uint8Array,
limit: number | false = 90
): `${Lowercase<Prefix>}1${string}` {
astr('bech32.encode prefix', prefix);
if (isBytes(words)) words = Array.from(words);
anumArr('bech32.encode', words);
const plen = prefix.length;
if (plen === 0) throw new TypeError(`Invalid prefix length ${plen}`);
const actualLength = plen + 7 + words.length;
if (limit !== false && actualLength > limit)
throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);
const lowered = prefix.toLowerCase();
const sum = bechChecksum(lowered, words, ENCODING_CONST);
return `${lowered}1${BECH_ALPHABET.encode(words)}${sum}` as `${Lowercase<Prefix>}1${string}`;
}
function decode<Prefix extends string>(
str: `${Prefix}1${string}`,
limit?: number | false
): Bech32Decoded<Prefix>;
function decode(str: string, limit?: number | false): Bech32Decoded;
function decode(str: string, limit: number | false = 90): Bech32Decoded {
astr('bech32.decode input', str);
const slen = str.length;
if (slen < 8 || (limit !== false && slen > limit))
throw new TypeError(`invalid string length: ${slen} (${str}). Expected (8..${limit})`);
// don't allow mixed case
const lowered = str.toLowerCase();
if (str !== lowered && str !== str.toUpperCase())
throw new Error(`String must be lowercase or uppercase`);
const sepIndex = lowered.lastIndexOf('1');
if (sepIndex === 0 || sepIndex === -1)
throw new Error(`Letter "1" must be present between prefix and data only`);
const prefix = lowered.slice(0, sepIndex);
const data = lowered.slice(sepIndex + 1);
if (data.length < 6) throw new Error('Data must be at least 6 characters long');
const words = BECH_ALPHABET.decode(data).slice(0, -6);
const sum = bechChecksum(prefix, words, ENCODING_CONST);
if (!data.endsWith(sum)) throw new Error(`Invalid checksum in ${str}: expected "${sum}"`);
return { prefix, words };
}
const decodeUnsafe = unsafeWrapper(decode);
function decodeToBytes(str: string): Bech32DecodedWithArray {
const { prefix, words } = decode(str, false);
return { prefix, words, bytes: fromWords(words) };
}
function encodeFromBytes(prefix: string, bytes: Uint8Array) {
return encode(prefix, toWords(bytes));
}
return {
encode,
decode,
encodeFromBytes,
decodeToBytes,
decodeUnsafe,
fromWords,
fromWordsUnsafe,
toWords,
};
}
/**
* bech32 from BIP 173. Operates on words.
* For high-level, check out scure-btc-signer:
* https://github.com/paulmillr/scure-btc-signer.
*/
export const bech32: Bech32 = genBech32('bech32');
/**
* bech32m from BIP 350. Operates on words.
* It was to mitigate `bech32` weaknesses.
* For high-level, check out scure-btc-signer:
* https://github.com/paulmillr/scure-btc-signer.
*/
export const bech32m: Bech32 = genBech32('bech32m');
declare const TextEncoder: any;
declare const TextDecoder: any;
/**
* UTF-8-to-byte decoder. Uses built-in TextDecoder / TextEncoder.
* @example
* ```js
* const b = utf8.decode("hey"); // => new Uint8Array([ 104, 101, 121 ])
* const str = utf8.encode(b); // "hey"
* ```
*/
export const utf8: BytesCoder = {
encode: (data) => new TextDecoder().decode(data),
decode: (str) => new TextEncoder().encode(str),
};
// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
// prettier-ignore
const hasHexBuiltin: boolean = /* @__PURE__ */ (() =>
typeof (Uint8Array as any).from([]).toHex === 'function' &&
typeof (Uint8Array as any).fromHex === 'function')();
// prettier-ignore
const hexBuiltin: BytesCoder = {
encode(data) { abytes(data); return (data as any).toHex(); },
decode(s) { astr('hex', s); return (Uint8Array as any).fromHex(s); },
};
/**
* hex string decoder. Uses built-in function, when available.
* @example
* ```js
* const b = hex.decode("0102ff"); // => new Uint8Array([ 1, 2, 255 ])
* const str = hex.encode(b); // "0102ff"
* ```
*/
export const hex: BytesCoder = hasHexBuiltin
? hexBuiltin
: chain(
radix2(4),
alphabet('0123456789abcdef'),
join(''),
normalize((s: string) => {
if (typeof s !== 'string' || s.length % 2 !== 0)
throw new TypeError(
`hex.decode: expected string, got ${typeof s} with length ${s.length}`
);
return s.toLowerCase();
})
);
export type SomeCoders = {
utf8: BytesCoder;
hex: BytesCoder;
base16: BytesCoder;
base32: BytesCoder;
base64: BytesCoder;
base64url: BytesCoder;
base58: BytesCoder;
base58xmr: BytesCoder;
};
// prettier-ignore
const CODERS: SomeCoders = {
utf8, hex, base16, base32, base64, base64url, base58, base58xmr
};
type CoderType = keyof SomeCoders;
const coderTypeError =
'Invalid encoding type. Available types: utf8, hex, base16, base32, base64, base64url, base58, base58xmr';
/** @deprecated */
export const bytesToString = (type: CoderType, bytes: Uint8Array): string => {
if (typeof type !== 'string' || !CODERS.hasOwnProperty(type)) throw new TypeError(coderTypeError);
if (!isBytes(bytes)) throw new TypeError('bytesToString() expects Uint8Array');
return CODERS[type].encode(bytes);
};
/** @deprecated */
export const str: (type: CoderType, bytes: Uint8Array) => string = bytesToString; // as in python, but for bytes only
/** @deprecated */
export const stringToBytes = (type: CoderType, str: string): Uint8Array => {
if (!CODERS.hasOwnProperty(type)) throw new TypeError(coderTypeError);
if (typeof str !== 'string') throw new TypeError('stringToBytes() expects string');
return CODERS[type].decode(str);
};
/** @deprecated */
export const bytes: (type: CoderType, str: string) => Uint8Array = stringToBytes;

294
node_modules/@scure/base/lib/esm/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,294 @@
/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
export interface Coder<F, T> {
encode(from: F): T;
decode(to: T): F;
}
export interface BytesCoder extends Coder<Uint8Array, string> {
encode: (data: Uint8Array) => string;
decode: (str: string) => Uint8Array;
}
type Chain = [Coder<any, any>, ...Coder<any, any>[]];
type Input<F> = F extends Coder<infer T, any> ? T : never;
type Output<F> = F extends Coder<any, infer T> ? T : never;
type First<T> = T extends [infer U, ...any[]] ? U : never;
type Last<T> = T extends [...any[], infer U] ? U : never;
type Tail<T> = T extends [any, ...infer U] ? U : never;
type AsChain<C extends Chain, Rest = Tail<C>> = {
[K in keyof C]: Coder<Input<C[K]>, Input<K extends keyof Rest ? Rest[K] : any>>;
};
/**
* @__NO_SIDE_EFFECTS__
*/
declare function chain<T extends Chain & AsChain<T>>(...args: T): Coder<Input<First<T>>, Output<Last<T>>>;
/**
* Encodes integer radix representation to array of strings using alphabet and back.
* Could also be array of strings.
* @__NO_SIDE_EFFECTS__
*/
declare function alphabet(letters: string | string[]): Coder<number[], string[]>;
/**
* @__NO_SIDE_EFFECTS__
*/
declare function join(separator?: string): Coder<string[], string>;
/**
* Pad strings array so it has integer number of bits
* @__NO_SIDE_EFFECTS__
*/
declare function padding(bits: number, chr?: string): Coder<string[], string[]>;
/**
* Slow: O(n^2) time complexity
*/
declare function convertRadix(data: number[], from: number, to: number): number[];
/**
* Implemented with numbers, because BigInt is 5x slower
*/
declare function convertRadix2(data: number[], from: number, to: number, padding: boolean): number[];
/**
* @__NO_SIDE_EFFECTS__
*/
declare function radix(num: number): Coder<Uint8Array, number[]>;
/**
* If both bases are power of same number (like `2**8 <-> 2**64`),
* there is a linear algorithm. For now we have implementation for power-of-two bases only.
* @__NO_SIDE_EFFECTS__
*/
declare function radix2(bits: number, revPadding?: boolean): Coder<Uint8Array, number[]>;
declare function checksum(len: number, fn: (data: Uint8Array) => Uint8Array): Coder<Uint8Array, Uint8Array>;
export declare const utils: {
alphabet: typeof alphabet;
chain: typeof chain;
checksum: typeof checksum;
convertRadix: typeof convertRadix;
convertRadix2: typeof convertRadix2;
radix: typeof radix;
radix2: typeof radix2;
join: typeof join;
padding: typeof padding;
};
/**
* base16 encoding from RFC 4648.
* @example
* ```js
* base16.encode(Uint8Array.from([0x12, 0xab]));
* // => '12AB'
* ```
*/
export declare const base16: BytesCoder;
/**
* base32 encoding from RFC 4648. Has padding.
* Use `base32nopad` for unpadded version.
* Also check out `base32hex`, `base32hexnopad`, `base32crockford`.
* @example
* ```js
* base32.encode(Uint8Array.from([0x12, 0xab]));
* // => 'CKVQ===='
* base32.decode('CKVQ====');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base32: BytesCoder;
/**
* base32 encoding from RFC 4648. No padding.
* Use `base32` for padded version.
* Also check out `base32hex`, `base32hexnopad`, `base32crockford`.
* @example
* ```js
* base32nopad.encode(Uint8Array.from([0x12, 0xab]));
* // => 'CKVQ'
* base32nopad.decode('CKVQ');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base32nopad: BytesCoder;
/**
* base32 encoding from RFC 4648. Padded. Compared to ordinary `base32`, slightly different alphabet.
* Use `base32hexnopad` for unpadded version.
* @example
* ```js
* base32hex.encode(Uint8Array.from([0x12, 0xab]));
* // => '2ALG===='
* base32hex.decode('2ALG====');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base32hex: BytesCoder;
/**
* base32 encoding from RFC 4648. No padding. Compared to ordinary `base32`, slightly different alphabet.
* Use `base32hex` for padded version.
* @example
* ```js
* base32hexnopad.encode(Uint8Array.from([0x12, 0xab]));
* // => '2ALG'
* base32hexnopad.decode('2ALG');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base32hexnopad: BytesCoder;
/**
* base32 encoding from RFC 4648. Doug Crockford's version.
* https://www.crockford.com/base32.html
* @example
* ```js
* base32crockford.encode(Uint8Array.from([0x12, 0xab]));
* // => '2ANG'
* base32crockford.decode('2ANG');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base32crockford: BytesCoder;
/**
* base64 from RFC 4648. Padded.
* Use `base64nopad` for unpadded version.
* Also check out `base64url`, `base64urlnopad`.
* Falls back to built-in function, when available.
* @example
* ```js
* base64.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs='
* base64.decode('Eqs=');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base64: BytesCoder;
/**
* base64 from RFC 4648. No padding.
* Use `base64` for padded version.
* @example
* ```js
* base64nopad.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs'
* base64nopad.decode('Eqs');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base64nopad: BytesCoder;
/**
* base64 from RFC 4648, using URL-safe alphabet. Padded.
* Use `base64urlnopad` for unpadded version.
* Falls back to built-in function, when available.
* @example
* ```js
* base64url.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs='
* base64url.decode('Eqs=');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base64url: BytesCoder;
/**
* base64 from RFC 4648, using URL-safe alphabet. No padding.
* Use `base64url` for padded version.
* @example
* ```js
* base64urlnopad.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs'
* base64urlnopad.decode('Eqs');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base64urlnopad: BytesCoder;
/**
* base58: base64 without ambigous characters +, /, 0, O, I, l.
* Quadratic (O(n^2)) - so, can't be used on large inputs.
* @example
* ```js
* base58.decode('01abcdef');
* // => '3UhJW'
* ```
*/
export declare const base58: BytesCoder;
/**
* base58: flickr version. Check out `base58`.
*/
export declare const base58flickr: BytesCoder;
/**
* base58: XRP version. Check out `base58`.
*/
export declare const base58xrp: BytesCoder;
/**
* base58: XMR version. Check out `base58`.
* Done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.
* Block encoding significantly reduces quadratic complexity of base58.
*/
export declare const base58xmr: BytesCoder;
/**
* Method, which creates base58check encoder.
* Requires function, calculating sha256.
*/
export declare const createBase58check: (sha256: (data: Uint8Array) => Uint8Array) => BytesCoder;
/**
* Use `createBase58check` instead.
* @deprecated
*/
export declare const base58check: (sha256: (data: Uint8Array) => Uint8Array) => BytesCoder;
export interface Bech32Decoded<Prefix extends string = string> {
prefix: Prefix;
words: number[];
}
export interface Bech32DecodedWithArray<Prefix extends string = string> {
prefix: Prefix;
words: number[];
bytes: Uint8Array;
}
export interface Bech32 {
encode<Prefix extends string>(prefix: Prefix, words: number[] | Uint8Array, limit?: number | false): `${Lowercase<Prefix>}1${string}`;
decode<Prefix extends string>(str: `${Prefix}1${string}`, limit?: number | false): Bech32Decoded<Prefix>;
encodeFromBytes(prefix: string, bytes: Uint8Array): string;
decodeToBytes(str: string): Bech32DecodedWithArray;
decodeUnsafe(str: string, limit?: number | false): void | Bech32Decoded<string>;
fromWords(to: number[]): Uint8Array;
fromWordsUnsafe(to: number[]): void | Uint8Array;
toWords(from: Uint8Array): number[];
}
/**
* bech32 from BIP 173. Operates on words.
* For high-level, check out scure-btc-signer:
* https://github.com/paulmillr/scure-btc-signer.
*/
export declare const bech32: Bech32;
/**
* bech32m from BIP 350. Operates on words.
* It was to mitigate `bech32` weaknesses.
* For high-level, check out scure-btc-signer:
* https://github.com/paulmillr/scure-btc-signer.
*/
export declare const bech32m: Bech32;
/**
* UTF-8-to-byte decoder. Uses built-in TextDecoder / TextEncoder.
* @example
* ```js
* const b = utf8.decode("hey"); // => new Uint8Array([ 104, 101, 121 ])
* const str = utf8.encode(b); // "hey"
* ```
*/
export declare const utf8: BytesCoder;
/**
* hex string decoder. Uses built-in function, when available.
* @example
* ```js
* const b = hex.decode("0102ff"); // => new Uint8Array([ 1, 2, 255 ])
* const str = hex.encode(b); // "0102ff"
* ```
*/
export declare const hex: BytesCoder;
export type SomeCoders = {
utf8: BytesCoder;
hex: BytesCoder;
base16: BytesCoder;
base32: BytesCoder;
base64: BytesCoder;
base64url: BytesCoder;
base58: BytesCoder;
base58xmr: BytesCoder;
};
type CoderType = keyof SomeCoders;
/** @deprecated */
export declare const bytesToString: (type: CoderType, bytes: Uint8Array) => string;
/** @deprecated */
export declare const str: (type: CoderType, bytes: Uint8Array) => string;
/** @deprecated */
export declare const stringToBytes: (type: CoderType, str: string) => Uint8Array;
/** @deprecated */
export declare const bytes: (type: CoderType, str: string) => Uint8Array;
export {};
//# sourceMappingURL=index.d.ts.map

1
node_modules/@scure/base/lib/esm/index.d.ts.map generated vendored Normal file

File diff suppressed because one or more lines are too long

707
node_modules/@scure/base/lib/esm/index.js generated vendored Normal file
View File

@@ -0,0 +1,707 @@
/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
function isBytes(a) {
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
}
/** Asserts something is Uint8Array. */
function abytes(b, ...lengths) {
if (!isBytes(b))
throw new Error('Uint8Array expected');
if (lengths.length > 0 && !lengths.includes(b.length))
throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
}
function isArrayOf(isString, arr) {
if (!Array.isArray(arr))
return false;
if (arr.length === 0)
return true;
if (isString) {
return arr.every((item) => typeof item === 'string');
}
else {
return arr.every((item) => Number.isSafeInteger(item));
}
}
// no abytes: seems to have 10% slowdown. Why?!
function afn(input) {
if (typeof input !== 'function')
throw new Error('function expected');
return true;
}
function astr(label, input) {
if (typeof input !== 'string')
throw new Error(`${label}: string expected`);
return true;
}
function anumber(n) {
if (!Number.isSafeInteger(n))
throw new Error(`invalid integer: ${n}`);
}
function aArr(input) {
if (!Array.isArray(input))
throw new Error('array expected');
}
function astrArr(label, input) {
if (!isArrayOf(true, input))
throw new Error(`${label}: array of strings expected`);
}
function anumArr(label, input) {
if (!isArrayOf(false, input))
throw new Error(`${label}: array of numbers expected`);
}
/**
* @__NO_SIDE_EFFECTS__
*/
function chain(...args) {
const id = (a) => a;
// Wrap call in closure so JIT can inline calls
const wrap = (a, b) => (c) => a(b(c));
// Construct chain of args[-1].encode(args[-2].encode([...]))
const encode = args.map((x) => x.encode).reduceRight(wrap, id);
// Construct chain of args[0].decode(args[1].decode(...))
const decode = args.map((x) => x.decode).reduce(wrap, id);
return { encode, decode };
}
/**
* Encodes integer radix representation to array of strings using alphabet and back.
* Could also be array of strings.
* @__NO_SIDE_EFFECTS__
*/
function alphabet(letters) {
// mapping 1 to "b"
const lettersA = typeof letters === 'string' ? letters.split('') : letters;
const len = lettersA.length;
astrArr('alphabet', lettersA);
// mapping "b" to 1
const indexes = new Map(lettersA.map((l, i) => [l, i]));
return {
encode: (digits) => {
aArr(digits);
return digits.map((i) => {
if (!Number.isSafeInteger(i) || i < 0 || i >= len)
throw new Error(`alphabet.encode: digit index outside alphabet "${i}". Allowed: ${letters}`);
return lettersA[i];
});
},
decode: (input) => {
aArr(input);
return input.map((letter) => {
astr('alphabet.decode', letter);
const i = indexes.get(letter);
if (i === undefined)
throw new Error(`Unknown letter: "${letter}". Allowed: ${letters}`);
return i;
});
},
};
}
/**
* @__NO_SIDE_EFFECTS__
*/
function join(separator = '') {
astr('join', separator);
return {
encode: (from) => {
astrArr('join.decode', from);
return from.join(separator);
},
decode: (to) => {
astr('join.decode', to);
return to.split(separator);
},
};
}
/**
* Pad strings array so it has integer number of bits
* @__NO_SIDE_EFFECTS__
*/
function padding(bits, chr = '=') {
anumber(bits);
astr('padding', chr);
return {
encode(data) {
astrArr('padding.encode', data);
while ((data.length * bits) % 8)
data.push(chr);
return data;
},
decode(input) {
astrArr('padding.decode', input);
let end = input.length;
if ((end * bits) % 8)
throw new Error('padding: invalid, string should have whole number of bytes');
for (; end > 0 && input[end - 1] === chr; end--) {
const last = end - 1;
const byte = last * bits;
if (byte % 8 === 0)
throw new Error('padding: invalid, string has too much padding');
}
return input.slice(0, end);
},
};
}
/**
* @__NO_SIDE_EFFECTS__
*/
function normalize(fn) {
afn(fn);
return { encode: (from) => from, decode: (to) => fn(to) };
}
/**
* Slow: O(n^2) time complexity
*/
function convertRadix(data, from, to) {
// base 1 is impossible
if (from < 2)
throw new Error(`convertRadix: invalid from=${from}, base cannot be less than 2`);
if (to < 2)
throw new Error(`convertRadix: invalid to=${to}, base cannot be less than 2`);
aArr(data);
if (!data.length)
return [];
let pos = 0;
const res = [];
const digits = Array.from(data, (d) => {
anumber(d);
if (d < 0 || d >= from)
throw new Error(`invalid integer: ${d}`);
return d;
});
const dlen = digits.length;
while (true) {
let carry = 0;
let done = true;
for (let i = pos; i < dlen; i++) {
const digit = digits[i];
const fromCarry = from * carry;
const digitBase = fromCarry + digit;
if (!Number.isSafeInteger(digitBase) ||
fromCarry / from !== carry ||
digitBase - digit !== fromCarry) {
throw new Error('convertRadix: carry overflow');
}
const div = digitBase / to;
carry = digitBase % to;
const rounded = Math.floor(div);
digits[i] = rounded;
if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)
throw new Error('convertRadix: carry overflow');
if (!done)
continue;
else if (!rounded)
pos = i;
else
done = false;
}
res.push(carry);
if (done)
break;
}
for (let i = 0; i < data.length - 1 && data[i] === 0; i++)
res.push(0);
return res.reverse();
}
const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));
const radix2carry = /* @__NO_SIDE_EFFECTS__ */ (from, to) => from + (to - gcd(from, to));
const powers = /* @__PURE__ */ (() => {
let res = [];
for (let i = 0; i < 40; i++)
res.push(2 ** i);
return res;
})();
/**
* Implemented with numbers, because BigInt is 5x slower
*/
function convertRadix2(data, from, to, padding) {
aArr(data);
if (from <= 0 || from > 32)
throw new Error(`convertRadix2: wrong from=${from}`);
if (to <= 0 || to > 32)
throw new Error(`convertRadix2: wrong to=${to}`);
if (radix2carry(from, to) > 32) {
throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`);
}
let carry = 0;
let pos = 0; // bitwise position in current element
const max = powers[from];
const mask = powers[to] - 1;
const res = [];
for (const n of data) {
anumber(n);
if (n >= max)
throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
carry = (carry << from) | n;
if (pos + from > 32)
throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
pos += from;
for (; pos >= to; pos -= to)
res.push(((carry >> (pos - to)) & mask) >>> 0);
const pow = powers[pos];
if (pow === undefined)
throw new Error('invalid carry');
carry &= pow - 1; // clean carry, otherwise it will cause overflow
}
carry = (carry << (to - pos)) & mask;
if (!padding && pos >= from)
throw new Error('Excess padding');
if (!padding && carry > 0)
throw new Error(`Non-zero padding: ${carry}`);
if (padding && pos > 0)
res.push(carry >>> 0);
return res;
}
/**
* @__NO_SIDE_EFFECTS__
*/
function radix(num) {
anumber(num);
const _256 = 2 ** 8;
return {
encode: (bytes) => {
if (!isBytes(bytes))
throw new Error('radix.encode input should be Uint8Array');
return convertRadix(Array.from(bytes), _256, num);
},
decode: (digits) => {
anumArr('radix.decode', digits);
return Uint8Array.from(convertRadix(digits, num, _256));
},
};
}
/**
* If both bases are power of same number (like `2**8 <-> 2**64`),
* there is a linear algorithm. For now we have implementation for power-of-two bases only.
* @__NO_SIDE_EFFECTS__
*/
function radix2(bits, revPadding = false) {
anumber(bits);
if (bits <= 0 || bits > 32)
throw new Error('radix2: bits should be in (0..32]');
if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)
throw new Error('radix2: carry overflow');
return {
encode: (bytes) => {
if (!isBytes(bytes))
throw new Error('radix2.encode input should be Uint8Array');
return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
},
decode: (digits) => {
anumArr('radix2.decode', digits);
return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
},
};
}
function unsafeWrapper(fn) {
afn(fn);
return function (...args) {
try {
return fn.apply(null, args);
}
catch (e) { }
};
}
function checksum(len, fn) {
anumber(len);
afn(fn);
return {
encode(data) {
if (!isBytes(data))
throw new Error('checksum.encode: input should be Uint8Array');
const sum = fn(data).slice(0, len);
const res = new Uint8Array(data.length + len);
res.set(data);
res.set(sum, data.length);
return res;
},
decode(data) {
if (!isBytes(data))
throw new Error('checksum.decode: input should be Uint8Array');
const payload = data.slice(0, -len);
const oldChecksum = data.slice(-len);
const newChecksum = fn(payload).slice(0, len);
for (let i = 0; i < len; i++)
if (newChecksum[i] !== oldChecksum[i])
throw new Error('Invalid checksum');
return payload;
},
};
}
// prettier-ignore
export const utils = {
alphabet, chain, checksum, convertRadix, convertRadix2, radix, radix2, join, padding,
};
// RFC 4648 aka RFC 3548
// ---------------------
/**
* base16 encoding from RFC 4648.
* @example
* ```js
* base16.encode(Uint8Array.from([0x12, 0xab]));
* // => '12AB'
* ```
*/
export const base16 = chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));
/**
* base32 encoding from RFC 4648. Has padding.
* Use `base32nopad` for unpadded version.
* Also check out `base32hex`, `base32hexnopad`, `base32crockford`.
* @example
* ```js
* base32.encode(Uint8Array.from([0x12, 0xab]));
* // => 'CKVQ===='
* base32.decode('CKVQ====');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export const base32 = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''));
/**
* base32 encoding from RFC 4648. No padding.
* Use `base32` for padded version.
* Also check out `base32hex`, `base32hexnopad`, `base32crockford`.
* @example
* ```js
* base32nopad.encode(Uint8Array.from([0x12, 0xab]));
* // => 'CKVQ'
* base32nopad.decode('CKVQ');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export const base32nopad = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), join(''));
/**
* base32 encoding from RFC 4648. Padded. Compared to ordinary `base32`, slightly different alphabet.
* Use `base32hexnopad` for unpadded version.
* @example
* ```js
* base32hex.encode(Uint8Array.from([0x12, 0xab]));
* // => '2ALG===='
* base32hex.decode('2ALG====');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export const base32hex = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join(''));
/**
* base32 encoding from RFC 4648. No padding. Compared to ordinary `base32`, slightly different alphabet.
* Use `base32hex` for padded version.
* @example
* ```js
* base32hexnopad.encode(Uint8Array.from([0x12, 0xab]));
* // => '2ALG'
* base32hexnopad.decode('2ALG');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export const base32hexnopad = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), join(''));
/**
* base32 encoding from RFC 4648. Doug Crockford's version.
* https://www.crockford.com/base32.html
* @example
* ```js
* base32crockford.encode(Uint8Array.from([0x12, 0xab]));
* // => '2ANG'
* base32crockford.decode('2ANG');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export const base32crockford = chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1')));
// Built-in base64 conversion https://caniuse.com/mdn-javascript_builtins_uint8array_frombase64
// prettier-ignore
const hasBase64Builtin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toBase64 === 'function' &&
typeof Uint8Array.fromBase64 === 'function')();
const decodeBase64Builtin = (s, isUrl) => {
astr('base64', s);
const re = isUrl ? /^[A-Za-z0-9=_-]+$/ : /^[A-Za-z0-9=+/]+$/;
const alphabet = isUrl ? 'base64url' : 'base64';
if (s.length > 0 && !re.test(s))
throw new Error('invalid base64');
return Uint8Array.fromBase64(s, { alphabet, lastChunkHandling: 'strict' });
};
/**
* base64 from RFC 4648. Padded.
* Use `base64nopad` for unpadded version.
* Also check out `base64url`, `base64urlnopad`.
* Falls back to built-in function, when available.
* @example
* ```js
* base64.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs='
* base64.decode('Eqs=');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
// prettier-ignore
export const base64 = hasBase64Builtin ? {
encode(b) { abytes(b); return b.toBase64(); },
decode(s) { return decodeBase64Builtin(s, false); },
} : chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join(''));
/**
* base64 from RFC 4648. No padding.
* Use `base64` for padded version.
* @example
* ```js
* base64nopad.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs'
* base64nopad.decode('Eqs');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export const base64nopad = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), join(''));
/**
* base64 from RFC 4648, using URL-safe alphabet. Padded.
* Use `base64urlnopad` for unpadded version.
* Falls back to built-in function, when available.
* @example
* ```js
* base64url.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs='
* base64url.decode('Eqs=');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
// prettier-ignore
export const base64url = hasBase64Builtin ? {
encode(b) { abytes(b); return b.toBase64({ alphabet: 'base64url' }); },
decode(s) { return decodeBase64Builtin(s, true); },
} : chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join(''));
/**
* base64 from RFC 4648, using URL-safe alphabet. No padding.
* Use `base64url` for padded version.
* @example
* ```js
* base64urlnopad.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs'
* base64urlnopad.decode('Eqs');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export const base64urlnopad = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), join(''));
// base58 code
// -----------
const genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => chain(radix(58), alphabet(abc), join(''));
/**
* base58: base64 without ambigous characters +, /, 0, O, I, l.
* Quadratic (O(n^2)) - so, can't be used on large inputs.
* @example
* ```js
* base58.decode('01abcdef');
* // => '3UhJW'
* ```
*/
export const base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
/**
* base58: flickr version. Check out `base58`.
*/
export const base58flickr = genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');
/**
* base58: XRP version. Check out `base58`.
*/
export const base58xrp = genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz');
// Data len (index) -> encoded block len
const XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];
/**
* base58: XMR version. Check out `base58`.
* Done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.
* Block encoding significantly reduces quadratic complexity of base58.
*/
export const base58xmr = {
encode(data) {
let res = '';
for (let i = 0; i < data.length; i += 8) {
const block = data.subarray(i, i + 8);
res += base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], '1');
}
return res;
},
decode(str) {
let res = [];
for (let i = 0; i < str.length; i += 11) {
const slice = str.slice(i, i + 11);
const blockLen = XMR_BLOCK_LEN.indexOf(slice.length);
const block = base58.decode(slice);
for (let j = 0; j < block.length - blockLen; j++) {
if (block[j] !== 0)
throw new Error('base58xmr: wrong padding');
}
res = res.concat(Array.from(block.slice(block.length - blockLen)));
}
return Uint8Array.from(res);
},
};
/**
* Method, which creates base58check encoder.
* Requires function, calculating sha256.
*/
export const createBase58check = (sha256) => chain(checksum(4, (data) => sha256(sha256(data))), base58);
/**
* Use `createBase58check` instead.
* @deprecated
*/
export const base58check = createBase58check;
const BECH_ALPHABET = chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));
const POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
function bech32Polymod(pre) {
const b = pre >> 25;
let chk = (pre & 0x1ffffff) << 5;
for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {
if (((b >> i) & 1) === 1)
chk ^= POLYMOD_GENERATORS[i];
}
return chk;
}
function bechChecksum(prefix, words, encodingConst = 1) {
const len = prefix.length;
let chk = 1;
for (let i = 0; i < len; i++) {
const c = prefix.charCodeAt(i);
if (c < 33 || c > 126)
throw new Error(`Invalid prefix (${prefix})`);
chk = bech32Polymod(chk) ^ (c >> 5);
}
chk = bech32Polymod(chk);
for (let i = 0; i < len; i++)
chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);
for (let v of words)
chk = bech32Polymod(chk) ^ v;
for (let i = 0; i < 6; i++)
chk = bech32Polymod(chk);
chk ^= encodingConst;
return BECH_ALPHABET.encode(convertRadix2([chk % powers[30]], 30, 5, false));
}
/**
* @__NO_SIDE_EFFECTS__
*/
function genBech32(encoding) {
const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;
const _words = radix2(5);
const fromWords = _words.decode;
const toWords = _words.encode;
const fromWordsUnsafe = unsafeWrapper(fromWords);
function encode(prefix, words, limit = 90) {
astr('bech32.encode prefix', prefix);
if (isBytes(words))
words = Array.from(words);
anumArr('bech32.encode', words);
const plen = prefix.length;
if (plen === 0)
throw new TypeError(`Invalid prefix length ${plen}`);
const actualLength = plen + 7 + words.length;
if (limit !== false && actualLength > limit)
throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);
const lowered = prefix.toLowerCase();
const sum = bechChecksum(lowered, words, ENCODING_CONST);
return `${lowered}1${BECH_ALPHABET.encode(words)}${sum}`;
}
function decode(str, limit = 90) {
astr('bech32.decode input', str);
const slen = str.length;
if (slen < 8 || (limit !== false && slen > limit))
throw new TypeError(`invalid string length: ${slen} (${str}). Expected (8..${limit})`);
// don't allow mixed case
const lowered = str.toLowerCase();
if (str !== lowered && str !== str.toUpperCase())
throw new Error(`String must be lowercase or uppercase`);
const sepIndex = lowered.lastIndexOf('1');
if (sepIndex === 0 || sepIndex === -1)
throw new Error(`Letter "1" must be present between prefix and data only`);
const prefix = lowered.slice(0, sepIndex);
const data = lowered.slice(sepIndex + 1);
if (data.length < 6)
throw new Error('Data must be at least 6 characters long');
const words = BECH_ALPHABET.decode(data).slice(0, -6);
const sum = bechChecksum(prefix, words, ENCODING_CONST);
if (!data.endsWith(sum))
throw new Error(`Invalid checksum in ${str}: expected "${sum}"`);
return { prefix, words };
}
const decodeUnsafe = unsafeWrapper(decode);
function decodeToBytes(str) {
const { prefix, words } = decode(str, false);
return { prefix, words, bytes: fromWords(words) };
}
function encodeFromBytes(prefix, bytes) {
return encode(prefix, toWords(bytes));
}
return {
encode,
decode,
encodeFromBytes,
decodeToBytes,
decodeUnsafe,
fromWords,
fromWordsUnsafe,
toWords,
};
}
/**
* bech32 from BIP 173. Operates on words.
* For high-level, check out scure-btc-signer:
* https://github.com/paulmillr/scure-btc-signer.
*/
export const bech32 = genBech32('bech32');
/**
* bech32m from BIP 350. Operates on words.
* It was to mitigate `bech32` weaknesses.
* For high-level, check out scure-btc-signer:
* https://github.com/paulmillr/scure-btc-signer.
*/
export const bech32m = genBech32('bech32m');
/**
* UTF-8-to-byte decoder. Uses built-in TextDecoder / TextEncoder.
* @example
* ```js
* const b = utf8.decode("hey"); // => new Uint8Array([ 104, 101, 121 ])
* const str = utf8.encode(b); // "hey"
* ```
*/
export const utf8 = {
encode: (data) => new TextDecoder().decode(data),
decode: (str) => new TextEncoder().encode(str),
};
// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
// prettier-ignore
const hasHexBuiltin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toHex === 'function' &&
typeof Uint8Array.fromHex === 'function')();
// prettier-ignore
const hexBuiltin = {
encode(data) { abytes(data); return data.toHex(); },
decode(s) { astr('hex', s); return Uint8Array.fromHex(s); },
};
/**
* hex string decoder. Uses built-in function, when available.
* @example
* ```js
* const b = hex.decode("0102ff"); // => new Uint8Array([ 1, 2, 255 ])
* const str = hex.encode(b); // "0102ff"
* ```
*/
export const hex = hasHexBuiltin
? hexBuiltin
: chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => {
if (typeof s !== 'string' || s.length % 2 !== 0)
throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);
return s.toLowerCase();
}));
// prettier-ignore
const CODERS = {
utf8, hex, base16, base32, base64, base64url, base58, base58xmr
};
const coderTypeError = 'Invalid encoding type. Available types: utf8, hex, base16, base32, base64, base64url, base58, base58xmr';
/** @deprecated */
export const bytesToString = (type, bytes) => {
if (typeof type !== 'string' || !CODERS.hasOwnProperty(type))
throw new TypeError(coderTypeError);
if (!isBytes(bytes))
throw new TypeError('bytesToString() expects Uint8Array');
return CODERS[type].encode(bytes);
};
/** @deprecated */
export const str = bytesToString; // as in python, but for bytes only
/** @deprecated */
export const stringToBytes = (type, str) => {
if (!CODERS.hasOwnProperty(type))
throw new TypeError(coderTypeError);
if (typeof str !== 'string')
throw new TypeError('stringToBytes() expects string');
return CODERS[type].decode(str);
};
/** @deprecated */
export const bytes = stringToBytes;
//# sourceMappingURL=index.js.map

1
node_modules/@scure/base/lib/esm/index.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

1
node_modules/@scure/base/lib/esm/package.json generated vendored Normal file
View File

@@ -0,0 +1 @@
{ "type": "module", "sideEffects": false }

294
node_modules/@scure/base/lib/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,294 @@
/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
export interface Coder<F, T> {
encode(from: F): T;
decode(to: T): F;
}
export interface BytesCoder extends Coder<Uint8Array, string> {
encode: (data: Uint8Array) => string;
decode: (str: string) => Uint8Array;
}
type Chain = [Coder<any, any>, ...Coder<any, any>[]];
type Input<F> = F extends Coder<infer T, any> ? T : never;
type Output<F> = F extends Coder<any, infer T> ? T : never;
type First<T> = T extends [infer U, ...any[]] ? U : never;
type Last<T> = T extends [...any[], infer U] ? U : never;
type Tail<T> = T extends [any, ...infer U] ? U : never;
type AsChain<C extends Chain, Rest = Tail<C>> = {
[K in keyof C]: Coder<Input<C[K]>, Input<K extends keyof Rest ? Rest[K] : any>>;
};
/**
* @__NO_SIDE_EFFECTS__
*/
declare function chain<T extends Chain & AsChain<T>>(...args: T): Coder<Input<First<T>>, Output<Last<T>>>;
/**
* Encodes integer radix representation to array of strings using alphabet and back.
* Could also be array of strings.
* @__NO_SIDE_EFFECTS__
*/
declare function alphabet(letters: string | string[]): Coder<number[], string[]>;
/**
* @__NO_SIDE_EFFECTS__
*/
declare function join(separator?: string): Coder<string[], string>;
/**
* Pad strings array so it has integer number of bits
* @__NO_SIDE_EFFECTS__
*/
declare function padding(bits: number, chr?: string): Coder<string[], string[]>;
/**
* Slow: O(n^2) time complexity
*/
declare function convertRadix(data: number[], from: number, to: number): number[];
/**
* Implemented with numbers, because BigInt is 5x slower
*/
declare function convertRadix2(data: number[], from: number, to: number, padding: boolean): number[];
/**
* @__NO_SIDE_EFFECTS__
*/
declare function radix(num: number): Coder<Uint8Array, number[]>;
/**
* If both bases are power of same number (like `2**8 <-> 2**64`),
* there is a linear algorithm. For now we have implementation for power-of-two bases only.
* @__NO_SIDE_EFFECTS__
*/
declare function radix2(bits: number, revPadding?: boolean): Coder<Uint8Array, number[]>;
declare function checksum(len: number, fn: (data: Uint8Array) => Uint8Array): Coder<Uint8Array, Uint8Array>;
export declare const utils: {
alphabet: typeof alphabet;
chain: typeof chain;
checksum: typeof checksum;
convertRadix: typeof convertRadix;
convertRadix2: typeof convertRadix2;
radix: typeof radix;
radix2: typeof radix2;
join: typeof join;
padding: typeof padding;
};
/**
* base16 encoding from RFC 4648.
* @example
* ```js
* base16.encode(Uint8Array.from([0x12, 0xab]));
* // => '12AB'
* ```
*/
export declare const base16: BytesCoder;
/**
* base32 encoding from RFC 4648. Has padding.
* Use `base32nopad` for unpadded version.
* Also check out `base32hex`, `base32hexnopad`, `base32crockford`.
* @example
* ```js
* base32.encode(Uint8Array.from([0x12, 0xab]));
* // => 'CKVQ===='
* base32.decode('CKVQ====');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base32: BytesCoder;
/**
* base32 encoding from RFC 4648. No padding.
* Use `base32` for padded version.
* Also check out `base32hex`, `base32hexnopad`, `base32crockford`.
* @example
* ```js
* base32nopad.encode(Uint8Array.from([0x12, 0xab]));
* // => 'CKVQ'
* base32nopad.decode('CKVQ');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base32nopad: BytesCoder;
/**
* base32 encoding from RFC 4648. Padded. Compared to ordinary `base32`, slightly different alphabet.
* Use `base32hexnopad` for unpadded version.
* @example
* ```js
* base32hex.encode(Uint8Array.from([0x12, 0xab]));
* // => '2ALG===='
* base32hex.decode('2ALG====');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base32hex: BytesCoder;
/**
* base32 encoding from RFC 4648. No padding. Compared to ordinary `base32`, slightly different alphabet.
* Use `base32hex` for padded version.
* @example
* ```js
* base32hexnopad.encode(Uint8Array.from([0x12, 0xab]));
* // => '2ALG'
* base32hexnopad.decode('2ALG');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base32hexnopad: BytesCoder;
/**
* base32 encoding from RFC 4648. Doug Crockford's version.
* https://www.crockford.com/base32.html
* @example
* ```js
* base32crockford.encode(Uint8Array.from([0x12, 0xab]));
* // => '2ANG'
* base32crockford.decode('2ANG');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base32crockford: BytesCoder;
/**
* base64 from RFC 4648. Padded.
* Use `base64nopad` for unpadded version.
* Also check out `base64url`, `base64urlnopad`.
* Falls back to built-in function, when available.
* @example
* ```js
* base64.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs='
* base64.decode('Eqs=');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base64: BytesCoder;
/**
* base64 from RFC 4648. No padding.
* Use `base64` for padded version.
* @example
* ```js
* base64nopad.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs'
* base64nopad.decode('Eqs');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base64nopad: BytesCoder;
/**
* base64 from RFC 4648, using URL-safe alphabet. Padded.
* Use `base64urlnopad` for unpadded version.
* Falls back to built-in function, when available.
* @example
* ```js
* base64url.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs='
* base64url.decode('Eqs=');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base64url: BytesCoder;
/**
* base64 from RFC 4648, using URL-safe alphabet. No padding.
* Use `base64url` for padded version.
* @example
* ```js
* base64urlnopad.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs'
* base64urlnopad.decode('Eqs');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
export declare const base64urlnopad: BytesCoder;
/**
* base58: base64 without ambigous characters +, /, 0, O, I, l.
* Quadratic (O(n^2)) - so, can't be used on large inputs.
* @example
* ```js
* base58.decode('01abcdef');
* // => '3UhJW'
* ```
*/
export declare const base58: BytesCoder;
/**
* base58: flickr version. Check out `base58`.
*/
export declare const base58flickr: BytesCoder;
/**
* base58: XRP version. Check out `base58`.
*/
export declare const base58xrp: BytesCoder;
/**
* base58: XMR version. Check out `base58`.
* Done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.
* Block encoding significantly reduces quadratic complexity of base58.
*/
export declare const base58xmr: BytesCoder;
/**
* Method, which creates base58check encoder.
* Requires function, calculating sha256.
*/
export declare const createBase58check: (sha256: (data: Uint8Array) => Uint8Array) => BytesCoder;
/**
* Use `createBase58check` instead.
* @deprecated
*/
export declare const base58check: (sha256: (data: Uint8Array) => Uint8Array) => BytesCoder;
export interface Bech32Decoded<Prefix extends string = string> {
prefix: Prefix;
words: number[];
}
export interface Bech32DecodedWithArray<Prefix extends string = string> {
prefix: Prefix;
words: number[];
bytes: Uint8Array;
}
export interface Bech32 {
encode<Prefix extends string>(prefix: Prefix, words: number[] | Uint8Array, limit?: number | false): `${Lowercase<Prefix>}1${string}`;
decode<Prefix extends string>(str: `${Prefix}1${string}`, limit?: number | false): Bech32Decoded<Prefix>;
encodeFromBytes(prefix: string, bytes: Uint8Array): string;
decodeToBytes(str: string): Bech32DecodedWithArray;
decodeUnsafe(str: string, limit?: number | false): void | Bech32Decoded<string>;
fromWords(to: number[]): Uint8Array;
fromWordsUnsafe(to: number[]): void | Uint8Array;
toWords(from: Uint8Array): number[];
}
/**
* bech32 from BIP 173. Operates on words.
* For high-level, check out scure-btc-signer:
* https://github.com/paulmillr/scure-btc-signer.
*/
export declare const bech32: Bech32;
/**
* bech32m from BIP 350. Operates on words.
* It was to mitigate `bech32` weaknesses.
* For high-level, check out scure-btc-signer:
* https://github.com/paulmillr/scure-btc-signer.
*/
export declare const bech32m: Bech32;
/**
* UTF-8-to-byte decoder. Uses built-in TextDecoder / TextEncoder.
* @example
* ```js
* const b = utf8.decode("hey"); // => new Uint8Array([ 104, 101, 121 ])
* const str = utf8.encode(b); // "hey"
* ```
*/
export declare const utf8: BytesCoder;
/**
* hex string decoder. Uses built-in function, when available.
* @example
* ```js
* const b = hex.decode("0102ff"); // => new Uint8Array([ 1, 2, 255 ])
* const str = hex.encode(b); // "0102ff"
* ```
*/
export declare const hex: BytesCoder;
export type SomeCoders = {
utf8: BytesCoder;
hex: BytesCoder;
base16: BytesCoder;
base32: BytesCoder;
base64: BytesCoder;
base64url: BytesCoder;
base58: BytesCoder;
base58xmr: BytesCoder;
};
type CoderType = keyof SomeCoders;
/** @deprecated */
export declare const bytesToString: (type: CoderType, bytes: Uint8Array) => string;
/** @deprecated */
export declare const str: (type: CoderType, bytes: Uint8Array) => string;
/** @deprecated */
export declare const stringToBytes: (type: CoderType, str: string) => Uint8Array;
/** @deprecated */
export declare const bytes: (type: CoderType, str: string) => Uint8Array;
export {};
//# sourceMappingURL=index.d.ts.map

1
node_modules/@scure/base/lib/index.d.ts.map generated vendored Normal file

File diff suppressed because one or more lines are too long

713
node_modules/@scure/base/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,713 @@
"use strict";
/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
Object.defineProperty(exports, "__esModule", { value: true });
exports.bytes = exports.stringToBytes = exports.str = exports.bytesToString = exports.hex = exports.utf8 = exports.bech32m = exports.bech32 = exports.base58check = exports.createBase58check = exports.base58xmr = exports.base58xrp = exports.base58flickr = exports.base58 = exports.base64urlnopad = exports.base64url = exports.base64nopad = exports.base64 = exports.base32crockford = exports.base32hexnopad = exports.base32hex = exports.base32nopad = exports.base32 = exports.base16 = exports.utils = void 0;
function isBytes(a) {
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
}
/** Asserts something is Uint8Array. */
function abytes(b, ...lengths) {
if (!isBytes(b))
throw new Error('Uint8Array expected');
if (lengths.length > 0 && !lengths.includes(b.length))
throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
}
function isArrayOf(isString, arr) {
if (!Array.isArray(arr))
return false;
if (arr.length === 0)
return true;
if (isString) {
return arr.every((item) => typeof item === 'string');
}
else {
return arr.every((item) => Number.isSafeInteger(item));
}
}
// no abytes: seems to have 10% slowdown. Why?!
function afn(input) {
if (typeof input !== 'function')
throw new Error('function expected');
return true;
}
function astr(label, input) {
if (typeof input !== 'string')
throw new Error(`${label}: string expected`);
return true;
}
function anumber(n) {
if (!Number.isSafeInteger(n))
throw new Error(`invalid integer: ${n}`);
}
function aArr(input) {
if (!Array.isArray(input))
throw new Error('array expected');
}
function astrArr(label, input) {
if (!isArrayOf(true, input))
throw new Error(`${label}: array of strings expected`);
}
function anumArr(label, input) {
if (!isArrayOf(false, input))
throw new Error(`${label}: array of numbers expected`);
}
/**
* @__NO_SIDE_EFFECTS__
*/
function chain(...args) {
const id = (a) => a;
// Wrap call in closure so JIT can inline calls
const wrap = (a, b) => (c) => a(b(c));
// Construct chain of args[-1].encode(args[-2].encode([...]))
const encode = args.map((x) => x.encode).reduceRight(wrap, id);
// Construct chain of args[0].decode(args[1].decode(...))
const decode = args.map((x) => x.decode).reduce(wrap, id);
return { encode, decode };
}
/**
* Encodes integer radix representation to array of strings using alphabet and back.
* Could also be array of strings.
* @__NO_SIDE_EFFECTS__
*/
function alphabet(letters) {
// mapping 1 to "b"
const lettersA = typeof letters === 'string' ? letters.split('') : letters;
const len = lettersA.length;
astrArr('alphabet', lettersA);
// mapping "b" to 1
const indexes = new Map(lettersA.map((l, i) => [l, i]));
return {
encode: (digits) => {
aArr(digits);
return digits.map((i) => {
if (!Number.isSafeInteger(i) || i < 0 || i >= len)
throw new Error(`alphabet.encode: digit index outside alphabet "${i}". Allowed: ${letters}`);
return lettersA[i];
});
},
decode: (input) => {
aArr(input);
return input.map((letter) => {
astr('alphabet.decode', letter);
const i = indexes.get(letter);
if (i === undefined)
throw new Error(`Unknown letter: "${letter}". Allowed: ${letters}`);
return i;
});
},
};
}
/**
* @__NO_SIDE_EFFECTS__
*/
function join(separator = '') {
astr('join', separator);
return {
encode: (from) => {
astrArr('join.decode', from);
return from.join(separator);
},
decode: (to) => {
astr('join.decode', to);
return to.split(separator);
},
};
}
/**
* Pad strings array so it has integer number of bits
* @__NO_SIDE_EFFECTS__
*/
function padding(bits, chr = '=') {
anumber(bits);
astr('padding', chr);
return {
encode(data) {
astrArr('padding.encode', data);
while ((data.length * bits) % 8)
data.push(chr);
return data;
},
decode(input) {
astrArr('padding.decode', input);
let end = input.length;
if ((end * bits) % 8)
throw new Error('padding: invalid, string should have whole number of bytes');
for (; end > 0 && input[end - 1] === chr; end--) {
const last = end - 1;
const byte = last * bits;
if (byte % 8 === 0)
throw new Error('padding: invalid, string has too much padding');
}
return input.slice(0, end);
},
};
}
/**
* @__NO_SIDE_EFFECTS__
*/
function normalize(fn) {
afn(fn);
return { encode: (from) => from, decode: (to) => fn(to) };
}
/**
* Slow: O(n^2) time complexity
*/
function convertRadix(data, from, to) {
// base 1 is impossible
if (from < 2)
throw new Error(`convertRadix: invalid from=${from}, base cannot be less than 2`);
if (to < 2)
throw new Error(`convertRadix: invalid to=${to}, base cannot be less than 2`);
aArr(data);
if (!data.length)
return [];
let pos = 0;
const res = [];
const digits = Array.from(data, (d) => {
anumber(d);
if (d < 0 || d >= from)
throw new Error(`invalid integer: ${d}`);
return d;
});
const dlen = digits.length;
while (true) {
let carry = 0;
let done = true;
for (let i = pos; i < dlen; i++) {
const digit = digits[i];
const fromCarry = from * carry;
const digitBase = fromCarry + digit;
if (!Number.isSafeInteger(digitBase) ||
fromCarry / from !== carry ||
digitBase - digit !== fromCarry) {
throw new Error('convertRadix: carry overflow');
}
const div = digitBase / to;
carry = digitBase % to;
const rounded = Math.floor(div);
digits[i] = rounded;
if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)
throw new Error('convertRadix: carry overflow');
if (!done)
continue;
else if (!rounded)
pos = i;
else
done = false;
}
res.push(carry);
if (done)
break;
}
for (let i = 0; i < data.length - 1 && data[i] === 0; i++)
res.push(0);
return res.reverse();
}
const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));
const radix2carry = /* @__NO_SIDE_EFFECTS__ */ (from, to) => from + (to - gcd(from, to));
const powers = /* @__PURE__ */ (() => {
let res = [];
for (let i = 0; i < 40; i++)
res.push(2 ** i);
return res;
})();
/**
* Implemented with numbers, because BigInt is 5x slower
*/
function convertRadix2(data, from, to, padding) {
aArr(data);
if (from <= 0 || from > 32)
throw new Error(`convertRadix2: wrong from=${from}`);
if (to <= 0 || to > 32)
throw new Error(`convertRadix2: wrong to=${to}`);
if (radix2carry(from, to) > 32) {
throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`);
}
let carry = 0;
let pos = 0; // bitwise position in current element
const max = powers[from];
const mask = powers[to] - 1;
const res = [];
for (const n of data) {
anumber(n);
if (n >= max)
throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
carry = (carry << from) | n;
if (pos + from > 32)
throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
pos += from;
for (; pos >= to; pos -= to)
res.push(((carry >> (pos - to)) & mask) >>> 0);
const pow = powers[pos];
if (pow === undefined)
throw new Error('invalid carry');
carry &= pow - 1; // clean carry, otherwise it will cause overflow
}
carry = (carry << (to - pos)) & mask;
if (!padding && pos >= from)
throw new Error('Excess padding');
if (!padding && carry > 0)
throw new Error(`Non-zero padding: ${carry}`);
if (padding && pos > 0)
res.push(carry >>> 0);
return res;
}
/**
* @__NO_SIDE_EFFECTS__
*/
function radix(num) {
anumber(num);
const _256 = 2 ** 8;
return {
encode: (bytes) => {
if (!isBytes(bytes))
throw new Error('radix.encode input should be Uint8Array');
return convertRadix(Array.from(bytes), _256, num);
},
decode: (digits) => {
anumArr('radix.decode', digits);
return Uint8Array.from(convertRadix(digits, num, _256));
},
};
}
/**
* If both bases are power of same number (like `2**8 <-> 2**64`),
* there is a linear algorithm. For now we have implementation for power-of-two bases only.
* @__NO_SIDE_EFFECTS__
*/
function radix2(bits, revPadding = false) {
anumber(bits);
if (bits <= 0 || bits > 32)
throw new Error('radix2: bits should be in (0..32]');
if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)
throw new Error('radix2: carry overflow');
return {
encode: (bytes) => {
if (!isBytes(bytes))
throw new Error('radix2.encode input should be Uint8Array');
return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
},
decode: (digits) => {
anumArr('radix2.decode', digits);
return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
},
};
}
function unsafeWrapper(fn) {
afn(fn);
return function (...args) {
try {
return fn.apply(null, args);
}
catch (e) { }
};
}
function checksum(len, fn) {
anumber(len);
afn(fn);
return {
encode(data) {
if (!isBytes(data))
throw new Error('checksum.encode: input should be Uint8Array');
const sum = fn(data).slice(0, len);
const res = new Uint8Array(data.length + len);
res.set(data);
res.set(sum, data.length);
return res;
},
decode(data) {
if (!isBytes(data))
throw new Error('checksum.decode: input should be Uint8Array');
const payload = data.slice(0, -len);
const oldChecksum = data.slice(-len);
const newChecksum = fn(payload).slice(0, len);
for (let i = 0; i < len; i++)
if (newChecksum[i] !== oldChecksum[i])
throw new Error('Invalid checksum');
return payload;
},
};
}
// prettier-ignore
exports.utils = {
alphabet, chain, checksum, convertRadix, convertRadix2, radix, radix2, join, padding,
};
// RFC 4648 aka RFC 3548
// ---------------------
/**
* base16 encoding from RFC 4648.
* @example
* ```js
* base16.encode(Uint8Array.from([0x12, 0xab]));
* // => '12AB'
* ```
*/
exports.base16 = chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));
/**
* base32 encoding from RFC 4648. Has padding.
* Use `base32nopad` for unpadded version.
* Also check out `base32hex`, `base32hexnopad`, `base32crockford`.
* @example
* ```js
* base32.encode(Uint8Array.from([0x12, 0xab]));
* // => 'CKVQ===='
* base32.decode('CKVQ====');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
exports.base32 = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''));
/**
* base32 encoding from RFC 4648. No padding.
* Use `base32` for padded version.
* Also check out `base32hex`, `base32hexnopad`, `base32crockford`.
* @example
* ```js
* base32nopad.encode(Uint8Array.from([0x12, 0xab]));
* // => 'CKVQ'
* base32nopad.decode('CKVQ');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
exports.base32nopad = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), join(''));
/**
* base32 encoding from RFC 4648. Padded. Compared to ordinary `base32`, slightly different alphabet.
* Use `base32hexnopad` for unpadded version.
* @example
* ```js
* base32hex.encode(Uint8Array.from([0x12, 0xab]));
* // => '2ALG===='
* base32hex.decode('2ALG====');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
exports.base32hex = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join(''));
/**
* base32 encoding from RFC 4648. No padding. Compared to ordinary `base32`, slightly different alphabet.
* Use `base32hex` for padded version.
* @example
* ```js
* base32hexnopad.encode(Uint8Array.from([0x12, 0xab]));
* // => '2ALG'
* base32hexnopad.decode('2ALG');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
exports.base32hexnopad = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), join(''));
/**
* base32 encoding from RFC 4648. Doug Crockford's version.
* https://www.crockford.com/base32.html
* @example
* ```js
* base32crockford.encode(Uint8Array.from([0x12, 0xab]));
* // => '2ANG'
* base32crockford.decode('2ANG');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
exports.base32crockford = chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1')));
// Built-in base64 conversion https://caniuse.com/mdn-javascript_builtins_uint8array_frombase64
// prettier-ignore
const hasBase64Builtin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toBase64 === 'function' &&
typeof Uint8Array.fromBase64 === 'function')();
const decodeBase64Builtin = (s, isUrl) => {
astr('base64', s);
const re = isUrl ? /^[A-Za-z0-9=_-]+$/ : /^[A-Za-z0-9=+/]+$/;
const alphabet = isUrl ? 'base64url' : 'base64';
if (s.length > 0 && !re.test(s))
throw new Error('invalid base64');
return Uint8Array.fromBase64(s, { alphabet, lastChunkHandling: 'strict' });
};
/**
* base64 from RFC 4648. Padded.
* Use `base64nopad` for unpadded version.
* Also check out `base64url`, `base64urlnopad`.
* Falls back to built-in function, when available.
* @example
* ```js
* base64.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs='
* base64.decode('Eqs=');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
// prettier-ignore
exports.base64 = hasBase64Builtin ? {
encode(b) { abytes(b); return b.toBase64(); },
decode(s) { return decodeBase64Builtin(s, false); },
} : chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join(''));
/**
* base64 from RFC 4648. No padding.
* Use `base64` for padded version.
* @example
* ```js
* base64nopad.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs'
* base64nopad.decode('Eqs');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
exports.base64nopad = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), join(''));
/**
* base64 from RFC 4648, using URL-safe alphabet. Padded.
* Use `base64urlnopad` for unpadded version.
* Falls back to built-in function, when available.
* @example
* ```js
* base64url.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs='
* base64url.decode('Eqs=');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
// prettier-ignore
exports.base64url = hasBase64Builtin ? {
encode(b) { abytes(b); return b.toBase64({ alphabet: 'base64url' }); },
decode(s) { return decodeBase64Builtin(s, true); },
} : chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join(''));
/**
* base64 from RFC 4648, using URL-safe alphabet. No padding.
* Use `base64url` for padded version.
* @example
* ```js
* base64urlnopad.encode(Uint8Array.from([0x12, 0xab]));
* // => 'Eqs'
* base64urlnopad.decode('Eqs');
* // => Uint8Array.from([0x12, 0xab])
* ```
*/
exports.base64urlnopad = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), join(''));
// base58 code
// -----------
const genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => chain(radix(58), alphabet(abc), join(''));
/**
* base58: base64 without ambigous characters +, /, 0, O, I, l.
* Quadratic (O(n^2)) - so, can't be used on large inputs.
* @example
* ```js
* base58.decode('01abcdef');
* // => '3UhJW'
* ```
*/
exports.base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
/**
* base58: flickr version. Check out `base58`.
*/
exports.base58flickr = genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');
/**
* base58: XRP version. Check out `base58`.
*/
exports.base58xrp = genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz');
// Data len (index) -> encoded block len
const XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];
/**
* base58: XMR version. Check out `base58`.
* Done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.
* Block encoding significantly reduces quadratic complexity of base58.
*/
exports.base58xmr = {
encode(data) {
let res = '';
for (let i = 0; i < data.length; i += 8) {
const block = data.subarray(i, i + 8);
res += exports.base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], '1');
}
return res;
},
decode(str) {
let res = [];
for (let i = 0; i < str.length; i += 11) {
const slice = str.slice(i, i + 11);
const blockLen = XMR_BLOCK_LEN.indexOf(slice.length);
const block = exports.base58.decode(slice);
for (let j = 0; j < block.length - blockLen; j++) {
if (block[j] !== 0)
throw new Error('base58xmr: wrong padding');
}
res = res.concat(Array.from(block.slice(block.length - blockLen)));
}
return Uint8Array.from(res);
},
};
/**
* Method, which creates base58check encoder.
* Requires function, calculating sha256.
*/
const createBase58check = (sha256) => chain(checksum(4, (data) => sha256(sha256(data))), exports.base58);
exports.createBase58check = createBase58check;
/**
* Use `createBase58check` instead.
* @deprecated
*/
exports.base58check = exports.createBase58check;
const BECH_ALPHABET = chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));
const POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
function bech32Polymod(pre) {
const b = pre >> 25;
let chk = (pre & 0x1ffffff) << 5;
for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {
if (((b >> i) & 1) === 1)
chk ^= POLYMOD_GENERATORS[i];
}
return chk;
}
function bechChecksum(prefix, words, encodingConst = 1) {
const len = prefix.length;
let chk = 1;
for (let i = 0; i < len; i++) {
const c = prefix.charCodeAt(i);
if (c < 33 || c > 126)
throw new Error(`Invalid prefix (${prefix})`);
chk = bech32Polymod(chk) ^ (c >> 5);
}
chk = bech32Polymod(chk);
for (let i = 0; i < len; i++)
chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);
for (let v of words)
chk = bech32Polymod(chk) ^ v;
for (let i = 0; i < 6; i++)
chk = bech32Polymod(chk);
chk ^= encodingConst;
return BECH_ALPHABET.encode(convertRadix2([chk % powers[30]], 30, 5, false));
}
/**
* @__NO_SIDE_EFFECTS__
*/
function genBech32(encoding) {
const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;
const _words = radix2(5);
const fromWords = _words.decode;
const toWords = _words.encode;
const fromWordsUnsafe = unsafeWrapper(fromWords);
function encode(prefix, words, limit = 90) {
astr('bech32.encode prefix', prefix);
if (isBytes(words))
words = Array.from(words);
anumArr('bech32.encode', words);
const plen = prefix.length;
if (plen === 0)
throw new TypeError(`Invalid prefix length ${plen}`);
const actualLength = plen + 7 + words.length;
if (limit !== false && actualLength > limit)
throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);
const lowered = prefix.toLowerCase();
const sum = bechChecksum(lowered, words, ENCODING_CONST);
return `${lowered}1${BECH_ALPHABET.encode(words)}${sum}`;
}
function decode(str, limit = 90) {
astr('bech32.decode input', str);
const slen = str.length;
if (slen < 8 || (limit !== false && slen > limit))
throw new TypeError(`invalid string length: ${slen} (${str}). Expected (8..${limit})`);
// don't allow mixed case
const lowered = str.toLowerCase();
if (str !== lowered && str !== str.toUpperCase())
throw new Error(`String must be lowercase or uppercase`);
const sepIndex = lowered.lastIndexOf('1');
if (sepIndex === 0 || sepIndex === -1)
throw new Error(`Letter "1" must be present between prefix and data only`);
const prefix = lowered.slice(0, sepIndex);
const data = lowered.slice(sepIndex + 1);
if (data.length < 6)
throw new Error('Data must be at least 6 characters long');
const words = BECH_ALPHABET.decode(data).slice(0, -6);
const sum = bechChecksum(prefix, words, ENCODING_CONST);
if (!data.endsWith(sum))
throw new Error(`Invalid checksum in ${str}: expected "${sum}"`);
return { prefix, words };
}
const decodeUnsafe = unsafeWrapper(decode);
function decodeToBytes(str) {
const { prefix, words } = decode(str, false);
return { prefix, words, bytes: fromWords(words) };
}
function encodeFromBytes(prefix, bytes) {
return encode(prefix, toWords(bytes));
}
return {
encode,
decode,
encodeFromBytes,
decodeToBytes,
decodeUnsafe,
fromWords,
fromWordsUnsafe,
toWords,
};
}
/**
* bech32 from BIP 173. Operates on words.
* For high-level, check out scure-btc-signer:
* https://github.com/paulmillr/scure-btc-signer.
*/
exports.bech32 = genBech32('bech32');
/**
* bech32m from BIP 350. Operates on words.
* It was to mitigate `bech32` weaknesses.
* For high-level, check out scure-btc-signer:
* https://github.com/paulmillr/scure-btc-signer.
*/
exports.bech32m = genBech32('bech32m');
/**
* UTF-8-to-byte decoder. Uses built-in TextDecoder / TextEncoder.
* @example
* ```js
* const b = utf8.decode("hey"); // => new Uint8Array([ 104, 101, 121 ])
* const str = utf8.encode(b); // "hey"
* ```
*/
exports.utf8 = {
encode: (data) => new TextDecoder().decode(data),
decode: (str) => new TextEncoder().encode(str),
};
// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
// prettier-ignore
const hasHexBuiltin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toHex === 'function' &&
typeof Uint8Array.fromHex === 'function')();
// prettier-ignore
const hexBuiltin = {
encode(data) { abytes(data); return data.toHex(); },
decode(s) { astr('hex', s); return Uint8Array.fromHex(s); },
};
/**
* hex string decoder. Uses built-in function, when available.
* @example
* ```js
* const b = hex.decode("0102ff"); // => new Uint8Array([ 1, 2, 255 ])
* const str = hex.encode(b); // "0102ff"
* ```
*/
exports.hex = hasHexBuiltin
? hexBuiltin
: chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => {
if (typeof s !== 'string' || s.length % 2 !== 0)
throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);
return s.toLowerCase();
}));
// prettier-ignore
const CODERS = {
utf8: exports.utf8, hex: exports.hex, base16: exports.base16, base32: exports.base32, base64: exports.base64, base64url: exports.base64url, base58: exports.base58, base58xmr: exports.base58xmr
};
const coderTypeError = 'Invalid encoding type. Available types: utf8, hex, base16, base32, base64, base64url, base58, base58xmr';
/** @deprecated */
const bytesToString = (type, bytes) => {
if (typeof type !== 'string' || !CODERS.hasOwnProperty(type))
throw new TypeError(coderTypeError);
if (!isBytes(bytes))
throw new TypeError('bytesToString() expects Uint8Array');
return CODERS[type].encode(bytes);
};
exports.bytesToString = bytesToString;
/** @deprecated */
exports.str = exports.bytesToString; // as in python, but for bytes only
/** @deprecated */
const stringToBytes = (type, str) => {
if (!CODERS.hasOwnProperty(type))
throw new TypeError(coderTypeError);
if (typeof str !== 'string')
throw new TypeError('stringToBytes() expects string');
return CODERS[type].decode(str);
};
exports.stringToBytes = stringToBytes;
/** @deprecated */
exports.bytes = exports.stringToBytes;
//# sourceMappingURL=index.js.map

1
node_modules/@scure/base/lib/index.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

70
node_modules/@scure/base/package.json generated vendored Normal file
View File

@@ -0,0 +1,70 @@
{
"name": "@scure/base",
"version": "1.2.6",
"description": "Secure, audited & 0-dep implementation of base64, bech32, base58, base32 & base16",
"files": [
"lib/index.js",
"lib/index.js.map",
"lib/index.d.ts",
"lib/index.d.ts.map",
"lib/esm/index.js",
"lib/esm/index.js.map",
"lib/esm/index.d.ts",
"lib/esm/index.d.ts.map",
"lib/esm/package.json",
"index.ts"
],
"main": "./lib/index.js",
"module": "./lib/esm/index.js",
"types": "./lib/index.d.ts",
"exports": {
".": {
"import": "./lib/esm/index.js",
"require": "./lib/index.js"
}
},
"scripts": {
"bench": "node test/benchmark/index.js",
"build": "tsc && tsc -p tsconfig.cjs.json",
"build:release": "npx jsbt esbuild test/build",
"lint": "prettier --check index.ts",
"format": "prettier --write index.ts",
"test": "node test/index.js",
"test:bun": "bun test/index.js",
"test:deno": "deno --allow-env --allow-read test/index.js && deno test/deno.ts"
},
"sideEffects": false,
"author": "Paul Miller (https://paulmillr.com)",
"license": "MIT",
"homepage": "https://paulmillr.com/noble/#scure",
"repository": {
"type": "git",
"url": "git+https://github.com/paulmillr/scure-base.git"
},
"devDependencies": {
"@noble/hashes": "1.8.0",
"@paulmillr/jsbt": "0.3.3",
"@types/node": "22.15.23",
"fast-check": "4.1.1",
"micro-bmark": "0.4.2",
"micro-should": "0.5.3",
"prettier": "3.5.3",
"typescript": "5.8.3"
},
"keywords": [
"bech32",
"bech32m",
"base64",
"base58",
"base32",
"base16",
"rfc4648",
"rfc3548",
"crockford",
"encode",
"encoder",
"base-x",
"base"
],
"funding": "https://paulmillr.com/funding/"
}

21
node_modules/@scure/bip32/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

141
node_modules/@scure/bip32/README.md generated vendored Normal file
View File

@@ -0,0 +1,141 @@
# scure-bip32
Audited & minimal implementation of BIP32 hierarchical deterministic (HD) wallets over secp256k1.
- 🔒 [Audited](#security) by an independent security firm
- 🔻 Tree-shakeable: unused code is excluded from your builds
- 📦 ESM and common.js
- ➰ Only 3 audited dependencies by the same author:
[noble-curves](https://github.com/paulmillr/noble-curves),
[noble-hashes](https://github.com/paulmillr/noble-hashes),
and [scure-base](https://github.com/paulmillr/scure-base)
- 🪶 18KB gzipped with all dependencies bundled
Check out [scure-bip39](https://github.com/paulmillr/scure-bip39) if you need mnemonic phrases.
See [key-producer](https://github.com/paulmillr/micro-key-producer) if you need SLIP-0010/BIP32 ed25519 hdkey implementation.
### This library belongs to _scure_
> **scure** — audited micro-libraries.
- Zero or minimal dependencies
- Highly readable TypeScript / JS code
- PGP-signed releases and transparent NPM builds
- Check out [homepage](https://paulmillr.com/noble/#scure) & all libraries:
[base](https://github.com/paulmillr/scure-base),
[bip32](https://github.com/paulmillr/scure-bip32),
[bip39](https://github.com/paulmillr/scure-bip39),
[btc-signer](https://github.com/paulmillr/scure-btc-signer),
[starknet](https://github.com/paulmillr/scure-starknet)
## Usage
> `npm install @scure/bip32`
> `deno add jsr:@scure/bip32`
> `deno doc jsr:@scure/bip32` # command-line documentation
This module exports a single class `HDKey`, which should be used like this:
```ts
import { HDKey } from '@scure/bip32';
const hdkey1 = HDKey.fromMasterSeed(seed);
const hdkey2 = HDKey.fromExtendedKey(base58key);
const hdkey3 = HDKey.fromJSON({ xpriv: string });
// props
[hdkey1.depth, hdkey1.index, hdkey1.chainCode];
console.log(hdkey2.privateKey, hdkey2.publicKey);
console.log(hdkey3.derive("m/0/2147483647'/1"));
const sig = hdkey3.sign(hash);
hdkey3.verify(hash, sig);
```
Note: `chainCode` property is essentially a private part
of a secret "master" key, it should be guarded from unauthorized access.
The full API is:
```ts
class HDKey {
public static HARDENED_OFFSET: number;
public static fromMasterSeed(seed: Uint8Array, versions: Versions): HDKey;
public static fromExtendedKey(base58key: string, versions: Versions): HDKey;
public static fromJSON(json: { xpriv: string }): HDKey;
readonly versions: Versions;
readonly depth: number = 0;
readonly index: number = 0;
readonly chainCode: Uint8Array | null = null;
readonly parentFingerprint: number = 0;
get fingerprint(): number;
get identifier(): Uint8Array | undefined;
get pubKeyHash(): Uint8Array | undefined;
get privateKey(): Uint8Array | null;
get publicKey(): Uint8Array | null;
get privateExtendedKey(): string;
get publicExtendedKey(): string;
derive(path: string): HDKey;
deriveChild(index: number): HDKey;
sign(hash: Uint8Array): Uint8Array;
verify(hash: Uint8Array, signature: Uint8Array): boolean;
wipePrivateData(): this;
}
interface Versions {
private: number;
public: number;
}
```
The module implements [bip32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) standard:
check it out for additional documentation.
The implementation is loosely based on cryptocoinjs/hdkey, [which has MIT License](#LICENSE).
## Security
The library has been independently audited:
- at version 1.0.1, in Jan 2022, by [cure53](https://cure53.de)
- PDFs: [online](https://cure53.de/pentest-report_hashing-libs.pdf), [offline](./audit/2022-01-05-cure53-audit-nbl2.pdf)
- [Changes since audit](https://github.com/paulmillr/scure-bip32/compare/1.0.0..main).
- The audit has been funded by [Ethereum Foundation](https://ethereum.org/en/) with help of [Nomic Labs](https://nomiclabs.io)
The library was initially developed for [js-ethereum-cryptography](https://github.com/ethereum/js-ethereum-cryptography).
At commit [ae00e6d7](https://github.com/ethereum/js-ethereum-cryptography/commit/ae00e6d7d24fb3c76a1c7fe10039f6ecd120b77e),
it was extracted to a separate package called `micro-bip32`.
After the audit we've decided to use `@scure` NPM namespace for security.
### Supply chain security
- **Commits** are signed with PGP keys, to prevent forgery. Make sure to verify commit signatures
- **Releases** are transparent and built on GitHub CI. Make sure to verify [provenance](https://docs.npmjs.com/generating-provenance-statements) logs
- **Rare releasing** is followed to ensure less re-audit need for end-users
- **Dependencies** are minimized and locked-down: any dependency could get hacked and users will be downloading malware with every install.
- We make sure to use as few dependencies as possible
- Automatic dep updates are prevented by locking-down version ranges; diffs are checked with `npm-diff`
- **Dev Dependencies** are disabled for end-users; they are only used to develop / build the source code
For this package, there are 3 dependencies; and a few dev dependencies:
- [noble-hashes](https://github.com/paulmillr/noble-hashes) provides cryptographic hashing functionality
- [noble-curves](https://github.com/paulmillr/noble-curves) provides ECDSA
- [scure-base](https://github.com/paulmillr/scure-base) provides base58
- micro-bmark, micro-should and jsbt are used for benchmarking / testing / build tooling and developed by the same author
- prettier, fast-check and typescript are used for code quality / test generation / ts compilation. It's hard to audit their source code thoroughly and fully because of their size
## Contributing & testing
- `npm install && npm run build && npm test` will build the code and run tests.
- `npm run lint` / `npm run format` will run linter / fix linter issues.
- `npm run build:release` will build single file
## License
[MIT License](./LICENSE)
Copyright (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com)

333
node_modules/@scure/bip32/index.ts generated vendored Normal file
View File

@@ -0,0 +1,333 @@
/**
* @module BIP32 hierarchical deterministic (HD) wallets over secp256k1.
* @example
* ```js
* import { HDKey } from "@scure/bip32";
* const hdkey1 = HDKey.fromMasterSeed(seed);
* const hdkey2 = HDKey.fromExtendedKey(base58key);
* const hdkey3 = HDKey.fromJSON({ xpriv: string });
*
* // props
* [hdkey1.depth, hdkey1.index, hdkey1.chainCode];
* console.log(hdkey2.privateKey, hdkey2.publicKey);
* console.log(hdkey3.derive("m/0/2147483647'/1"));
* const sig = hdkey3.sign(hash);
* hdkey3.verify(hash, sig);
* ```
*/
/*! scure-bip32 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) */
import { mod } from '@noble/curves/abstract/modular';
import { secp256k1 as secp } from '@noble/curves/secp256k1';
import { hmac } from '@noble/hashes/hmac';
import { ripemd160 } from '@noble/hashes/legacy';
import { sha256, sha512 } from '@noble/hashes/sha2';
import {
abytes,
bytesToHex,
concatBytes,
createView,
hexToBytes,
utf8ToBytes,
} from '@noble/hashes/utils';
import { createBase58check } from '@scure/base';
const Point = secp.ProjectivePoint;
const base58check = createBase58check(sha256);
function bytesToNumber(bytes: Uint8Array): bigint {
abytes(bytes);
const h = bytes.length === 0 ? '0' : bytesToHex(bytes);
return BigInt('0x' + h);
}
function numberToBytes(num: bigint): Uint8Array {
if (typeof num !== 'bigint') throw new Error('bigint expected');
return hexToBytes(num.toString(16).padStart(64, '0'));
}
const MASTER_SECRET = utf8ToBytes('Bitcoin seed');
// Bitcoin hardcoded by default
const BITCOIN_VERSIONS: Versions = { private: 0x0488ade4, public: 0x0488b21e };
export const HARDENED_OFFSET: number = 0x80000000;
export interface Versions {
private: number;
public: number;
}
const hash160 = (data: Uint8Array) => ripemd160(sha256(data));
const fromU32 = (data: Uint8Array) => createView(data).getUint32(0, false);
const toU32 = (n: number) => {
if (!Number.isSafeInteger(n) || n < 0 || n > 2 ** 32 - 1) {
throw new Error('invalid number, should be from 0 to 2**32-1, got ' + n);
}
const buf = new Uint8Array(4);
createView(buf).setUint32(0, n, false);
return buf;
};
interface HDKeyOpt {
versions?: Versions;
depth?: number;
index?: number;
parentFingerprint?: number;
chainCode?: Uint8Array;
publicKey?: Uint8Array;
privateKey?: Uint8Array | bigint;
}
export class HDKey {
get fingerprint(): number {
if (!this.pubHash) {
throw new Error('No publicKey set!');
}
return fromU32(this.pubHash);
}
get identifier(): Uint8Array | undefined {
return this.pubHash;
}
get pubKeyHash(): Uint8Array | undefined {
return this.pubHash;
}
get privateKey(): Uint8Array | null {
return this.privKeyBytes || null;
}
get publicKey(): Uint8Array | null {
return this.pubKey || null;
}
get privateExtendedKey(): string {
const priv = this.privateKey;
if (!priv) {
throw new Error('No private key');
}
return base58check.encode(
this.serialize(this.versions.private, concatBytes(new Uint8Array([0]), priv))
);
}
get publicExtendedKey(): string {
if (!this.pubKey) {
throw new Error('No public key');
}
return base58check.encode(this.serialize(this.versions.public, this.pubKey));
}
public static fromMasterSeed(seed: Uint8Array, versions: Versions = BITCOIN_VERSIONS): HDKey {
abytes(seed);
if (8 * seed.length < 128 || 8 * seed.length > 512) {
throw new Error(
'HDKey: seed length must be between 128 and 512 bits; 256 bits is advised, got ' +
seed.length
);
}
const I = hmac(sha512, MASTER_SECRET, seed);
return new HDKey({
versions,
chainCode: I.slice(32),
privateKey: I.slice(0, 32),
});
}
public static fromExtendedKey(base58key: string, versions: Versions = BITCOIN_VERSIONS): HDKey {
// => version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
const keyBuffer: Uint8Array = base58check.decode(base58key);
const keyView = createView(keyBuffer);
const version = keyView.getUint32(0, false);
const opt = {
versions,
depth: keyBuffer[4],
parentFingerprint: keyView.getUint32(5, false),
index: keyView.getUint32(9, false),
chainCode: keyBuffer.slice(13, 45),
};
const key = keyBuffer.slice(45);
const isPriv = key[0] === 0;
if (version !== versions[isPriv ? 'private' : 'public']) {
throw new Error('Version mismatch');
}
if (isPriv) {
return new HDKey({ ...opt, privateKey: key.slice(1) });
} else {
return new HDKey({ ...opt, publicKey: key });
}
}
public static fromJSON(json: { xpriv: string }): HDKey {
return HDKey.fromExtendedKey(json.xpriv);
}
public readonly versions: Versions;
public readonly depth: number = 0;
public readonly index: number = 0;
public readonly chainCode: Uint8Array | null = null;
public readonly parentFingerprint: number = 0;
private privKey?: bigint;
private privKeyBytes?: Uint8Array;
private pubKey?: Uint8Array;
private pubHash: Uint8Array | undefined;
constructor(opt: HDKeyOpt) {
if (!opt || typeof opt !== 'object') {
throw new Error('HDKey.constructor must not be called directly');
}
this.versions = opt.versions || BITCOIN_VERSIONS;
this.depth = opt.depth || 0;
this.chainCode = opt.chainCode || null;
this.index = opt.index || 0;
this.parentFingerprint = opt.parentFingerprint || 0;
if (!this.depth) {
if (this.parentFingerprint || this.index) {
throw new Error('HDKey: zero depth with non-zero index/parent fingerprint');
}
}
if (opt.publicKey && opt.privateKey) {
throw new Error('HDKey: publicKey and privateKey at same time.');
}
if (opt.privateKey) {
if (!secp.utils.isValidPrivateKey(opt.privateKey)) {
throw new Error('Invalid private key');
}
this.privKey =
typeof opt.privateKey === 'bigint' ? opt.privateKey : bytesToNumber(opt.privateKey);
this.privKeyBytes = numberToBytes(this.privKey);
this.pubKey = secp.getPublicKey(opt.privateKey, true);
} else if (opt.publicKey) {
this.pubKey = Point.fromHex(opt.publicKey).toRawBytes(true); // force compressed point
} else {
throw new Error('HDKey: no public or private key provided');
}
this.pubHash = hash160(this.pubKey);
}
public derive(path: string): HDKey {
if (!/^[mM]'?/.test(path)) {
throw new Error('Path must start with "m" or "M"');
}
if (/^[mM]'?$/.test(path)) {
return this;
}
const parts = path.replace(/^[mM]'?\//, '').split('/');
// tslint:disable-next-line
let child: HDKey = this;
for (const c of parts) {
const m = /^(\d+)('?)$/.exec(c);
const m1 = m && m[1];
if (!m || m.length !== 3 || typeof m1 !== 'string')
throw new Error('invalid child index: ' + c);
let idx = +m1;
if (!Number.isSafeInteger(idx) || idx >= HARDENED_OFFSET) {
throw new Error('Invalid index');
}
// hardened key
if (m[2] === "'") {
idx += HARDENED_OFFSET;
}
child = child.deriveChild(idx);
}
return child;
}
public deriveChild(index: number): HDKey {
if (!this.pubKey || !this.chainCode) {
throw new Error('No publicKey or chainCode set');
}
let data = toU32(index);
if (index >= HARDENED_OFFSET) {
// Hardened
const priv = this.privateKey;
if (!priv) {
throw new Error('Could not derive hardened child key');
}
// Hardened child: 0x00 || ser256(kpar) || ser32(index)
data = concatBytes(new Uint8Array([0]), priv, data);
} else {
// Normal child: serP(point(kpar)) || ser32(index)
data = concatBytes(this.pubKey, data);
}
const I = hmac(sha512, this.chainCode, data);
const childTweak = bytesToNumber(I.slice(0, 32));
const chainCode = I.slice(32);
if (!secp.utils.isValidPrivateKey(childTweak)) {
throw new Error('Tweak bigger than curve order');
}
const opt: HDKeyOpt = {
versions: this.versions,
chainCode,
depth: this.depth + 1,
parentFingerprint: this.fingerprint,
index,
};
try {
// Private parent key -> private child key
if (this.privateKey) {
const added = mod(this.privKey! + childTweak, secp.CURVE.n);
if (!secp.utils.isValidPrivateKey(added)) {
throw new Error('The tweak was out of range or the resulted private key is invalid');
}
opt.privateKey = added;
} else {
const added = Point.fromHex(this.pubKey).add(Point.fromPrivateKey(childTweak));
// Cryptographically impossible: hmac-sha512 preimage would need to be found
if (added.equals(Point.ZERO)) {
throw new Error('The tweak was equal to negative P, which made the result key invalid');
}
opt.publicKey = added.toRawBytes(true);
}
return new HDKey(opt);
} catch (err) {
return this.deriveChild(index + 1);
}
}
public sign(hash: Uint8Array): Uint8Array {
if (!this.privateKey) {
throw new Error('No privateKey set!');
}
abytes(hash, 32);
return secp.sign(hash, this.privKey!).toCompactRawBytes();
}
public verify(hash: Uint8Array, signature: Uint8Array): boolean {
abytes(hash, 32);
abytes(signature, 64);
if (!this.publicKey) {
throw new Error('No publicKey set!');
}
let sig;
try {
sig = secp.Signature.fromCompact(signature);
} catch (error) {
return false;
}
return secp.verify(sig, hash, this.publicKey);
}
public wipePrivateData(): this {
this.privKey = undefined;
if (this.privKeyBytes) {
this.privKeyBytes.fill(0);
this.privKeyBytes = undefined;
}
return this;
}
public toJSON(): { xpriv: string; xpub: string } {
return {
xpriv: this.privateExtendedKey,
xpub: this.publicExtendedKey,
};
}
private serialize(version: number, key: Uint8Array) {
if (!this.chainCode) {
throw new Error('No chainCode set');
}
abytes(key, 33);
// version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
return concatBytes(
toU32(version),
new Uint8Array([this.depth]),
toU32(this.parentFingerprint),
toU32(this.index),
this.chainCode,
key
);
}
}

50
node_modules/@scure/bip32/lib/esm/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,50 @@
export declare const HARDENED_OFFSET: number;
export interface Versions {
private: number;
public: number;
}
interface HDKeyOpt {
versions?: Versions;
depth?: number;
index?: number;
parentFingerprint?: number;
chainCode?: Uint8Array;
publicKey?: Uint8Array;
privateKey?: Uint8Array | bigint;
}
export declare class HDKey {
get fingerprint(): number;
get identifier(): Uint8Array | undefined;
get pubKeyHash(): Uint8Array | undefined;
get privateKey(): Uint8Array | null;
get publicKey(): Uint8Array | null;
get privateExtendedKey(): string;
get publicExtendedKey(): string;
static fromMasterSeed(seed: Uint8Array, versions?: Versions): HDKey;
static fromExtendedKey(base58key: string, versions?: Versions): HDKey;
static fromJSON(json: {
xpriv: string;
}): HDKey;
readonly versions: Versions;
readonly depth: number;
readonly index: number;
readonly chainCode: Uint8Array | null;
readonly parentFingerprint: number;
private privKey?;
private privKeyBytes?;
private pubKey?;
private pubHash;
constructor(opt: HDKeyOpt);
derive(path: string): HDKey;
deriveChild(index: number): HDKey;
sign(hash: Uint8Array): Uint8Array;
verify(hash: Uint8Array, signature: Uint8Array): boolean;
wipePrivateData(): this;
toJSON(): {
xpriv: string;
xpub: string;
};
private serialize;
}
export {};
//# sourceMappingURL=index.d.ts.map

1
node_modules/@scure/bip32/lib/esm/index.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":"AAkDA,eAAO,MAAM,eAAe,EAAE,MAAmB,CAAC;AAElD,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAaD,UAAU,QAAQ;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,UAAU,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;CAClC;AAED,qBAAa,KAAK;IAChB,IAAI,WAAW,IAAI,MAAM,CAKxB;IACD,IAAI,UAAU,IAAI,UAAU,GAAG,SAAS,CAEvC;IACD,IAAI,UAAU,IAAI,UAAU,GAAG,SAAS,CAEvC;IACD,IAAI,UAAU,IAAI,UAAU,GAAG,IAAI,CAElC;IACD,IAAI,SAAS,IAAI,UAAU,GAAG,IAAI,CAEjC;IACD,IAAI,kBAAkB,IAAI,MAAM,CAQ/B;IACD,IAAI,iBAAiB,IAAI,MAAM,CAK9B;WAEa,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,GAAE,QAA2B,GAAG,KAAK;WAgB9E,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,QAA2B,GAAG,KAAK;WAwBhF,QAAQ,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK;IAGtD,SAAgB,QAAQ,EAAE,QAAQ,CAAC;IACnC,SAAgB,KAAK,EAAE,MAAM,CAAK;IAClC,SAAgB,KAAK,EAAE,MAAM,CAAK;IAClC,SAAgB,SAAS,EAAE,UAAU,GAAG,IAAI,CAAQ;IACpD,SAAgB,iBAAiB,EAAE,MAAM,CAAK;IAC9C,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,YAAY,CAAC,CAAa;IAClC,OAAO,CAAC,MAAM,CAAC,CAAa;IAC5B,OAAO,CAAC,OAAO,CAAyB;gBAE5B,GAAG,EAAE,QAAQ;IAiClB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK;IA4B3B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK;IAoDjC,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU;IAQlC,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO;IAexD,eAAe,IAAI,IAAI;IAQvB,MAAM,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAOhD,OAAO,CAAC,SAAS;CAelB"}

288
node_modules/@scure/bip32/lib/esm/index.js generated vendored Normal file
View File

@@ -0,0 +1,288 @@
/**
* @module BIP32 hierarchical deterministic (HD) wallets over secp256k1.
* @example
* ```js
* import { HDKey } from "@scure/bip32";
* const hdkey1 = HDKey.fromMasterSeed(seed);
* const hdkey2 = HDKey.fromExtendedKey(base58key);
* const hdkey3 = HDKey.fromJSON({ xpriv: string });
*
* // props
* [hdkey1.depth, hdkey1.index, hdkey1.chainCode];
* console.log(hdkey2.privateKey, hdkey2.publicKey);
* console.log(hdkey3.derive("m/0/2147483647'/1"));
* const sig = hdkey3.sign(hash);
* hdkey3.verify(hash, sig);
* ```
*/
/*! scure-bip32 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) */
import { mod } from '@noble/curves/abstract/modular';
import { secp256k1 as secp } from '@noble/curves/secp256k1';
import { hmac } from '@noble/hashes/hmac';
import { ripemd160 } from '@noble/hashes/legacy';
import { sha256, sha512 } from '@noble/hashes/sha2';
import { abytes, bytesToHex, concatBytes, createView, hexToBytes, utf8ToBytes, } from '@noble/hashes/utils';
import { createBase58check } from '@scure/base';
const Point = secp.ProjectivePoint;
const base58check = createBase58check(sha256);
function bytesToNumber(bytes) {
abytes(bytes);
const h = bytes.length === 0 ? '0' : bytesToHex(bytes);
return BigInt('0x' + h);
}
function numberToBytes(num) {
if (typeof num !== 'bigint')
throw new Error('bigint expected');
return hexToBytes(num.toString(16).padStart(64, '0'));
}
const MASTER_SECRET = utf8ToBytes('Bitcoin seed');
// Bitcoin hardcoded by default
const BITCOIN_VERSIONS = { private: 0x0488ade4, public: 0x0488b21e };
export const HARDENED_OFFSET = 0x80000000;
const hash160 = (data) => ripemd160(sha256(data));
const fromU32 = (data) => createView(data).getUint32(0, false);
const toU32 = (n) => {
if (!Number.isSafeInteger(n) || n < 0 || n > 2 ** 32 - 1) {
throw new Error('invalid number, should be from 0 to 2**32-1, got ' + n);
}
const buf = new Uint8Array(4);
createView(buf).setUint32(0, n, false);
return buf;
};
export class HDKey {
get fingerprint() {
if (!this.pubHash) {
throw new Error('No publicKey set!');
}
return fromU32(this.pubHash);
}
get identifier() {
return this.pubHash;
}
get pubKeyHash() {
return this.pubHash;
}
get privateKey() {
return this.privKeyBytes || null;
}
get publicKey() {
return this.pubKey || null;
}
get privateExtendedKey() {
const priv = this.privateKey;
if (!priv) {
throw new Error('No private key');
}
return base58check.encode(this.serialize(this.versions.private, concatBytes(new Uint8Array([0]), priv)));
}
get publicExtendedKey() {
if (!this.pubKey) {
throw new Error('No public key');
}
return base58check.encode(this.serialize(this.versions.public, this.pubKey));
}
static fromMasterSeed(seed, versions = BITCOIN_VERSIONS) {
abytes(seed);
if (8 * seed.length < 128 || 8 * seed.length > 512) {
throw new Error('HDKey: seed length must be between 128 and 512 bits; 256 bits is advised, got ' +
seed.length);
}
const I = hmac(sha512, MASTER_SECRET, seed);
return new HDKey({
versions,
chainCode: I.slice(32),
privateKey: I.slice(0, 32),
});
}
static fromExtendedKey(base58key, versions = BITCOIN_VERSIONS) {
// => version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
const keyBuffer = base58check.decode(base58key);
const keyView = createView(keyBuffer);
const version = keyView.getUint32(0, false);
const opt = {
versions,
depth: keyBuffer[4],
parentFingerprint: keyView.getUint32(5, false),
index: keyView.getUint32(9, false),
chainCode: keyBuffer.slice(13, 45),
};
const key = keyBuffer.slice(45);
const isPriv = key[0] === 0;
if (version !== versions[isPriv ? 'private' : 'public']) {
throw new Error('Version mismatch');
}
if (isPriv) {
return new HDKey({ ...opt, privateKey: key.slice(1) });
}
else {
return new HDKey({ ...opt, publicKey: key });
}
}
static fromJSON(json) {
return HDKey.fromExtendedKey(json.xpriv);
}
constructor(opt) {
this.depth = 0;
this.index = 0;
this.chainCode = null;
this.parentFingerprint = 0;
if (!opt || typeof opt !== 'object') {
throw new Error('HDKey.constructor must not be called directly');
}
this.versions = opt.versions || BITCOIN_VERSIONS;
this.depth = opt.depth || 0;
this.chainCode = opt.chainCode || null;
this.index = opt.index || 0;
this.parentFingerprint = opt.parentFingerprint || 0;
if (!this.depth) {
if (this.parentFingerprint || this.index) {
throw new Error('HDKey: zero depth with non-zero index/parent fingerprint');
}
}
if (opt.publicKey && opt.privateKey) {
throw new Error('HDKey: publicKey and privateKey at same time.');
}
if (opt.privateKey) {
if (!secp.utils.isValidPrivateKey(opt.privateKey)) {
throw new Error('Invalid private key');
}
this.privKey =
typeof opt.privateKey === 'bigint' ? opt.privateKey : bytesToNumber(opt.privateKey);
this.privKeyBytes = numberToBytes(this.privKey);
this.pubKey = secp.getPublicKey(opt.privateKey, true);
}
else if (opt.publicKey) {
this.pubKey = Point.fromHex(opt.publicKey).toRawBytes(true); // force compressed point
}
else {
throw new Error('HDKey: no public or private key provided');
}
this.pubHash = hash160(this.pubKey);
}
derive(path) {
if (!/^[mM]'?/.test(path)) {
throw new Error('Path must start with "m" or "M"');
}
if (/^[mM]'?$/.test(path)) {
return this;
}
const parts = path.replace(/^[mM]'?\//, '').split('/');
// tslint:disable-next-line
let child = this;
for (const c of parts) {
const m = /^(\d+)('?)$/.exec(c);
const m1 = m && m[1];
if (!m || m.length !== 3 || typeof m1 !== 'string')
throw new Error('invalid child index: ' + c);
let idx = +m1;
if (!Number.isSafeInteger(idx) || idx >= HARDENED_OFFSET) {
throw new Error('Invalid index');
}
// hardened key
if (m[2] === "'") {
idx += HARDENED_OFFSET;
}
child = child.deriveChild(idx);
}
return child;
}
deriveChild(index) {
if (!this.pubKey || !this.chainCode) {
throw new Error('No publicKey or chainCode set');
}
let data = toU32(index);
if (index >= HARDENED_OFFSET) {
// Hardened
const priv = this.privateKey;
if (!priv) {
throw new Error('Could not derive hardened child key');
}
// Hardened child: 0x00 || ser256(kpar) || ser32(index)
data = concatBytes(new Uint8Array([0]), priv, data);
}
else {
// Normal child: serP(point(kpar)) || ser32(index)
data = concatBytes(this.pubKey, data);
}
const I = hmac(sha512, this.chainCode, data);
const childTweak = bytesToNumber(I.slice(0, 32));
const chainCode = I.slice(32);
if (!secp.utils.isValidPrivateKey(childTweak)) {
throw new Error('Tweak bigger than curve order');
}
const opt = {
versions: this.versions,
chainCode,
depth: this.depth + 1,
parentFingerprint: this.fingerprint,
index,
};
try {
// Private parent key -> private child key
if (this.privateKey) {
const added = mod(this.privKey + childTweak, secp.CURVE.n);
if (!secp.utils.isValidPrivateKey(added)) {
throw new Error('The tweak was out of range or the resulted private key is invalid');
}
opt.privateKey = added;
}
else {
const added = Point.fromHex(this.pubKey).add(Point.fromPrivateKey(childTweak));
// Cryptographically impossible: hmac-sha512 preimage would need to be found
if (added.equals(Point.ZERO)) {
throw new Error('The tweak was equal to negative P, which made the result key invalid');
}
opt.publicKey = added.toRawBytes(true);
}
return new HDKey(opt);
}
catch (err) {
return this.deriveChild(index + 1);
}
}
sign(hash) {
if (!this.privateKey) {
throw new Error('No privateKey set!');
}
abytes(hash, 32);
return secp.sign(hash, this.privKey).toCompactRawBytes();
}
verify(hash, signature) {
abytes(hash, 32);
abytes(signature, 64);
if (!this.publicKey) {
throw new Error('No publicKey set!');
}
let sig;
try {
sig = secp.Signature.fromCompact(signature);
}
catch (error) {
return false;
}
return secp.verify(sig, hash, this.publicKey);
}
wipePrivateData() {
this.privKey = undefined;
if (this.privKeyBytes) {
this.privKeyBytes.fill(0);
this.privKeyBytes = undefined;
}
return this;
}
toJSON() {
return {
xpriv: this.privateExtendedKey,
xpub: this.publicExtendedKey,
};
}
serialize(version, key) {
if (!this.chainCode) {
throw new Error('No chainCode set');
}
abytes(key, 33);
// version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
return concatBytes(toU32(version), new Uint8Array([this.depth]), toU32(this.parentFingerprint), toU32(this.index), this.chainCode, key);
}
}
//# sourceMappingURL=index.js.map

1
node_modules/@scure/bip32/lib/esm/index.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

4
node_modules/@scure/bip32/lib/esm/package.json generated vendored Normal file
View File

@@ -0,0 +1,4 @@
{
"type": "module",
"sideEffects": false
}

50
node_modules/@scure/bip32/lib/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,50 @@
export declare const HARDENED_OFFSET: number;
export interface Versions {
private: number;
public: number;
}
interface HDKeyOpt {
versions?: Versions;
depth?: number;
index?: number;
parentFingerprint?: number;
chainCode?: Uint8Array;
publicKey?: Uint8Array;
privateKey?: Uint8Array | bigint;
}
export declare class HDKey {
get fingerprint(): number;
get identifier(): Uint8Array | undefined;
get pubKeyHash(): Uint8Array | undefined;
get privateKey(): Uint8Array | null;
get publicKey(): Uint8Array | null;
get privateExtendedKey(): string;
get publicExtendedKey(): string;
static fromMasterSeed(seed: Uint8Array, versions?: Versions): HDKey;
static fromExtendedKey(base58key: string, versions?: Versions): HDKey;
static fromJSON(json: {
xpriv: string;
}): HDKey;
readonly versions: Versions;
readonly depth: number;
readonly index: number;
readonly chainCode: Uint8Array | null;
readonly parentFingerprint: number;
private privKey?;
private privKeyBytes?;
private pubKey?;
private pubHash;
constructor(opt: HDKeyOpt);
derive(path: string): HDKey;
deriveChild(index: number): HDKey;
sign(hash: Uint8Array): Uint8Array;
verify(hash: Uint8Array, signature: Uint8Array): boolean;
wipePrivateData(): this;
toJSON(): {
xpriv: string;
xpub: string;
};
private serialize;
}
export {};
//# sourceMappingURL=index.d.ts.map

1
node_modules/@scure/bip32/lib/index.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAkDA,eAAO,MAAM,eAAe,EAAE,MAAmB,CAAC;AAElD,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAaD,UAAU,QAAQ;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,UAAU,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;CAClC;AAED,qBAAa,KAAK;IAChB,IAAI,WAAW,IAAI,MAAM,CAKxB;IACD,IAAI,UAAU,IAAI,UAAU,GAAG,SAAS,CAEvC;IACD,IAAI,UAAU,IAAI,UAAU,GAAG,SAAS,CAEvC;IACD,IAAI,UAAU,IAAI,UAAU,GAAG,IAAI,CAElC;IACD,IAAI,SAAS,IAAI,UAAU,GAAG,IAAI,CAEjC;IACD,IAAI,kBAAkB,IAAI,MAAM,CAQ/B;IACD,IAAI,iBAAiB,IAAI,MAAM,CAK9B;WAEa,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,GAAE,QAA2B,GAAG,KAAK;WAgB9E,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,QAA2B,GAAG,KAAK;WAwBhF,QAAQ,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK;IAGtD,SAAgB,QAAQ,EAAE,QAAQ,CAAC;IACnC,SAAgB,KAAK,EAAE,MAAM,CAAK;IAClC,SAAgB,KAAK,EAAE,MAAM,CAAK;IAClC,SAAgB,SAAS,EAAE,UAAU,GAAG,IAAI,CAAQ;IACpD,SAAgB,iBAAiB,EAAE,MAAM,CAAK;IAC9C,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,YAAY,CAAC,CAAa;IAClC,OAAO,CAAC,MAAM,CAAC,CAAa;IAC5B,OAAO,CAAC,OAAO,CAAyB;gBAE5B,GAAG,EAAE,QAAQ;IAiClB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK;IA4B3B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK;IAoDjC,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU;IAQlC,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO;IAexD,eAAe,IAAI,IAAI;IAQvB,MAAM,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAOhD,OAAO,CAAC,SAAS;CAelB"}

292
node_modules/@scure/bip32/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,292 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HDKey = exports.HARDENED_OFFSET = void 0;
/**
* @module BIP32 hierarchical deterministic (HD) wallets over secp256k1.
* @example
* ```js
* import { HDKey } from "@scure/bip32";
* const hdkey1 = HDKey.fromMasterSeed(seed);
* const hdkey2 = HDKey.fromExtendedKey(base58key);
* const hdkey3 = HDKey.fromJSON({ xpriv: string });
*
* // props
* [hdkey1.depth, hdkey1.index, hdkey1.chainCode];
* console.log(hdkey2.privateKey, hdkey2.publicKey);
* console.log(hdkey3.derive("m/0/2147483647'/1"));
* const sig = hdkey3.sign(hash);
* hdkey3.verify(hash, sig);
* ```
*/
/*! scure-bip32 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) */
const modular_1 = require("@noble/curves/abstract/modular");
const secp256k1_1 = require("@noble/curves/secp256k1");
const hmac_1 = require("@noble/hashes/hmac");
const legacy_1 = require("@noble/hashes/legacy");
const sha2_1 = require("@noble/hashes/sha2");
const utils_1 = require("@noble/hashes/utils");
const base_1 = require("@scure/base");
const Point = secp256k1_1.secp256k1.ProjectivePoint;
const base58check = (0, base_1.createBase58check)(sha2_1.sha256);
function bytesToNumber(bytes) {
(0, utils_1.abytes)(bytes);
const h = bytes.length === 0 ? '0' : (0, utils_1.bytesToHex)(bytes);
return BigInt('0x' + h);
}
function numberToBytes(num) {
if (typeof num !== 'bigint')
throw new Error('bigint expected');
return (0, utils_1.hexToBytes)(num.toString(16).padStart(64, '0'));
}
const MASTER_SECRET = (0, utils_1.utf8ToBytes)('Bitcoin seed');
// Bitcoin hardcoded by default
const BITCOIN_VERSIONS = { private: 0x0488ade4, public: 0x0488b21e };
exports.HARDENED_OFFSET = 0x80000000;
const hash160 = (data) => (0, legacy_1.ripemd160)((0, sha2_1.sha256)(data));
const fromU32 = (data) => (0, utils_1.createView)(data).getUint32(0, false);
const toU32 = (n) => {
if (!Number.isSafeInteger(n) || n < 0 || n > 2 ** 32 - 1) {
throw new Error('invalid number, should be from 0 to 2**32-1, got ' + n);
}
const buf = new Uint8Array(4);
(0, utils_1.createView)(buf).setUint32(0, n, false);
return buf;
};
class HDKey {
get fingerprint() {
if (!this.pubHash) {
throw new Error('No publicKey set!');
}
return fromU32(this.pubHash);
}
get identifier() {
return this.pubHash;
}
get pubKeyHash() {
return this.pubHash;
}
get privateKey() {
return this.privKeyBytes || null;
}
get publicKey() {
return this.pubKey || null;
}
get privateExtendedKey() {
const priv = this.privateKey;
if (!priv) {
throw new Error('No private key');
}
return base58check.encode(this.serialize(this.versions.private, (0, utils_1.concatBytes)(new Uint8Array([0]), priv)));
}
get publicExtendedKey() {
if (!this.pubKey) {
throw new Error('No public key');
}
return base58check.encode(this.serialize(this.versions.public, this.pubKey));
}
static fromMasterSeed(seed, versions = BITCOIN_VERSIONS) {
(0, utils_1.abytes)(seed);
if (8 * seed.length < 128 || 8 * seed.length > 512) {
throw new Error('HDKey: seed length must be between 128 and 512 bits; 256 bits is advised, got ' +
seed.length);
}
const I = (0, hmac_1.hmac)(sha2_1.sha512, MASTER_SECRET, seed);
return new HDKey({
versions,
chainCode: I.slice(32),
privateKey: I.slice(0, 32),
});
}
static fromExtendedKey(base58key, versions = BITCOIN_VERSIONS) {
// => version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
const keyBuffer = base58check.decode(base58key);
const keyView = (0, utils_1.createView)(keyBuffer);
const version = keyView.getUint32(0, false);
const opt = {
versions,
depth: keyBuffer[4],
parentFingerprint: keyView.getUint32(5, false),
index: keyView.getUint32(9, false),
chainCode: keyBuffer.slice(13, 45),
};
const key = keyBuffer.slice(45);
const isPriv = key[0] === 0;
if (version !== versions[isPriv ? 'private' : 'public']) {
throw new Error('Version mismatch');
}
if (isPriv) {
return new HDKey({ ...opt, privateKey: key.slice(1) });
}
else {
return new HDKey({ ...opt, publicKey: key });
}
}
static fromJSON(json) {
return HDKey.fromExtendedKey(json.xpriv);
}
constructor(opt) {
this.depth = 0;
this.index = 0;
this.chainCode = null;
this.parentFingerprint = 0;
if (!opt || typeof opt !== 'object') {
throw new Error('HDKey.constructor must not be called directly');
}
this.versions = opt.versions || BITCOIN_VERSIONS;
this.depth = opt.depth || 0;
this.chainCode = opt.chainCode || null;
this.index = opt.index || 0;
this.parentFingerprint = opt.parentFingerprint || 0;
if (!this.depth) {
if (this.parentFingerprint || this.index) {
throw new Error('HDKey: zero depth with non-zero index/parent fingerprint');
}
}
if (opt.publicKey && opt.privateKey) {
throw new Error('HDKey: publicKey and privateKey at same time.');
}
if (opt.privateKey) {
if (!secp256k1_1.secp256k1.utils.isValidPrivateKey(opt.privateKey)) {
throw new Error('Invalid private key');
}
this.privKey =
typeof opt.privateKey === 'bigint' ? opt.privateKey : bytesToNumber(opt.privateKey);
this.privKeyBytes = numberToBytes(this.privKey);
this.pubKey = secp256k1_1.secp256k1.getPublicKey(opt.privateKey, true);
}
else if (opt.publicKey) {
this.pubKey = Point.fromHex(opt.publicKey).toRawBytes(true); // force compressed point
}
else {
throw new Error('HDKey: no public or private key provided');
}
this.pubHash = hash160(this.pubKey);
}
derive(path) {
if (!/^[mM]'?/.test(path)) {
throw new Error('Path must start with "m" or "M"');
}
if (/^[mM]'?$/.test(path)) {
return this;
}
const parts = path.replace(/^[mM]'?\//, '').split('/');
// tslint:disable-next-line
let child = this;
for (const c of parts) {
const m = /^(\d+)('?)$/.exec(c);
const m1 = m && m[1];
if (!m || m.length !== 3 || typeof m1 !== 'string')
throw new Error('invalid child index: ' + c);
let idx = +m1;
if (!Number.isSafeInteger(idx) || idx >= exports.HARDENED_OFFSET) {
throw new Error('Invalid index');
}
// hardened key
if (m[2] === "'") {
idx += exports.HARDENED_OFFSET;
}
child = child.deriveChild(idx);
}
return child;
}
deriveChild(index) {
if (!this.pubKey || !this.chainCode) {
throw new Error('No publicKey or chainCode set');
}
let data = toU32(index);
if (index >= exports.HARDENED_OFFSET) {
// Hardened
const priv = this.privateKey;
if (!priv) {
throw new Error('Could not derive hardened child key');
}
// Hardened child: 0x00 || ser256(kpar) || ser32(index)
data = (0, utils_1.concatBytes)(new Uint8Array([0]), priv, data);
}
else {
// Normal child: serP(point(kpar)) || ser32(index)
data = (0, utils_1.concatBytes)(this.pubKey, data);
}
const I = (0, hmac_1.hmac)(sha2_1.sha512, this.chainCode, data);
const childTweak = bytesToNumber(I.slice(0, 32));
const chainCode = I.slice(32);
if (!secp256k1_1.secp256k1.utils.isValidPrivateKey(childTweak)) {
throw new Error('Tweak bigger than curve order');
}
const opt = {
versions: this.versions,
chainCode,
depth: this.depth + 1,
parentFingerprint: this.fingerprint,
index,
};
try {
// Private parent key -> private child key
if (this.privateKey) {
const added = (0, modular_1.mod)(this.privKey + childTweak, secp256k1_1.secp256k1.CURVE.n);
if (!secp256k1_1.secp256k1.utils.isValidPrivateKey(added)) {
throw new Error('The tweak was out of range or the resulted private key is invalid');
}
opt.privateKey = added;
}
else {
const added = Point.fromHex(this.pubKey).add(Point.fromPrivateKey(childTweak));
// Cryptographically impossible: hmac-sha512 preimage would need to be found
if (added.equals(Point.ZERO)) {
throw new Error('The tweak was equal to negative P, which made the result key invalid');
}
opt.publicKey = added.toRawBytes(true);
}
return new HDKey(opt);
}
catch (err) {
return this.deriveChild(index + 1);
}
}
sign(hash) {
if (!this.privateKey) {
throw new Error('No privateKey set!');
}
(0, utils_1.abytes)(hash, 32);
return secp256k1_1.secp256k1.sign(hash, this.privKey).toCompactRawBytes();
}
verify(hash, signature) {
(0, utils_1.abytes)(hash, 32);
(0, utils_1.abytes)(signature, 64);
if (!this.publicKey) {
throw new Error('No publicKey set!');
}
let sig;
try {
sig = secp256k1_1.secp256k1.Signature.fromCompact(signature);
}
catch (error) {
return false;
}
return secp256k1_1.secp256k1.verify(sig, hash, this.publicKey);
}
wipePrivateData() {
this.privKey = undefined;
if (this.privKeyBytes) {
this.privKeyBytes.fill(0);
this.privKeyBytes = undefined;
}
return this;
}
toJSON() {
return {
xpriv: this.privateExtendedKey,
xpub: this.publicExtendedKey,
};
}
serialize(version, key) {
if (!this.chainCode) {
throw new Error('No chainCode set');
}
(0, utils_1.abytes)(key, 33);
// version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
return (0, utils_1.concatBytes)(toU32(version), new Uint8Array([this.depth]), toU32(this.parentFingerprint), toU32(this.index), this.chainCode, key);
}
}
exports.HDKey = HDKey;
//# sourceMappingURL=index.js.map

1
node_modules/@scure/bip32/lib/index.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

61
node_modules/@scure/bip32/package.json generated vendored Normal file
View File

@@ -0,0 +1,61 @@
{
"name": "@scure/bip32",
"version": "1.7.0",
"description": "Secure, audited & minimal implementation of BIP32 hierarchical deterministic (HD) wallets over secp256k1",
"files": [
"index.ts",
"./lib"
],
"main": "./lib/index.js",
"module": "./lib/esm/index.js",
"types": "./lib/index.d.ts",
"exports": {
".": {
"import": "./lib/esm/index.js",
"require": "./lib/index.js"
}
},
"dependencies": {
"@noble/curves": "~1.9.0",
"@noble/hashes": "~1.8.0",
"@scure/base": "~1.2.5"
},
"devDependencies": {
"@paulmillr/jsbt": "0.3.3",
"micro-should": "0.5.2",
"prettier": "3.5.3",
"typescript": "5.8.3"
},
"sideEffects": false,
"author": "Paul Miller (https://paulmillr.com)",
"homepage": "https://paulmillr.com/noble/#scure",
"repository": {
"type": "git",
"url": "git+https://github.com/paulmillr/scure-bip32.git"
},
"license": "MIT",
"scripts": {
"build": "tsc && tsc -p tsconfig.cjs.json",
"build:release": "npx jsbt esbuild test/build",
"lint": "prettier --check 'index.ts' 'test/*.test.ts'",
"format": "prettier --write 'index.ts' 'test/*.test.ts'",
"test": "node test/index.js",
"test:bun": "bun test/index.js",
"test:deno": "deno --allow-env --allow-read test/index.js"
},
"keywords": [
"bip32",
"hierarchical",
"deterministic",
"hd key",
"bip0032",
"bip-32",
"bip39",
"micro",
"scure",
"mnemonic",
"phrase",
"code"
],
"funding": "https://paulmillr.com/funding/"
}

21
node_modules/@scure/bip39/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

133
node_modules/@scure/bip39/README.md generated vendored Normal file
View File

@@ -0,0 +1,133 @@
# scure-bip39
Audited & minimal JS implementation of [BIP39 mnemonic phrases](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki).
- 🔒 [**Audited**](#security) by an independent security firm
- 🔻 Tree-shakeable: unused code is excluded from your builds
- 📦 ESM and common.js
- ➰ Only 2 audited dependencies by the same author:
[noble-hashes](https://github.com/paulmillr/noble-hashes) and [scure-base](https://github.com/paulmillr/scure-base)
- 🪶 14KB gzipped with one wordlist, 79KB with all of them: much smaller than similar libraries
Check out [scure-bip32](https://github.com/paulmillr/scure-bip32) if you need
hierarchical deterministic wallets ("HD Wallets").
### This library belongs to _scure_
> **scure** — audited micro-libraries.
- Zero or minimal dependencies
- Highly readable TypeScript / JS code
- PGP-signed releases and transparent NPM builds
- Check out [homepage](https://paulmillr.com/noble/#scure) & all libraries:
[base](https://github.com/paulmillr/scure-base),
[bip32](https://github.com/paulmillr/scure-bip32),
[bip39](https://github.com/paulmillr/scure-bip39),
[btc-signer](https://github.com/paulmillr/scure-btc-signer),
[starknet](https://github.com/paulmillr/scure-starknet)
## Usage
> `npm install @scure/bip39`
> `deno add jsr:@scure/bip39`
> `deno doc jsr:@scure/bip39` # command-line documentation
We don't provide source maps.
Wordlists are large, including source maps would double package size.
```js
import * as bip39 from '@scure/bip39';
import { wordlist } from '@scure/bip39/wordlists/english';
// Generate x random words. Uses Cryptographically-Secure Random Number Generator.
const mn = bip39.generateMnemonic(wordlist);
console.log(mn);
// Reversible: Converts mnemonic string to raw entropy in form of byte array.
const ent = bip39.mnemonicToEntropy(mn, wordlist);
// Reversible: Converts raw entropy in form of byte array to mnemonic string.
bip39.entropyToMnemonic(ent, wordlist);
// Validates mnemonic for being 12-24 words contained in `wordlist`.
bip39.validateMnemonic(mn, wordlist);
// Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.
await bip39.mnemonicToSeed(mn, 'password');
bip39.mnemonicToSeedSync(mn, 'password');
```
This submodule contains the word lists defined by BIP39 for Czech, English, French, Italian, Japanese, Korean, Portuguese, Simplified and Traditional Chinese, and Spanish. These are not imported by default, as that would increase bundle sizes too much. Instead, you should import and use them explicitly.
```typescript
function generateMnemonic(wordlist: string[], strength?: number): string;
function mnemonicToEntropy(mnemonic: string, wordlist: string[]): Uint8Array;
function entropyToMnemonic(entropy: Uint8Array, wordlist: string[]): string;
function validateMnemonic(mnemonic: string, wordlist: string[]): boolean;
function mnemonicToSeed(mnemonic: string, passphrase?: string): Promise<Uint8Array>;
function mnemonicToSeedSync(mnemonic: string, passphrase?: string): Uint8Array;
```
All wordlists:
```typescript
import { wordlist as czech } from '@scure/bip39/wordlists/czech';
import { wordlist as english } from '@scure/bip39/wordlists/english';
import { wordlist as french } from '@scure/bip39/wordlists/french';
import { wordlist as italian } from '@scure/bip39/wordlists/italian';
import { wordlist as japanese } from '@scure/bip39/wordlists/japanese';
import { wordlist as korean } from '@scure/bip39/wordlists/korean';
import { wordlist as portuguese } from '@scure/bip39/wordlists/portuguese';
import { wordlist as simplifiedChinese } from '@scure/bip39/wordlists/simplified-chinese';
import { wordlist as spanish } from '@scure/bip39/wordlists/spanish';
import { wordlist as traditionalChinese } from '@scure/bip39/wordlists/traditional-chinese';
```
## Security
To audit wordlist content, run `node scripts/fetch-wordlist.js`.
The library has been independently audited:
- at version 1.0.0, in Jan 2022, by [cure53](https://cure53.de)
- PDFs: [online](https://cure53.de/pentest-report_hashing-libs.pdf), [offline](./audit/2022-01-05-cure53-audit-nbl2.pdf)
- [Changes since audit](https://github.com/paulmillr/scure-bip39/compare/1.0.0..main).
- The audit has been funded by [Ethereum Foundation](https://ethereum.org/en/) with help of [Nomic Labs](https://nomiclabs.io)
The library was initially developed for [js-ethereum-cryptography](https://github.com/ethereum/js-ethereum-cryptography).
At commit [ae00e6d7](https://github.com/ethereum/js-ethereum-cryptography/commit/ae00e6d7d24fb3c76a1c7fe10039f6ecd120b77e),
it was extracted to a separate package called `micro-bip39`.
After the audit we've decided to use `@scure` NPM namespace for security.
### Supply chain security
- **Commits** are signed with PGP keys, to prevent forgery. Make sure to verify commit signatures
- **Releases** are transparent and built on GitHub CI. Make sure to verify [provenance](https://docs.npmjs.com/generating-provenance-statements) logs
- Use GitHub CLI to verify single-file builds:
`gh attestation verify --owner paulmillr scure-bip39.js`
- **Rare releasing** is followed to ensure less re-audit need for end-users
- **Dependencies** are minimized and locked-down: any dependency could get hacked and users will be downloading malware with every install.
- We make sure to use as few dependencies as possible
- Automatic dep updates are prevented by locking-down version ranges; diffs are checked with `npm-diff`
- **Dev Dependencies** are disabled for end-users; they are only used to develop / build the source code
For this package, there are 2 dependencies; and a few dev dependencies:
- [noble-hashes](https://github.com/paulmillr/noble-hashes) provides cryptographic hashing functionality
- [scure-base](https://github.com/paulmillr/scure-base) provides low-level wordlist utilities
- micro-bmark, micro-should and jsbt are used for benchmarking / testing / build tooling and developed by the same author
- prettier, fast-check and typescript are used for code quality / test generation / ts compilation. It's hard to audit their source code thoroughly and fully because of their size
## Contributing & testing
- `npm install && npm run build && npm test` will build the code and run tests.
- `npm run lint` / `npm run format` will run linter / fix linter issues.
- `npm run build:release` will build single file
## License
[MIT License](./LICENSE)
Copyright (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com)

92
node_modules/@scure/bip39/esm/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,92 @@
/**
* Audited & minimal JS implementation of
* [BIP39 mnemonic phrases](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki).
* @module
* @example
```js
import * as bip39 from '@scure/bip39';
import { wordlist } from '@scure/bip39/wordlists/english';
const mn = bip39.generateMnemonic(wordlist);
console.log(mn);
const ent = bip39.mnemonicToEntropy(mn, wordlist)
bip39.entropyToMnemonic(ent, wordlist);
bip39.validateMnemonic(mn, wordlist);
await bip39.mnemonicToSeed(mn, 'password');
bip39.mnemonicToSeedSync(mn, 'password');
// Wordlists
import { wordlist as czech } from '@scure/bip39/wordlists/czech';
import { wordlist as english } from '@scure/bip39/wordlists/english';
import { wordlist as french } from '@scure/bip39/wordlists/french';
import { wordlist as italian } from '@scure/bip39/wordlists/italian';
import { wordlist as japanese } from '@scure/bip39/wordlists/japanese';
import { wordlist as korean } from '@scure/bip39/wordlists/korean';
import { wordlist as portuguese } from '@scure/bip39/wordlists/portuguese';
import { wordlist as simplifiedChinese } from '@scure/bip39/wordlists/simplified-chinese';
import { wordlist as spanish } from '@scure/bip39/wordlists/spanish';
import { wordlist as traditionalChinese } from '@scure/bip39/wordlists/traditional-chinese';
```
*/
/**
* Generate x random words. Uses Cryptographically-Secure Random Number Generator.
* @param wordlist imported wordlist for specific language
* @param strength mnemonic strength 128-256 bits
* @example
* generateMnemonic(wordlist, 128)
* // 'legal winner thank year wave sausage worth useful legal winner thank yellow'
*/
export declare function generateMnemonic(wordlist: string[], strength?: number): string;
/**
* Reversible: Converts mnemonic string to raw entropy in form of byte array.
* @param mnemonic 12-24 words
* @param wordlist imported wordlist for specific language
* @example
* const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
* mnemonicToEntropy(mnem, wordlist)
* // Produces
* new Uint8Array([
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
* ])
*/
export declare function mnemonicToEntropy(mnemonic: string, wordlist: string[]): Uint8Array;
/**
* Reversible: Converts raw entropy in form of byte array to mnemonic string.
* @param entropy byte array
* @param wordlist imported wordlist for specific language
* @returns 12-24 words
* @example
* const ent = new Uint8Array([
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
* ]);
* entropyToMnemonic(ent, wordlist);
* // 'legal winner thank year wave sausage worth useful legal winner thank yellow'
*/
export declare function entropyToMnemonic(entropy: Uint8Array, wordlist: string[]): string;
/**
* Validates mnemonic for being 12-24 words contained in `wordlist`.
*/
export declare function validateMnemonic(mnemonic: string, wordlist: string[]): boolean;
/**
* Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.
* @param mnemonic 12-24 words
* @param passphrase string that will additionally protect the key
* @returns 64 bytes of key data
* @example
* const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
* await mnemonicToSeed(mnem, 'password');
* // new Uint8Array([...64 bytes])
*/
export declare function mnemonicToSeed(mnemonic: string, passphrase?: string): Promise<Uint8Array>;
/**
* Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.
* @param mnemonic 12-24 words
* @param passphrase string that will additionally protect the key
* @returns 64 bytes of key data
* @example
* const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
* mnemonicToSeedSync(mnem, 'password');
* // new Uint8Array([...64 bytes])
*/
export declare function mnemonicToSeedSync(mnemonic: string, passphrase?: string): Uint8Array;

161
node_modules/@scure/bip39/esm/index.js generated vendored Normal file
View File

@@ -0,0 +1,161 @@
/**
* Audited & minimal JS implementation of
* [BIP39 mnemonic phrases](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki).
* @module
* @example
```js
import * as bip39 from '@scure/bip39';
import { wordlist } from '@scure/bip39/wordlists/english';
const mn = bip39.generateMnemonic(wordlist);
console.log(mn);
const ent = bip39.mnemonicToEntropy(mn, wordlist)
bip39.entropyToMnemonic(ent, wordlist);
bip39.validateMnemonic(mn, wordlist);
await bip39.mnemonicToSeed(mn, 'password');
bip39.mnemonicToSeedSync(mn, 'password');
// Wordlists
import { wordlist as czech } from '@scure/bip39/wordlists/czech';
import { wordlist as english } from '@scure/bip39/wordlists/english';
import { wordlist as french } from '@scure/bip39/wordlists/french';
import { wordlist as italian } from '@scure/bip39/wordlists/italian';
import { wordlist as japanese } from '@scure/bip39/wordlists/japanese';
import { wordlist as korean } from '@scure/bip39/wordlists/korean';
import { wordlist as portuguese } from '@scure/bip39/wordlists/portuguese';
import { wordlist as simplifiedChinese } from '@scure/bip39/wordlists/simplified-chinese';
import { wordlist as spanish } from '@scure/bip39/wordlists/spanish';
import { wordlist as traditionalChinese } from '@scure/bip39/wordlists/traditional-chinese';
```
*/
/*! scure-bip39 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) */
import { pbkdf2, pbkdf2Async } from '@noble/hashes/pbkdf2';
import { sha256, sha512 } from '@noble/hashes/sha2';
import { abytes, anumber, randomBytes } from '@noble/hashes/utils';
import { utils as baseUtils } from '@scure/base';
// Japanese wordlist
const isJapanese = (wordlist) => wordlist[0] === '\u3042\u3044\u3053\u304f\u3057\u3093';
// Normalization replaces equivalent sequences of characters
// so that any two texts that are equivalent will be reduced
// to the same sequence of code points, called the normal form of the original text.
// https://tonsky.me/blog/unicode/#why-is-a----
function nfkd(str) {
if (typeof str !== 'string')
throw new TypeError('invalid mnemonic type: ' + typeof str);
return str.normalize('NFKD');
}
function normalize(str) {
const norm = nfkd(str);
const words = norm.split(' ');
if (![12, 15, 18, 21, 24].includes(words.length))
throw new Error('Invalid mnemonic');
return { nfkd: norm, words };
}
function aentropy(ent) {
abytes(ent, 16, 20, 24, 28, 32);
}
/**
* Generate x random words. Uses Cryptographically-Secure Random Number Generator.
* @param wordlist imported wordlist for specific language
* @param strength mnemonic strength 128-256 bits
* @example
* generateMnemonic(wordlist, 128)
* // 'legal winner thank year wave sausage worth useful legal winner thank yellow'
*/
export function generateMnemonic(wordlist, strength = 128) {
anumber(strength);
if (strength % 32 !== 0 || strength > 256)
throw new TypeError('Invalid entropy');
return entropyToMnemonic(randomBytes(strength / 8), wordlist);
}
const calcChecksum = (entropy) => {
// Checksum is ent.length/4 bits long
const bitsLeft = 8 - entropy.length / 4;
// Zero rightmost "bitsLeft" bits in byte
// For example: bitsLeft=4 val=10111101 -> 10110000
return new Uint8Array([(sha256(entropy)[0] >> bitsLeft) << bitsLeft]);
};
function getCoder(wordlist) {
if (!Array.isArray(wordlist) || wordlist.length !== 2048 || typeof wordlist[0] !== 'string')
throw new Error('Wordlist: expected array of 2048 strings');
wordlist.forEach((i) => {
if (typeof i !== 'string')
throw new Error('wordlist: non-string element: ' + i);
});
return baseUtils.chain(baseUtils.checksum(1, calcChecksum), baseUtils.radix2(11, true), baseUtils.alphabet(wordlist));
}
/**
* Reversible: Converts mnemonic string to raw entropy in form of byte array.
* @param mnemonic 12-24 words
* @param wordlist imported wordlist for specific language
* @example
* const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
* mnemonicToEntropy(mnem, wordlist)
* // Produces
* new Uint8Array([
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
* ])
*/
export function mnemonicToEntropy(mnemonic, wordlist) {
const { words } = normalize(mnemonic);
const entropy = getCoder(wordlist).decode(words);
aentropy(entropy);
return entropy;
}
/**
* Reversible: Converts raw entropy in form of byte array to mnemonic string.
* @param entropy byte array
* @param wordlist imported wordlist for specific language
* @returns 12-24 words
* @example
* const ent = new Uint8Array([
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
* ]);
* entropyToMnemonic(ent, wordlist);
* // 'legal winner thank year wave sausage worth useful legal winner thank yellow'
*/
export function entropyToMnemonic(entropy, wordlist) {
aentropy(entropy);
const words = getCoder(wordlist).encode(entropy);
return words.join(isJapanese(wordlist) ? '\u3000' : ' ');
}
/**
* Validates mnemonic for being 12-24 words contained in `wordlist`.
*/
export function validateMnemonic(mnemonic, wordlist) {
try {
mnemonicToEntropy(mnemonic, wordlist);
}
catch (e) {
return false;
}
return true;
}
const psalt = (passphrase) => nfkd('mnemonic' + passphrase);
/**
* Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.
* @param mnemonic 12-24 words
* @param passphrase string that will additionally protect the key
* @returns 64 bytes of key data
* @example
* const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
* await mnemonicToSeed(mnem, 'password');
* // new Uint8Array([...64 bytes])
*/
export function mnemonicToSeed(mnemonic, passphrase = '') {
return pbkdf2Async(sha512, normalize(mnemonic).nfkd, psalt(passphrase), { c: 2048, dkLen: 64 });
}
/**
* Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.
* @param mnemonic 12-24 words
* @param passphrase string that will additionally protect the key
* @returns 64 bytes of key data
* @example
* const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
* mnemonicToSeedSync(mnem, 'password');
* // new Uint8Array([...64 bytes])
*/
export function mnemonicToSeedSync(mnemonic, passphrase = '') {
return pbkdf2(sha512, normalize(mnemonic).nfkd, psalt(passphrase), { c: 2048, dkLen: 64 });
}

3
node_modules/@scure/bip39/esm/package.json generated vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"type": "module"
}

1
node_modules/@scure/bip39/esm/wordlists/czech.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2048
node_modules/@scure/bip39/esm/wordlists/czech.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@scure/bip39/esm/wordlists/english.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2048
node_modules/@scure/bip39/esm/wordlists/english.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@scure/bip39/esm/wordlists/french.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2048
node_modules/@scure/bip39/esm/wordlists/french.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@scure/bip39/esm/wordlists/italian.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2048
node_modules/@scure/bip39/esm/wordlists/italian.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2048
node_modules/@scure/bip39/esm/wordlists/japanese.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@scure/bip39/esm/wordlists/korean.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2048
node_modules/@scure/bip39/esm/wordlists/korean.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2048
node_modules/@scure/bip39/esm/wordlists/portuguese.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

File diff suppressed because it is too large Load Diff

1
node_modules/@scure/bip39/esm/wordlists/spanish.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2048
node_modules/@scure/bip39/esm/wordlists/spanish.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

File diff suppressed because it is too large Load Diff

92
node_modules/@scure/bip39/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,92 @@
/**
* Audited & minimal JS implementation of
* [BIP39 mnemonic phrases](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki).
* @module
* @example
```js
import * as bip39 from '@scure/bip39';
import { wordlist } from '@scure/bip39/wordlists/english';
const mn = bip39.generateMnemonic(wordlist);
console.log(mn);
const ent = bip39.mnemonicToEntropy(mn, wordlist)
bip39.entropyToMnemonic(ent, wordlist);
bip39.validateMnemonic(mn, wordlist);
await bip39.mnemonicToSeed(mn, 'password');
bip39.mnemonicToSeedSync(mn, 'password');
// Wordlists
import { wordlist as czech } from '@scure/bip39/wordlists/czech';
import { wordlist as english } from '@scure/bip39/wordlists/english';
import { wordlist as french } from '@scure/bip39/wordlists/french';
import { wordlist as italian } from '@scure/bip39/wordlists/italian';
import { wordlist as japanese } from '@scure/bip39/wordlists/japanese';
import { wordlist as korean } from '@scure/bip39/wordlists/korean';
import { wordlist as portuguese } from '@scure/bip39/wordlists/portuguese';
import { wordlist as simplifiedChinese } from '@scure/bip39/wordlists/simplified-chinese';
import { wordlist as spanish } from '@scure/bip39/wordlists/spanish';
import { wordlist as traditionalChinese } from '@scure/bip39/wordlists/traditional-chinese';
```
*/
/**
* Generate x random words. Uses Cryptographically-Secure Random Number Generator.
* @param wordlist imported wordlist for specific language
* @param strength mnemonic strength 128-256 bits
* @example
* generateMnemonic(wordlist, 128)
* // 'legal winner thank year wave sausage worth useful legal winner thank yellow'
*/
export declare function generateMnemonic(wordlist: string[], strength?: number): string;
/**
* Reversible: Converts mnemonic string to raw entropy in form of byte array.
* @param mnemonic 12-24 words
* @param wordlist imported wordlist for specific language
* @example
* const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
* mnemonicToEntropy(mnem, wordlist)
* // Produces
* new Uint8Array([
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
* ])
*/
export declare function mnemonicToEntropy(mnemonic: string, wordlist: string[]): Uint8Array;
/**
* Reversible: Converts raw entropy in form of byte array to mnemonic string.
* @param entropy byte array
* @param wordlist imported wordlist for specific language
* @returns 12-24 words
* @example
* const ent = new Uint8Array([
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
* ]);
* entropyToMnemonic(ent, wordlist);
* // 'legal winner thank year wave sausage worth useful legal winner thank yellow'
*/
export declare function entropyToMnemonic(entropy: Uint8Array, wordlist: string[]): string;
/**
* Validates mnemonic for being 12-24 words contained in `wordlist`.
*/
export declare function validateMnemonic(mnemonic: string, wordlist: string[]): boolean;
/**
* Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.
* @param mnemonic 12-24 words
* @param passphrase string that will additionally protect the key
* @returns 64 bytes of key data
* @example
* const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
* await mnemonicToSeed(mnem, 'password');
* // new Uint8Array([...64 bytes])
*/
export declare function mnemonicToSeed(mnemonic: string, passphrase?: string): Promise<Uint8Array>;
/**
* Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.
* @param mnemonic 12-24 words
* @param passphrase string that will additionally protect the key
* @returns 64 bytes of key data
* @example
* const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
* mnemonicToSeedSync(mnem, 'password');
* // new Uint8Array([...64 bytes])
*/
export declare function mnemonicToSeedSync(mnemonic: string, passphrase?: string): Uint8Array;

169
node_modules/@scure/bip39/index.js generated vendored Normal file
View File

@@ -0,0 +1,169 @@
"use strict";
/**
* Audited & minimal JS implementation of
* [BIP39 mnemonic phrases](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki).
* @module
* @example
```js
import * as bip39 from '@scure/bip39';
import { wordlist } from '@scure/bip39/wordlists/english';
const mn = bip39.generateMnemonic(wordlist);
console.log(mn);
const ent = bip39.mnemonicToEntropy(mn, wordlist)
bip39.entropyToMnemonic(ent, wordlist);
bip39.validateMnemonic(mn, wordlist);
await bip39.mnemonicToSeed(mn, 'password');
bip39.mnemonicToSeedSync(mn, 'password');
// Wordlists
import { wordlist as czech } from '@scure/bip39/wordlists/czech';
import { wordlist as english } from '@scure/bip39/wordlists/english';
import { wordlist as french } from '@scure/bip39/wordlists/french';
import { wordlist as italian } from '@scure/bip39/wordlists/italian';
import { wordlist as japanese } from '@scure/bip39/wordlists/japanese';
import { wordlist as korean } from '@scure/bip39/wordlists/korean';
import { wordlist as portuguese } from '@scure/bip39/wordlists/portuguese';
import { wordlist as simplifiedChinese } from '@scure/bip39/wordlists/simplified-chinese';
import { wordlist as spanish } from '@scure/bip39/wordlists/spanish';
import { wordlist as traditionalChinese } from '@scure/bip39/wordlists/traditional-chinese';
```
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateMnemonic = generateMnemonic;
exports.mnemonicToEntropy = mnemonicToEntropy;
exports.entropyToMnemonic = entropyToMnemonic;
exports.validateMnemonic = validateMnemonic;
exports.mnemonicToSeed = mnemonicToSeed;
exports.mnemonicToSeedSync = mnemonicToSeedSync;
/*! scure-bip39 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) */
const pbkdf2_1 = require("@noble/hashes/pbkdf2");
const sha2_1 = require("@noble/hashes/sha2");
const utils_1 = require("@noble/hashes/utils");
const base_1 = require("@scure/base");
// Japanese wordlist
const isJapanese = (wordlist) => wordlist[0] === '\u3042\u3044\u3053\u304f\u3057\u3093';
// Normalization replaces equivalent sequences of characters
// so that any two texts that are equivalent will be reduced
// to the same sequence of code points, called the normal form of the original text.
// https://tonsky.me/blog/unicode/#why-is-a----
function nfkd(str) {
if (typeof str !== 'string')
throw new TypeError('invalid mnemonic type: ' + typeof str);
return str.normalize('NFKD');
}
function normalize(str) {
const norm = nfkd(str);
const words = norm.split(' ');
if (![12, 15, 18, 21, 24].includes(words.length))
throw new Error('Invalid mnemonic');
return { nfkd: norm, words };
}
function aentropy(ent) {
(0, utils_1.abytes)(ent, 16, 20, 24, 28, 32);
}
/**
* Generate x random words. Uses Cryptographically-Secure Random Number Generator.
* @param wordlist imported wordlist for specific language
* @param strength mnemonic strength 128-256 bits
* @example
* generateMnemonic(wordlist, 128)
* // 'legal winner thank year wave sausage worth useful legal winner thank yellow'
*/
function generateMnemonic(wordlist, strength = 128) {
(0, utils_1.anumber)(strength);
if (strength % 32 !== 0 || strength > 256)
throw new TypeError('Invalid entropy');
return entropyToMnemonic((0, utils_1.randomBytes)(strength / 8), wordlist);
}
const calcChecksum = (entropy) => {
// Checksum is ent.length/4 bits long
const bitsLeft = 8 - entropy.length / 4;
// Zero rightmost "bitsLeft" bits in byte
// For example: bitsLeft=4 val=10111101 -> 10110000
return new Uint8Array([((0, sha2_1.sha256)(entropy)[0] >> bitsLeft) << bitsLeft]);
};
function getCoder(wordlist) {
if (!Array.isArray(wordlist) || wordlist.length !== 2048 || typeof wordlist[0] !== 'string')
throw new Error('Wordlist: expected array of 2048 strings');
wordlist.forEach((i) => {
if (typeof i !== 'string')
throw new Error('wordlist: non-string element: ' + i);
});
return base_1.utils.chain(base_1.utils.checksum(1, calcChecksum), base_1.utils.radix2(11, true), base_1.utils.alphabet(wordlist));
}
/**
* Reversible: Converts mnemonic string to raw entropy in form of byte array.
* @param mnemonic 12-24 words
* @param wordlist imported wordlist for specific language
* @example
* const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
* mnemonicToEntropy(mnem, wordlist)
* // Produces
* new Uint8Array([
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
* ])
*/
function mnemonicToEntropy(mnemonic, wordlist) {
const { words } = normalize(mnemonic);
const entropy = getCoder(wordlist).decode(words);
aentropy(entropy);
return entropy;
}
/**
* Reversible: Converts raw entropy in form of byte array to mnemonic string.
* @param entropy byte array
* @param wordlist imported wordlist for specific language
* @returns 12-24 words
* @example
* const ent = new Uint8Array([
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
* ]);
* entropyToMnemonic(ent, wordlist);
* // 'legal winner thank year wave sausage worth useful legal winner thank yellow'
*/
function entropyToMnemonic(entropy, wordlist) {
aentropy(entropy);
const words = getCoder(wordlist).encode(entropy);
return words.join(isJapanese(wordlist) ? '\u3000' : ' ');
}
/**
* Validates mnemonic for being 12-24 words contained in `wordlist`.
*/
function validateMnemonic(mnemonic, wordlist) {
try {
mnemonicToEntropy(mnemonic, wordlist);
}
catch (e) {
return false;
}
return true;
}
const psalt = (passphrase) => nfkd('mnemonic' + passphrase);
/**
* Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.
* @param mnemonic 12-24 words
* @param passphrase string that will additionally protect the key
* @returns 64 bytes of key data
* @example
* const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
* await mnemonicToSeed(mnem, 'password');
* // new Uint8Array([...64 bytes])
*/
function mnemonicToSeed(mnemonic, passphrase = '') {
return (0, pbkdf2_1.pbkdf2Async)(sha2_1.sha512, normalize(mnemonic).nfkd, psalt(passphrase), { c: 2048, dkLen: 64 });
}
/**
* Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.
* @param mnemonic 12-24 words
* @param passphrase string that will additionally protect the key
* @returns 64 bytes of key data
* @example
* const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
* mnemonicToSeedSync(mnem, 'password');
* // new Uint8Array([...64 bytes])
*/
function mnemonicToSeedSync(mnemonic, passphrase = '') {
return (0, pbkdf2_1.pbkdf2)(sha2_1.sha512, normalize(mnemonic).nfkd, psalt(passphrase), { c: 2048, dkLen: 64 });
}

106
node_modules/@scure/bip39/package.json generated vendored Normal file
View File

@@ -0,0 +1,106 @@
{
"name": "@scure/bip39",
"version": "1.6.0",
"description": "Secure, audited & minimal implementation of BIP39 mnemonic phrases",
"files": [
"index.js",
"index.d.ts",
"wordlists/*.js",
"wordlists/*.d.ts",
"esm",
"src/index.ts"
],
"dependencies": {
"@noble/hashes": "~1.8.0",
"@scure/base": "~1.2.5"
},
"devDependencies": {
"@paulmillr/jsbt": "0.3.3",
"micro-bmark": "0.4.1",
"micro-should": "0.5.2",
"prettier": "3.5.3",
"typescript": "5.8.3"
},
"author": "Paul Miller (https://paulmillr.com)",
"homepage": "https://paulmillr.com/",
"repository": {
"type": "git",
"url": "git+https://github.com/paulmillr/scure-bip39.git"
},
"license": "MIT",
"scripts": {
"build": "tsc && tsc -p tsconfig.cjs.json",
"build:release": "npx jsbt esbuild test/build",
"lint": "prettier --check 'src/**/*.ts' 'test/*.test.ts' 'scripts/*.js'",
"format": "prettier --write 'src/**/*.ts' 'test/*.test.ts' 'scripts/*.js'",
"test": "node test/index.js",
"test:bun": "bun test/index.js",
"test:deno": "deno --allow-env --allow-read test/index.js",
"fetch-wordlist": "./scripts/fetch-wordlist.js"
},
"sideEffects": false,
"main": "index.js",
"types": "./index.d.ts",
"exports": {
".": {
"import": "./esm/index.js",
"require": "./index.js"
},
"./index": {
"import": "./esm/index.js",
"require": "./index.js"
},
"./wordlists/czech": {
"import": "./esm/wordlists/czech.js",
"require": "./wordlists/czech.js"
},
"./wordlists/english": {
"import": "./esm/wordlists/english.js",
"require": "./wordlists/english.js"
},
"./wordlists/french": {
"import": "./esm/wordlists/french.js",
"require": "./wordlists/french.js"
},
"./wordlists/italian": {
"import": "./esm/wordlists/italian.js",
"require": "./wordlists/italian.js"
},
"./wordlists/japanese": {
"import": "./esm/wordlists/japanese.js",
"require": "./wordlists/japanese.js"
},
"./wordlists/korean": {
"import": "./esm/wordlists/korean.js",
"require": "./wordlists/korean.js"
},
"./wordlists/portuguese": {
"import": "./esm/wordlists/portuguese.js",
"require": "./wordlists/portuguese.js"
},
"./wordlists/simplified-chinese": {
"import": "./esm/wordlists/simplified-chinese.js",
"require": "./wordlists/simplified-chinese.js"
},
"./wordlists/spanish": {
"import": "./esm/wordlists/spanish.js",
"require": "./wordlists/spanish.js"
},
"./wordlists/traditional-chinese": {
"import": "./esm/wordlists/traditional-chinese.js",
"require": "./wordlists/traditional-chinese.js"
}
},
"keywords": [
"bip39",
"mnemonic",
"phrase",
"code",
"bip0039",
"bip-39",
"wordlist",
"scure",
"noble"
],
"funding": "https://paulmillr.com/funding/"
}

174
node_modules/@scure/bip39/src/index.ts generated vendored Normal file
View File

@@ -0,0 +1,174 @@
/**
* Audited & minimal JS implementation of
* [BIP39 mnemonic phrases](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki).
* @module
* @example
```js
import * as bip39 from '@scure/bip39';
import { wordlist } from '@scure/bip39/wordlists/english';
const mn = bip39.generateMnemonic(wordlist);
console.log(mn);
const ent = bip39.mnemonicToEntropy(mn, wordlist)
bip39.entropyToMnemonic(ent, wordlist);
bip39.validateMnemonic(mn, wordlist);
await bip39.mnemonicToSeed(mn, 'password');
bip39.mnemonicToSeedSync(mn, 'password');
// Wordlists
import { wordlist as czech } from '@scure/bip39/wordlists/czech';
import { wordlist as english } from '@scure/bip39/wordlists/english';
import { wordlist as french } from '@scure/bip39/wordlists/french';
import { wordlist as italian } from '@scure/bip39/wordlists/italian';
import { wordlist as japanese } from '@scure/bip39/wordlists/japanese';
import { wordlist as korean } from '@scure/bip39/wordlists/korean';
import { wordlist as portuguese } from '@scure/bip39/wordlists/portuguese';
import { wordlist as simplifiedChinese } from '@scure/bip39/wordlists/simplified-chinese';
import { wordlist as spanish } from '@scure/bip39/wordlists/spanish';
import { wordlist as traditionalChinese } from '@scure/bip39/wordlists/traditional-chinese';
```
*/
/*! scure-bip39 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) */
import { pbkdf2, pbkdf2Async } from '@noble/hashes/pbkdf2';
import { sha256, sha512 } from '@noble/hashes/sha2';
import { abytes, anumber, randomBytes } from '@noble/hashes/utils';
import { utils as baseUtils } from '@scure/base';
// Japanese wordlist
const isJapanese = (wordlist: string[]) => wordlist[0] === '\u3042\u3044\u3053\u304f\u3057\u3093';
// Normalization replaces equivalent sequences of characters
// so that any two texts that are equivalent will be reduced
// to the same sequence of code points, called the normal form of the original text.
// https://tonsky.me/blog/unicode/#why-is-a----
function nfkd(str: string) {
if (typeof str !== 'string') throw new TypeError('invalid mnemonic type: ' + typeof str);
return str.normalize('NFKD');
}
function normalize(str: string) {
const norm = nfkd(str);
const words = norm.split(' ');
if (![12, 15, 18, 21, 24].includes(words.length)) throw new Error('Invalid mnemonic');
return { nfkd: norm, words };
}
function aentropy(ent: Uint8Array) {
abytes(ent, 16, 20, 24, 28, 32);
}
/**
* Generate x random words. Uses Cryptographically-Secure Random Number Generator.
* @param wordlist imported wordlist for specific language
* @param strength mnemonic strength 128-256 bits
* @example
* generateMnemonic(wordlist, 128)
* // 'legal winner thank year wave sausage worth useful legal winner thank yellow'
*/
export function generateMnemonic(wordlist: string[], strength: number = 128): string {
anumber(strength);
if (strength % 32 !== 0 || strength > 256) throw new TypeError('Invalid entropy');
return entropyToMnemonic(randomBytes(strength / 8), wordlist);
}
const calcChecksum = (entropy: Uint8Array) => {
// Checksum is ent.length/4 bits long
const bitsLeft = 8 - entropy.length / 4;
// Zero rightmost "bitsLeft" bits in byte
// For example: bitsLeft=4 val=10111101 -> 10110000
return new Uint8Array([(sha256(entropy)[0]! >> bitsLeft) << bitsLeft]);
};
function getCoder(wordlist: string[]) {
if (!Array.isArray(wordlist) || wordlist.length !== 2048 || typeof wordlist[0] !== 'string')
throw new Error('Wordlist: expected array of 2048 strings');
wordlist.forEach((i) => {
if (typeof i !== 'string') throw new Error('wordlist: non-string element: ' + i);
});
return baseUtils.chain(
baseUtils.checksum(1, calcChecksum),
baseUtils.radix2(11, true),
baseUtils.alphabet(wordlist)
);
}
/**
* Reversible: Converts mnemonic string to raw entropy in form of byte array.
* @param mnemonic 12-24 words
* @param wordlist imported wordlist for specific language
* @example
* const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
* mnemonicToEntropy(mnem, wordlist)
* // Produces
* new Uint8Array([
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
* ])
*/
export function mnemonicToEntropy(mnemonic: string, wordlist: string[]): Uint8Array {
const { words } = normalize(mnemonic);
const entropy = getCoder(wordlist).decode(words);
aentropy(entropy);
return entropy;
}
/**
* Reversible: Converts raw entropy in form of byte array to mnemonic string.
* @param entropy byte array
* @param wordlist imported wordlist for specific language
* @returns 12-24 words
* @example
* const ent = new Uint8Array([
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
* ]);
* entropyToMnemonic(ent, wordlist);
* // 'legal winner thank year wave sausage worth useful legal winner thank yellow'
*/
export function entropyToMnemonic(entropy: Uint8Array, wordlist: string[]): string {
aentropy(entropy);
const words = getCoder(wordlist).encode(entropy);
return words.join(isJapanese(wordlist) ? '\u3000' : ' ');
}
/**
* Validates mnemonic for being 12-24 words contained in `wordlist`.
*/
export function validateMnemonic(mnemonic: string, wordlist: string[]): boolean {
try {
mnemonicToEntropy(mnemonic, wordlist);
} catch (e) {
return false;
}
return true;
}
const psalt = (passphrase: string) => nfkd('mnemonic' + passphrase);
/**
* Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.
* @param mnemonic 12-24 words
* @param passphrase string that will additionally protect the key
* @returns 64 bytes of key data
* @example
* const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
* await mnemonicToSeed(mnem, 'password');
* // new Uint8Array([...64 bytes])
*/
export function mnemonicToSeed(mnemonic: string, passphrase = ''): Promise<Uint8Array> {
return pbkdf2Async(sha512, normalize(mnemonic).nfkd, psalt(passphrase), { c: 2048, dkLen: 64 });
}
/**
* Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.
* @param mnemonic 12-24 words
* @param passphrase string that will additionally protect the key
* @returns 64 bytes of key data
* @example
* const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
* mnemonicToSeedSync(mnem, 'password');
* // new Uint8Array([...64 bytes])
*/
export function mnemonicToSeedSync(mnemonic: string, passphrase = ''): Uint8Array {
return pbkdf2(sha512, normalize(mnemonic).nfkd, psalt(passphrase), { c: 2048, dkLen: 64 });
}

1
node_modules/@scure/bip39/wordlists/czech.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2051
node_modules/@scure/bip39/wordlists/czech.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@scure/bip39/wordlists/english.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2051
node_modules/@scure/bip39/wordlists/english.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@scure/bip39/wordlists/french.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2051
node_modules/@scure/bip39/wordlists/french.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@scure/bip39/wordlists/italian.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2051
node_modules/@scure/bip39/wordlists/italian.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@scure/bip39/wordlists/japanese.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2051
node_modules/@scure/bip39/wordlists/japanese.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@scure/bip39/wordlists/korean.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2051
node_modules/@scure/bip39/wordlists/korean.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@scure/bip39/wordlists/portuguese.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2051
node_modules/@scure/bip39/wordlists/portuguese.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2051
node_modules/@scure/bip39/wordlists/simplified-chinese.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@scure/bip39/wordlists/spanish.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

2051
node_modules/@scure/bip39/wordlists/spanish.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
export declare const wordlist: string[];

File diff suppressed because it is too large Load Diff