diff --git a/packages/hw-ledger-transports/browser.d.ts b/packages/hw-ledger-transports/browser.d.ts new file mode 100644 index 0000000..4cca0c9 --- /dev/null +++ b/packages/hw-ledger-transports/browser.d.ts @@ -0,0 +1,2 @@ +export { packageInfo } from './packageInfo.js'; +export declare const transports: import("./types.js").TransportDef[]; diff --git a/packages/hw-ledger-transports/browser.js b/packages/hw-ledger-transports/browser.js new file mode 100644 index 0000000..bdbe646 --- /dev/null +++ b/packages/hw-ledger-transports/browser.js @@ -0,0 +1,5 @@ +import LedgerHid from '@ledgerhq/hw-transport-webhid'; +import LedgerUsb from '@ledgerhq/hw-transport-webusb'; +import { createDefs } from './util.js'; +export { packageInfo } from './packageInfo.js'; +export const transports = /*#__PURE__*/ createDefs(['webusb', LedgerUsb], ['hid', LedgerHid]); diff --git a/packages/hw-ledger-transports/cjs/browser.d.ts b/packages/hw-ledger-transports/cjs/browser.d.ts new file mode 100644 index 0000000..4cca0c9 --- /dev/null +++ b/packages/hw-ledger-transports/cjs/browser.d.ts @@ -0,0 +1,2 @@ +export { packageInfo } from './packageInfo.js'; +export declare const transports: import("./types.js").TransportDef[]; diff --git a/packages/hw-ledger-transports/cjs/browser.js b/packages/hw-ledger-transports/cjs/browser.js new file mode 100644 index 0000000..ea86308 --- /dev/null +++ b/packages/hw-ledger-transports/cjs/browser.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.transports = exports.packageInfo = void 0; +const tslib_1 = require("tslib"); +const hw_transport_webhid_1 = tslib_1.__importDefault(require("@ledgerhq/hw-transport-webhid")); +const hw_transport_webusb_1 = tslib_1.__importDefault(require("@ledgerhq/hw-transport-webusb")); +const util_js_1 = require("./util.js"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +exports.transports = (0, util_js_1.createDefs)(['webusb', hw_transport_webusb_1.default], ['hid', hw_transport_webhid_1.default]); diff --git a/packages/hw-ledger-transports/cjs/empty.d.ts b/packages/hw-ledger-transports/cjs/empty.d.ts new file mode 100644 index 0000000..4cca0c9 --- /dev/null +++ b/packages/hw-ledger-transports/cjs/empty.d.ts @@ -0,0 +1,2 @@ +export { packageInfo } from './packageInfo.js'; +export declare const transports: import("./types.js").TransportDef[]; diff --git a/packages/hw-ledger-transports/cjs/empty.js b/packages/hw-ledger-transports/cjs/empty.js new file mode 100644 index 0000000..022b0b2 --- /dev/null +++ b/packages/hw-ledger-transports/cjs/empty.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.transports = exports.packageInfo = void 0; +const util_js_1 = require("./util.js"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +exports.transports = (0, util_js_1.createDefs)(); diff --git a/packages/hw-ledger-transports/cjs/node.d.ts b/packages/hw-ledger-transports/cjs/node.d.ts new file mode 100644 index 0000000..4cca0c9 --- /dev/null +++ b/packages/hw-ledger-transports/cjs/node.d.ts @@ -0,0 +1,2 @@ +export { packageInfo } from './packageInfo.js'; +export declare const transports: import("./types.js").TransportDef[]; diff --git a/packages/hw-ledger-transports/cjs/node.js b/packages/hw-ledger-transports/cjs/node.js new file mode 100644 index 0000000..367ea08 --- /dev/null +++ b/packages/hw-ledger-transports/cjs/node.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.transports = exports.packageInfo = void 0; +const tslib_1 = require("tslib"); +const hw_transport_node_hid_singleton_1 = tslib_1.__importDefault(require("@ledgerhq/hw-transport-node-hid-singleton")); +const util_js_1 = require("./util.js"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +exports.transports = (0, util_js_1.createDefs)(['hid', hw_transport_node_hid_singleton_1.default]); diff --git a/packages/hw-ledger-transports/cjs/package.json b/packages/hw-ledger-transports/cjs/package.json new file mode 100644 index 0000000..5bbefff --- /dev/null +++ b/packages/hw-ledger-transports/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/hw-ledger-transports/cjs/packageDetect.d.ts b/packages/hw-ledger-transports/cjs/packageDetect.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/hw-ledger-transports/cjs/packageDetect.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/hw-ledger-transports/cjs/packageDetect.js b/packages/hw-ledger-transports/cjs/packageDetect.js new file mode 100644 index 0000000..a518596 --- /dev/null +++ b/packages/hw-ledger-transports/cjs/packageDetect.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = require("@pezkuwi/util"); +const packageInfo_js_1 = require("./packageInfo.js"); +(0, util_1.detectPackage)(packageInfo_js_1.packageInfo, null, []); diff --git a/packages/hw-ledger-transports/cjs/packageInfo.d.ts b/packages/hw-ledger-transports/cjs/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/hw-ledger-transports/cjs/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/hw-ledger-transports/cjs/packageInfo.js b/packages/hw-ledger-transports/cjs/packageInfo.js new file mode 100644 index 0000000..4cd5a96 --- /dev/null +++ b/packages/hw-ledger-transports/cjs/packageInfo.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +exports.packageInfo = { name: '@pezkuwi/hw-ledger-transports', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; diff --git a/packages/hw-ledger-transports/cjs/react-native.d.ts b/packages/hw-ledger-transports/cjs/react-native.d.ts new file mode 100644 index 0000000..9d91112 --- /dev/null +++ b/packages/hw-ledger-transports/cjs/react-native.d.ts @@ -0,0 +1 @@ +export * from './empty.js'; diff --git a/packages/hw-ledger-transports/cjs/react-native.js b/packages/hw-ledger-transports/cjs/react-native.js new file mode 100644 index 0000000..f180229 --- /dev/null +++ b/packages/hw-ledger-transports/cjs/react-native.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +tslib_1.__exportStar(require("./empty.js"), exports); diff --git a/packages/hw-ledger-transports/cjs/types.d.ts b/packages/hw-ledger-transports/cjs/types.d.ts new file mode 100644 index 0000000..5821d87 --- /dev/null +++ b/packages/hw-ledger-transports/cjs/types.d.ts @@ -0,0 +1,9 @@ +import type * as HwTransport from '@ledgerhq/hw-transport'; +export type TransportType = 'hid' | 'webusb'; +export type Transport = HwTransport.default; +export interface TransportDef { + /** Create a transport to be used in Ledger operations */ + create(): Promise; + /** The type of the underlying transport definition */ + type: TransportType; +} diff --git a/packages/hw-ledger-transports/cjs/types.js b/packages/hw-ledger-transports/cjs/types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/packages/hw-ledger-transports/cjs/types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/packages/hw-ledger-transports/cjs/util.d.ts b/packages/hw-ledger-transports/cjs/util.d.ts new file mode 100644 index 0000000..e3c7187 --- /dev/null +++ b/packages/hw-ledger-transports/cjs/util.d.ts @@ -0,0 +1,2 @@ +import type { TransportDef, TransportType } from './types.js'; +export declare function createDefs(...items: readonly [type: TransportType, Clazz: unknown][]): TransportDef[]; diff --git a/packages/hw-ledger-transports/cjs/util.js b/packages/hw-ledger-transports/cjs/util.js new file mode 100644 index 0000000..028e2e7 --- /dev/null +++ b/packages/hw-ledger-transports/cjs/util.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createDefs = createDefs; +function createDefs(...items) { + return items.map(([type, Clazz]) => ({ + create: () => Clazz.create(), + type + })); +} diff --git a/packages/hw-ledger-transports/empty.d.ts b/packages/hw-ledger-transports/empty.d.ts new file mode 100644 index 0000000..4cca0c9 --- /dev/null +++ b/packages/hw-ledger-transports/empty.d.ts @@ -0,0 +1,2 @@ +export { packageInfo } from './packageInfo.js'; +export declare const transports: import("./types.js").TransportDef[]; diff --git a/packages/hw-ledger-transports/empty.js b/packages/hw-ledger-transports/empty.js new file mode 100644 index 0000000..8006b5e --- /dev/null +++ b/packages/hw-ledger-transports/empty.js @@ -0,0 +1,3 @@ +import { createDefs } from './util.js'; +export { packageInfo } from './packageInfo.js'; +export const transports = /*#__PURE__*/ createDefs(); diff --git a/packages/hw-ledger-transports/node.d.ts b/packages/hw-ledger-transports/node.d.ts new file mode 100644 index 0000000..4cca0c9 --- /dev/null +++ b/packages/hw-ledger-transports/node.d.ts @@ -0,0 +1,2 @@ +export { packageInfo } from './packageInfo.js'; +export declare const transports: import("./types.js").TransportDef[]; diff --git a/packages/hw-ledger-transports/node.js b/packages/hw-ledger-transports/node.js new file mode 100644 index 0000000..d48ab8a --- /dev/null +++ b/packages/hw-ledger-transports/node.js @@ -0,0 +1,4 @@ +import LedgerHid from '@ledgerhq/hw-transport-node-hid-singleton'; +import { createDefs } from './util.js'; +export { packageInfo } from './packageInfo.js'; +export const transports = /*#__PURE__*/ createDefs(['hid', LedgerHid]); diff --git a/packages/hw-ledger-transports/package.json b/packages/hw-ledger-transports/package.json index 3fdd7ab..59aa812 100644 --- a/packages/hw-ledger-transports/package.json +++ b/packages/hw-ledger-transports/package.json @@ -14,15 +14,196 @@ }, "sideEffects": false, "type": "module", - "version": "14.0.10", - "browser": "browser.js", - "main": "node.js", - "react-native": "react-native.js", + "version": "14.0.11", + "main": "./cjs/node.js", + "module": "./node.js", + "browser": "./cjs/browser.js", + "react-native": "./cjs/react-native.js", + "types": "./node.d.ts", + "exports": { + "./cjs/package.json": "./cjs/package.json", + "./cjs/*": "./cjs/*.js", + ".": { + "types": "./node.d.ts", + "react-native": { + "module": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + }, + "require": { + "types": "./cjs/react-native.d.ts", + "default": "./cjs/react-native.js" + }, + "default": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + } + }, + "browser": { + "module": { + "types": "./browser.d.ts", + "default": "./browser.js" + }, + "require": { + "types": "./cjs/browser.d.ts", + "default": "./cjs/browser.js" + }, + "default": { + "types": "./browser.d.ts", + "default": "./browser.js" + } + }, + "node": { + "module": { + "types": "./node.d.ts", + "default": "./node.js" + }, + "require": { + "types": "./cjs/node.d.ts", + "default": "./cjs/node.js" + }, + "default": { + "types": "./node.d.ts", + "default": "./node.js" + } + } + }, + "./browser": { + "module": { + "types": "./browser.d.ts", + "default": "./browser.js" + }, + "require": { + "types": "./cjs/browser.d.ts", + "default": "./cjs/browser.js" + }, + "default": { + "types": "./browser.d.ts", + "default": "./browser.js" + } + }, + "./empty": { + "module": { + "types": "./empty.d.ts", + "default": "./empty.js" + }, + "require": { + "types": "./cjs/empty.d.ts", + "default": "./cjs/empty.js" + }, + "default": { + "types": "./empty.d.ts", + "default": "./empty.js" + } + }, + "./node": { + "module": { + "types": "./node.d.ts", + "default": "./node.js" + }, + "require": { + "types": "./cjs/node.d.ts", + "default": "./cjs/node.js" + }, + "default": { + "types": "./node.d.ts", + "default": "./node.js" + } + }, + "./package.json": { + "require": "./cjs/package.json", + "default": "./package.json" + }, + "./packageDetect": { + "module": { + "types": "./packageDetect.d.ts", + "default": "./packageDetect.js" + }, + "require": { + "types": "./cjs/packageDetect.d.ts", + "default": "./cjs/packageDetect.js" + }, + "default": { + "types": "./packageDetect.d.ts", + "default": "./packageDetect.js" + } + }, + "./packageInfo.js": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./packageInfo": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./react-native": { + "module": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + }, + "require": { + "types": "./cjs/react-native.d.ts", + "default": "./cjs/react-native.js" + }, + "default": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + } + }, + "./types": { + "module": { + "types": "./types.d.ts", + "default": "./types.js" + }, + "require": { + "types": "./cjs/types.d.ts", + "default": "./cjs/types.js" + }, + "default": { + "types": "./types.d.ts", + "default": "./types.js" + } + }, + "./util": { + "module": { + "types": "./util.d.ts", + "default": "./util.js" + }, + "require": { + "types": "./cjs/util.d.ts", + "default": "./cjs/util.js" + }, + "default": { + "types": "./util.d.ts", + "default": "./util.js" + } + } + }, "dependencies": { "@ledgerhq/hw-transport": "^6.31.4", "@ledgerhq/hw-transport-webhid": "^6.29.4", "@ledgerhq/hw-transport-webusb": "^6.29.4", - "@pezkuwi/util": "workspace:*", + "@pezkuwi/util": "14.0.11", "tslib": "^2.8.0" }, "optionalDependencies": { diff --git a/packages/hw-ledger-transports/packageDetect.d.ts b/packages/hw-ledger-transports/packageDetect.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/hw-ledger-transports/packageDetect.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/hw-ledger-transports/packageDetect.js b/packages/hw-ledger-transports/packageDetect.js new file mode 100644 index 0000000..47ccfce --- /dev/null +++ b/packages/hw-ledger-transports/packageDetect.js @@ -0,0 +1,3 @@ +import { detectPackage } from '@pezkuwi/util'; +import { packageInfo } from './packageInfo.js'; +detectPackage(packageInfo, null, []); diff --git a/packages/hw-ledger-transports/packageInfo.d.ts b/packages/hw-ledger-transports/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/hw-ledger-transports/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/hw-ledger-transports/packageInfo.js b/packages/hw-ledger-transports/packageInfo.js new file mode 100644 index 0000000..2109313 --- /dev/null +++ b/packages/hw-ledger-transports/packageInfo.js @@ -0,0 +1 @@ +export const packageInfo = { name: '@pezkuwi/hw-ledger-transports', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; diff --git a/packages/hw-ledger-transports/react-native.d.ts b/packages/hw-ledger-transports/react-native.d.ts new file mode 100644 index 0000000..9d91112 --- /dev/null +++ b/packages/hw-ledger-transports/react-native.d.ts @@ -0,0 +1 @@ +export * from './empty.js'; diff --git a/packages/hw-ledger-transports/react-native.js b/packages/hw-ledger-transports/react-native.js new file mode 100644 index 0000000..9d91112 --- /dev/null +++ b/packages/hw-ledger-transports/react-native.js @@ -0,0 +1 @@ +export * from './empty.js'; diff --git a/packages/hw-ledger-transports/types.d.ts b/packages/hw-ledger-transports/types.d.ts new file mode 100644 index 0000000..5821d87 --- /dev/null +++ b/packages/hw-ledger-transports/types.d.ts @@ -0,0 +1,9 @@ +import type * as HwTransport from '@ledgerhq/hw-transport'; +export type TransportType = 'hid' | 'webusb'; +export type Transport = HwTransport.default; +export interface TransportDef { + /** Create a transport to be used in Ledger operations */ + create(): Promise; + /** The type of the underlying transport definition */ + type: TransportType; +} diff --git a/packages/hw-ledger-transports/types.js b/packages/hw-ledger-transports/types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/hw-ledger-transports/types.js @@ -0,0 +1 @@ +export {}; diff --git a/packages/hw-ledger-transports/util.d.ts b/packages/hw-ledger-transports/util.d.ts new file mode 100644 index 0000000..e3c7187 --- /dev/null +++ b/packages/hw-ledger-transports/util.d.ts @@ -0,0 +1,2 @@ +import type { TransportDef, TransportType } from './types.js'; +export declare function createDefs(...items: readonly [type: TransportType, Clazz: unknown][]): TransportDef[]; diff --git a/packages/hw-ledger-transports/util.js b/packages/hw-ledger-transports/util.js new file mode 100644 index 0000000..e2f4338 --- /dev/null +++ b/packages/hw-ledger-transports/util.js @@ -0,0 +1,6 @@ +export function createDefs(...items) { + return items.map(([type, Clazz]) => ({ + create: () => Clazz.create(), + type + })); +} diff --git a/packages/hw-ledger/Ledger.d.ts b/packages/hw-ledger/Ledger.d.ts new file mode 100644 index 0000000..a7a75f0 --- /dev/null +++ b/packages/hw-ledger/Ledger.d.ts @@ -0,0 +1,43 @@ +import type { SubstrateApp } from '@zondax/ledger-substrate'; +import type { TransportType } from '@pezkuwi/hw-ledger-transports/types'; +import type { AccountOptions, LedgerAddress, LedgerSignature, LedgerVersion } from './types.js'; +import { ledgerApps } from './defaults.js'; +export { packageInfo } from './packageInfo.js'; +type Chain = keyof typeof ledgerApps; +/** + * @name Ledger + * + * @description + * Legacy wrapper for a ledger app - + * - it connects automatically on use, creating an underlying interface as required + * - Promises reject with errors (unwrapped errors from @zondax/ledger-substrate) + * @deprecated Use LedgerGeneric for up to date integration with ledger + */ +export declare class Ledger { + #private; + constructor(transport: TransportType, chain: Chain); + /** + * Returns the address associated with a specific account & address offset. Optionally + * asks for on-device confirmation + */ + getAddress(confirm?: boolean, accountOffset?: number, addressOffset?: number, { account, addressIndex, change }?: Partial): Promise; + /** + * Returns the version of the Ledger application on the device + */ + getVersion(): Promise; + /** + * Signs a transaction on the Ledger device + */ + sign(message: Uint8Array, accountOffset?: number, addressOffset?: number, options?: Partial): Promise; + /** + * Signs a message (non-transactional) on the Ledger device + */ + signRaw(message: Uint8Array, accountOffset?: number, addressOffset?: number, options?: Partial): Promise; + /** + * @internal + * + * Returns a created SubstrateApp to perform operations against. Generally + * this is only used internally, to ensure consistent bahavior. + */ + withApp(fn: (app: SubstrateApp) => Promise): Promise; +} diff --git a/packages/hw-ledger/Ledger.js b/packages/hw-ledger/Ledger.js new file mode 100644 index 0000000..0d16993 --- /dev/null +++ b/packages/hw-ledger/Ledger.js @@ -0,0 +1,112 @@ +import { newSubstrateApp } from '@zondax/ledger-substrate'; +import { transports } from '@pezkuwi/hw-ledger-transports'; +import { hexAddPrefix, u8aToBuffer, u8aWrapBytes } from '@pezkuwi/util'; +import { LEDGER_DEFAULT_ACCOUNT, LEDGER_DEFAULT_CHANGE, LEDGER_DEFAULT_INDEX, LEDGER_SUCCESS_CODE } from './constants.js'; +import { ledgerApps } from './defaults.js'; +export { packageInfo } from './packageInfo.js'; +/** @internal Wraps a SubstrateApp call, checking the result for any errors which result in a rejection */ +async function wrapError(promise) { + const result = await promise; + if (result.return_code !== LEDGER_SUCCESS_CODE) { + throw new Error(result.error_message); + } + return result; +} +/** @internal Wraps a sign/signRaw call and returns the associated signature */ +function sign(method, message, accountOffset = 0, addressOffset = 0, { account = LEDGER_DEFAULT_ACCOUNT, addressIndex = LEDGER_DEFAULT_INDEX, change = LEDGER_DEFAULT_CHANGE } = {}) { + return async (app) => { + const { signature } = await wrapError(app[method](account + accountOffset, change, addressIndex + addressOffset, u8aToBuffer(message))); + return { + signature: hexAddPrefix(signature.toString('hex')) + }; + }; +} +/** + * @name Ledger + * + * @description + * Legacy wrapper for a ledger app - + * - it connects automatically on use, creating an underlying interface as required + * - Promises reject with errors (unwrapped errors from @zondax/ledger-substrate) + * @deprecated Use LedgerGeneric for up to date integration with ledger + */ +export class Ledger { + #ledgerName; + #transportDef; + #app = null; + constructor(transport, chain) { + const ledgerName = ledgerApps[chain]; + const transportDef = transports.find(({ type }) => type === transport); + if (!ledgerName) { + throw new Error(`Unsupported Ledger chain ${chain}`); + } + else if (!transportDef) { + throw new Error(`Unsupported Ledger transport ${transport}`); + } + this.#ledgerName = ledgerName; + this.#transportDef = transportDef; + } + /** + * Returns the address associated with a specific account & address offset. Optionally + * asks for on-device confirmation + */ + async getAddress(confirm = false, accountOffset = 0, addressOffset = 0, { account = LEDGER_DEFAULT_ACCOUNT, addressIndex = LEDGER_DEFAULT_INDEX, change = LEDGER_DEFAULT_CHANGE } = {}) { + return this.withApp(async (app) => { + const { address, pubKey } = await wrapError(app.getAddress(account + accountOffset, change, addressIndex + addressOffset, confirm)); + return { + address, + publicKey: hexAddPrefix(pubKey) + }; + }); + } + /** + * Returns the version of the Ledger application on the device + */ + async getVersion() { + return this.withApp(async (app) => { + const { device_locked: isLocked, major, minor, patch, test_mode: isTestMode } = await wrapError(app.getVersion()); + return { + isLocked, + isTestMode, + version: [major, minor, patch] + }; + }); + } + /** + * Signs a transaction on the Ledger device + */ + async sign(message, accountOffset, addressOffset, options) { + return this.withApp(sign('sign', message, accountOffset, addressOffset, options)); + } + /** + * Signs a message (non-transactional) on the Ledger device + */ + async signRaw(message, accountOffset, addressOffset, options) { + return this.withApp(sign('signRaw', u8aWrapBytes(message), accountOffset, addressOffset, options)); + } + /** + * @internal + * + * Returns a created SubstrateApp to perform operations against. Generally + * this is only used internally, to ensure consistent bahavior. + */ + async withApp(fn) { + try { + if (!this.#app) { + const transport = await this.#transportDef.create(); + // We need this override for the actual type passing - the Deno environment + // is quite a bit stricter and it yields invalids between the two (specifically + // since we mangle the imports from .default in the types for CJS/ESM and between + // esm.sh versions this yields problematic outputs) + // + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any + this.#app = newSubstrateApp(transport, this.#ledgerName); + } + return await fn(this.#app); + } + catch (error) { + this.#app = null; + throw error; + } + } +} diff --git a/packages/hw-ledger/LedgerGeneric.d.ts b/packages/hw-ledger/LedgerGeneric.d.ts new file mode 100644 index 0000000..24939bd --- /dev/null +++ b/packages/hw-ledger/LedgerGeneric.d.ts @@ -0,0 +1,63 @@ +import type { TransportType } from '@pezkuwi/hw-ledger-transports/types'; +import type { AccountOptionsGeneric, LedgerAddress, LedgerSignature, LedgerVersion } from './types.js'; +import { PolkadotGenericApp } from '@zondax/ledger-substrate'; +import { ledgerApps } from './defaults.js'; +export { packageInfo } from './packageInfo.js'; +type Chain = keyof typeof ledgerApps; +/** + * @name Ledger + * + * @description + * A very basic wrapper for a ledger app - + * - it connects automatically on use, creating an underlying interface as required + * - Promises reject with errors (unwrapped errors from @zondax/ledger-substrate-js) + */ +export declare class LedgerGeneric { + #private; + constructor(transport: TransportType, chain: Chain, slip44: number, chainId?: string, metaUrl?: string); + /** + * @description Returns the address associated with a specific Ed25519 account & address offset. Optionally + * asks for on-device confirmation + */ + getAddress(ss58Prefix: number, confirm?: boolean, accountIndex?: number, addressOffset?: number): Promise; + /** + * @description Returns the address associated with a specific ecdsa account & address offset. Optionally + * asks for on-device confirmation + */ + getAddressEcdsa(confirm?: boolean, accountIndex?: number, addressOffset?: number): Promise; + /** + * @description Returns the version of the Ledger application on the device + */ + getVersion(): Promise; + /** + * @description Signs a transaction on the Ledger device. This requires the LedgerGeneric class to be instantiated with `chainId`, and `metaUrl` + */ + sign(message: Uint8Array, accountIndex?: number, addressOffset?: number): Promise; + /** + * @description Signs a message (non-transactional) on the Ledger device + */ + signRaw(message: Uint8Array, accountIndex?: number, addressOffset?: number): Promise; + /** + * @description Signs a transaction on the Ledger device with Ecdsa. This requires the LedgerGeneric class to be instantiated with `chainId`, and `metaUrl` + */ + signEcdsa(message: Uint8Array, accountIndex?: number, addressOffset?: number): Promise; + /** + * @description Signs a message with Ecdsa (non-transactional) on the Ledger device + */ + signRawEcdsa(message: Uint8Array, accountIndex?: number, addressOffset?: number): Promise; + /** + * @description Signs a transaction on the ledger device provided some metadata. + */ + signWithMetadata(message: Uint8Array, accountIndex?: number, addressOffset?: number, options?: Partial): Promise; + /** + * @description Signs a transaction on the ledger device for an ecdsa signature provided some metadata. + */ + signWithMetadataEcdsa(message: Uint8Array, accountIndex?: number, addressOffset?: number, options?: Partial): Promise; + /** + * @internal + * + * Returns a created PolkadotGenericApp to perform operations against. Generally + * this is only used internally, to ensure consistent bahavior. + */ + withApp(fn: (app: PolkadotGenericApp) => Promise): Promise; +} diff --git a/packages/hw-ledger/LedgerGeneric.js b/packages/hw-ledger/LedgerGeneric.js new file mode 100644 index 0000000..5570cee --- /dev/null +++ b/packages/hw-ledger/LedgerGeneric.js @@ -0,0 +1,211 @@ +import { PolkadotGenericApp } from '@zondax/ledger-substrate'; +import { transports } from '@pezkuwi/hw-ledger-transports'; +import { hexAddPrefix, u8aToBuffer, u8aWrapBytes } from '@pezkuwi/util'; +import { ledgerApps } from './defaults.js'; +export { packageInfo } from './packageInfo.js'; +/** @internal Wraps a PolkadotGenericApp call, checking the result for any errors which result in a rejection */ +async function wrapError(promise) { + let result; + try { + result = await promise; + } + catch (e) { + // We check to see if the propogated error is the newer ResponseError type. + // The response code use to be part of the result, but with the latest breaking changes from 0.42.x + // the interface and it's types have completely changed. + if (e.returnCode) { + throw new Error(`${e.returnCode}: ${e.errorMessage}`); + } + throw new Error(e.message); + } + return result; +} +/** @internal Wraps a signEd25519/signRawEd25519 call and returns the associated signature */ +function sign(method, message, slip44, accountIndex = 0, addressOffset = 0) { + const bip42Path = `m/44'/${slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return async (app) => { + const { signature } = await wrapError(app[method](bip42Path, u8aToBuffer(message))); + return { + signature: hexAddPrefix(signature.toString('hex')) + }; + }; +} +/** @internal Wraps a signEcdsa/signRawEcdsa call and returns the associated signature */ +function signEcdsa(method, message, slip44, accountIndex = 0, addressOffset = 0) { + const bip42Path = `m/44'/${slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return async (app) => { + const { r, s, v } = await wrapError(app[method](bip42Path, u8aToBuffer(message))); + const signature = Buffer.concat([r, s, v]); + return { + signature: hexAddPrefix(signature.toString('hex')) + }; + }; +} +/** @internal Wraps a signWithMetadataEd25519 call and returns the associated signature */ +function signWithMetadata(message, slip44, accountIndex = 0, addressOffset = 0, { metadata } = {}) { + const bip42Path = `m/44'/${slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return async (app) => { + if (!metadata) { + throw new Error('The metadata option must be present when using signWithMetadata'); + } + const bufferMsg = Buffer.from(message); + const { signature } = await wrapError(app.signWithMetadataEd25519(bip42Path, bufferMsg, metadata)); + return { + signature: hexAddPrefix(signature.toString('hex')) + }; + }; +} +/** @internal Wraps a signWithMetadataEcdsa call and returns the associated signature */ +function signWithMetadataEcdsa(message, slip44, accountIndex = 0, addressOffset = 0, { metadata } = {}) { + const bip42Path = `m/44'/${slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return async (app) => { + if (!metadata) { + throw new Error('The metadata option must be present when using signWithMetadata'); + } + const bufferMsg = Buffer.from(message); + const { r, s, v } = await wrapError(app.signWithMetadataEcdsa(bip42Path, bufferMsg, metadata)); + const signature = Buffer.concat([r, s, v]); + return { + signature: hexAddPrefix(signature.toString('hex')) + }; + }; +} +/** + * @name Ledger + * + * @description + * A very basic wrapper for a ledger app - + * - it connects automatically on use, creating an underlying interface as required + * - Promises reject with errors (unwrapped errors from @zondax/ledger-substrate-js) + */ +export class LedgerGeneric { + #transportDef; + #slip44; + /** + * The chainId is represented by the chains token in all lowercase. Example: Polkadot -> dot + */ + #chainId; + /** + * The metaUrl is seen as a server url that the underlying `PolkadotGenericApp` will use to + * retrieve the signature given a tx blob, and a chainId. It is important to note that if you would like to avoid + * having any network calls made, use `signWithMetadata`, and avoid `sign`. + */ + #metaUrl; + #app = null; + constructor(transport, chain, slip44, chainId, metaUrl) { + const ledgerName = ledgerApps[chain]; + const transportDef = transports.find(({ type }) => type === transport); + if (!ledgerName) { + throw new Error(`Unsupported Ledger chain ${chain}`); + } + else if (!transportDef) { + throw new Error(`Unsupported Ledger transport ${transport}`); + } + this.#metaUrl = metaUrl; + this.#chainId = chainId; + this.#slip44 = slip44; + this.#transportDef = transportDef; + } + /** + * @description Returns the address associated with a specific Ed25519 account & address offset. Optionally + * asks for on-device confirmation + */ + async getAddress(ss58Prefix, confirm = false, accountIndex = 0, addressOffset = 0) { + const bip42Path = `m/44'/${this.#slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return this.withApp(async (app) => { + const { address, pubKey } = await wrapError(app.getAddressEd25519(bip42Path, ss58Prefix, confirm)); + return { + address, + publicKey: hexAddPrefix(pubKey) + }; + }); + } + /** + * @description Returns the address associated with a specific ecdsa account & address offset. Optionally + * asks for on-device confirmation + */ + async getAddressEcdsa(confirm = false, accountIndex = 0, addressOffset = 0) { + const bip42Path = `m/44'/${this.#slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return this.withApp(async (app) => { + const { address, pubKey } = await wrapError(app.getAddressEcdsa(bip42Path, confirm)); + return { + address, + publicKey: hexAddPrefix(pubKey) + }; + }); + } + /** + * @description Returns the version of the Ledger application on the device + */ + async getVersion() { + return this.withApp(async (app) => { + const { deviceLocked: isLocked, major, minor, patch, testMode: isTestMode } = await wrapError(app.getVersion()); + return { + isLocked: !!isLocked, + isTestMode: !!isTestMode, + version: [major || 0, minor || 0, patch || 0] + }; + }); + } + /** + * @description Signs a transaction on the Ledger device. This requires the LedgerGeneric class to be instantiated with `chainId`, and `metaUrl` + */ + async sign(message, accountIndex, addressOffset) { + return this.withApp(sign('signEd25519', message, this.#slip44, accountIndex, addressOffset)); + } + /** + * @description Signs a message (non-transactional) on the Ledger device + */ + async signRaw(message, accountIndex, addressOffset) { + return this.withApp(sign('signRawEd25519', u8aWrapBytes(message), this.#slip44, accountIndex, addressOffset)); + } + /** + * @description Signs a transaction on the Ledger device with Ecdsa. This requires the LedgerGeneric class to be instantiated with `chainId`, and `metaUrl` + */ + async signEcdsa(message, accountIndex, addressOffset) { + return this.withApp(signEcdsa('signEcdsa', u8aWrapBytes(message), this.#slip44, accountIndex, addressOffset)); + } + /** + * @description Signs a message with Ecdsa (non-transactional) on the Ledger device + */ + async signRawEcdsa(message, accountIndex, addressOffset) { + return this.withApp(signEcdsa('signRawEcdsa', u8aWrapBytes(message), this.#slip44, accountIndex, addressOffset)); + } + /** + * @description Signs a transaction on the ledger device provided some metadata. + */ + async signWithMetadata(message, accountIndex, addressOffset, options) { + return this.withApp(signWithMetadata(message, this.#slip44, accountIndex, addressOffset, options)); + } + /** + * @description Signs a transaction on the ledger device for an ecdsa signature provided some metadata. + */ + async signWithMetadataEcdsa(message, accountIndex, addressOffset, options) { + return this.withApp(signWithMetadataEcdsa(message, this.#slip44, accountIndex, addressOffset, options)); + } + /** + * @internal + * + * Returns a created PolkadotGenericApp to perform operations against. Generally + * this is only used internally, to ensure consistent bahavior. + */ + async withApp(fn) { + try { + if (!this.#app) { + const transport = await this.#transportDef.create(); + // We need this override for the actual type passing - the Deno environment + // is quite a bit stricter and it yields invalids between the two (specifically + // since we mangle the imports from .default in the types for CJS/ESM and between + // esm.sh versions this yields problematic outputs) + // + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any + this.#app = new PolkadotGenericApp(transport, this.#chainId, this.#metaUrl); + } + return await fn(this.#app); + } + catch (error) { + this.#app = null; + throw error; + } + } +} diff --git a/packages/hw-ledger/bundle-pezkuwi-hw-ledger.js b/packages/hw-ledger/bundle-pezkuwi-hw-ledger.js new file mode 100644 index 0000000..7f1dcc4 --- /dev/null +++ b/packages/hw-ledger/bundle-pezkuwi-hw-ledger.js @@ -0,0 +1,9473 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@pezkuwi/util')) : + typeof define === 'function' && define.amd ? define(['exports', '@pezkuwi/util'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.pezkuwiHwLedger = {}, global.pezkuwiUtil)); +})(this, (function (exports, util$1) { 'use strict'; + + const global = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : window; + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function getAugmentedNamespace(n) { + if (n.__esModule) return n; + var f = n.default; + if (typeof f == "function") { + var a = function a () { + if (this instanceof a) { + return Reflect.construct(f, arguments, this.constructor); + } + return f.apply(this, arguments); + }; + a.prototype = f.prototype; + } else a = {}; + Object.defineProperty(a, '__esModule', {value: true}); + Object.keys(n).forEach(function (k) { + var d = Object.getOwnPropertyDescriptor(n, k); + Object.defineProperty(a, k, d.get ? d : { + enumerable: true, + get: function () { + return n[k]; + } + }); + }); + return a; + } + + var dist$1 = {}; + + var legacy_apps = {}; + + var supported_apps = {}; + + var substrate_app = {}; + + var common$1 = {}; + + (function (exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.ERROR_DESCRIPTION = exports$1.ECDSA_PUBKEY_LEN = exports$1.ED25519_PUBKEY_LEN = exports$1.CHUNK_SIZE = void 0; + exports$1.errorCodeToString = errorCodeToString; + exports$1.processErrorResponse = processErrorResponse; + exports$1.getVersion = getVersion; + exports$1.serializePath = serializePath; + exports$1.CHUNK_SIZE = 250; + exports$1.ED25519_PUBKEY_LEN = 32; + exports$1.ECDSA_PUBKEY_LEN = 33; + exports$1.ERROR_DESCRIPTION = { + 1: 'U2F: Unknown', + 2: 'U2F: Bad request', + 3: 'U2F: Configuration unsupported', + 4: 'U2F: Device Ineligible', + 5: 'U2F: Timeout', + 14: 'Timeout', + 0x9000: 'No errors', + 0x9001: 'Device is busy', + 0x6802: 'Error deriving keys', + 0x6400: 'Execution Error', + 0x6700: 'Wrong Length', + 0x6982: 'Empty Buffer', + 0x6983: 'Output buffer too small', + 0x6984: 'Data is invalid', + 0x6985: 'Conditions not satisfied', + 0x6986: 'Transaction rejected', + 0x6a80: 'Bad key handle', + 0x6b00: 'Invalid P1/P2', + 0x6d00: 'Instruction not supported', + 0x6e01: 'App does not seem to be open', + 0x6f00: 'Unknown error', + 0x6f01: 'Sign/verify error', + }; + function errorCodeToString(statusCode) { + if (statusCode in exports$1.ERROR_DESCRIPTION) + return exports$1.ERROR_DESCRIPTION[statusCode]; + return `Unknown Status Code: ${statusCode}`; + } + function isDict(v) { + return typeof v === 'object' && v !== null && !(v instanceof Array) && !(v instanceof Date); + } + function processErrorResponse(response) { + if (response != null) { + if (isDict(response)) { + if (Object.prototype.hasOwnProperty.call(response, 'returnCode')) { + return { + return_code: response.returnCode, + error_message: errorCodeToString(response.returnCode), + }; + } + if (Object.prototype.hasOwnProperty.call(response, 'statusCode')) { + return { + return_code: response.statusCode, + error_message: errorCodeToString(response.statusCode), + }; + } + if (Object.prototype.hasOwnProperty.call(response, 'return_code') && + Object.prototype.hasOwnProperty.call(response, 'error_message')) { + return response; + } + } + return { + return_code: 0xffff, + error_message: response.toString(), + }; + } + return { + return_code: 0xffff, + error_message: response.toString(), + }; + } + async function getVersion(transport, cla) { + try { + const response = await transport.send(cla, 0 , 0, 0); + const errorCodeData = response.subarray(-2); + const returnCode = errorCodeData[0] * 256 + errorCodeData[1]; + if (response.length !== 14 && response.length !== 20) { + return { + return_code: 27012 , + error_message: errorCodeToString(27012 ), + }; + } + let major, minor, patch, deviceLocked, targetId; + if (response.length === 14) { + major = response.readUInt16BE(1); + minor = response.readUInt16BE(3); + patch = response.readUInt16BE(5); + deviceLocked = response[7] === 1; + targetId = (response[8] << 24) + (response[9] << 16) + (response[10] << 8) + (response[11] << 0); + } + else { + major = response.readUInt32BE(1); + minor = response.readUInt32BE(5); + patch = response.readUInt32BE(9); + deviceLocked = response[13] === 1; + targetId = (response[14] << 24) + (response[15] << 16) + (response[16] << 8) + (response[17] << 0); + } + return { + return_code: returnCode, + error_message: errorCodeToString(returnCode), + test_mode: response[0] !== 0, + major, + minor, + patch, + deviceLocked, + target_id: targetId.toString(16), + }; + } + catch (e) { + return processErrorResponse(e); + } + } + function serializePath(slip0044, account, change, addressIndex) { + if (!Number.isInteger(account)) + throw new Error('Input must be an integer'); + if (!Number.isInteger(change)) + throw new Error('Input must be an integer'); + if (!Number.isInteger(addressIndex)) + throw new Error('Input must be an integer'); + const buf = Buffer.alloc(20); + buf.writeUInt32LE(0x8000002c, 0); + buf.writeUInt32LE(slip0044, 4); + buf.writeUInt32LE(account, 8); + buf.writeUInt32LE(change, 12); + buf.writeUInt32LE(addressIndex, 16); + return buf; + } + } (common$1)); + getDefaultExportFromCjs(common$1); + + Object.defineProperty(substrate_app, "__esModule", { value: true }); + substrate_app.SubstrateApp = void 0; + const common_1$2 = common$1; + class SubstrateApp { + constructor(transport, cla, slip0044) { + if (transport == null) { + throw new Error('Transport has not been defined'); + } + this.transport = transport; + this.cla = cla; + this.slip0044 = slip0044; + } + static serializePath(slip0044, account, change, addressIndex) { + if (!Number.isInteger(account)) + throw new Error('Input must be an integer'); + if (!Number.isInteger(change)) + throw new Error('Input must be an integer'); + if (!Number.isInteger(addressIndex)) + throw new Error('Input must be an integer'); + const buf = Buffer.alloc(20); + buf.writeUInt32LE(0x8000002c, 0); + buf.writeUInt32LE(slip0044, 4); + buf.writeUInt32LE(account, 8); + buf.writeUInt32LE(change, 12); + buf.writeUInt32LE(addressIndex, 16); + return buf; + } + static GetChunks(message) { + const chunks = []; + const buffer = Buffer.from(message); + for (let i = 0; i < buffer.length; i += common_1$2.CHUNK_SIZE) { + let end = i + common_1$2.CHUNK_SIZE; + if (i > buffer.length) { + end = buffer.length; + } + chunks.push(buffer.subarray(i, end)); + } + return chunks; + } + static signGetChunks(slip0044, account, change, addressIndex, message) { + const chunks = []; + const bip44Path = SubstrateApp.serializePath(slip0044, account, change, addressIndex); + chunks.push(bip44Path); + chunks.push(...SubstrateApp.GetChunks(message)); + return chunks; + } + async getVersion() { + try { + return await (0, common_1$2.getVersion)(this.transport, this.cla); + } + catch (e) { + return (0, common_1$2.processErrorResponse)(e); + } + } + async appInfo() { + return await this.transport.send(0xb0, 0x01, 0, 0).then(response => { + const errorCodeData = response.subarray(-2); + const returnCode = errorCodeData[0] * 256 + errorCodeData[1]; + let appName = ''; + let appVersion = ''; + let flagLen = 0; + let flagsValue = 0; + if (response[0] !== 1) { + return { + return_code: 0x9001, + error_message: 'response format ID not recognized', + }; + } + else { + const appNameLen = response[1]; + appName = response.subarray(2, 2 + appNameLen).toString('ascii'); + let idx = 2 + appNameLen; + const appVersionLen = response[idx]; + idx += 1; + appVersion = response.subarray(idx, idx + appVersionLen).toString('ascii'); + idx += appVersionLen; + const appFlagsLen = response[idx]; + idx += 1; + flagLen = appFlagsLen; + flagsValue = response[idx]; + } + return { + return_code: returnCode, + error_message: (0, common_1$2.errorCodeToString)(returnCode), + appName: appName === '' || 'err', + appVersion: appVersion === '' || 'err', + flagLen, + flagsValue, + flag_recovery: (flagsValue & 1) !== 0, + flag_signed_mcu_code: (flagsValue & 2) !== 0, + flag_onboarded: (flagsValue & 4) !== 0, + flag_pin_validated: (flagsValue & 128) !== 0, + }; + }, common_1$2.processErrorResponse); + } + async getAddress(account, change, addressIndex, requireConfirmation = false, scheme = 0 ) { + const bip44Path = SubstrateApp.serializePath(this.slip0044, account, change, addressIndex); + let p1 = 0; + if (requireConfirmation) + p1 = 1; + let p2 = 0; + if (!isNaN(scheme)) + p2 = scheme; + return await this.transport.send(this.cla, 1 , p1, p2, bip44Path).then(response => { + const errorCodeData = response.subarray(-2); + const errorCode = errorCodeData[0] * 256 + errorCodeData[1]; + let pubkeyLen = 32; + if (scheme == 2 ) { + pubkeyLen = 33; + } + return { + pubKey: response.subarray(0, pubkeyLen).toString('hex'), + address: response.subarray(pubkeyLen, response.length - 2).toString('ascii'), + return_code: errorCode, + error_message: (0, common_1$2.errorCodeToString)(errorCode), + }; + }, common_1$2.processErrorResponse); + } + async signSendChunk(chunkIdx, chunkNum, chunk, scheme = 0 , ins = 2 ) { + let payloadType = 1 ; + if (chunkIdx === 1) { + payloadType = 0 ; + } + if (chunkIdx === chunkNum) { + payloadType = 2 ; + } + let p2 = 0; + if (!isNaN(scheme)) + p2 = scheme; + return await this.transport.send(this.cla, ins, payloadType, p2, chunk, [36864 , 0x6984, 0x6a80]).then(response => { + const errorCodeData = response.subarray(-2); + const returnCode = errorCodeData[0] * 256 + errorCodeData[1]; + let errorMessage = (0, common_1$2.errorCodeToString)(returnCode); + let signature = null; + if (returnCode === 0x6a80 || returnCode === 0x6984) { + errorMessage = response.subarray(0, response.length - 2).toString('ascii'); + } + else if (response.length > 2) { + signature = response.subarray(0, response.length - 2); + } + return { + signature, + return_code: returnCode, + error_message: errorMessage, + }; + }, common_1$2.processErrorResponse); + } + async signImpl(account, change, addressIndex, message, ins, scheme = 0 ) { + const chunks = SubstrateApp.signGetChunks(this.slip0044, account, change, addressIndex, message); + return await this.signSendChunk(1, chunks.length, chunks[0], scheme, ins).then(async () => { + let result; + for (let i = 1; i < chunks.length; i += 1) { + result = await this.signSendChunk(1 + i, chunks.length, chunks[i], scheme, ins); + if (result.return_code !== 36864 ) { + break; + } + } + return { + return_code: result.return_code, + error_message: result.error_message, + signature: result.signature, + }; + }, common_1$2.processErrorResponse); + } + async sign(account, change, addressIndex, message, scheme = 0 ) { + return await this.signImpl(account, change, addressIndex, message, 2 , scheme); + } + async signRaw(account, change, addressIndex, message, scheme = 0 ) { + return await this.signImpl(account, change, addressIndex, message, 3 , scheme); + } + async getAllowlistPubKey() { + return await this.transport.send(this.cla, 144 , 0, 0).then(response => { + const errorCodeData = response.subarray(-2); + const returnCode = errorCodeData[0] * 256 + errorCodeData[1]; + console.log(response); + const pubkey = response.subarray(0, 32); + if (response.length !== 34) { + return { + return_code: 0x6984, + error_message: (0, common_1$2.errorCodeToString)(0x6984), + }; + } + return { + return_code: returnCode, + error_message: (0, common_1$2.errorCodeToString)(returnCode), + pubkey, + }; + }, common_1$2.processErrorResponse); + } + async setAllowlistPubKey(pk) { + return await this.transport.send(this.cla, 145 , 0, 0, pk).then(response => { + const errorCodeData = response.subarray(-2); + const returnCode = errorCodeData[0] * 256 + errorCodeData[1]; + return { + return_code: returnCode, + error_message: (0, common_1$2.errorCodeToString)(returnCode), + }; + }, common_1$2.processErrorResponse); + } + async getAllowlistHash() { + return await this.transport.send(this.cla, 146 , 0, 0).then(response => { + const errorCodeData = response.subarray(-2); + const returnCode = errorCodeData[0] * 256 + errorCodeData[1]; + console.log(response); + const hash = response.subarray(0, 32); + if (response.length !== 34) { + return { + return_code: 0x6984, + error_message: (0, common_1$2.errorCodeToString)(0x6984), + }; + } + return { + return_code: returnCode, + error_message: (0, common_1$2.errorCodeToString)(returnCode), + hash, + }; + }, common_1$2.processErrorResponse); + } + async uploadSendChunk(chunkIdx, chunkNum, chunk) { + let payloadType = 1 ; + if (chunkIdx === 1) { + payloadType = 0 ; + } + if (chunkIdx === chunkNum) { + payloadType = 2 ; + } + return await this.transport.send(this.cla, 147 , payloadType, 0, chunk, [36864 ]).then(response => { + const errorCodeData = response.subarray(-2); + const returnCode = errorCodeData[0] * 256 + errorCodeData[1]; + const errorMessage = (0, common_1$2.errorCodeToString)(returnCode); + return { + return_code: returnCode, + error_message: errorMessage, + }; + }, common_1$2.processErrorResponse); + } + async uploadAllowlist(message) { + const chunks = []; + chunks.push(Buffer.from([0])); + chunks.push(...SubstrateApp.GetChunks(message)); + return await this.uploadSendChunk(1, chunks.length, chunks[0]).then(async (result) => { + if (result.return_code !== 36864 ) { + return { + return_code: result.return_code, + error_message: result.error_message, + }; + } + for (let i = 1; i < chunks.length; i += 1) { + result = await this.uploadSendChunk(1 + i, chunks.length, chunks[i]); + if (result.return_code !== 36864 ) { + break; + } + } + return { + return_code: result.return_code, + error_message: result.error_message, + }; + }, common_1$2.processErrorResponse); + } + } + substrate_app.SubstrateApp = SubstrateApp; + + (function (exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.supportedApps = void 0; + exports$1.newSubstrateApp = newSubstrateApp; + exports$1.getAppParams = getAppParams; + const substrate_app_1 = substrate_app; + function newSubstrateApp(transport, chainName) { + const requestedApp = exports$1.supportedApps.find((app) => { + return app.name.toLowerCase() === chainName.toLowerCase(); + }); + if (requestedApp != null) { + return new substrate_app_1.SubstrateApp(transport, requestedApp.cla, requestedApp.slip0044); + } + throw new Error(`Error: ${chainName} not supported`); + } + function getAppParams(chainName) { + const params = exports$1.supportedApps.find((app) => { + return app.name.toLowerCase() === chainName.toLowerCase(); + }); + return params; + } + exports$1.supportedApps = [ + { + name: 'Polkadot', + cla: 0x90, + slip0044: 0x80000162, + ss58_addr_type: 0, + }, + { + name: 'Polymesh', + cla: 0x91, + slip0044: 0x80000253, + ss58_addr_type: 12, + }, + { + name: 'Dock', + cla: 0x92, + slip0044: 0x80000252, + ss58_addr_type: 22, + }, + { + name: 'Centrifuge', + cla: 0x93, + slip0044: 0x800002eb, + ss58_addr_type: 36, + }, + { + name: 'Edgeware', + cla: 0x94, + slip0044: 0x8000020b, + ss58_addr_type: 7, + }, + { + name: 'Equilibrium', + cla: 0x95, + slip0044: 0x85f5e0fd, + ss58_addr_type: 67, + }, + { + name: 'Statemint', + cla: 0x96, + slip0044: 0x80000162, + ss58_addr_type: 0, + }, + { + name: 'Statemine', + cla: 0x97, + slip0044: 0x800001b2, + ss58_addr_type: 2, + }, + { + name: 'Nodle', + cla: 0x98, + slip0044: 0x800003eb, + ss58_addr_type: 37, + }, + { + name: 'Kusama', + cla: 0x99, + slip0044: 0x800001b2, + ss58_addr_type: 2, + }, + { + name: 'Karura', + cla: 0x9a, + slip0044: 0x800002ae, + ss58_addr_type: 8, + }, + { + name: 'Acala', + cla: 0x9b, + slip0044: 0x80000313, + ss58_addr_type: 10, + }, + { + name: 'VTB', + cla: 0x9c, + slip0044: 0x800002b6, + ss58_addr_type: 42, + }, + { + name: 'Peer', + cla: 0x9d, + slip0044: 0x800002ce, + ss58_addr_type: 42, + }, + { + name: 'Genshiro', + cla: 0x9e, + slip0044: 0x85f5e0fc, + ss58_addr_type: 67, + }, + { + name: 'Sora', + cla: 0x9f, + slip0044: 0x80000269, + ss58_addr_type: 69, + }, + { + name: 'Polkadex', + cla: 0xa0, + slip0044: 0x8000031f, + ss58_addr_type: 88, + }, + { + name: 'Bifrost', + cla: 0xa1, + slip0044: 0x80000314, + ss58_addr_type: 6, + }, + { + name: 'Reef', + cla: 0xa2, + slip0044: 0x80000333, + ss58_addr_type: 42, + }, + { + name: 'XXNetwork', + cla: 0xa3, + slip0044: 0x800007a3, + ss58_addr_type: 55, + }, + { + name: 'AlephZero', + cla: 0xa4, + slip0044: 0x80000283, + ss58_addr_type: 42, + }, + { + name: 'Interlay', + cla: 0xa5, + slip0044: 0x80000162, + ss58_addr_type: 2032, + }, + { + name: 'Parallel', + cla: 0xa6, + slip0044: 0x80000162, + ss58_addr_type: 172, + }, + { + name: 'Picasso', + cla: 0xa7, + slip0044: 0x800001b2, + ss58_addr_type: 49, + }, + { + name: 'Composable', + cla: 0xa8, + slip0044: 0x80000162, + ss58_addr_type: 49, + }, + { + name: 'Astar', + cla: 0xa9, + slip0044: 0x8000032a, + ss58_addr_type: 5, + }, + { + name: 'OriginTrail', + cla: 0xaa, + slip0044: 0x80000162, + ss58_addr_type: 101, + }, + { + name: 'HydraDX', + cla: 0xab, + slip0044: 0x80000162, + ss58_addr_type: 63, + }, + { + name: 'Stafi', + cla: 0xac, + slip0044: 0x8000038b, + ss58_addr_type: 20, + }, + { + name: 'Unique', + cla: 0xad, + slip0044: 0x80000295, + ss58_addr_type: 7391, + }, + { + name: 'BifrostKusama', + cla: 0xae, + slip0044: 0x80000314, + ss58_addr_type: 6, + }, + { + name: 'Phala', + cla: 0xaf, + slip0044: 0x80000162, + ss58_addr_type: 30, + }, + { + name: 'Khala', + cla: 0xb1, + slip0044: 0x800001b2, + ss58_addr_type: 30, + }, + { + name: 'Darwinia', + cla: 0xb2, + slip0044: 0x80000162, + ss58_addr_type: 18, + }, + { + name: 'Ajuna', + cla: 0xb3, + slip0044: 0x80000162, + ss58_addr_type: 1328, + }, + { + name: 'Bittensor', + cla: 0xb4, + slip0044: 0x800003ed, + ss58_addr_type: 42, + }, + { + name: 'Ternoa', + cla: 0xb5, + slip0044: 0x800003e3, + ss58_addr_type: 42, + }, + { + name: 'Pendulum', + cla: 0xb6, + slip0044: 0x80000162, + ss58_addr_type: 56, + }, + { + name: 'Zeitgeist', + cla: 0xb7, + slip0044: 0x80000162, + ss58_addr_type: 73, + }, + { + name: 'Joystream', + cla: 0xb8, + slip0044: 0x80000219, + ss58_addr_type: 126, + }, + { + name: 'Enjin', + cla: 0xb9, + slip0044: 0x80000483, + ss58_addr_type: 2135, + }, + { + name: 'Matrixchain', + cla: 0xba, + slip0044: 0x80000483, + ss58_addr_type: 1110, + }, + { + name: 'Quartz', + cla: 0xbb, + slip0044: 0x80000277, + ss58_addr_type: 255, + }, + { + name: 'Avail', + cla: 0xbc, + slip0044: 0x800002c5, + ss58_addr_type: 42, + }, + { + name: 'Entropy', + cla: 0xbd, + slip0044: 0x80000520, + ss58_addr_type: 42, + }, + { + name: 'Peaq', + cla: 0x61, + slip0044: 0x8000003c, + ss58_addr_type: 42, + }, + { + name: 'AvailRecovery', + cla: 0xbe, + slip0044: 0x80000162, + ss58_addr_type: 42, + }, + ]; + } (supported_apps)); + getDefaultExportFromCjs(supported_apps); + + Object.defineProperty(legacy_apps, "__esModule", { value: true }); + legacy_apps.newKusamaApp = newKusamaApp; + legacy_apps.newPolkadotApp = newPolkadotApp; + legacy_apps.newPolymeshApp = newPolymeshApp; + legacy_apps.newDockApp = newDockApp; + legacy_apps.newCentrifugeApp = newCentrifugeApp; + legacy_apps.newEdgewareApp = newEdgewareApp; + legacy_apps.newEquilibriumApp = newEquilibriumApp; + legacy_apps.newGenshiroApp = newGenshiroApp; + legacy_apps.newStatemintApp = newStatemintApp; + legacy_apps.newStatemineApp = newStatemineApp; + legacy_apps.newNodleApp = newNodleApp; + legacy_apps.newSoraApp = newSoraApp; + legacy_apps.newPolkadexApp = newPolkadexApp; + legacy_apps.newBifrostApp = newBifrostApp; + legacy_apps.newKaruraApp = newKaruraApp; + legacy_apps.newReefApp = newReefApp; + legacy_apps.newAcalaApp = newAcalaApp; + legacy_apps.newXXNetworkApp = newXXNetworkApp; + legacy_apps.newParallelApp = newParallelApp; + legacy_apps.newAstarApp = newAstarApp; + legacy_apps.newComposableApp = newComposableApp; + legacy_apps.newStafiApp = newStafiApp; + legacy_apps.newAlephZeroApp = newAlephZeroApp; + legacy_apps.newInterlayApp = newInterlayApp; + legacy_apps.newUniqueApp = newUniqueApp; + legacy_apps.newBifrostKusamaApp = newBifrostKusamaApp; + const supported_apps_1 = supported_apps; + function newKusamaApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Kusama'); + } + function newPolkadotApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Polkadot'); + } + function newPolymeshApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Polymesh'); + } + function newDockApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Dock'); + } + function newCentrifugeApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Centrifuge'); + } + function newEdgewareApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Edgeware'); + } + function newEquilibriumApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Equilibrium'); + } + function newGenshiroApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Genshiro'); + } + function newStatemintApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Statemint'); + } + function newStatemineApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Statemine'); + } + function newNodleApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Nodle'); + } + function newSoraApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Sora'); + } + function newPolkadexApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Polkadex'); + } + function newBifrostApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Bifrost'); + } + function newKaruraApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Karura'); + } + function newReefApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Reef'); + } + function newAcalaApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Acala'); + } + function newXXNetworkApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'XXNetwork'); + } + function newParallelApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Parallel'); + } + function newAstarApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Astar'); + } + function newComposableApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Composable'); + } + function newStafiApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Stafi'); + } + function newAlephZeroApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'AlephZero'); + } + function newInterlayApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Interlay'); + } + function newUniqueApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'Unique'); + } + function newBifrostKusamaApp(transport) { + return (0, supported_apps_1.newSubstrateApp)(transport, 'BifrostKusama'); + } + + var generic_app = {}; + + /*! Axios v1.13.2 Copyright (c) 2025 Matt Zabriskie and contributors */ + + /** + * Create a bound version of a function with a specified `this` context + * + * @param {Function} fn - The function to bind + * @param {*} thisArg - The value to be passed as the `this` parameter + * @returns {Function} A new function that will call the original function with the specified `this` context + */ + function bind(fn, thisArg) { + return function wrap() { + return fn.apply(thisArg, arguments); + }; + } + + // utils is a library of generic helper functions non-specific to axios + + const {toString} = Object.prototype; + const {getPrototypeOf} = Object; + const {iterator, toStringTag} = Symbol; + + const kindOf = (cache => thing => { + const str = toString.call(thing); + return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase()); + })(Object.create(null)); + + const kindOfTest = (type) => { + type = type.toLowerCase(); + return (thing) => kindOf(thing) === type + }; + + const typeOfTest = type => thing => typeof thing === type; + + /** + * Determine if a value is an Array + * + * @param {Object} val The value to test + * + * @returns {boolean} True if value is an Array, otherwise false + */ + const {isArray} = Array; + + /** + * Determine if a value is undefined + * + * @param {*} val The value to test + * + * @returns {boolean} True if the value is undefined, otherwise false + */ + const isUndefined = typeOfTest('undefined'); + + /** + * Determine if a value is a Buffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Buffer, otherwise false + */ + function isBuffer(val) { + return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) + && isFunction$1(val.constructor.isBuffer) && val.constructor.isBuffer(val); + } + + /** + * Determine if a value is an ArrayBuffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is an ArrayBuffer, otherwise false + */ + const isArrayBuffer = kindOfTest('ArrayBuffer'); + + + /** + * Determine if a value is a view on an ArrayBuffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false + */ + function isArrayBufferView(val) { + let result; + if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) { + result = ArrayBuffer.isView(val); + } else { + result = (val) && (val.buffer) && (isArrayBuffer(val.buffer)); + } + return result; + } + + /** + * Determine if a value is a String + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a String, otherwise false + */ + const isString = typeOfTest('string'); + + /** + * Determine if a value is a Function + * + * @param {*} val The value to test + * @returns {boolean} True if value is a Function, otherwise false + */ + const isFunction$1 = typeOfTest('function'); + + /** + * Determine if a value is a Number + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Number, otherwise false + */ + const isNumber = typeOfTest('number'); + + /** + * Determine if a value is an Object + * + * @param {*} thing The value to test + * + * @returns {boolean} True if value is an Object, otherwise false + */ + const isObject$1 = (thing) => thing !== null && typeof thing === 'object'; + + /** + * Determine if a value is a Boolean + * + * @param {*} thing The value to test + * @returns {boolean} True if value is a Boolean, otherwise false + */ + const isBoolean = thing => thing === true || thing === false; + + /** + * Determine if a value is a plain Object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a plain Object, otherwise false + */ + const isPlainObject = (val) => { + if (kindOf(val) !== 'object') { + return false; + } + + const prototype = getPrototypeOf(val); + return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val); + }; + + /** + * Determine if a value is an empty object (safely handles Buffers) + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is an empty object, otherwise false + */ + const isEmptyObject = (val) => { + // Early return for non-objects or Buffers to prevent RangeError + if (!isObject$1(val) || isBuffer(val)) { + return false; + } + + try { + return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype; + } catch (e) { + // Fallback for any other objects that might cause RangeError with Object.keys() + return false; + } + }; + + /** + * Determine if a value is a Date + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Date, otherwise false + */ + const isDate = kindOfTest('Date'); + + /** + * Determine if a value is a File + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a File, otherwise false + */ + const isFile = kindOfTest('File'); + + /** + * Determine if a value is a Blob + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Blob, otherwise false + */ + const isBlob = kindOfTest('Blob'); + + /** + * Determine if a value is a FileList + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a File, otherwise false + */ + const isFileList = kindOfTest('FileList'); + + /** + * Determine if a value is a Stream + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Stream, otherwise false + */ + const isStream = (val) => isObject$1(val) && isFunction$1(val.pipe); + + /** + * Determine if a value is a FormData + * + * @param {*} thing The value to test + * + * @returns {boolean} True if value is an FormData, otherwise false + */ + const isFormData = (thing) => { + let kind; + return thing && ( + (typeof FormData === 'function' && thing instanceof FormData) || ( + isFunction$1(thing.append) && ( + (kind = kindOf(thing)) === 'formdata' || + // detect form-data instance + (kind === 'object' && isFunction$1(thing.toString) && thing.toString() === '[object FormData]') + ) + ) + ) + }; + + /** + * Determine if a value is a URLSearchParams object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a URLSearchParams object, otherwise false + */ + const isURLSearchParams = kindOfTest('URLSearchParams'); + + const [isReadableStream, isRequest, isResponse, isHeaders] = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest); + + /** + * Trim excess whitespace off the beginning and end of a string + * + * @param {String} str The String to trim + * + * @returns {String} The String freed of excess whitespace + */ + const trim = (str) => str.trim ? + str.trim() : str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + + /** + * Iterate over an Array or an Object invoking a function for each item. + * + * If `obj` is an Array callback will be called passing + * the value, index, and complete array for each item. + * + * If 'obj' is an Object callback will be called passing + * the value, key, and complete object for each property. + * + * @param {Object|Array} obj The object to iterate + * @param {Function} fn The callback to invoke for each item + * + * @param {Boolean} [allOwnKeys = false] + * @returns {any} + */ + function forEach(obj, fn, {allOwnKeys = false} = {}) { + // Don't bother if no value provided + if (obj === null || typeof obj === 'undefined') { + return; + } + + let i; + let l; + + // Force an array if not already something iterable + if (typeof obj !== 'object') { + /*eslint no-param-reassign:0*/ + obj = [obj]; + } + + if (isArray(obj)) { + // Iterate over array values + for (i = 0, l = obj.length; i < l; i++) { + fn.call(null, obj[i], i, obj); + } + } else { + // Buffer check + if (isBuffer(obj)) { + return; + } + + // Iterate over object keys + const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj); + const len = keys.length; + let key; + + for (i = 0; i < len; i++) { + key = keys[i]; + fn.call(null, obj[key], key, obj); + } + } + } + + function findKey(obj, key) { + if (isBuffer(obj)){ + return null; + } + + key = key.toLowerCase(); + const keys = Object.keys(obj); + let i = keys.length; + let _key; + while (i-- > 0) { + _key = keys[i]; + if (key === _key.toLowerCase()) { + return _key; + } + } + return null; + } + + const _global = (() => { + /*eslint no-undef:0*/ + if (typeof globalThis !== "undefined") return globalThis; + return typeof self !== "undefined" ? self : (typeof window !== 'undefined' ? window : commonjsGlobal) + })(); + + const isContextDefined = (context) => !isUndefined(context) && context !== _global; + + /** + * Accepts varargs expecting each argument to be an object, then + * immutably merges the properties of each object and returns result. + * + * When multiple objects contain the same key the later object in + * the arguments list will take precedence. + * + * Example: + * + * ```js + * var result = merge({foo: 123}, {foo: 456}); + * console.log(result.foo); // outputs 456 + * ``` + * + * @param {Object} obj1 Object to merge + * + * @returns {Object} Result of all merge properties + */ + function merge(/* obj1, obj2, obj3, ... */) { + const {caseless, skipUndefined} = isContextDefined(this) && this || {}; + const result = {}; + const assignValue = (val, key) => { + const targetKey = caseless && findKey(result, key) || key; + if (isPlainObject(result[targetKey]) && isPlainObject(val)) { + result[targetKey] = merge(result[targetKey], val); + } else if (isPlainObject(val)) { + result[targetKey] = merge({}, val); + } else if (isArray(val)) { + result[targetKey] = val.slice(); + } else if (!skipUndefined || !isUndefined(val)) { + result[targetKey] = val; + } + }; + + for (let i = 0, l = arguments.length; i < l; i++) { + arguments[i] && forEach(arguments[i], assignValue); + } + return result; + } + + /** + * Extends object a by mutably adding to it the properties of object b. + * + * @param {Object} a The object to be extended + * @param {Object} b The object to copy properties from + * @param {Object} thisArg The object to bind function to + * + * @param {Boolean} [allOwnKeys] + * @returns {Object} The resulting value of object a + */ + const extend = (a, b, thisArg, {allOwnKeys}= {}) => { + forEach(b, (val, key) => { + if (thisArg && isFunction$1(val)) { + a[key] = bind(val, thisArg); + } else { + a[key] = val; + } + }, {allOwnKeys}); + return a; + }; + + /** + * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) + * + * @param {string} content with BOM + * + * @returns {string} content value without BOM + */ + const stripBOM = (content) => { + if (content.charCodeAt(0) === 0xFEFF) { + content = content.slice(1); + } + return content; + }; + + /** + * Inherit the prototype methods from one constructor into another + * @param {function} constructor + * @param {function} superConstructor + * @param {object} [props] + * @param {object} [descriptors] + * + * @returns {void} + */ + const inherits = (constructor, superConstructor, props, descriptors) => { + constructor.prototype = Object.create(superConstructor.prototype, descriptors); + constructor.prototype.constructor = constructor; + Object.defineProperty(constructor, 'super', { + value: superConstructor.prototype + }); + props && Object.assign(constructor.prototype, props); + }; + + /** + * Resolve object with deep prototype chain to a flat object + * @param {Object} sourceObj source object + * @param {Object} [destObj] + * @param {Function|Boolean} [filter] + * @param {Function} [propFilter] + * + * @returns {Object} + */ + const toFlatObject = (sourceObj, destObj, filter, propFilter) => { + let props; + let i; + let prop; + const merged = {}; + + destObj = destObj || {}; + // eslint-disable-next-line no-eq-null,eqeqeq + if (sourceObj == null) return destObj; + + do { + props = Object.getOwnPropertyNames(sourceObj); + i = props.length; + while (i-- > 0) { + prop = props[i]; + if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) { + destObj[prop] = sourceObj[prop]; + merged[prop] = true; + } + } + sourceObj = filter !== false && getPrototypeOf(sourceObj); + } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype); + + return destObj; + }; + + /** + * Determines whether a string ends with the characters of a specified string + * + * @param {String} str + * @param {String} searchString + * @param {Number} [position= 0] + * + * @returns {boolean} + */ + const endsWith = (str, searchString, position) => { + str = String(str); + if (position === undefined || position > str.length) { + position = str.length; + } + position -= searchString.length; + const lastIndex = str.indexOf(searchString, position); + return lastIndex !== -1 && lastIndex === position; + }; + + + /** + * Returns new array from array like object or null if failed + * + * @param {*} [thing] + * + * @returns {?Array} + */ + const toArray = (thing) => { + if (!thing) return null; + if (isArray(thing)) return thing; + let i = thing.length; + if (!isNumber(i)) return null; + const arr = new Array(i); + while (i-- > 0) { + arr[i] = thing[i]; + } + return arr; + }; + + /** + * Checking if the Uint8Array exists and if it does, it returns a function that checks if the + * thing passed in is an instance of Uint8Array + * + * @param {TypedArray} + * + * @returns {Array} + */ + // eslint-disable-next-line func-names + const isTypedArray = (TypedArray => { + // eslint-disable-next-line func-names + return thing => { + return TypedArray && thing instanceof TypedArray; + }; + })(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array)); + + /** + * For each entry in the object, call the function with the key and value. + * + * @param {Object} obj - The object to iterate over. + * @param {Function} fn - The function to call for each entry. + * + * @returns {void} + */ + const forEachEntry = (obj, fn) => { + const generator = obj && obj[iterator]; + + const _iterator = generator.call(obj); + + let result; + + while ((result = _iterator.next()) && !result.done) { + const pair = result.value; + fn.call(obj, pair[0], pair[1]); + } + }; + + /** + * It takes a regular expression and a string, and returns an array of all the matches + * + * @param {string} regExp - The regular expression to match against. + * @param {string} str - The string to search. + * + * @returns {Array} + */ + const matchAll = (regExp, str) => { + let matches; + const arr = []; + + while ((matches = regExp.exec(str)) !== null) { + arr.push(matches); + } + + return arr; + }; + + /* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */ + const isHTMLForm = kindOfTest('HTMLFormElement'); + + const toCamelCase = str => { + return str.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g, + function replacer(m, p1, p2) { + return p1.toUpperCase() + p2; + } + ); + }; + + /* Creating a function that will check if an object has a property. */ + const hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype); + + /** + * Determine if a value is a RegExp object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a RegExp object, otherwise false + */ + const isRegExp = kindOfTest('RegExp'); + + const reduceDescriptors = (obj, reducer) => { + const descriptors = Object.getOwnPropertyDescriptors(obj); + const reducedDescriptors = {}; + + forEach(descriptors, (descriptor, name) => { + let ret; + if ((ret = reducer(descriptor, name, obj)) !== false) { + reducedDescriptors[name] = ret || descriptor; + } + }); + + Object.defineProperties(obj, reducedDescriptors); + }; + + /** + * Makes all methods read-only + * @param {Object} obj + */ + + const freezeMethods = (obj) => { + reduceDescriptors(obj, (descriptor, name) => { + // skip restricted props in strict mode + if (isFunction$1(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) { + return false; + } + + const value = obj[name]; + + if (!isFunction$1(value)) return; + + descriptor.enumerable = false; + + if ('writable' in descriptor) { + descriptor.writable = false; + return; + } + + if (!descriptor.set) { + descriptor.set = () => { + throw Error('Can not rewrite read-only method \'' + name + '\''); + }; + } + }); + }; + + const toObjectSet = (arrayOrString, delimiter) => { + const obj = {}; + + const define = (arr) => { + arr.forEach(value => { + obj[value] = true; + }); + }; + + isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter)); + + return obj; + }; + + const noop = () => {}; + + const toFiniteNumber = (value, defaultValue) => { + return value != null && Number.isFinite(value = +value) ? value : defaultValue; + }; + + + + /** + * If the thing is a FormData object, return true, otherwise return false. + * + * @param {unknown} thing - The thing to check. + * + * @returns {boolean} + */ + function isSpecCompliantForm(thing) { + return !!(thing && isFunction$1(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]); + } + + const toJSONObject = (obj) => { + const stack = new Array(10); + + const visit = (source, i) => { + + if (isObject$1(source)) { + if (stack.indexOf(source) >= 0) { + return; + } + + //Buffer check + if (isBuffer(source)) { + return source; + } + + if(!('toJSON' in source)) { + stack[i] = source; + const target = isArray(source) ? [] : {}; + + forEach(source, (value, key) => { + const reducedValue = visit(value, i + 1); + !isUndefined(reducedValue) && (target[key] = reducedValue); + }); + + stack[i] = undefined; + + return target; + } + } + + return source; + }; + + return visit(obj, 0); + }; + + const isAsyncFn = kindOfTest('AsyncFunction'); + + const isThenable = (thing) => + thing && (isObject$1(thing) || isFunction$1(thing)) && isFunction$1(thing.then) && isFunction$1(thing.catch); + + // original code + // https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34 + + const _setImmediate = ((setImmediateSupported, postMessageSupported) => { + if (setImmediateSupported) { + return setImmediate; + } + + return postMessageSupported ? ((token, callbacks) => { + _global.addEventListener("message", ({source, data}) => { + if (source === _global && data === token) { + callbacks.length && callbacks.shift()(); + } + }, false); + + return (cb) => { + callbacks.push(cb); + _global.postMessage(token, "*"); + } + })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb); + })( + typeof setImmediate === 'function', + isFunction$1(_global.postMessage) + ); + + const asap = typeof queueMicrotask !== 'undefined' ? + queueMicrotask.bind(_global) : ( typeof process !== 'undefined' && process.nextTick || _setImmediate); + + // ********************* + + + const isIterable = (thing) => thing != null && isFunction$1(thing[iterator]); + + + var utils$1 = { + isArray, + isArrayBuffer, + isBuffer, + isFormData, + isArrayBufferView, + isString, + isNumber, + isBoolean, + isObject: isObject$1, + isPlainObject, + isEmptyObject, + isReadableStream, + isRequest, + isResponse, + isHeaders, + isUndefined, + isDate, + isFile, + isBlob, + isRegExp, + isFunction: isFunction$1, + isStream, + isURLSearchParams, + isTypedArray, + isFileList, + forEach, + merge, + extend, + trim, + stripBOM, + inherits, + toFlatObject, + kindOf, + kindOfTest, + endsWith, + toArray, + forEachEntry, + matchAll, + isHTMLForm, + hasOwnProperty, + hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection + reduceDescriptors, + freezeMethods, + toObjectSet, + toCamelCase, + noop, + toFiniteNumber, + findKey, + global: _global, + isContextDefined, + isSpecCompliantForm, + toJSONObject, + isAsyncFn, + isThenable, + setImmediate: _setImmediate, + asap, + isIterable + }; + + /** + * Create an Error with the specified message, config, error code, request and response. + * + * @param {string} message The error message. + * @param {string} [code] The error code (for example, 'ECONNABORTED'). + * @param {Object} [config] The config. + * @param {Object} [request] The request. + * @param {Object} [response] The response. + * + * @returns {Error} The created error. + */ + function AxiosError(message, code, config, request, response) { + Error.call(this); + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } else { + this.stack = (new Error()).stack; + } + + this.message = message; + this.name = 'AxiosError'; + code && (this.code = code); + config && (this.config = config); + request && (this.request = request); + if (response) { + this.response = response; + this.status = response.status ? response.status : null; + } + } + + utils$1.inherits(AxiosError, Error, { + toJSON: function toJSON() { + return { + // Standard + message: this.message, + name: this.name, + // Microsoft + description: this.description, + number: this.number, + // Mozilla + fileName: this.fileName, + lineNumber: this.lineNumber, + columnNumber: this.columnNumber, + stack: this.stack, + // Axios + config: utils$1.toJSONObject(this.config), + code: this.code, + status: this.status + }; + } + }); + + const prototype$1 = AxiosError.prototype; + const descriptors = {}; + + [ + 'ERR_BAD_OPTION_VALUE', + 'ERR_BAD_OPTION', + 'ECONNABORTED', + 'ETIMEDOUT', + 'ERR_NETWORK', + 'ERR_FR_TOO_MANY_REDIRECTS', + 'ERR_DEPRECATED', + 'ERR_BAD_RESPONSE', + 'ERR_BAD_REQUEST', + 'ERR_CANCELED', + 'ERR_NOT_SUPPORT', + 'ERR_INVALID_URL' + // eslint-disable-next-line func-names + ].forEach(code => { + descriptors[code] = {value: code}; + }); + + Object.defineProperties(AxiosError, descriptors); + Object.defineProperty(prototype$1, 'isAxiosError', {value: true}); + + // eslint-disable-next-line func-names + AxiosError.from = (error, code, config, request, response, customProps) => { + const axiosError = Object.create(prototype$1); + + utils$1.toFlatObject(error, axiosError, function filter(obj) { + return obj !== Error.prototype; + }, prop => { + return prop !== 'isAxiosError'; + }); + + const msg = error && error.message ? error.message : 'Error'; + + // Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED) + const errCode = code == null && error ? error.code : code; + AxiosError.call(axiosError, msg, errCode, config, request, response); + + // Chain the original error on the standard field; non-enumerable to avoid JSON noise + if (error && axiosError.cause == null) { + Object.defineProperty(axiosError, 'cause', { value: error, configurable: true }); + } + + axiosError.name = (error && error.name) || 'Error'; + + customProps && Object.assign(axiosError, customProps); + + return axiosError; + }; + + // eslint-disable-next-line strict + var httpAdapter = null; + + /** + * Determines if the given thing is a array or js object. + * + * @param {string} thing - The object or array to be visited. + * + * @returns {boolean} + */ + function isVisitable(thing) { + return utils$1.isPlainObject(thing) || utils$1.isArray(thing); + } + + /** + * It removes the brackets from the end of a string + * + * @param {string} key - The key of the parameter. + * + * @returns {string} the key without the brackets. + */ + function removeBrackets(key) { + return utils$1.endsWith(key, '[]') ? key.slice(0, -2) : key; + } + + /** + * It takes a path, a key, and a boolean, and returns a string + * + * @param {string} path - The path to the current key. + * @param {string} key - The key of the current object being iterated over. + * @param {string} dots - If true, the key will be rendered with dots instead of brackets. + * + * @returns {string} The path to the current key. + */ + function renderKey(path, key, dots) { + if (!path) return key; + return path.concat(key).map(function each(token, i) { + // eslint-disable-next-line no-param-reassign + token = removeBrackets(token); + return !dots && i ? '[' + token + ']' : token; + }).join(dots ? '.' : ''); + } + + /** + * If the array is an array and none of its elements are visitable, then it's a flat array. + * + * @param {Array} arr - The array to check + * + * @returns {boolean} + */ + function isFlatArray(arr) { + return utils$1.isArray(arr) && !arr.some(isVisitable); + } + + const predicates = utils$1.toFlatObject(utils$1, {}, null, function filter(prop) { + return /^is[A-Z]/.test(prop); + }); + + /** + * Convert a data object to FormData + * + * @param {Object} obj + * @param {?Object} [formData] + * @param {?Object} [options] + * @param {Function} [options.visitor] + * @param {Boolean} [options.metaTokens = true] + * @param {Boolean} [options.dots = false] + * @param {?Boolean} [options.indexes = false] + * + * @returns {Object} + **/ + + /** + * It converts an object into a FormData object + * + * @param {Object} obj - The object to convert to form data. + * @param {string} formData - The FormData object to append to. + * @param {Object} options + * + * @returns + */ + function toFormData(obj, formData, options) { + if (!utils$1.isObject(obj)) { + throw new TypeError('target must be an object'); + } + + // eslint-disable-next-line no-param-reassign + formData = formData || new (FormData)(); + + // eslint-disable-next-line no-param-reassign + options = utils$1.toFlatObject(options, { + metaTokens: true, + dots: false, + indexes: false + }, false, function defined(option, source) { + // eslint-disable-next-line no-eq-null,eqeqeq + return !utils$1.isUndefined(source[option]); + }); + + const metaTokens = options.metaTokens; + // eslint-disable-next-line no-use-before-define + const visitor = options.visitor || defaultVisitor; + const dots = options.dots; + const indexes = options.indexes; + const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob; + const useBlob = _Blob && utils$1.isSpecCompliantForm(formData); + + if (!utils$1.isFunction(visitor)) { + throw new TypeError('visitor must be a function'); + } + + function convertValue(value) { + if (value === null) return ''; + + if (utils$1.isDate(value)) { + return value.toISOString(); + } + + if (utils$1.isBoolean(value)) { + return value.toString(); + } + + if (!useBlob && utils$1.isBlob(value)) { + throw new AxiosError('Blob is not supported. Use a Buffer instead.'); + } + + if (utils$1.isArrayBuffer(value) || utils$1.isTypedArray(value)) { + return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value); + } + + return value; + } + + /** + * Default visitor. + * + * @param {*} value + * @param {String|Number} key + * @param {Array} path + * @this {FormData} + * + * @returns {boolean} return true to visit the each prop of the value recursively + */ + function defaultVisitor(value, key, path) { + let arr = value; + + if (value && !path && typeof value === 'object') { + if (utils$1.endsWith(key, '{}')) { + // eslint-disable-next-line no-param-reassign + key = metaTokens ? key : key.slice(0, -2); + // eslint-disable-next-line no-param-reassign + value = JSON.stringify(value); + } else if ( + (utils$1.isArray(value) && isFlatArray(value)) || + ((utils$1.isFileList(value) || utils$1.endsWith(key, '[]')) && (arr = utils$1.toArray(value)) + )) { + // eslint-disable-next-line no-param-reassign + key = removeBrackets(key); + + arr.forEach(function each(el, index) { + !(utils$1.isUndefined(el) || el === null) && formData.append( + // eslint-disable-next-line no-nested-ternary + indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'), + convertValue(el) + ); + }); + return false; + } + } + + if (isVisitable(value)) { + return true; + } + + formData.append(renderKey(path, key, dots), convertValue(value)); + + return false; + } + + const stack = []; + + const exposedHelpers = Object.assign(predicates, { + defaultVisitor, + convertValue, + isVisitable + }); + + function build(value, path) { + if (utils$1.isUndefined(value)) return; + + if (stack.indexOf(value) !== -1) { + throw Error('Circular reference detected in ' + path.join('.')); + } + + stack.push(value); + + utils$1.forEach(value, function each(el, key) { + const result = !(utils$1.isUndefined(el) || el === null) && visitor.call( + formData, el, utils$1.isString(key) ? key.trim() : key, path, exposedHelpers + ); + + if (result === true) { + build(el, path ? path.concat(key) : [key]); + } + }); + + stack.pop(); + } + + if (!utils$1.isObject(obj)) { + throw new TypeError('data must be an object'); + } + + build(obj); + + return formData; + } + + /** + * It encodes a string by replacing all characters that are not in the unreserved set with + * their percent-encoded equivalents + * + * @param {string} str - The string to encode. + * + * @returns {string} The encoded string. + */ + function encode$1(str) { + const charMap = { + '!': '%21', + "'": '%27', + '(': '%28', + ')': '%29', + '~': '%7E', + '%20': '+', + '%00': '\x00' + }; + return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) { + return charMap[match]; + }); + } + + /** + * It takes a params object and converts it to a FormData object + * + * @param {Object} params - The parameters to be converted to a FormData object. + * @param {Object} options - The options object passed to the Axios constructor. + * + * @returns {void} + */ + function AxiosURLSearchParams(params, options) { + this._pairs = []; + + params && toFormData(params, this, options); + } + + const prototype = AxiosURLSearchParams.prototype; + + prototype.append = function append(name, value) { + this._pairs.push([name, value]); + }; + + prototype.toString = function toString(encoder) { + const _encode = encoder ? function(value) { + return encoder.call(this, value, encode$1); + } : encode$1; + + return this._pairs.map(function each(pair) { + return _encode(pair[0]) + '=' + _encode(pair[1]); + }, '').join('&'); + }; + + /** + * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their + * URI encoded counterparts + * + * @param {string} val The value to be encoded. + * + * @returns {string} The encoded value. + */ + function encode(val) { + return encodeURIComponent(val). + replace(/%3A/gi, ':'). + replace(/%24/g, '$'). + replace(/%2C/gi, ','). + replace(/%20/g, '+'); + } + + /** + * Build a URL by appending params to the end + * + * @param {string} url The base of the url (e.g., http://www.google.com) + * @param {object} [params] The params to be appended + * @param {?(object|Function)} options + * + * @returns {string} The formatted url + */ + function buildURL(url, params, options) { + /*eslint no-param-reassign:0*/ + if (!params) { + return url; + } + + const _encode = options && options.encode || encode; + + if (utils$1.isFunction(options)) { + options = { + serialize: options + }; + } + + const serializeFn = options && options.serialize; + + let serializedParams; + + if (serializeFn) { + serializedParams = serializeFn(params, options); + } else { + serializedParams = utils$1.isURLSearchParams(params) ? + params.toString() : + new AxiosURLSearchParams(params, options).toString(_encode); + } + + if (serializedParams) { + const hashmarkIndex = url.indexOf("#"); + + if (hashmarkIndex !== -1) { + url = url.slice(0, hashmarkIndex); + } + url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams; + } + + return url; + } + + class InterceptorManager { + constructor() { + this.handlers = []; + } + + /** + * Add a new interceptor to the stack + * + * @param {Function} fulfilled The function to handle `then` for a `Promise` + * @param {Function} rejected The function to handle `reject` for a `Promise` + * + * @return {Number} An ID used to remove interceptor later + */ + use(fulfilled, rejected, options) { + this.handlers.push({ + fulfilled, + rejected, + synchronous: options ? options.synchronous : false, + runWhen: options ? options.runWhen : null + }); + return this.handlers.length - 1; + } + + /** + * Remove an interceptor from the stack + * + * @param {Number} id The ID that was returned by `use` + * + * @returns {void} + */ + eject(id) { + if (this.handlers[id]) { + this.handlers[id] = null; + } + } + + /** + * Clear all interceptors from the stack + * + * @returns {void} + */ + clear() { + if (this.handlers) { + this.handlers = []; + } + } + + /** + * Iterate over all the registered interceptors + * + * This method is particularly useful for skipping over any + * interceptors that may have become `null` calling `eject`. + * + * @param {Function} fn The function to call for each interceptor + * + * @returns {void} + */ + forEach(fn) { + utils$1.forEach(this.handlers, function forEachHandler(h) { + if (h !== null) { + fn(h); + } + }); + } + } + + var InterceptorManager$1 = InterceptorManager; + + var transitionalDefaults = { + silentJSONParsing: true, + forcedJSONParsing: true, + clarifyTimeoutError: false + }; + + var URLSearchParams$1 = typeof URLSearchParams !== 'undefined' ? URLSearchParams : AxiosURLSearchParams; + + var FormData$1 = typeof FormData !== 'undefined' ? FormData : null; + + var Blob$1 = typeof Blob !== 'undefined' ? Blob : null; + + var platform$1 = { + isBrowser: true, + classes: { + URLSearchParams: URLSearchParams$1, + FormData: FormData$1, + Blob: Blob$1 + }, + protocols: ['http', 'https', 'file', 'blob', 'url', 'data'] + }; + + const hasBrowserEnv = typeof window !== 'undefined' && typeof document !== 'undefined'; + + const _navigator = typeof navigator === 'object' && navigator || undefined; + + /** + * Determine if we're running in a standard browser environment + * + * This allows axios to run in a web worker, and react-native. + * Both environments support XMLHttpRequest, but not fully standard globals. + * + * web workers: + * typeof window -> undefined + * typeof document -> undefined + * + * react-native: + * navigator.product -> 'ReactNative' + * nativescript + * navigator.product -> 'NativeScript' or 'NS' + * + * @returns {boolean} + */ + const hasStandardBrowserEnv = hasBrowserEnv && + (!_navigator || ['ReactNative', 'NativeScript', 'NS'].indexOf(_navigator.product) < 0); + + /** + * Determine if we're running in a standard browser webWorker environment + * + * Although the `isStandardBrowserEnv` method indicates that + * `allows axios to run in a web worker`, the WebWorker will still be + * filtered out due to its judgment standard + * `typeof window !== 'undefined' && typeof document !== 'undefined'`. + * This leads to a problem when axios post `FormData` in webWorker + */ + const hasStandardBrowserWebWorkerEnv = (() => { + return ( + typeof WorkerGlobalScope !== 'undefined' && + // eslint-disable-next-line no-undef + self instanceof WorkerGlobalScope && + typeof self.importScripts === 'function' + ); + })(); + + const origin = hasBrowserEnv && window.location.href || 'http://localhost'; + + var utils = /*#__PURE__*/Object.freeze({ + __proto__: null, + hasBrowserEnv: hasBrowserEnv, + hasStandardBrowserWebWorkerEnv: hasStandardBrowserWebWorkerEnv, + hasStandardBrowserEnv: hasStandardBrowserEnv, + navigator: _navigator, + origin: origin + }); + + var platform = { + ...utils, + ...platform$1 + }; + + function toURLEncodedForm(data, options) { + return toFormData(data, new platform.classes.URLSearchParams(), { + visitor: function(value, key, path, helpers) { + if (platform.isNode && utils$1.isBuffer(value)) { + this.append(key, value.toString('base64')); + return false; + } + + return helpers.defaultVisitor.apply(this, arguments); + }, + ...options + }); + } + + /** + * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z'] + * + * @param {string} name - The name of the property to get. + * + * @returns An array of strings. + */ + function parsePropPath(name) { + // foo[x][y][z] + // foo.x.y.z + // foo-x-y-z + // foo x y z + return utils$1.matchAll(/\w+|\[(\w*)]/g, name).map(match => { + return match[0] === '[]' ? '' : match[1] || match[0]; + }); + } + + /** + * Convert an array to an object. + * + * @param {Array} arr - The array to convert to an object. + * + * @returns An object with the same keys and values as the array. + */ + function arrayToObject(arr) { + const obj = {}; + const keys = Object.keys(arr); + let i; + const len = keys.length; + let key; + for (i = 0; i < len; i++) { + key = keys[i]; + obj[key] = arr[key]; + } + return obj; + } + + /** + * It takes a FormData object and returns a JavaScript object + * + * @param {string} formData The FormData object to convert to JSON. + * + * @returns {Object | null} The converted object. + */ + function formDataToJSON(formData) { + function buildPath(path, value, target, index) { + let name = path[index++]; + + if (name === '__proto__') return true; + + const isNumericKey = Number.isFinite(+name); + const isLast = index >= path.length; + name = !name && utils$1.isArray(target) ? target.length : name; + + if (isLast) { + if (utils$1.hasOwnProp(target, name)) { + target[name] = [target[name], value]; + } else { + target[name] = value; + } + + return !isNumericKey; + } + + if (!target[name] || !utils$1.isObject(target[name])) { + target[name] = []; + } + + const result = buildPath(path, value, target[name], index); + + if (result && utils$1.isArray(target[name])) { + target[name] = arrayToObject(target[name]); + } + + return !isNumericKey; + } + + if (utils$1.isFormData(formData) && utils$1.isFunction(formData.entries)) { + const obj = {}; + + utils$1.forEachEntry(formData, (name, value) => { + buildPath(parsePropPath(name), value, obj, 0); + }); + + return obj; + } + + return null; + } + + /** + * It takes a string, tries to parse it, and if it fails, it returns the stringified version + * of the input + * + * @param {any} rawValue - The value to be stringified. + * @param {Function} parser - A function that parses a string into a JavaScript object. + * @param {Function} encoder - A function that takes a value and returns a string. + * + * @returns {string} A stringified version of the rawValue. + */ + function stringifySafely(rawValue, parser, encoder) { + if (utils$1.isString(rawValue)) { + try { + (parser || JSON.parse)(rawValue); + return utils$1.trim(rawValue); + } catch (e) { + if (e.name !== 'SyntaxError') { + throw e; + } + } + } + + return (encoder || JSON.stringify)(rawValue); + } + + const defaults = { + + transitional: transitionalDefaults, + + adapter: ['xhr', 'http', 'fetch'], + + transformRequest: [function transformRequest(data, headers) { + const contentType = headers.getContentType() || ''; + const hasJSONContentType = contentType.indexOf('application/json') > -1; + const isObjectPayload = utils$1.isObject(data); + + if (isObjectPayload && utils$1.isHTMLForm(data)) { + data = new FormData(data); + } + + const isFormData = utils$1.isFormData(data); + + if (isFormData) { + return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data; + } + + if (utils$1.isArrayBuffer(data) || + utils$1.isBuffer(data) || + utils$1.isStream(data) || + utils$1.isFile(data) || + utils$1.isBlob(data) || + utils$1.isReadableStream(data) + ) { + return data; + } + if (utils$1.isArrayBufferView(data)) { + return data.buffer; + } + if (utils$1.isURLSearchParams(data)) { + headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false); + return data.toString(); + } + + let isFileList; + + if (isObjectPayload) { + if (contentType.indexOf('application/x-www-form-urlencoded') > -1) { + return toURLEncodedForm(data, this.formSerializer).toString(); + } + + if ((isFileList = utils$1.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) { + const _FormData = this.env && this.env.FormData; + + return toFormData( + isFileList ? {'files[]': data} : data, + _FormData && new _FormData(), + this.formSerializer + ); + } + } + + if (isObjectPayload || hasJSONContentType ) { + headers.setContentType('application/json', false); + return stringifySafely(data); + } + + return data; + }], + + transformResponse: [function transformResponse(data) { + const transitional = this.transitional || defaults.transitional; + const forcedJSONParsing = transitional && transitional.forcedJSONParsing; + const JSONRequested = this.responseType === 'json'; + + if (utils$1.isResponse(data) || utils$1.isReadableStream(data)) { + return data; + } + + if (data && utils$1.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) { + const silentJSONParsing = transitional && transitional.silentJSONParsing; + const strictJSONParsing = !silentJSONParsing && JSONRequested; + + try { + return JSON.parse(data, this.parseReviver); + } catch (e) { + if (strictJSONParsing) { + if (e.name === 'SyntaxError') { + throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response); + } + throw e; + } + } + } + + return data; + }], + + /** + * A timeout in milliseconds to abort a request. If set to 0 (default) a + * timeout is not created. + */ + timeout: 0, + + xsrfCookieName: 'XSRF-TOKEN', + xsrfHeaderName: 'X-XSRF-TOKEN', + + maxContentLength: -1, + maxBodyLength: -1, + + env: { + FormData: platform.classes.FormData, + Blob: platform.classes.Blob + }, + + validateStatus: function validateStatus(status) { + return status >= 200 && status < 300; + }, + + headers: { + common: { + 'Accept': 'application/json, text/plain, */*', + 'Content-Type': undefined + } + } + }; + + utils$1.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => { + defaults.headers[method] = {}; + }); + + var defaults$1 = defaults; + + // RawAxiosHeaders whose duplicates are ignored by node + // c.f. https://nodejs.org/api/http.html#http_message_headers + const ignoreDuplicateOf = utils$1.toObjectSet([ + 'age', 'authorization', 'content-length', 'content-type', 'etag', + 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since', + 'last-modified', 'location', 'max-forwards', 'proxy-authorization', + 'referer', 'retry-after', 'user-agent' + ]); + + /** + * Parse headers into an object + * + * ``` + * Date: Wed, 27 Aug 2014 08:58:49 GMT + * Content-Type: application/json + * Connection: keep-alive + * Transfer-Encoding: chunked + * ``` + * + * @param {String} rawHeaders Headers needing to be parsed + * + * @returns {Object} Headers parsed into an object + */ + var parseHeaders = rawHeaders => { + const parsed = {}; + let key; + let val; + let i; + + rawHeaders && rawHeaders.split('\n').forEach(function parser(line) { + i = line.indexOf(':'); + key = line.substring(0, i).trim().toLowerCase(); + val = line.substring(i + 1).trim(); + + if (!key || (parsed[key] && ignoreDuplicateOf[key])) { + return; + } + + if (key === 'set-cookie') { + if (parsed[key]) { + parsed[key].push(val); + } else { + parsed[key] = [val]; + } + } else { + parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; + } + }); + + return parsed; + }; + + const $internals = Symbol('internals'); + + function normalizeHeader(header) { + return header && String(header).trim().toLowerCase(); + } + + function normalizeValue(value) { + if (value === false || value == null) { + return value; + } + + return utils$1.isArray(value) ? value.map(normalizeValue) : String(value); + } + + function parseTokens(str) { + const tokens = Object.create(null); + const tokensRE = /([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g; + let match; + + while ((match = tokensRE.exec(str))) { + tokens[match[1]] = match[2]; + } + + return tokens; + } + + const isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim()); + + function matchHeaderValue(context, value, header, filter, isHeaderNameFilter) { + if (utils$1.isFunction(filter)) { + return filter.call(this, value, header); + } + + if (isHeaderNameFilter) { + value = header; + } + + if (!utils$1.isString(value)) return; + + if (utils$1.isString(filter)) { + return value.indexOf(filter) !== -1; + } + + if (utils$1.isRegExp(filter)) { + return filter.test(value); + } + } + + function formatHeader(header) { + return header.trim() + .toLowerCase().replace(/([a-z\d])(\w*)/g, (w, char, str) => { + return char.toUpperCase() + str; + }); + } + + function buildAccessors(obj, header) { + const accessorName = utils$1.toCamelCase(' ' + header); + + ['get', 'set', 'has'].forEach(methodName => { + Object.defineProperty(obj, methodName + accessorName, { + value: function(arg1, arg2, arg3) { + return this[methodName].call(this, header, arg1, arg2, arg3); + }, + configurable: true + }); + }); + } + + class AxiosHeaders { + constructor(headers) { + headers && this.set(headers); + } + + set(header, valueOrRewrite, rewrite) { + const self = this; + + function setHeader(_value, _header, _rewrite) { + const lHeader = normalizeHeader(_header); + + if (!lHeader) { + throw new Error('header name must be a non-empty string'); + } + + const key = utils$1.findKey(self, lHeader); + + if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) { + self[key || _header] = normalizeValue(_value); + } + } + + const setHeaders = (headers, _rewrite) => + utils$1.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite)); + + if (utils$1.isPlainObject(header) || header instanceof this.constructor) { + setHeaders(header, valueOrRewrite); + } else if(utils$1.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) { + setHeaders(parseHeaders(header), valueOrRewrite); + } else if (utils$1.isObject(header) && utils$1.isIterable(header)) { + let obj = {}, dest, key; + for (const entry of header) { + if (!utils$1.isArray(entry)) { + throw TypeError('Object iterator must return a key-value pair'); + } + + obj[key = entry[0]] = (dest = obj[key]) ? + (utils$1.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]]) : entry[1]; + } + + setHeaders(obj, valueOrRewrite); + } else { + header != null && setHeader(valueOrRewrite, header, rewrite); + } + + return this; + } + + get(header, parser) { + header = normalizeHeader(header); + + if (header) { + const key = utils$1.findKey(this, header); + + if (key) { + const value = this[key]; + + if (!parser) { + return value; + } + + if (parser === true) { + return parseTokens(value); + } + + if (utils$1.isFunction(parser)) { + return parser.call(this, value, key); + } + + if (utils$1.isRegExp(parser)) { + return parser.exec(value); + } + + throw new TypeError('parser must be boolean|regexp|function'); + } + } + } + + has(header, matcher) { + header = normalizeHeader(header); + + if (header) { + const key = utils$1.findKey(this, header); + + return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher))); + } + + return false; + } + + delete(header, matcher) { + const self = this; + let deleted = false; + + function deleteHeader(_header) { + _header = normalizeHeader(_header); + + if (_header) { + const key = utils$1.findKey(self, _header); + + if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) { + delete self[key]; + + deleted = true; + } + } + } + + if (utils$1.isArray(header)) { + header.forEach(deleteHeader); + } else { + deleteHeader(header); + } + + return deleted; + } + + clear(matcher) { + const keys = Object.keys(this); + let i = keys.length; + let deleted = false; + + while (i--) { + const key = keys[i]; + if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) { + delete this[key]; + deleted = true; + } + } + + return deleted; + } + + normalize(format) { + const self = this; + const headers = {}; + + utils$1.forEach(this, (value, header) => { + const key = utils$1.findKey(headers, header); + + if (key) { + self[key] = normalizeValue(value); + delete self[header]; + return; + } + + const normalized = format ? formatHeader(header) : String(header).trim(); + + if (normalized !== header) { + delete self[header]; + } + + self[normalized] = normalizeValue(value); + + headers[normalized] = true; + }); + + return this; + } + + concat(...targets) { + return this.constructor.concat(this, ...targets); + } + + toJSON(asStrings) { + const obj = Object.create(null); + + utils$1.forEach(this, (value, header) => { + value != null && value !== false && (obj[header] = asStrings && utils$1.isArray(value) ? value.join(', ') : value); + }); + + return obj; + } + + [Symbol.iterator]() { + return Object.entries(this.toJSON())[Symbol.iterator](); + } + + toString() { + return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\n'); + } + + getSetCookie() { + return this.get("set-cookie") || []; + } + + get [Symbol.toStringTag]() { + return 'AxiosHeaders'; + } + + static from(thing) { + return thing instanceof this ? thing : new this(thing); + } + + static concat(first, ...targets) { + const computed = new this(first); + + targets.forEach((target) => computed.set(target)); + + return computed; + } + + static accessor(header) { + const internals = this[$internals] = (this[$internals] = { + accessors: {} + }); + + const accessors = internals.accessors; + const prototype = this.prototype; + + function defineAccessor(_header) { + const lHeader = normalizeHeader(_header); + + if (!accessors[lHeader]) { + buildAccessors(prototype, _header); + accessors[lHeader] = true; + } + } + + utils$1.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header); + + return this; + } + } + + AxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']); + + // reserved names hotfix + utils$1.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => { + let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set` + return { + get: () => value, + set(headerValue) { + this[mapped] = headerValue; + } + } + }); + + utils$1.freezeMethods(AxiosHeaders); + + var AxiosHeaders$1 = AxiosHeaders; + + /** + * Transform the data for a request or a response + * + * @param {Array|Function} fns A single function or Array of functions + * @param {?Object} response The response object + * + * @returns {*} The resulting transformed data + */ + function transformData(fns, response) { + const config = this || defaults$1; + const context = response || config; + const headers = AxiosHeaders$1.from(context.headers); + let data = context.data; + + utils$1.forEach(fns, function transform(fn) { + data = fn.call(config, data, headers.normalize(), response ? response.status : undefined); + }); + + headers.normalize(); + + return data; + } + + function isCancel(value) { + return !!(value && value.__CANCEL__); + } + + /** + * A `CanceledError` is an object that is thrown when an operation is canceled. + * + * @param {string=} message The message. + * @param {Object=} config The config. + * @param {Object=} request The request. + * + * @returns {CanceledError} The created error. + */ + function CanceledError(message, config, request) { + // eslint-disable-next-line no-eq-null,eqeqeq + AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request); + this.name = 'CanceledError'; + } + + utils$1.inherits(CanceledError, AxiosError, { + __CANCEL__: true + }); + + /** + * Resolve or reject a Promise based on response status. + * + * @param {Function} resolve A function that resolves the promise. + * @param {Function} reject A function that rejects the promise. + * @param {object} response The response. + * + * @returns {object} The response. + */ + function settle(resolve, reject, response) { + const validateStatus = response.config.validateStatus; + if (!response.status || !validateStatus || validateStatus(response.status)) { + resolve(response); + } else { + reject(new AxiosError( + 'Request failed with status code ' + response.status, + [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4], + response.config, + response.request, + response + )); + } + } + + function parseProtocol(url) { + const match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url); + return match && match[1] || ''; + } + + /** + * Calculate data maxRate + * @param {Number} [samplesCount= 10] + * @param {Number} [min= 1000] + * @returns {Function} + */ + function speedometer(samplesCount, min) { + samplesCount = samplesCount || 10; + const bytes = new Array(samplesCount); + const timestamps = new Array(samplesCount); + let head = 0; + let tail = 0; + let firstSampleTS; + + min = min !== undefined ? min : 1000; + + return function push(chunkLength) { + const now = Date.now(); + + const startedAt = timestamps[tail]; + + if (!firstSampleTS) { + firstSampleTS = now; + } + + bytes[head] = chunkLength; + timestamps[head] = now; + + let i = tail; + let bytesCount = 0; + + while (i !== head) { + bytesCount += bytes[i++]; + i = i % samplesCount; + } + + head = (head + 1) % samplesCount; + + if (head === tail) { + tail = (tail + 1) % samplesCount; + } + + if (now - firstSampleTS < min) { + return; + } + + const passed = startedAt && now - startedAt; + + return passed ? Math.round(bytesCount * 1000 / passed) : undefined; + }; + } + + /** + * Throttle decorator + * @param {Function} fn + * @param {Number} freq + * @return {Function} + */ + function throttle(fn, freq) { + let timestamp = 0; + let threshold = 1000 / freq; + let lastArgs; + let timer; + + const invoke = (args, now = Date.now()) => { + timestamp = now; + lastArgs = null; + if (timer) { + clearTimeout(timer); + timer = null; + } + fn(...args); + }; + + const throttled = (...args) => { + const now = Date.now(); + const passed = now - timestamp; + if ( passed >= threshold) { + invoke(args, now); + } else { + lastArgs = args; + if (!timer) { + timer = setTimeout(() => { + timer = null; + invoke(lastArgs); + }, threshold - passed); + } + } + }; + + const flush = () => lastArgs && invoke(lastArgs); + + return [throttled, flush]; + } + + const progressEventReducer = (listener, isDownloadStream, freq = 3) => { + let bytesNotified = 0; + const _speedometer = speedometer(50, 250); + + return throttle(e => { + const loaded = e.loaded; + const total = e.lengthComputable ? e.total : undefined; + const progressBytes = loaded - bytesNotified; + const rate = _speedometer(progressBytes); + const inRange = loaded <= total; + + bytesNotified = loaded; + + const data = { + loaded, + total, + progress: total ? (loaded / total) : undefined, + bytes: progressBytes, + rate: rate ? rate : undefined, + estimated: rate && total && inRange ? (total - loaded) / rate : undefined, + event: e, + lengthComputable: total != null, + [isDownloadStream ? 'download' : 'upload']: true + }; + + listener(data); + }, freq); + }; + + const progressEventDecorator = (total, throttled) => { + const lengthComputable = total != null; + + return [(loaded) => throttled[0]({ + lengthComputable, + total, + loaded + }), throttled[1]]; + }; + + const asyncDecorator = (fn) => (...args) => utils$1.asap(() => fn(...args)); + + var isURLSameOrigin = platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => { + url = new URL(url, platform.origin); + + return ( + origin.protocol === url.protocol && + origin.host === url.host && + (isMSIE || origin.port === url.port) + ); + })( + new URL(platform.origin), + platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent) + ) : () => true; + + var cookies = platform.hasStandardBrowserEnv ? + + // Standard browser envs support document.cookie + { + write(name, value, expires, path, domain, secure, sameSite) { + if (typeof document === 'undefined') return; + + const cookie = [`${name}=${encodeURIComponent(value)}`]; + + if (utils$1.isNumber(expires)) { + cookie.push(`expires=${new Date(expires).toUTCString()}`); + } + if (utils$1.isString(path)) { + cookie.push(`path=${path}`); + } + if (utils$1.isString(domain)) { + cookie.push(`domain=${domain}`); + } + if (secure === true) { + cookie.push('secure'); + } + if (utils$1.isString(sameSite)) { + cookie.push(`SameSite=${sameSite}`); + } + + document.cookie = cookie.join('; '); + }, + + read(name) { + if (typeof document === 'undefined') return null; + const match = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]*)')); + return match ? decodeURIComponent(match[1]) : null; + }, + + remove(name) { + this.write(name, '', Date.now() - 86400000, '/'); + } + } + + : + + // Non-standard browser env (web workers, react-native) lack needed support. + { + write() {}, + read() { + return null; + }, + remove() {} + }; + + /** + * Determines whether the specified URL is absolute + * + * @param {string} url The URL to test + * + * @returns {boolean} True if the specified URL is absolute, otherwise false + */ + function isAbsoluteURL(url) { + // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). + // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed + // by any combination of letters, digits, plus, period, or hyphen. + return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url); + } + + /** + * Creates a new URL by combining the specified URLs + * + * @param {string} baseURL The base URL + * @param {string} relativeURL The relative URL + * + * @returns {string} The combined URL + */ + function combineURLs(baseURL, relativeURL) { + return relativeURL + ? baseURL.replace(/\/?\/$/, '') + '/' + relativeURL.replace(/^\/+/, '') + : baseURL; + } + + /** + * Creates a new URL by combining the baseURL with the requestedURL, + * only when the requestedURL is not already an absolute URL. + * If the requestURL is absolute, this function returns the requestedURL untouched. + * + * @param {string} baseURL The base URL + * @param {string} requestedURL Absolute or relative URL to combine + * + * @returns {string} The combined full path + */ + function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) { + let isRelativeUrl = !isAbsoluteURL(requestedURL); + if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) { + return combineURLs(baseURL, requestedURL); + } + return requestedURL; + } + + const headersToObject = (thing) => thing instanceof AxiosHeaders$1 ? { ...thing } : thing; + + /** + * Config-specific merge-function which creates a new config-object + * by merging two configuration objects together. + * + * @param {Object} config1 + * @param {Object} config2 + * + * @returns {Object} New object resulting from merging config2 to config1 + */ + function mergeConfig(config1, config2) { + // eslint-disable-next-line no-param-reassign + config2 = config2 || {}; + const config = {}; + + function getMergedValue(target, source, prop, caseless) { + if (utils$1.isPlainObject(target) && utils$1.isPlainObject(source)) { + return utils$1.merge.call({caseless}, target, source); + } else if (utils$1.isPlainObject(source)) { + return utils$1.merge({}, source); + } else if (utils$1.isArray(source)) { + return source.slice(); + } + return source; + } + + // eslint-disable-next-line consistent-return + function mergeDeepProperties(a, b, prop, caseless) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(a, b, prop, caseless); + } else if (!utils$1.isUndefined(a)) { + return getMergedValue(undefined, a, prop, caseless); + } + } + + // eslint-disable-next-line consistent-return + function valueFromConfig2(a, b) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(undefined, b); + } + } + + // eslint-disable-next-line consistent-return + function defaultToConfig2(a, b) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(undefined, b); + } else if (!utils$1.isUndefined(a)) { + return getMergedValue(undefined, a); + } + } + + // eslint-disable-next-line consistent-return + function mergeDirectKeys(a, b, prop) { + if (prop in config2) { + return getMergedValue(a, b); + } else if (prop in config1) { + return getMergedValue(undefined, a); + } + } + + const mergeMap = { + url: valueFromConfig2, + method: valueFromConfig2, + data: valueFromConfig2, + baseURL: defaultToConfig2, + transformRequest: defaultToConfig2, + transformResponse: defaultToConfig2, + paramsSerializer: defaultToConfig2, + timeout: defaultToConfig2, + timeoutMessage: defaultToConfig2, + withCredentials: defaultToConfig2, + withXSRFToken: defaultToConfig2, + adapter: defaultToConfig2, + responseType: defaultToConfig2, + xsrfCookieName: defaultToConfig2, + xsrfHeaderName: defaultToConfig2, + onUploadProgress: defaultToConfig2, + onDownloadProgress: defaultToConfig2, + decompress: defaultToConfig2, + maxContentLength: defaultToConfig2, + maxBodyLength: defaultToConfig2, + beforeRedirect: defaultToConfig2, + transport: defaultToConfig2, + httpAgent: defaultToConfig2, + httpsAgent: defaultToConfig2, + cancelToken: defaultToConfig2, + socketPath: defaultToConfig2, + responseEncoding: defaultToConfig2, + validateStatus: mergeDirectKeys, + headers: (a, b, prop) => mergeDeepProperties(headersToObject(a), headersToObject(b), prop, true) + }; + + utils$1.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) { + const merge = mergeMap[prop] || mergeDeepProperties; + const configValue = merge(config1[prop], config2[prop], prop); + (utils$1.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue); + }); + + return config; + } + + var resolveConfig = (config) => { + const newConfig = mergeConfig({}, config); + + let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig; + + newConfig.headers = headers = AxiosHeaders$1.from(headers); + + newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer); + + // HTTP basic authentication + if (auth) { + headers.set('Authorization', 'Basic ' + + btoa((auth.username || '') + ':' + (auth.password ? unescape(encodeURIComponent(auth.password)) : '')) + ); + } + + if (utils$1.isFormData(data)) { + if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) { + headers.setContentType(undefined); // browser handles it + } else if (utils$1.isFunction(data.getHeaders)) { + // Node.js FormData (like form-data package) + const formHeaders = data.getHeaders(); + // Only set safe headers to avoid overwriting security headers + const allowedHeaders = ['content-type', 'content-length']; + Object.entries(formHeaders).forEach(([key, val]) => { + if (allowedHeaders.includes(key.toLowerCase())) { + headers.set(key, val); + } + }); + } + } + + // Add xsrf header + // This is only done if running in a standard browser environment. + // Specifically not if we're in a web worker, or react-native. + + if (platform.hasStandardBrowserEnv) { + withXSRFToken && utils$1.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig)); + + if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) { + // Add xsrf header + const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName); + + if (xsrfValue) { + headers.set(xsrfHeaderName, xsrfValue); + } + } + } + + return newConfig; + }; + + const isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined'; + + var xhrAdapter = isXHRAdapterSupported && function (config) { + return new Promise(function dispatchXhrRequest(resolve, reject) { + const _config = resolveConfig(config); + let requestData = _config.data; + const requestHeaders = AxiosHeaders$1.from(_config.headers).normalize(); + let {responseType, onUploadProgress, onDownloadProgress} = _config; + let onCanceled; + let uploadThrottled, downloadThrottled; + let flushUpload, flushDownload; + + function done() { + flushUpload && flushUpload(); // flush events + flushDownload && flushDownload(); // flush events + + _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled); + + _config.signal && _config.signal.removeEventListener('abort', onCanceled); + } + + let request = new XMLHttpRequest(); + + request.open(_config.method.toUpperCase(), _config.url, true); + + // Set the request timeout in MS + request.timeout = _config.timeout; + + function onloadend() { + if (!request) { + return; + } + // Prepare the response + const responseHeaders = AxiosHeaders$1.from( + 'getAllResponseHeaders' in request && request.getAllResponseHeaders() + ); + const responseData = !responseType || responseType === 'text' || responseType === 'json' ? + request.responseText : request.response; + const response = { + data: responseData, + status: request.status, + statusText: request.statusText, + headers: responseHeaders, + config, + request + }; + + settle(function _resolve(value) { + resolve(value); + done(); + }, function _reject(err) { + reject(err); + done(); + }, response); + + // Clean up request + request = null; + } + + if ('onloadend' in request) { + // Use onloadend if available + request.onloadend = onloadend; + } else { + // Listen for ready state to emulate onloadend + request.onreadystatechange = function handleLoad() { + if (!request || request.readyState !== 4) { + return; + } + + // The request errored out and we didn't get a response, this will be + // handled by onerror instead + // With one exception: request that using file: protocol, most browsers + // will return status as 0 even though it's a successful request + if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) { + return; + } + // readystate handler is calling before onerror or ontimeout handlers, + // so we should call onloadend on the next 'tick' + setTimeout(onloadend); + }; + } + + // Handle browser request cancellation (as opposed to a manual cancellation) + request.onabort = function handleAbort() { + if (!request) { + return; + } + + reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request)); + + // Clean up request + request = null; + }; + + // Handle low level network errors + request.onerror = function handleError(event) { + // Browsers deliver a ProgressEvent in XHR onerror + // (message may be empty; when present, surface it) + // See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event + const msg = event && event.message ? event.message : 'Network Error'; + const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request); + // attach the underlying event for consumers who want details + err.event = event || null; + reject(err); + request = null; + }; + + // Handle timeout + request.ontimeout = function handleTimeout() { + let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded'; + const transitional = _config.transitional || transitionalDefaults; + if (_config.timeoutErrorMessage) { + timeoutErrorMessage = _config.timeoutErrorMessage; + } + reject(new AxiosError( + timeoutErrorMessage, + transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, + config, + request)); + + // Clean up request + request = null; + }; + + // Remove Content-Type if data is undefined + requestData === undefined && requestHeaders.setContentType(null); + + // Add headers to the request + if ('setRequestHeader' in request) { + utils$1.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) { + request.setRequestHeader(key, val); + }); + } + + // Add withCredentials to request if needed + if (!utils$1.isUndefined(_config.withCredentials)) { + request.withCredentials = !!_config.withCredentials; + } + + // Add responseType to request if needed + if (responseType && responseType !== 'json') { + request.responseType = _config.responseType; + } + + // Handle progress if needed + if (onDownloadProgress) { + ([downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true)); + request.addEventListener('progress', downloadThrottled); + } + + // Not all browsers support upload events + if (onUploadProgress && request.upload) { + ([uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress)); + + request.upload.addEventListener('progress', uploadThrottled); + + request.upload.addEventListener('loadend', flushUpload); + } + + if (_config.cancelToken || _config.signal) { + // Handle cancellation + // eslint-disable-next-line func-names + onCanceled = cancel => { + if (!request) { + return; + } + reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel); + request.abort(); + request = null; + }; + + _config.cancelToken && _config.cancelToken.subscribe(onCanceled); + if (_config.signal) { + _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled); + } + } + + const protocol = parseProtocol(_config.url); + + if (protocol && platform.protocols.indexOf(protocol) === -1) { + reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config)); + return; + } + + + // Send the request + request.send(requestData || null); + }); + }; + + const composeSignals = (signals, timeout) => { + const {length} = (signals = signals ? signals.filter(Boolean) : []); + + if (timeout || length) { + let controller = new AbortController(); + + let aborted; + + const onabort = function (reason) { + if (!aborted) { + aborted = true; + unsubscribe(); + const err = reason instanceof Error ? reason : this.reason; + controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err)); + } + }; + + let timer = timeout && setTimeout(() => { + timer = null; + onabort(new AxiosError(`timeout ${timeout} of ms exceeded`, AxiosError.ETIMEDOUT)); + }, timeout); + + const unsubscribe = () => { + if (signals) { + timer && clearTimeout(timer); + timer = null; + signals.forEach(signal => { + signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort); + }); + signals = null; + } + }; + + signals.forEach((signal) => signal.addEventListener('abort', onabort)); + + const {signal} = controller; + + signal.unsubscribe = () => utils$1.asap(unsubscribe); + + return signal; + } + }; + + var composeSignals$1 = composeSignals; + + const streamChunk = function* (chunk, chunkSize) { + let len = chunk.byteLength; + + if (len < chunkSize) { + yield chunk; + return; + } + + let pos = 0; + let end; + + while (pos < len) { + end = pos + chunkSize; + yield chunk.slice(pos, end); + pos = end; + } + }; + + const readBytes = async function* (iterable, chunkSize) { + for await (const chunk of readStream(iterable)) { + yield* streamChunk(chunk, chunkSize); + } + }; + + const readStream = async function* (stream) { + if (stream[Symbol.asyncIterator]) { + yield* stream; + return; + } + + const reader = stream.getReader(); + try { + for (;;) { + const {done, value} = await reader.read(); + if (done) { + break; + } + yield value; + } + } finally { + await reader.cancel(); + } + }; + + const trackStream = (stream, chunkSize, onProgress, onFinish) => { + const iterator = readBytes(stream, chunkSize); + + let bytes = 0; + let done; + let _onFinish = (e) => { + if (!done) { + done = true; + onFinish && onFinish(e); + } + }; + + return new ReadableStream({ + async pull(controller) { + try { + const {done, value} = await iterator.next(); + + if (done) { + _onFinish(); + controller.close(); + return; + } + + let len = value.byteLength; + if (onProgress) { + let loadedBytes = bytes += len; + onProgress(loadedBytes); + } + controller.enqueue(new Uint8Array(value)); + } catch (err) { + _onFinish(err); + throw err; + } + }, + cancel(reason) { + _onFinish(reason); + return iterator.return(); + } + }, { + highWaterMark: 2 + }) + }; + + const DEFAULT_CHUNK_SIZE = 64 * 1024; + + const {isFunction} = utils$1; + + const globalFetchAPI = (({Request, Response}) => ({ + Request, Response + }))(utils$1.global); + + const { + ReadableStream: ReadableStream$1, TextEncoder + } = utils$1.global; + + + const test = (fn, ...args) => { + try { + return !!fn(...args); + } catch (e) { + return false + } + }; + + const factory = (env) => { + env = utils$1.merge.call({ + skipUndefined: true + }, globalFetchAPI, env); + + const {fetch: envFetch, Request, Response} = env; + const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function'; + const isRequestSupported = isFunction(Request); + const isResponseSupported = isFunction(Response); + + if (!isFetchSupported) { + return false; + } + + const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream$1); + + const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ? + ((encoder) => (str) => encoder.encode(str))(new TextEncoder()) : + async (str) => new Uint8Array(await new Request(str).arrayBuffer()) + ); + + const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => { + let duplexAccessed = false; + + const hasContentType = new Request(platform.origin, { + body: new ReadableStream$1(), + method: 'POST', + get duplex() { + duplexAccessed = true; + return 'half'; + }, + }).headers.has('Content-Type'); + + return duplexAccessed && !hasContentType; + }); + + const supportsResponseStream = isResponseSupported && isReadableStreamSupported && + test(() => utils$1.isReadableStream(new Response('').body)); + + const resolvers = { + stream: supportsResponseStream && ((res) => res.body) + }; + + isFetchSupported && ((() => { + ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => { + !resolvers[type] && (resolvers[type] = (res, config) => { + let method = res && res[type]; + + if (method) { + return method.call(res); + } + + throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config); + }); + }); + })()); + + const getBodyLength = async (body) => { + if (body == null) { + return 0; + } + + if (utils$1.isBlob(body)) { + return body.size; + } + + if (utils$1.isSpecCompliantForm(body)) { + const _request = new Request(platform.origin, { + method: 'POST', + body, + }); + return (await _request.arrayBuffer()).byteLength; + } + + if (utils$1.isArrayBufferView(body) || utils$1.isArrayBuffer(body)) { + return body.byteLength; + } + + if (utils$1.isURLSearchParams(body)) { + body = body + ''; + } + + if (utils$1.isString(body)) { + return (await encodeText(body)).byteLength; + } + }; + + const resolveBodyLength = async (headers, body) => { + const length = utils$1.toFiniteNumber(headers.getContentLength()); + + return length == null ? getBodyLength(body) : length; + }; + + return async (config) => { + let { + url, + method, + data, + signal, + cancelToken, + timeout, + onDownloadProgress, + onUploadProgress, + responseType, + headers, + withCredentials = 'same-origin', + fetchOptions + } = resolveConfig(config); + + let _fetch = envFetch || fetch; + + responseType = responseType ? (responseType + '').toLowerCase() : 'text'; + + let composedSignal = composeSignals$1([signal, cancelToken && cancelToken.toAbortSignal()], timeout); + + let request = null; + + const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => { + composedSignal.unsubscribe(); + }); + + let requestContentLength; + + try { + if ( + onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' && + (requestContentLength = await resolveBodyLength(headers, data)) !== 0 + ) { + let _request = new Request(url, { + method: 'POST', + body: data, + duplex: "half" + }); + + let contentTypeHeader; + + if (utils$1.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) { + headers.setContentType(contentTypeHeader); + } + + if (_request.body) { + const [onProgress, flush] = progressEventDecorator( + requestContentLength, + progressEventReducer(asyncDecorator(onUploadProgress)) + ); + + data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush); + } + } + + if (!utils$1.isString(withCredentials)) { + withCredentials = withCredentials ? 'include' : 'omit'; + } + + // Cloudflare Workers throws when credentials are defined + // see https://github.com/cloudflare/workerd/issues/902 + const isCredentialsSupported = isRequestSupported && "credentials" in Request.prototype; + + const resolvedOptions = { + ...fetchOptions, + signal: composedSignal, + method: method.toUpperCase(), + headers: headers.normalize().toJSON(), + body: data, + duplex: "half", + credentials: isCredentialsSupported ? withCredentials : undefined + }; + + request = isRequestSupported && new Request(url, resolvedOptions); + + let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions)); + + const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response'); + + if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) { + const options = {}; + + ['status', 'statusText', 'headers'].forEach(prop => { + options[prop] = response[prop]; + }); + + const responseContentLength = utils$1.toFiniteNumber(response.headers.get('content-length')); + + const [onProgress, flush] = onDownloadProgress && progressEventDecorator( + responseContentLength, + progressEventReducer(asyncDecorator(onDownloadProgress), true) + ) || []; + + response = new Response( + trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => { + flush && flush(); + unsubscribe && unsubscribe(); + }), + options + ); + } + + responseType = responseType || 'text'; + + let responseData = await resolvers[utils$1.findKey(resolvers, responseType) || 'text'](response, config); + + !isStreamResponse && unsubscribe && unsubscribe(); + + return await new Promise((resolve, reject) => { + settle(resolve, reject, { + data: responseData, + headers: AxiosHeaders$1.from(response.headers), + status: response.status, + statusText: response.statusText, + config, + request + }); + }) + } catch (err) { + unsubscribe && unsubscribe(); + + if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) { + throw Object.assign( + new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request), + { + cause: err.cause || err + } + ) + } + + throw AxiosError.from(err, err && err.code, config, request); + } + } + }; + + const seedCache = new Map(); + + const getFetch = (config) => { + let env = (config && config.env) || {}; + const {fetch, Request, Response} = env; + const seeds = [ + Request, Response, fetch + ]; + + let len = seeds.length, i = len, + seed, target, map = seedCache; + + while (i--) { + seed = seeds[i]; + target = map.get(seed); + + target === undefined && map.set(seed, target = (i ? new Map() : factory(env))); + + map = target; + } + + return target; + }; + + getFetch(); + + /** + * Known adapters mapping. + * Provides environment-specific adapters for Axios: + * - `http` for Node.js + * - `xhr` for browsers + * - `fetch` for fetch API-based requests + * + * @type {Object} + */ + const knownAdapters = { + http: httpAdapter, + xhr: xhrAdapter, + fetch: { + get: getFetch, + } + }; + + // Assign adapter names for easier debugging and identification + utils$1.forEach(knownAdapters, (fn, value) => { + if (fn) { + try { + Object.defineProperty(fn, 'name', { value }); + } catch (e) { + // eslint-disable-next-line no-empty + } + Object.defineProperty(fn, 'adapterName', { value }); + } + }); + + /** + * Render a rejection reason string for unknown or unsupported adapters + * + * @param {string} reason + * @returns {string} + */ + const renderReason = (reason) => `- ${reason}`; + + /** + * Check if the adapter is resolved (function, null, or false) + * + * @param {Function|null|false} adapter + * @returns {boolean} + */ + const isResolvedHandle = (adapter) => utils$1.isFunction(adapter) || adapter === null || adapter === false; + + /** + * Get the first suitable adapter from the provided list. + * Tries each adapter in order until a supported one is found. + * Throws an AxiosError if no adapter is suitable. + * + * @param {Array|string|Function} adapters - Adapter(s) by name or function. + * @param {Object} config - Axios request configuration + * @throws {AxiosError} If no suitable adapter is available + * @returns {Function} The resolved adapter function + */ + function getAdapter(adapters, config) { + adapters = utils$1.isArray(adapters) ? adapters : [adapters]; + + const { length } = adapters; + let nameOrAdapter; + let adapter; + + const rejectedReasons = {}; + + for (let i = 0; i < length; i++) { + nameOrAdapter = adapters[i]; + let id; + + adapter = nameOrAdapter; + + if (!isResolvedHandle(nameOrAdapter)) { + adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()]; + + if (adapter === undefined) { + throw new AxiosError(`Unknown adapter '${id}'`); + } + } + + if (adapter && (utils$1.isFunction(adapter) || (adapter = adapter.get(config)))) { + break; + } + + rejectedReasons[id || '#' + i] = adapter; + } + + if (!adapter) { + const reasons = Object.entries(rejectedReasons) + .map(([id, state]) => `adapter ${id} ` + + (state === false ? 'is not supported by the environment' : 'is not available in the build') + ); + + let s = length ? + (reasons.length > 1 ? 'since :\n' + reasons.map(renderReason).join('\n') : ' ' + renderReason(reasons[0])) : + 'as no adapter specified'; + + throw new AxiosError( + `There is no suitable adapter to dispatch the request ` + s, + 'ERR_NOT_SUPPORT' + ); + } + + return adapter; + } + + /** + * Exports Axios adapters and utility to resolve an adapter + */ + var adapters = { + /** + * Resolve an adapter from a list of adapter names or functions. + * @type {Function} + */ + getAdapter, + + /** + * Exposes all known adapters + * @type {Object} + */ + adapters: knownAdapters + }; + + /** + * Throws a `CanceledError` if cancellation has been requested. + * + * @param {Object} config The config that is to be used for the request + * + * @returns {void} + */ + function throwIfCancellationRequested(config) { + if (config.cancelToken) { + config.cancelToken.throwIfRequested(); + } + + if (config.signal && config.signal.aborted) { + throw new CanceledError(null, config); + } + } + + /** + * Dispatch a request to the server using the configured adapter. + * + * @param {object} config The config that is to be used for the request + * + * @returns {Promise} The Promise to be fulfilled + */ + function dispatchRequest(config) { + throwIfCancellationRequested(config); + + config.headers = AxiosHeaders$1.from(config.headers); + + // Transform request data + config.data = transformData.call( + config, + config.transformRequest + ); + + if (['post', 'put', 'patch'].indexOf(config.method) !== -1) { + config.headers.setContentType('application/x-www-form-urlencoded', false); + } + + const adapter = adapters.getAdapter(config.adapter || defaults$1.adapter, config); + + return adapter(config).then(function onAdapterResolution(response) { + throwIfCancellationRequested(config); + + // Transform response data + response.data = transformData.call( + config, + config.transformResponse, + response + ); + + response.headers = AxiosHeaders$1.from(response.headers); + + return response; + }, function onAdapterRejection(reason) { + if (!isCancel(reason)) { + throwIfCancellationRequested(config); + + // Transform response data + if (reason && reason.response) { + reason.response.data = transformData.call( + config, + config.transformResponse, + reason.response + ); + reason.response.headers = AxiosHeaders$1.from(reason.response.headers); + } + } + + return Promise.reject(reason); + }); + } + + const VERSION = "1.13.2"; + + const validators$1 = {}; + + // eslint-disable-next-line func-names + ['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => { + validators$1[type] = function validator(thing) { + return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type; + }; + }); + + const deprecatedWarnings = {}; + + /** + * Transitional option validator + * + * @param {function|boolean?} validator - set to false if the transitional option has been removed + * @param {string?} version - deprecated version / removed since version + * @param {string?} message - some message with additional info + * + * @returns {function} + */ + validators$1.transitional = function transitional(validator, version, message) { + function formatMessage(opt, desc) { + return '[Axios v' + VERSION + '] Transitional option \'' + opt + '\'' + desc + (message ? '. ' + message : ''); + } + + // eslint-disable-next-line func-names + return (value, opt, opts) => { + if (validator === false) { + throw new AxiosError( + formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')), + AxiosError.ERR_DEPRECATED + ); + } + + if (version && !deprecatedWarnings[opt]) { + deprecatedWarnings[opt] = true; + // eslint-disable-next-line no-console + console.warn( + formatMessage( + opt, + ' has been deprecated since v' + version + ' and will be removed in the near future' + ) + ); + } + + return validator ? validator(value, opt, opts) : true; + }; + }; + + validators$1.spelling = function spelling(correctSpelling) { + return (value, opt) => { + // eslint-disable-next-line no-console + console.warn(`${opt} is likely a misspelling of ${correctSpelling}`); + return true; + } + }; + + /** + * Assert object's properties type + * + * @param {object} options + * @param {object} schema + * @param {boolean?} allowUnknown + * + * @returns {object} + */ + + function assertOptions(options, schema, allowUnknown) { + if (typeof options !== 'object') { + throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE); + } + const keys = Object.keys(options); + let i = keys.length; + while (i-- > 0) { + const opt = keys[i]; + const validator = schema[opt]; + if (validator) { + const value = options[opt]; + const result = value === undefined || validator(value, opt, options); + if (result !== true) { + throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE); + } + continue; + } + if (allowUnknown !== true) { + throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION); + } + } + } + + var validator = { + assertOptions, + validators: validators$1 + }; + + const validators = validator.validators; + + /** + * Create a new instance of Axios + * + * @param {Object} instanceConfig The default config for the instance + * + * @return {Axios} A new instance of Axios + */ + class Axios { + constructor(instanceConfig) { + this.defaults = instanceConfig || {}; + this.interceptors = { + request: new InterceptorManager$1(), + response: new InterceptorManager$1() + }; + } + + /** + * Dispatch a request + * + * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults) + * @param {?Object} config + * + * @returns {Promise} The Promise to be fulfilled + */ + async request(configOrUrl, config) { + try { + return await this._request(configOrUrl, config); + } catch (err) { + if (err instanceof Error) { + let dummy = {}; + + Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error()); + + // slice off the Error: ... line + const stack = dummy.stack ? dummy.stack.replace(/^.+\n/, '') : ''; + try { + if (!err.stack) { + err.stack = stack; + // match without the 2 top stack lines + } else if (stack && !String(err.stack).endsWith(stack.replace(/^.+\n.+\n/, ''))) { + err.stack += '\n' + stack; + } + } catch (e) { + // ignore the case where "stack" is an un-writable property + } + } + + throw err; + } + } + + _request(configOrUrl, config) { + /*eslint no-param-reassign:0*/ + // Allow for axios('example/url'[, config]) a la fetch API + if (typeof configOrUrl === 'string') { + config = config || {}; + config.url = configOrUrl; + } else { + config = configOrUrl || {}; + } + + config = mergeConfig(this.defaults, config); + + const {transitional, paramsSerializer, headers} = config; + + if (transitional !== undefined) { + validator.assertOptions(transitional, { + silentJSONParsing: validators.transitional(validators.boolean), + forcedJSONParsing: validators.transitional(validators.boolean), + clarifyTimeoutError: validators.transitional(validators.boolean) + }, false); + } + + if (paramsSerializer != null) { + if (utils$1.isFunction(paramsSerializer)) { + config.paramsSerializer = { + serialize: paramsSerializer + }; + } else { + validator.assertOptions(paramsSerializer, { + encode: validators.function, + serialize: validators.function + }, true); + } + } + + // Set config.allowAbsoluteUrls + if (config.allowAbsoluteUrls !== undefined) ; else if (this.defaults.allowAbsoluteUrls !== undefined) { + config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls; + } else { + config.allowAbsoluteUrls = true; + } + + validator.assertOptions(config, { + baseUrl: validators.spelling('baseURL'), + withXsrfToken: validators.spelling('withXSRFToken') + }, true); + + // Set config.method + config.method = (config.method || this.defaults.method || 'get').toLowerCase(); + + // Flatten headers + let contextHeaders = headers && utils$1.merge( + headers.common, + headers[config.method] + ); + + headers && utils$1.forEach( + ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'], + (method) => { + delete headers[method]; + } + ); + + config.headers = AxiosHeaders$1.concat(contextHeaders, headers); + + // filter out skipped interceptors + const requestInterceptorChain = []; + let synchronousRequestInterceptors = true; + this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { + if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) { + return; + } + + synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous; + + requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected); + }); + + const responseInterceptorChain = []; + this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { + responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected); + }); + + let promise; + let i = 0; + let len; + + if (!synchronousRequestInterceptors) { + const chain = [dispatchRequest.bind(this), undefined]; + chain.unshift(...requestInterceptorChain); + chain.push(...responseInterceptorChain); + len = chain.length; + + promise = Promise.resolve(config); + + while (i < len) { + promise = promise.then(chain[i++], chain[i++]); + } + + return promise; + } + + len = requestInterceptorChain.length; + + let newConfig = config; + + while (i < len) { + const onFulfilled = requestInterceptorChain[i++]; + const onRejected = requestInterceptorChain[i++]; + try { + newConfig = onFulfilled(newConfig); + } catch (error) { + onRejected.call(this, error); + break; + } + } + + try { + promise = dispatchRequest.call(this, newConfig); + } catch (error) { + return Promise.reject(error); + } + + i = 0; + len = responseInterceptorChain.length; + + while (i < len) { + promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]); + } + + return promise; + } + + getUri(config) { + config = mergeConfig(this.defaults, config); + const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls); + return buildURL(fullPath, config.params, config.paramsSerializer); + } + } + + // Provide aliases for supported request methods + utils$1.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) { + /*eslint func-names:0*/ + Axios.prototype[method] = function(url, config) { + return this.request(mergeConfig(config || {}, { + method, + url, + data: (config || {}).data + })); + }; + }); + + utils$1.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { + /*eslint func-names:0*/ + + function generateHTTPMethod(isForm) { + return function httpMethod(url, data, config) { + return this.request(mergeConfig(config || {}, { + method, + headers: isForm ? { + 'Content-Type': 'multipart/form-data' + } : {}, + url, + data + })); + }; + } + + Axios.prototype[method] = generateHTTPMethod(); + + Axios.prototype[method + 'Form'] = generateHTTPMethod(true); + }); + + var Axios$1 = Axios; + + /** + * A `CancelToken` is an object that can be used to request cancellation of an operation. + * + * @param {Function} executor The executor function. + * + * @returns {CancelToken} + */ + class CancelToken { + constructor(executor) { + if (typeof executor !== 'function') { + throw new TypeError('executor must be a function.'); + } + + let resolvePromise; + + this.promise = new Promise(function promiseExecutor(resolve) { + resolvePromise = resolve; + }); + + const token = this; + + // eslint-disable-next-line func-names + this.promise.then(cancel => { + if (!token._listeners) return; + + let i = token._listeners.length; + + while (i-- > 0) { + token._listeners[i](cancel); + } + token._listeners = null; + }); + + // eslint-disable-next-line func-names + this.promise.then = onfulfilled => { + let _resolve; + // eslint-disable-next-line func-names + const promise = new Promise(resolve => { + token.subscribe(resolve); + _resolve = resolve; + }).then(onfulfilled); + + promise.cancel = function reject() { + token.unsubscribe(_resolve); + }; + + return promise; + }; + + executor(function cancel(message, config, request) { + if (token.reason) { + // Cancellation has already been requested + return; + } + + token.reason = new CanceledError(message, config, request); + resolvePromise(token.reason); + }); + } + + /** + * Throws a `CanceledError` if cancellation has been requested. + */ + throwIfRequested() { + if (this.reason) { + throw this.reason; + } + } + + /** + * Subscribe to the cancel signal + */ + + subscribe(listener) { + if (this.reason) { + listener(this.reason); + return; + } + + if (this._listeners) { + this._listeners.push(listener); + } else { + this._listeners = [listener]; + } + } + + /** + * Unsubscribe from the cancel signal + */ + + unsubscribe(listener) { + if (!this._listeners) { + return; + } + const index = this._listeners.indexOf(listener); + if (index !== -1) { + this._listeners.splice(index, 1); + } + } + + toAbortSignal() { + const controller = new AbortController(); + + const abort = (err) => { + controller.abort(err); + }; + + this.subscribe(abort); + + controller.signal.unsubscribe = () => this.unsubscribe(abort); + + return controller.signal; + } + + /** + * Returns an object that contains a new `CancelToken` and a function that, when called, + * cancels the `CancelToken`. + */ + static source() { + let cancel; + const token = new CancelToken(function executor(c) { + cancel = c; + }); + return { + token, + cancel + }; + } + } + + var CancelToken$1 = CancelToken; + + /** + * Syntactic sugar for invoking a function and expanding an array for arguments. + * + * Common use case would be to use `Function.prototype.apply`. + * + * ```js + * function f(x, y, z) {} + * var args = [1, 2, 3]; + * f.apply(null, args); + * ``` + * + * With `spread` this example can be re-written. + * + * ```js + * spread(function(x, y, z) {})([1, 2, 3]); + * ``` + * + * @param {Function} callback + * + * @returns {Function} + */ + function spread(callback) { + return function wrap(arr) { + return callback.apply(null, arr); + }; + } + + /** + * Determines whether the payload is an error thrown by Axios + * + * @param {*} payload The value to test + * + * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false + */ + function isAxiosError(payload) { + return utils$1.isObject(payload) && (payload.isAxiosError === true); + } + + const HttpStatusCode = { + Continue: 100, + SwitchingProtocols: 101, + Processing: 102, + EarlyHints: 103, + Ok: 200, + Created: 201, + Accepted: 202, + NonAuthoritativeInformation: 203, + NoContent: 204, + ResetContent: 205, + PartialContent: 206, + MultiStatus: 207, + AlreadyReported: 208, + ImUsed: 226, + MultipleChoices: 300, + MovedPermanently: 301, + Found: 302, + SeeOther: 303, + NotModified: 304, + UseProxy: 305, + Unused: 306, + TemporaryRedirect: 307, + PermanentRedirect: 308, + BadRequest: 400, + Unauthorized: 401, + PaymentRequired: 402, + Forbidden: 403, + NotFound: 404, + MethodNotAllowed: 405, + NotAcceptable: 406, + ProxyAuthenticationRequired: 407, + RequestTimeout: 408, + Conflict: 409, + Gone: 410, + LengthRequired: 411, + PreconditionFailed: 412, + PayloadTooLarge: 413, + UriTooLong: 414, + UnsupportedMediaType: 415, + RangeNotSatisfiable: 416, + ExpectationFailed: 417, + ImATeapot: 418, + MisdirectedRequest: 421, + UnprocessableEntity: 422, + Locked: 423, + FailedDependency: 424, + TooEarly: 425, + UpgradeRequired: 426, + PreconditionRequired: 428, + TooManyRequests: 429, + RequestHeaderFieldsTooLarge: 431, + UnavailableForLegalReasons: 451, + InternalServerError: 500, + NotImplemented: 501, + BadGateway: 502, + ServiceUnavailable: 503, + GatewayTimeout: 504, + HttpVersionNotSupported: 505, + VariantAlsoNegotiates: 506, + InsufficientStorage: 507, + LoopDetected: 508, + NotExtended: 510, + NetworkAuthenticationRequired: 511, + WebServerIsDown: 521, + ConnectionTimedOut: 522, + OriginIsUnreachable: 523, + TimeoutOccurred: 524, + SslHandshakeFailed: 525, + InvalidSslCertificate: 526, + }; + + Object.entries(HttpStatusCode).forEach(([key, value]) => { + HttpStatusCode[value] = key; + }); + + var HttpStatusCode$1 = HttpStatusCode; + + /** + * Create an instance of Axios + * + * @param {Object} defaultConfig The default config for the instance + * + * @returns {Axios} A new instance of Axios + */ + function createInstance(defaultConfig) { + const context = new Axios$1(defaultConfig); + const instance = bind(Axios$1.prototype.request, context); + + // Copy axios.prototype to instance + utils$1.extend(instance, Axios$1.prototype, context, {allOwnKeys: true}); + + // Copy context to instance + utils$1.extend(instance, context, null, {allOwnKeys: true}); + + // Factory for creating new instances + instance.create = function create(instanceConfig) { + return createInstance(mergeConfig(defaultConfig, instanceConfig)); + }; + + return instance; + } + + // Create the default instance to be exported + const axios = createInstance(defaults$1); + + // Expose Axios class to allow class inheritance + axios.Axios = Axios$1; + + // Expose Cancel & CancelToken + axios.CanceledError = CanceledError; + axios.CancelToken = CancelToken$1; + axios.isCancel = isCancel; + axios.VERSION = VERSION; + axios.toFormData = toFormData; + + // Expose AxiosError class + axios.AxiosError = AxiosError; + + // alias for CanceledError for backward compatibility + axios.Cancel = axios.CanceledError; + + // Expose all/spread + axios.all = function all(promises) { + return Promise.all(promises); + }; + + axios.spread = spread; + + // Expose isAxiosError + axios.isAxiosError = isAxiosError; + + // Expose mergeConfig + axios.mergeConfig = mergeConfig; + + axios.AxiosHeaders = AxiosHeaders$1; + + axios.formToJSON = thing => formDataToJSON(utils$1.isHTMLForm(thing) ? new FormData(thing) : thing); + + axios.getAdapter = adapters.getAdapter; + + axios.HttpStatusCode = HttpStatusCode$1; + + axios.default = axios; + + var axios_1$1 = axios; + + var dist = {}; + + var app = {}; + + var bip32 = {}; + + var consts = {}; + + Object.defineProperty(consts, "__esModule", { value: true }); + consts.ERROR_DESCRIPTION_OVERRIDE = consts.LedgerError = consts.PAYLOAD_TYPE = consts.LEDGER_DASHBOARD_CLA = consts.HARDENED = void 0; + consts.HARDENED = 0x80000000; + consts.LEDGER_DASHBOARD_CLA = 0xb0; + consts.PAYLOAD_TYPE = { + INIT: 0x00, + ADD: 0x01, + LAST: 0x02, + }; + var LedgerError; + (function (LedgerError) { + LedgerError[LedgerError["U2FUnknown"] = 1] = "U2FUnknown"; + LedgerError[LedgerError["U2FBadRequest"] = 2] = "U2FBadRequest"; + LedgerError[LedgerError["U2FConfigurationUnsupported"] = 3] = "U2FConfigurationUnsupported"; + LedgerError[LedgerError["U2FDeviceIneligible"] = 4] = "U2FDeviceIneligible"; + LedgerError[LedgerError["U2FTimeout"] = 5] = "U2FTimeout"; + LedgerError[LedgerError["Timeout"] = 14] = "Timeout"; + LedgerError[LedgerError["GpAuthFailed"] = 25344] = "GpAuthFailed"; + LedgerError[LedgerError["PinRemainingAttempts"] = 25536] = "PinRemainingAttempts"; + LedgerError[LedgerError["ExecutionError"] = 25600] = "ExecutionError"; + LedgerError[LedgerError["WrongLength"] = 26368] = "WrongLength"; + LedgerError[LedgerError["IncorrectLength"] = 26368] = "IncorrectLength"; + LedgerError[LedgerError["MissingCriticalParameter"] = 26624] = "MissingCriticalParameter"; + LedgerError[LedgerError["ErrorDerivingKeys"] = 26626] = "ErrorDerivingKeys"; + LedgerError[LedgerError["EmptyBuffer"] = 27010] = "EmptyBuffer"; + LedgerError[LedgerError["SecurityStatusNotSatisfied"] = 27010] = "SecurityStatusNotSatisfied"; + LedgerError[LedgerError["OutputBufferTooSmall"] = 27011] = "OutputBufferTooSmall"; + LedgerError[LedgerError["DataIsInvalid"] = 27012] = "DataIsInvalid"; + LedgerError[LedgerError["ConditionsOfUseNotSatisfied"] = 27013] = "ConditionsOfUseNotSatisfied"; + LedgerError[LedgerError["CommandIncompatibleFileStructure"] = 27009] = "CommandIncompatibleFileStructure"; + LedgerError[LedgerError["TransactionRejected"] = 27014] = "TransactionRejected"; + LedgerError[LedgerError["BadKeyHandle"] = 27264] = "BadKeyHandle"; + LedgerError[LedgerError["IncorrectData"] = 27264] = "IncorrectData"; + LedgerError[LedgerError["ReferencedDataNotFound"] = 27272] = "ReferencedDataNotFound"; + LedgerError[LedgerError["NotEnoughMemorySpace"] = 27268] = "NotEnoughMemorySpace"; + LedgerError[LedgerError["FileAlreadyExists"] = 27273] = "FileAlreadyExists"; + LedgerError[LedgerError["InvalidP1P2"] = 27392] = "InvalidP1P2"; + LedgerError[LedgerError["IncorrectP1P2"] = 27392] = "IncorrectP1P2"; + LedgerError[LedgerError["InstructionNotSupported"] = 27904] = "InstructionNotSupported"; + LedgerError[LedgerError["InsNotSupported"] = 27904] = "InsNotSupported"; + LedgerError[LedgerError["UnknownApdu"] = 27906] = "UnknownApdu"; + LedgerError[LedgerError["DeviceNotOnboarded"] = 27911] = "DeviceNotOnboarded"; + LedgerError[LedgerError["DeviceNotOnboarded2"] = 26129] = "DeviceNotOnboarded2"; + LedgerError[LedgerError["CustomImageBootloader"] = 26159] = "CustomImageBootloader"; + LedgerError[LedgerError["CustomImageEmpty"] = 26158] = "CustomImageEmpty"; + LedgerError[LedgerError["AppDoesNotSeemToBeOpen"] = 28161] = "AppDoesNotSeemToBeOpen"; + LedgerError[LedgerError["ClaNotSupported"] = 28160] = "ClaNotSupported"; + LedgerError[LedgerError["Licensing"] = 28482] = "Licensing"; + LedgerError[LedgerError["UnknownError"] = 28416] = "UnknownError"; + LedgerError[LedgerError["TechnicalProblem"] = 28416] = "TechnicalProblem"; + LedgerError[LedgerError["SignVerifyError"] = 28417] = "SignVerifyError"; + LedgerError[LedgerError["Halted"] = 28586] = "Halted"; + LedgerError[LedgerError["NoErrors"] = 36864] = "NoErrors"; + LedgerError[LedgerError["DeviceIsBusy"] = 36865] = "DeviceIsBusy"; + LedgerError[LedgerError["UnknownTransportError"] = 65535] = "UnknownTransportError"; + LedgerError[LedgerError["AccessConditionNotFulfilled"] = 38916] = "AccessConditionNotFulfilled"; + LedgerError[LedgerError["AlgorithmNotSupported"] = 38020] = "AlgorithmNotSupported"; + LedgerError[LedgerError["CodeBlocked"] = 38976] = "CodeBlocked"; + LedgerError[LedgerError["CodeNotInitialized"] = 38914] = "CodeNotInitialized"; + LedgerError[LedgerError["ContradictionInvalidation"] = 38928] = "ContradictionInvalidation"; + LedgerError[LedgerError["ContradictionSecretCodeStatus"] = 38920] = "ContradictionSecretCodeStatus"; + LedgerError[LedgerError["InvalidKcv"] = 38021] = "InvalidKcv"; + LedgerError[LedgerError["InvalidOffset"] = 37890] = "InvalidOffset"; + LedgerError[LedgerError["LockedDevice"] = 21781] = "LockedDevice"; + LedgerError[LedgerError["MaxValueReached"] = 38992] = "MaxValueReached"; + LedgerError[LedgerError["MemoryProblem"] = 37440] = "MemoryProblem"; + LedgerError[LedgerError["NoEfSelected"] = 37888] = "NoEfSelected"; + LedgerError[LedgerError["InconsistentFile"] = 37896] = "InconsistentFile"; + LedgerError[LedgerError["FileNotFound"] = 37892] = "FileNotFound"; + LedgerError[LedgerError["UserRefusedOnDevice"] = 21761] = "UserRefusedOnDevice"; + LedgerError[LedgerError["NotEnoughSpace"] = 20738] = "NotEnoughSpace"; + LedgerError[LedgerError["GenericError"] = 4294967295] = "GenericError"; + })(LedgerError || (consts.LedgerError = LedgerError = {})); + consts.ERROR_DESCRIPTION_OVERRIDE = { + [LedgerError.U2FUnknown]: 'U2F: Unknown', + [LedgerError.U2FBadRequest]: 'U2F: Bad request', + [LedgerError.U2FConfigurationUnsupported]: 'U2F: Configuration unsupported', + [LedgerError.U2FDeviceIneligible]: 'U2F: Device Ineligible', + [LedgerError.U2FTimeout]: 'U2F: Timeout', + [LedgerError.Timeout]: 'Timeout', + [LedgerError.NoErrors]: 'No errors', + [LedgerError.DeviceIsBusy]: 'Device is busy', + [LedgerError.ErrorDerivingKeys]: 'Error deriving keys', + [LedgerError.ExecutionError]: 'Execution Error', + [LedgerError.WrongLength]: 'Wrong Length', + [LedgerError.EmptyBuffer]: 'Empty Buffer', + [LedgerError.OutputBufferTooSmall]: 'Output buffer too small', + [LedgerError.DataIsInvalid]: 'Data is invalid', + [LedgerError.TransactionRejected]: 'Transaction rejected', + [LedgerError.BadKeyHandle]: 'Bad key handle', + [LedgerError.InvalidP1P2]: 'Invalid P1/P2', + [LedgerError.InstructionNotSupported]: 'Instruction not supported', + [LedgerError.AppDoesNotSeemToBeOpen]: 'App does not seem to be open', + [LedgerError.UnknownError]: 'Unknown error', + [LedgerError.SignVerifyError]: 'Sign/verify error', + [LedgerError.UnknownTransportError]: 'Unknown transport error', + [LedgerError.GpAuthFailed]: 'GP Authentication Failed', + [LedgerError.PinRemainingAttempts]: 'PIN Remaining Attempts', + [LedgerError.MissingCriticalParameter]: 'Missing Critical Parameter', + [LedgerError.ConditionsOfUseNotSatisfied]: 'Conditions of Use Not Satisfied', + [LedgerError.CommandIncompatibleFileStructure]: 'Command Incompatible with File Structure', + [LedgerError.ReferencedDataNotFound]: 'Referenced Data Not Found', + [LedgerError.NotEnoughMemorySpace]: 'Not Enough Memory Space', + [LedgerError.FileAlreadyExists]: 'File Already Exists', + [LedgerError.UnknownApdu]: 'Unknown APDU', + [LedgerError.DeviceNotOnboarded]: 'Device Not Onboarded', + [LedgerError.DeviceNotOnboarded2]: 'Device Not Onboarded (Secondary)', + [LedgerError.CustomImageBootloader]: 'Custom Image Bootloader Error', + [LedgerError.CustomImageEmpty]: 'Custom Image Empty', + [LedgerError.ClaNotSupported]: 'CLA Not Supported', + [LedgerError.Licensing]: 'Licensing Error', + [LedgerError.Halted]: 'Device Halted', + [LedgerError.AccessConditionNotFulfilled]: 'Access Condition Not Fulfilled', + [LedgerError.AlgorithmNotSupported]: 'Algorithm Not Supported', + [LedgerError.CodeBlocked]: 'Code Blocked', + [LedgerError.CodeNotInitialized]: 'Code Not Initialized', + [LedgerError.ContradictionInvalidation]: 'Contradiction Invalidation', + [LedgerError.ContradictionSecretCodeStatus]: 'Contradiction with Secret Code Status', + [LedgerError.InvalidKcv]: 'Invalid KCV', + [LedgerError.InvalidOffset]: 'Invalid Offset', + [LedgerError.LockedDevice]: 'Device Locked', + [LedgerError.MaxValueReached]: 'Maximum Value Reached', + [LedgerError.MemoryProblem]: 'Memory Problem', + [LedgerError.NoEfSelected]: 'No EF Selected', + [LedgerError.InconsistentFile]: 'Inconsistent File', + [LedgerError.FileNotFound]: 'File Not Found', + [LedgerError.UserRefusedOnDevice]: 'User Refused on Device', + [LedgerError.NotEnoughSpace]: 'Not Enough Space', + [LedgerError.GenericError]: 'Generic Error', + }; + + var responseError = {}; + + var errors = {}; + + Object.defineProperty(errors, "__esModule", { value: true }); + errors.errorCodeToString = errorCodeToString; + const consts_1$4 = consts; + function errorCodeToString(returnCode, customErrorList) { + const returnCodeStr = returnCode.toString(16).toUpperCase(); + let errDescription = `Unknown Return Code: 0x${returnCodeStr}`; + if (returnCode in consts_1$4.ERROR_DESCRIPTION_OVERRIDE) { + return consts_1$4.ERROR_DESCRIPTION_OVERRIDE[returnCode]; + } + if (customErrorList && returnCode in customErrorList) { + return customErrorList[returnCode]; + } + return errDescription; + } + + Object.defineProperty(responseError, "__esModule", { value: true }); + responseError.ResponseError = void 0; + const errors_1$1 = errors; + class ResponseError extends Error { + constructor(returnCode, errorMessage) { + super(errorMessage); + this.errorMessage = errorMessage; + this.returnCode = returnCode; + } + static fromReturnCode(returnCode, customErrorList) { + return new ResponseError(returnCode, (0, errors_1$1.errorCodeToString)(returnCode, customErrorList)); + } + } + responseError.ResponseError = ResponseError; + + Object.defineProperty(bip32, "__esModule", { value: true }); + bip32.serializePath = serializePath; + bip32.numbersToBip32Path = numbersToBip32Path; + bip32.bufferToBip32Path = bufferToBip32Path; + const consts_1$3 = consts; + const responseError_1$3 = responseError; + function serializePath(path, requiredPathLengths) { + if (typeof path !== 'string') { + throw new responseError_1$3.ResponseError(consts_1$3.LedgerError.GenericError, "Path should be a string (e.g \"m/44'/461'/5'/0/3\")"); + } + if (!path.startsWith('m/')) { + throw new responseError_1$3.ResponseError(consts_1$3.LedgerError.GenericError, 'Path should start with "m/" (e.g "m/44\'/461\'/5\'/0/3")'); + } + const pathArray = path.split('/'); + pathArray.shift(); + if (requiredPathLengths && requiredPathLengths.length > 0 && !requiredPathLengths.includes(pathArray.length)) { + throw new responseError_1$3.ResponseError(consts_1$3.LedgerError.GenericError, "Invalid path length. (e.g \"m/44'/5757'/5'/0/3\")"); + } + const buf = Buffer.alloc(4 * pathArray.length); + pathArray.forEach((child, i) => { + let value = 0; + if (child.endsWith("'")) { + value += consts_1$3.HARDENED; + child = child.slice(0, -1); + } + const numChild = Number(child); + if (Number.isNaN(numChild)) { + throw new responseError_1$3.ResponseError(consts_1$3.LedgerError.GenericError, `Invalid path : ${child} is not a number. (e.g "m/44'/461'/5'/0/3")`); + } + if (numChild >= consts_1$3.HARDENED) { + throw new responseError_1$3.ResponseError(consts_1$3.LedgerError.GenericError, 'Incorrect child value (bigger or equal to 0x80000000)'); + } + value += numChild; + buf.writeUInt32LE(value, 4 * i); + }); + return buf; + } + function numbersToBip32Path(items) { + if (items.length === 0) { + throw new responseError_1$3.ResponseError(consts_1$3.LedgerError.GenericError, 'The items array cannot be empty.'); + } + const pathArray = []; + for (let i = 0; i < items.length; i++) { + let value = items[i]; + if (!Number.isInteger(value) || value < 0) { + throw new responseError_1$3.ResponseError(consts_1$3.LedgerError.GenericError, 'Each item must be a positive integer.'); + } + let child = value & ~consts_1$3.HARDENED; + if (value >= consts_1$3.HARDENED) { + pathArray.push(`${child}'`); + } + else { + pathArray.push(`${child}`); + } + } + return 'm/' + pathArray.join('/'); + } + function bufferToBip32Path(buffer) { + if (buffer.length % 4 !== 0) { + throw new responseError_1$3.ResponseError(consts_1$3.LedgerError.GenericError, 'The buffer length must be a multiple of 4.'); + } + const items = []; + for (let i = 0; i < buffer.length; i += 4) { + items.push(buffer.readUInt32LE(i)); + } + return numbersToBip32Path(items); + } + + var common = {}; + + var payload = {}; + + var byteStream = {}; + + Object.defineProperty(byteStream, "__esModule", { value: true }); + byteStream.ByteStream = void 0; + const consts_1$2 = consts; + const responseError_1$2 = responseError; + class ByteStream { + constructor(buffer) { + this.readOffset = 0; + this.writeOffset = 0; + this.internalBuffer = buffer ? Buffer.from(buffer) : Buffer.alloc(0); + this.readOffset = 0; + this.writeOffset = this.internalBuffer.length; + } + appendUint8(value) { + const byteBuffer = Buffer.from([value]); + this.appendBytes(byteBuffer); + } + appendUint16(value) { + const byteBuffer = Buffer.alloc(2); + byteBuffer.writeUInt16LE(value, 0); + this.appendBytes(byteBuffer); + } + appendUint32(value) { + const byteBuffer = Buffer.alloc(4); + byteBuffer.writeUInt32LE(value, 0); + this.appendBytes(byteBuffer); + } + appendUint64(value) { + const byteBuffer = Buffer.alloc(8); + byteBuffer.writeBigUInt64LE(value, 0); + this.appendBytes(byteBuffer); + } + readBytes(length) { + if (this.readOffset + length > this.internalBuffer.length) { + throw new responseError_1$2.ResponseError(consts_1$2.LedgerError.UnknownError, 'Attempt to read beyond buffer length'); + } + const response = this.internalBuffer.subarray(this.readOffset, this.readOffset + length); + this.readOffset += length; + return response; + } + readBytesAt(length, offset) { + if (offset + length > this.internalBuffer.length) { + throw new responseError_1$2.ResponseError(consts_1$2.LedgerError.UnknownError, 'Attempt to read beyond buffer length'); + } + return this.internalBuffer.subarray(offset, offset + length); + } + appendBytes(data) { + if (this.writeOffset + data.length > this.internalBuffer.length) { + const newBuffer = Buffer.alloc(this.writeOffset + data.length); + this.internalBuffer.copy(newBuffer, 0, 0, this.writeOffset); + this.internalBuffer = newBuffer; + } + data.copy(this.internalBuffer, this.writeOffset); + this.writeOffset += data.length; + } + insertBytesAt(data, offset) { + if (offset > this.internalBuffer.length) { + const padding = Buffer.alloc(offset - this.internalBuffer.length, 0); + this.internalBuffer = Buffer.concat([this.internalBuffer, padding, data]); + } + else { + const before = this.internalBuffer.subarray(0, offset); + const after = this.internalBuffer.subarray(offset); + this.internalBuffer = Buffer.concat([before, data, after]); + } + } + writeBytesAt(data, offset) { + if (offset + data.length > this.internalBuffer.length) { + const newBuffer = Buffer.alloc(offset + data.length); + this.internalBuffer.copy(newBuffer, 0, 0, offset); + this.internalBuffer = newBuffer; + } + data.copy(this.internalBuffer, offset); + this.writeOffset = offset + data.length; + } + skipBytes(length) { + if (this.readOffset + length > this.internalBuffer.length) { + throw new responseError_1$2.ResponseError(consts_1$2.LedgerError.UnknownError, 'Attempt to skip beyond buffer length'); + } + this.readOffset += length; + } + clear() { + this.internalBuffer = Buffer.alloc(0); + this.readOffset = 0; + this.writeOffset = 0; + } + resetOffset() { + this.readOffset = 0; + this.writeOffset = 0; + } + getCompleteBuffer() { + return Buffer.from(this.internalBuffer); + } + getAvailableBuffer() { + return Buffer.from(this.internalBuffer.subarray(this.readOffset)); + } + length() { + return this.internalBuffer.length - this.readOffset; + } + capacity() { + return this.internalBuffer.length; + } + getReadOffset() { + return this.readOffset; + } + getWriteOffset() { + return this.writeOffset; + } + setReadOffset(offset) { + if (offset < 0 || offset > this.internalBuffer.length) { + throw new responseError_1$2.ResponseError(consts_1$2.LedgerError.UnknownError, 'Invalid read offset'); + } + this.readOffset = offset; + } + setWriteOffset(offset) { + if (offset < 0 || offset > this.internalBuffer.length) { + throw new responseError_1$2.ResponseError(consts_1$2.LedgerError.UnknownError, 'Invalid write offset'); + } + this.writeOffset = offset; + } + } + byteStream.ByteStream = ByteStream; + + Object.defineProperty(payload, "__esModule", { value: true }); + payload.ResponsePayload = void 0; + const byteStream_1 = byteStream; + class ResponsePayload extends byteStream_1.ByteStream { + constructor(payload) { + super(payload); + } + } + payload.ResponsePayload = ResponsePayload; + + Object.defineProperty(common, "__esModule", { value: true }); + common.processResponse = processResponse; + common.processErrorResponse = processErrorResponse; + const consts_1$1 = consts; + const errors_1 = errors; + const payload_1 = payload; + const responseError_1$1 = responseError; + function isDict(v) { + return typeof v === 'object' && v !== null && !(v instanceof Array) && !(v instanceof Date); + } + function processResponse(responseRaw, customErrorList) { + if (responseRaw.length < 2) { + throw responseError_1$1.ResponseError.fromReturnCode(consts_1$1.LedgerError.EmptyBuffer); + } + const returnCode = responseRaw.readUInt16BE(responseRaw.length - 2); + let errorMessage = (0, errors_1.errorCodeToString)(returnCode, customErrorList); + const payload = responseRaw.subarray(0, responseRaw.length - 2); + if (returnCode === consts_1$1.LedgerError.NoErrors) { + return new payload_1.ResponsePayload(payload); + } + if (payload.length > 0) { + const payloadString = payload.toString('utf8'); + if (!payloadString.includes(errorMessage)) { + errorMessage += ` : ${payloadString}`; + } + else { + errorMessage = payloadString; + } + } + throw new responseError_1$1.ResponseError(returnCode, errorMessage); + } + function processErrorResponse(response, customErrorList) { + if (isDict(response)) { + if (Object.prototype.hasOwnProperty.call(response, 'statusCode')) { + return responseError_1$1.ResponseError.fromReturnCode(response.statusCode, customErrorList); + } + if (Object.prototype.hasOwnProperty.call(response, 'returnCode') && Object.prototype.hasOwnProperty.call(response, 'errorMessage')) { + return response; + } + } + return responseError_1$1.ResponseError.fromReturnCode(consts_1$1.LedgerError.UnknownTransportError); + } + + Object.defineProperty(app, "__esModule", { value: true }); + const bip32_1 = bip32; + const common_1$1 = common; + const consts_1 = consts; + const responseError_1 = responseError; + class BaseApp { + constructor(transport, params) { + if (transport == null) { + throw new Error('Transport has not been defined'); + } + this.transport = transport; + this.CLA = params.cla; + this.INS = params.ins; + this.P1_VALUES = params.p1Values; + this.CHUNK_SIZE = params.chunkSize; + this.REQUIRED_PATH_LENGTHS = params.acceptedPathLengths; + this.CUSTOM_APP_ERROR_DESCRIPTION = params.customAppErrorDescription; + } + serializePath(path) { + return (0, bip32_1.serializePath)(path, this.REQUIRED_PATH_LENGTHS); + } + prepareChunks(path, message) { + const serializedPathBuffer = this.serializePath(path); + const chunks = this.messageToChunks(message); + chunks.unshift(serializedPathBuffer); + return chunks; + } + messageToChunks(message) { + const chunks = []; + const messageBuffer = Buffer.from(message); + for (let i = 0; i < messageBuffer.length; i += this.CHUNK_SIZE) { + const end = Math.min(i + this.CHUNK_SIZE, messageBuffer.length); + chunks.push(messageBuffer.subarray(i, end)); + } + return chunks; + } + async sendGenericChunk(ins, p2, chunkIdx, chunkNum, chunk) { + let payloadType = consts_1.PAYLOAD_TYPE.ADD; + if (chunkIdx === 1) { + payloadType = consts_1.PAYLOAD_TYPE.INIT; + } + if (chunkIdx === chunkNum) { + payloadType = consts_1.PAYLOAD_TYPE.LAST; + } + const statusList = [consts_1.LedgerError.NoErrors, consts_1.LedgerError.DataIsInvalid, consts_1.LedgerError.BadKeyHandle]; + try { + const responseBuffer = await this.transport.send(this.CLA, ins, payloadType, p2, chunk, statusList); + return (0, common_1$1.processResponse)(responseBuffer, this.CUSTOM_APP_ERROR_DESCRIPTION); + } + catch (e) { + const statusCode = e.statusCode || e.returnCode || consts_1.LedgerError.UnknownTransportError; + const message = e.message; + let buffer; + if (message?.length > 0) { + const messageBytes = Buffer.from(message, 'utf8'); + buffer = Buffer.concat([messageBytes, Buffer.allocUnsafe(2)]); + buffer.writeUInt16BE(statusCode, buffer.length - 2); + } + else { + buffer = Buffer.allocUnsafe(2); + buffer.writeUInt16BE(statusCode, 0); + } + return (0, common_1$1.processResponse)(buffer, this.CUSTOM_APP_ERROR_DESCRIPTION); + } + } + async signSendChunk(ins, chunkIdx, chunkNum, chunk) { + return this.sendGenericChunk(ins, 0, chunkIdx, chunkNum, chunk); + } + async getVersion() { + try { + const responseBuffer = await this.transport.send(this.CLA, this.INS.GET_VERSION, 0, 0); + const response = (0, common_1$1.processResponse)(responseBuffer, this.CUSTOM_APP_ERROR_DESCRIPTION); + let testMode; + let major, minor, patch; + if (response.length() === 5 || response.length() === 9) { + testMode = response.readBytes(1).readUInt8() !== 0; + major = response.readBytes(1).readUInt8(); + minor = response.readBytes(1).readUInt8(); + patch = response.readBytes(1).readUInt8(); + } + else if (response.length() === 8 || response.length() === 12) { + testMode = response.readBytes(1).readUInt8() !== 0; + major = response.readBytes(2).readUInt16BE(); + minor = response.readBytes(2).readUInt16BE(); + patch = response.readBytes(2).readUInt16BE(); + } + else if (response.length() === 14 || response.length() === 18) { + testMode = response.readBytes(1).readUInt8() !== 0; + major = response.readBytes(4).readUInt32BE(); + minor = response.readBytes(4).readUInt32BE(); + patch = response.readBytes(4).readUInt32BE(); + } + else { + throw new responseError_1.ResponseError(consts_1.LedgerError.TechnicalProblem, 'Invalid response length'); + } + const deviceLocked = response.readBytes(1).readUInt8() === 1; + let targetId = ''; + if (response.length() >= 4) { + targetId = response.readBytes(4).readUInt32BE().toString(16).padStart(8, '0'); + } + return { + testMode, + major, + minor, + patch, + deviceLocked, + targetId, + }; + } + catch (error) { + throw (0, common_1$1.processErrorResponse)(error); + } + } + async appInfo() { + try { + const responseBuffer = await this.transport.send(consts_1.LEDGER_DASHBOARD_CLA, 0x01, 0, 0); + const response = (0, common_1$1.processResponse)(responseBuffer, this.CUSTOM_APP_ERROR_DESCRIPTION); + const formatId = response.readBytes(1).readUInt8(); + if (formatId !== 1) { + throw new responseError_1.ResponseError(consts_1.LedgerError.TechnicalProblem, 'Format ID not recognized'); + } + const appNameLen = response.readBytes(1).readUInt8(); + const appName = response.readBytes(appNameLen).toString('ascii'); + const appVersionLen = response.readBytes(1).readUInt8(); + const appVersion = response.readBytes(appVersionLen).toString('ascii'); + const flagLen = response.readBytes(1).readUInt8(); + const flagsValue = response.readBytes(flagLen).readUInt8(); + return { + appName, + appVersion, + flagLen, + flagsValue, + flagRecovery: (flagsValue & 1) !== 0, + flagSignedMcuCode: (flagsValue & 2) !== 0, + flagOnboarded: (flagsValue & 4) !== 0, + flagPINValidated: (flagsValue & 128) !== 0, + }; + } + catch (error) { + throw (0, common_1$1.processErrorResponse)(error); + } + } + async deviceInfo() { + try { + const responseBuffer = await this.transport.send(0xe0, 0x01, 0, 0, Buffer.from([]), [consts_1.LedgerError.NoErrors, 0x6e00]); + const response = (0, common_1$1.processResponse)(responseBuffer, this.CUSTOM_APP_ERROR_DESCRIPTION); + const targetId = response.readBytes(4).toString('hex'); + const secureElementVersionLen = response.readBytes(1).readUInt8(); + const seVersion = response.readBytes(secureElementVersionLen).toString(); + const flagsLen = response.readBytes(1).readUInt8(); + const flag = response.readBytes(flagsLen).toString('hex'); + const mcuVersionLen = response.readBytes(1).readUInt8(); + let tmp = response.readBytes(mcuVersionLen); + const firstZeroIndex = tmp.indexOf(0); + if (firstZeroIndex !== -1) { + tmp = tmp.subarray(0, firstZeroIndex); + } + const mcuVersion = tmp.toString(); + return { + targetId, + seVersion, + flag, + mcuVersion, + }; + } + catch (error) { + throw (0, common_1$1.processErrorResponse)(error); + } + } + } + app.default = BaseApp; + + var types = {}; + + Object.defineProperty(types, "__esModule", { value: true }); + + (function (exports$1) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports$1) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$1, p)) __createBinding(exports$1, m, p); + }; + var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; + }; + Object.defineProperty(exports$1, "__esModule", { value: true }); + const app_1 = __importDefault(app); + exports$1.default = app_1.default; + __exportStar(common, exports$1); + __exportStar(consts, exports$1); + __exportStar(types, exports$1); + __exportStar(bip32, exports$1); + __exportStar(responseError, exports$1); + __exportStar(payload, exports$1); + } (dist)); + getDefaultExportFromCjs(dist); + + var __createBinding$1 = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault$1 = (commonjsGlobal && commonjsGlobal.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar$1 = (commonjsGlobal && commonjsGlobal.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding$1(result, mod, k[i]); + __setModuleDefault$1(result, mod); + return result; + }; + })(); + var __importDefault$1 = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; + }; + Object.defineProperty(generic_app, "__esModule", { value: true }); + generic_app.PolkadotGenericApp = void 0; + const axios_1 = __importDefault$1(axios_1$1); + const ledger_js_1$1 = __importStar$1(dist); + const common_1 = common$1; + class PolkadotGenericApp extends ledger_js_1$1.default { + constructor(transport, txMetadataChainId, txMetadataSrvUrl) { + super(transport, PolkadotGenericApp._params); + this.txMetadataSrvUrl = txMetadataSrvUrl; + this.txMetadataChainId = txMetadataChainId; + if (!this.transport) { + throw new Error('Transport has not been defined'); + } + } + async getTxMetadata(txBlob, txMetadataChainId, txMetadataSrvUrl) { + const txMetadataChainIdVal = txMetadataChainId ?? this.txMetadataChainId; + const txMetadataSrvUrlVal = txMetadataSrvUrl ?? this.txMetadataSrvUrl; + if (!txMetadataChainIdVal) { + throw new ledger_js_1$1.ResponseError(ledger_js_1$1.LedgerError.GenericError, 'txMetadataSrvUrl is not defined or is empty. The use of the method requires access to a metadata shortening service.'); + } + if (!txMetadataSrvUrlVal) { + throw new ledger_js_1$1.ResponseError(ledger_js_1$1.LedgerError.GenericError, 'txMetadataChainId is not defined or is empty. These values are configured in the metadata shortening service. Check the corresponding configuration in the service.'); + } + const resp = await axios_1.default.post(txMetadataSrvUrlVal, { + txBlob: txBlob.toString('hex'), + chain: { id: txMetadataChainIdVal }, + }); + let txMetadata = resp.data.txMetadata; + if (txMetadata.slice(0, 2) === '0x') { + txMetadata = txMetadata.slice(2); + } + return Buffer.from(txMetadata, 'hex'); + } + async getAddress(bip44Path, ss58prefix, showAddrInDevice = false, scheme = 0 ) { + if (!Number.isInteger(ss58prefix) || ss58prefix < 0 || ss58prefix >> 16 !== 0) { + throw new ledger_js_1$1.ResponseError(ledger_js_1$1.LedgerError.ConditionsOfUseNotSatisfied, `Unexpected ss58prefix ${ss58prefix}. Needs to be a non-negative integer up to 2^16`); + } + if (scheme != 2 && scheme != 0 ) { + throw new ledger_js_1$1.ResponseError(ledger_js_1$1.LedgerError.ConditionsOfUseNotSatisfied, `Unexpected scheme ${scheme}. Needs to be ECDSA (2) or ED25519 (0)`); + } + const bip44PathBuffer = this.serializePath(bip44Path); + const prefixBuffer = Buffer.alloc(2); + prefixBuffer.writeUInt16LE(ss58prefix); + let payload = bip44PathBuffer; + if (scheme === 0 ) { + payload = Buffer.concat([payload, prefixBuffer]); + } + const p1 = showAddrInDevice ? 1 : 0 ; + try { + const responseBuffer = await this.transport.send(this.CLA, this.INS.GET_ADDR, p1, scheme ?? 0 , payload); + const response = (0, ledger_js_1$1.processResponse)(responseBuffer); + const currentScheme = (scheme ?? 0 ); + const pubKeyLen = currentScheme === 2 ? common_1.ECDSA_PUBKEY_LEN : common_1.ED25519_PUBKEY_LEN; + const pubKey = response.readBytes(pubKeyLen).toString('hex'); + let address = ''; + if (currentScheme === 2 ) { + address = response.readBytes(response.length()).toString('hex'); + } + else { + address = response.readBytes(response.length()).toString('ascii'); + } + return { + pubKey, + address, + }; + } + catch (e) { + throw (0, ledger_js_1$1.processErrorResponse)(e); + } + } + async getAddressEcdsa(bip44Path, showAddrInDevice = false) { + return this.getAddress(bip44Path, 0, showAddrInDevice, 2 ); + } + async getAddressEd25519(bip44Path, ss58prefix, showAddrInDevice = false) { + return this.getAddress(bip44Path, ss58prefix, showAddrInDevice); + } + splitBufferToChunks(message, chunkSize) { + const chunks = []; + const buffer = Buffer.from(message); + for (let i = 0; i < buffer.length; i += chunkSize) { + let end = i + chunkSize; + if (i > buffer.length) { + end = buffer.length; + } + chunks.push(buffer.subarray(i, end)); + } + return chunks; + } + getSignReqChunks(path, txBlob, metadata) { + const chunks = []; + const bip44Path = this.serializePath(path); + const blobLen = Buffer.alloc(2); + blobLen.writeUInt16LE(txBlob.length); + chunks.push(Buffer.concat([bip44Path, blobLen])); + if (metadata == null) { + chunks.push(...this.splitBufferToChunks(txBlob, this.CHUNK_SIZE)); + } + else { + chunks.push(...this.splitBufferToChunks(Buffer.concat([txBlob, metadata]), this.CHUNK_SIZE)); + } + return chunks; + } + async signImplEd25519(path, ins, blob, metadata) { + const chunks = this.getSignReqChunks(path, blob, metadata); + try { + let result = await this.sendGenericChunk(ins, 0 , 1, chunks.length, chunks[0]); + for (let i = 1; i < chunks.length; i += 1) { + result = await this.sendGenericChunk(ins, 0 , 1 + i, chunks.length, chunks[i]); + } + return { + signature: result.readBytes(result.length()), + }; + } + catch (e) { + throw (0, ledger_js_1$1.processErrorResponse)(e); + } + } + async signImplEcdsa(path, ins, blob, metadata) { + const chunks = this.getSignReqChunks(path, blob, metadata); + try { + let result = await this.sendGenericChunk(ins, 2 , 1, chunks.length, chunks[0]); + for (let i = 1; i < chunks.length; i += 1) { + result = await this.sendGenericChunk(ins, 2 , 1 + i, chunks.length, chunks[i]); + } + return { + r: result.readBytes(32), + s: result.readBytes(32), + v: result.readBytes(1), + }; + } + catch (e) { + throw (0, ledger_js_1$1.processErrorResponse)(e); + } + } + async sign(path, txBlob, scheme = 0 ) { + if (scheme != 2 && scheme != 0 ) { + throw new ledger_js_1$1.ResponseError(ledger_js_1$1.LedgerError.ConditionsOfUseNotSatisfied, `Unexpected scheme ${scheme}. Needs to be ECDSA (2) or ED25519 (0)`); + } + if (scheme === 2 ) { + return await this.signEcdsa(path, txBlob); + } + return await this.signEd25519(path, txBlob); + } + async signEd25519(path, txBlob) { + if (!this.txMetadataSrvUrl) { + throw new ledger_js_1$1.ResponseError(ledger_js_1$1.LedgerError.GenericError, 'txMetadataSrvUrl is not defined or is empty. The use of the method requires access to a metadata shortening service.'); + } + if (!this.txMetadataChainId) { + throw new ledger_js_1$1.ResponseError(ledger_js_1$1.LedgerError.GenericError, 'txMetadataChainId is not defined or is empty. These values are configured in the metadata shortening service. Check the corresponding configuration in the service.'); + } + const txMetadata = await this.getTxMetadata(txBlob); + return await this.signImplEd25519(path, this.INS.SIGN, txBlob, txMetadata); + } + async signEcdsa(path, txBlob) { + if (!this.txMetadataSrvUrl) { + throw new ledger_js_1$1.ResponseError(ledger_js_1$1.LedgerError.GenericError, 'txMetadataSrvUrl is not defined or is empty. The use of the method requires access to a metadata shortening service.'); + } + if (!this.txMetadataChainId) { + throw new ledger_js_1$1.ResponseError(ledger_js_1$1.LedgerError.GenericError, 'txMetadataChainId is not defined or is empty. These values are configured in the metadata shortening service. Check the corresponding configuration in the service.'); + } + const txMetadata = await this.getTxMetadata(txBlob); + return await this.signImplEcdsa(path, this.INS.SIGN, txBlob, txMetadata); + } + async signMigration(path, txBlob, txMetadataChainId, txMetadataSrvUrl) { + if (!this.txMetadataSrvUrl) { + throw new ledger_js_1$1.ResponseError(ledger_js_1$1.LedgerError.GenericError, 'txMetadataSrvUrl is not defined or is empty. The use of the method requires access to a metadata shortening service.'); + } + if (!this.txMetadataChainId) { + throw new ledger_js_1$1.ResponseError(ledger_js_1$1.LedgerError.GenericError, 'txMetadataChainId is not defined or is empty. These values are configured in the metadata shortening service. Check the corresponding configuration in the service.'); + } + const txMetadata = await this.getTxMetadata(txBlob, txMetadataChainId, txMetadataSrvUrl); + return await this.signImplEd25519(path, this.INS.SIGN, txBlob, txMetadata); + } + async signRaw(path, txBlob, scheme = 0 ) { + if (scheme != 2 && scheme != 0 ) { + throw new ledger_js_1$1.ResponseError(ledger_js_1$1.LedgerError.ConditionsOfUseNotSatisfied, `Unexpected scheme ${scheme}. Needs to be ECDSA (2) or ED25519 (0)`); + } + if (scheme === 2 ) { + return await this.signRawEcdsa(path, txBlob); + } + return await this.signRawEd25519(path, txBlob); + } + async signRawEd25519(path, txBlob) { + return await this.signImplEd25519(path, this.INS.SIGN_RAW, txBlob); + } + async signRawEcdsa(path, txBlob) { + return await this.signImplEcdsa(path, this.INS.SIGN_RAW, txBlob); + } + async signWithMetadata(path, txBlob, txMetadata, scheme) { + if (scheme != 2 && scheme != 0 ) { + throw new ledger_js_1$1.ResponseError(ledger_js_1$1.LedgerError.ConditionsOfUseNotSatisfied, `Unexpected scheme ${scheme}. Needs to be ECDSA (2) or ED25519 (0)`); + } + if (scheme === 2 ) { + return await this.signWithMetadataEcdsa(path, txBlob, txMetadata); + } + return await this.signWithMetadataEd25519(path, txBlob, txMetadata); + } + async signWithMetadataEcdsa(path, txBlob, txMetadata) { + return await this.signImplEcdsa(path, this.INS.SIGN, txBlob, txMetadata); + } + async signWithMetadataEd25519(path, txBlob, txMetadata) { + return await this.signImplEd25519(path, this.INS.SIGN, txBlob, txMetadata); + } + } + generic_app.PolkadotGenericApp = PolkadotGenericApp; + PolkadotGenericApp._INS = { + GET_VERSION: 0x00, + GET_ADDR: 0x01, + SIGN: 0x02, + SIGN_RAW: 0x03, + }; + PolkadotGenericApp._params = { + cla: 0xf9, + ins: { ...PolkadotGenericApp._INS }, + p1Values: { ONLY_RETRIEVE: 0x00, SHOW_ADDRESS_IN_DEVICE: 0x01 }, + chunkSize: 250, + requiredPathLengths: [5], + }; + + var generic_legacy = {}; + + Object.defineProperty(generic_legacy, "__esModule", { value: true }); + generic_legacy.PolkadotGenericAppLegacy = void 0; + const ledger_js_1 = dist; + const generic_app_1 = generic_app; + class PolkadotGenericAppLegacy { + constructor(transport, ss58prefix, txMetadataChainId, txMetadataSrvUrl) { + this.genericApp = new generic_app_1.PolkadotGenericApp(transport, txMetadataChainId, txMetadataSrvUrl); + this.ss58prefix = ss58prefix; + } + convertToLegacyError(e) { + return { + error_message: e.errorMessage, + return_code: e.returnCode, + }; + } + convertLegacyPath(account, change, addressIndex) { + return (0, ledger_js_1.numbersToBip32Path)([0x8000002c, 0x80000162, account, change, addressIndex]); + } + async getVersion() { + try { + const version = await this.genericApp.getVersion(); + const legacyError = this.convertToLegacyError(ledger_js_1.ResponseError.fromReturnCode(ledger_js_1.LedgerError.NoErrors)); + return { + ...legacyError, + major: version.major ?? 0, + minor: version.minor ?? 0, + patch: version.patch ?? 0, + device_locked: version.deviceLocked ?? false, + test_mode: version.testMode ?? false, + }; + } + catch (e) { + const legacyError = this.convertToLegacyError(e); + return { + device_locked: false, + major: 0, + minor: 0, + patch: 0, + test_mode: false, + ...legacyError, + }; + } + } + async appInfo() { + try { + const info = await this.genericApp.appInfo(); + const legacyError = this.convertToLegacyError(ledger_js_1.ResponseError.fromReturnCode(ledger_js_1.LedgerError.NoErrors)); + return { + ...legacyError, + ...info, + }; + } + catch (e) { + const legacyError = this.convertToLegacyError(e); + return { + ...legacyError, + }; + } + } + async getAddress(account, change, addressIndex, requireConfirmation, scheme) { + if (scheme !== 0 ) { + throw ledger_js_1.ResponseError.fromReturnCode(ledger_js_1.LedgerError.AlgorithmNotSupported); + } + try { + const bip44Path = this.convertLegacyPath(account, change, addressIndex); + const address = await this.genericApp.getAddress(bip44Path, this.ss58prefix, requireConfirmation); + const legacyError = this.convertToLegacyError(ledger_js_1.ResponseError.fromReturnCode(ledger_js_1.LedgerError.NoErrors)); + return { + ...legacyError, + ...address, + }; + } + catch (e) { + const legacyError = this.convertToLegacyError(e); + return { + address: 'ERROR', + pubKey: 'ERROR', + ...legacyError, + }; + } + } + async sign(account, change, addressIndex, message, scheme) { + try { + if (scheme !== 0 ) { + throw ledger_js_1.ResponseError.fromReturnCode(ledger_js_1.LedgerError.AlgorithmNotSupported); + } + const bip44Path = this.convertLegacyPath(account, change, addressIndex); + const signature = await this.genericApp.signEd25519(bip44Path, message); + const legacyError = this.convertToLegacyError(ledger_js_1.ResponseError.fromReturnCode(ledger_js_1.LedgerError.NoErrors)); + return { + ...legacyError, + ...signature, + }; + } + catch (e) { + const legacyError = this.convertToLegacyError(e); + return { + signature: Buffer.alloc(0), + ...legacyError, + }; + } + } + async signRaw(account, change, addressIndex, message, scheme) { + try { + if (scheme !== 0 ) { + throw ledger_js_1.ResponseError.fromReturnCode(ledger_js_1.LedgerError.AlgorithmNotSupported); + } + const bip44Path = this.convertLegacyPath(account, change, addressIndex); + const signature = await this.genericApp.signRawEd25519(bip44Path, message); + const legacyError = this.convertToLegacyError(ledger_js_1.ResponseError.fromReturnCode(ledger_js_1.LedgerError.NoErrors)); + return { + ...legacyError, + ...signature, + }; + } + catch (e) { + const legacyError = this.convertToLegacyError(e); + return { + signature: Buffer.alloc(0), + ...legacyError, + }; + } + } + } + generic_legacy.PolkadotGenericAppLegacy = PolkadotGenericAppLegacy; + + (function (exports$1) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports$1) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$1, p)) __createBinding(exports$1, m, p); + }; + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.supportedApps = exports$1.newSubstrateApp = exports$1.SubstrateApp = void 0; + __exportStar(legacy_apps, exports$1); + __exportStar(generic_app, exports$1); + __exportStar(generic_legacy, exports$1); + var substrate_app_1 = substrate_app; + Object.defineProperty(exports$1, "SubstrateApp", { enumerable: true, get: function () { return substrate_app_1.SubstrateApp; } }); + var supported_apps_1 = supported_apps; + Object.defineProperty(exports$1, "newSubstrateApp", { enumerable: true, get: function () { return supported_apps_1.newSubstrateApp; } }); + Object.defineProperty(exports$1, "supportedApps", { enumerable: true, get: function () { return supported_apps_1.supportedApps; } }); + } (dist$1)); + getDefaultExportFromCjs(dist$1); + + var browser = {}; + + var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + function __extends(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + } + function __param(paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } + } + function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; + }function __runInitializers(thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; + }function __propKey(x) { + return typeof x === "symbol" ? x : "".concat(x); + }function __setFunctionName(f, name, prefix) { + if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; + return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); + }function __metadata(metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); + } + function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + } + function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); + return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } + } + var __createBinding = Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + }); + function __exportStar(m, o) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); + } + function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + } + function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; + } + function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; + } + function __spreadArrays() { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; + } + function __spreadArray(to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); + } + function __await(v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); + } + function __asyncGenerator(thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; + function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; } + function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } + } + function __asyncDelegator(o) { + var i, p; + return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; + function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; } + } + function __asyncValues(o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } + } + function __makeTemplateObject(cooked, raw) { + if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } + return cooked; + }var __setModuleDefault = Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }; + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + function __importStar(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + } + function __importDefault(mod) { + return (mod && mod.__esModule) ? mod : { default: mod }; + } + function __classPrivateFieldGet(receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); + } + function __classPrivateFieldSet(receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; + } + function __classPrivateFieldIn(state, receiver) { + if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); + return typeof state === "function" ? receiver === state : state.has(receiver); + } + function __addDisposableResource(env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose, inner; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + if (async) inner = dispose; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } }; + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; + } + var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; + }; + function __disposeResources(env) { + function fail(e) { + env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + var r, s = 0; + function next() { + while (r = env.stack.pop()) { + try { + if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next); + if (r.dispose) { + var result = r.dispose.call(r.value); + if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + else s |= 1; + } + catch (e) { + fail(e); + } + } + if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve(); + if (env.hasError) throw env.error; + } + return next(); + } + function __rewriteRelativeImportExtension(path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); + } + return path; + } + const tslib_es6 = { + __extends, + __assign, + __rest, + __decorate, + __param, + __esDecorate, + __runInitializers, + __propKey, + __setFunctionName, + __metadata, + __awaiter, + __generator, + __createBinding, + __exportStar, + __values, + __read, + __spread, + __spreadArrays, + __spreadArray, + __await, + __asyncGenerator, + __asyncDelegator, + __asyncValues, + __makeTemplateObject, + __importStar, + __importDefault, + __classPrivateFieldGet, + __classPrivateFieldSet, + __classPrivateFieldIn, + __addDisposableResource, + __disposeResources, + __rewriteRelativeImportExtension, + }; + + const tslib_es6$1 = /*#__PURE__*/Object.freeze({ + __proto__: null, + __addDisposableResource: __addDisposableResource, + get __assign () { return __assign; }, + __asyncDelegator: __asyncDelegator, + __asyncGenerator: __asyncGenerator, + __asyncValues: __asyncValues, + __await: __await, + __awaiter: __awaiter, + __classPrivateFieldGet: __classPrivateFieldGet, + __classPrivateFieldIn: __classPrivateFieldIn, + __classPrivateFieldSet: __classPrivateFieldSet, + __createBinding: __createBinding, + __decorate: __decorate, + __disposeResources: __disposeResources, + __esDecorate: __esDecorate, + __exportStar: __exportStar, + __extends: __extends, + __generator: __generator, + __importDefault: __importDefault, + __importStar: __importStar, + __makeTemplateObject: __makeTemplateObject, + __metadata: __metadata, + __param: __param, + __propKey: __propKey, + __read: __read, + __rest: __rest, + __rewriteRelativeImportExtension: __rewriteRelativeImportExtension, + __runInitializers: __runInitializers, + __setFunctionName: __setFunctionName, + __spread: __spread, + __spreadArray: __spreadArray, + __spreadArrays: __spreadArrays, + __values: __values, + default: tslib_es6 + }); + + const require$$0 = /*@__PURE__*/getAugmentedNamespace(tslib_es6$1); + + const EventEmitter = {}; + + const errorClasses = {}; + const deserializers = {}; + const addCustomErrorDeserializer = (name, deserializer) => { + deserializers[name] = deserializer; + }; + const createCustomErrorClass = (name) => { + class CustomErrorClass extends Error { + cause; + constructor(message, fields, options) { + super(message || name, options); + Object.setPrototypeOf(this, CustomErrorClass.prototype); + this.name = name; + if (fields) { + for (const k in fields) { + this[k] = fields[k]; + } + } + if (options && isObject(options) && "cause" in options && !this.cause) { + const cause = options.cause; + this.cause = cause; + if ("stack" in cause) { + this.stack = this.stack + "\nCAUSE: " + cause.stack; + } + } + } + } + errorClasses[name] = CustomErrorClass; + return CustomErrorClass; + }; + function isObject(value) { + return typeof value === "object"; + } + + createCustomErrorClass("AccountNameRequired"); + createCustomErrorClass("AccountNotSupported"); + createCustomErrorClass("AccountAwaitingSendPendingOperations"); + createCustomErrorClass("AmountRequired"); + createCustomErrorClass("BluetoothRequired"); + createCustomErrorClass("BtcUnmatchedApp"); + createCustomErrorClass("CantOpenDevice"); + createCustomErrorClass("CashAddrNotSupported"); + createCustomErrorClass("ClaimRewardsFeesWarning"); + createCustomErrorClass("CurrencyNotSupported"); + createCustomErrorClass("DeviceAppVerifyNotSupported"); + createCustomErrorClass("DeviceGenuineSocketEarlyClose"); + createCustomErrorClass("DeviceNotGenuine"); + createCustomErrorClass("DeviceOnDashboardExpected"); + createCustomErrorClass("DeviceOnDashboardUnexpected"); + createCustomErrorClass("DeviceInOSUExpected"); + createCustomErrorClass("DeviceHalted"); + createCustomErrorClass("DeviceNameInvalid"); + createCustomErrorClass("DeviceSocketFail"); + createCustomErrorClass("DeviceSocketNoBulkStatus"); + createCustomErrorClass("DeviceSocketNoBulkStatus"); + createCustomErrorClass("UnresponsiveDeviceError"); + const DisconnectedDevice = createCustomErrorClass("DisconnectedDevice"); + const DisconnectedDeviceDuringOperation = createCustomErrorClass("DisconnectedDeviceDuringOperation"); + createCustomErrorClass("DeviceExtractOnboardingStateError"); + createCustomErrorClass("DeviceOnboardingStatePollingError"); + createCustomErrorClass("EnpointConfig"); + createCustomErrorClass("EthAppPleaseEnableContractData"); + createCustomErrorClass("SolAppPleaseEnableContractData"); + createCustomErrorClass("CeloAppPleaseEnableContractData"); + createCustomErrorClass("FeeEstimationFailed"); + createCustomErrorClass("FirmwareNotRecognized"); + createCustomErrorClass("HardResetFail"); + createCustomErrorClass("InvalidXRPTag"); + createCustomErrorClass("InvalidAddress"); + createCustomErrorClass("InvalidNonce"); + createCustomErrorClass("InvalidAddressBecauseDestinationIsAlsoSource"); + createCustomErrorClass("LatestMCUInstalledError"); + createCustomErrorClass("LatestFirmwareVersionRequired"); + createCustomErrorClass("UnsupportedFeatureError"); + createCustomErrorClass("NanoSNotSupported"); + createCustomErrorClass("UnknownMCU"); + createCustomErrorClass("LedgerAPIError"); + createCustomErrorClass("LedgerAPIErrorWithMessage"); + createCustomErrorClass("LedgerAPINotAvailable"); + createCustomErrorClass("ManagerAppAlreadyInstalled"); + createCustomErrorClass("ManagerAppRelyOnBTC"); + createCustomErrorClass("ManagerAppDepInstallRequired"); + createCustomErrorClass("ManagerAppDepUninstallRequired"); + createCustomErrorClass("ManagerDeviceLocked"); + createCustomErrorClass("ManagerFirmwareNotEnoughSpace"); + createCustomErrorClass("ManagerNotEnoughSpace"); + createCustomErrorClass("ManagerUninstallBTCDep"); + createCustomErrorClass("NetworkDown"); + createCustomErrorClass("NetworkError"); + createCustomErrorClass("NoAddressesFound"); + createCustomErrorClass("NotEnoughBalance"); + createCustomErrorClass("NotEnoughBalanceFees"); + createCustomErrorClass("NotEnoughBalanceSwap"); + createCustomErrorClass("NotEnoughBalanceToDelegate"); + createCustomErrorClass("UnstakeNotEnoughStakedBalanceLeft"); + createCustomErrorClass("RestakeNotEnoughStakedBalanceLeft"); + createCustomErrorClass("NotEnoughToRestake"); + createCustomErrorClass("NotEnoughToUnstake"); + createCustomErrorClass("NotEnoughBalanceInParentAccount"); + createCustomErrorClass("NotEnoughSpendableBalance"); + createCustomErrorClass("NotEnoughBalanceBecauseDestinationNotCreated"); + createCustomErrorClass("NotEnoughToStake"); + createCustomErrorClass("NoAccessToCamera"); + createCustomErrorClass("NotEnoughGas"); + createCustomErrorClass("NotEnoughGasSwap"); + createCustomErrorClass("TronEmptyAccount"); + createCustomErrorClass("MaybeKeepTronAccountAlive"); + createCustomErrorClass("NotSupportedLegacyAddress"); + createCustomErrorClass("GasLessThanEstimate"); + createCustomErrorClass("PriorityFeeTooLow"); + createCustomErrorClass("PriorityFeeTooHigh"); + createCustomErrorClass("PriorityFeeHigherThanMaxFee"); + createCustomErrorClass("MaxFeeTooLow"); + createCustomErrorClass("PasswordsDontMatch"); + createCustomErrorClass("PasswordIncorrect"); + createCustomErrorClass("RecommendSubAccountsToEmpty"); + createCustomErrorClass("RecommendUndelegation"); + createCustomErrorClass("TimeoutTagged"); + createCustomErrorClass("UnexpectedBootloader"); + createCustomErrorClass("MCUNotGenuineToDashboard"); + createCustomErrorClass("RecipientRequired"); + createCustomErrorClass("UnavailableTezosOriginatedAccountReceive"); + createCustomErrorClass("UnavailableTezosOriginatedAccountSend"); + createCustomErrorClass("UpdateFetchFileFail"); + createCustomErrorClass("UpdateIncorrectHash"); + createCustomErrorClass("UpdateIncorrectSig"); + createCustomErrorClass("UpdateYourApp"); + createCustomErrorClass("UserRefusedDeviceNameChange"); + createCustomErrorClass("UserRefusedAddress"); + createCustomErrorClass("UserRefusedFirmwareUpdate"); + createCustomErrorClass("UserRefusedAllowManager"); + createCustomErrorClass("UserRefusedOnDevice"); + createCustomErrorClass("PinNotSet"); + createCustomErrorClass("ExpertModeRequired"); + const TransportOpenUserCancelled = createCustomErrorClass("TransportOpenUserCancelled"); + const TransportInterfaceNotAvailable = createCustomErrorClass("TransportInterfaceNotAvailable"); + const TransportRaceCondition = createCustomErrorClass("TransportRaceCondition"); + const TransportWebUSBGestureRequired = createCustomErrorClass("TransportWebUSBGestureRequired"); + createCustomErrorClass("TransactionHasBeenValidatedError"); + createCustomErrorClass("TransportExchangeTimeoutError"); + createCustomErrorClass("DeviceShouldStayInApp"); + createCustomErrorClass("WebsocketConnectionError"); + createCustomErrorClass("WebsocketConnectionFailed"); + createCustomErrorClass("WrongDeviceForAccount"); + createCustomErrorClass("WrongDeviceForAccountPayout"); + createCustomErrorClass("MissingSwapPayloadParamaters"); + createCustomErrorClass("WrongDeviceForAccountRefund"); + createCustomErrorClass("WrongAppForCurrency"); + createCustomErrorClass("ETHAddressNonEIP"); + createCustomErrorClass("CantScanQRCode"); + createCustomErrorClass("FeeNotLoaded"); + createCustomErrorClass("FeeNotLoadedSwap"); + createCustomErrorClass("FeeRequired"); + createCustomErrorClass("FeeTooHigh"); + createCustomErrorClass("PendingOperation"); + createCustomErrorClass("SyncError"); + createCustomErrorClass("PairingFailed"); + createCustomErrorClass("PeerRemovedPairing"); + createCustomErrorClass("GenuineCheckFailed"); + createCustomErrorClass("LedgerAPI4xx"); + createCustomErrorClass("LedgerAPI5xx"); + createCustomErrorClass("FirmwareOrAppUpdateRequired"); + createCustomErrorClass("ReplacementTransactionUnderpriced"); + createCustomErrorClass("OpReturnSizeLimit"); + createCustomErrorClass("DustLimit"); + createCustomErrorClass("LanguageNotFound"); + createCustomErrorClass("NoDBPathGiven"); + createCustomErrorClass("DBWrongPassword"); + createCustomErrorClass("DBNotReset"); + createCustomErrorClass("SequenceNumberError"); + createCustomErrorClass("DisabledTransactionBroadcastError"); + var HwTransportErrorType; + (function (HwTransportErrorType) { + HwTransportErrorType["Unknown"] = "Unknown"; + HwTransportErrorType["LocationServicesDisabled"] = "LocationServicesDisabled"; + HwTransportErrorType["LocationServicesUnauthorized"] = "LocationServicesUnauthorized"; + HwTransportErrorType["BluetoothScanStartFailed"] = "BluetoothScanStartFailed"; + })(HwTransportErrorType || (HwTransportErrorType = {})); + class TransportError extends Error { + id; + constructor(message, id) { + const name = "TransportError"; + super(message || name); + this.name = name; + this.message = message; + this.stack = new Error(message).stack; + this.id = id; + } + } + addCustomErrorDeserializer("TransportError", e => new TransportError(e.message, e.id)); + const StatusCodes = { + ACCESS_CONDITION_NOT_FULFILLED: 0x9804, + ALGORITHM_NOT_SUPPORTED: 0x9484, + CLA_NOT_SUPPORTED: 0x6e00, + CODE_BLOCKED: 0x9840, + CODE_NOT_INITIALIZED: 0x9802, + COMMAND_INCOMPATIBLE_FILE_STRUCTURE: 0x6981, + CONDITIONS_OF_USE_NOT_SATISFIED: 0x6985, + CONTRADICTION_INVALIDATION: 0x9810, + CONTRADICTION_SECRET_CODE_STATUS: 0x9808, + DEVICE_IN_RECOVERY_MODE: 0x662f, + CUSTOM_IMAGE_EMPTY: 0x662e, + FILE_ALREADY_EXISTS: 0x6a89, + FILE_NOT_FOUND: 0x9404, + GP_AUTH_FAILED: 0x6300, + HALTED: 0x6faa, + INCONSISTENT_FILE: 0x9408, + INCORRECT_DATA: 0x6a80, + INCORRECT_LENGTH: 0x6700, + INCORRECT_P1_P2: 0x6b00, + INS_NOT_SUPPORTED: 0x6d00, + DEVICE_NOT_ONBOARDED: 0x6d07, + DEVICE_NOT_ONBOARDED_2: 0x6611, + INVALID_KCV: 0x9485, + INVALID_OFFSET: 0x9402, + LICENSING: 0x6f42, + LOCKED_DEVICE: 0x5515, + MAX_VALUE_REACHED: 0x9850, + MEMORY_PROBLEM: 0x9240, + MISSING_CRITICAL_PARAMETER: 0x6800, + NO_EF_SELECTED: 0x9400, + NOT_ENOUGH_MEMORY_SPACE: 0x6a84, + OK: 0x9000, + PIN_REMAINING_ATTEMPTS: 0x63c0, + REFERENCED_DATA_NOT_FOUND: 0x6a88, + SECURITY_STATUS_NOT_SATISFIED: 0x6982, + TECHNICAL_PROBLEM: 0x6f00, + UNKNOWN_APDU: 0x6d02, + USER_REFUSED_ON_DEVICE: 0x5501, + NOT_ENOUGH_SPACE: 0x5102, + APP_NOT_FOUND_OR_INVALID_CONTEXT: 0x5123, + INVALID_APP_NAME_LENGTH: 0x670a, + GEN_AES_KEY_FAILED: 0x5419, + INTERNAL_CRYPTO_OPERATION_FAILED: 0x541a, + INTERNAL_COMPUTE_AES_CMAC_FAILED: 0x541b, + ENCRYPT_APP_STORAGE_FAILED: 0x541c, + INVALID_BACKUP_STATE: 0x6642, + PIN_NOT_SET: 0x5502, + INVALID_BACKUP_LENGTH: 0x6733, + INVALID_RESTORE_STATE: 0x6643, + INVALID_CHUNK_LENGTH: 0x6734, + INVALID_BACKUP_HEADER: 0x684a, + TRUSTCHAIN_WRONG_SEED: 0xb007, + }; + function getAltStatusMessage(code) { + switch (code) { + case 0x6700: + return "Incorrect length"; + case 0x6800: + return "Missing critical parameter"; + case 0x6982: + return "Security not satisfied (dongle locked or have invalid access rights)"; + case 0x6985: + return "Condition of use not satisfied (denied by the user?)"; + case 0x6a80: + return "Invalid data received"; + case 0x6b00: + return "Invalid parameter received"; + case 0x5515: + return "Locked device"; + } + if (0x6f00 <= code && code <= 0x6fff) { + return "Internal error, please report"; + } + } + class TransportStatusError extends Error { + statusCode; + statusText; + constructor(statusCode, { canBeMappedToChildError = true } = {}) { + const statusText = Object.keys(StatusCodes).find(k => StatusCodes[k] === statusCode) || "UNKNOWN_ERROR"; + const smsg = getAltStatusMessage(statusCode) || statusText; + const statusCodeStr = statusCode.toString(16); + const message = `Ledger device: ${smsg} (0x${statusCodeStr})`; + super(message); + this.name = "TransportStatusError"; + this.statusCode = statusCode; + this.statusText = statusText; + Object.setPrototypeOf(this, TransportStatusError.prototype); + if (canBeMappedToChildError && statusCode === StatusCodes.LOCKED_DEVICE) { + return new LockedDeviceError(message); + } + } + } + class LockedDeviceError extends TransportStatusError { + constructor(message) { + super(StatusCodes.LOCKED_DEVICE, { canBeMappedToChildError: false }); + if (message) { + this.message = message; + } + this.name = "LockedDeviceError"; + Object.setPrototypeOf(this, LockedDeviceError.prototype); + } + } + addCustomErrorDeserializer("TransportStatusError", e => new TransportStatusError(e.statusCode)); + + let id = 0; + const subscribers = []; + const log = (type, message, data) => { + const obj = { + type, + id: String(++id), + date: new Date(), + }; + if (message) + obj.message = message; + dispatch(obj); + }; + const trace = ({ type, message, data, context, }) => { + const obj = { + type, + id: String(++id), + date: new Date(), + }; + if (message) + obj.message = message; + if (data) + obj.data = data; + if (context) + obj.context = context; + dispatch(obj); + }; + class LocalTracer { + type; + context; + constructor(type, context) { + this.type = type; + this.context = context; + } + trace(message, data) { + trace({ + type: this.type, + message, + data, + context: this.context, + }); + } + getContext() { + return this.context; + } + setContext(context) { + this.context = context; + } + updateContext(contextToAdd) { + this.context = { ...this.context, ...contextToAdd }; + } + getType() { + return this.type; + } + setType(type) { + this.type = type; + } + withType(type) { + return new LocalTracer(type, this.context); + } + withContext(context) { + return new LocalTracer(this.type, context); + } + withUpdatedContext(contextToAdd) { + return new LocalTracer(this.type, { ...this.context, ...contextToAdd }); + } + } + const listen = (cb) => { + subscribers.push(cb); + return () => { + const i = subscribers.indexOf(cb); + if (i !== -1) { + subscribers[i] = subscribers[subscribers.length - 1]; + subscribers.pop(); + } + }; + }; + function dispatch(log) { + for (let i = 0; i < subscribers.length; i++) { + try { + subscribers[i](log); + } + catch (e) { + console.error(e); + } + } + } + if (typeof window !== "undefined") { + window.__ledgerLogsListen = listen; + } + + const DEFAULT_LOG_TYPE = "transport"; + class Transport { + exchangeTimeout = 30000; + unresponsiveTimeout = 15000; + deviceModel = null; + tracer; + constructor({ context, logType } = {}) { + this.tracer = new LocalTracer(logType ?? DEFAULT_LOG_TYPE, context); + } + static isSupported; + static list; + static listen; + static open; + exchange(_apdu, { abortTimeoutMs: _abortTimeoutMs } = {}) { + throw new Error("exchange not implemented"); + } + exchangeBulk(apdus, observer) { + let unsubscribed = false; + const unsubscribe = () => { + unsubscribed = true; + }; + const main = async () => { + if (unsubscribed) + return; + for (const apdu of apdus) { + const r = await this.exchange(apdu); + if (unsubscribed) + return; + const status = r.readUInt16BE(r.length - 2); + if (status !== StatusCodes.OK) { + throw new TransportStatusError(status); + } + observer.next(r); + } + }; + main().then(() => !unsubscribed && observer.complete(), e => !unsubscribed && observer.error(e)); + return { unsubscribe }; + } + setScrambleKey(_key) { } + close() { + return Promise.resolve(); + } + _events = new EventEmitter(); + on(eventName, cb) { + this._events.on(eventName, cb); + } + off(eventName, cb) { + this._events.removeListener(eventName, cb); + } + emit(event, ...args) { + this._events.emit(event, ...args); + } + setDebugMode() { + console.warn("setDebugMode is deprecated. use @ledgerhq/logs instead. No logs are emitted in this anymore."); + } + setExchangeTimeout(exchangeTimeout) { + this.exchangeTimeout = exchangeTimeout; + } + setExchangeUnresponsiveTimeout(unresponsiveTimeout) { + this.unresponsiveTimeout = unresponsiveTimeout; + } + send = async (cla, ins, p1, p2, data = Buffer.alloc(0), statusList = [StatusCodes.OK], { abortTimeoutMs } = {}) => { + const tracer = this.tracer.withUpdatedContext({ function: "send" }); + if (data.length >= 256) { + tracer.trace("data.length exceeded 256 bytes limit", { dataLength: data.length }); + throw new TransportError("data.length exceed 256 bytes limit. Got: " + data.length, "DataLengthTooBig"); + } + const response = await this.exchange( + Buffer.concat([Buffer.from([cla, ins, p1, p2]), Buffer.from([data.length]), data]), { abortTimeoutMs }); + const sw = response.readUInt16BE(response.length - 2); + if (!statusList.some(s => s === sw)) { + throw new TransportStatusError(sw); + } + return response; + }; + static create(openTimeout = 3000, listenTimeout) { + return new Promise((resolve, reject) => { + let found = false; + const sub = this.listen({ + next: e => { + found = true; + if (sub) + sub.unsubscribe(); + if (listenTimeoutId) + clearTimeout(listenTimeoutId); + this.open(e.descriptor, openTimeout).then(resolve, reject); + }, + error: e => { + if (listenTimeoutId) + clearTimeout(listenTimeoutId); + reject(e); + }, + complete: () => { + if (listenTimeoutId) + clearTimeout(listenTimeoutId); + if (!found) { + reject(new TransportError(this.ErrorMessage_NoDeviceFound, "NoDeviceFound")); + } + }, + }); + const listenTimeoutId = listenTimeout + ? setTimeout(() => { + sub.unsubscribe(); + reject(new TransportError(this.ErrorMessage_ListenTimeout, "ListenTimeout")); + }, listenTimeout) + : null; + }); + } + exchangeBusyPromise; + async exchangeAtomicImpl(f) { + const tracer = this.tracer.withUpdatedContext({ + function: "exchangeAtomicImpl", + unresponsiveTimeout: this.unresponsiveTimeout, + }); + if (this.exchangeBusyPromise) { + tracer.trace("Atomic exchange is already busy"); + throw new TransportRaceCondition("An action was already pending on the Ledger device. Please deny or reconnect."); + } + let resolveBusy; + const busyPromise = new Promise(r => { + resolveBusy = r; + }); + this.exchangeBusyPromise = busyPromise; + let unresponsiveReached = false; + const timeout = setTimeout(() => { + tracer.trace(`Timeout reached, emitting Transport event "unresponsive"`, { + unresponsiveTimeout: this.unresponsiveTimeout, + }); + unresponsiveReached = true; + this.emit("unresponsive"); + }, this.unresponsiveTimeout); + try { + const res = await f(); + if (unresponsiveReached) { + tracer.trace("Device was unresponsive, emitting responsive"); + this.emit("responsive"); + } + return res; + } + finally { + tracer.trace("Finalize, clearing busy guard"); + clearTimeout(timeout); + if (resolveBusy) + resolveBusy(); + this.exchangeBusyPromise = null; + } + } + decorateAppAPIMethods(self, methods, scrambleKey) { + for (const methodName of methods) { + self[methodName] = this.decorateAppAPIMethod(methodName, self[methodName], self, scrambleKey); + } + } + _appAPIlock = null; + decorateAppAPIMethod(methodName, f, ctx, scrambleKey) { + return async (...args) => { + const { _appAPIlock } = this; + if (_appAPIlock) { + return Promise.reject(new TransportError("Ledger Device is busy (lock " + _appAPIlock + ")", "TransportLocked")); + } + try { + this._appAPIlock = methodName; + this.setScrambleKey(scrambleKey); + return await f.apply(ctx, args); + } + finally { + this._appAPIlock = null; + } + }; + } + setTraceContext(context) { + this.tracer = this.tracer.withContext(context); + } + updateTraceContext(contextToAdd) { + this.tracer.updateContext(contextToAdd); + } + getTraceContext() { + return this.tracer.getContext(); + } + static ErrorMessage_ListenTimeout = "No Ledger device found (timeout)"; + static ErrorMessage_NoDeviceFound = "No Ledger device found"; + } + + const Tag = 0x05; + function asUInt16BE(value) { + const b = Buffer.alloc(2); + b.writeUInt16BE(value, 0); + return b; + } + const initialAcc = { + data: Buffer.alloc(0), + dataLength: 0, + sequence: 0, + }; + const createHIDframing = (channel, packetSize) => { + return { + makeBlocks(apdu) { + let data = Buffer.concat([asUInt16BE(apdu.length), apdu]); + const blockSize = packetSize - 5; + const nbBlocks = Math.ceil(data.length / blockSize); + data = Buffer.concat([data, Buffer.alloc(nbBlocks * blockSize - data.length + 1).fill(0)]); + const blocks = []; + for (let i = 0; i < nbBlocks; i++) { + const head = Buffer.alloc(5); + head.writeUInt16BE(channel, 0); + head.writeUInt8(Tag, 2); + head.writeUInt16BE(i, 3); + const chunk = data.slice(i * blockSize, (i + 1) * blockSize); + blocks.push(Buffer.concat([head, chunk])); + } + return blocks; + }, + reduceResponse(acc, chunk) { + let { data, dataLength, sequence } = acc || initialAcc; + if (chunk.readUInt16BE(0) !== channel) { + throw new TransportError("Invalid channel", "InvalidChannel"); + } + if (chunk.readUInt8(2) !== Tag) { + throw new TransportError("Invalid tag", "InvalidTag"); + } + if (chunk.readUInt16BE(3) !== sequence) { + throw new TransportError("Invalid sequence", "InvalidSequence"); + } + if (!acc) { + dataLength = chunk.readUInt16BE(5); + } + sequence++; + const chunkData = chunk.slice(acc ? 5 : 7); + data = Buffer.concat([data, chunkData]); + if (data.length > dataLength) { + data = data.slice(0, dataLength); + } + return { + data, + dataLength, + sequence, + }; + }, + getReducedResult(acc) { + if (acc && acc.dataLength === acc.data.length) { + return acc.data; + } + }, + }; + }; + + var re$2 = {exports: {}}; + + const SEMVER_SPEC_VERSION = '2.0.0'; + const MAX_LENGTH$1 = 256; + const MAX_SAFE_INTEGER$1 = Number.MAX_SAFE_INTEGER || + 9007199254740991; + const MAX_SAFE_COMPONENT_LENGTH = 16; + const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH$1 - 6; + const RELEASE_TYPES = [ + 'major', + 'premajor', + 'minor', + 'preminor', + 'patch', + 'prepatch', + 'prerelease', + ]; + var constants$1 = { + MAX_LENGTH: MAX_LENGTH$1, + MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, + MAX_SAFE_INTEGER: MAX_SAFE_INTEGER$1, + RELEASE_TYPES, + SEMVER_SPEC_VERSION, + FLAG_INCLUDE_PRERELEASE: 0b001, + FLAG_LOOSE: 0b010, + }; + getDefaultExportFromCjs(constants$1); + + const debug$1 = ( + typeof process === 'object' && + process.env && + process.env.NODE_DEBUG && + /\bsemver\b/i.test(process.env.NODE_DEBUG) + ) ? (...args) => console.error('SEMVER', ...args) + : () => {}; + var debug_1 = debug$1; + getDefaultExportFromCjs(debug_1); + + (function (module, exports$1) { + const { + MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, + MAX_LENGTH, + } = constants$1; + const debug = debug_1; + exports$1 = module.exports = {}; + const re = exports$1.re = []; + const safeRe = exports$1.safeRe = []; + const src = exports$1.src = []; + const safeSrc = exports$1.safeSrc = []; + const t = exports$1.t = {}; + let R = 0; + const LETTERDASHNUMBER = '[a-zA-Z0-9-]'; + const safeRegexReplacements = [ + ['\\s', 1], + ['\\d', MAX_LENGTH], + [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH], + ]; + const makeSafeRegex = (value) => { + for (const [token, max] of safeRegexReplacements) { + value = value + .split(`${token}*`).join(`${token}{0,${max}}`) + .split(`${token}+`).join(`${token}{1,${max}}`); + } + return value + }; + const createToken = (name, value, isGlobal) => { + const safe = makeSafeRegex(value); + const index = R++; + debug(name, index, value); + t[name] = index; + src[index] = value; + safeSrc[index] = safe; + re[index] = new RegExp(value, isGlobal ? 'g' : undefined); + safeRe[index] = new RegExp(safe, isGlobal ? 'g' : undefined); + }; + createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*'); + createToken('NUMERICIDENTIFIERLOOSE', '\\d+'); + createToken('NONNUMERICIDENTIFIER', `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`); + createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` + + `(${src[t.NUMERICIDENTIFIER]})\\.` + + `(${src[t.NUMERICIDENTIFIER]})`); + createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + + `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + + `(${src[t.NUMERICIDENTIFIERLOOSE]})`); + createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NONNUMERICIDENTIFIER] + }|${src[t.NUMERICIDENTIFIER]})`); + createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NONNUMERICIDENTIFIER] + }|${src[t.NUMERICIDENTIFIERLOOSE]})`); + createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER] + }(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`); + createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE] + }(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`); + createToken('BUILDIDENTIFIER', `${LETTERDASHNUMBER}+`); + createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER] + }(?:\\.${src[t.BUILDIDENTIFIER]})*))`); + createToken('FULLPLAIN', `v?${src[t.MAINVERSION] + }${src[t.PRERELEASE]}?${ + src[t.BUILD]}?`); + createToken('FULL', `^${src[t.FULLPLAIN]}$`); + createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE] + }${src[t.PRERELEASELOOSE]}?${ + src[t.BUILD]}?`); + createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`); + createToken('GTLT', '((?:<|>)?=?)'); + createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`); + createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`); + createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` + + `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + + `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + + `(?:${src[t.PRERELEASE]})?${ + src[t.BUILD]}?` + + `)?)?`); + createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` + + `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + + `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + + `(?:${src[t.PRERELEASELOOSE]})?${ + src[t.BUILD]}?` + + `)?)?`); + createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`); + createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`); + createToken('COERCEPLAIN', `${'(^|[^\\d])' + + '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` + + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`); + createToken('COERCE', `${src[t.COERCEPLAIN]}(?:$|[^\\d])`); + createToken('COERCEFULL', src[t.COERCEPLAIN] + + `(?:${src[t.PRERELEASE]})?` + + `(?:${src[t.BUILD]})?` + + `(?:$|[^\\d])`); + createToken('COERCERTL', src[t.COERCE], true); + createToken('COERCERTLFULL', src[t.COERCEFULL], true); + createToken('LONETILDE', '(?:~>?)'); + createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true); + exports$1.tildeTrimReplace = '$1~'; + createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`); + createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`); + createToken('LONECARET', '(?:\\^)'); + createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true); + exports$1.caretTrimReplace = '$1^'; + createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`); + createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`); + createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`); + createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`); + createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT] + }\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true); + exports$1.comparatorTrimReplace = '$1$2$3'; + createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` + + `\\s+-\\s+` + + `(${src[t.XRANGEPLAIN]})` + + `\\s*$`); + createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` + + `\\s+-\\s+` + + `(${src[t.XRANGEPLAINLOOSE]})` + + `\\s*$`); + createToken('STAR', '(<|>)?=?\\s*\\*'); + createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$'); + createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$'); + } (re$2, re$2.exports)); + var reExports = re$2.exports; + getDefaultExportFromCjs(reExports); + + const looseOption = Object.freeze({ loose: true }); + const emptyOpts = Object.freeze({ }); + const parseOptions$1 = options => { + if (!options) { + return emptyOpts + } + if (typeof options !== 'object') { + return looseOption + } + return options + }; + var parseOptions_1 = parseOptions$1; + getDefaultExportFromCjs(parseOptions_1); + + const numeric = /^[0-9]+$/; + const compareIdentifiers$1 = (a, b) => { + if (typeof a === 'number' && typeof b === 'number') { + return a === b ? 0 : a < b ? -1 : 1 + } + const anum = numeric.test(a); + const bnum = numeric.test(b); + if (anum && bnum) { + a = +a; + b = +b; + } + return a === b ? 0 + : (anum && !bnum) ? -1 + : (bnum && !anum) ? 1 + : a < b ? -1 + : 1 + }; + const rcompareIdentifiers = (a, b) => compareIdentifiers$1(b, a); + var identifiers$1 = { + compareIdentifiers: compareIdentifiers$1, + rcompareIdentifiers, + }; + getDefaultExportFromCjs(identifiers$1); + + const debug = debug_1; + const { MAX_LENGTH, MAX_SAFE_INTEGER } = constants$1; + const { safeRe: re$1, t: t$1 } = reExports; + const parseOptions = parseOptions_1; + const { compareIdentifiers } = identifiers$1; + let SemVer$d = class SemVer { + constructor (version, options) { + options = parseOptions(options); + if (version instanceof SemVer) { + if (version.loose === !!options.loose && + version.includePrerelease === !!options.includePrerelease) { + return version + } else { + version = version.version; + } + } else if (typeof version !== 'string') { + throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`) + } + if (version.length > MAX_LENGTH) { + throw new TypeError( + `version is longer than ${MAX_LENGTH} characters` + ) + } + debug('SemVer', version, options); + this.options = options; + this.loose = !!options.loose; + this.includePrerelease = !!options.includePrerelease; + const m = version.trim().match(options.loose ? re$1[t$1.LOOSE] : re$1[t$1.FULL]); + if (!m) { + throw new TypeError(`Invalid Version: ${version}`) + } + this.raw = version; + this.major = +m[1]; + this.minor = +m[2]; + this.patch = +m[3]; + if (this.major > MAX_SAFE_INTEGER || this.major < 0) { + throw new TypeError('Invalid major version') + } + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { + throw new TypeError('Invalid minor version') + } + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { + throw new TypeError('Invalid patch version') + } + if (!m[4]) { + this.prerelease = []; + } else { + this.prerelease = m[4].split('.').map((id) => { + if (/^[0-9]+$/.test(id)) { + const num = +id; + if (num >= 0 && num < MAX_SAFE_INTEGER) { + return num + } + } + return id + }); + } + this.build = m[5] ? m[5].split('.') : []; + this.format(); + } + format () { + this.version = `${this.major}.${this.minor}.${this.patch}`; + if (this.prerelease.length) { + this.version += `-${this.prerelease.join('.')}`; + } + return this.version + } + toString () { + return this.version + } + compare (other) { + debug('SemVer.compare', this.version, this.options, other); + if (!(other instanceof SemVer)) { + if (typeof other === 'string' && other === this.version) { + return 0 + } + other = new SemVer(other, this.options); + } + if (other.version === this.version) { + return 0 + } + return this.compareMain(other) || this.comparePre(other) + } + compareMain (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options); + } + if (this.major < other.major) { + return -1 + } + if (this.major > other.major) { + return 1 + } + if (this.minor < other.minor) { + return -1 + } + if (this.minor > other.minor) { + return 1 + } + if (this.patch < other.patch) { + return -1 + } + if (this.patch > other.patch) { + return 1 + } + return 0 + } + comparePre (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options); + } + if (this.prerelease.length && !other.prerelease.length) { + return -1 + } else if (!this.prerelease.length && other.prerelease.length) { + return 1 + } else if (!this.prerelease.length && !other.prerelease.length) { + return 0 + } + let i = 0; + do { + const a = this.prerelease[i]; + const b = other.prerelease[i]; + debug('prerelease compare', i, a, b); + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) + } + compareBuild (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options); + } + let i = 0; + do { + const a = this.build[i]; + const b = other.build[i]; + debug('build compare', i, a, b); + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) + } + inc (release, identifier, identifierBase) { + if (release.startsWith('pre')) { + if (!identifier && identifierBase === false) { + throw new Error('invalid increment argument: identifier is empty') + } + if (identifier) { + const match = `-${identifier}`.match(this.options.loose ? re$1[t$1.PRERELEASELOOSE] : re$1[t$1.PRERELEASE]); + if (!match || match[1] !== identifier) { + throw new Error(`invalid identifier: ${identifier}`) + } + } + } + switch (release) { + case 'premajor': + this.prerelease.length = 0; + this.patch = 0; + this.minor = 0; + this.major++; + this.inc('pre', identifier, identifierBase); + break + case 'preminor': + this.prerelease.length = 0; + this.patch = 0; + this.minor++; + this.inc('pre', identifier, identifierBase); + break + case 'prepatch': + this.prerelease.length = 0; + this.inc('patch', identifier, identifierBase); + this.inc('pre', identifier, identifierBase); + break + case 'prerelease': + if (this.prerelease.length === 0) { + this.inc('patch', identifier, identifierBase); + } + this.inc('pre', identifier, identifierBase); + break + case 'release': + if (this.prerelease.length === 0) { + throw new Error(`version ${this.raw} is not a prerelease`) + } + this.prerelease.length = 0; + break + case 'major': + if ( + this.minor !== 0 || + this.patch !== 0 || + this.prerelease.length === 0 + ) { + this.major++; + } + this.minor = 0; + this.patch = 0; + this.prerelease = []; + break + case 'minor': + if (this.patch !== 0 || this.prerelease.length === 0) { + this.minor++; + } + this.patch = 0; + this.prerelease = []; + break + case 'patch': + if (this.prerelease.length === 0) { + this.patch++; + } + this.prerelease = []; + break + case 'pre': { + const base = Number(identifierBase) ? 1 : 0; + if (this.prerelease.length === 0) { + this.prerelease = [base]; + } else { + let i = this.prerelease.length; + while (--i >= 0) { + if (typeof this.prerelease[i] === 'number') { + this.prerelease[i]++; + i = -2; + } + } + if (i === -1) { + if (identifier === this.prerelease.join('.') && identifierBase === false) { + throw new Error('invalid increment argument: identifier already exists') + } + this.prerelease.push(base); + } + } + if (identifier) { + let prerelease = [identifier, base]; + if (identifierBase === false) { + prerelease = [identifier]; + } + if (compareIdentifiers(this.prerelease[0], identifier) === 0) { + if (isNaN(this.prerelease[1])) { + this.prerelease = prerelease; + } + } else { + this.prerelease = prerelease; + } + } + break + } + default: + throw new Error(`invalid increment argument: ${release}`) + } + this.raw = this.format(); + if (this.build.length) { + this.raw += `+${this.build.join('.')}`; + } + return this + } + }; + var semver$2 = SemVer$d; + getDefaultExportFromCjs(semver$2); + + const SemVer$c = semver$2; + const parse$6 = (version, options, throwErrors = false) => { + if (version instanceof SemVer$c) { + return version + } + try { + return new SemVer$c(version, options) + } catch (er) { + if (!throwErrors) { + return null + } + throw er + } + }; + var parse_1 = parse$6; + getDefaultExportFromCjs(parse_1); + + const parse$5 = parse_1; + const valid$2 = (version, options) => { + const v = parse$5(version, options); + return v ? v.version : null + }; + var valid_1 = valid$2; + getDefaultExportFromCjs(valid_1); + + const parse$4 = parse_1; + const clean$1 = (version, options) => { + const s = parse$4(version.trim().replace(/^[=v]+/, ''), options); + return s ? s.version : null + }; + var clean_1 = clean$1; + getDefaultExportFromCjs(clean_1); + + const SemVer$b = semver$2; + const inc$1 = (version, release, options, identifier, identifierBase) => { + if (typeof (options) === 'string') { + identifierBase = identifier; + identifier = options; + options = undefined; + } + try { + return new SemVer$b( + version instanceof SemVer$b ? version.version : version, + options + ).inc(release, identifier, identifierBase).version + } catch (er) { + return null + } + }; + var inc_1 = inc$1; + getDefaultExportFromCjs(inc_1); + + const parse$3 = parse_1; + const diff$1 = (version1, version2) => { + const v1 = parse$3(version1, null, true); + const v2 = parse$3(version2, null, true); + const comparison = v1.compare(v2); + if (comparison === 0) { + return null + } + const v1Higher = comparison > 0; + const highVersion = v1Higher ? v1 : v2; + const lowVersion = v1Higher ? v2 : v1; + const highHasPre = !!highVersion.prerelease.length; + const lowHasPre = !!lowVersion.prerelease.length; + if (lowHasPre && !highHasPre) { + if (!lowVersion.patch && !lowVersion.minor) { + return 'major' + } + if (lowVersion.compareMain(highVersion) === 0) { + if (lowVersion.minor && !lowVersion.patch) { + return 'minor' + } + return 'patch' + } + } + const prefix = highHasPre ? 'pre' : ''; + if (v1.major !== v2.major) { + return prefix + 'major' + } + if (v1.minor !== v2.minor) { + return prefix + 'minor' + } + if (v1.patch !== v2.patch) { + return prefix + 'patch' + } + return 'prerelease' + }; + var diff_1 = diff$1; + getDefaultExportFromCjs(diff_1); + + const SemVer$a = semver$2; + const major$1 = (a, loose) => new SemVer$a(a, loose).major; + var major_1 = major$1; + getDefaultExportFromCjs(major_1); + + const SemVer$9 = semver$2; + const minor$1 = (a, loose) => new SemVer$9(a, loose).minor; + var minor_1 = minor$1; + getDefaultExportFromCjs(minor_1); + + const SemVer$8 = semver$2; + const patch$1 = (a, loose) => new SemVer$8(a, loose).patch; + var patch_1 = patch$1; + getDefaultExportFromCjs(patch_1); + + const parse$2 = parse_1; + const prerelease$1 = (version, options) => { + const parsed = parse$2(version, options); + return (parsed && parsed.prerelease.length) ? parsed.prerelease : null + }; + var prerelease_1 = prerelease$1; + getDefaultExportFromCjs(prerelease_1); + + const SemVer$7 = semver$2; + const compare$b = (a, b, loose) => + new SemVer$7(a, loose).compare(new SemVer$7(b, loose)); + var compare_1 = compare$b; + getDefaultExportFromCjs(compare_1); + + const compare$a = compare_1; + const rcompare$1 = (a, b, loose) => compare$a(b, a, loose); + var rcompare_1 = rcompare$1; + getDefaultExportFromCjs(rcompare_1); + + const compare$9 = compare_1; + const compareLoose$1 = (a, b) => compare$9(a, b, true); + var compareLoose_1 = compareLoose$1; + getDefaultExportFromCjs(compareLoose_1); + + const SemVer$6 = semver$2; + const compareBuild$3 = (a, b, loose) => { + const versionA = new SemVer$6(a, loose); + const versionB = new SemVer$6(b, loose); + return versionA.compare(versionB) || versionA.compareBuild(versionB) + }; + var compareBuild_1 = compareBuild$3; + getDefaultExportFromCjs(compareBuild_1); + + const compareBuild$2 = compareBuild_1; + const sort$1 = (list, loose) => list.sort((a, b) => compareBuild$2(a, b, loose)); + var sort_1 = sort$1; + getDefaultExportFromCjs(sort_1); + + const compareBuild$1 = compareBuild_1; + const rsort$1 = (list, loose) => list.sort((a, b) => compareBuild$1(b, a, loose)); + var rsort_1 = rsort$1; + getDefaultExportFromCjs(rsort_1); + + const compare$8 = compare_1; + const gt$4 = (a, b, loose) => compare$8(a, b, loose) > 0; + var gt_1 = gt$4; + getDefaultExportFromCjs(gt_1); + + const compare$7 = compare_1; + const lt$3 = (a, b, loose) => compare$7(a, b, loose) < 0; + var lt_1 = lt$3; + getDefaultExportFromCjs(lt_1); + + const compare$6 = compare_1; + const eq$2 = (a, b, loose) => compare$6(a, b, loose) === 0; + var eq_1 = eq$2; + getDefaultExportFromCjs(eq_1); + + const compare$5 = compare_1; + const neq$2 = (a, b, loose) => compare$5(a, b, loose) !== 0; + var neq_1 = neq$2; + getDefaultExportFromCjs(neq_1); + + const compare$4 = compare_1; + const gte$3 = (a, b, loose) => compare$4(a, b, loose) >= 0; + var gte_1 = gte$3; + getDefaultExportFromCjs(gte_1); + + const compare$3 = compare_1; + const lte$3 = (a, b, loose) => compare$3(a, b, loose) <= 0; + var lte_1 = lte$3; + getDefaultExportFromCjs(lte_1); + + const eq$1 = eq_1; + const neq$1 = neq_1; + const gt$3 = gt_1; + const gte$2 = gte_1; + const lt$2 = lt_1; + const lte$2 = lte_1; + const cmp$1 = (a, op, b, loose) => { + switch (op) { + case '===': + if (typeof a === 'object') { + a = a.version; + } + if (typeof b === 'object') { + b = b.version; + } + return a === b + case '!==': + if (typeof a === 'object') { + a = a.version; + } + if (typeof b === 'object') { + b = b.version; + } + return a !== b + case '': + case '=': + case '==': + return eq$1(a, b, loose) + case '!=': + return neq$1(a, b, loose) + case '>': + return gt$3(a, b, loose) + case '>=': + return gte$2(a, b, loose) + case '<': + return lt$2(a, b, loose) + case '<=': + return lte$2(a, b, loose) + default: + throw new TypeError(`Invalid operator: ${op}`) + } + }; + var cmp_1 = cmp$1; + getDefaultExportFromCjs(cmp_1); + + const SemVer$5 = semver$2; + const parse$1 = parse_1; + const { safeRe: re, t } = reExports; + const coerce$1 = (version, options) => { + if (version instanceof SemVer$5) { + return version + } + if (typeof version === 'number') { + version = String(version); + } + if (typeof version !== 'string') { + return null + } + options = options || {}; + let match = null; + if (!options.rtl) { + match = version.match(options.includePrerelease ? re[t.COERCEFULL] : re[t.COERCE]); + } else { + const coerceRtlRegex = options.includePrerelease ? re[t.COERCERTLFULL] : re[t.COERCERTL]; + let next; + while ((next = coerceRtlRegex.exec(version)) && + (!match || match.index + match[0].length !== version.length) + ) { + if (!match || + next.index + next[0].length !== match.index + match[0].length) { + match = next; + } + coerceRtlRegex.lastIndex = next.index + next[1].length + next[2].length; + } + coerceRtlRegex.lastIndex = -1; + } + if (match === null) { + return null + } + const major = match[2]; + const minor = match[3] || '0'; + const patch = match[4] || '0'; + const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : ''; + const build = options.includePrerelease && match[6] ? `+${match[6]}` : ''; + return parse$1(`${major}.${minor}.${patch}${prerelease}${build}`, options) + }; + var coerce_1 = coerce$1; + getDefaultExportFromCjs(coerce_1); + + var lrucache; + var hasRequiredLrucache; + function requireLrucache () { + if (hasRequiredLrucache) return lrucache; + hasRequiredLrucache = 1; + class LRUCache { + constructor () { + this.max = 1000; + this.map = new Map(); + } + get (key) { + const value = this.map.get(key); + if (value === undefined) { + return undefined + } else { + this.map.delete(key); + this.map.set(key, value); + return value + } + } + delete (key) { + return this.map.delete(key) + } + set (key, value) { + const deleted = this.delete(key); + if (!deleted && value !== undefined) { + if (this.map.size >= this.max) { + const firstKey = this.map.keys().next().value; + this.delete(firstKey); + } + this.map.set(key, value); + } + return this + } + } + lrucache = LRUCache; + return lrucache; + } + + var range; + var hasRequiredRange; + function requireRange () { + if (hasRequiredRange) return range; + hasRequiredRange = 1; + const SPACE_CHARACTERS = /\s+/g; + class Range { + constructor (range, options) { + options = parseOptions(options); + if (range instanceof Range) { + if ( + range.loose === !!options.loose && + range.includePrerelease === !!options.includePrerelease + ) { + return range + } else { + return new Range(range.raw, options) + } + } + if (range instanceof Comparator) { + this.raw = range.value; + this.set = [[range]]; + this.formatted = undefined; + return this + } + this.options = options; + this.loose = !!options.loose; + this.includePrerelease = !!options.includePrerelease; + this.raw = range.trim().replace(SPACE_CHARACTERS, ' '); + this.set = this.raw + .split('||') + .map(r => this.parseRange(r.trim())) + .filter(c => c.length); + if (!this.set.length) { + throw new TypeError(`Invalid SemVer Range: ${this.raw}`) + } + if (this.set.length > 1) { + const first = this.set[0]; + this.set = this.set.filter(c => !isNullSet(c[0])); + if (this.set.length === 0) { + this.set = [first]; + } else if (this.set.length > 1) { + for (const c of this.set) { + if (c.length === 1 && isAny(c[0])) { + this.set = [c]; + break + } + } + } + } + this.formatted = undefined; + } + get range () { + if (this.formatted === undefined) { + this.formatted = ''; + for (let i = 0; i < this.set.length; i++) { + if (i > 0) { + this.formatted += '||'; + } + const comps = this.set[i]; + for (let k = 0; k < comps.length; k++) { + if (k > 0) { + this.formatted += ' '; + } + this.formatted += comps[k].toString().trim(); + } + } + } + return this.formatted + } + format () { + return this.range + } + toString () { + return this.range + } + parseRange (range) { + const memoOpts = + (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | + (this.options.loose && FLAG_LOOSE); + const memoKey = memoOpts + ':' + range; + const cached = cache.get(memoKey); + if (cached) { + return cached + } + const loose = this.options.loose; + const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE]; + range = range.replace(hr, hyphenReplace(this.options.includePrerelease)); + debug('hyphen replace', range); + range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace); + debug('comparator trim', range); + range = range.replace(re[t.TILDETRIM], tildeTrimReplace); + debug('tilde trim', range); + range = range.replace(re[t.CARETTRIM], caretTrimReplace); + debug('caret trim', range); + let rangeList = range + .split(' ') + .map(comp => parseComparator(comp, this.options)) + .join(' ') + .split(/\s+/) + .map(comp => replaceGTE0(comp, this.options)); + if (loose) { + rangeList = rangeList.filter(comp => { + debug('loose invalid filter', comp, this.options); + return !!comp.match(re[t.COMPARATORLOOSE]) + }); + } + debug('range list', rangeList); + const rangeMap = new Map(); + const comparators = rangeList.map(comp => new Comparator(comp, this.options)); + for (const comp of comparators) { + if (isNullSet(comp)) { + return [comp] + } + rangeMap.set(comp.value, comp); + } + if (rangeMap.size > 1 && rangeMap.has('')) { + rangeMap.delete(''); + } + const result = [...rangeMap.values()]; + cache.set(memoKey, result); + return result + } + intersects (range, options) { + if (!(range instanceof Range)) { + throw new TypeError('a Range is required') + } + return this.set.some((thisComparators) => { + return ( + isSatisfiable(thisComparators, options) && + range.set.some((rangeComparators) => { + return ( + isSatisfiable(rangeComparators, options) && + thisComparators.every((thisComparator) => { + return rangeComparators.every((rangeComparator) => { + return thisComparator.intersects(rangeComparator, options) + }) + }) + ) + }) + ) + }) + } + test (version) { + if (!version) { + return false + } + if (typeof version === 'string') { + try { + version = new SemVer(version, this.options); + } catch (er) { + return false + } + } + for (let i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version, this.options)) { + return true + } + } + return false + } + } + range = Range; + const LRU = requireLrucache(); + const cache = new LRU(); + const parseOptions = parseOptions_1; + const Comparator = requireComparator(); + const debug = debug_1; + const SemVer = semver$2; + const { + safeRe: re, + t, + comparatorTrimReplace, + tildeTrimReplace, + caretTrimReplace, + } = reExports; + const { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = constants$1; + const isNullSet = c => c.value === '<0.0.0-0'; + const isAny = c => c.value === ''; + const isSatisfiable = (comparators, options) => { + let result = true; + const remainingComparators = comparators.slice(); + let testComparator = remainingComparators.pop(); + while (result && remainingComparators.length) { + result = remainingComparators.every((otherComparator) => { + return testComparator.intersects(otherComparator, options) + }); + testComparator = remainingComparators.pop(); + } + return result + }; + const parseComparator = (comp, options) => { + comp = comp.replace(re[t.BUILD], ''); + debug('comp', comp, options); + comp = replaceCarets(comp, options); + debug('caret', comp); + comp = replaceTildes(comp, options); + debug('tildes', comp); + comp = replaceXRanges(comp, options); + debug('xrange', comp); + comp = replaceStars(comp, options); + debug('stars', comp); + return comp + }; + const isX = id => !id || id.toLowerCase() === 'x' || id === '*'; + const replaceTildes = (comp, options) => { + return comp + .trim() + .split(/\s+/) + .map((c) => replaceTilde(c, options)) + .join(' ') + }; + const replaceTilde = (comp, options) => { + const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE]; + return comp.replace(r, (_, M, m, p, pr) => { + debug('tilde', comp, _, M, m, p, pr); + let ret; + if (isX(M)) { + ret = ''; + } else if (isX(m)) { + ret = `>=${M}.0.0 <${+M + 1}.0.0-0`; + } else if (isX(p)) { + ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`; + } else if (pr) { + debug('replaceTilde pr', pr); + ret = `>=${M}.${m}.${p}-${pr + } <${M}.${+m + 1}.0-0`; + } else { + ret = `>=${M}.${m}.${p + } <${M}.${+m + 1}.0-0`; + } + debug('tilde return', ret); + return ret + }) + }; + const replaceCarets = (comp, options) => { + return comp + .trim() + .split(/\s+/) + .map((c) => replaceCaret(c, options)) + .join(' ') + }; + const replaceCaret = (comp, options) => { + debug('caret', comp, options); + const r = options.loose ? re[t.CARETLOOSE] : re[t.CARET]; + const z = options.includePrerelease ? '-0' : ''; + return comp.replace(r, (_, M, m, p, pr) => { + debug('caret', comp, _, M, m, p, pr); + let ret; + if (isX(M)) { + ret = ''; + } else if (isX(m)) { + ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0`; + } else if (isX(p)) { + if (M === '0') { + ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0`; + } else { + ret = `>=${M}.${m}.0${z} <${+M + 1}.0.0-0`; + } + } else if (pr) { + debug('replaceCaret pr', pr); + if (M === '0') { + if (m === '0') { + ret = `>=${M}.${m}.${p}-${pr + } <${M}.${m}.${+p + 1}-0`; + } else { + ret = `>=${M}.${m}.${p}-${pr + } <${M}.${+m + 1}.0-0`; + } + } else { + ret = `>=${M}.${m}.${p}-${pr + } <${+M + 1}.0.0-0`; + } + } else { + debug('no pr'); + if (M === '0') { + if (m === '0') { + ret = `>=${M}.${m}.${p + }${z} <${M}.${m}.${+p + 1}-0`; + } else { + ret = `>=${M}.${m}.${p + }${z} <${M}.${+m + 1}.0-0`; + } + } else { + ret = `>=${M}.${m}.${p + } <${+M + 1}.0.0-0`; + } + } + debug('caret return', ret); + return ret + }) + }; + const replaceXRanges = (comp, options) => { + debug('replaceXRanges', comp, options); + return comp + .split(/\s+/) + .map((c) => replaceXRange(c, options)) + .join(' ') + }; + const replaceXRange = (comp, options) => { + comp = comp.trim(); + const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE]; + return comp.replace(r, (ret, gtlt, M, m, p, pr) => { + debug('xRange', comp, ret, gtlt, M, m, p, pr); + const xM = isX(M); + const xm = xM || isX(m); + const xp = xm || isX(p); + const anyX = xp; + if (gtlt === '=' && anyX) { + gtlt = ''; + } + pr = options.includePrerelease ? '-0' : ''; + if (xM) { + if (gtlt === '>' || gtlt === '<') { + ret = '<0.0.0-0'; + } else { + ret = '*'; + } + } else if (gtlt && anyX) { + if (xm) { + m = 0; + } + p = 0; + if (gtlt === '>') { + gtlt = '>='; + if (xm) { + M = +M + 1; + m = 0; + p = 0; + } else { + m = +m + 1; + p = 0; + } + } else if (gtlt === '<=') { + gtlt = '<'; + if (xm) { + M = +M + 1; + } else { + m = +m + 1; + } + } + if (gtlt === '<') { + pr = '-0'; + } + ret = `${gtlt + M}.${m}.${p}${pr}`; + } else if (xm) { + ret = `>=${M}.0.0${pr} <${+M + 1}.0.0-0`; + } else if (xp) { + ret = `>=${M}.${m}.0${pr + } <${M}.${+m + 1}.0-0`; + } + debug('xRange return', ret); + return ret + }) + }; + const replaceStars = (comp, options) => { + debug('replaceStars', comp, options); + return comp + .trim() + .replace(re[t.STAR], '') + }; + const replaceGTE0 = (comp, options) => { + debug('replaceGTE0', comp, options); + return comp + .trim() + .replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], '') + }; + const hyphenReplace = incPr => ($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr) => { + if (isX(fM)) { + from = ''; + } else if (isX(fm)) { + from = `>=${fM}.0.0${incPr ? '-0' : ''}`; + } else if (isX(fp)) { + from = `>=${fM}.${fm}.0${incPr ? '-0' : ''}`; + } else if (fpr) { + from = `>=${from}`; + } else { + from = `>=${from}${incPr ? '-0' : ''}`; + } + if (isX(tM)) { + to = ''; + } else if (isX(tm)) { + to = `<${+tM + 1}.0.0-0`; + } else if (isX(tp)) { + to = `<${tM}.${+tm + 1}.0-0`; + } else if (tpr) { + to = `<=${tM}.${tm}.${tp}-${tpr}`; + } else if (incPr) { + to = `<${tM}.${tm}.${+tp + 1}-0`; + } else { + to = `<=${to}`; + } + return `${from} ${to}`.trim() + }; + const testSet = (set, version, options) => { + for (let i = 0; i < set.length; i++) { + if (!set[i].test(version)) { + return false + } + } + if (version.prerelease.length && !options.includePrerelease) { + for (let i = 0; i < set.length; i++) { + debug(set[i].semver); + if (set[i].semver === Comparator.ANY) { + continue + } + if (set[i].semver.prerelease.length > 0) { + const allowed = set[i].semver; + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) { + return true + } + } + } + return false + } + return true + }; + return range; + } + + var comparator; + var hasRequiredComparator; + function requireComparator () { + if (hasRequiredComparator) return comparator; + hasRequiredComparator = 1; + const ANY = Symbol('SemVer ANY'); + class Comparator { + static get ANY () { + return ANY + } + constructor (comp, options) { + options = parseOptions(options); + if (comp instanceof Comparator) { + if (comp.loose === !!options.loose) { + return comp + } else { + comp = comp.value; + } + } + comp = comp.trim().split(/\s+/).join(' '); + debug('comparator', comp, options); + this.options = options; + this.loose = !!options.loose; + this.parse(comp); + if (this.semver === ANY) { + this.value = ''; + } else { + this.value = this.operator + this.semver.version; + } + debug('comp', this); + } + parse (comp) { + const r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR]; + const m = comp.match(r); + if (!m) { + throw new TypeError(`Invalid comparator: ${comp}`) + } + this.operator = m[1] !== undefined ? m[1] : ''; + if (this.operator === '=') { + this.operator = ''; + } + if (!m[2]) { + this.semver = ANY; + } else { + this.semver = new SemVer(m[2], this.options.loose); + } + } + toString () { + return this.value + } + test (version) { + debug('Comparator.test', version, this.options.loose); + if (this.semver === ANY || version === ANY) { + return true + } + if (typeof version === 'string') { + try { + version = new SemVer(version, this.options); + } catch (er) { + return false + } + } + return cmp(version, this.operator, this.semver, this.options) + } + intersects (comp, options) { + if (!(comp instanceof Comparator)) { + throw new TypeError('a Comparator is required') + } + if (this.operator === '') { + if (this.value === '') { + return true + } + return new Range(comp.value, options).test(this.value) + } else if (comp.operator === '') { + if (comp.value === '') { + return true + } + return new Range(this.value, options).test(comp.semver) + } + options = parseOptions(options); + if (options.includePrerelease && + (this.value === '<0.0.0-0' || comp.value === '<0.0.0-0')) { + return false + } + if (!options.includePrerelease && + (this.value.startsWith('<0.0.0') || comp.value.startsWith('<0.0.0'))) { + return false + } + if (this.operator.startsWith('>') && comp.operator.startsWith('>')) { + return true + } + if (this.operator.startsWith('<') && comp.operator.startsWith('<')) { + return true + } + if ( + (this.semver.version === comp.semver.version) && + this.operator.includes('=') && comp.operator.includes('=')) { + return true + } + if (cmp(this.semver, '<', comp.semver, options) && + this.operator.startsWith('>') && comp.operator.startsWith('<')) { + return true + } + if (cmp(this.semver, '>', comp.semver, options) && + this.operator.startsWith('<') && comp.operator.startsWith('>')) { + return true + } + return false + } + } + comparator = Comparator; + const parseOptions = parseOptions_1; + const { safeRe: re, t } = reExports; + const cmp = cmp_1; + const debug = debug_1; + const SemVer = semver$2; + const Range = requireRange(); + return comparator; + } + + const Range$9 = requireRange(); + const satisfies$4 = (version, range, options) => { + try { + range = new Range$9(range, options); + } catch (er) { + return false + } + return range.test(version) + }; + var satisfies_1 = satisfies$4; + getDefaultExportFromCjs(satisfies_1); + + const Range$8 = requireRange(); + const toComparators$1 = (range, options) => + new Range$8(range, options).set + .map(comp => comp.map(c => c.value).join(' ').trim().split(' ')); + var toComparators_1 = toComparators$1; + getDefaultExportFromCjs(toComparators_1); + + const SemVer$4 = semver$2; + const Range$7 = requireRange(); + const maxSatisfying$1 = (versions, range, options) => { + let max = null; + let maxSV = null; + let rangeObj = null; + try { + rangeObj = new Range$7(range, options); + } catch (er) { + return null + } + versions.forEach((v) => { + if (rangeObj.test(v)) { + if (!max || maxSV.compare(v) === -1) { + max = v; + maxSV = new SemVer$4(max, options); + } + } + }); + return max + }; + var maxSatisfying_1 = maxSatisfying$1; + getDefaultExportFromCjs(maxSatisfying_1); + + const SemVer$3 = semver$2; + const Range$6 = requireRange(); + const minSatisfying$1 = (versions, range, options) => { + let min = null; + let minSV = null; + let rangeObj = null; + try { + rangeObj = new Range$6(range, options); + } catch (er) { + return null + } + versions.forEach((v) => { + if (rangeObj.test(v)) { + if (!min || minSV.compare(v) === 1) { + min = v; + minSV = new SemVer$3(min, options); + } + } + }); + return min + }; + var minSatisfying_1 = minSatisfying$1; + getDefaultExportFromCjs(minSatisfying_1); + + const SemVer$2 = semver$2; + const Range$5 = requireRange(); + const gt$2 = gt_1; + const minVersion$1 = (range, loose) => { + range = new Range$5(range, loose); + let minver = new SemVer$2('0.0.0'); + if (range.test(minver)) { + return minver + } + minver = new SemVer$2('0.0.0-0'); + if (range.test(minver)) { + return minver + } + minver = null; + for (let i = 0; i < range.set.length; ++i) { + const comparators = range.set[i]; + let setMin = null; + comparators.forEach((comparator) => { + const compver = new SemVer$2(comparator.semver.version); + switch (comparator.operator) { + case '>': + if (compver.prerelease.length === 0) { + compver.patch++; + } else { + compver.prerelease.push(0); + } + compver.raw = compver.format(); + case '': + case '>=': + if (!setMin || gt$2(compver, setMin)) { + setMin = compver; + } + break + case '<': + case '<=': + break + default: + throw new Error(`Unexpected operation: ${comparator.operator}`) + } + }); + if (setMin && (!minver || gt$2(minver, setMin))) { + minver = setMin; + } + } + if (minver && range.test(minver)) { + return minver + } + return null + }; + var minVersion_1 = minVersion$1; + getDefaultExportFromCjs(minVersion_1); + + const Range$4 = requireRange(); + const validRange$1 = (range, options) => { + try { + return new Range$4(range, options).range || '*' + } catch (er) { + return null + } + }; + var valid$1 = validRange$1; + getDefaultExportFromCjs(valid$1); + + const SemVer$1 = semver$2; + const Comparator$2 = requireComparator(); + const { ANY: ANY$1 } = Comparator$2; + const Range$3 = requireRange(); + const satisfies$3 = satisfies_1; + const gt$1 = gt_1; + const lt$1 = lt_1; + const lte$1 = lte_1; + const gte$1 = gte_1; + const outside$3 = (version, range, hilo, options) => { + version = new SemVer$1(version, options); + range = new Range$3(range, options); + let gtfn, ltefn, ltfn, comp, ecomp; + switch (hilo) { + case '>': + gtfn = gt$1; + ltefn = lte$1; + ltfn = lt$1; + comp = '>'; + ecomp = '>='; + break + case '<': + gtfn = lt$1; + ltefn = gte$1; + ltfn = gt$1; + comp = '<'; + ecomp = '<='; + break + default: + throw new TypeError('Must provide a hilo val of "<" or ">"') + } + if (satisfies$3(version, range, options)) { + return false + } + for (let i = 0; i < range.set.length; ++i) { + const comparators = range.set[i]; + let high = null; + let low = null; + comparators.forEach((comparator) => { + if (comparator.semver === ANY$1) { + comparator = new Comparator$2('>=0.0.0'); + } + high = high || comparator; + low = low || comparator; + if (gtfn(comparator.semver, high.semver, options)) { + high = comparator; + } else if (ltfn(comparator.semver, low.semver, options)) { + low = comparator; + } + }); + if (high.operator === comp || high.operator === ecomp) { + return false + } + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false + } + } + return true + }; + var outside_1 = outside$3; + getDefaultExportFromCjs(outside_1); + + const outside$2 = outside_1; + const gtr$1 = (version, range, options) => outside$2(version, range, '>', options); + var gtr_1 = gtr$1; + getDefaultExportFromCjs(gtr_1); + + const outside$1 = outside_1; + const ltr$1 = (version, range, options) => outside$1(version, range, '<', options); + var ltr_1 = ltr$1; + getDefaultExportFromCjs(ltr_1); + + const Range$2 = requireRange(); + const intersects$1 = (r1, r2, options) => { + r1 = new Range$2(r1, options); + r2 = new Range$2(r2, options); + return r1.intersects(r2, options) + }; + var intersects_1 = intersects$1; + getDefaultExportFromCjs(intersects_1); + + const satisfies$2 = satisfies_1; + const compare$2 = compare_1; + var simplify = (versions, range, options) => { + const set = []; + let first = null; + let prev = null; + const v = versions.sort((a, b) => compare$2(a, b, options)); + for (const version of v) { + const included = satisfies$2(version, range, options); + if (included) { + prev = version; + if (!first) { + first = version; + } + } else { + if (prev) { + set.push([first, prev]); + } + prev = null; + first = null; + } + } + if (first) { + set.push([first, null]); + } + const ranges = []; + for (const [min, max] of set) { + if (min === max) { + ranges.push(min); + } else if (!max && min === v[0]) { + ranges.push('*'); + } else if (!max) { + ranges.push(`>=${min}`); + } else if (min === v[0]) { + ranges.push(`<=${max}`); + } else { + ranges.push(`${min} - ${max}`); + } + } + const simplified = ranges.join(' || '); + const original = typeof range.raw === 'string' ? range.raw : String(range); + return simplified.length < original.length ? simplified : range + }; + getDefaultExportFromCjs(simplify); + + const Range$1 = requireRange(); + const Comparator$1 = requireComparator(); + const { ANY } = Comparator$1; + const satisfies$1 = satisfies_1; + const compare$1 = compare_1; + const subset$1 = (sub, dom, options = {}) => { + if (sub === dom) { + return true + } + sub = new Range$1(sub, options); + dom = new Range$1(dom, options); + let sawNonNull = false; + OUTER: for (const simpleSub of sub.set) { + for (const simpleDom of dom.set) { + const isSub = simpleSubset(simpleSub, simpleDom, options); + sawNonNull = sawNonNull || isSub !== null; + if (isSub) { + continue OUTER + } + } + if (sawNonNull) { + return false + } + } + return true + }; + const minimumVersionWithPreRelease = [new Comparator$1('>=0.0.0-0')]; + const minimumVersion = [new Comparator$1('>=0.0.0')]; + const simpleSubset = (sub, dom, options) => { + if (sub === dom) { + return true + } + if (sub.length === 1 && sub[0].semver === ANY) { + if (dom.length === 1 && dom[0].semver === ANY) { + return true + } else if (options.includePrerelease) { + sub = minimumVersionWithPreRelease; + } else { + sub = minimumVersion; + } + } + if (dom.length === 1 && dom[0].semver === ANY) { + if (options.includePrerelease) { + return true + } else { + dom = minimumVersion; + } + } + const eqSet = new Set(); + let gt, lt; + for (const c of sub) { + if (c.operator === '>' || c.operator === '>=') { + gt = higherGT(gt, c, options); + } else if (c.operator === '<' || c.operator === '<=') { + lt = lowerLT(lt, c, options); + } else { + eqSet.add(c.semver); + } + } + if (eqSet.size > 1) { + return null + } + let gtltComp; + if (gt && lt) { + gtltComp = compare$1(gt.semver, lt.semver, options); + if (gtltComp > 0) { + return null + } else if (gtltComp === 0 && (gt.operator !== '>=' || lt.operator !== '<=')) { + return null + } + } + for (const eq of eqSet) { + if (gt && !satisfies$1(eq, String(gt), options)) { + return null + } + if (lt && !satisfies$1(eq, String(lt), options)) { + return null + } + for (const c of dom) { + if (!satisfies$1(eq, String(c), options)) { + return false + } + } + return true + } + let higher, lower; + let hasDomLT, hasDomGT; + let needDomLTPre = lt && + !options.includePrerelease && + lt.semver.prerelease.length ? lt.semver : false; + let needDomGTPre = gt && + !options.includePrerelease && + gt.semver.prerelease.length ? gt.semver : false; + if (needDomLTPre && needDomLTPre.prerelease.length === 1 && + lt.operator === '<' && needDomLTPre.prerelease[0] === 0) { + needDomLTPre = false; + } + for (const c of dom) { + hasDomGT = hasDomGT || c.operator === '>' || c.operator === '>='; + hasDomLT = hasDomLT || c.operator === '<' || c.operator === '<='; + if (gt) { + if (needDomGTPre) { + if (c.semver.prerelease && c.semver.prerelease.length && + c.semver.major === needDomGTPre.major && + c.semver.minor === needDomGTPre.minor && + c.semver.patch === needDomGTPre.patch) { + needDomGTPre = false; + } + } + if (c.operator === '>' || c.operator === '>=') { + higher = higherGT(gt, c, options); + if (higher === c && higher !== gt) { + return false + } + } else if (gt.operator === '>=' && !satisfies$1(gt.semver, String(c), options)) { + return false + } + } + if (lt) { + if (needDomLTPre) { + if (c.semver.prerelease && c.semver.prerelease.length && + c.semver.major === needDomLTPre.major && + c.semver.minor === needDomLTPre.minor && + c.semver.patch === needDomLTPre.patch) { + needDomLTPre = false; + } + } + if (c.operator === '<' || c.operator === '<=') { + lower = lowerLT(lt, c, options); + if (lower === c && lower !== lt) { + return false + } + } else if (lt.operator === '<=' && !satisfies$1(lt.semver, String(c), options)) { + return false + } + } + if (!c.operator && (lt || gt) && gtltComp !== 0) { + return false + } + } + if (gt && hasDomLT && !lt && gtltComp !== 0) { + return false + } + if (lt && hasDomGT && !gt && gtltComp !== 0) { + return false + } + if (needDomGTPre || needDomLTPre) { + return false + } + return true + }; + const higherGT = (a, b, options) => { + if (!a) { + return b + } + const comp = compare$1(a.semver, b.semver, options); + return comp > 0 ? a + : comp < 0 ? b + : b.operator === '>' && a.operator === '>=' ? b + : a + }; + const lowerLT = (a, b, options) => { + if (!a) { + return b + } + const comp = compare$1(a.semver, b.semver, options); + return comp < 0 ? a + : comp > 0 ? b + : b.operator === '<' && a.operator === '<=' ? b + : a + }; + var subset_1 = subset$1; + getDefaultExportFromCjs(subset_1); + + const internalRe = reExports; + const constants = constants$1; + const SemVer = semver$2; + const identifiers = identifiers$1; + const parse = parse_1; + const valid = valid_1; + const clean = clean_1; + const inc = inc_1; + const diff = diff_1; + const major = major_1; + const minor = minor_1; + const patch = patch_1; + const prerelease = prerelease_1; + const compare = compare_1; + const rcompare = rcompare_1; + const compareLoose = compareLoose_1; + const compareBuild = compareBuild_1; + const sort = sort_1; + const rsort = rsort_1; + const gt = gt_1; + const lt = lt_1; + const eq = eq_1; + const neq = neq_1; + const gte = gte_1; + const lte = lte_1; + const cmp = cmp_1; + const coerce = coerce_1; + const Comparator = requireComparator(); + const Range = requireRange(); + const satisfies = satisfies_1; + const toComparators = toComparators_1; + const maxSatisfying = maxSatisfying_1; + const minSatisfying = minSatisfying_1; + const minVersion = minVersion_1; + const validRange = valid$1; + const outside = outside_1; + const gtr = gtr_1; + const ltr = ltr_1; + const intersects = intersects_1; + const simplifyRange = simplify; + const subset = subset_1; + var semver = { + parse, + valid, + clean, + inc, + diff, + major, + minor, + patch, + prerelease, + compare, + rcompare, + compareLoose, + compareBuild, + sort, + rsort, + gt, + lt, + eq, + neq, + gte, + lte, + cmp, + coerce, + Comparator, + Range, + satisfies, + toComparators, + maxSatisfying, + minSatisfying, + minVersion, + validRange, + outside, + gtr, + ltr, + intersects, + simplifyRange, + subset, + SemVer, + re: internalRe.re, + src: internalRe.src, + tokens: internalRe.t, + SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION, + RELEASE_TYPES: constants.RELEASE_TYPES, + compareIdentifiers: identifiers.compareIdentifiers, + rcompareIdentifiers: identifiers.rcompareIdentifiers, + }; + const semver$1 = getDefaultExportFromCjs(semver); + + var DeviceModelId; + (function (DeviceModelId) { + DeviceModelId["blue"] = "blue"; + DeviceModelId["nanoS"] = "nanoS"; + DeviceModelId["nanoSP"] = "nanoSP"; + DeviceModelId["nanoX"] = "nanoX"; + DeviceModelId["stax"] = "stax"; + DeviceModelId["europa"] = "europa"; + DeviceModelId["apex"] = "apex"; + })(DeviceModelId || (DeviceModelId = {})); + const devices = { + [DeviceModelId.blue]: { + id: DeviceModelId.blue, + productName: "Ledger Blue", + productIdMM: 0x00, + legacyUsbProductId: 0x0000, + usbOnly: true, + memorySize: 480 * 1024, + masks: [0x31000000, 0x31010000], + getBlockSize: (_firwareVersion) => 4 * 1024, + }, + [DeviceModelId.nanoS]: { + id: DeviceModelId.nanoS, + productName: "Ledger Nano S", + productIdMM: 0x10, + legacyUsbProductId: 0x0001, + usbOnly: true, + memorySize: 320 * 1024, + masks: [0x31100000], + getBlockSize: (firmwareVersion) => semver$1.lt(semver$1.coerce(firmwareVersion) ?? "", "2.0.0") ? 4 * 1024 : 2 * 1024, + }, + [DeviceModelId.nanoX]: { + id: DeviceModelId.nanoX, + productName: "Ledger Nano X", + productIdMM: 0x40, + legacyUsbProductId: 0x0004, + usbOnly: false, + memorySize: 2 * 1024 * 1024, + masks: [0x33000000], + getBlockSize: (_firwareVersion) => 4 * 1024, + bluetoothSpec: [ + { + serviceUuid: "13d63400-2c97-0004-0000-4c6564676572", + notifyUuid: "13d63400-2c97-0004-0001-4c6564676572", + writeUuid: "13d63400-2c97-0004-0002-4c6564676572", + writeCmdUuid: "13d63400-2c97-0004-0003-4c6564676572", + }, + ], + }, + [DeviceModelId.nanoSP]: { + id: DeviceModelId.nanoSP, + productName: "Ledger Nano S Plus", + productIdMM: 0x50, + legacyUsbProductId: 0x0005, + usbOnly: true, + memorySize: 1533 * 1024, + masks: [0x33100000], + getBlockSize: (_firmwareVersion) => 32, + }, + [DeviceModelId.apex]: { + id: DeviceModelId.apex, + productName: "Ledger Nano Gen5", + productIdMM: 0x80, + legacyUsbProductId: 0x0008, + usbOnly: false, + memorySize: 1533 * 1024, + masks: [0x33400000], + getBlockSize: (_firmwareVersion) => 32, + bluetoothSpec: [ + { + serviceUuid: "13d63400-2c97-8004-0000-4c6564676572", + notifyUuid: "13d63400-2c97-8004-0001-4c6564676572", + writeUuid: "13d63400-2c97-8004-0002-4c6564676572", + writeCmdUuid: "13d63400-2c97-8004-0003-4c6564676572", + }, + ], + }, + [DeviceModelId.stax]: { + id: DeviceModelId.stax, + productName: "Ledger Stax", + productIdMM: 0x60, + legacyUsbProductId: 0x0006, + usbOnly: false, + memorySize: 1533 * 1024, + masks: [0x33200000], + getBlockSize: (_firmwareVersion) => 32, + bluetoothSpec: [ + { + serviceUuid: "13d63400-2c97-6004-0000-4c6564676572", + notifyUuid: "13d63400-2c97-6004-0001-4c6564676572", + writeUuid: "13d63400-2c97-6004-0002-4c6564676572", + writeCmdUuid: "13d63400-2c97-6004-0003-4c6564676572", + }, + ], + }, + [DeviceModelId.europa]: { + id: DeviceModelId.europa, + productName: "Ledger Flex", + productIdMM: 0x70, + legacyUsbProductId: 0x0007, + usbOnly: false, + memorySize: 1533 * 1024, + masks: [0x33300000], + getBlockSize: (_firmwareVersion) => 32, + bluetoothSpec: [ + { + serviceUuid: "13d63400-2c97-3004-0000-4c6564676572", + notifyUuid: "13d63400-2c97-3004-0001-4c6564676572", + writeUuid: "13d63400-2c97-3004-0002-4c6564676572", + writeCmdUuid: "13d63400-2c97-3004-0003-4c6564676572", + }, + ], + }, + }; + ({ + Blue: DeviceModelId.blue, + "Nano S": DeviceModelId.nanoS, + "Nano S Plus": DeviceModelId.nanoSP, + "Nano X": DeviceModelId.nanoX, + Stax: DeviceModelId.stax, + Europa: DeviceModelId.europa, + }); + const devicesList = Object.values(devices); + const ledgerUSBVendorId = 0x2c97; + const identifyUSBProductId = (usbProductId) => { + const legacy = devicesList.find(d => d.legacyUsbProductId === usbProductId); + if (legacy) + return legacy; + const mm = usbProductId >> 8; + const deviceModel = devicesList.find(d => d.productIdMM === mm); + return deviceModel; + }; + const bluetoothServices = []; + const serviceUuidToInfos = {}; + for (const id in devices) { + const deviceModel = devices[id]; + const { bluetoothSpec } = deviceModel; + if (bluetoothSpec) { + for (let i = 0; i < bluetoothSpec.length; i++) { + const spec = bluetoothSpec[i]; + bluetoothServices.push(spec.serviceUuid); + serviceUuidToInfos[spec.serviceUuid] = serviceUuidToInfos[spec.serviceUuid.replace(/-/g, "")] = { + deviceModel, + ...spec, + }; + } + } + } + + const ledgerDevices$1 = [ + { + vendorId: ledgerUSBVendorId, + }, + ]; + const isSupported$1 = () => Promise.resolve(!!(window.navigator && window.navigator.hid)); + const getHID = () => { + const { hid } = navigator; + if (!hid) + throw new TransportError("navigator.hid is not supported", "HIDNotSupported"); + return hid; + }; + async function requestLedgerDevices() { + const device = await getHID().requestDevice({ + filters: ledgerDevices$1, + }); + if (Array.isArray(device)) + return device; + return [device]; + } + async function getLedgerDevices$1() { + const devices = await getHID().getDevices(); + return devices.filter(d => d.vendorId === ledgerUSBVendorId); + } + async function getFirstLedgerDevice$1() { + const existingDevices = await getLedgerDevices$1(); + if (existingDevices.length > 0) + return existingDevices[0]; + const devices = await requestLedgerDevices(); + return devices[0]; + } + class TransportWebHID extends Transport { + device; + deviceModel; + channel = Math.floor(Math.random() * 0xffff); + packetSize = 64; + constructor(device) { + super(); + this.device = device; + this.deviceModel = + typeof device.productId === "number" ? identifyUSBProductId(device.productId) : undefined; + device.addEventListener("inputreport", this.onInputReport); + } + inputs = []; + inputCallback; + read = () => { + if (this.inputs.length) { + return Promise.resolve(this.inputs.shift()); + } + return new Promise(success => { + this.inputCallback = success; + }); + }; + onInputReport = (e) => { + const buffer = Buffer.from(e.data.buffer); + if (this.inputCallback) { + this.inputCallback(buffer); + this.inputCallback = null; + } + else { + this.inputs.push(buffer); + } + }; + static isSupported = isSupported$1; + static list = getLedgerDevices$1; + static listen = (observer) => { + let unsubscribed = false; + getFirstLedgerDevice$1().then(device => { + if (!device) { + observer.error(new TransportOpenUserCancelled("Access denied to use Ledger device")); + } + else if (!unsubscribed) { + const deviceModel = typeof device.productId === "number" + ? identifyUSBProductId(device.productId) + : undefined; + observer.next({ + type: "add", + descriptor: device, + deviceModel, + }); + observer.complete(); + } + }, error => { + observer.error(new TransportOpenUserCancelled(error.message)); + }); + function unsubscribe() { + unsubscribed = true; + } + return { + unsubscribe, + }; + }; + static async request() { + const [device] = await requestLedgerDevices(); + return TransportWebHID.open(device); + } + static async openConnected() { + const devices = await getLedgerDevices$1(); + if (devices.length === 0) + return null; + return TransportWebHID.open(devices[0]); + } + static async open(device) { + await device.open(); + const transport = new TransportWebHID(device); + const onDisconnect = e => { + if (device === e.device) { + getHID().removeEventListener("disconnect", onDisconnect); + transport._emitDisconnect(new DisconnectedDevice()); + } + }; + getHID().addEventListener("disconnect", onDisconnect); + return transport; + } + _disconnectEmitted = false; + _emitDisconnect = (e) => { + if (this._disconnectEmitted) + return; + this._disconnectEmitted = true; + this.emit("disconnect", e); + }; + async close() { + await this.exchangeBusyPromise; + this.device.removeEventListener("inputreport", this.onInputReport); + await this.device.close(); + } + exchange = async (apdu) => { + const b = await this.exchangeAtomicImpl(async () => { + const { channel, packetSize } = this; + log("apdu", "=> " + apdu.toString("hex")); + const framing = createHIDframing(channel, packetSize); + const blocks = framing.makeBlocks(apdu); + for (let i = 0; i < blocks.length; i++) { + await this.device.sendReport(0, blocks[i]); + } + let result; + let acc; + while (!(result = framing.getReducedResult(acc))) { + try { + const buffer = await this.read(); + acc = framing.reduceResponse(acc, buffer); + } + catch (e) { + if (e instanceof TransportError && e.id === "InvalidChannel") { + continue; + } + throw e; + } + } + log("apdu", "<= " + result.toString("hex")); + return result; + }).catch(e => { + if (e && e.message && e.message.includes("write")) { + this._emitDisconnect(e); + throw new DisconnectedDeviceDuringOperation(e.message); + } + throw e; + }); + return b; + }; + setScrambleKey() { } + } + + const TransportWebHID$1 = /*#__PURE__*/Object.freeze({ + __proto__: null, + default: TransportWebHID + }); + + const require$$1 = /*@__PURE__*/getAugmentedNamespace(TransportWebHID$1); + + const ledgerDevices = [ + { + vendorId: ledgerUSBVendorId, + }, + ]; + async function requestLedgerDevice() { + const device = await navigator.usb.requestDevice({ + filters: ledgerDevices, + }); + return device; + } + async function getLedgerDevices() { + const devices = await navigator.usb.getDevices(); + return devices.filter(d => d.vendorId === ledgerUSBVendorId); + } + async function getFirstLedgerDevice() { + const existingDevices = await getLedgerDevices(); + if (existingDevices.length > 0) + return existingDevices[0]; + return requestLedgerDevice(); + } + const isSupported = () => Promise.resolve(!!navigator && !!navigator.usb && typeof navigator.usb.getDevices === "function"); + + const configurationValue = 1; + const endpointNumber = 3; + class TransportWebUSB extends Transport { + device; + deviceModel; + channel = Math.floor(Math.random() * 0xffff); + packetSize = 64; + interfaceNumber; + constructor(device, interfaceNumber) { + super(); + this.device = device; + this.interfaceNumber = interfaceNumber; + this.deviceModel = identifyUSBProductId(device.productId); + } + static isSupported = isSupported; + static list = getLedgerDevices; + static listen = (observer) => { + let unsubscribed = false; + getFirstLedgerDevice().then(device => { + if (!unsubscribed) { + const deviceModel = identifyUSBProductId(device.productId); + observer.next({ + type: "add", + descriptor: device, + deviceModel, + }); + observer.complete(); + } + }, error => { + if (window.DOMException && error instanceof window.DOMException && error.code === 18) { + observer.error(new TransportWebUSBGestureRequired(error.message)); + } + else { + observer.error(new TransportOpenUserCancelled(error.message)); + } + }); + function unsubscribe() { + unsubscribed = true; + } + return { + unsubscribe, + }; + }; + static async request() { + const device = await requestLedgerDevice(); + return TransportWebUSB.open(device); + } + static async openConnected() { + const devices = await getLedgerDevices(); + if (devices.length === 0) + return null; + return TransportWebUSB.open(devices[0]); + } + static async open(device) { + await device.open(); + if (device.configuration === null) { + await device.selectConfiguration(configurationValue); + } + await gracefullyResetDevice(device); + const iface = device.configurations[0].interfaces.find(({ alternates }) => alternates.some(a => a.interfaceClass === 255)); + if (!iface) { + throw new TransportInterfaceNotAvailable("No WebUSB interface found for your Ledger device. Please upgrade firmware or contact techsupport."); + } + const interfaceNumber = iface.interfaceNumber; + try { + await device.claimInterface(interfaceNumber); + } + catch (e) { + await device.close(); + throw new TransportInterfaceNotAvailable(e.message); + } + const transport = new TransportWebUSB(device, interfaceNumber); + const onDisconnect = e => { + if (device === e.device) { + navigator.usb.removeEventListener("disconnect", onDisconnect); + transport._emitDisconnect(new DisconnectedDevice()); + } + }; + navigator.usb.addEventListener("disconnect", onDisconnect); + return transport; + } + _disconnectEmitted = false; + _emitDisconnect = (e) => { + if (this._disconnectEmitted) + return; + this._disconnectEmitted = true; + this.emit("disconnect", e); + }; + async close() { + await this.exchangeBusyPromise; + await this.device.releaseInterface(this.interfaceNumber); + await gracefullyResetDevice(this.device); + await this.device.close(); + } + async exchange(apdu) { + const b = await this.exchangeAtomicImpl(async () => { + const { channel, packetSize } = this; + log("apdu", "=> " + apdu.toString("hex")); + const framing = createHIDframing(channel, packetSize); + const blocks = framing.makeBlocks(apdu); + for (let i = 0; i < blocks.length; i++) { + await this.device.transferOut(endpointNumber, blocks[i]); + } + let result; + let acc; + while (!(result = framing.getReducedResult(acc))) { + const r = await this.device.transferIn(endpointNumber, packetSize); + const buffer = Buffer.from(r.data.buffer); + acc = framing.reduceResponse(acc, buffer); + } + log("apdu", "<= " + result.toString("hex")); + return result; + }).catch(e => { + if (e && e.message && e.message.includes("disconnected")) { + this._emitDisconnect(e); + throw new DisconnectedDeviceDuringOperation(e.message); + } + throw e; + }); + return b; + } + setScrambleKey() { } + } + async function gracefullyResetDevice(device) { + try { + await device.reset(); + } + catch (err) { + console.warn(err); + } + } + + const TransportWebUSB$1 = /*#__PURE__*/Object.freeze({ + __proto__: null, + default: TransportWebUSB + }); + + const require$$2 = /*@__PURE__*/getAugmentedNamespace(TransportWebUSB$1); + + var util = {}; + + var hasRequiredUtil; + function requireUtil () { + if (hasRequiredUtil) return util; + hasRequiredUtil = 1; + Object.defineProperty(util, "__esModule", { value: true }); + util.createDefs = createDefs; + function createDefs(...items) { + return items.map(([type, Clazz]) => ({ + create: () => Clazz.create(), + type + })); + } + return util; + } + + var packageInfo = {}; + + var hasRequiredPackageInfo; + function requirePackageInfo () { + if (hasRequiredPackageInfo) return packageInfo; + hasRequiredPackageInfo = 1; + Object.defineProperty(packageInfo, "__esModule", { value: true }); + packageInfo.packageInfo = void 0; + packageInfo.packageInfo = { name: '@pezkuwi/hw-ledger-transports', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; + return packageInfo; + } + + (function (exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.transports = exports$1.packageInfo = void 0; + const tslib_1 = require$$0; + const hw_transport_webhid_1 = tslib_1.__importDefault(require$$1); + const hw_transport_webusb_1 = tslib_1.__importDefault(require$$2); + const util_js_1 = requireUtil(); + var packageInfo_js_1 = requirePackageInfo(); + Object.defineProperty(exports$1, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); + exports$1.transports = (0, util_js_1.createDefs)(['webusb', hw_transport_webusb_1.default], ['hid', hw_transport_webhid_1.default]); + } (browser)); + getDefaultExportFromCjs(browser); + + const LEDGER_DEFAULT_ACCOUNT = 0x80000000; + const LEDGER_DEFAULT_CHANGE = 0x80000000; + const LEDGER_DEFAULT_INDEX = 0x80000000; + const LEDGER_SUCCESS_CODE = 0x9000; + + const prevLedgerRecord = { + acala: 'Acala', + ajuna: 'Ajuna', + 'aleph-node': 'AlephZero', + astar: 'Astar', + bifrost: 'Bifrost', + 'bifrost-kusama': 'BifrostKusama', + centrifuge: 'Centrifuge', + composable: 'Composable', + darwinia: 'Darwinia', + 'dock-mainnet': 'Dock', + edgeware: 'Edgeware', + enjin: 'Enjin', + equilibrium: 'Equilibrium', + genshiro: 'Genshiro', + hydradx: 'HydraDX', + 'interlay-parachain': 'Interlay', + karura: 'Karura', + khala: 'Khala', + kusama: 'Kusama', + matrixchain: 'Matrixchain', + nodle: 'Nodle', + origintrail: 'OriginTrail', + parallel: 'Parallel', + peaq: 'Peaq', + pendulum: 'Pendulum', + phala: 'Phala', + picasso: 'Picasso', + polkadex: 'Polkadex', + polkadot: 'Polkadot', + polymesh: 'Polymesh', + quartz: 'Quartz', + sora: 'Sora', + stafi: 'Stafi', + statemine: 'Statemine', + statemint: 'Statemint', + ternoa: 'Ternoa', + unique: 'Unique', + vtb: 'VTB', + xxnetwork: 'XXNetwork', + zeitgeist: 'Zeitgeist' + }; + const genericLedgerApps = { + bittensor: 'Bittensor', + creditcoin3: 'Creditcoin3', + dentnet: 'DENTNet', + encointer: 'Encointer', + frequency: 'Frequency', + integritee: 'Integritee', + liberland: 'Liberland', + mythos: 'Mythos', + polimec: 'Polimec', + vara: 'Vara' + }; + const ledgerApps = { + ...prevLedgerRecord, + ...genericLedgerApps + }; + + async function wrapError$1(promise) { + const result = await promise; + if (result.return_code !== LEDGER_SUCCESS_CODE) { + throw new Error(result.error_message); + } + return result; + } + function sign$1(method, message, accountOffset = 0, addressOffset = 0, { account = LEDGER_DEFAULT_ACCOUNT, addressIndex = LEDGER_DEFAULT_INDEX, change = LEDGER_DEFAULT_CHANGE } = {}) { + return async (app) => { + const { signature } = await wrapError$1(app[method](account + accountOffset, change, addressIndex + addressOffset, util$1.u8aToBuffer(message))); + return { + signature: util$1.hexAddPrefix(signature.toString('hex')) + }; + }; + } + class Ledger { + #ledgerName; + #transportDef; + #app = null; + constructor(transport, chain) { + const ledgerName = ledgerApps[chain]; + const transportDef = browser.transports.find(({ type }) => type === transport); + if (!ledgerName) { + throw new Error(`Unsupported Ledger chain ${chain}`); + } + else if (!transportDef) { + throw new Error(`Unsupported Ledger transport ${transport}`); + } + this.#ledgerName = ledgerName; + this.#transportDef = transportDef; + } + async getAddress(confirm = false, accountOffset = 0, addressOffset = 0, { account = LEDGER_DEFAULT_ACCOUNT, addressIndex = LEDGER_DEFAULT_INDEX, change = LEDGER_DEFAULT_CHANGE } = {}) { + return this.withApp(async (app) => { + const { address, pubKey } = await wrapError$1(app.getAddress(account + accountOffset, change, addressIndex + addressOffset, confirm)); + return { + address, + publicKey: util$1.hexAddPrefix(pubKey) + }; + }); + } + async getVersion() { + return this.withApp(async (app) => { + const { device_locked: isLocked, major, minor, patch, test_mode: isTestMode } = await wrapError$1(app.getVersion()); + return { + isLocked, + isTestMode, + version: [major, minor, patch] + }; + }); + } + async sign(message, accountOffset, addressOffset, options) { + return this.withApp(sign$1('sign', message, accountOffset, addressOffset, options)); + } + async signRaw(message, accountOffset, addressOffset, options) { + return this.withApp(sign$1('signRaw', util$1.u8aWrapBytes(message), accountOffset, addressOffset, options)); + } + async withApp(fn) { + try { + if (!this.#app) { + const transport = await this.#transportDef.create(); + this.#app = dist$1.newSubstrateApp(transport, this.#ledgerName); + } + return await fn(this.#app); + } + catch (error) { + this.#app = null; + throw error; + } + } + } + + async function wrapError(promise) { + let result; + try { + result = await promise; + } + catch (e) { + if (e.returnCode) { + throw new Error(`${e.returnCode}: ${e.errorMessage}`); + } + throw new Error(e.message); + } + return result; + } + function sign(method, message, slip44, accountIndex = 0, addressOffset = 0) { + const bip42Path = `m/44'/${slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return async (app) => { + const { signature } = await wrapError(app[method](bip42Path, util$1.u8aToBuffer(message))); + return { + signature: util$1.hexAddPrefix(signature.toString('hex')) + }; + }; + } + function signEcdsa(method, message, slip44, accountIndex = 0, addressOffset = 0) { + const bip42Path = `m/44'/${slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return async (app) => { + const { r, s, v } = await wrapError(app[method](bip42Path, util$1.u8aToBuffer(message))); + const signature = Buffer.concat([r, s, v]); + return { + signature: util$1.hexAddPrefix(signature.toString('hex')) + }; + }; + } + function signWithMetadata(message, slip44, accountIndex = 0, addressOffset = 0, { metadata } = {}) { + const bip42Path = `m/44'/${slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return async (app) => { + if (!metadata) { + throw new Error('The metadata option must be present when using signWithMetadata'); + } + const bufferMsg = Buffer.from(message); + const { signature } = await wrapError(app.signWithMetadataEd25519(bip42Path, bufferMsg, metadata)); + return { + signature: util$1.hexAddPrefix(signature.toString('hex')) + }; + }; + } + function signWithMetadataEcdsa(message, slip44, accountIndex = 0, addressOffset = 0, { metadata } = {}) { + const bip42Path = `m/44'/${slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return async (app) => { + if (!metadata) { + throw new Error('The metadata option must be present when using signWithMetadata'); + } + const bufferMsg = Buffer.from(message); + const { r, s, v } = await wrapError(app.signWithMetadataEcdsa(bip42Path, bufferMsg, metadata)); + const signature = Buffer.concat([r, s, v]); + return { + signature: util$1.hexAddPrefix(signature.toString('hex')) + }; + }; + } + class LedgerGeneric { + #transportDef; + #slip44; + #chainId; + #metaUrl; + #app = null; + constructor(transport, chain, slip44, chainId, metaUrl) { + const ledgerName = ledgerApps[chain]; + const transportDef = browser.transports.find(({ type }) => type === transport); + if (!ledgerName) { + throw new Error(`Unsupported Ledger chain ${chain}`); + } + else if (!transportDef) { + throw new Error(`Unsupported Ledger transport ${transport}`); + } + this.#metaUrl = metaUrl; + this.#chainId = chainId; + this.#slip44 = slip44; + this.#transportDef = transportDef; + } + async getAddress(ss58Prefix, confirm = false, accountIndex = 0, addressOffset = 0) { + const bip42Path = `m/44'/${this.#slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return this.withApp(async (app) => { + const { address, pubKey } = await wrapError(app.getAddressEd25519(bip42Path, ss58Prefix, confirm)); + return { + address, + publicKey: util$1.hexAddPrefix(pubKey) + }; + }); + } + async getAddressEcdsa(confirm = false, accountIndex = 0, addressOffset = 0) { + const bip42Path = `m/44'/${this.#slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return this.withApp(async (app) => { + const { address, pubKey } = await wrapError(app.getAddressEcdsa(bip42Path, confirm)); + return { + address, + publicKey: util$1.hexAddPrefix(pubKey) + }; + }); + } + async getVersion() { + return this.withApp(async (app) => { + const { deviceLocked: isLocked, major, minor, patch, testMode: isTestMode } = await wrapError(app.getVersion()); + return { + isLocked: !!isLocked, + isTestMode: !!isTestMode, + version: [major || 0, minor || 0, patch || 0] + }; + }); + } + async sign(message, accountIndex, addressOffset) { + return this.withApp(sign('signEd25519', message, this.#slip44, accountIndex, addressOffset)); + } + async signRaw(message, accountIndex, addressOffset) { + return this.withApp(sign('signRawEd25519', util$1.u8aWrapBytes(message), this.#slip44, accountIndex, addressOffset)); + } + async signEcdsa(message, accountIndex, addressOffset) { + return this.withApp(signEcdsa('signEcdsa', util$1.u8aWrapBytes(message), this.#slip44, accountIndex, addressOffset)); + } + async signRawEcdsa(message, accountIndex, addressOffset) { + return this.withApp(signEcdsa('signRawEcdsa', util$1.u8aWrapBytes(message), this.#slip44, accountIndex, addressOffset)); + } + async signWithMetadata(message, accountIndex, addressOffset, options) { + return this.withApp(signWithMetadata(message, this.#slip44, accountIndex, addressOffset, options)); + } + async signWithMetadataEcdsa(message, accountIndex, addressOffset, options) { + return this.withApp(signWithMetadataEcdsa(message, this.#slip44, accountIndex, addressOffset, options)); + } + async withApp(fn) { + try { + if (!this.#app) { + const transport = await this.#transportDef.create(); + this.#app = new dist$1.PolkadotGenericApp(transport, this.#chainId, this.#metaUrl); + } + return await fn(this.#app); + } + catch (error) { + this.#app = null; + throw error; + } + } + } + + exports.Ledger = Ledger; + exports.LedgerGeneric = LedgerGeneric; + +})); diff --git a/packages/hw-ledger/bundle.d.ts b/packages/hw-ledger/bundle.d.ts new file mode 100644 index 0000000..f5cbfe5 --- /dev/null +++ b/packages/hw-ledger/bundle.d.ts @@ -0,0 +1,2 @@ +export { Ledger } from './Ledger.js'; +export { LedgerGeneric } from './LedgerGeneric.js'; diff --git a/packages/hw-ledger/bundle.js b/packages/hw-ledger/bundle.js new file mode 100644 index 0000000..f5cbfe5 --- /dev/null +++ b/packages/hw-ledger/bundle.js @@ -0,0 +1,2 @@ +export { Ledger } from './Ledger.js'; +export { LedgerGeneric } from './LedgerGeneric.js'; diff --git a/packages/hw-ledger/cjs/Ledger.d.ts b/packages/hw-ledger/cjs/Ledger.d.ts new file mode 100644 index 0000000..a7a75f0 --- /dev/null +++ b/packages/hw-ledger/cjs/Ledger.d.ts @@ -0,0 +1,43 @@ +import type { SubstrateApp } from '@zondax/ledger-substrate'; +import type { TransportType } from '@pezkuwi/hw-ledger-transports/types'; +import type { AccountOptions, LedgerAddress, LedgerSignature, LedgerVersion } from './types.js'; +import { ledgerApps } from './defaults.js'; +export { packageInfo } from './packageInfo.js'; +type Chain = keyof typeof ledgerApps; +/** + * @name Ledger + * + * @description + * Legacy wrapper for a ledger app - + * - it connects automatically on use, creating an underlying interface as required + * - Promises reject with errors (unwrapped errors from @zondax/ledger-substrate) + * @deprecated Use LedgerGeneric for up to date integration with ledger + */ +export declare class Ledger { + #private; + constructor(transport: TransportType, chain: Chain); + /** + * Returns the address associated with a specific account & address offset. Optionally + * asks for on-device confirmation + */ + getAddress(confirm?: boolean, accountOffset?: number, addressOffset?: number, { account, addressIndex, change }?: Partial): Promise; + /** + * Returns the version of the Ledger application on the device + */ + getVersion(): Promise; + /** + * Signs a transaction on the Ledger device + */ + sign(message: Uint8Array, accountOffset?: number, addressOffset?: number, options?: Partial): Promise; + /** + * Signs a message (non-transactional) on the Ledger device + */ + signRaw(message: Uint8Array, accountOffset?: number, addressOffset?: number, options?: Partial): Promise; + /** + * @internal + * + * Returns a created SubstrateApp to perform operations against. Generally + * this is only used internally, to ensure consistent bahavior. + */ + withApp(fn: (app: SubstrateApp) => Promise): Promise; +} diff --git a/packages/hw-ledger/cjs/Ledger.js b/packages/hw-ledger/cjs/Ledger.js new file mode 100644 index 0000000..72826b8 --- /dev/null +++ b/packages/hw-ledger/cjs/Ledger.js @@ -0,0 +1,117 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Ledger = exports.packageInfo = void 0; +const ledger_substrate_1 = require("@zondax/ledger-substrate"); +const hw_ledger_transports_1 = require("@pezkuwi/hw-ledger-transports"); +const util_1 = require("@pezkuwi/util"); +const constants_js_1 = require("./constants.js"); +const defaults_js_1 = require("./defaults.js"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +/** @internal Wraps a SubstrateApp call, checking the result for any errors which result in a rejection */ +async function wrapError(promise) { + const result = await promise; + if (result.return_code !== constants_js_1.LEDGER_SUCCESS_CODE) { + throw new Error(result.error_message); + } + return result; +} +/** @internal Wraps a sign/signRaw call and returns the associated signature */ +function sign(method, message, accountOffset = 0, addressOffset = 0, { account = constants_js_1.LEDGER_DEFAULT_ACCOUNT, addressIndex = constants_js_1.LEDGER_DEFAULT_INDEX, change = constants_js_1.LEDGER_DEFAULT_CHANGE } = {}) { + return async (app) => { + const { signature } = await wrapError(app[method](account + accountOffset, change, addressIndex + addressOffset, (0, util_1.u8aToBuffer)(message))); + return { + signature: (0, util_1.hexAddPrefix)(signature.toString('hex')) + }; + }; +} +/** + * @name Ledger + * + * @description + * Legacy wrapper for a ledger app - + * - it connects automatically on use, creating an underlying interface as required + * - Promises reject with errors (unwrapped errors from @zondax/ledger-substrate) + * @deprecated Use LedgerGeneric for up to date integration with ledger + */ +class Ledger { + #ledgerName; + #transportDef; + #app = null; + constructor(transport, chain) { + const ledgerName = defaults_js_1.ledgerApps[chain]; + const transportDef = hw_ledger_transports_1.transports.find(({ type }) => type === transport); + if (!ledgerName) { + throw new Error(`Unsupported Ledger chain ${chain}`); + } + else if (!transportDef) { + throw new Error(`Unsupported Ledger transport ${transport}`); + } + this.#ledgerName = ledgerName; + this.#transportDef = transportDef; + } + /** + * Returns the address associated with a specific account & address offset. Optionally + * asks for on-device confirmation + */ + async getAddress(confirm = false, accountOffset = 0, addressOffset = 0, { account = constants_js_1.LEDGER_DEFAULT_ACCOUNT, addressIndex = constants_js_1.LEDGER_DEFAULT_INDEX, change = constants_js_1.LEDGER_DEFAULT_CHANGE } = {}) { + return this.withApp(async (app) => { + const { address, pubKey } = await wrapError(app.getAddress(account + accountOffset, change, addressIndex + addressOffset, confirm)); + return { + address, + publicKey: (0, util_1.hexAddPrefix)(pubKey) + }; + }); + } + /** + * Returns the version of the Ledger application on the device + */ + async getVersion() { + return this.withApp(async (app) => { + const { device_locked: isLocked, major, minor, patch, test_mode: isTestMode } = await wrapError(app.getVersion()); + return { + isLocked, + isTestMode, + version: [major, minor, patch] + }; + }); + } + /** + * Signs a transaction on the Ledger device + */ + async sign(message, accountOffset, addressOffset, options) { + return this.withApp(sign('sign', message, accountOffset, addressOffset, options)); + } + /** + * Signs a message (non-transactional) on the Ledger device + */ + async signRaw(message, accountOffset, addressOffset, options) { + return this.withApp(sign('signRaw', (0, util_1.u8aWrapBytes)(message), accountOffset, addressOffset, options)); + } + /** + * @internal + * + * Returns a created SubstrateApp to perform operations against. Generally + * this is only used internally, to ensure consistent bahavior. + */ + async withApp(fn) { + try { + if (!this.#app) { + const transport = await this.#transportDef.create(); + // We need this override for the actual type passing - the Deno environment + // is quite a bit stricter and it yields invalids between the two (specifically + // since we mangle the imports from .default in the types for CJS/ESM and between + // esm.sh versions this yields problematic outputs) + // + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any + this.#app = (0, ledger_substrate_1.newSubstrateApp)(transport, this.#ledgerName); + } + return await fn(this.#app); + } + catch (error) { + this.#app = null; + throw error; + } + } +} +exports.Ledger = Ledger; diff --git a/packages/hw-ledger/cjs/LedgerGeneric.d.ts b/packages/hw-ledger/cjs/LedgerGeneric.d.ts new file mode 100644 index 0000000..24939bd --- /dev/null +++ b/packages/hw-ledger/cjs/LedgerGeneric.d.ts @@ -0,0 +1,63 @@ +import type { TransportType } from '@pezkuwi/hw-ledger-transports/types'; +import type { AccountOptionsGeneric, LedgerAddress, LedgerSignature, LedgerVersion } from './types.js'; +import { PolkadotGenericApp } from '@zondax/ledger-substrate'; +import { ledgerApps } from './defaults.js'; +export { packageInfo } from './packageInfo.js'; +type Chain = keyof typeof ledgerApps; +/** + * @name Ledger + * + * @description + * A very basic wrapper for a ledger app - + * - it connects automatically on use, creating an underlying interface as required + * - Promises reject with errors (unwrapped errors from @zondax/ledger-substrate-js) + */ +export declare class LedgerGeneric { + #private; + constructor(transport: TransportType, chain: Chain, slip44: number, chainId?: string, metaUrl?: string); + /** + * @description Returns the address associated with a specific Ed25519 account & address offset. Optionally + * asks for on-device confirmation + */ + getAddress(ss58Prefix: number, confirm?: boolean, accountIndex?: number, addressOffset?: number): Promise; + /** + * @description Returns the address associated with a specific ecdsa account & address offset. Optionally + * asks for on-device confirmation + */ + getAddressEcdsa(confirm?: boolean, accountIndex?: number, addressOffset?: number): Promise; + /** + * @description Returns the version of the Ledger application on the device + */ + getVersion(): Promise; + /** + * @description Signs a transaction on the Ledger device. This requires the LedgerGeneric class to be instantiated with `chainId`, and `metaUrl` + */ + sign(message: Uint8Array, accountIndex?: number, addressOffset?: number): Promise; + /** + * @description Signs a message (non-transactional) on the Ledger device + */ + signRaw(message: Uint8Array, accountIndex?: number, addressOffset?: number): Promise; + /** + * @description Signs a transaction on the Ledger device with Ecdsa. This requires the LedgerGeneric class to be instantiated with `chainId`, and `metaUrl` + */ + signEcdsa(message: Uint8Array, accountIndex?: number, addressOffset?: number): Promise; + /** + * @description Signs a message with Ecdsa (non-transactional) on the Ledger device + */ + signRawEcdsa(message: Uint8Array, accountIndex?: number, addressOffset?: number): Promise; + /** + * @description Signs a transaction on the ledger device provided some metadata. + */ + signWithMetadata(message: Uint8Array, accountIndex?: number, addressOffset?: number, options?: Partial): Promise; + /** + * @description Signs a transaction on the ledger device for an ecdsa signature provided some metadata. + */ + signWithMetadataEcdsa(message: Uint8Array, accountIndex?: number, addressOffset?: number, options?: Partial): Promise; + /** + * @internal + * + * Returns a created PolkadotGenericApp to perform operations against. Generally + * this is only used internally, to ensure consistent bahavior. + */ + withApp(fn: (app: PolkadotGenericApp) => Promise): Promise; +} diff --git a/packages/hw-ledger/cjs/LedgerGeneric.js b/packages/hw-ledger/cjs/LedgerGeneric.js new file mode 100644 index 0000000..e3c33ca --- /dev/null +++ b/packages/hw-ledger/cjs/LedgerGeneric.js @@ -0,0 +1,216 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LedgerGeneric = exports.packageInfo = void 0; +const ledger_substrate_1 = require("@zondax/ledger-substrate"); +const hw_ledger_transports_1 = require("@pezkuwi/hw-ledger-transports"); +const util_1 = require("@pezkuwi/util"); +const defaults_js_1 = require("./defaults.js"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +/** @internal Wraps a PolkadotGenericApp call, checking the result for any errors which result in a rejection */ +async function wrapError(promise) { + let result; + try { + result = await promise; + } + catch (e) { + // We check to see if the propogated error is the newer ResponseError type. + // The response code use to be part of the result, but with the latest breaking changes from 0.42.x + // the interface and it's types have completely changed. + if (e.returnCode) { + throw new Error(`${e.returnCode}: ${e.errorMessage}`); + } + throw new Error(e.message); + } + return result; +} +/** @internal Wraps a signEd25519/signRawEd25519 call and returns the associated signature */ +function sign(method, message, slip44, accountIndex = 0, addressOffset = 0) { + const bip42Path = `m/44'/${slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return async (app) => { + const { signature } = await wrapError(app[method](bip42Path, (0, util_1.u8aToBuffer)(message))); + return { + signature: (0, util_1.hexAddPrefix)(signature.toString('hex')) + }; + }; +} +/** @internal Wraps a signEcdsa/signRawEcdsa call and returns the associated signature */ +function signEcdsa(method, message, slip44, accountIndex = 0, addressOffset = 0) { + const bip42Path = `m/44'/${slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return async (app) => { + const { r, s, v } = await wrapError(app[method](bip42Path, (0, util_1.u8aToBuffer)(message))); + const signature = Buffer.concat([r, s, v]); + return { + signature: (0, util_1.hexAddPrefix)(signature.toString('hex')) + }; + }; +} +/** @internal Wraps a signWithMetadataEd25519 call and returns the associated signature */ +function signWithMetadata(message, slip44, accountIndex = 0, addressOffset = 0, { metadata } = {}) { + const bip42Path = `m/44'/${slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return async (app) => { + if (!metadata) { + throw new Error('The metadata option must be present when using signWithMetadata'); + } + const bufferMsg = Buffer.from(message); + const { signature } = await wrapError(app.signWithMetadataEd25519(bip42Path, bufferMsg, metadata)); + return { + signature: (0, util_1.hexAddPrefix)(signature.toString('hex')) + }; + }; +} +/** @internal Wraps a signWithMetadataEcdsa call and returns the associated signature */ +function signWithMetadataEcdsa(message, slip44, accountIndex = 0, addressOffset = 0, { metadata } = {}) { + const bip42Path = `m/44'/${slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return async (app) => { + if (!metadata) { + throw new Error('The metadata option must be present when using signWithMetadata'); + } + const bufferMsg = Buffer.from(message); + const { r, s, v } = await wrapError(app.signWithMetadataEcdsa(bip42Path, bufferMsg, metadata)); + const signature = Buffer.concat([r, s, v]); + return { + signature: (0, util_1.hexAddPrefix)(signature.toString('hex')) + }; + }; +} +/** + * @name Ledger + * + * @description + * A very basic wrapper for a ledger app - + * - it connects automatically on use, creating an underlying interface as required + * - Promises reject with errors (unwrapped errors from @zondax/ledger-substrate-js) + */ +class LedgerGeneric { + #transportDef; + #slip44; + /** + * The chainId is represented by the chains token in all lowercase. Example: Polkadot -> dot + */ + #chainId; + /** + * The metaUrl is seen as a server url that the underlying `PolkadotGenericApp` will use to + * retrieve the signature given a tx blob, and a chainId. It is important to note that if you would like to avoid + * having any network calls made, use `signWithMetadata`, and avoid `sign`. + */ + #metaUrl; + #app = null; + constructor(transport, chain, slip44, chainId, metaUrl) { + const ledgerName = defaults_js_1.ledgerApps[chain]; + const transportDef = hw_ledger_transports_1.transports.find(({ type }) => type === transport); + if (!ledgerName) { + throw new Error(`Unsupported Ledger chain ${chain}`); + } + else if (!transportDef) { + throw new Error(`Unsupported Ledger transport ${transport}`); + } + this.#metaUrl = metaUrl; + this.#chainId = chainId; + this.#slip44 = slip44; + this.#transportDef = transportDef; + } + /** + * @description Returns the address associated with a specific Ed25519 account & address offset. Optionally + * asks for on-device confirmation + */ + async getAddress(ss58Prefix, confirm = false, accountIndex = 0, addressOffset = 0) { + const bip42Path = `m/44'/${this.#slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return this.withApp(async (app) => { + const { address, pubKey } = await wrapError(app.getAddressEd25519(bip42Path, ss58Prefix, confirm)); + return { + address, + publicKey: (0, util_1.hexAddPrefix)(pubKey) + }; + }); + } + /** + * @description Returns the address associated with a specific ecdsa account & address offset. Optionally + * asks for on-device confirmation + */ + async getAddressEcdsa(confirm = false, accountIndex = 0, addressOffset = 0) { + const bip42Path = `m/44'/${this.#slip44}'/${accountIndex}'/${0}'/${addressOffset}'`; + return this.withApp(async (app) => { + const { address, pubKey } = await wrapError(app.getAddressEcdsa(bip42Path, confirm)); + return { + address, + publicKey: (0, util_1.hexAddPrefix)(pubKey) + }; + }); + } + /** + * @description Returns the version of the Ledger application on the device + */ + async getVersion() { + return this.withApp(async (app) => { + const { deviceLocked: isLocked, major, minor, patch, testMode: isTestMode } = await wrapError(app.getVersion()); + return { + isLocked: !!isLocked, + isTestMode: !!isTestMode, + version: [major || 0, minor || 0, patch || 0] + }; + }); + } + /** + * @description Signs a transaction on the Ledger device. This requires the LedgerGeneric class to be instantiated with `chainId`, and `metaUrl` + */ + async sign(message, accountIndex, addressOffset) { + return this.withApp(sign('signEd25519', message, this.#slip44, accountIndex, addressOffset)); + } + /** + * @description Signs a message (non-transactional) on the Ledger device + */ + async signRaw(message, accountIndex, addressOffset) { + return this.withApp(sign('signRawEd25519', (0, util_1.u8aWrapBytes)(message), this.#slip44, accountIndex, addressOffset)); + } + /** + * @description Signs a transaction on the Ledger device with Ecdsa. This requires the LedgerGeneric class to be instantiated with `chainId`, and `metaUrl` + */ + async signEcdsa(message, accountIndex, addressOffset) { + return this.withApp(signEcdsa('signEcdsa', (0, util_1.u8aWrapBytes)(message), this.#slip44, accountIndex, addressOffset)); + } + /** + * @description Signs a message with Ecdsa (non-transactional) on the Ledger device + */ + async signRawEcdsa(message, accountIndex, addressOffset) { + return this.withApp(signEcdsa('signRawEcdsa', (0, util_1.u8aWrapBytes)(message), this.#slip44, accountIndex, addressOffset)); + } + /** + * @description Signs a transaction on the ledger device provided some metadata. + */ + async signWithMetadata(message, accountIndex, addressOffset, options) { + return this.withApp(signWithMetadata(message, this.#slip44, accountIndex, addressOffset, options)); + } + /** + * @description Signs a transaction on the ledger device for an ecdsa signature provided some metadata. + */ + async signWithMetadataEcdsa(message, accountIndex, addressOffset, options) { + return this.withApp(signWithMetadataEcdsa(message, this.#slip44, accountIndex, addressOffset, options)); + } + /** + * @internal + * + * Returns a created PolkadotGenericApp to perform operations against. Generally + * this is only used internally, to ensure consistent bahavior. + */ + async withApp(fn) { + try { + if (!this.#app) { + const transport = await this.#transportDef.create(); + // We need this override for the actual type passing - the Deno environment + // is quite a bit stricter and it yields invalids between the two (specifically + // since we mangle the imports from .default in the types for CJS/ESM and between + // esm.sh versions this yields problematic outputs) + // + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any + this.#app = new ledger_substrate_1.PolkadotGenericApp(transport, this.#chainId, this.#metaUrl); + } + return await fn(this.#app); + } + catch (error) { + this.#app = null; + throw error; + } + } +} +exports.LedgerGeneric = LedgerGeneric; diff --git a/packages/hw-ledger/cjs/bundle.d.ts b/packages/hw-ledger/cjs/bundle.d.ts new file mode 100644 index 0000000..f5cbfe5 --- /dev/null +++ b/packages/hw-ledger/cjs/bundle.d.ts @@ -0,0 +1,2 @@ +export { Ledger } from './Ledger.js'; +export { LedgerGeneric } from './LedgerGeneric.js'; diff --git a/packages/hw-ledger/cjs/bundle.js b/packages/hw-ledger/cjs/bundle.js new file mode 100644 index 0000000..4a10c8c --- /dev/null +++ b/packages/hw-ledger/cjs/bundle.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LedgerGeneric = exports.Ledger = void 0; +var Ledger_js_1 = require("./Ledger.js"); +Object.defineProperty(exports, "Ledger", { enumerable: true, get: function () { return Ledger_js_1.Ledger; } }); +var LedgerGeneric_js_1 = require("./LedgerGeneric.js"); +Object.defineProperty(exports, "LedgerGeneric", { enumerable: true, get: function () { return LedgerGeneric_js_1.LedgerGeneric; } }); diff --git a/packages/hw-ledger/cjs/constants.d.ts b/packages/hw-ledger/cjs/constants.d.ts new file mode 100644 index 0000000..cdf8d68 --- /dev/null +++ b/packages/hw-ledger/cjs/constants.d.ts @@ -0,0 +1,4 @@ +export declare const LEDGER_DEFAULT_ACCOUNT = 2147483648; +export declare const LEDGER_DEFAULT_CHANGE = 2147483648; +export declare const LEDGER_DEFAULT_INDEX = 2147483648; +export declare const LEDGER_SUCCESS_CODE = 36864; diff --git a/packages/hw-ledger/cjs/constants.js b/packages/hw-ledger/cjs/constants.js new file mode 100644 index 0000000..a75aabc --- /dev/null +++ b/packages/hw-ledger/cjs/constants.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LEDGER_SUCCESS_CODE = exports.LEDGER_DEFAULT_INDEX = exports.LEDGER_DEFAULT_CHANGE = exports.LEDGER_DEFAULT_ACCOUNT = void 0; +exports.LEDGER_DEFAULT_ACCOUNT = 0x80000000; +exports.LEDGER_DEFAULT_CHANGE = 0x80000000; +exports.LEDGER_DEFAULT_INDEX = 0x80000000; +exports.LEDGER_SUCCESS_CODE = 0x9000; diff --git a/packages/hw-ledger/cjs/defaults.d.ts b/packages/hw-ledger/cjs/defaults.d.ts new file mode 100644 index 0000000..6ef324f --- /dev/null +++ b/packages/hw-ledger/cjs/defaults.d.ts @@ -0,0 +1,14 @@ +export declare const prevLedgerRecord: Record; +export declare const genericLedgerApps: { + bittensor: string; + creditcoin3: string; + dentnet: string; + encointer: string; + frequency: string; + integritee: string; + liberland: string; + mythos: string; + polimec: string; + vara: string; +}; +export declare const ledgerApps: Record; diff --git a/packages/hw-ledger/cjs/defaults.js b/packages/hw-ledger/cjs/defaults.js new file mode 100644 index 0000000..46294ca --- /dev/null +++ b/packages/hw-ledger/cjs/defaults.js @@ -0,0 +1,61 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ledgerApps = exports.genericLedgerApps = exports.prevLedgerRecord = void 0; +exports.prevLedgerRecord = { + acala: 'Acala', + ajuna: 'Ajuna', + 'aleph-node': 'AlephZero', + astar: 'Astar', + bifrost: 'Bifrost', + 'bifrost-kusama': 'BifrostKusama', + centrifuge: 'Centrifuge', + composable: 'Composable', + darwinia: 'Darwinia', + 'dock-mainnet': 'Dock', + edgeware: 'Edgeware', + enjin: 'Enjin', + equilibrium: 'Equilibrium', + genshiro: 'Genshiro', + hydradx: 'HydraDX', + 'interlay-parachain': 'Interlay', + karura: 'Karura', + khala: 'Khala', + kusama: 'Kusama', + matrixchain: 'Matrixchain', + nodle: 'Nodle', + origintrail: 'OriginTrail', + parallel: 'Parallel', + peaq: 'Peaq', + pendulum: 'Pendulum', + phala: 'Phala', + picasso: 'Picasso', + polkadex: 'Polkadex', + polkadot: 'Polkadot', + polymesh: 'Polymesh', + quartz: 'Quartz', + sora: 'Sora', + stafi: 'Stafi', + statemine: 'Statemine', + statemint: 'Statemint', + ternoa: 'Ternoa', + unique: 'Unique', + vtb: 'VTB', + xxnetwork: 'XXNetwork', + zeitgeist: 'Zeitgeist' +}; +exports.genericLedgerApps = { + bittensor: 'Bittensor', + creditcoin3: 'Creditcoin3', + dentnet: 'DENTNet', + encointer: 'Encointer', + frequency: 'Frequency', + integritee: 'Integritee', + liberland: 'Liberland', + mythos: 'Mythos', + polimec: 'Polimec', + vara: 'Vara' +}; +exports.ledgerApps = { + ...exports.prevLedgerRecord, + ...exports.genericLedgerApps +}; diff --git a/packages/hw-ledger/cjs/index.d.ts b/packages/hw-ledger/cjs/index.d.ts new file mode 100644 index 0000000..ca3f403 --- /dev/null +++ b/packages/hw-ledger/cjs/index.d.ts @@ -0,0 +1,2 @@ +import './packageDetect.js'; +export * from './bundle.js'; diff --git a/packages/hw-ledger/cjs/index.js b/packages/hw-ledger/cjs/index.js new file mode 100644 index 0000000..6d0bab1 --- /dev/null +++ b/packages/hw-ledger/cjs/index.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +require("./packageDetect.js"); +tslib_1.__exportStar(require("./bundle.js"), exports); diff --git a/packages/hw-ledger/cjs/package.json b/packages/hw-ledger/cjs/package.json new file mode 100644 index 0000000..5bbefff --- /dev/null +++ b/packages/hw-ledger/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/hw-ledger/cjs/packageDetect.d.ts b/packages/hw-ledger/cjs/packageDetect.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/hw-ledger/cjs/packageDetect.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/hw-ledger/cjs/packageDetect.js b/packages/hw-ledger/cjs/packageDetect.js new file mode 100644 index 0000000..d7f32a6 --- /dev/null +++ b/packages/hw-ledger/cjs/packageDetect.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const packageInfo_1 = require("@pezkuwi/hw-ledger-transports/cjs/packageInfo"); +const util_1 = require("@pezkuwi/util"); +const packageInfo_2 = require("@pezkuwi/util/cjs/packageInfo"); +const packageInfo_js_1 = require("./packageInfo.js"); +(0, util_1.detectPackage)(packageInfo_js_1.packageInfo, null, [packageInfo_1.packageInfo, packageInfo_2.packageInfo]); diff --git a/packages/hw-ledger/cjs/packageInfo.d.ts b/packages/hw-ledger/cjs/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/hw-ledger/cjs/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/hw-ledger/cjs/packageInfo.js b/packages/hw-ledger/cjs/packageInfo.js new file mode 100644 index 0000000..a6e4f8c --- /dev/null +++ b/packages/hw-ledger/cjs/packageInfo.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +exports.packageInfo = { name: '@pezkuwi/hw-ledger', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; diff --git a/packages/hw-ledger/cjs/types.d.ts b/packages/hw-ledger/cjs/types.d.ts new file mode 100644 index 0000000..858348e --- /dev/null +++ b/packages/hw-ledger/cjs/types.d.ts @@ -0,0 +1,34 @@ +import type { HexString } from '@pezkuwi/util/types'; +/** + * Legacy Type that works with the `Ledger` class. + */ +export interface AccountOptions { + /** The index of the account */ + account: number; + /** The index of the address */ + addressIndex: number; + /** The change to apply */ + change: number; +} +export interface AccountOptionsGeneric extends AccountOptions { + /** Option for PolkadotGenericApp.signWithMetadata */ + metadata: Buffer; +} +export interface LedgerAddress { + /** The ss58 encoded address */ + address: string; + /** The hex-encoded publicKey */ + publicKey: HexString; +} +export interface LedgerSignature { + /** A hex-encoded signature, as generated by the device */ + signature: HexString; +} +export interface LedgerVersion { + /** Indicator flag for locked status */ + isLocked: boolean; + /** Indicator flag for testmode status */ + isTestMode: boolean; + /** The software version for this device */ + version: [major: number, minor: number, patch: number]; +} diff --git a/packages/hw-ledger/cjs/types.js b/packages/hw-ledger/cjs/types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/packages/hw-ledger/cjs/types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/packages/hw-ledger/constants.d.ts b/packages/hw-ledger/constants.d.ts new file mode 100644 index 0000000..cdf8d68 --- /dev/null +++ b/packages/hw-ledger/constants.d.ts @@ -0,0 +1,4 @@ +export declare const LEDGER_DEFAULT_ACCOUNT = 2147483648; +export declare const LEDGER_DEFAULT_CHANGE = 2147483648; +export declare const LEDGER_DEFAULT_INDEX = 2147483648; +export declare const LEDGER_SUCCESS_CODE = 36864; diff --git a/packages/hw-ledger/constants.js b/packages/hw-ledger/constants.js new file mode 100644 index 0000000..fe87f98 --- /dev/null +++ b/packages/hw-ledger/constants.js @@ -0,0 +1,4 @@ +export const LEDGER_DEFAULT_ACCOUNT = 0x80000000; +export const LEDGER_DEFAULT_CHANGE = 0x80000000; +export const LEDGER_DEFAULT_INDEX = 0x80000000; +export const LEDGER_SUCCESS_CODE = 0x9000; diff --git a/packages/hw-ledger/defaults.d.ts b/packages/hw-ledger/defaults.d.ts new file mode 100644 index 0000000..6ef324f --- /dev/null +++ b/packages/hw-ledger/defaults.d.ts @@ -0,0 +1,14 @@ +export declare const prevLedgerRecord: Record; +export declare const genericLedgerApps: { + bittensor: string; + creditcoin3: string; + dentnet: string; + encointer: string; + frequency: string; + integritee: string; + liberland: string; + mythos: string; + polimec: string; + vara: string; +}; +export declare const ledgerApps: Record; diff --git a/packages/hw-ledger/defaults.js b/packages/hw-ledger/defaults.js new file mode 100644 index 0000000..6710c49 --- /dev/null +++ b/packages/hw-ledger/defaults.js @@ -0,0 +1,58 @@ +export const prevLedgerRecord = { + acala: 'Acala', + ajuna: 'Ajuna', + 'aleph-node': 'AlephZero', + astar: 'Astar', + bifrost: 'Bifrost', + 'bifrost-kusama': 'BifrostKusama', + centrifuge: 'Centrifuge', + composable: 'Composable', + darwinia: 'Darwinia', + 'dock-mainnet': 'Dock', + edgeware: 'Edgeware', + enjin: 'Enjin', + equilibrium: 'Equilibrium', + genshiro: 'Genshiro', + hydradx: 'HydraDX', + 'interlay-parachain': 'Interlay', + karura: 'Karura', + khala: 'Khala', + kusama: 'Kusama', + matrixchain: 'Matrixchain', + nodle: 'Nodle', + origintrail: 'OriginTrail', + parallel: 'Parallel', + peaq: 'Peaq', + pendulum: 'Pendulum', + phala: 'Phala', + picasso: 'Picasso', + polkadex: 'Polkadex', + polkadot: 'Polkadot', + polymesh: 'Polymesh', + quartz: 'Quartz', + sora: 'Sora', + stafi: 'Stafi', + statemine: 'Statemine', + statemint: 'Statemint', + ternoa: 'Ternoa', + unique: 'Unique', + vtb: 'VTB', + xxnetwork: 'XXNetwork', + zeitgeist: 'Zeitgeist' +}; +export const genericLedgerApps = { + bittensor: 'Bittensor', + creditcoin3: 'Creditcoin3', + dentnet: 'DENTNet', + encointer: 'Encointer', + frequency: 'Frequency', + integritee: 'Integritee', + liberland: 'Liberland', + mythos: 'Mythos', + polimec: 'Polimec', + vara: 'Vara' +}; +export const ledgerApps = { + ...prevLedgerRecord, + ...genericLedgerApps +}; diff --git a/packages/hw-ledger/index.d.ts b/packages/hw-ledger/index.d.ts new file mode 100644 index 0000000..ca3f403 --- /dev/null +++ b/packages/hw-ledger/index.d.ts @@ -0,0 +1,2 @@ +import './packageDetect.js'; +export * from './bundle.js'; diff --git a/packages/hw-ledger/index.js b/packages/hw-ledger/index.js new file mode 100644 index 0000000..ca3f403 --- /dev/null +++ b/packages/hw-ledger/index.js @@ -0,0 +1,2 @@ +import './packageDetect.js'; +export * from './bundle.js'; diff --git a/packages/hw-ledger/package.json b/packages/hw-ledger/package.json index fff667d..a7fa3e3 100644 --- a/packages/hw-ledger/package.json +++ b/packages/hw-ledger/package.json @@ -14,14 +14,164 @@ }, "sideEffects": [ "./packageDetect.js", - "./packageDetect.cjs" + "./cjs/packageDetect.js" ], "type": "module", - "version": "14.0.10", - "main": "index.js", + "version": "14.0.11", + "main": "./cjs/index.js", + "module": "./index.js", + "types": "./index.d.ts", + "exports": { + "./cjs/package.json": "./cjs/package.json", + "./cjs/*": "./cjs/*.js", + ".": { + "module": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "require": { + "types": "./cjs/index.d.ts", + "default": "./cjs/index.js" + }, + "default": { + "types": "./index.d.ts", + "default": "./index.js" + } + }, + "./bundle": { + "module": { + "types": "./bundle.d.ts", + "default": "./bundle.js" + }, + "require": { + "types": "./cjs/bundle.d.ts", + "default": "./cjs/bundle.js" + }, + "default": { + "types": "./bundle.d.ts", + "default": "./bundle.js" + } + }, + "./constants": { + "module": { + "types": "./constants.d.ts", + "default": "./constants.js" + }, + "require": { + "types": "./cjs/constants.d.ts", + "default": "./cjs/constants.js" + }, + "default": { + "types": "./constants.d.ts", + "default": "./constants.js" + } + }, + "./defaults": { + "module": { + "types": "./defaults.d.ts", + "default": "./defaults.js" + }, + "require": { + "types": "./cjs/defaults.d.ts", + "default": "./cjs/defaults.js" + }, + "default": { + "types": "./defaults.d.ts", + "default": "./defaults.js" + } + }, + "./Ledger": { + "module": { + "types": "./Ledger.d.ts", + "default": "./Ledger.js" + }, + "require": { + "types": "./cjs/Ledger.d.ts", + "default": "./cjs/Ledger.js" + }, + "default": { + "types": "./Ledger.d.ts", + "default": "./Ledger.js" + } + }, + "./LedgerGeneric": { + "module": { + "types": "./LedgerGeneric.d.ts", + "default": "./LedgerGeneric.js" + }, + "require": { + "types": "./cjs/LedgerGeneric.d.ts", + "default": "./cjs/LedgerGeneric.js" + }, + "default": { + "types": "./LedgerGeneric.d.ts", + "default": "./LedgerGeneric.js" + } + }, + "./package.json": { + "require": "./cjs/package.json", + "default": "./package.json" + }, + "./packageDetect": { + "module": { + "types": "./packageDetect.d.ts", + "default": "./packageDetect.js" + }, + "require": { + "types": "./cjs/packageDetect.d.ts", + "default": "./cjs/packageDetect.js" + }, + "default": { + "types": "./packageDetect.d.ts", + "default": "./packageDetect.js" + } + }, + "./packageInfo.js": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./packageInfo": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./types": { + "module": { + "types": "./types.d.ts", + "default": "./types.js" + }, + "require": { + "types": "./cjs/types.d.ts", + "default": "./cjs/types.js" + }, + "default": { + "types": "./types.d.ts", + "default": "./types.js" + } + } + }, "dependencies": { - "@pezkuwi/hw-ledger-transports": "workspace:*", - "@pezkuwi/util": "workspace:*", + "@pezkuwi/hw-ledger-transports": "14.0.11", + "@pezkuwi/util": "14.0.11", "@zondax/ledger-substrate": "1.1.1", "tslib": "^2.8.0" } diff --git a/packages/hw-ledger/packageDetect.d.ts b/packages/hw-ledger/packageDetect.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/hw-ledger/packageDetect.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/hw-ledger/packageDetect.js b/packages/hw-ledger/packageDetect.js new file mode 100644 index 0000000..d718773 --- /dev/null +++ b/packages/hw-ledger/packageDetect.js @@ -0,0 +1,5 @@ +import { packageInfo as transportInfo } from '@pezkuwi/hw-ledger-transports/packageInfo'; +import { detectPackage } from '@pezkuwi/util'; +import { packageInfo as utilInfo } from '@pezkuwi/util/packageInfo'; +import { packageInfo } from './packageInfo.js'; +detectPackage(packageInfo, null, [transportInfo, utilInfo]); diff --git a/packages/hw-ledger/packageInfo.d.ts b/packages/hw-ledger/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/hw-ledger/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/hw-ledger/packageInfo.js b/packages/hw-ledger/packageInfo.js new file mode 100644 index 0000000..4161bc9 --- /dev/null +++ b/packages/hw-ledger/packageInfo.js @@ -0,0 +1 @@ +export const packageInfo = { name: '@pezkuwi/hw-ledger', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; diff --git a/packages/hw-ledger/types.d.ts b/packages/hw-ledger/types.d.ts new file mode 100644 index 0000000..858348e --- /dev/null +++ b/packages/hw-ledger/types.d.ts @@ -0,0 +1,34 @@ +import type { HexString } from '@pezkuwi/util/types'; +/** + * Legacy Type that works with the `Ledger` class. + */ +export interface AccountOptions { + /** The index of the account */ + account: number; + /** The index of the address */ + addressIndex: number; + /** The change to apply */ + change: number; +} +export interface AccountOptionsGeneric extends AccountOptions { + /** Option for PolkadotGenericApp.signWithMetadata */ + metadata: Buffer; +} +export interface LedgerAddress { + /** The ss58 encoded address */ + address: string; + /** The hex-encoded publicKey */ + publicKey: HexString; +} +export interface LedgerSignature { + /** A hex-encoded signature, as generated by the device */ + signature: HexString; +} +export interface LedgerVersion { + /** Indicator flag for locked status */ + isLocked: boolean; + /** Indicator flag for testmode status */ + isTestMode: boolean; + /** The software version for this device */ + version: [major: number, minor: number, patch: number]; +} diff --git a/packages/hw-ledger/types.js b/packages/hw-ledger/types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/hw-ledger/types.js @@ -0,0 +1 @@ +export {}; diff --git a/packages/keyring/bundle-pezkuwi-keyring.js b/packages/keyring/bundle-pezkuwi-keyring.js new file mode 100644 index 0000000..a1ad3d5 --- /dev/null +++ b/packages/keyring/bundle-pezkuwi-keyring.js @@ -0,0 +1,553 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@pezkuwi/util-crypto'), require('@pezkuwi/util')) : + typeof define === 'function' && define.amd ? define(['exports', '@pezkuwi/util-crypto', '@pezkuwi/util'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.pezkuwiKeyring = {}, global.pezkuwiUtilCrypto, global.pezkuwiUtil)); +})(this, (function (exports, utilCrypto, util) { 'use strict'; + + const global = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : window; + + var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null; + const PAIR_DIV = new Uint8Array([161, 35, 3, 33, 0]); + const PAIR_HDR = new Uint8Array([48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32]); + const PUB_LENGTH = 32; + const SEC_LENGTH = 64; + const SEED_LENGTH = 32; + + const SEED_OFFSET = PAIR_HDR.length; + function decodePair(passphrase, encrypted, _encType) { + const encType = Array.isArray(_encType) || _encType === undefined + ? _encType + : [_encType]; + const decrypted = utilCrypto.jsonDecryptData(encrypted, passphrase, encType); + const header = decrypted.subarray(0, PAIR_HDR.length); + if (!util.u8aEq(header, PAIR_HDR)) { + throw new Error('Invalid encoding header found in body'); + } + let secretKey = decrypted.subarray(SEED_OFFSET, SEED_OFFSET + SEC_LENGTH); + let divOffset = SEED_OFFSET + SEC_LENGTH; + let divider = decrypted.subarray(divOffset, divOffset + PAIR_DIV.length); + if (!util.u8aEq(divider, PAIR_DIV)) { + divOffset = SEED_OFFSET + SEED_LENGTH; + secretKey = decrypted.subarray(SEED_OFFSET, divOffset); + divider = decrypted.subarray(divOffset, divOffset + PAIR_DIV.length); + if (!util.u8aEq(divider, PAIR_DIV)) { + throw new Error('Invalid encoding divider found in body'); + } + } + const pubOffset = divOffset + PAIR_DIV.length; + const publicKey = decrypted.subarray(pubOffset, pubOffset + PUB_LENGTH); + return { + publicKey, + secretKey + }; + } + + function encodePair({ publicKey, secretKey }, passphrase) { + if (!secretKey) { + throw new Error('Expected a valid secretKey to be passed to encode'); + } + const encoded = util.u8aConcat(PAIR_HDR, secretKey, PAIR_DIV, publicKey); + if (!passphrase) { + return encoded; + } + const { params, password, salt } = utilCrypto.scryptEncode(passphrase); + const { encrypted, nonce } = utilCrypto.naclEncrypt(encoded, password.subarray(0, 32)); + return util.u8aConcat(utilCrypto.scryptToU8a(salt, params), nonce, encrypted); + } + + function pairToJson(type, { address, meta }, encoded, isEncrypted) { + return util.objectSpread(utilCrypto.jsonEncryptFormat(encoded, ['pkcs8', type], isEncrypted), { + address, + meta + }); + } + + const SIG_TYPE_NONE = new Uint8Array(); + const TYPE_FROM_SEED = { + ecdsa: utilCrypto.secp256k1PairFromSeed, + ed25519: utilCrypto.ed25519PairFromSeed, + ethereum: utilCrypto.secp256k1PairFromSeed, + sr25519: utilCrypto.sr25519PairFromSeed + }; + const TYPE_PREFIX = { + ecdsa: new Uint8Array([2]), + ed25519: new Uint8Array([0]), + ethereum: new Uint8Array([2]), + sr25519: new Uint8Array([1]) + }; + const TYPE_SIGNATURE = { + ecdsa: (m, p) => utilCrypto.secp256k1Sign(m, p, 'blake2'), + ed25519: utilCrypto.ed25519Sign, + ethereum: (m, p) => utilCrypto.secp256k1Sign(m, p, 'keccak'), + sr25519: utilCrypto.sr25519Sign + }; + const TYPE_ADDRESS = { + ecdsa: (p) => p.length > 32 ? utilCrypto.blake2AsU8a(p) : p, + ed25519: (p) => p, + ethereum: (p) => p.length === 20 ? p : utilCrypto.keccakAsU8a(utilCrypto.secp256k1Expand(p)), + sr25519: (p) => p + }; + function isLocked(secretKey) { + return !secretKey || util.u8aEmpty(secretKey); + } + function vrfHash(proof, context, extra) { + return utilCrypto.blake2AsU8a(util.u8aConcat(context || '', extra || '', proof)); + } + function createPair({ toSS58, type }, { publicKey, secretKey }, meta = {}, encoded = null, encTypes) { + const decodePkcs8 = (passphrase, userEncoded) => { + const decoded = decodePair(passphrase, userEncoded || encoded, encTypes); + if (decoded.secretKey.length === 64) { + publicKey = decoded.publicKey; + secretKey = decoded.secretKey; + } + else { + const pair = TYPE_FROM_SEED[type](decoded.secretKey); + publicKey = pair.publicKey; + secretKey = pair.secretKey; + } + }; + const recode = (passphrase) => { + isLocked(secretKey) && encoded && decodePkcs8(passphrase, encoded); + encoded = encodePair({ publicKey, secretKey }, passphrase); + encTypes = undefined; + return encoded; + }; + const encodeAddress = () => { + const raw = TYPE_ADDRESS[type](publicKey); + return type === 'ethereum' + ? utilCrypto.ethereumEncode(raw) + : toSS58(raw); + }; + return { + get address() { + return encodeAddress(); + }, + get addressRaw() { + const raw = TYPE_ADDRESS[type](publicKey); + return type === 'ethereum' + ? raw.slice(-20) + : raw; + }, + get isLocked() { + return isLocked(secretKey); + }, + get meta() { + return meta; + }, + get publicKey() { + return publicKey; + }, + get type() { + return type; + }, + decodePkcs8, + derive: (suri, meta) => { + if (type === 'ethereum') { + throw new Error('Unable to derive on this keypair'); + } + else if (isLocked(secretKey)) { + throw new Error('Cannot derive on a locked keypair'); + } + const { path } = utilCrypto.keyExtractPath(suri); + const derived = utilCrypto.keyFromPath({ publicKey, secretKey }, path, type); + return createPair({ toSS58, type }, derived, meta, null); + }, + encodePkcs8: (passphrase) => { + return recode(passphrase); + }, + lock: () => { + secretKey = new Uint8Array(); + }, + setMeta: (additional) => { + meta = util.objectSpread({}, meta, additional); + }, + sign: (message, options = {}) => { + if (isLocked(secretKey)) { + throw new Error('Cannot sign with a locked key pair'); + } + return util.u8aConcat(options.withType + ? TYPE_PREFIX[type] + : SIG_TYPE_NONE, TYPE_SIGNATURE[type](util.u8aToU8a(message), { publicKey, secretKey })); + }, + toJson: (passphrase) => { + const address = ['ecdsa', 'ethereum'].includes(type) + ? publicKey.length === 20 + ? util.u8aToHex(publicKey) + : util.u8aToHex(utilCrypto.secp256k1Compress(publicKey)) + : encodeAddress(); + return pairToJson(type, { address, meta }, recode(passphrase), !!passphrase); + }, + unlock: (passphrase) => { + return decodePkcs8(passphrase); + }, + verify: (message, signature, signerPublic) => { + return utilCrypto.signatureVerify(message, signature, TYPE_ADDRESS[type](util.u8aToU8a(signerPublic))).isValid; + }, + vrfSign: (message, context, extra) => { + if (isLocked(secretKey)) { + throw new Error('Cannot sign with a locked key pair'); + } + if (type === 'sr25519') { + return utilCrypto.sr25519VrfSign(message, { secretKey }, context, extra); + } + const proof = TYPE_SIGNATURE[type](util.u8aToU8a(message), { publicKey, secretKey }); + return util.u8aConcat(vrfHash(proof, context, extra), proof); + }, + vrfVerify: (message, vrfResult, signerPublic, context, extra) => { + if (type === 'sr25519') { + return utilCrypto.sr25519VrfVerify(message, vrfResult, publicKey, context, extra); + } + const result = utilCrypto.signatureVerify(message, util.u8aConcat(TYPE_PREFIX[type], vrfResult.subarray(32)), TYPE_ADDRESS[type](util.u8aToU8a(signerPublic))); + return result.isValid && util.u8aEq(vrfResult.subarray(0, 32), vrfHash(vrfResult.subarray(32), context, extra)); + } + }; + } + + const DEV_PHRASE = 'bottom drive obey lake curtain smoke basket hold race lonely fit walk'; + const DEV_SEED = '0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e'; + + class Pairs { + #map = {}; + add(pair) { + this.#map[utilCrypto.decodeAddress(pair.address).toString()] = pair; + return pair; + } + all() { + return Object.values(this.#map); + } + get(address) { + const pair = this.#map[utilCrypto.decodeAddress(address).toString()]; + if (!pair) { + throw new Error(`Unable to retrieve keypair '${util.isU8a(address) || util.isHex(address) + ? util.u8aToHex(util.u8aToU8a(address)) + : address}'`); + } + return pair; + } + remove(address) { + delete this.#map[utilCrypto.decodeAddress(address).toString()]; + } + } + + const PairFromSeed = { + ecdsa: (seed) => utilCrypto.secp256k1PairFromSeed(seed), + ed25519: (seed) => utilCrypto.ed25519PairFromSeed(seed), + ethereum: (seed) => utilCrypto.secp256k1PairFromSeed(seed), + sr25519: (seed) => utilCrypto.sr25519PairFromSeed(seed) + }; + function pairToPublic({ publicKey }) { + return publicKey; + } + class Keyring { + #pairs; + #type; + #ss58; + decodeAddress = utilCrypto.decodeAddress; + constructor(options = {}) { + options.type = options.type || 'ed25519'; + if (!['ecdsa', 'ethereum', 'ed25519', 'sr25519'].includes(options.type || 'undefined')) { + throw new Error(`Expected a keyring type of either 'ed25519', 'sr25519', 'ethereum' or 'ecdsa', found '${options.type || 'unknown'}`); + } + this.#pairs = new Pairs(); + this.#ss58 = options.ss58Format; + this.#type = options.type; + } + get pairs() { + return this.getPairs(); + } + get publicKeys() { + return this.getPublicKeys(); + } + get type() { + return this.#type; + } + addPair(pair) { + return this.#pairs.add(pair); + } + addFromAddress(address, meta = {}, encoded = null, type = this.type, ignoreChecksum, encType) { + const publicKey = this.decodeAddress(address, ignoreChecksum); + return this.addPair(createPair({ toSS58: this.encodeAddress, type }, { publicKey, secretKey: new Uint8Array() }, meta, encoded, encType)); + } + addFromJson(json, ignoreChecksum) { + return this.addPair(this.createFromJson(json, ignoreChecksum)); + } + addFromMnemonic(mnemonic, meta = {}, type = this.type, wordlist) { + return this.addFromUri(mnemonic, meta, type, wordlist); + } + addFromPair(pair, meta = {}, type = this.type) { + return this.addPair(this.createFromPair(pair, meta, type)); + } + addFromSeed(seed, meta = {}, type = this.type) { + return this.addPair(createPair({ toSS58: this.encodeAddress, type }, PairFromSeed[type](seed), meta, null)); + } + addFromUri(suri, meta = {}, type = this.type, wordlist) { + return this.addPair(this.createFromUri(suri, meta, type, wordlist)); + } + createFromJson({ address, encoded, encoding: { content, type, version }, meta }, ignoreChecksum) { + if (version === '3' && content[0] !== 'pkcs8') { + throw new Error(`Unable to decode non-pkcs8 type, [${content.join(',')}] found}`); + } + const cryptoType = version === '0' || !Array.isArray(content) + ? this.type + : content[1]; + const encType = !Array.isArray(type) + ? [type] + : type; + if (!['ed25519', 'sr25519', 'ecdsa', 'ethereum'].includes(cryptoType)) { + throw new Error(`Unknown crypto type ${cryptoType}`); + } + const publicKey = util.isHex(address) + ? util.hexToU8a(address) + : this.decodeAddress(address, ignoreChecksum); + const decoded = util.isHex(encoded) + ? util.hexToU8a(encoded) + : utilCrypto.base64Decode(encoded); + return createPair({ toSS58: this.encodeAddress, type: cryptoType }, { publicKey, secretKey: new Uint8Array() }, meta, decoded, encType); + } + createFromPair(pair, meta = {}, type = this.type) { + return createPair({ toSS58: this.encodeAddress, type }, pair, meta, null); + } + createFromUri(_suri, meta = {}, type = this.type, wordlist) { + const suri = _suri.startsWith('//') + ? `${DEV_PHRASE}${_suri}` + : _suri; + const { derivePath, password, path, phrase } = utilCrypto.keyExtractSuri(suri); + let seed; + const isPhraseHex = util.isHex(phrase, 256); + if (isPhraseHex) { + seed = util.hexToU8a(phrase); + } + else { + const parts = phrase.split(' '); + if ([12, 15, 18, 21, 24].includes(parts.length)) { + seed = type === 'ethereum' + ? utilCrypto.mnemonicToLegacySeed(phrase, '', false, 64) + : utilCrypto.mnemonicToMiniSecret(phrase, password, wordlist); + } + else { + if (phrase.length > 32) { + throw new Error('specified phrase is not a valid mnemonic and is invalid as a raw seed at > 32 bytes'); + } + seed = util.stringToU8a(phrase.padEnd(32)); + } + } + const derived = type === 'ethereum' + ? isPhraseHex + ? PairFromSeed[type](seed) + : utilCrypto.hdEthereum(seed, derivePath.substring(1)) + : utilCrypto.keyFromPath(PairFromSeed[type](seed), path, type); + return createPair({ toSS58: this.encodeAddress, type }, derived, meta, null); + } + encodeAddress = (address, ss58Format) => { + return this.type === 'ethereum' + ? utilCrypto.ethereumEncode(address) + : utilCrypto.encodeAddress(address, ss58Format ?? this.#ss58); + }; + getPair(address) { + return this.#pairs.get(address); + } + getPairs() { + return this.#pairs.all(); + } + getPublicKeys() { + return this.#pairs.all().map(pairToPublic); + } + removePair(address) { + this.#pairs.remove(address); + } + setSS58Format(ss58) { + this.#ss58 = ss58; + } + toJson(address, passphrase) { + return this.#pairs.get(address).toJson(passphrase); + } + } + + const packageInfo = { name: '@pezkuwi/keyring', path: (({ url: (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-keyring.js', document.baseURI).href)) }) && (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-keyring.js', document.baseURI).href))) ? new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-keyring.js', document.baseURI).href))).pathname.substring(0, new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-keyring.js', document.baseURI).href))).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; + + const PAIRSSR25519 = [ + { + p: '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d', + s: '0x98319d4ff8a9508c4bb0cf0b5a78d760a0b2082c02775e6e82370816fedfff48925a225d97aa00682d6a59b95b18780c10d7032336e88f3442b42361f4a66011', + seed: 'Alice', + type: 'sr25519' + }, + { + p: '0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f', + s: '0xe8da6c9d810e020f5e3c7f5af2dea314cbeaa0d72bc6421e92c0808a0c584a6046ab28e97c3ffc77fe12b5a4d37e8cd4afbfebbf2391ffc7cb07c0f38c023efd', + seed: 'Alice//stash', + type: 'sr25519' + }, + { + p: '0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48', + s: '0x081ff694633e255136bdb456c20a5fc8fed21f8b964c11bb17ff534ce80ebd5941ae88f85d0c1bfc37be41c904e1dfc01de8c8067b0d6d5df25dd1ac0894a325', + seed: 'Bob', + type: 'sr25519' + }, + { + p: '0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e', + s: '0xc006507cdfc267a21532394c49ca9b754ca71de21e15a1cdf807c7ceab6d0b6c3ed408d9d35311540dcd54931933e67cf1ea10d46f75408f82b789d9bd212fde', + seed: 'Bob//stash', + type: 'sr25519' + }, + { + p: '0x90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22', + s: '0xa8f2d83016052e5d6d77b2f6fd5d59418922a09024cda701b3c34369ec43a7668faf12ff39cd4e5d92bb773972f41a7a5279ebc2ed92264bed8f47d344f8f18c', + seed: 'Charlie', + type: 'sr25519' + }, + { + p: '0x306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20', + s: '0x20e05482ca4677e0edbc58ae9a3a59f6ed3b1a9484ba17e64d6fe8688b2b7b5d108c4487b9323b98b11fe36cb301b084e920f7b7895536809a6d62a451b25568', + seed: 'Dave', + type: 'sr25519' + }, + { + p: '0xe659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e', + s: '0x683576abfd5dc35273e4264c23095a1bf21c14517bece57c7f0cc5c0ed4ce06a3dbf386b7828f348abe15d76973a72009e6ef86a5c91db2990cb36bb657c6587', + seed: 'Eve', + type: 'sr25519' + }, + { + p: '0x1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c', + s: '0xb835c20f450079cf4f513900ae9faf8df06ad86c681884122c752a4b2bf74d4303e4f21bc6cc62bb4eeed5a9cce642c25e2d2ac1464093b50f6196d78e3a7426', + seed: 'Ferdie', + type: 'sr25519' + } + ]; + const PAIRSETHEREUM = [ + { + name: 'Alith', + p: '0x02509540919faacf9ab52146c9aa40db68172d83777250b28e4679176e49ccdd9f', + s: '0x5fb92d6e98884f76de468fa3f6278f8807c48bebc13595d45af5bdc4da702133', + type: 'ethereum' + }, + { + name: 'Baltathar', + p: '0x033bc19e36ff1673910575b6727a974a9abd80c9a875d41ab3e2648dbfb9e4b518', + s: '0x8075991ce870b93a8870eca0c0f91913d12f47948ca0fd25b49c6fa7cdbeee8b', + type: 'ethereum' + }, + { + name: 'Charleth', + p: '0x0234637bdc0e89b5d46543bcbf8edff329d2702bc995e27e9af4b1ba009a3c2a5e', + s: '0x0b6e18cafb6ed99687ec547bd28139cafdd2bffe70e6b688025de6b445aa5c5b', + type: 'ethereum' + }, + { + name: 'Dorothy', + p: '0x02a00d60b2b408c2a14c5d70cdd2c205db8985ef737a7e55ad20ea32cc9e7c417c', + s: '0x39539ab1876910bbf3a223d84a29e28f1cb4e2e456503e7e91ed39b2e7223d68', + type: 'ethereum' + }, + { + name: 'Ethan', + p: '0x025cdc005b752651cd3f728fb9192182acb3a9c89e19072cbd5b03f3ee1f1b3ffa', + s: '0x7dce9bc8babb68fec1409be38c8e1a52650206a7ed90ff956ae8a6d15eeaaef4', + type: 'ethereum' + }, + { + name: 'Faith', + p: '0x037964b6c9d546da4646ada28a99e34acaa1d14e7aba861a9055f9bd200c8abf74', + s: '0xb9d2ea9a615f3165812e8d44de0d24da9bbd164b65c4f0573e1ce2c8dbd9c8df', + type: 'ethereum' + } + ]; + function createMeta(name, seed) { + if (!name && !seed) { + throw new Error('Testing pair should have either a name or a seed'); + } + return { + isTesting: true, + name: name || seed?.replace('//', '_').toLowerCase() + }; + } + function createTestKeyring(options = {}, isDerived = true) { + const keyring = new Keyring(options); + const pairs = options.type === 'ethereum' + ? PAIRSETHEREUM + : PAIRSSR25519; + for (const { name, p, s, seed, type } of pairs) { + const meta = createMeta(name, seed); + const pair = !isDerived && !name && seed + ? keyring.addFromUri(seed, meta, options.type) + : keyring.addPair(createPair({ toSS58: keyring.encodeAddress, type }, { publicKey: util.hexToU8a(p), secretKey: util.hexToU8a(s) }, meta)); + pair.lock = () => { + }; + } + return keyring; + } + + const publicKey = new Uint8Array(32); + const address = '5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM'; + const meta = { + isTesting: true, + name: 'nobody' + }; + const json = { + address, + encoded: '', + encoding: { + content: ['pkcs8', 'ed25519'], + type: 'none', + version: '0' + }, + meta + }; + const pair = { + address, + addressRaw: publicKey, + decodePkcs8: (_passphrase, _encoded) => undefined, + derive: (_suri, _meta) => pair, + encodePkcs8: (_passphrase) => new Uint8Array(0), + isLocked: true, + lock: () => { + }, + meta, + publicKey, + setMeta: (_meta) => undefined, + sign: (_message) => new Uint8Array(64), + toJson: (_passphrase) => json, + type: 'ed25519', + unlock: (_passphrase) => undefined, + verify: (_message, _signature) => false, + vrfSign: (_message, _context, _extra) => new Uint8Array(96), + vrfVerify: (_message, _vrfResult, _context, _extra) => false + }; + function nobody() { + return pair; + } + + function createTestPairs(options, isDerived = true) { + const keyring = createTestKeyring(options, isDerived); + const pairs = keyring.getPairs(); + const map = { nobody: nobody() }; + for (const p of pairs) { + if (p.meta.name) { + map[p.meta.name] = p; + } + } + return map; + } + + Object.defineProperty(exports, "decodeAddress", { + enumerable: true, + get: function () { return utilCrypto.decodeAddress; } + }); + Object.defineProperty(exports, "encodeAddress", { + enumerable: true, + get: function () { return utilCrypto.encodeAddress; } + }); + Object.defineProperty(exports, "setSS58Format", { + enumerable: true, + get: function () { return utilCrypto.setSS58Format; } + }); + exports.DEV_PHRASE = DEV_PHRASE; + exports.DEV_SEED = DEV_SEED; + exports.Keyring = Keyring; + exports.createPair = createPair; + exports.createTestKeyring = createTestKeyring; + exports.createTestPairs = createTestPairs; + exports.packageInfo = packageInfo; + +})); diff --git a/packages/keyring/bundle.d.ts b/packages/keyring/bundle.d.ts new file mode 100644 index 0000000..41834ec --- /dev/null +++ b/packages/keyring/bundle.d.ts @@ -0,0 +1,7 @@ +export { decodeAddress, encodeAddress, setSS58Format } from '@pezkuwi/util-crypto'; +export { Keyring } from './keyring.js'; +export { packageInfo } from './packageInfo.js'; +export { createPair } from './pair/index.js'; +export { createTestKeyring } from './testing.js'; +export { createTestPairs } from './testingPairs.js'; +export * from './defaults.js'; diff --git a/packages/keyring/bundle.js b/packages/keyring/bundle.js new file mode 100644 index 0000000..41834ec --- /dev/null +++ b/packages/keyring/bundle.js @@ -0,0 +1,7 @@ +export { decodeAddress, encodeAddress, setSS58Format } from '@pezkuwi/util-crypto'; +export { Keyring } from './keyring.js'; +export { packageInfo } from './packageInfo.js'; +export { createPair } from './pair/index.js'; +export { createTestKeyring } from './testing.js'; +export { createTestPairs } from './testingPairs.js'; +export * from './defaults.js'; diff --git a/packages/keyring/cjs/bundle.d.ts b/packages/keyring/cjs/bundle.d.ts new file mode 100644 index 0000000..41834ec --- /dev/null +++ b/packages/keyring/cjs/bundle.d.ts @@ -0,0 +1,7 @@ +export { decodeAddress, encodeAddress, setSS58Format } from '@pezkuwi/util-crypto'; +export { Keyring } from './keyring.js'; +export { packageInfo } from './packageInfo.js'; +export { createPair } from './pair/index.js'; +export { createTestKeyring } from './testing.js'; +export { createTestPairs } from './testingPairs.js'; +export * from './defaults.js'; diff --git a/packages/keyring/cjs/bundle.js b/packages/keyring/cjs/bundle.js new file mode 100644 index 0000000..c12488a --- /dev/null +++ b/packages/keyring/cjs/bundle.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createTestPairs = exports.createTestKeyring = exports.createPair = exports.packageInfo = exports.Keyring = exports.setSS58Format = exports.encodeAddress = exports.decodeAddress = void 0; +const tslib_1 = require("tslib"); +var util_crypto_1 = require("@pezkuwi/util-crypto"); +Object.defineProperty(exports, "decodeAddress", { enumerable: true, get: function () { return util_crypto_1.decodeAddress; } }); +Object.defineProperty(exports, "encodeAddress", { enumerable: true, get: function () { return util_crypto_1.encodeAddress; } }); +Object.defineProperty(exports, "setSS58Format", { enumerable: true, get: function () { return util_crypto_1.setSS58Format; } }); +var keyring_js_1 = require("./keyring.js"); +Object.defineProperty(exports, "Keyring", { enumerable: true, get: function () { return keyring_js_1.Keyring; } }); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +var index_js_1 = require("./pair/index.js"); +Object.defineProperty(exports, "createPair", { enumerable: true, get: function () { return index_js_1.createPair; } }); +var testing_js_1 = require("./testing.js"); +Object.defineProperty(exports, "createTestKeyring", { enumerable: true, get: function () { return testing_js_1.createTestKeyring; } }); +var testingPairs_js_1 = require("./testingPairs.js"); +Object.defineProperty(exports, "createTestPairs", { enumerable: true, get: function () { return testingPairs_js_1.createTestPairs; } }); +tslib_1.__exportStar(require("./defaults.js"), exports); diff --git a/packages/keyring/cjs/defaults.d.ts b/packages/keyring/cjs/defaults.d.ts new file mode 100644 index 0000000..bfeb45d --- /dev/null +++ b/packages/keyring/cjs/defaults.d.ts @@ -0,0 +1,2 @@ +export declare const DEV_PHRASE = "bottom drive obey lake curtain smoke basket hold race lonely fit walk"; +export declare const DEV_SEED = "0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e"; diff --git a/packages/keyring/cjs/defaults.js b/packages/keyring/cjs/defaults.js new file mode 100644 index 0000000..b34985d --- /dev/null +++ b/packages/keyring/cjs/defaults.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DEV_SEED = exports.DEV_PHRASE = void 0; +exports.DEV_PHRASE = 'bottom drive obey lake curtain smoke basket hold race lonely fit walk'; +exports.DEV_SEED = '0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e'; diff --git a/packages/keyring/cjs/index.d.ts b/packages/keyring/cjs/index.d.ts new file mode 100644 index 0000000..e350889 --- /dev/null +++ b/packages/keyring/cjs/index.d.ts @@ -0,0 +1,4 @@ +import './packageDetect.js'; +import { Keyring } from './bundle.js'; +export * from './bundle.js'; +export default Keyring; diff --git a/packages/keyring/cjs/index.js b/packages/keyring/cjs/index.js new file mode 100644 index 0000000..d68e858 --- /dev/null +++ b/packages/keyring/cjs/index.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +require("./packageDetect.js"); +const bundle_js_1 = require("./bundle.js"); +tslib_1.__exportStar(require("./bundle.js"), exports); +exports.default = bundle_js_1.Keyring; diff --git a/packages/keyring/cjs/keyring.d.ts b/packages/keyring/cjs/keyring.d.ts new file mode 100644 index 0000000..f49d0b5 --- /dev/null +++ b/packages/keyring/cjs/keyring.d.ts @@ -0,0 +1,145 @@ +import type { EncryptedJsonEncoding, Keypair, KeypairType } from '@pezkuwi/util-crypto/types'; +import type { KeyringInstance, KeyringOptions, KeyringPair, KeyringPair$Json, KeyringPair$Meta } from './types.js'; +import { decodeAddress } from '@pezkuwi/util-crypto'; +/** + * # @pezkuwi/keyring + * + * ## Overview + * + * @name Keyring + * @summary Keyring management of user accounts + * @description Allows generation of keyring pairs from a variety of input combinations, such as + * json object containing account address or public key, account metadata, and account encoded using + * `addFromJson`, or by providing those values as arguments separately to `addFromAddress`, + * or by providing the mnemonic (seed phrase) and account metadata as arguments to `addFromMnemonic`. + * Stores the keyring pairs in a keyring pair dictionary. Removal of the keyring pairs from the keyring pair + * dictionary is achieved using `removePair`. Retrieval of all the stored pairs via `getPairs` or perform + * lookup of a pair for a given account address or public key using `getPair`. JSON metadata associated with + * an account may be obtained using `toJson` accompanied by the account passphrase. + */ +export declare class Keyring implements KeyringInstance { + #private; + decodeAddress: typeof decodeAddress; + constructor(options?: KeyringOptions); + /** + * @description retrieve the pairs (alias for getPairs) + */ + get pairs(): KeyringPair[]; + /** + * @description retrieve the publicKeys (alias for getPublicKeys) + */ + get publicKeys(): Uint8Array[]; + /** + * @description Returns the type of the keyring, ed25519, sr25519 or ecdsa + */ + get type(): KeypairType; + /** + * @name addPair + * @summary Stores an account, given a keyring pair, as a Key/Value (public key, pair) in Keyring Pair Dictionary + */ + addPair(pair: KeyringPair): KeyringPair; + /** + * @name addFromAddress + * @summary Stores an account, given an account address, as a Key/Value (public key, pair) in Keyring Pair Dictionary + * @description Allows user to explicitly provide separate inputs including account address or public key, and optionally + * the associated account metadata, and the default encoded value as arguments (that may be obtained from the json file + * of an account backup), and then generates a keyring pair from them that it passes to + * `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value. + */ + addFromAddress(address: string | Uint8Array, meta?: KeyringPair$Meta, encoded?: Uint8Array | null, type?: KeypairType, ignoreChecksum?: boolean, encType?: EncryptedJsonEncoding[]): KeyringPair; + /** + * @name addFromJson + * @summary Stores an account, given JSON data, as a Key/Value (public key, pair) in Keyring Pair Dictionary + * @description Allows user to provide a json object argument that contains account information (that may be obtained from the json file + * of an account backup), and then generates a keyring pair from it that it passes to + * `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value. + */ + addFromJson(json: KeyringPair$Json, ignoreChecksum?: boolean): KeyringPair; + /** + * @name addFromMnemonic + * @summary Stores an account, given a mnemonic, as a Key/Value (public key, pair) in Keyring Pair Dictionary + * @description Allows user to provide a mnemonic (seed phrase that is provided when account is originally created) + * argument and a metadata argument that contains account information (that may be obtained from the json file + * of an account backup), and then generates a keyring pair from it that it passes to + * `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value. + */ + addFromMnemonic(mnemonic: string, meta?: KeyringPair$Meta, type?: KeypairType, wordlist?: string[]): KeyringPair; + /** + * @name addFromPair + * @summary Stores an account created from an explicit publicKey/secreteKey combination + */ + addFromPair(pair: Keypair, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair; + /** + * @name addFromSeed + * @summary Stores an account, given seed data, as a Key/Value (public key, pair) in Keyring Pair Dictionary + * @description Stores in a keyring pair dictionary the public key of the pair as a key and the pair as the associated value. + * Allows user to provide the account seed as an argument, and then generates a keyring pair from it that it passes to + * `addPair` to store in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value. + */ + addFromSeed(seed: Uint8Array, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair; + /** + * @name addFromUri + * @summary Creates an account via an suri + * @description Extracts the phrase, path and password from a SURI format for specifying secret keys `//////` (the `///password` may be omitted, and `/` and `//` maybe repeated and mixed). The secret can be a hex string, mnemonic phrase or a string (to be padded) + */ + addFromUri(suri: string, meta?: KeyringPair$Meta, type?: KeypairType, wordlist?: string[]): KeyringPair; + /** + * @name createFromJson + * @description Creates a pair from a JSON keyfile + */ + createFromJson({ address, encoded, encoding: { content, type, version }, meta }: KeyringPair$Json, ignoreChecksum?: boolean): KeyringPair; + /** + * @name createFromPair + * @summary Creates a pair from an explicit publicKey/secreteKey combination + */ + createFromPair(pair: Keypair, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair; + /** + * @name createFromUri + * @summary Creates a Keypair from an suri + * @description This creates a pair from the suri, but does not add it to the keyring + */ + createFromUri(_suri: string, meta?: KeyringPair$Meta, type?: KeypairType, wordlist?: string[]): KeyringPair; + /** + * @name encodeAddress + * @description Encodes the input into an ss58 representation + */ + encodeAddress: (address: Uint8Array | string, ss58Format?: number) => string; + /** + * @name getPair + * @summary Retrieves an account keyring pair from the Keyring Pair Dictionary, given an account address + * @description Returns a keyring pair value from the keyring pair dictionary by performing + * a key lookup using the provided account address or public key (after decoding it). + */ + getPair(address: string | Uint8Array): KeyringPair; + /** + * @name getPairs + * @summary Retrieves all account keyring pairs from the Keyring Pair Dictionary + * @description Returns an array list of all the keyring pair values that are stored in the keyring pair dictionary. + */ + getPairs(): KeyringPair[]; + /** + * @name getPublicKeys + * @summary Retrieves Public Keys of all Keyring Pairs stored in the Keyring Pair Dictionary + * @description Returns an array list of all the public keys associated with each of the keyring pair values that are stored in the keyring pair dictionary. + */ + getPublicKeys(): Uint8Array[]; + /** + * @name removePair + * @description Deletes the provided input address or public key from the stored Keyring Pair Dictionary. + */ + removePair(address: string | Uint8Array): void; + /** + * @name setSS58Format; + * @description Sets the ss58 format for the keyring + */ + setSS58Format(ss58: number): void; + /** + * @name toJson + * @summary Returns a JSON object associated with the input argument that contains metadata assocated with an account + * @description Returns a JSON object containing the metadata associated with an account + * when valid address or public key and when the account passphrase is provided if the account secret + * is not already unlocked and available in memory. Note that in [Polkadot-JS Apps](https://github.com/polkadot-js/apps) the user + * may backup their account to a JSON file that contains this information. + */ + toJson(address: string | Uint8Array, passphrase?: string): KeyringPair$Json; +} diff --git a/packages/keyring/cjs/keyring.js b/packages/keyring/cjs/keyring.js new file mode 100644 index 0000000..bbe89c2 --- /dev/null +++ b/packages/keyring/cjs/keyring.js @@ -0,0 +1,261 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Keyring = void 0; +const util_1 = require("@pezkuwi/util"); +const util_crypto_1 = require("@pezkuwi/util-crypto"); +const index_js_1 = require("./pair/index.js"); +const defaults_js_1 = require("./defaults.js"); +const pairs_js_1 = require("./pairs.js"); +const PairFromSeed = { + ecdsa: (seed) => (0, util_crypto_1.secp256k1PairFromSeed)(seed), + ed25519: (seed) => (0, util_crypto_1.ed25519PairFromSeed)(seed), + ethereum: (seed) => (0, util_crypto_1.secp256k1PairFromSeed)(seed), + sr25519: (seed) => (0, util_crypto_1.sr25519PairFromSeed)(seed) +}; +function pairToPublic({ publicKey }) { + return publicKey; +} +/** + * # @pezkuwi/keyring + * + * ## Overview + * + * @name Keyring + * @summary Keyring management of user accounts + * @description Allows generation of keyring pairs from a variety of input combinations, such as + * json object containing account address or public key, account metadata, and account encoded using + * `addFromJson`, or by providing those values as arguments separately to `addFromAddress`, + * or by providing the mnemonic (seed phrase) and account metadata as arguments to `addFromMnemonic`. + * Stores the keyring pairs in a keyring pair dictionary. Removal of the keyring pairs from the keyring pair + * dictionary is achieved using `removePair`. Retrieval of all the stored pairs via `getPairs` or perform + * lookup of a pair for a given account address or public key using `getPair`. JSON metadata associated with + * an account may be obtained using `toJson` accompanied by the account passphrase. + */ +class Keyring { + #pairs; + #type; + #ss58; + decodeAddress = util_crypto_1.decodeAddress; + constructor(options = {}) { + options.type = options.type || 'ed25519'; + if (!['ecdsa', 'ethereum', 'ed25519', 'sr25519'].includes(options.type || 'undefined')) { + throw new Error(`Expected a keyring type of either 'ed25519', 'sr25519', 'ethereum' or 'ecdsa', found '${options.type || 'unknown'}`); + } + this.#pairs = new pairs_js_1.Pairs(); + this.#ss58 = options.ss58Format; + this.#type = options.type; + } + /** + * @description retrieve the pairs (alias for getPairs) + */ + get pairs() { + return this.getPairs(); + } + /** + * @description retrieve the publicKeys (alias for getPublicKeys) + */ + get publicKeys() { + return this.getPublicKeys(); + } + /** + * @description Returns the type of the keyring, ed25519, sr25519 or ecdsa + */ + get type() { + return this.#type; + } + /** + * @name addPair + * @summary Stores an account, given a keyring pair, as a Key/Value (public key, pair) in Keyring Pair Dictionary + */ + addPair(pair) { + return this.#pairs.add(pair); + } + /** + * @name addFromAddress + * @summary Stores an account, given an account address, as a Key/Value (public key, pair) in Keyring Pair Dictionary + * @description Allows user to explicitly provide separate inputs including account address or public key, and optionally + * the associated account metadata, and the default encoded value as arguments (that may be obtained from the json file + * of an account backup), and then generates a keyring pair from them that it passes to + * `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value. + */ + addFromAddress(address, meta = {}, encoded = null, type = this.type, ignoreChecksum, encType) { + const publicKey = this.decodeAddress(address, ignoreChecksum); + return this.addPair((0, index_js_1.createPair)({ toSS58: this.encodeAddress, type }, { publicKey, secretKey: new Uint8Array() }, meta, encoded, encType)); + } + /** + * @name addFromJson + * @summary Stores an account, given JSON data, as a Key/Value (public key, pair) in Keyring Pair Dictionary + * @description Allows user to provide a json object argument that contains account information (that may be obtained from the json file + * of an account backup), and then generates a keyring pair from it that it passes to + * `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value. + */ + addFromJson(json, ignoreChecksum) { + return this.addPair(this.createFromJson(json, ignoreChecksum)); + } + /** + * @name addFromMnemonic + * @summary Stores an account, given a mnemonic, as a Key/Value (public key, pair) in Keyring Pair Dictionary + * @description Allows user to provide a mnemonic (seed phrase that is provided when account is originally created) + * argument and a metadata argument that contains account information (that may be obtained from the json file + * of an account backup), and then generates a keyring pair from it that it passes to + * `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value. + */ + addFromMnemonic(mnemonic, meta = {}, type = this.type, wordlist) { + return this.addFromUri(mnemonic, meta, type, wordlist); + } + /** + * @name addFromPair + * @summary Stores an account created from an explicit publicKey/secreteKey combination + */ + addFromPair(pair, meta = {}, type = this.type) { + return this.addPair(this.createFromPair(pair, meta, type)); + } + /** + * @name addFromSeed + * @summary Stores an account, given seed data, as a Key/Value (public key, pair) in Keyring Pair Dictionary + * @description Stores in a keyring pair dictionary the public key of the pair as a key and the pair as the associated value. + * Allows user to provide the account seed as an argument, and then generates a keyring pair from it that it passes to + * `addPair` to store in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value. + */ + addFromSeed(seed, meta = {}, type = this.type) { + return this.addPair((0, index_js_1.createPair)({ toSS58: this.encodeAddress, type }, PairFromSeed[type](seed), meta, null)); + } + /** + * @name addFromUri + * @summary Creates an account via an suri + * @description Extracts the phrase, path and password from a SURI format for specifying secret keys `//////` (the `///password` may be omitted, and `/` and `//` maybe repeated and mixed). The secret can be a hex string, mnemonic phrase or a string (to be padded) + */ + addFromUri(suri, meta = {}, type = this.type, wordlist) { + return this.addPair(this.createFromUri(suri, meta, type, wordlist)); + } + /** + * @name createFromJson + * @description Creates a pair from a JSON keyfile + */ + createFromJson({ address, encoded, encoding: { content, type, version }, meta }, ignoreChecksum) { + if (version === '3' && content[0] !== 'pkcs8') { + throw new Error(`Unable to decode non-pkcs8 type, [${content.join(',')}] found}`); + } + const cryptoType = version === '0' || !Array.isArray(content) + ? this.type + : content[1]; + const encType = !Array.isArray(type) + ? [type] + : type; + if (!['ed25519', 'sr25519', 'ecdsa', 'ethereum'].includes(cryptoType)) { + throw new Error(`Unknown crypto type ${cryptoType}`); + } + // Here the address and publicKey are 32 bytes and isomorphic. This is why the address field needs to be the public key for ethereum type pairs + const publicKey = (0, util_1.isHex)(address) + ? (0, util_1.hexToU8a)(address) + : this.decodeAddress(address, ignoreChecksum); + const decoded = (0, util_1.isHex)(encoded) + ? (0, util_1.hexToU8a)(encoded) + : (0, util_crypto_1.base64Decode)(encoded); + return (0, index_js_1.createPair)({ toSS58: this.encodeAddress, type: cryptoType }, { publicKey, secretKey: new Uint8Array() }, meta, decoded, encType); + } + /** + * @name createFromPair + * @summary Creates a pair from an explicit publicKey/secreteKey combination + */ + createFromPair(pair, meta = {}, type = this.type) { + return (0, index_js_1.createPair)({ toSS58: this.encodeAddress, type }, pair, meta, null); + } + /** + * @name createFromUri + * @summary Creates a Keypair from an suri + * @description This creates a pair from the suri, but does not add it to the keyring + */ + createFromUri(_suri, meta = {}, type = this.type, wordlist) { + // here we only aut-add the dev phrase if we have a hard-derived path + const suri = _suri.startsWith('//') + ? `${defaults_js_1.DEV_PHRASE}${_suri}` + : _suri; + const { derivePath, password, path, phrase } = (0, util_crypto_1.keyExtractSuri)(suri); + let seed; + const isPhraseHex = (0, util_1.isHex)(phrase, 256); + if (isPhraseHex) { + seed = (0, util_1.hexToU8a)(phrase); + } + else { + const parts = phrase.split(' '); + if ([12, 15, 18, 21, 24].includes(parts.length)) { + seed = type === 'ethereum' + ? (0, util_crypto_1.mnemonicToLegacySeed)(phrase, '', false, 64) + : (0, util_crypto_1.mnemonicToMiniSecret)(phrase, password, wordlist); + } + else { + if (phrase.length > 32) { + throw new Error('specified phrase is not a valid mnemonic and is invalid as a raw seed at > 32 bytes'); + } + seed = (0, util_1.stringToU8a)(phrase.padEnd(32)); + } + } + const derived = type === 'ethereum' + ? isPhraseHex + ? PairFromSeed[type](seed) // for eth, if the private key is provided as suri, it must be derived only once + : (0, util_crypto_1.hdEthereum)(seed, derivePath.substring(1)) + : (0, util_crypto_1.keyFromPath)(PairFromSeed[type](seed), path, type); + return (0, index_js_1.createPair)({ toSS58: this.encodeAddress, type }, derived, meta, null); + } + /** + * @name encodeAddress + * @description Encodes the input into an ss58 representation + */ + encodeAddress = (address, ss58Format) => { + return this.type === 'ethereum' + ? (0, util_crypto_1.ethereumEncode)(address) + : (0, util_crypto_1.encodeAddress)(address, ss58Format ?? this.#ss58); + }; + /** + * @name getPair + * @summary Retrieves an account keyring pair from the Keyring Pair Dictionary, given an account address + * @description Returns a keyring pair value from the keyring pair dictionary by performing + * a key lookup using the provided account address or public key (after decoding it). + */ + getPair(address) { + return this.#pairs.get(address); + } + /** + * @name getPairs + * @summary Retrieves all account keyring pairs from the Keyring Pair Dictionary + * @description Returns an array list of all the keyring pair values that are stored in the keyring pair dictionary. + */ + getPairs() { + return this.#pairs.all(); + } + /** + * @name getPublicKeys + * @summary Retrieves Public Keys of all Keyring Pairs stored in the Keyring Pair Dictionary + * @description Returns an array list of all the public keys associated with each of the keyring pair values that are stored in the keyring pair dictionary. + */ + getPublicKeys() { + return this.#pairs.all().map(pairToPublic); + } + /** + * @name removePair + * @description Deletes the provided input address or public key from the stored Keyring Pair Dictionary. + */ + removePair(address) { + this.#pairs.remove(address); + } + /** + * @name setSS58Format; + * @description Sets the ss58 format for the keyring + */ + setSS58Format(ss58) { + this.#ss58 = ss58; + } + /** + * @name toJson + * @summary Returns a JSON object associated with the input argument that contains metadata assocated with an account + * @description Returns a JSON object containing the metadata associated with an account + * when valid address or public key and when the account passphrase is provided if the account secret + * is not already unlocked and available in memory. Note that in [Polkadot-JS Apps](https://github.com/polkadot-js/apps) the user + * may backup their account to a JSON file that contains this information. + */ + toJson(address, passphrase) { + return this.#pairs.get(address).toJson(passphrase); + } +} +exports.Keyring = Keyring; diff --git a/packages/keyring/cjs/package.json b/packages/keyring/cjs/package.json new file mode 100644 index 0000000..5bbefff --- /dev/null +++ b/packages/keyring/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/keyring/cjs/packageDetect.d.ts b/packages/keyring/cjs/packageDetect.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/keyring/cjs/packageDetect.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/keyring/cjs/packageDetect.js b/packages/keyring/cjs/packageDetect.js new file mode 100644 index 0000000..344754c --- /dev/null +++ b/packages/keyring/cjs/packageDetect.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = require("@pezkuwi/util"); +const packageInfo_1 = require("@pezkuwi/util/cjs/packageInfo"); +const packageInfo_2 = require("@pezkuwi/util-crypto/cjs/packageInfo"); +const packageInfo_js_1 = require("./packageInfo.js"); +(0, util_1.detectPackage)(packageInfo_js_1.packageInfo, null, [packageInfo_2.packageInfo, packageInfo_1.packageInfo]); diff --git a/packages/keyring/cjs/packageInfo.d.ts b/packages/keyring/cjs/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/keyring/cjs/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/keyring/cjs/packageInfo.js b/packages/keyring/cjs/packageInfo.js new file mode 100644 index 0000000..bd9576a --- /dev/null +++ b/packages/keyring/cjs/packageInfo.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +exports.packageInfo = { name: '@pezkuwi/keyring', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; diff --git a/packages/keyring/cjs/pair/decode.d.ts b/packages/keyring/cjs/pair/decode.d.ts new file mode 100644 index 0000000..422f747 --- /dev/null +++ b/packages/keyring/cjs/pair/decode.d.ts @@ -0,0 +1,12 @@ +import type { EncryptedJsonEncoding } from '@pezkuwi/util-crypto/types'; +/** + * Decode a pair, taking into account the generation-specific formats and headers + * + * For divisor/headers, don't rely on the magic being static. These will + * change between generations, aka with the long-awaited 4th generation + * of the format. The external decode interface is the only way to use and decode these. + **/ +export declare function decodePair(passphrase?: string, encrypted?: Uint8Array | null, _encType?: EncryptedJsonEncoding | EncryptedJsonEncoding[]): { + publicKey: Uint8Array; + secretKey: Uint8Array; +}; diff --git a/packages/keyring/cjs/pair/decode.js b/packages/keyring/cjs/pair/decode.js new file mode 100644 index 0000000..6a34a54 --- /dev/null +++ b/packages/keyring/cjs/pair/decode.js @@ -0,0 +1,45 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.decodePair = decodePair; +const util_1 = require("@pezkuwi/util"); +const util_crypto_1 = require("@pezkuwi/util-crypto"); +const defaults_js_1 = require("./defaults.js"); +const SEED_OFFSET = defaults_js_1.PAIR_HDR.length; +/** + * Decode a pair, taking into account the generation-specific formats and headers + * + * For divisor/headers, don't rely on the magic being static. These will + * change between generations, aka with the long-awaited 4th generation + * of the format. The external decode interface is the only way to use and decode these. + **/ +function decodePair(passphrase, encrypted, _encType) { + const encType = Array.isArray(_encType) || _encType === undefined + ? _encType + : [_encType]; + const decrypted = (0, util_crypto_1.jsonDecryptData)(encrypted, passphrase, encType); + const header = decrypted.subarray(0, defaults_js_1.PAIR_HDR.length); + // check the start header (generations 1-3) + if (!(0, util_1.u8aEq)(header, defaults_js_1.PAIR_HDR)) { + throw new Error('Invalid encoding header found in body'); + } + // setup for generation 3 format + let secretKey = decrypted.subarray(SEED_OFFSET, SEED_OFFSET + defaults_js_1.SEC_LENGTH); + let divOffset = SEED_OFFSET + defaults_js_1.SEC_LENGTH; + let divider = decrypted.subarray(divOffset, divOffset + defaults_js_1.PAIR_DIV.length); + // old-style (generation 1 & 2), we have the seed here + if (!(0, util_1.u8aEq)(divider, defaults_js_1.PAIR_DIV)) { + divOffset = SEED_OFFSET + defaults_js_1.SEED_LENGTH; + secretKey = decrypted.subarray(SEED_OFFSET, divOffset); + divider = decrypted.subarray(divOffset, divOffset + defaults_js_1.PAIR_DIV.length); + // check the divisior at this point (already checked for generation 3) + if (!(0, util_1.u8aEq)(divider, defaults_js_1.PAIR_DIV)) { + throw new Error('Invalid encoding divider found in body'); + } + } + const pubOffset = divOffset + defaults_js_1.PAIR_DIV.length; + const publicKey = decrypted.subarray(pubOffset, pubOffset + defaults_js_1.PUB_LENGTH); + return { + publicKey, + secretKey + }; +} diff --git a/packages/keyring/cjs/pair/defaults.d.ts b/packages/keyring/cjs/pair/defaults.d.ts new file mode 100644 index 0000000..bbff8c3 --- /dev/null +++ b/packages/keyring/cjs/pair/defaults.d.ts @@ -0,0 +1,12 @@ +/** public/secret section divider (generation 1-3, will change in 4, don't rely on value) */ +export declare const PAIR_DIV: Uint8Array; +/** public/secret start block (generation 1-3, will change in 4, don't rely on value) */ +export declare const PAIR_HDR: Uint8Array; +/** length of a public key */ +export declare const PUB_LENGTH = 32; +/** length of a salt */ +export declare const SALT_LENGTH = 32; +/** length of a secret key */ +export declare const SEC_LENGTH = 64; +/** length of a user-input seed */ +export declare const SEED_LENGTH = 32; diff --git a/packages/keyring/cjs/pair/defaults.js b/packages/keyring/cjs/pair/defaults.js new file mode 100644 index 0000000..53220cc --- /dev/null +++ b/packages/keyring/cjs/pair/defaults.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.SEED_LENGTH = exports.SEC_LENGTH = exports.SALT_LENGTH = exports.PUB_LENGTH = exports.PAIR_HDR = exports.PAIR_DIV = void 0; +/** public/secret section divider (generation 1-3, will change in 4, don't rely on value) */ +exports.PAIR_DIV = new Uint8Array([161, 35, 3, 33, 0]); +/** public/secret start block (generation 1-3, will change in 4, don't rely on value) */ +exports.PAIR_HDR = new Uint8Array([48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32]); +/** length of a public key */ +exports.PUB_LENGTH = 32; +/** length of a salt */ +exports.SALT_LENGTH = 32; +/** length of a secret key */ +exports.SEC_LENGTH = 64; +/** length of a user-input seed */ +exports.SEED_LENGTH = 32; diff --git a/packages/keyring/cjs/pair/encode.d.ts b/packages/keyring/cjs/pair/encode.d.ts new file mode 100644 index 0000000..2896952 --- /dev/null +++ b/packages/keyring/cjs/pair/encode.d.ts @@ -0,0 +1,5 @@ +import type { PairInfo } from './types.js'; +/** + * Encode a pair with the latest generation format (generation 3) + **/ +export declare function encodePair({ publicKey, secretKey }: PairInfo, passphrase?: string): Uint8Array; diff --git a/packages/keyring/cjs/pair/encode.js b/packages/keyring/cjs/pair/encode.js new file mode 100644 index 0000000..ee25dfa --- /dev/null +++ b/packages/keyring/cjs/pair/encode.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.encodePair = encodePair; +const util_1 = require("@pezkuwi/util"); +const util_crypto_1 = require("@pezkuwi/util-crypto"); +const defaults_js_1 = require("./defaults.js"); +/** + * Encode a pair with the latest generation format (generation 3) + **/ +function encodePair({ publicKey, secretKey }, passphrase) { + if (!secretKey) { + throw new Error('Expected a valid secretKey to be passed to encode'); + } + const encoded = (0, util_1.u8aConcat)(defaults_js_1.PAIR_HDR, secretKey, defaults_js_1.PAIR_DIV, publicKey); + if (!passphrase) { + return encoded; + } + // this is only for generation 3 (previous generations are only handled in decoding) + const { params, password, salt } = (0, util_crypto_1.scryptEncode)(passphrase); + const { encrypted, nonce } = (0, util_crypto_1.naclEncrypt)(encoded, password.subarray(0, 32)); + return (0, util_1.u8aConcat)((0, util_crypto_1.scryptToU8a)(salt, params), nonce, encrypted); +} diff --git a/packages/keyring/cjs/pair/index.d.ts b/packages/keyring/cjs/pair/index.d.ts new file mode 100644 index 0000000..94b4810 --- /dev/null +++ b/packages/keyring/cjs/pair/index.d.ts @@ -0,0 +1,40 @@ +import type { EncryptedJsonEncoding, KeypairType } from '@pezkuwi/util-crypto/types'; +import type { KeyringPair, KeyringPair$Meta } from '../types.js'; +import type { PairInfo } from './types.js'; +interface Setup { + toSS58: (publicKey: Uint8Array) => string; + type: KeypairType; +} +/** + * @name createPair + * @summary Creates a keyring pair object + * @description Creates a keyring pair object with provided account public key, metadata, and encoded arguments. + * The keyring pair stores the account state including the encoded address and associated metadata. + * + * It has properties whose values are functions that may be called to perform account actions: + * + * - `address` function retrieves the address associated with the account. + * - `decodedPkcs8` function is called with the account passphrase and account encoded public key. + * It decodes the encoded public key using the passphrase provided to obtain the decoded account public key + * and associated secret key that are then available in memory, and changes the account address stored in the + * state of the pair to correspond to the address of the decoded public key. + * - `encodePkcs8` function when provided with the correct passphrase associated with the account pair + * and when the secret key is in memory (when the account pair is not locked) it returns an encoded + * public key of the account. + * - `meta` is the metadata that is stored in the state of the pair, either when it was originally + * created or set via `setMeta`. + * - `publicKey` returns the public key stored in memory for the pair. + * - `sign` may be used to return a signature by signing a provided message with the secret + * key (if it is in memory) using Nacl. + * - `toJson` calls another `toJson` function and provides the state of the pair, + * it generates arguments to be passed to the other `toJson` function including an encoded public key of the account + * that it generates using the secret key from memory (if it has been made available in memory) + * and the optionally provided passphrase argument. It passes a third boolean argument to `toJson` + * indicating whether the public key has been encoded or not (if a passphrase argument was provided then it is encoded). + * The `toJson` function that it calls returns a JSON object with properties including the `address` + * and `meta` that are assigned with the values stored in the corresponding state variables of the account pair, + * an `encoded` property that is assigned with the encoded public key in hex format, and an `encoding` + * property that indicates whether the public key value of the `encoded` property is encoded or not. + */ +export declare function createPair({ toSS58, type }: Setup, { publicKey, secretKey }: PairInfo, meta?: KeyringPair$Meta, encoded?: Uint8Array | null, encTypes?: EncryptedJsonEncoding[]): KeyringPair; +export {}; diff --git a/packages/keyring/cjs/pair/index.js b/packages/keyring/cjs/pair/index.js new file mode 100644 index 0000000..15edec2 --- /dev/null +++ b/packages/keyring/cjs/pair/index.js @@ -0,0 +1,183 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createPair = createPair; +const util_1 = require("@pezkuwi/util"); +const util_crypto_1 = require("@pezkuwi/util-crypto"); +const decode_js_1 = require("./decode.js"); +const encode_js_1 = require("./encode.js"); +const toJson_js_1 = require("./toJson.js"); +const SIG_TYPE_NONE = new Uint8Array(); +const TYPE_FROM_SEED = { + ecdsa: util_crypto_1.secp256k1PairFromSeed, + ed25519: util_crypto_1.ed25519PairFromSeed, + ethereum: util_crypto_1.secp256k1PairFromSeed, + sr25519: util_crypto_1.sr25519PairFromSeed +}; +const TYPE_PREFIX = { + ecdsa: new Uint8Array([2]), + ed25519: new Uint8Array([0]), + ethereum: new Uint8Array([2]), + sr25519: new Uint8Array([1]) +}; +const TYPE_SIGNATURE = { + ecdsa: (m, p) => (0, util_crypto_1.secp256k1Sign)(m, p, 'blake2'), + ed25519: util_crypto_1.ed25519Sign, + ethereum: (m, p) => (0, util_crypto_1.secp256k1Sign)(m, p, 'keccak'), + sr25519: util_crypto_1.sr25519Sign +}; +const TYPE_ADDRESS = { + ecdsa: (p) => p.length > 32 ? (0, util_crypto_1.blake2AsU8a)(p) : p, + ed25519: (p) => p, + ethereum: (p) => p.length === 20 ? p : (0, util_crypto_1.keccakAsU8a)((0, util_crypto_1.secp256k1Expand)(p)), + sr25519: (p) => p +}; +function isLocked(secretKey) { + return !secretKey || (0, util_1.u8aEmpty)(secretKey); +} +function vrfHash(proof, context, extra) { + return (0, util_crypto_1.blake2AsU8a)((0, util_1.u8aConcat)(context || '', extra || '', proof)); +} +/** + * @name createPair + * @summary Creates a keyring pair object + * @description Creates a keyring pair object with provided account public key, metadata, and encoded arguments. + * The keyring pair stores the account state including the encoded address and associated metadata. + * + * It has properties whose values are functions that may be called to perform account actions: + * + * - `address` function retrieves the address associated with the account. + * - `decodedPkcs8` function is called with the account passphrase and account encoded public key. + * It decodes the encoded public key using the passphrase provided to obtain the decoded account public key + * and associated secret key that are then available in memory, and changes the account address stored in the + * state of the pair to correspond to the address of the decoded public key. + * - `encodePkcs8` function when provided with the correct passphrase associated with the account pair + * and when the secret key is in memory (when the account pair is not locked) it returns an encoded + * public key of the account. + * - `meta` is the metadata that is stored in the state of the pair, either when it was originally + * created or set via `setMeta`. + * - `publicKey` returns the public key stored in memory for the pair. + * - `sign` may be used to return a signature by signing a provided message with the secret + * key (if it is in memory) using Nacl. + * - `toJson` calls another `toJson` function and provides the state of the pair, + * it generates arguments to be passed to the other `toJson` function including an encoded public key of the account + * that it generates using the secret key from memory (if it has been made available in memory) + * and the optionally provided passphrase argument. It passes a third boolean argument to `toJson` + * indicating whether the public key has been encoded or not (if a passphrase argument was provided then it is encoded). + * The `toJson` function that it calls returns a JSON object with properties including the `address` + * and `meta` that are assigned with the values stored in the corresponding state variables of the account pair, + * an `encoded` property that is assigned with the encoded public key in hex format, and an `encoding` + * property that indicates whether the public key value of the `encoded` property is encoded or not. + */ +function createPair({ toSS58, type }, { publicKey, secretKey }, meta = {}, encoded = null, encTypes) { + const decodePkcs8 = (passphrase, userEncoded) => { + const decoded = (0, decode_js_1.decodePair)(passphrase, userEncoded || encoded, encTypes); + if (decoded.secretKey.length === 64) { + publicKey = decoded.publicKey; + secretKey = decoded.secretKey; + } + else { + const pair = TYPE_FROM_SEED[type](decoded.secretKey); + publicKey = pair.publicKey; + secretKey = pair.secretKey; + } + }; + const recode = (passphrase) => { + isLocked(secretKey) && encoded && decodePkcs8(passphrase, encoded); + encoded = (0, encode_js_1.encodePair)({ publicKey, secretKey }, passphrase); // re-encode, latest version + encTypes = undefined; // swap to defaults, latest version follows + return encoded; + }; + const encodeAddress = () => { + const raw = TYPE_ADDRESS[type](publicKey); + return type === 'ethereum' + ? (0, util_crypto_1.ethereumEncode)(raw) + : toSS58(raw); + }; + return { + get address() { + return encodeAddress(); + }, + get addressRaw() { + const raw = TYPE_ADDRESS[type](publicKey); + return type === 'ethereum' + ? raw.slice(-20) + : raw; + }, + get isLocked() { + return isLocked(secretKey); + }, + get meta() { + return meta; + }, + get publicKey() { + return publicKey; + }, + get type() { + return type; + }, + // eslint-disable-next-line sort-keys + decodePkcs8, + derive: (suri, meta) => { + if (type === 'ethereum') { + throw new Error('Unable to derive on this keypair'); + } + else if (isLocked(secretKey)) { + throw new Error('Cannot derive on a locked keypair'); + } + const { path } = (0, util_crypto_1.keyExtractPath)(suri); + const derived = (0, util_crypto_1.keyFromPath)({ publicKey, secretKey }, path, type); + return createPair({ toSS58, type }, derived, meta, null); + }, + encodePkcs8: (passphrase) => { + return recode(passphrase); + }, + lock: () => { + secretKey = new Uint8Array(); + }, + setMeta: (additional) => { + meta = (0, util_1.objectSpread)({}, meta, additional); + }, + sign: (message, options = {}) => { + if (isLocked(secretKey)) { + throw new Error('Cannot sign with a locked key pair'); + } + return (0, util_1.u8aConcat)(options.withType + ? TYPE_PREFIX[type] + : SIG_TYPE_NONE, TYPE_SIGNATURE[type]((0, util_1.u8aToU8a)(message), { publicKey, secretKey })); + }, + toJson: (passphrase) => { + // NOTE: For ecdsa and ethereum, the publicKey cannot be extracted from the address. For these + // pass the hex-encoded publicKey through to the address portion of the JSON (before decoding) + // unless the publicKey is already an address + const address = ['ecdsa', 'ethereum'].includes(type) + ? publicKey.length === 20 + ? (0, util_1.u8aToHex)(publicKey) + : (0, util_1.u8aToHex)((0, util_crypto_1.secp256k1Compress)(publicKey)) + : encodeAddress(); + return (0, toJson_js_1.pairToJson)(type, { address, meta }, recode(passphrase), !!passphrase); + }, + unlock: (passphrase) => { + return decodePkcs8(passphrase); + }, + verify: (message, signature, signerPublic) => { + return (0, util_crypto_1.signatureVerify)(message, signature, TYPE_ADDRESS[type]((0, util_1.u8aToU8a)(signerPublic))).isValid; + }, + vrfSign: (message, context, extra) => { + if (isLocked(secretKey)) { + throw new Error('Cannot sign with a locked key pair'); + } + if (type === 'sr25519') { + return (0, util_crypto_1.sr25519VrfSign)(message, { secretKey }, context, extra); + } + const proof = TYPE_SIGNATURE[type]((0, util_1.u8aToU8a)(message), { publicKey, secretKey }); + return (0, util_1.u8aConcat)(vrfHash(proof, context, extra), proof); + }, + vrfVerify: (message, vrfResult, signerPublic, context, extra) => { + if (type === 'sr25519') { + return (0, util_crypto_1.sr25519VrfVerify)(message, vrfResult, publicKey, context, extra); + } + const result = (0, util_crypto_1.signatureVerify)(message, (0, util_1.u8aConcat)(TYPE_PREFIX[type], vrfResult.subarray(32)), TYPE_ADDRESS[type]((0, util_1.u8aToU8a)(signerPublic))); + return result.isValid && (0, util_1.u8aEq)(vrfResult.subarray(0, 32), vrfHash(vrfResult.subarray(32), context, extra)); + } + }; +} diff --git a/packages/keyring/cjs/pair/nobody.d.ts b/packages/keyring/cjs/pair/nobody.d.ts new file mode 100644 index 0000000..d7fae62 --- /dev/null +++ b/packages/keyring/cjs/pair/nobody.d.ts @@ -0,0 +1,2 @@ +import type { KeyringPair } from '../types.js'; +export declare function nobody(): KeyringPair; diff --git a/packages/keyring/cjs/pair/nobody.js b/packages/keyring/cjs/pair/nobody.js new file mode 100644 index 0000000..631e2d5 --- /dev/null +++ b/packages/keyring/cjs/pair/nobody.js @@ -0,0 +1,43 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.nobody = nobody; +const publicKey = new Uint8Array(32); +const address = '5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM'; +const meta = { + isTesting: true, + name: 'nobody' +}; +const json = { + address, + encoded: '', + encoding: { + content: ['pkcs8', 'ed25519'], + type: 'none', + version: '0' + }, + meta +}; +const pair = { + address, + addressRaw: publicKey, + decodePkcs8: (_passphrase, _encoded) => undefined, + derive: (_suri, _meta) => pair, + encodePkcs8: (_passphrase) => new Uint8Array(0), + isLocked: true, + lock: () => { + // no locking, it is always locked + }, + meta, + publicKey, + setMeta: (_meta) => undefined, + sign: (_message) => new Uint8Array(64), + toJson: (_passphrase) => json, + type: 'ed25519', + unlock: (_passphrase) => undefined, + verify: (_message, _signature) => false, + vrfSign: (_message, _context, _extra) => new Uint8Array(96), + vrfVerify: (_message, _vrfResult, _context, _extra) => false +}; +function nobody() { + return pair; +} diff --git a/packages/keyring/cjs/pair/toJson.d.ts b/packages/keyring/cjs/pair/toJson.d.ts new file mode 100644 index 0000000..b1e671b --- /dev/null +++ b/packages/keyring/cjs/pair/toJson.d.ts @@ -0,0 +1,8 @@ +import type { KeypairType } from '@pezkuwi/util-crypto/types'; +import type { KeyringPair$Json, KeyringPair$Meta } from '../types.js'; +interface PairStateJson { + address: string; + meta: KeyringPair$Meta; +} +export declare function pairToJson(type: KeypairType, { address, meta }: PairStateJson, encoded: Uint8Array, isEncrypted: boolean): KeyringPair$Json; +export {}; diff --git a/packages/keyring/cjs/pair/toJson.js b/packages/keyring/cjs/pair/toJson.js new file mode 100644 index 0000000..495fd7a --- /dev/null +++ b/packages/keyring/cjs/pair/toJson.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.pairToJson = pairToJson; +const util_1 = require("@pezkuwi/util"); +const util_crypto_1 = require("@pezkuwi/util-crypto"); +function pairToJson(type, { address, meta }, encoded, isEncrypted) { + return (0, util_1.objectSpread)((0, util_crypto_1.jsonEncryptFormat)(encoded, ['pkcs8', type], isEncrypted), { + address, + meta + }); +} diff --git a/packages/keyring/cjs/pair/types.d.ts b/packages/keyring/cjs/pair/types.d.ts new file mode 100644 index 0000000..37ef45f --- /dev/null +++ b/packages/keyring/cjs/pair/types.d.ts @@ -0,0 +1,5 @@ +export interface PairInfo { + publicKey: Uint8Array; + secretKey?: Uint8Array | undefined; + seed?: Uint8Array | null; +} diff --git a/packages/keyring/cjs/pair/types.js b/packages/keyring/cjs/pair/types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/packages/keyring/cjs/pair/types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/packages/keyring/cjs/pairs.d.ts b/packages/keyring/cjs/pairs.d.ts new file mode 100644 index 0000000..99eb5e1 --- /dev/null +++ b/packages/keyring/cjs/pairs.d.ts @@ -0,0 +1,8 @@ +import type { KeyringPair, KeyringPairs } from './types.js'; +export declare class Pairs implements KeyringPairs { + #private; + add(pair: KeyringPair): KeyringPair; + all(): KeyringPair[]; + get(address: string | Uint8Array): KeyringPair; + remove(address: string | Uint8Array): void; +} diff --git a/packages/keyring/cjs/pairs.js b/packages/keyring/cjs/pairs.js new file mode 100644 index 0000000..2e26f78 --- /dev/null +++ b/packages/keyring/cjs/pairs.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Pairs = void 0; +const util_1 = require("@pezkuwi/util"); +const util_crypto_1 = require("@pezkuwi/util-crypto"); +class Pairs { + #map = {}; + add(pair) { + this.#map[(0, util_crypto_1.decodeAddress)(pair.address).toString()] = pair; + return pair; + } + all() { + return Object.values(this.#map); + } + get(address) { + const pair = this.#map[(0, util_crypto_1.decodeAddress)(address).toString()]; + if (!pair) { + throw new Error(`Unable to retrieve keypair '${(0, util_1.isU8a)(address) || (0, util_1.isHex)(address) + ? (0, util_1.u8aToHex)((0, util_1.u8aToU8a)(address)) + : address}'`); + } + return pair; + } + remove(address) { + delete this.#map[(0, util_crypto_1.decodeAddress)(address).toString()]; + } +} +exports.Pairs = Pairs; diff --git a/packages/keyring/cjs/testing.d.ts b/packages/keyring/cjs/testing.d.ts new file mode 100644 index 0000000..4aca4b3 --- /dev/null +++ b/packages/keyring/cjs/testing.d.ts @@ -0,0 +1,20 @@ +import type { HexString } from '@pezkuwi/util/types'; +import type { KeypairType } from '@pezkuwi/util-crypto/types'; +import type { KeyringInstance, KeyringOptions } from './types.js'; +interface PairDef { + name?: string; + p: HexString; + s: HexString; + seed?: string; + type: KeypairType; +} +export declare const PAIRSSR25519: PairDef[]; +export declare const PAIRSETHEREUM: PairDef[]; +/** + * @name testKeyring + * @summary Create an instance of Keyring pre-populated with locked test accounts + * @description The test accounts (i.e. alice, bob, dave, eve, ferdie) + * are available on the dev chain and each test account is initialized with DOT funds. + */ +export declare function createTestKeyring(options?: KeyringOptions, isDerived?: boolean): KeyringInstance; +export {}; diff --git a/packages/keyring/cjs/testing.js b/packages/keyring/cjs/testing.js new file mode 100644 index 0000000..84ad498 --- /dev/null +++ b/packages/keyring/cjs/testing.js @@ -0,0 +1,126 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PAIRSETHEREUM = exports.PAIRSSR25519 = void 0; +exports.createTestKeyring = createTestKeyring; +const util_1 = require("@pezkuwi/util"); +const index_js_1 = require("./pair/index.js"); +const keyring_js_1 = require("./keyring.js"); +exports.PAIRSSR25519 = [ + { + p: '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d', + s: '0x98319d4ff8a9508c4bb0cf0b5a78d760a0b2082c02775e6e82370816fedfff48925a225d97aa00682d6a59b95b18780c10d7032336e88f3442b42361f4a66011', // nosemgrep + seed: 'Alice', + type: 'sr25519' + }, + { + p: '0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f', + s: '0xe8da6c9d810e020f5e3c7f5af2dea314cbeaa0d72bc6421e92c0808a0c584a6046ab28e97c3ffc77fe12b5a4d37e8cd4afbfebbf2391ffc7cb07c0f38c023efd', // nosemgrep + seed: 'Alice//stash', + type: 'sr25519' + }, + { + p: '0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48', + s: '0x081ff694633e255136bdb456c20a5fc8fed21f8b964c11bb17ff534ce80ebd5941ae88f85d0c1bfc37be41c904e1dfc01de8c8067b0d6d5df25dd1ac0894a325', // nosemgrep + seed: 'Bob', + type: 'sr25519' + }, + { + p: '0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e', + s: '0xc006507cdfc267a21532394c49ca9b754ca71de21e15a1cdf807c7ceab6d0b6c3ed408d9d35311540dcd54931933e67cf1ea10d46f75408f82b789d9bd212fde', // nosemgrep + seed: 'Bob//stash', + type: 'sr25519' + }, + { + p: '0x90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22', + s: '0xa8f2d83016052e5d6d77b2f6fd5d59418922a09024cda701b3c34369ec43a7668faf12ff39cd4e5d92bb773972f41a7a5279ebc2ed92264bed8f47d344f8f18c', // nosemgrep + seed: 'Charlie', + type: 'sr25519' + }, + { + p: '0x306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20', + s: '0x20e05482ca4677e0edbc58ae9a3a59f6ed3b1a9484ba17e64d6fe8688b2b7b5d108c4487b9323b98b11fe36cb301b084e920f7b7895536809a6d62a451b25568', // nosemgrep + seed: 'Dave', + type: 'sr25519' + }, + { + p: '0xe659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e', + s: '0x683576abfd5dc35273e4264c23095a1bf21c14517bece57c7f0cc5c0ed4ce06a3dbf386b7828f348abe15d76973a72009e6ef86a5c91db2990cb36bb657c6587', // nosemgrep + seed: 'Eve', + type: 'sr25519' + }, + { + p: '0x1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c', + s: '0xb835c20f450079cf4f513900ae9faf8df06ad86c681884122c752a4b2bf74d4303e4f21bc6cc62bb4eeed5a9cce642c25e2d2ac1464093b50f6196d78e3a7426', // nosemgrep + seed: 'Ferdie', + type: 'sr25519' + } +]; +exports.PAIRSETHEREUM = [ + { + name: 'Alith', + p: '0x02509540919faacf9ab52146c9aa40db68172d83777250b28e4679176e49ccdd9f', + s: '0x5fb92d6e98884f76de468fa3f6278f8807c48bebc13595d45af5bdc4da702133', // nosemgrep + type: 'ethereum' + }, + { + name: 'Baltathar', + p: '0x033bc19e36ff1673910575b6727a974a9abd80c9a875d41ab3e2648dbfb9e4b518', + s: '0x8075991ce870b93a8870eca0c0f91913d12f47948ca0fd25b49c6fa7cdbeee8b', // nosemgrep + type: 'ethereum' + }, + { + name: 'Charleth', + p: '0x0234637bdc0e89b5d46543bcbf8edff329d2702bc995e27e9af4b1ba009a3c2a5e', + s: '0x0b6e18cafb6ed99687ec547bd28139cafdd2bffe70e6b688025de6b445aa5c5b', // nosemgrep + type: 'ethereum' + }, + { + name: 'Dorothy', + p: '0x02a00d60b2b408c2a14c5d70cdd2c205db8985ef737a7e55ad20ea32cc9e7c417c', + s: '0x39539ab1876910bbf3a223d84a29e28f1cb4e2e456503e7e91ed39b2e7223d68', // nosemgrep + type: 'ethereum' + }, + { + name: 'Ethan', + p: '0x025cdc005b752651cd3f728fb9192182acb3a9c89e19072cbd5b03f3ee1f1b3ffa', + s: '0x7dce9bc8babb68fec1409be38c8e1a52650206a7ed90ff956ae8a6d15eeaaef4', // nosemgrep + type: 'ethereum' + }, + { + name: 'Faith', + p: '0x037964b6c9d546da4646ada28a99e34acaa1d14e7aba861a9055f9bd200c8abf74', + s: '0xb9d2ea9a615f3165812e8d44de0d24da9bbd164b65c4f0573e1ce2c8dbd9c8df', // nosemgrep + type: 'ethereum' + } +]; +function createMeta(name, seed) { + if (!name && !seed) { + throw new Error('Testing pair should have either a name or a seed'); + } + return { + isTesting: true, + name: name || seed?.replace('//', '_').toLowerCase() + }; +} +/** + * @name testKeyring + * @summary Create an instance of Keyring pre-populated with locked test accounts + * @description The test accounts (i.e. alice, bob, dave, eve, ferdie) + * are available on the dev chain and each test account is initialized with DOT funds. + */ +function createTestKeyring(options = {}, isDerived = true) { + const keyring = new keyring_js_1.Keyring(options); + const pairs = options.type === 'ethereum' + ? exports.PAIRSETHEREUM + : exports.PAIRSSR25519; + for (const { name, p, s, seed, type } of pairs) { + const meta = createMeta(name, seed); + const pair = !isDerived && !name && seed + ? keyring.addFromUri(seed, meta, options.type) + : keyring.addPair((0, index_js_1.createPair)({ toSS58: keyring.encodeAddress, type }, { publicKey: (0, util_1.hexToU8a)(p), secretKey: (0, util_1.hexToU8a)(s) }, meta)); + pair.lock = () => { + // we don't have lock/unlock functionality here + }; + } + return keyring; +} diff --git a/packages/keyring/cjs/testingPairs.d.ts b/packages/keyring/cjs/testingPairs.d.ts new file mode 100644 index 0000000..8d76565 --- /dev/null +++ b/packages/keyring/cjs/testingPairs.d.ts @@ -0,0 +1,25 @@ +import type { KeypairType } from '@pezkuwi/util-crypto/types'; +import type { KeyringOptions, KeyringPair } from './types.js'; +export interface TestKeyringMap { + nobody: KeyringPair; + [index: string]: KeyringPair; +} +export interface TestKeyringMapBizinikiwi extends TestKeyringMap { + alice: KeyringPair; + bob: KeyringPair; + charlie: KeyringPair; + dave: KeyringPair; + eve: KeyringPair; + ferdie: KeyringPair; +} +export interface TestKeyringMapEthereum extends TestKeyringMap { + Alith: KeyringPair; + Baltathar: KeyringPair; + Charleth: KeyringPair; + Dorothy: KeyringPair; + Ethan: KeyringPair; + Faith: KeyringPair; +} +export type DetectMap = DetectPairType extends 'ethereum' ? TestKeyringMapEthereum : TestKeyringMapBizinikiwi; +export type DetectPairType = O extends KeyringOptions ? O['type'] extends KeypairType ? O['type'] : 'sr25519' : 'sr25519'; +export declare function createTestPairs>(options?: O, isDerived?: boolean): M; diff --git a/packages/keyring/cjs/testingPairs.js b/packages/keyring/cjs/testingPairs.js new file mode 100644 index 0000000..8d762d9 --- /dev/null +++ b/packages/keyring/cjs/testingPairs.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createTestPairs = createTestPairs; +const nobody_js_1 = require("./pair/nobody.js"); +const testing_js_1 = require("./testing.js"); +function createTestPairs(options, isDerived = true) { + const keyring = (0, testing_js_1.createTestKeyring)(options, isDerived); + const pairs = keyring.getPairs(); + const map = { nobody: (0, nobody_js_1.nobody)() }; + for (const p of pairs) { + if (p.meta.name) { + map[p.meta.name] = p; + } + } + return map; +} diff --git a/packages/keyring/cjs/types.d.ts b/packages/keyring/cjs/types.d.ts new file mode 100644 index 0000000..0bd1dc7 --- /dev/null +++ b/packages/keyring/cjs/types.d.ts @@ -0,0 +1,111 @@ +import type { HexString } from '@pezkuwi/util/types'; +import type { EncryptedJson, Keypair, KeypairType, Prefix } from '@pezkuwi/util-crypto/types'; +export interface KeyringOptions { + /** The ss58Format to use for address encoding (defaults to 42) */ + ss58Format?: Prefix; + /** The type of keyring to create (defaults to ed25519) */ + type?: KeypairType; +} +export interface KeyringPair$MetaHardware { + accountIndex?: number; + accountOffset?: number; + addressOffset?: number; + hardwareType?: 'ledger'; +} +export interface KeyringPair$MetaFlags { + isDefaultAuthSelected?: boolean; + isExternal?: boolean; + isHardware?: boolean; + isHidden?: boolean; + isInjected?: boolean; + isMultisig?: boolean; + isProxied?: boolean; + isRecent?: boolean; + isTesting?: boolean; +} +export interface KeyringPair$MetaContract { + abi: string; + genesisHash?: HexString | null; +} +export interface KeyringPair$MetaExtension { + source?: string; +} +export interface KeyringPair$MetaMultisig { + threshold?: number; + who?: string[]; +} +export interface KeyringPair$MetaParent { + parentAddress?: string; + parentName?: string; +} +export interface KeyringPair$Meta extends KeyringPair$MetaExtension, KeyringPair$MetaFlags, KeyringPair$MetaHardware, KeyringPair$MetaMultisig, KeyringPair$MetaParent { + address?: string; + contract?: KeyringPair$MetaContract; + genesisHash?: HexString | null; + name?: string; + suri?: string; + tags?: string[]; + type?: KeypairType; + whenCreated?: number; + whenEdited?: number; + whenUsed?: number; + [key: string]: unknown; +} +export interface KeyringPair$Json extends EncryptedJson { + /** The ss58 encoded address or the hex-encoded version (the latter is for ETH-compat chains) */ + address: string; + /** The underlying metadata associated with the keypair */ + meta: KeyringPair$Meta; +} +export interface SignOptions { + /** Create a MultiSignature-compatible output with an indicator type */ + withType?: boolean; +} +export interface KeyringPair { + readonly address: string; + readonly addressRaw: Uint8Array; + readonly meta: KeyringPair$Meta; + readonly isLocked: boolean; + readonly publicKey: Uint8Array; + readonly type: KeypairType; + decodePkcs8(passphrase?: string, encoded?: Uint8Array): void; + derive(suri: string, meta?: KeyringPair$Meta): KeyringPair; + encodePkcs8(passphrase?: string): Uint8Array; + lock(): void; + setMeta(meta: KeyringPair$Meta): void; + sign(message: string | Uint8Array, options?: SignOptions): Uint8Array; + toJson(passphrase?: string): KeyringPair$Json; + unlock(passphrase?: string): void; + verify(message: string | Uint8Array, signature: Uint8Array, signerPublic: string | Uint8Array): boolean; + vrfSign(message: string | Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): Uint8Array; + vrfVerify(message: string | Uint8Array, vrfResult: Uint8Array, signerPublic: string | Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): boolean; +} +export interface KeyringPairs { + add: (pair: KeyringPair) => KeyringPair; + all: () => KeyringPair[]; + get: (address: string | Uint8Array) => KeyringPair; + remove: (address: string | Uint8Array) => void; +} +export interface KeyringInstance { + readonly pairs: KeyringPair[]; + readonly publicKeys: Uint8Array[]; + readonly type: KeypairType; + decodeAddress(encoded: string | Uint8Array, ignoreChecksum?: boolean, ss58Format?: Prefix): Uint8Array; + encodeAddress(key: Uint8Array | string, ss58Format?: Prefix): string; + setSS58Format(ss58Format: Prefix): void; + addPair(pair: KeyringPair): KeyringPair; + addFromAddress(address: string | Uint8Array, meta?: KeyringPair$Meta, encoded?: Uint8Array | null, type?: KeypairType, ignoreChecksum?: boolean): KeyringPair; + addFromJson(pair: KeyringPair$Json, ignoreChecksum?: boolean): KeyringPair; + addFromMnemonic(mnemonic: string, meta?: KeyringPair$Meta, type?: KeypairType, wordlist?: string[]): KeyringPair; + addFromPair(pair: Keypair, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair; + addFromSeed(seed: Uint8Array, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair; + addFromUri(suri: string, meta?: KeyringPair$Meta, type?: KeypairType, wordlist?: string[]): KeyringPair; + createFromJson(json: KeyringPair$Json, ignoreChecksum?: boolean): KeyringPair; + createFromPair(pair: Keypair, meta: KeyringPair$Meta, type: KeypairType): KeyringPair; + createFromUri(suri: string, meta?: KeyringPair$Meta, type?: KeypairType, wordlist?: string[]): KeyringPair; + getPair(address: string | Uint8Array): KeyringPair; + getPairs(): KeyringPair[]; + getPublicKeys(): Uint8Array[]; + removePair(address: string | Uint8Array): void; + toJson(address: string | Uint8Array, passphrase?: string): KeyringPair$Json; +} diff --git a/packages/keyring/cjs/types.js b/packages/keyring/cjs/types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/packages/keyring/cjs/types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/packages/keyring/defaults.d.ts b/packages/keyring/defaults.d.ts new file mode 100644 index 0000000..bfeb45d --- /dev/null +++ b/packages/keyring/defaults.d.ts @@ -0,0 +1,2 @@ +export declare const DEV_PHRASE = "bottom drive obey lake curtain smoke basket hold race lonely fit walk"; +export declare const DEV_SEED = "0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e"; diff --git a/packages/keyring/defaults.js b/packages/keyring/defaults.js new file mode 100644 index 0000000..c53f0e9 --- /dev/null +++ b/packages/keyring/defaults.js @@ -0,0 +1,2 @@ +export const DEV_PHRASE = 'bottom drive obey lake curtain smoke basket hold race lonely fit walk'; +export const DEV_SEED = '0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e'; diff --git a/packages/keyring/index.d.ts b/packages/keyring/index.d.ts new file mode 100644 index 0000000..e350889 --- /dev/null +++ b/packages/keyring/index.d.ts @@ -0,0 +1,4 @@ +import './packageDetect.js'; +import { Keyring } from './bundle.js'; +export * from './bundle.js'; +export default Keyring; diff --git a/packages/keyring/index.js b/packages/keyring/index.js new file mode 100644 index 0000000..e350889 --- /dev/null +++ b/packages/keyring/index.js @@ -0,0 +1,4 @@ +import './packageDetect.js'; +import { Keyring } from './bundle.js'; +export * from './bundle.js'; +export default Keyring; diff --git a/packages/keyring/keyring.d.ts b/packages/keyring/keyring.d.ts new file mode 100644 index 0000000..f49d0b5 --- /dev/null +++ b/packages/keyring/keyring.d.ts @@ -0,0 +1,145 @@ +import type { EncryptedJsonEncoding, Keypair, KeypairType } from '@pezkuwi/util-crypto/types'; +import type { KeyringInstance, KeyringOptions, KeyringPair, KeyringPair$Json, KeyringPair$Meta } from './types.js'; +import { decodeAddress } from '@pezkuwi/util-crypto'; +/** + * # @pezkuwi/keyring + * + * ## Overview + * + * @name Keyring + * @summary Keyring management of user accounts + * @description Allows generation of keyring pairs from a variety of input combinations, such as + * json object containing account address or public key, account metadata, and account encoded using + * `addFromJson`, or by providing those values as arguments separately to `addFromAddress`, + * or by providing the mnemonic (seed phrase) and account metadata as arguments to `addFromMnemonic`. + * Stores the keyring pairs in a keyring pair dictionary. Removal of the keyring pairs from the keyring pair + * dictionary is achieved using `removePair`. Retrieval of all the stored pairs via `getPairs` or perform + * lookup of a pair for a given account address or public key using `getPair`. JSON metadata associated with + * an account may be obtained using `toJson` accompanied by the account passphrase. + */ +export declare class Keyring implements KeyringInstance { + #private; + decodeAddress: typeof decodeAddress; + constructor(options?: KeyringOptions); + /** + * @description retrieve the pairs (alias for getPairs) + */ + get pairs(): KeyringPair[]; + /** + * @description retrieve the publicKeys (alias for getPublicKeys) + */ + get publicKeys(): Uint8Array[]; + /** + * @description Returns the type of the keyring, ed25519, sr25519 or ecdsa + */ + get type(): KeypairType; + /** + * @name addPair + * @summary Stores an account, given a keyring pair, as a Key/Value (public key, pair) in Keyring Pair Dictionary + */ + addPair(pair: KeyringPair): KeyringPair; + /** + * @name addFromAddress + * @summary Stores an account, given an account address, as a Key/Value (public key, pair) in Keyring Pair Dictionary + * @description Allows user to explicitly provide separate inputs including account address or public key, and optionally + * the associated account metadata, and the default encoded value as arguments (that may be obtained from the json file + * of an account backup), and then generates a keyring pair from them that it passes to + * `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value. + */ + addFromAddress(address: string | Uint8Array, meta?: KeyringPair$Meta, encoded?: Uint8Array | null, type?: KeypairType, ignoreChecksum?: boolean, encType?: EncryptedJsonEncoding[]): KeyringPair; + /** + * @name addFromJson + * @summary Stores an account, given JSON data, as a Key/Value (public key, pair) in Keyring Pair Dictionary + * @description Allows user to provide a json object argument that contains account information (that may be obtained from the json file + * of an account backup), and then generates a keyring pair from it that it passes to + * `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value. + */ + addFromJson(json: KeyringPair$Json, ignoreChecksum?: boolean): KeyringPair; + /** + * @name addFromMnemonic + * @summary Stores an account, given a mnemonic, as a Key/Value (public key, pair) in Keyring Pair Dictionary + * @description Allows user to provide a mnemonic (seed phrase that is provided when account is originally created) + * argument and a metadata argument that contains account information (that may be obtained from the json file + * of an account backup), and then generates a keyring pair from it that it passes to + * `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value. + */ + addFromMnemonic(mnemonic: string, meta?: KeyringPair$Meta, type?: KeypairType, wordlist?: string[]): KeyringPair; + /** + * @name addFromPair + * @summary Stores an account created from an explicit publicKey/secreteKey combination + */ + addFromPair(pair: Keypair, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair; + /** + * @name addFromSeed + * @summary Stores an account, given seed data, as a Key/Value (public key, pair) in Keyring Pair Dictionary + * @description Stores in a keyring pair dictionary the public key of the pair as a key and the pair as the associated value. + * Allows user to provide the account seed as an argument, and then generates a keyring pair from it that it passes to + * `addPair` to store in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value. + */ + addFromSeed(seed: Uint8Array, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair; + /** + * @name addFromUri + * @summary Creates an account via an suri + * @description Extracts the phrase, path and password from a SURI format for specifying secret keys `//////` (the `///password` may be omitted, and `/` and `//` maybe repeated and mixed). The secret can be a hex string, mnemonic phrase or a string (to be padded) + */ + addFromUri(suri: string, meta?: KeyringPair$Meta, type?: KeypairType, wordlist?: string[]): KeyringPair; + /** + * @name createFromJson + * @description Creates a pair from a JSON keyfile + */ + createFromJson({ address, encoded, encoding: { content, type, version }, meta }: KeyringPair$Json, ignoreChecksum?: boolean): KeyringPair; + /** + * @name createFromPair + * @summary Creates a pair from an explicit publicKey/secreteKey combination + */ + createFromPair(pair: Keypair, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair; + /** + * @name createFromUri + * @summary Creates a Keypair from an suri + * @description This creates a pair from the suri, but does not add it to the keyring + */ + createFromUri(_suri: string, meta?: KeyringPair$Meta, type?: KeypairType, wordlist?: string[]): KeyringPair; + /** + * @name encodeAddress + * @description Encodes the input into an ss58 representation + */ + encodeAddress: (address: Uint8Array | string, ss58Format?: number) => string; + /** + * @name getPair + * @summary Retrieves an account keyring pair from the Keyring Pair Dictionary, given an account address + * @description Returns a keyring pair value from the keyring pair dictionary by performing + * a key lookup using the provided account address or public key (after decoding it). + */ + getPair(address: string | Uint8Array): KeyringPair; + /** + * @name getPairs + * @summary Retrieves all account keyring pairs from the Keyring Pair Dictionary + * @description Returns an array list of all the keyring pair values that are stored in the keyring pair dictionary. + */ + getPairs(): KeyringPair[]; + /** + * @name getPublicKeys + * @summary Retrieves Public Keys of all Keyring Pairs stored in the Keyring Pair Dictionary + * @description Returns an array list of all the public keys associated with each of the keyring pair values that are stored in the keyring pair dictionary. + */ + getPublicKeys(): Uint8Array[]; + /** + * @name removePair + * @description Deletes the provided input address or public key from the stored Keyring Pair Dictionary. + */ + removePair(address: string | Uint8Array): void; + /** + * @name setSS58Format; + * @description Sets the ss58 format for the keyring + */ + setSS58Format(ss58: number): void; + /** + * @name toJson + * @summary Returns a JSON object associated with the input argument that contains metadata assocated with an account + * @description Returns a JSON object containing the metadata associated with an account + * when valid address or public key and when the account passphrase is provided if the account secret + * is not already unlocked and available in memory. Note that in [Polkadot-JS Apps](https://github.com/polkadot-js/apps) the user + * may backup their account to a JSON file that contains this information. + */ + toJson(address: string | Uint8Array, passphrase?: string): KeyringPair$Json; +} diff --git a/packages/keyring/keyring.js b/packages/keyring/keyring.js new file mode 100644 index 0000000..ca044f5 --- /dev/null +++ b/packages/keyring/keyring.js @@ -0,0 +1,257 @@ +import { hexToU8a, isHex, stringToU8a } from '@pezkuwi/util'; +import { base64Decode, decodeAddress, ed25519PairFromSeed as ed25519FromSeed, encodeAddress, ethereumEncode, hdEthereum, keyExtractSuri, keyFromPath, mnemonicToLegacySeed, mnemonicToMiniSecret, secp256k1PairFromSeed as secp256k1FromSeed, sr25519PairFromSeed as sr25519FromSeed } from '@pezkuwi/util-crypto'; +import { createPair } from './pair/index.js'; +import { DEV_PHRASE } from './defaults.js'; +import { Pairs } from './pairs.js'; +const PairFromSeed = { + ecdsa: (seed) => secp256k1FromSeed(seed), + ed25519: (seed) => ed25519FromSeed(seed), + ethereum: (seed) => secp256k1FromSeed(seed), + sr25519: (seed) => sr25519FromSeed(seed) +}; +function pairToPublic({ publicKey }) { + return publicKey; +} +/** + * # @pezkuwi/keyring + * + * ## Overview + * + * @name Keyring + * @summary Keyring management of user accounts + * @description Allows generation of keyring pairs from a variety of input combinations, such as + * json object containing account address or public key, account metadata, and account encoded using + * `addFromJson`, or by providing those values as arguments separately to `addFromAddress`, + * or by providing the mnemonic (seed phrase) and account metadata as arguments to `addFromMnemonic`. + * Stores the keyring pairs in a keyring pair dictionary. Removal of the keyring pairs from the keyring pair + * dictionary is achieved using `removePair`. Retrieval of all the stored pairs via `getPairs` or perform + * lookup of a pair for a given account address or public key using `getPair`. JSON metadata associated with + * an account may be obtained using `toJson` accompanied by the account passphrase. + */ +export class Keyring { + #pairs; + #type; + #ss58; + decodeAddress = decodeAddress; + constructor(options = {}) { + options.type = options.type || 'ed25519'; + if (!['ecdsa', 'ethereum', 'ed25519', 'sr25519'].includes(options.type || 'undefined')) { + throw new Error(`Expected a keyring type of either 'ed25519', 'sr25519', 'ethereum' or 'ecdsa', found '${options.type || 'unknown'}`); + } + this.#pairs = new Pairs(); + this.#ss58 = options.ss58Format; + this.#type = options.type; + } + /** + * @description retrieve the pairs (alias for getPairs) + */ + get pairs() { + return this.getPairs(); + } + /** + * @description retrieve the publicKeys (alias for getPublicKeys) + */ + get publicKeys() { + return this.getPublicKeys(); + } + /** + * @description Returns the type of the keyring, ed25519, sr25519 or ecdsa + */ + get type() { + return this.#type; + } + /** + * @name addPair + * @summary Stores an account, given a keyring pair, as a Key/Value (public key, pair) in Keyring Pair Dictionary + */ + addPair(pair) { + return this.#pairs.add(pair); + } + /** + * @name addFromAddress + * @summary Stores an account, given an account address, as a Key/Value (public key, pair) in Keyring Pair Dictionary + * @description Allows user to explicitly provide separate inputs including account address or public key, and optionally + * the associated account metadata, and the default encoded value as arguments (that may be obtained from the json file + * of an account backup), and then generates a keyring pair from them that it passes to + * `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value. + */ + addFromAddress(address, meta = {}, encoded = null, type = this.type, ignoreChecksum, encType) { + const publicKey = this.decodeAddress(address, ignoreChecksum); + return this.addPair(createPair({ toSS58: this.encodeAddress, type }, { publicKey, secretKey: new Uint8Array() }, meta, encoded, encType)); + } + /** + * @name addFromJson + * @summary Stores an account, given JSON data, as a Key/Value (public key, pair) in Keyring Pair Dictionary + * @description Allows user to provide a json object argument that contains account information (that may be obtained from the json file + * of an account backup), and then generates a keyring pair from it that it passes to + * `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value. + */ + addFromJson(json, ignoreChecksum) { + return this.addPair(this.createFromJson(json, ignoreChecksum)); + } + /** + * @name addFromMnemonic + * @summary Stores an account, given a mnemonic, as a Key/Value (public key, pair) in Keyring Pair Dictionary + * @description Allows user to provide a mnemonic (seed phrase that is provided when account is originally created) + * argument and a metadata argument that contains account information (that may be obtained from the json file + * of an account backup), and then generates a keyring pair from it that it passes to + * `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value. + */ + addFromMnemonic(mnemonic, meta = {}, type = this.type, wordlist) { + return this.addFromUri(mnemonic, meta, type, wordlist); + } + /** + * @name addFromPair + * @summary Stores an account created from an explicit publicKey/secreteKey combination + */ + addFromPair(pair, meta = {}, type = this.type) { + return this.addPair(this.createFromPair(pair, meta, type)); + } + /** + * @name addFromSeed + * @summary Stores an account, given seed data, as a Key/Value (public key, pair) in Keyring Pair Dictionary + * @description Stores in a keyring pair dictionary the public key of the pair as a key and the pair as the associated value. + * Allows user to provide the account seed as an argument, and then generates a keyring pair from it that it passes to + * `addPair` to store in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value. + */ + addFromSeed(seed, meta = {}, type = this.type) { + return this.addPair(createPair({ toSS58: this.encodeAddress, type }, PairFromSeed[type](seed), meta, null)); + } + /** + * @name addFromUri + * @summary Creates an account via an suri + * @description Extracts the phrase, path and password from a SURI format for specifying secret keys `//////` (the `///password` may be omitted, and `/` and `//` maybe repeated and mixed). The secret can be a hex string, mnemonic phrase or a string (to be padded) + */ + addFromUri(suri, meta = {}, type = this.type, wordlist) { + return this.addPair(this.createFromUri(suri, meta, type, wordlist)); + } + /** + * @name createFromJson + * @description Creates a pair from a JSON keyfile + */ + createFromJson({ address, encoded, encoding: { content, type, version }, meta }, ignoreChecksum) { + if (version === '3' && content[0] !== 'pkcs8') { + throw new Error(`Unable to decode non-pkcs8 type, [${content.join(',')}] found}`); + } + const cryptoType = version === '0' || !Array.isArray(content) + ? this.type + : content[1]; + const encType = !Array.isArray(type) + ? [type] + : type; + if (!['ed25519', 'sr25519', 'ecdsa', 'ethereum'].includes(cryptoType)) { + throw new Error(`Unknown crypto type ${cryptoType}`); + } + // Here the address and publicKey are 32 bytes and isomorphic. This is why the address field needs to be the public key for ethereum type pairs + const publicKey = isHex(address) + ? hexToU8a(address) + : this.decodeAddress(address, ignoreChecksum); + const decoded = isHex(encoded) + ? hexToU8a(encoded) + : base64Decode(encoded); + return createPair({ toSS58: this.encodeAddress, type: cryptoType }, { publicKey, secretKey: new Uint8Array() }, meta, decoded, encType); + } + /** + * @name createFromPair + * @summary Creates a pair from an explicit publicKey/secreteKey combination + */ + createFromPair(pair, meta = {}, type = this.type) { + return createPair({ toSS58: this.encodeAddress, type }, pair, meta, null); + } + /** + * @name createFromUri + * @summary Creates a Keypair from an suri + * @description This creates a pair from the suri, but does not add it to the keyring + */ + createFromUri(_suri, meta = {}, type = this.type, wordlist) { + // here we only aut-add the dev phrase if we have a hard-derived path + const suri = _suri.startsWith('//') + ? `${DEV_PHRASE}${_suri}` + : _suri; + const { derivePath, password, path, phrase } = keyExtractSuri(suri); + let seed; + const isPhraseHex = isHex(phrase, 256); + if (isPhraseHex) { + seed = hexToU8a(phrase); + } + else { + const parts = phrase.split(' '); + if ([12, 15, 18, 21, 24].includes(parts.length)) { + seed = type === 'ethereum' + ? mnemonicToLegacySeed(phrase, '', false, 64) + : mnemonicToMiniSecret(phrase, password, wordlist); + } + else { + if (phrase.length > 32) { + throw new Error('specified phrase is not a valid mnemonic and is invalid as a raw seed at > 32 bytes'); + } + seed = stringToU8a(phrase.padEnd(32)); + } + } + const derived = type === 'ethereum' + ? isPhraseHex + ? PairFromSeed[type](seed) // for eth, if the private key is provided as suri, it must be derived only once + : hdEthereum(seed, derivePath.substring(1)) + : keyFromPath(PairFromSeed[type](seed), path, type); + return createPair({ toSS58: this.encodeAddress, type }, derived, meta, null); + } + /** + * @name encodeAddress + * @description Encodes the input into an ss58 representation + */ + encodeAddress = (address, ss58Format) => { + return this.type === 'ethereum' + ? ethereumEncode(address) + : encodeAddress(address, ss58Format ?? this.#ss58); + }; + /** + * @name getPair + * @summary Retrieves an account keyring pair from the Keyring Pair Dictionary, given an account address + * @description Returns a keyring pair value from the keyring pair dictionary by performing + * a key lookup using the provided account address or public key (after decoding it). + */ + getPair(address) { + return this.#pairs.get(address); + } + /** + * @name getPairs + * @summary Retrieves all account keyring pairs from the Keyring Pair Dictionary + * @description Returns an array list of all the keyring pair values that are stored in the keyring pair dictionary. + */ + getPairs() { + return this.#pairs.all(); + } + /** + * @name getPublicKeys + * @summary Retrieves Public Keys of all Keyring Pairs stored in the Keyring Pair Dictionary + * @description Returns an array list of all the public keys associated with each of the keyring pair values that are stored in the keyring pair dictionary. + */ + getPublicKeys() { + return this.#pairs.all().map(pairToPublic); + } + /** + * @name removePair + * @description Deletes the provided input address or public key from the stored Keyring Pair Dictionary. + */ + removePair(address) { + this.#pairs.remove(address); + } + /** + * @name setSS58Format; + * @description Sets the ss58 format for the keyring + */ + setSS58Format(ss58) { + this.#ss58 = ss58; + } + /** + * @name toJson + * @summary Returns a JSON object associated with the input argument that contains metadata assocated with an account + * @description Returns a JSON object containing the metadata associated with an account + * when valid address or public key and when the account passphrase is provided if the account secret + * is not already unlocked and available in memory. Note that in [Polkadot-JS Apps](https://github.com/polkadot-js/apps) the user + * may backup their account to a JSON file that contains this information. + */ + toJson(address, passphrase) { + return this.#pairs.get(address).toJson(passphrase); + } +} diff --git a/packages/keyring/package.json b/packages/keyring/package.json index 8a846bd..4f7d690 100644 --- a/packages/keyring/package.json +++ b/packages/keyring/package.json @@ -15,18 +15,280 @@ }, "sideEffects": [ "./packageDetect.js", - "./packageDetect.cjs" + "./cjs/packageDetect.js" ], "type": "module", - "version": "14.0.10", - "main": "index.js", + "version": "14.0.11", + "main": "./cjs/index.js", + "module": "./index.js", + "types": "./index.d.ts", + "exports": { + "./cjs/package.json": "./cjs/package.json", + "./cjs/*": "./cjs/*.js", + ".": { + "module": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "require": { + "types": "./cjs/index.d.ts", + "default": "./cjs/index.js" + }, + "default": { + "types": "./index.d.ts", + "default": "./index.js" + } + }, + "./bundle": { + "module": { + "types": "./bundle.d.ts", + "default": "./bundle.js" + }, + "require": { + "types": "./cjs/bundle.d.ts", + "default": "./cjs/bundle.js" + }, + "default": { + "types": "./bundle.d.ts", + "default": "./bundle.js" + } + }, + "./defaults": { + "module": { + "types": "./defaults.d.ts", + "default": "./defaults.js" + }, + "require": { + "types": "./cjs/defaults.d.ts", + "default": "./cjs/defaults.js" + }, + "default": { + "types": "./defaults.d.ts", + "default": "./defaults.js" + } + }, + "./keyring": { + "module": { + "types": "./keyring.d.ts", + "default": "./keyring.js" + }, + "require": { + "types": "./cjs/keyring.d.ts", + "default": "./cjs/keyring.js" + }, + "default": { + "types": "./keyring.d.ts", + "default": "./keyring.js" + } + }, + "./package.json": { + "require": "./cjs/package.json", + "default": "./package.json" + }, + "./packageDetect": { + "module": { + "types": "./packageDetect.d.ts", + "default": "./packageDetect.js" + }, + "require": { + "types": "./cjs/packageDetect.d.ts", + "default": "./cjs/packageDetect.js" + }, + "default": { + "types": "./packageDetect.d.ts", + "default": "./packageDetect.js" + } + }, + "./packageInfo.js": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./packageInfo": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./pair": { + "module": { + "types": "./pair/index.d.ts", + "default": "./pair/index.js" + }, + "require": { + "types": "./cjs/pair/index.d.ts", + "default": "./cjs/pair/index.js" + }, + "default": { + "types": "./pair/index.d.ts", + "default": "./pair/index.js" + } + }, + "./pair/decode": { + "module": { + "types": "./pair/decode.d.ts", + "default": "./pair/decode.js" + }, + "require": { + "types": "./cjs/pair/decode.d.ts", + "default": "./cjs/pair/decode.js" + }, + "default": { + "types": "./pair/decode.d.ts", + "default": "./pair/decode.js" + } + }, + "./pair/defaults": { + "module": { + "types": "./pair/defaults.d.ts", + "default": "./pair/defaults.js" + }, + "require": { + "types": "./cjs/pair/defaults.d.ts", + "default": "./cjs/pair/defaults.js" + }, + "default": { + "types": "./pair/defaults.d.ts", + "default": "./pair/defaults.js" + } + }, + "./pair/encode": { + "module": { + "types": "./pair/encode.d.ts", + "default": "./pair/encode.js" + }, + "require": { + "types": "./cjs/pair/encode.d.ts", + "default": "./cjs/pair/encode.js" + }, + "default": { + "types": "./pair/encode.d.ts", + "default": "./pair/encode.js" + } + }, + "./pair/nobody": { + "module": { + "types": "./pair/nobody.d.ts", + "default": "./pair/nobody.js" + }, + "require": { + "types": "./cjs/pair/nobody.d.ts", + "default": "./cjs/pair/nobody.js" + }, + "default": { + "types": "./pair/nobody.d.ts", + "default": "./pair/nobody.js" + } + }, + "./pair/toJson": { + "module": { + "types": "./pair/toJson.d.ts", + "default": "./pair/toJson.js" + }, + "require": { + "types": "./cjs/pair/toJson.d.ts", + "default": "./cjs/pair/toJson.js" + }, + "default": { + "types": "./pair/toJson.d.ts", + "default": "./pair/toJson.js" + } + }, + "./pair/types": { + "module": { + "types": "./pair/types.d.ts", + "default": "./pair/types.js" + }, + "require": { + "types": "./cjs/pair/types.d.ts", + "default": "./cjs/pair/types.js" + }, + "default": { + "types": "./pair/types.d.ts", + "default": "./pair/types.js" + } + }, + "./pairs": { + "module": { + "types": "./pairs.d.ts", + "default": "./pairs.js" + }, + "require": { + "types": "./cjs/pairs.d.ts", + "default": "./cjs/pairs.js" + }, + "default": { + "types": "./pairs.d.ts", + "default": "./pairs.js" + } + }, + "./testing": { + "module": { + "types": "./testing.d.ts", + "default": "./testing.js" + }, + "require": { + "types": "./cjs/testing.d.ts", + "default": "./cjs/testing.js" + }, + "default": { + "types": "./testing.d.ts", + "default": "./testing.js" + } + }, + "./testingPairs": { + "module": { + "types": "./testingPairs.d.ts", + "default": "./testingPairs.js" + }, + "require": { + "types": "./cjs/testingPairs.d.ts", + "default": "./cjs/testingPairs.js" + }, + "default": { + "types": "./testingPairs.d.ts", + "default": "./testingPairs.js" + } + }, + "./types": { + "module": { + "types": "./types.d.ts", + "default": "./types.js" + }, + "require": { + "types": "./cjs/types.d.ts", + "default": "./cjs/types.js" + }, + "default": { + "types": "./types.d.ts", + "default": "./types.js" + } + } + }, "dependencies": { - "@pezkuwi/util": "workspace:*", - "@pezkuwi/util-crypto": "workspace:*", + "@pezkuwi/util": "14.0.11", + "@pezkuwi/util-crypto": "14.0.11", "tslib": "^2.8.0" }, "peerDependencies": { - "@pezkuwi/util": "workspace:*", - "@pezkuwi/util-crypto": "workspace:*" + "@pezkuwi/util": "14.0.11", + "@pezkuwi/util-crypto": "14.0.11" } } diff --git a/packages/keyring/packageDetect.d.ts b/packages/keyring/packageDetect.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/keyring/packageDetect.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/keyring/packageDetect.js b/packages/keyring/packageDetect.js new file mode 100644 index 0000000..8f262f2 --- /dev/null +++ b/packages/keyring/packageDetect.js @@ -0,0 +1,5 @@ +import { detectPackage } from '@pezkuwi/util'; +import { packageInfo as utilInfo } from '@pezkuwi/util/packageInfo'; +import { packageInfo as cryptoInfo } from '@pezkuwi/util-crypto/packageInfo'; +import { packageInfo } from './packageInfo.js'; +detectPackage(packageInfo, null, [cryptoInfo, utilInfo]); diff --git a/packages/keyring/packageInfo.d.ts b/packages/keyring/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/keyring/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/keyring/packageInfo.js b/packages/keyring/packageInfo.js new file mode 100644 index 0000000..a3e5106 --- /dev/null +++ b/packages/keyring/packageInfo.js @@ -0,0 +1 @@ +export const packageInfo = { name: '@pezkuwi/keyring', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; diff --git a/packages/keyring/pair/decode.d.ts b/packages/keyring/pair/decode.d.ts new file mode 100644 index 0000000..422f747 --- /dev/null +++ b/packages/keyring/pair/decode.d.ts @@ -0,0 +1,12 @@ +import type { EncryptedJsonEncoding } from '@pezkuwi/util-crypto/types'; +/** + * Decode a pair, taking into account the generation-specific formats and headers + * + * For divisor/headers, don't rely on the magic being static. These will + * change between generations, aka with the long-awaited 4th generation + * of the format. The external decode interface is the only way to use and decode these. + **/ +export declare function decodePair(passphrase?: string, encrypted?: Uint8Array | null, _encType?: EncryptedJsonEncoding | EncryptedJsonEncoding[]): { + publicKey: Uint8Array; + secretKey: Uint8Array; +}; diff --git a/packages/keyring/pair/decode.js b/packages/keyring/pair/decode.js new file mode 100644 index 0000000..28412ed --- /dev/null +++ b/packages/keyring/pair/decode.js @@ -0,0 +1,42 @@ +import { u8aEq } from '@pezkuwi/util'; +import { jsonDecryptData } from '@pezkuwi/util-crypto'; +import { PAIR_DIV, PAIR_HDR, PUB_LENGTH, SEC_LENGTH, SEED_LENGTH } from './defaults.js'; +const SEED_OFFSET = PAIR_HDR.length; +/** + * Decode a pair, taking into account the generation-specific formats and headers + * + * For divisor/headers, don't rely on the magic being static. These will + * change between generations, aka with the long-awaited 4th generation + * of the format. The external decode interface is the only way to use and decode these. + **/ +export function decodePair(passphrase, encrypted, _encType) { + const encType = Array.isArray(_encType) || _encType === undefined + ? _encType + : [_encType]; + const decrypted = jsonDecryptData(encrypted, passphrase, encType); + const header = decrypted.subarray(0, PAIR_HDR.length); + // check the start header (generations 1-3) + if (!u8aEq(header, PAIR_HDR)) { + throw new Error('Invalid encoding header found in body'); + } + // setup for generation 3 format + let secretKey = decrypted.subarray(SEED_OFFSET, SEED_OFFSET + SEC_LENGTH); + let divOffset = SEED_OFFSET + SEC_LENGTH; + let divider = decrypted.subarray(divOffset, divOffset + PAIR_DIV.length); + // old-style (generation 1 & 2), we have the seed here + if (!u8aEq(divider, PAIR_DIV)) { + divOffset = SEED_OFFSET + SEED_LENGTH; + secretKey = decrypted.subarray(SEED_OFFSET, divOffset); + divider = decrypted.subarray(divOffset, divOffset + PAIR_DIV.length); + // check the divisior at this point (already checked for generation 3) + if (!u8aEq(divider, PAIR_DIV)) { + throw new Error('Invalid encoding divider found in body'); + } + } + const pubOffset = divOffset + PAIR_DIV.length; + const publicKey = decrypted.subarray(pubOffset, pubOffset + PUB_LENGTH); + return { + publicKey, + secretKey + }; +} diff --git a/packages/keyring/pair/defaults.d.ts b/packages/keyring/pair/defaults.d.ts new file mode 100644 index 0000000..bbff8c3 --- /dev/null +++ b/packages/keyring/pair/defaults.d.ts @@ -0,0 +1,12 @@ +/** public/secret section divider (generation 1-3, will change in 4, don't rely on value) */ +export declare const PAIR_DIV: Uint8Array; +/** public/secret start block (generation 1-3, will change in 4, don't rely on value) */ +export declare const PAIR_HDR: Uint8Array; +/** length of a public key */ +export declare const PUB_LENGTH = 32; +/** length of a salt */ +export declare const SALT_LENGTH = 32; +/** length of a secret key */ +export declare const SEC_LENGTH = 64; +/** length of a user-input seed */ +export declare const SEED_LENGTH = 32; diff --git a/packages/keyring/pair/defaults.js b/packages/keyring/pair/defaults.js new file mode 100644 index 0000000..2c34d00 --- /dev/null +++ b/packages/keyring/pair/defaults.js @@ -0,0 +1,12 @@ +/** public/secret section divider (generation 1-3, will change in 4, don't rely on value) */ +export const PAIR_DIV = new Uint8Array([161, 35, 3, 33, 0]); +/** public/secret start block (generation 1-3, will change in 4, don't rely on value) */ +export const PAIR_HDR = new Uint8Array([48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32]); +/** length of a public key */ +export const PUB_LENGTH = 32; +/** length of a salt */ +export const SALT_LENGTH = 32; +/** length of a secret key */ +export const SEC_LENGTH = 64; +/** length of a user-input seed */ +export const SEED_LENGTH = 32; diff --git a/packages/keyring/pair/encode.d.ts b/packages/keyring/pair/encode.d.ts new file mode 100644 index 0000000..2896952 --- /dev/null +++ b/packages/keyring/pair/encode.d.ts @@ -0,0 +1,5 @@ +import type { PairInfo } from './types.js'; +/** + * Encode a pair with the latest generation format (generation 3) + **/ +export declare function encodePair({ publicKey, secretKey }: PairInfo, passphrase?: string): Uint8Array; diff --git a/packages/keyring/pair/encode.js b/packages/keyring/pair/encode.js new file mode 100644 index 0000000..ab8d9d2 --- /dev/null +++ b/packages/keyring/pair/encode.js @@ -0,0 +1,19 @@ +import { u8aConcat } from '@pezkuwi/util'; +import { naclEncrypt, scryptEncode, scryptToU8a } from '@pezkuwi/util-crypto'; +import { PAIR_DIV, PAIR_HDR } from './defaults.js'; +/** + * Encode a pair with the latest generation format (generation 3) + **/ +export function encodePair({ publicKey, secretKey }, passphrase) { + if (!secretKey) { + throw new Error('Expected a valid secretKey to be passed to encode'); + } + const encoded = u8aConcat(PAIR_HDR, secretKey, PAIR_DIV, publicKey); + if (!passphrase) { + return encoded; + } + // this is only for generation 3 (previous generations are only handled in decoding) + const { params, password, salt } = scryptEncode(passphrase); + const { encrypted, nonce } = naclEncrypt(encoded, password.subarray(0, 32)); + return u8aConcat(scryptToU8a(salt, params), nonce, encrypted); +} diff --git a/packages/keyring/pair/index.d.ts b/packages/keyring/pair/index.d.ts new file mode 100644 index 0000000..94b4810 --- /dev/null +++ b/packages/keyring/pair/index.d.ts @@ -0,0 +1,40 @@ +import type { EncryptedJsonEncoding, KeypairType } from '@pezkuwi/util-crypto/types'; +import type { KeyringPair, KeyringPair$Meta } from '../types.js'; +import type { PairInfo } from './types.js'; +interface Setup { + toSS58: (publicKey: Uint8Array) => string; + type: KeypairType; +} +/** + * @name createPair + * @summary Creates a keyring pair object + * @description Creates a keyring pair object with provided account public key, metadata, and encoded arguments. + * The keyring pair stores the account state including the encoded address and associated metadata. + * + * It has properties whose values are functions that may be called to perform account actions: + * + * - `address` function retrieves the address associated with the account. + * - `decodedPkcs8` function is called with the account passphrase and account encoded public key. + * It decodes the encoded public key using the passphrase provided to obtain the decoded account public key + * and associated secret key that are then available in memory, and changes the account address stored in the + * state of the pair to correspond to the address of the decoded public key. + * - `encodePkcs8` function when provided with the correct passphrase associated with the account pair + * and when the secret key is in memory (when the account pair is not locked) it returns an encoded + * public key of the account. + * - `meta` is the metadata that is stored in the state of the pair, either when it was originally + * created or set via `setMeta`. + * - `publicKey` returns the public key stored in memory for the pair. + * - `sign` may be used to return a signature by signing a provided message with the secret + * key (if it is in memory) using Nacl. + * - `toJson` calls another `toJson` function and provides the state of the pair, + * it generates arguments to be passed to the other `toJson` function including an encoded public key of the account + * that it generates using the secret key from memory (if it has been made available in memory) + * and the optionally provided passphrase argument. It passes a third boolean argument to `toJson` + * indicating whether the public key has been encoded or not (if a passphrase argument was provided then it is encoded). + * The `toJson` function that it calls returns a JSON object with properties including the `address` + * and `meta` that are assigned with the values stored in the corresponding state variables of the account pair, + * an `encoded` property that is assigned with the encoded public key in hex format, and an `encoding` + * property that indicates whether the public key value of the `encoded` property is encoded or not. + */ +export declare function createPair({ toSS58, type }: Setup, { publicKey, secretKey }: PairInfo, meta?: KeyringPair$Meta, encoded?: Uint8Array | null, encTypes?: EncryptedJsonEncoding[]): KeyringPair; +export {}; diff --git a/packages/keyring/pair/index.js b/packages/keyring/pair/index.js new file mode 100644 index 0000000..9123c6a --- /dev/null +++ b/packages/keyring/pair/index.js @@ -0,0 +1,180 @@ +import { objectSpread, u8aConcat, u8aEmpty, u8aEq, u8aToHex, u8aToU8a } from '@pezkuwi/util'; +import { blake2AsU8a, ed25519PairFromSeed as ed25519FromSeed, ed25519Sign, ethereumEncode, keccakAsU8a, keyExtractPath, keyFromPath, secp256k1Compress, secp256k1Expand, secp256k1PairFromSeed as secp256k1FromSeed, secp256k1Sign, signatureVerify, sr25519PairFromSeed as sr25519FromSeed, sr25519Sign, sr25519VrfSign, sr25519VrfVerify } from '@pezkuwi/util-crypto'; +import { decodePair } from './decode.js'; +import { encodePair } from './encode.js'; +import { pairToJson } from './toJson.js'; +const SIG_TYPE_NONE = new Uint8Array(); +const TYPE_FROM_SEED = { + ecdsa: secp256k1FromSeed, + ed25519: ed25519FromSeed, + ethereum: secp256k1FromSeed, + sr25519: sr25519FromSeed +}; +const TYPE_PREFIX = { + ecdsa: new Uint8Array([2]), + ed25519: new Uint8Array([0]), + ethereum: new Uint8Array([2]), + sr25519: new Uint8Array([1]) +}; +const TYPE_SIGNATURE = { + ecdsa: (m, p) => secp256k1Sign(m, p, 'blake2'), + ed25519: ed25519Sign, + ethereum: (m, p) => secp256k1Sign(m, p, 'keccak'), + sr25519: sr25519Sign +}; +const TYPE_ADDRESS = { + ecdsa: (p) => p.length > 32 ? blake2AsU8a(p) : p, + ed25519: (p) => p, + ethereum: (p) => p.length === 20 ? p : keccakAsU8a(secp256k1Expand(p)), + sr25519: (p) => p +}; +function isLocked(secretKey) { + return !secretKey || u8aEmpty(secretKey); +} +function vrfHash(proof, context, extra) { + return blake2AsU8a(u8aConcat(context || '', extra || '', proof)); +} +/** + * @name createPair + * @summary Creates a keyring pair object + * @description Creates a keyring pair object with provided account public key, metadata, and encoded arguments. + * The keyring pair stores the account state including the encoded address and associated metadata. + * + * It has properties whose values are functions that may be called to perform account actions: + * + * - `address` function retrieves the address associated with the account. + * - `decodedPkcs8` function is called with the account passphrase and account encoded public key. + * It decodes the encoded public key using the passphrase provided to obtain the decoded account public key + * and associated secret key that are then available in memory, and changes the account address stored in the + * state of the pair to correspond to the address of the decoded public key. + * - `encodePkcs8` function when provided with the correct passphrase associated with the account pair + * and when the secret key is in memory (when the account pair is not locked) it returns an encoded + * public key of the account. + * - `meta` is the metadata that is stored in the state of the pair, either when it was originally + * created or set via `setMeta`. + * - `publicKey` returns the public key stored in memory for the pair. + * - `sign` may be used to return a signature by signing a provided message with the secret + * key (if it is in memory) using Nacl. + * - `toJson` calls another `toJson` function and provides the state of the pair, + * it generates arguments to be passed to the other `toJson` function including an encoded public key of the account + * that it generates using the secret key from memory (if it has been made available in memory) + * and the optionally provided passphrase argument. It passes a third boolean argument to `toJson` + * indicating whether the public key has been encoded or not (if a passphrase argument was provided then it is encoded). + * The `toJson` function that it calls returns a JSON object with properties including the `address` + * and `meta` that are assigned with the values stored in the corresponding state variables of the account pair, + * an `encoded` property that is assigned with the encoded public key in hex format, and an `encoding` + * property that indicates whether the public key value of the `encoded` property is encoded or not. + */ +export function createPair({ toSS58, type }, { publicKey, secretKey }, meta = {}, encoded = null, encTypes) { + const decodePkcs8 = (passphrase, userEncoded) => { + const decoded = decodePair(passphrase, userEncoded || encoded, encTypes); + if (decoded.secretKey.length === 64) { + publicKey = decoded.publicKey; + secretKey = decoded.secretKey; + } + else { + const pair = TYPE_FROM_SEED[type](decoded.secretKey); + publicKey = pair.publicKey; + secretKey = pair.secretKey; + } + }; + const recode = (passphrase) => { + isLocked(secretKey) && encoded && decodePkcs8(passphrase, encoded); + encoded = encodePair({ publicKey, secretKey }, passphrase); // re-encode, latest version + encTypes = undefined; // swap to defaults, latest version follows + return encoded; + }; + const encodeAddress = () => { + const raw = TYPE_ADDRESS[type](publicKey); + return type === 'ethereum' + ? ethereumEncode(raw) + : toSS58(raw); + }; + return { + get address() { + return encodeAddress(); + }, + get addressRaw() { + const raw = TYPE_ADDRESS[type](publicKey); + return type === 'ethereum' + ? raw.slice(-20) + : raw; + }, + get isLocked() { + return isLocked(secretKey); + }, + get meta() { + return meta; + }, + get publicKey() { + return publicKey; + }, + get type() { + return type; + }, + // eslint-disable-next-line sort-keys + decodePkcs8, + derive: (suri, meta) => { + if (type === 'ethereum') { + throw new Error('Unable to derive on this keypair'); + } + else if (isLocked(secretKey)) { + throw new Error('Cannot derive on a locked keypair'); + } + const { path } = keyExtractPath(suri); + const derived = keyFromPath({ publicKey, secretKey }, path, type); + return createPair({ toSS58, type }, derived, meta, null); + }, + encodePkcs8: (passphrase) => { + return recode(passphrase); + }, + lock: () => { + secretKey = new Uint8Array(); + }, + setMeta: (additional) => { + meta = objectSpread({}, meta, additional); + }, + sign: (message, options = {}) => { + if (isLocked(secretKey)) { + throw new Error('Cannot sign with a locked key pair'); + } + return u8aConcat(options.withType + ? TYPE_PREFIX[type] + : SIG_TYPE_NONE, TYPE_SIGNATURE[type](u8aToU8a(message), { publicKey, secretKey })); + }, + toJson: (passphrase) => { + // NOTE: For ecdsa and ethereum, the publicKey cannot be extracted from the address. For these + // pass the hex-encoded publicKey through to the address portion of the JSON (before decoding) + // unless the publicKey is already an address + const address = ['ecdsa', 'ethereum'].includes(type) + ? publicKey.length === 20 + ? u8aToHex(publicKey) + : u8aToHex(secp256k1Compress(publicKey)) + : encodeAddress(); + return pairToJson(type, { address, meta }, recode(passphrase), !!passphrase); + }, + unlock: (passphrase) => { + return decodePkcs8(passphrase); + }, + verify: (message, signature, signerPublic) => { + return signatureVerify(message, signature, TYPE_ADDRESS[type](u8aToU8a(signerPublic))).isValid; + }, + vrfSign: (message, context, extra) => { + if (isLocked(secretKey)) { + throw new Error('Cannot sign with a locked key pair'); + } + if (type === 'sr25519') { + return sr25519VrfSign(message, { secretKey }, context, extra); + } + const proof = TYPE_SIGNATURE[type](u8aToU8a(message), { publicKey, secretKey }); + return u8aConcat(vrfHash(proof, context, extra), proof); + }, + vrfVerify: (message, vrfResult, signerPublic, context, extra) => { + if (type === 'sr25519') { + return sr25519VrfVerify(message, vrfResult, publicKey, context, extra); + } + const result = signatureVerify(message, u8aConcat(TYPE_PREFIX[type], vrfResult.subarray(32)), TYPE_ADDRESS[type](u8aToU8a(signerPublic))); + return result.isValid && u8aEq(vrfResult.subarray(0, 32), vrfHash(vrfResult.subarray(32), context, extra)); + } + }; +} diff --git a/packages/keyring/pair/nobody.d.ts b/packages/keyring/pair/nobody.d.ts new file mode 100644 index 0000000..d7fae62 --- /dev/null +++ b/packages/keyring/pair/nobody.d.ts @@ -0,0 +1,2 @@ +import type { KeyringPair } from '../types.js'; +export declare function nobody(): KeyringPair; diff --git a/packages/keyring/pair/nobody.js b/packages/keyring/pair/nobody.js new file mode 100644 index 0000000..56611db --- /dev/null +++ b/packages/keyring/pair/nobody.js @@ -0,0 +1,40 @@ +const publicKey = new Uint8Array(32); +const address = '5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM'; +const meta = { + isTesting: true, + name: 'nobody' +}; +const json = { + address, + encoded: '', + encoding: { + content: ['pkcs8', 'ed25519'], + type: 'none', + version: '0' + }, + meta +}; +const pair = { + address, + addressRaw: publicKey, + decodePkcs8: (_passphrase, _encoded) => undefined, + derive: (_suri, _meta) => pair, + encodePkcs8: (_passphrase) => new Uint8Array(0), + isLocked: true, + lock: () => { + // no locking, it is always locked + }, + meta, + publicKey, + setMeta: (_meta) => undefined, + sign: (_message) => new Uint8Array(64), + toJson: (_passphrase) => json, + type: 'ed25519', + unlock: (_passphrase) => undefined, + verify: (_message, _signature) => false, + vrfSign: (_message, _context, _extra) => new Uint8Array(96), + vrfVerify: (_message, _vrfResult, _context, _extra) => false +}; +export function nobody() { + return pair; +} diff --git a/packages/keyring/pair/toJson.d.ts b/packages/keyring/pair/toJson.d.ts new file mode 100644 index 0000000..b1e671b --- /dev/null +++ b/packages/keyring/pair/toJson.d.ts @@ -0,0 +1,8 @@ +import type { KeypairType } from '@pezkuwi/util-crypto/types'; +import type { KeyringPair$Json, KeyringPair$Meta } from '../types.js'; +interface PairStateJson { + address: string; + meta: KeyringPair$Meta; +} +export declare function pairToJson(type: KeypairType, { address, meta }: PairStateJson, encoded: Uint8Array, isEncrypted: boolean): KeyringPair$Json; +export {}; diff --git a/packages/keyring/pair/toJson.js b/packages/keyring/pair/toJson.js new file mode 100644 index 0000000..dbc8658 --- /dev/null +++ b/packages/keyring/pair/toJson.js @@ -0,0 +1,8 @@ +import { objectSpread } from '@pezkuwi/util'; +import { jsonEncryptFormat } from '@pezkuwi/util-crypto'; +export function pairToJson(type, { address, meta }, encoded, isEncrypted) { + return objectSpread(jsonEncryptFormat(encoded, ['pkcs8', type], isEncrypted), { + address, + meta + }); +} diff --git a/packages/keyring/pair/types.d.ts b/packages/keyring/pair/types.d.ts new file mode 100644 index 0000000..37ef45f --- /dev/null +++ b/packages/keyring/pair/types.d.ts @@ -0,0 +1,5 @@ +export interface PairInfo { + publicKey: Uint8Array; + secretKey?: Uint8Array | undefined; + seed?: Uint8Array | null; +} diff --git a/packages/keyring/pair/types.js b/packages/keyring/pair/types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/keyring/pair/types.js @@ -0,0 +1 @@ +export {}; diff --git a/packages/keyring/pairs.d.ts b/packages/keyring/pairs.d.ts new file mode 100644 index 0000000..99eb5e1 --- /dev/null +++ b/packages/keyring/pairs.d.ts @@ -0,0 +1,8 @@ +import type { KeyringPair, KeyringPairs } from './types.js'; +export declare class Pairs implements KeyringPairs { + #private; + add(pair: KeyringPair): KeyringPair; + all(): KeyringPair[]; + get(address: string | Uint8Array): KeyringPair; + remove(address: string | Uint8Array): void; +} diff --git a/packages/keyring/pairs.js b/packages/keyring/pairs.js new file mode 100644 index 0000000..ceedce6 --- /dev/null +++ b/packages/keyring/pairs.js @@ -0,0 +1,24 @@ +import { isHex, isU8a, u8aToHex, u8aToU8a } from '@pezkuwi/util'; +import { decodeAddress } from '@pezkuwi/util-crypto'; +export class Pairs { + #map = {}; + add(pair) { + this.#map[decodeAddress(pair.address).toString()] = pair; + return pair; + } + all() { + return Object.values(this.#map); + } + get(address) { + const pair = this.#map[decodeAddress(address).toString()]; + if (!pair) { + throw new Error(`Unable to retrieve keypair '${isU8a(address) || isHex(address) + ? u8aToHex(u8aToU8a(address)) + : address}'`); + } + return pair; + } + remove(address) { + delete this.#map[decodeAddress(address).toString()]; + } +} diff --git a/packages/keyring/testing.d.ts b/packages/keyring/testing.d.ts new file mode 100644 index 0000000..4aca4b3 --- /dev/null +++ b/packages/keyring/testing.d.ts @@ -0,0 +1,20 @@ +import type { HexString } from '@pezkuwi/util/types'; +import type { KeypairType } from '@pezkuwi/util-crypto/types'; +import type { KeyringInstance, KeyringOptions } from './types.js'; +interface PairDef { + name?: string; + p: HexString; + s: HexString; + seed?: string; + type: KeypairType; +} +export declare const PAIRSSR25519: PairDef[]; +export declare const PAIRSETHEREUM: PairDef[]; +/** + * @name testKeyring + * @summary Create an instance of Keyring pre-populated with locked test accounts + * @description The test accounts (i.e. alice, bob, dave, eve, ferdie) + * are available on the dev chain and each test account is initialized with DOT funds. + */ +export declare function createTestKeyring(options?: KeyringOptions, isDerived?: boolean): KeyringInstance; +export {}; diff --git a/packages/keyring/testing.js b/packages/keyring/testing.js new file mode 100644 index 0000000..a57d8f1 --- /dev/null +++ b/packages/keyring/testing.js @@ -0,0 +1,122 @@ +import { hexToU8a } from '@pezkuwi/util'; +import { createPair } from './pair/index.js'; +import { Keyring } from './keyring.js'; +export const PAIRSSR25519 = [ + { + p: '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d', + s: '0x98319d4ff8a9508c4bb0cf0b5a78d760a0b2082c02775e6e82370816fedfff48925a225d97aa00682d6a59b95b18780c10d7032336e88f3442b42361f4a66011', // nosemgrep + seed: 'Alice', + type: 'sr25519' + }, + { + p: '0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f', + s: '0xe8da6c9d810e020f5e3c7f5af2dea314cbeaa0d72bc6421e92c0808a0c584a6046ab28e97c3ffc77fe12b5a4d37e8cd4afbfebbf2391ffc7cb07c0f38c023efd', // nosemgrep + seed: 'Alice//stash', + type: 'sr25519' + }, + { + p: '0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48', + s: '0x081ff694633e255136bdb456c20a5fc8fed21f8b964c11bb17ff534ce80ebd5941ae88f85d0c1bfc37be41c904e1dfc01de8c8067b0d6d5df25dd1ac0894a325', // nosemgrep + seed: 'Bob', + type: 'sr25519' + }, + { + p: '0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e', + s: '0xc006507cdfc267a21532394c49ca9b754ca71de21e15a1cdf807c7ceab6d0b6c3ed408d9d35311540dcd54931933e67cf1ea10d46f75408f82b789d9bd212fde', // nosemgrep + seed: 'Bob//stash', + type: 'sr25519' + }, + { + p: '0x90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22', + s: '0xa8f2d83016052e5d6d77b2f6fd5d59418922a09024cda701b3c34369ec43a7668faf12ff39cd4e5d92bb773972f41a7a5279ebc2ed92264bed8f47d344f8f18c', // nosemgrep + seed: 'Charlie', + type: 'sr25519' + }, + { + p: '0x306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20', + s: '0x20e05482ca4677e0edbc58ae9a3a59f6ed3b1a9484ba17e64d6fe8688b2b7b5d108c4487b9323b98b11fe36cb301b084e920f7b7895536809a6d62a451b25568', // nosemgrep + seed: 'Dave', + type: 'sr25519' + }, + { + p: '0xe659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e', + s: '0x683576abfd5dc35273e4264c23095a1bf21c14517bece57c7f0cc5c0ed4ce06a3dbf386b7828f348abe15d76973a72009e6ef86a5c91db2990cb36bb657c6587', // nosemgrep + seed: 'Eve', + type: 'sr25519' + }, + { + p: '0x1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c', + s: '0xb835c20f450079cf4f513900ae9faf8df06ad86c681884122c752a4b2bf74d4303e4f21bc6cc62bb4eeed5a9cce642c25e2d2ac1464093b50f6196d78e3a7426', // nosemgrep + seed: 'Ferdie', + type: 'sr25519' + } +]; +export const PAIRSETHEREUM = [ + { + name: 'Alith', + p: '0x02509540919faacf9ab52146c9aa40db68172d83777250b28e4679176e49ccdd9f', + s: '0x5fb92d6e98884f76de468fa3f6278f8807c48bebc13595d45af5bdc4da702133', // nosemgrep + type: 'ethereum' + }, + { + name: 'Baltathar', + p: '0x033bc19e36ff1673910575b6727a974a9abd80c9a875d41ab3e2648dbfb9e4b518', + s: '0x8075991ce870b93a8870eca0c0f91913d12f47948ca0fd25b49c6fa7cdbeee8b', // nosemgrep + type: 'ethereum' + }, + { + name: 'Charleth', + p: '0x0234637bdc0e89b5d46543bcbf8edff329d2702bc995e27e9af4b1ba009a3c2a5e', + s: '0x0b6e18cafb6ed99687ec547bd28139cafdd2bffe70e6b688025de6b445aa5c5b', // nosemgrep + type: 'ethereum' + }, + { + name: 'Dorothy', + p: '0x02a00d60b2b408c2a14c5d70cdd2c205db8985ef737a7e55ad20ea32cc9e7c417c', + s: '0x39539ab1876910bbf3a223d84a29e28f1cb4e2e456503e7e91ed39b2e7223d68', // nosemgrep + type: 'ethereum' + }, + { + name: 'Ethan', + p: '0x025cdc005b752651cd3f728fb9192182acb3a9c89e19072cbd5b03f3ee1f1b3ffa', + s: '0x7dce9bc8babb68fec1409be38c8e1a52650206a7ed90ff956ae8a6d15eeaaef4', // nosemgrep + type: 'ethereum' + }, + { + name: 'Faith', + p: '0x037964b6c9d546da4646ada28a99e34acaa1d14e7aba861a9055f9bd200c8abf74', + s: '0xb9d2ea9a615f3165812e8d44de0d24da9bbd164b65c4f0573e1ce2c8dbd9c8df', // nosemgrep + type: 'ethereum' + } +]; +function createMeta(name, seed) { + if (!name && !seed) { + throw new Error('Testing pair should have either a name or a seed'); + } + return { + isTesting: true, + name: name || seed?.replace('//', '_').toLowerCase() + }; +} +/** + * @name testKeyring + * @summary Create an instance of Keyring pre-populated with locked test accounts + * @description The test accounts (i.e. alice, bob, dave, eve, ferdie) + * are available on the dev chain and each test account is initialized with DOT funds. + */ +export function createTestKeyring(options = {}, isDerived = true) { + const keyring = new Keyring(options); + const pairs = options.type === 'ethereum' + ? PAIRSETHEREUM + : PAIRSSR25519; + for (const { name, p, s, seed, type } of pairs) { + const meta = createMeta(name, seed); + const pair = !isDerived && !name && seed + ? keyring.addFromUri(seed, meta, options.type) + : keyring.addPair(createPair({ toSS58: keyring.encodeAddress, type }, { publicKey: hexToU8a(p), secretKey: hexToU8a(s) }, meta)); + pair.lock = () => { + // we don't have lock/unlock functionality here + }; + } + return keyring; +} diff --git a/packages/keyring/testingPairs.d.ts b/packages/keyring/testingPairs.d.ts new file mode 100644 index 0000000..8d76565 --- /dev/null +++ b/packages/keyring/testingPairs.d.ts @@ -0,0 +1,25 @@ +import type { KeypairType } from '@pezkuwi/util-crypto/types'; +import type { KeyringOptions, KeyringPair } from './types.js'; +export interface TestKeyringMap { + nobody: KeyringPair; + [index: string]: KeyringPair; +} +export interface TestKeyringMapBizinikiwi extends TestKeyringMap { + alice: KeyringPair; + bob: KeyringPair; + charlie: KeyringPair; + dave: KeyringPair; + eve: KeyringPair; + ferdie: KeyringPair; +} +export interface TestKeyringMapEthereum extends TestKeyringMap { + Alith: KeyringPair; + Baltathar: KeyringPair; + Charleth: KeyringPair; + Dorothy: KeyringPair; + Ethan: KeyringPair; + Faith: KeyringPair; +} +export type DetectMap = DetectPairType extends 'ethereum' ? TestKeyringMapEthereum : TestKeyringMapBizinikiwi; +export type DetectPairType = O extends KeyringOptions ? O['type'] extends KeypairType ? O['type'] : 'sr25519' : 'sr25519'; +export declare function createTestPairs>(options?: O, isDerived?: boolean): M; diff --git a/packages/keyring/testingPairs.js b/packages/keyring/testingPairs.js new file mode 100644 index 0000000..c0be4b5 --- /dev/null +++ b/packages/keyring/testingPairs.js @@ -0,0 +1,13 @@ +import { nobody } from './pair/nobody.js'; +import { createTestKeyring } from './testing.js'; +export function createTestPairs(options, isDerived = true) { + const keyring = createTestKeyring(options, isDerived); + const pairs = keyring.getPairs(); + const map = { nobody: nobody() }; + for (const p of pairs) { + if (p.meta.name) { + map[p.meta.name] = p; + } + } + return map; +} diff --git a/packages/keyring/types.d.ts b/packages/keyring/types.d.ts new file mode 100644 index 0000000..0bd1dc7 --- /dev/null +++ b/packages/keyring/types.d.ts @@ -0,0 +1,111 @@ +import type { HexString } from '@pezkuwi/util/types'; +import type { EncryptedJson, Keypair, KeypairType, Prefix } from '@pezkuwi/util-crypto/types'; +export interface KeyringOptions { + /** The ss58Format to use for address encoding (defaults to 42) */ + ss58Format?: Prefix; + /** The type of keyring to create (defaults to ed25519) */ + type?: KeypairType; +} +export interface KeyringPair$MetaHardware { + accountIndex?: number; + accountOffset?: number; + addressOffset?: number; + hardwareType?: 'ledger'; +} +export interface KeyringPair$MetaFlags { + isDefaultAuthSelected?: boolean; + isExternal?: boolean; + isHardware?: boolean; + isHidden?: boolean; + isInjected?: boolean; + isMultisig?: boolean; + isProxied?: boolean; + isRecent?: boolean; + isTesting?: boolean; +} +export interface KeyringPair$MetaContract { + abi: string; + genesisHash?: HexString | null; +} +export interface KeyringPair$MetaExtension { + source?: string; +} +export interface KeyringPair$MetaMultisig { + threshold?: number; + who?: string[]; +} +export interface KeyringPair$MetaParent { + parentAddress?: string; + parentName?: string; +} +export interface KeyringPair$Meta extends KeyringPair$MetaExtension, KeyringPair$MetaFlags, KeyringPair$MetaHardware, KeyringPair$MetaMultisig, KeyringPair$MetaParent { + address?: string; + contract?: KeyringPair$MetaContract; + genesisHash?: HexString | null; + name?: string; + suri?: string; + tags?: string[]; + type?: KeypairType; + whenCreated?: number; + whenEdited?: number; + whenUsed?: number; + [key: string]: unknown; +} +export interface KeyringPair$Json extends EncryptedJson { + /** The ss58 encoded address or the hex-encoded version (the latter is for ETH-compat chains) */ + address: string; + /** The underlying metadata associated with the keypair */ + meta: KeyringPair$Meta; +} +export interface SignOptions { + /** Create a MultiSignature-compatible output with an indicator type */ + withType?: boolean; +} +export interface KeyringPair { + readonly address: string; + readonly addressRaw: Uint8Array; + readonly meta: KeyringPair$Meta; + readonly isLocked: boolean; + readonly publicKey: Uint8Array; + readonly type: KeypairType; + decodePkcs8(passphrase?: string, encoded?: Uint8Array): void; + derive(suri: string, meta?: KeyringPair$Meta): KeyringPair; + encodePkcs8(passphrase?: string): Uint8Array; + lock(): void; + setMeta(meta: KeyringPair$Meta): void; + sign(message: string | Uint8Array, options?: SignOptions): Uint8Array; + toJson(passphrase?: string): KeyringPair$Json; + unlock(passphrase?: string): void; + verify(message: string | Uint8Array, signature: Uint8Array, signerPublic: string | Uint8Array): boolean; + vrfSign(message: string | Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): Uint8Array; + vrfVerify(message: string | Uint8Array, vrfResult: Uint8Array, signerPublic: string | Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): boolean; +} +export interface KeyringPairs { + add: (pair: KeyringPair) => KeyringPair; + all: () => KeyringPair[]; + get: (address: string | Uint8Array) => KeyringPair; + remove: (address: string | Uint8Array) => void; +} +export interface KeyringInstance { + readonly pairs: KeyringPair[]; + readonly publicKeys: Uint8Array[]; + readonly type: KeypairType; + decodeAddress(encoded: string | Uint8Array, ignoreChecksum?: boolean, ss58Format?: Prefix): Uint8Array; + encodeAddress(key: Uint8Array | string, ss58Format?: Prefix): string; + setSS58Format(ss58Format: Prefix): void; + addPair(pair: KeyringPair): KeyringPair; + addFromAddress(address: string | Uint8Array, meta?: KeyringPair$Meta, encoded?: Uint8Array | null, type?: KeypairType, ignoreChecksum?: boolean): KeyringPair; + addFromJson(pair: KeyringPair$Json, ignoreChecksum?: boolean): KeyringPair; + addFromMnemonic(mnemonic: string, meta?: KeyringPair$Meta, type?: KeypairType, wordlist?: string[]): KeyringPair; + addFromPair(pair: Keypair, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair; + addFromSeed(seed: Uint8Array, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair; + addFromUri(suri: string, meta?: KeyringPair$Meta, type?: KeypairType, wordlist?: string[]): KeyringPair; + createFromJson(json: KeyringPair$Json, ignoreChecksum?: boolean): KeyringPair; + createFromPair(pair: Keypair, meta: KeyringPair$Meta, type: KeypairType): KeyringPair; + createFromUri(suri: string, meta?: KeyringPair$Meta, type?: KeypairType, wordlist?: string[]): KeyringPair; + getPair(address: string | Uint8Array): KeyringPair; + getPairs(): KeyringPair[]; + getPublicKeys(): Uint8Array[]; + removePair(address: string | Uint8Array): void; + toJson(address: string | Uint8Array, passphrase?: string): KeyringPair$Json; +} diff --git a/packages/keyring/types.js b/packages/keyring/types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/keyring/types.js @@ -0,0 +1 @@ +export {}; diff --git a/packages/networks/cjs/defaults/genesis.d.ts b/packages/networks/cjs/defaults/genesis.d.ts new file mode 100644 index 0000000..19e4684 --- /dev/null +++ b/packages/networks/cjs/defaults/genesis.d.ts @@ -0,0 +1,2 @@ +import type { KnownGenesis } from '../types.js'; +export declare const knownGenesis: KnownGenesis; diff --git a/packages/networks/cjs/defaults/genesis.js b/packages/networks/cjs/defaults/genesis.js new file mode 100644 index 0000000..beed5cd --- /dev/null +++ b/packages/networks/cjs/defaults/genesis.js @@ -0,0 +1,216 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.knownGenesis = void 0; +exports.knownGenesis = { + acala: [ + '0xfc41b9bd8ef8fe53d58c7ea67c794c7ec9a73daf05e6d54b14ff6342c99ba64c' + ], + ajuna: [ + '0xe358eb1d11b31255a286c12e44fe6780b7edb171d657905a97e39f71d9c6c3ee' + ], + 'aleph-node': [ + '0x70255b4d28de0fc4e1a193d7e175ad1ccef431598211c55538f1018651a0344e' + ], + astar: [ + '0x9eb76c5184c4ab8679d2d5d819fdf90b9c001403e9e17da2e14b6d8aec4029c6' + ], + basilisk: [ + '0xa85cfb9b9fd4d622a5b28289a02347af987d8f73fa3108450e2b4a11c1ce5755' + ], + bifrost: [ + '0x262e1b2ad728475fd6fe88e62d34c200abe6fd693931ddad144059b1eb884e5b' + ], + 'bifrost-kusama': [ + '0x9f28c6a68e0fc9646eff64935684f6eeeece527e37bbe1f213d22caa1d9d6bed' + ], + bittensor: [ + '0x2f0555cc76fc2840a25a6ea3b9637146806f1f44b090c175ffde2a7e5ab36c03' + ], + centrifuge: [ + '0xb3db41421702df9a7fcac62b53ffeac85f7853cc4e689e0b93aeb3db18c09d82', + '0x67dddf2673b69e5f875f6f25277495834398eafd67f492e09f3f3345e003d1b5' + ], + cere: [ + '0x81443836a9a24caaa23f1241897d1235717535711d1d3fe24eae4fdc942c092c' + ], + composable: [ + '0xdaab8df776eb52ec604a5df5d388bb62a050a0aaec4556a64265b9d42755552d' + ], + creditcoin3: [ + '0x4436a7d64e363df85e065a894721002a86643283f9707338bf195d360ba2ee71', // cc3 mainnet + '0xfc4ec97a1c1f119c4353aecb4a17c7c0cf7b40d5d660143d8bad9117e9866572', // cc3 testnet/drynet + '0xfc9df99a665f964aed6649f275055e54df5e3420489538ed31d7788f53d11ef6' // cc3 devnet + ], + darwinia: [ + '0xe71578b37a7c799b0ab4ee87ffa6f059a6b98f71f06fb8c84a8d88013a548ad6' + ], + dentnet: [ + '0x0313f6a011d128d22f996703cbab05162e2fdc9e031493314fe6db79979c5ca7' + ], + 'dock-mainnet': [ + '0x6bfe24dca2a3be10f22212678ac13a6446ec764103c0f3471c71609eac384aae', + '0xf73467c6544aa68df2ee546b135f955c46b90fa627e9b5d7935f41061bb8a5a9' + ], + edgeware: [ + '0x742a2ca70c2fda6cee4f8df98d64c4c670a052d9568058982dad9d5a7a135c5b' + ], + encointer: [ + '0x7dd99936c1e9e6d1ce7d90eb6f33bea8393b4bf87677d675aa63c9cb3e8c5b5b' + ], + enjin: [ + '0xd8761d3c88f26dc12875c00d3165f7d67243d56fc85b4cf19937601a7916e5a9' + ], + equilibrium: [ + '0x6f1a800de3daff7f5e037ddf66ab22ce03ab91874debeddb1086f5f7dbd48925' + ], + frequency: [ + '0x4a587bf17a404e3572747add7aab7bbe56e805a5479c6c436f07f36fcc8d3ae1' + ], + genshiro: [ + '0x9b8cefc0eb5c568b527998bdd76c184e2b76ae561be76e4667072230217ea243' + ], + hydradx: [ + '0xafdc188f45c71dacbaa0b62e16a91f726c7b8699a9748cdf715459de6b7f366d', // Hydration | HydraDX Parachain + '0xd2a620c27ec5cbc5621ff9a522689895074f7cca0d08e7134a7804e1a3ba86fc', // Snakenet Gen3-1 + '0x10af6e84234477d84dc572bac0789813b254aa490767ed06fb9591191d1073f9', // Snakenet Gen3 + '0x3d75507dd46301767e601265791da1d9cb47b6ebc94e87347b635e5bf58bd047', // Snakenet Gen2 + '0x0ed32bfcab4a83517fac88f2aa7cbc2f88d3ab93be9a12b6188a036bf8a943c2' // Snakenet Gen1 + ], + integritee: [ + '0xcdedc8eadbfa209d3f207bba541e57c3c58a667b05a2e1d1e86353c9000758da', // on Kusama + '0xe13e7af377c64e83f95e0d70d5e5c3c01d697a84538776c5b9bbe0e7d7b6034c' // on Polkadot + ], + 'interlay-parachain': [ + '0xbf88efe70e9e0e916416e8bed61f2b45717f517d7f3523e33c7b001e5ffcbc72' + ], + karura: [ + '0xbaf5aabe40646d11f0ee8abbdc64f4a4b7674925cba08e4a05ff9ebed6e2126b' + ], + khala: [ + '0xd43540ba6d3eb4897c28a77d48cb5b729fea37603cbbfc7a86a73b72adb3be8d' + ], + kulupu: [ + '0xf7a99d3cb92853d00d5275c971c132c074636256583fee53b3bbe60d7b8769ba' + ], + kusama: [ + '0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe', // Kusama CC3, + '0xe3777fa922cafbff200cadeaea1a76bd7898ad5b89f7848999058b50e715f636', // Kusama CC2 + '0x3fd7b9eb6a00376e5be61f01abb429ffb0b104be05eaff4d458da48fcd425baf' // Kusama CC1 + ], + // Dicle - Pezkuwi canary relay chain (placeholder until mainnet launch) + dicle: [ + '0xd9d3cd7c1e5d890d969b957f4c5b71a111bbeeabc968f1d0d4538c2663f080a7' + ], + liberland: [ + '0x6bd89e052d67a45bb60a9a23e8581053d5e0d619f15cb9865946937e690c42d6' + ], + matrixchain: [ + '0x3af4ff48ec76d2efc8476730f423ac07e25ad48f5f4c9dc39c778b164d808615' + ], + mythos: [ + '0xf6ee56e9c5277df5b4ce6ae9983ee88f3cbed27d31beeb98f9f84f997a1ab0b9' + ], + nodle: [ + '0x97da7ede98d7bad4e36b4d734b6055425a3be036da2a332ea5a7037656427a21' + ], + origintrail: [ + '0xe7e0962324a3b86c83404dbea483f25fb5dab4c224791c81b756cfc948006174' + ], + p3d: [ + '0x6c5894837ad89b6d92b114a2fb3eafa8fe3d26a54848e3447015442cd6ef4e66' + ], + parallel: [ + '0xe61a41c53f5dcd0beb09df93b34402aada44cb05117b71059cce40a2723a4e97' + ], + peaq: [ + '0xd2a5d385932d1f650dae03ef8e2748983779ee342c614f80854d32b8cd8fa48c' + ], + pendulum: [ + '0x5d3c298622d5634ed019bf61ea4b71655030015bde9beb0d6a24743714462c86' + ], + phala: [ + '0x1bb969d85965e4bb5a651abbedf21a54b6b31a21f66b5401cc3f1e286268d736' + ], + picasso: [ + '0x6811a339673c9daa897944dcdac99c6e2939cc88245ed21951a0a3c9a2be75bc', + '0xe8e7f0f4c4f5a00720b4821dbfddefea7490bcf0b19009961cc46957984e2c1c' + ], + polimec: [ + '0x7eb9354488318e7549c722669dcbdcdc526f1fef1420e7944667212f3601fdbd' + ], + polkadex: [ + '0x3920bcb4960a1eef5580cd5367ff3f430eef052774f78468852f7b9cb39f8a3c' + ], + polkadot: [ + '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3' + ], + // Pezkuwi - Pezkuwi main relay chain (placeholder until mainnet launch) + pezkuwi: [ + '0x41693961995d879073269a008d0a52832caa3e0ae73869f02127f3d5daa4934c' + ], + polymesh: [ + '0x6fbd74e5e1d0a61d52ccfe9d4adaed16dd3a7caa37c6bc4d0c2fa12e8b2f4063' + ], + quartz: [ + '0xcd4d732201ebe5d6b014edda071c4203e16867305332301dc8d092044b28e554' + ], + rococo: [ + '0x6408de7737c59c238890533af25896a2c20608d8b380bb01029acb392781063e', + '0xaaf2cd1b74b5f726895921259421b534124726263982522174147046b8827897', + '0x037f5f3c8e67b314062025fc886fcd6238ea25a4a9b45dce8d246815c9ebe770', + '0xc196f81260cf1686172b47a79cf002120735d7cb0eb1474e8adce56618456fff', + '0xf6e9983c37baf68846fedafe21e56718790e39fb1c582abc408b81bc7b208f9a', + '0x5fce687da39305dfe682b117f0820b319348e8bb37eb16cf34acbf6a202de9d9', + '0xe7c3d5edde7db964317cd9b51a3a059d7cd99f81bdbce14990047354334c9779', + '0x1611e1dbf0405379b861e2e27daa90f480b2e6d3682414a80835a52e8cb8a215', + '0x343442f12fa715489a8714e79a7b264ea88c0d5b8c66b684a7788a516032f6b9', + '0x78bcd530c6b3a068bc17473cf5d2aff9c287102bed9af3ae3c41c33b9d6c6147', + '0x47381ee0697153d64404fc578392c8fd5cba9073391908f46c888498415647bd', + '0x19c0e4fa8ab75f5ac7865e0b8f74ff91eb9a100d336f423cd013a8befba40299' + ], + // PezkuwiChain - Pezkuwi dev relay chain (placeholder until devnet launch) + pezkuwichain: [ + '0x32154fd2c844f928c82964ff66168b41b15fc235f3a956d14393734c1ed4326b' + ], + sora: [ + '0x7e4e32d0feafd4f9c9414b0be86373f9a1efa904809b683453a9af6856d38ad5' + ], + stafi: [ + '0x290a4149f09ea0e402c74c1c7e96ae4239588577fe78932f94f5404c68243d80' + ], + statemine: [ + '0x48239ef607d7928874027a43a67689209727dfb3d3dc5e5b03a39bdc2eda771a' + ], + statemint: [ + '0x68d56f15f85d3136970ec16946040bc1752654e906147f7e43e9d539d7c3de2f' + ], + subsocial: [ + '0x0bd72c1c305172e1275278aaeb3f161e02eccb7a819e63f62d47bd53a28189f8' + ], + ternoa: [ + '0x6859c81ca95ef624c9dfe4dc6e3381c33e5d6509e35e147092bfbc780f777c4e' + ], + unique: [ + '0x84322d9cddbf35088f1e54e9a85c967a41a56a4f43445768125e61af166c7d31' + ], + vara: [ + '0xfe1b4c55fd4d668101126434206571a7838a8b6b93a6d1b95d607e78e6c53763' + ], + vtb: [ + '0x286bc8414c7000ce1d6ee6a834e29a54c1784814b76243eb77ed0b2c5573c60f', + '0x7483b89572fb2bd687c7b9a93b242d0b237f9aba463aba07ec24503931038aaa' + ], + westend: [ + '0xe143f23803ac50e8f6f8e62695d1ce9e4e1d68aa36c1cd2cfd15340213f3423e' + ], + // Zagros - Pezkuwi test relay chain (placeholder until testnet launch) + zagros: [ + '0x297f5a4d105b4b28312586ff1915572ffe4ee015ff772b76399ecbff25a22026' + ], + xxnetwork: [ + '0x50dd5d206917bf10502c68fb4d18a59fc8aa31586f4e8856b493e43544aa82aa' + ], + zeitgeist: [ + '0x1bf2a2ecb4a868de66ea8610f2ce7c8c43706561b6476031315f6640fe38e060' + ] +}; diff --git a/packages/networks/cjs/defaults/icons.d.ts b/packages/networks/cjs/defaults/icons.d.ts new file mode 100644 index 0000000..86ab6b6 --- /dev/null +++ b/packages/networks/cjs/defaults/icons.d.ts @@ -0,0 +1,2 @@ +import type { KnownIcon } from '../types.js'; +export declare const knownIcon: KnownIcon; diff --git a/packages/networks/cjs/defaults/icons.js b/packages/networks/cjs/defaults/icons.js new file mode 100644 index 0000000..0a62a56 --- /dev/null +++ b/packages/networks/cjs/defaults/icons.js @@ -0,0 +1,12 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.knownIcon = void 0; +exports.knownIcon = { + centrifuge: 'polkadot', + kusama: 'polkadot', + polkadot: 'polkadot', + sora: 'polkadot', + statemine: 'polkadot', + statemint: 'polkadot', + westmint: 'polkadot' +}; diff --git a/packages/networks/cjs/defaults/index.d.ts b/packages/networks/cjs/defaults/index.d.ts new file mode 100644 index 0000000..d8b788f --- /dev/null +++ b/packages/networks/cjs/defaults/index.d.ts @@ -0,0 +1,4 @@ +export { knownGenesis } from './genesis.js'; +export { knownIcon } from './icons.js'; +export { knownLedger } from './ledger.js'; +export { knownTestnet } from './testnets.js'; diff --git a/packages/networks/cjs/defaults/index.js b/packages/networks/cjs/defaults/index.js new file mode 100644 index 0000000..89c0939 --- /dev/null +++ b/packages/networks/cjs/defaults/index.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.knownTestnet = exports.knownLedger = exports.knownIcon = exports.knownGenesis = void 0; +var genesis_js_1 = require("./genesis.js"); +Object.defineProperty(exports, "knownGenesis", { enumerable: true, get: function () { return genesis_js_1.knownGenesis; } }); +var icons_js_1 = require("./icons.js"); +Object.defineProperty(exports, "knownIcon", { enumerable: true, get: function () { return icons_js_1.knownIcon; } }); +var ledger_js_1 = require("./ledger.js"); +Object.defineProperty(exports, "knownLedger", { enumerable: true, get: function () { return ledger_js_1.knownLedger; } }); +var testnets_js_1 = require("./testnets.js"); +Object.defineProperty(exports, "knownTestnet", { enumerable: true, get: function () { return testnets_js_1.knownTestnet; } }); diff --git a/packages/networks/cjs/defaults/ledger.d.ts b/packages/networks/cjs/defaults/ledger.d.ts new file mode 100644 index 0000000..c8c595d --- /dev/null +++ b/packages/networks/cjs/defaults/ledger.d.ts @@ -0,0 +1,2 @@ +import type { KnownLedger } from '../types.js'; +export declare const knownLedger: KnownLedger; diff --git a/packages/networks/cjs/defaults/ledger.js b/packages/networks/cjs/defaults/ledger.js new file mode 100644 index 0000000..e33f857 --- /dev/null +++ b/packages/networks/cjs/defaults/ledger.js @@ -0,0 +1,55 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.knownLedger = void 0; +exports.knownLedger = { + acala: 0x00000313, + ajuna: 0x00000162, + 'aleph-node': 0x00000283, + astar: 0x0000032a, + bifrost: 0x00000314, + 'bifrost-kusama': 0x00000314, + bittensor: 0x00000162, + centrifuge: 0x000002eb, + composable: 0x00000162, + creditcoin3: 0x00000162, + darwinia: 0x00000162, + dentnet: 0x000002de, + 'dock-mainnet': 0x00000252, + edgeware: 0x0000020b, + encointer: 0x000001b2, + enjin: 0x00000483, + equilibrium: 0x05f5e0fd, + frequency: 0x0000082b, + genshiro: 0x05f5e0fc, + hydradx: 0x00000162, + integritee: 0x000007df, + 'interlay-parachain': 0x00000162, + karura: 0x000002ae, + khala: 0x000001b2, + kusama: 0x000001b2, + liberland: 0x000002ff, + matrixchain: 0x00000483, + mythos: 0x0000003c, + nodle: 0x000003eb, + origintrail: 0x00000162, + parallel: 0x00000162, + peaq: 0x00000d0a, + pendulum: 0x00000162, + phala: 0x00000162, + picasso: 0x000001b2, + polimec: 0x00000d10, + polkadex: 0x0000031f, + polkadot: 0x00000162, + polymesh: 0x00000253, + quartz: 0x00000277, + sora: 0x00000269, + stafi: 0x0000038b, + statemine: 0x000001b2, // common-good on Kusama, shares derivation + statemint: 0x00000162, // common-good on Polkadot, shares derivation + ternoa: 0x00003e3, + unique: 0x00000295, + vara: 0x00001370, + vtb: 0x000002b6, + xxnetwork: 0x000007a3, + zeitgeist: 0x00000162 +}; diff --git a/packages/networks/cjs/defaults/testnets.d.ts b/packages/networks/cjs/defaults/testnets.d.ts new file mode 100644 index 0000000..f56029e --- /dev/null +++ b/packages/networks/cjs/defaults/testnets.d.ts @@ -0,0 +1,2 @@ +import type { KnownTestnet } from '../types.js'; +export declare const knownTestnet: KnownTestnet; diff --git a/packages/networks/cjs/defaults/testnets.js b/packages/networks/cjs/defaults/testnets.js new file mode 100644 index 0000000..2ab6ff9 --- /dev/null +++ b/packages/networks/cjs/defaults/testnets.js @@ -0,0 +1,13 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.knownTestnet = void 0; +exports.knownTestnet = { + '': true, // this is the default non-network entry + 'cess-testnet': true, + 'dock-testnet': true, + jupiter: true, + 'mathchain-testnet': true, + p3dt: true, + subspace_testnet: true, + 'zero-alphaville': true +}; diff --git a/packages/networks/cjs/index.d.ts b/packages/networks/cjs/index.d.ts new file mode 100644 index 0000000..06a360c --- /dev/null +++ b/packages/networks/cjs/index.d.ts @@ -0,0 +1,2 @@ +export * from './interfaces.js'; +export { packageInfo } from './packageInfo.js'; diff --git a/packages/networks/cjs/index.js b/packages/networks/cjs/index.js new file mode 100644 index 0000000..7c776f0 --- /dev/null +++ b/packages/networks/cjs/index.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +const tslib_1 = require("tslib"); +tslib_1.__exportStar(require("./interfaces.js"), exports); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); diff --git a/packages/networks/cjs/interfaces.d.ts b/packages/networks/cjs/interfaces.d.ts new file mode 100644 index 0000000..eb58297 --- /dev/null +++ b/packages/networks/cjs/interfaces.d.ts @@ -0,0 +1,4 @@ +import type { Network, BizinikwiNetwork } from './types.js'; +export declare const allNetworks: BizinikwiNetwork[]; +export declare const availableNetworks: Network[]; +export declare const selectableNetworks: Network[]; diff --git a/packages/networks/cjs/interfaces.js b/packages/networks/cjs/interfaces.js new file mode 100644 index 0000000..f7c4674 --- /dev/null +++ b/packages/networks/cjs/interfaces.js @@ -0,0 +1,82 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.selectableNetworks = exports.availableNetworks = exports.allNetworks = void 0; +const index_js_1 = require("./defaults/index.js"); +const UNSORTED = [0, 2, 42]; +const TESTNETS = ['testnet']; +const customNetworks = [ + { + decimals: [10], + displayName: 'Pezkuwi Relay Chain', + network: 'pezkuwi', + prefix: 0, + standardAccount: '*25519', + symbols: ['PZW'], + website: 'https://pezkuwi.com' + }, + { + decimals: [12], + displayName: 'Zagros Relay Chain', + network: 'zagros', + prefix: 2, + standardAccount: '*25519', + symbols: ['ZGS'], + website: 'https://zagros.pezkuwi.com' + }, + { + decimals: [12], + displayName: 'Bizinikiwi', + network: 'bizinikiwi', + prefix: 42, + standardAccount: '*25519', + symbols: ['BZN'], + website: 'https://bizinikiwi.com' + }, + { + decimals: [18], + displayName: 'PezkuwiChain', + network: 'pezkuwichain', + prefix: 1453, + standardAccount: '*25519', + symbols: ['PZC'], + website: 'https://chain.pezkuwi.com' + } +]; +function toExpanded(o) { + const network = o.network || ''; + const nameParts = network.replace(/_/g, '-').split('-'); + const n = o; + // ledger additions + n.slip44 = index_js_1.knownLedger[network]; + n.hasLedgerSupport = !!n.slip44; + // general items + n.genesisHash = index_js_1.knownGenesis[network] || []; + n.icon = index_js_1.knownIcon[network] || 'substrate'; + // filtering + n.isTestnet = !!index_js_1.knownTestnet[network] || TESTNETS.includes(nameParts[nameParts.length - 1]); + n.isIgnored = n.isTestnet || (!(o.standardAccount && + o.decimals?.length && + o.symbols?.length) && + o.prefix !== 42); + return n; +} +function filterSelectable({ genesisHash, prefix }) { + return !!genesisHash.length || prefix === 42; +} +function filterAvailable(n) { + return !n.isIgnored && !!n.network; +} +function sortNetworks(a, b) { + const isUnSortedA = UNSORTED.includes(a.prefix); + const isUnSortedB = UNSORTED.includes(b.prefix); + return isUnSortedA === isUnSortedB + ? isUnSortedA + ? 0 + : a.displayName.localeCompare(b.displayName) + : isUnSortedA + ? -1 + : 1; +} +exports.allNetworks = customNetworks.map(toExpanded); +exports.availableNetworks = exports.allNetworks.filter(filterAvailable).sort(sortNetworks); +exports.selectableNetworks = exports.availableNetworks.filter(filterSelectable); diff --git a/packages/networks/cjs/package.json b/packages/networks/cjs/package.json new file mode 100644 index 0000000..5bbefff --- /dev/null +++ b/packages/networks/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/networks/cjs/packageDetect.d.ts b/packages/networks/cjs/packageDetect.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/networks/cjs/packageDetect.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/networks/cjs/packageDetect.js b/packages/networks/cjs/packageDetect.js new file mode 100644 index 0000000..a518596 --- /dev/null +++ b/packages/networks/cjs/packageDetect.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = require("@pezkuwi/util"); +const packageInfo_js_1 = require("./packageInfo.js"); +(0, util_1.detectPackage)(packageInfo_js_1.packageInfo, null, []); diff --git a/packages/networks/cjs/packageInfo.d.ts b/packages/networks/cjs/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/networks/cjs/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/networks/cjs/packageInfo.js b/packages/networks/cjs/packageInfo.js new file mode 100644 index 0000000..b8d9c32 --- /dev/null +++ b/packages/networks/cjs/packageInfo.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +exports.packageInfo = { name: '@pezkuwi/networks', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; diff --git a/packages/networks/cjs/types.d.ts b/packages/networks/cjs/types.d.ts new file mode 100644 index 0000000..4187e1b --- /dev/null +++ b/packages/networks/cjs/types.d.ts @@ -0,0 +1,31 @@ +import type { RegistryEntry } from '@substrate/ss58-registry'; +import type { HexString } from '@pezkuwi/util/types'; +export type Icon = 'beachball' | 'empty' | 'jdenticon' | 'polkadot' | 'substrate'; +export type KnownIcon = Record; +export type KnownLedger = Record; +export type KnownGenesis = Record; +export type KnownBizinikiwi = RegistryEntry; +export type KnownTestnet = Record; +export interface BizinikwiNetwork extends KnownBizinikiwi { + /** The genesisHash for the chain */ + genesisHash: HexString[]; + /** Does the chain has support for Ledger devices */ + hasLedgerSupport: boolean; + /** The IdentityIcon to use for the chain */ + icon: Icon; + /** Flag set when we don't include this chain */ + isIgnored: boolean; + /** Flag to indicate a testnet */ + isTestnet: boolean; + /** The Ledger-specific/required slip44 for the chain */ + slip44?: number | null; +} +export interface Network extends BizinikwiNetwork { + /** The network assigned to this chain */ + network: string; +} +export interface Ss58Registry { + registry: KnownBizinikiwi[]; + specification: string; + schema: Record; +} diff --git a/packages/networks/cjs/types.js b/packages/networks/cjs/types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/packages/networks/cjs/types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/packages/networks/defaults/genesis.d.ts b/packages/networks/defaults/genesis.d.ts new file mode 100644 index 0000000..19e4684 --- /dev/null +++ b/packages/networks/defaults/genesis.d.ts @@ -0,0 +1,2 @@ +import type { KnownGenesis } from '../types.js'; +export declare const knownGenesis: KnownGenesis; diff --git a/packages/networks/defaults/genesis.js b/packages/networks/defaults/genesis.js new file mode 100644 index 0000000..d957aa5 --- /dev/null +++ b/packages/networks/defaults/genesis.js @@ -0,0 +1,213 @@ +export const knownGenesis = { + acala: [ + '0xfc41b9bd8ef8fe53d58c7ea67c794c7ec9a73daf05e6d54b14ff6342c99ba64c' + ], + ajuna: [ + '0xe358eb1d11b31255a286c12e44fe6780b7edb171d657905a97e39f71d9c6c3ee' + ], + 'aleph-node': [ + '0x70255b4d28de0fc4e1a193d7e175ad1ccef431598211c55538f1018651a0344e' + ], + astar: [ + '0x9eb76c5184c4ab8679d2d5d819fdf90b9c001403e9e17da2e14b6d8aec4029c6' + ], + basilisk: [ + '0xa85cfb9b9fd4d622a5b28289a02347af987d8f73fa3108450e2b4a11c1ce5755' + ], + bifrost: [ + '0x262e1b2ad728475fd6fe88e62d34c200abe6fd693931ddad144059b1eb884e5b' + ], + 'bifrost-kusama': [ + '0x9f28c6a68e0fc9646eff64935684f6eeeece527e37bbe1f213d22caa1d9d6bed' + ], + bittensor: [ + '0x2f0555cc76fc2840a25a6ea3b9637146806f1f44b090c175ffde2a7e5ab36c03' + ], + centrifuge: [ + '0xb3db41421702df9a7fcac62b53ffeac85f7853cc4e689e0b93aeb3db18c09d82', + '0x67dddf2673b69e5f875f6f25277495834398eafd67f492e09f3f3345e003d1b5' + ], + cere: [ + '0x81443836a9a24caaa23f1241897d1235717535711d1d3fe24eae4fdc942c092c' + ], + composable: [ + '0xdaab8df776eb52ec604a5df5d388bb62a050a0aaec4556a64265b9d42755552d' + ], + creditcoin3: [ + '0x4436a7d64e363df85e065a894721002a86643283f9707338bf195d360ba2ee71', // cc3 mainnet + '0xfc4ec97a1c1f119c4353aecb4a17c7c0cf7b40d5d660143d8bad9117e9866572', // cc3 testnet/drynet + '0xfc9df99a665f964aed6649f275055e54df5e3420489538ed31d7788f53d11ef6' // cc3 devnet + ], + darwinia: [ + '0xe71578b37a7c799b0ab4ee87ffa6f059a6b98f71f06fb8c84a8d88013a548ad6' + ], + dentnet: [ + '0x0313f6a011d128d22f996703cbab05162e2fdc9e031493314fe6db79979c5ca7' + ], + 'dock-mainnet': [ + '0x6bfe24dca2a3be10f22212678ac13a6446ec764103c0f3471c71609eac384aae', + '0xf73467c6544aa68df2ee546b135f955c46b90fa627e9b5d7935f41061bb8a5a9' + ], + edgeware: [ + '0x742a2ca70c2fda6cee4f8df98d64c4c670a052d9568058982dad9d5a7a135c5b' + ], + encointer: [ + '0x7dd99936c1e9e6d1ce7d90eb6f33bea8393b4bf87677d675aa63c9cb3e8c5b5b' + ], + enjin: [ + '0xd8761d3c88f26dc12875c00d3165f7d67243d56fc85b4cf19937601a7916e5a9' + ], + equilibrium: [ + '0x6f1a800de3daff7f5e037ddf66ab22ce03ab91874debeddb1086f5f7dbd48925' + ], + frequency: [ + '0x4a587bf17a404e3572747add7aab7bbe56e805a5479c6c436f07f36fcc8d3ae1' + ], + genshiro: [ + '0x9b8cefc0eb5c568b527998bdd76c184e2b76ae561be76e4667072230217ea243' + ], + hydradx: [ + '0xafdc188f45c71dacbaa0b62e16a91f726c7b8699a9748cdf715459de6b7f366d', // Hydration | HydraDX Parachain + '0xd2a620c27ec5cbc5621ff9a522689895074f7cca0d08e7134a7804e1a3ba86fc', // Snakenet Gen3-1 + '0x10af6e84234477d84dc572bac0789813b254aa490767ed06fb9591191d1073f9', // Snakenet Gen3 + '0x3d75507dd46301767e601265791da1d9cb47b6ebc94e87347b635e5bf58bd047', // Snakenet Gen2 + '0x0ed32bfcab4a83517fac88f2aa7cbc2f88d3ab93be9a12b6188a036bf8a943c2' // Snakenet Gen1 + ], + integritee: [ + '0xcdedc8eadbfa209d3f207bba541e57c3c58a667b05a2e1d1e86353c9000758da', // on Kusama + '0xe13e7af377c64e83f95e0d70d5e5c3c01d697a84538776c5b9bbe0e7d7b6034c' // on Polkadot + ], + 'interlay-parachain': [ + '0xbf88efe70e9e0e916416e8bed61f2b45717f517d7f3523e33c7b001e5ffcbc72' + ], + karura: [ + '0xbaf5aabe40646d11f0ee8abbdc64f4a4b7674925cba08e4a05ff9ebed6e2126b' + ], + khala: [ + '0xd43540ba6d3eb4897c28a77d48cb5b729fea37603cbbfc7a86a73b72adb3be8d' + ], + kulupu: [ + '0xf7a99d3cb92853d00d5275c971c132c074636256583fee53b3bbe60d7b8769ba' + ], + kusama: [ + '0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe', // Kusama CC3, + '0xe3777fa922cafbff200cadeaea1a76bd7898ad5b89f7848999058b50e715f636', // Kusama CC2 + '0x3fd7b9eb6a00376e5be61f01abb429ffb0b104be05eaff4d458da48fcd425baf' // Kusama CC1 + ], + // Dicle - Pezkuwi canary relay chain (placeholder until mainnet launch) + dicle: [ + '0xd9d3cd7c1e5d890d969b957f4c5b71a111bbeeabc968f1d0d4538c2663f080a7' + ], + liberland: [ + '0x6bd89e052d67a45bb60a9a23e8581053d5e0d619f15cb9865946937e690c42d6' + ], + matrixchain: [ + '0x3af4ff48ec76d2efc8476730f423ac07e25ad48f5f4c9dc39c778b164d808615' + ], + mythos: [ + '0xf6ee56e9c5277df5b4ce6ae9983ee88f3cbed27d31beeb98f9f84f997a1ab0b9' + ], + nodle: [ + '0x97da7ede98d7bad4e36b4d734b6055425a3be036da2a332ea5a7037656427a21' + ], + origintrail: [ + '0xe7e0962324a3b86c83404dbea483f25fb5dab4c224791c81b756cfc948006174' + ], + p3d: [ + '0x6c5894837ad89b6d92b114a2fb3eafa8fe3d26a54848e3447015442cd6ef4e66' + ], + parallel: [ + '0xe61a41c53f5dcd0beb09df93b34402aada44cb05117b71059cce40a2723a4e97' + ], + peaq: [ + '0xd2a5d385932d1f650dae03ef8e2748983779ee342c614f80854d32b8cd8fa48c' + ], + pendulum: [ + '0x5d3c298622d5634ed019bf61ea4b71655030015bde9beb0d6a24743714462c86' + ], + phala: [ + '0x1bb969d85965e4bb5a651abbedf21a54b6b31a21f66b5401cc3f1e286268d736' + ], + picasso: [ + '0x6811a339673c9daa897944dcdac99c6e2939cc88245ed21951a0a3c9a2be75bc', + '0xe8e7f0f4c4f5a00720b4821dbfddefea7490bcf0b19009961cc46957984e2c1c' + ], + polimec: [ + '0x7eb9354488318e7549c722669dcbdcdc526f1fef1420e7944667212f3601fdbd' + ], + polkadex: [ + '0x3920bcb4960a1eef5580cd5367ff3f430eef052774f78468852f7b9cb39f8a3c' + ], + polkadot: [ + '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3' + ], + // Pezkuwi - Pezkuwi main relay chain (placeholder until mainnet launch) + pezkuwi: [ + '0x41693961995d879073269a008d0a52832caa3e0ae73869f02127f3d5daa4934c' + ], + polymesh: [ + '0x6fbd74e5e1d0a61d52ccfe9d4adaed16dd3a7caa37c6bc4d0c2fa12e8b2f4063' + ], + quartz: [ + '0xcd4d732201ebe5d6b014edda071c4203e16867305332301dc8d092044b28e554' + ], + rococo: [ + '0x6408de7737c59c238890533af25896a2c20608d8b380bb01029acb392781063e', + '0xaaf2cd1b74b5f726895921259421b534124726263982522174147046b8827897', + '0x037f5f3c8e67b314062025fc886fcd6238ea25a4a9b45dce8d246815c9ebe770', + '0xc196f81260cf1686172b47a79cf002120735d7cb0eb1474e8adce56618456fff', + '0xf6e9983c37baf68846fedafe21e56718790e39fb1c582abc408b81bc7b208f9a', + '0x5fce687da39305dfe682b117f0820b319348e8bb37eb16cf34acbf6a202de9d9', + '0xe7c3d5edde7db964317cd9b51a3a059d7cd99f81bdbce14990047354334c9779', + '0x1611e1dbf0405379b861e2e27daa90f480b2e6d3682414a80835a52e8cb8a215', + '0x343442f12fa715489a8714e79a7b264ea88c0d5b8c66b684a7788a516032f6b9', + '0x78bcd530c6b3a068bc17473cf5d2aff9c287102bed9af3ae3c41c33b9d6c6147', + '0x47381ee0697153d64404fc578392c8fd5cba9073391908f46c888498415647bd', + '0x19c0e4fa8ab75f5ac7865e0b8f74ff91eb9a100d336f423cd013a8befba40299' + ], + // PezkuwiChain - Pezkuwi dev relay chain (placeholder until devnet launch) + pezkuwichain: [ + '0x32154fd2c844f928c82964ff66168b41b15fc235f3a956d14393734c1ed4326b' + ], + sora: [ + '0x7e4e32d0feafd4f9c9414b0be86373f9a1efa904809b683453a9af6856d38ad5' + ], + stafi: [ + '0x290a4149f09ea0e402c74c1c7e96ae4239588577fe78932f94f5404c68243d80' + ], + statemine: [ + '0x48239ef607d7928874027a43a67689209727dfb3d3dc5e5b03a39bdc2eda771a' + ], + statemint: [ + '0x68d56f15f85d3136970ec16946040bc1752654e906147f7e43e9d539d7c3de2f' + ], + subsocial: [ + '0x0bd72c1c305172e1275278aaeb3f161e02eccb7a819e63f62d47bd53a28189f8' + ], + ternoa: [ + '0x6859c81ca95ef624c9dfe4dc6e3381c33e5d6509e35e147092bfbc780f777c4e' + ], + unique: [ + '0x84322d9cddbf35088f1e54e9a85c967a41a56a4f43445768125e61af166c7d31' + ], + vara: [ + '0xfe1b4c55fd4d668101126434206571a7838a8b6b93a6d1b95d607e78e6c53763' + ], + vtb: [ + '0x286bc8414c7000ce1d6ee6a834e29a54c1784814b76243eb77ed0b2c5573c60f', + '0x7483b89572fb2bd687c7b9a93b242d0b237f9aba463aba07ec24503931038aaa' + ], + westend: [ + '0xe143f23803ac50e8f6f8e62695d1ce9e4e1d68aa36c1cd2cfd15340213f3423e' + ], + // Zagros - Pezkuwi test relay chain (placeholder until testnet launch) + zagros: [ + '0x297f5a4d105b4b28312586ff1915572ffe4ee015ff772b76399ecbff25a22026' + ], + xxnetwork: [ + '0x50dd5d206917bf10502c68fb4d18a59fc8aa31586f4e8856b493e43544aa82aa' + ], + zeitgeist: [ + '0x1bf2a2ecb4a868de66ea8610f2ce7c8c43706561b6476031315f6640fe38e060' + ] +}; diff --git a/packages/networks/defaults/icons.d.ts b/packages/networks/defaults/icons.d.ts new file mode 100644 index 0000000..86ab6b6 --- /dev/null +++ b/packages/networks/defaults/icons.d.ts @@ -0,0 +1,2 @@ +import type { KnownIcon } from '../types.js'; +export declare const knownIcon: KnownIcon; diff --git a/packages/networks/defaults/icons.js b/packages/networks/defaults/icons.js new file mode 100644 index 0000000..a86595a --- /dev/null +++ b/packages/networks/defaults/icons.js @@ -0,0 +1,9 @@ +export const knownIcon = { + centrifuge: 'polkadot', + kusama: 'polkadot', + polkadot: 'polkadot', + sora: 'polkadot', + statemine: 'polkadot', + statemint: 'polkadot', + westmint: 'polkadot' +}; diff --git a/packages/networks/defaults/index.d.ts b/packages/networks/defaults/index.d.ts new file mode 100644 index 0000000..d8b788f --- /dev/null +++ b/packages/networks/defaults/index.d.ts @@ -0,0 +1,4 @@ +export { knownGenesis } from './genesis.js'; +export { knownIcon } from './icons.js'; +export { knownLedger } from './ledger.js'; +export { knownTestnet } from './testnets.js'; diff --git a/packages/networks/defaults/index.js b/packages/networks/defaults/index.js new file mode 100644 index 0000000..d8b788f --- /dev/null +++ b/packages/networks/defaults/index.js @@ -0,0 +1,4 @@ +export { knownGenesis } from './genesis.js'; +export { knownIcon } from './icons.js'; +export { knownLedger } from './ledger.js'; +export { knownTestnet } from './testnets.js'; diff --git a/packages/networks/defaults/ledger.d.ts b/packages/networks/defaults/ledger.d.ts new file mode 100644 index 0000000..c8c595d --- /dev/null +++ b/packages/networks/defaults/ledger.d.ts @@ -0,0 +1,2 @@ +import type { KnownLedger } from '../types.js'; +export declare const knownLedger: KnownLedger; diff --git a/packages/networks/defaults/ledger.js b/packages/networks/defaults/ledger.js new file mode 100644 index 0000000..08b6170 --- /dev/null +++ b/packages/networks/defaults/ledger.js @@ -0,0 +1,52 @@ +export const knownLedger = { + acala: 0x00000313, + ajuna: 0x00000162, + 'aleph-node': 0x00000283, + astar: 0x0000032a, + bifrost: 0x00000314, + 'bifrost-kusama': 0x00000314, + bittensor: 0x00000162, + centrifuge: 0x000002eb, + composable: 0x00000162, + creditcoin3: 0x00000162, + darwinia: 0x00000162, + dentnet: 0x000002de, + 'dock-mainnet': 0x00000252, + edgeware: 0x0000020b, + encointer: 0x000001b2, + enjin: 0x00000483, + equilibrium: 0x05f5e0fd, + frequency: 0x0000082b, + genshiro: 0x05f5e0fc, + hydradx: 0x00000162, + integritee: 0x000007df, + 'interlay-parachain': 0x00000162, + karura: 0x000002ae, + khala: 0x000001b2, + kusama: 0x000001b2, + liberland: 0x000002ff, + matrixchain: 0x00000483, + mythos: 0x0000003c, + nodle: 0x000003eb, + origintrail: 0x00000162, + parallel: 0x00000162, + peaq: 0x00000d0a, + pendulum: 0x00000162, + phala: 0x00000162, + picasso: 0x000001b2, + polimec: 0x00000d10, + polkadex: 0x0000031f, + polkadot: 0x00000162, + polymesh: 0x00000253, + quartz: 0x00000277, + sora: 0x00000269, + stafi: 0x0000038b, + statemine: 0x000001b2, // common-good on Kusama, shares derivation + statemint: 0x00000162, // common-good on Polkadot, shares derivation + ternoa: 0x00003e3, + unique: 0x00000295, + vara: 0x00001370, + vtb: 0x000002b6, + xxnetwork: 0x000007a3, + zeitgeist: 0x00000162 +}; diff --git a/packages/networks/defaults/testnets.d.ts b/packages/networks/defaults/testnets.d.ts new file mode 100644 index 0000000..f56029e --- /dev/null +++ b/packages/networks/defaults/testnets.d.ts @@ -0,0 +1,2 @@ +import type { KnownTestnet } from '../types.js'; +export declare const knownTestnet: KnownTestnet; diff --git a/packages/networks/defaults/testnets.js b/packages/networks/defaults/testnets.js new file mode 100644 index 0000000..903c957 --- /dev/null +++ b/packages/networks/defaults/testnets.js @@ -0,0 +1,10 @@ +export const knownTestnet = { + '': true, // this is the default non-network entry + 'cess-testnet': true, + 'dock-testnet': true, + jupiter: true, + 'mathchain-testnet': true, + p3dt: true, + subspace_testnet: true, + 'zero-alphaville': true +}; diff --git a/packages/networks/index.d.ts b/packages/networks/index.d.ts new file mode 100644 index 0000000..06a360c --- /dev/null +++ b/packages/networks/index.d.ts @@ -0,0 +1,2 @@ +export * from './interfaces.js'; +export { packageInfo } from './packageInfo.js'; diff --git a/packages/networks/index.js b/packages/networks/index.js new file mode 100644 index 0000000..06a360c --- /dev/null +++ b/packages/networks/index.js @@ -0,0 +1,2 @@ +export * from './interfaces.js'; +export { packageInfo } from './packageInfo.js'; diff --git a/packages/networks/interfaces.d.ts b/packages/networks/interfaces.d.ts new file mode 100644 index 0000000..eb58297 --- /dev/null +++ b/packages/networks/interfaces.d.ts @@ -0,0 +1,4 @@ +import type { Network, BizinikwiNetwork } from './types.js'; +export declare const allNetworks: BizinikwiNetwork[]; +export declare const availableNetworks: Network[]; +export declare const selectableNetworks: Network[]; diff --git a/packages/networks/interfaces.js b/packages/networks/interfaces.js new file mode 100644 index 0000000..d70cace --- /dev/null +++ b/packages/networks/interfaces.js @@ -0,0 +1,79 @@ +import { knownGenesis, knownIcon, knownLedger, knownTestnet } from './defaults/index.js'; +const UNSORTED = [0, 2, 42]; +const TESTNETS = ['testnet']; +const customNetworks = [ + { + decimals: [10], + displayName: 'Pezkuwi Relay Chain', + network: 'pezkuwi', + prefix: 0, + standardAccount: '*25519', + symbols: ['PZW'], + website: 'https://pezkuwi.com' + }, + { + decimals: [12], + displayName: 'Zagros Relay Chain', + network: 'zagros', + prefix: 2, + standardAccount: '*25519', + symbols: ['ZGS'], + website: 'https://zagros.pezkuwi.com' + }, + { + decimals: [12], + displayName: 'Bizinikiwi', + network: 'bizinikiwi', + prefix: 42, + standardAccount: '*25519', + symbols: ['BZN'], + website: 'https://bizinikiwi.com' + }, + { + decimals: [18], + displayName: 'PezkuwiChain', + network: 'pezkuwichain', + prefix: 1453, + standardAccount: '*25519', + symbols: ['PZC'], + website: 'https://chain.pezkuwi.com' + } +]; +function toExpanded(o) { + const network = o.network || ''; + const nameParts = network.replace(/_/g, '-').split('-'); + const n = o; + // ledger additions + n.slip44 = knownLedger[network]; + n.hasLedgerSupport = !!n.slip44; + // general items + n.genesisHash = knownGenesis[network] || []; + n.icon = knownIcon[network] || 'substrate'; + // filtering + n.isTestnet = !!knownTestnet[network] || TESTNETS.includes(nameParts[nameParts.length - 1]); + n.isIgnored = n.isTestnet || (!(o.standardAccount && + o.decimals?.length && + o.symbols?.length) && + o.prefix !== 42); + return n; +} +function filterSelectable({ genesisHash, prefix }) { + return !!genesisHash.length || prefix === 42; +} +function filterAvailable(n) { + return !n.isIgnored && !!n.network; +} +function sortNetworks(a, b) { + const isUnSortedA = UNSORTED.includes(a.prefix); + const isUnSortedB = UNSORTED.includes(b.prefix); + return isUnSortedA === isUnSortedB + ? isUnSortedA + ? 0 + : a.displayName.localeCompare(b.displayName) + : isUnSortedA + ? -1 + : 1; +} +export const allNetworks = customNetworks.map(toExpanded); +export const availableNetworks = allNetworks.filter(filterAvailable).sort(sortNetworks); +export const selectableNetworks = availableNetworks.filter(filterSelectable); diff --git a/packages/networks/package.json b/packages/networks/package.json index 1b276bb..d55c887 100644 --- a/packages/networks/package.json +++ b/packages/networks/package.json @@ -15,14 +15,175 @@ }, "sideEffects": false, "type": "module", - "version": "14.0.10", - "main": "index.js", + "version": "14.0.11", + "main": "./cjs/index.js", + "module": "./index.js", + "types": "./index.d.ts", + "exports": { + "./cjs/package.json": "./cjs/package.json", + "./cjs/*": "./cjs/*.js", + ".": { + "module": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "require": { + "types": "./cjs/index.d.ts", + "default": "./cjs/index.js" + }, + "default": { + "types": "./index.d.ts", + "default": "./index.js" + } + }, + "./defaults": { + "module": { + "types": "./defaults/index.d.ts", + "default": "./defaults/index.js" + }, + "require": { + "types": "./cjs/defaults/index.d.ts", + "default": "./cjs/defaults/index.js" + }, + "default": { + "types": "./defaults/index.d.ts", + "default": "./defaults/index.js" + } + }, + "./defaults/genesis": { + "module": { + "types": "./defaults/genesis.d.ts", + "default": "./defaults/genesis.js" + }, + "require": { + "types": "./cjs/defaults/genesis.d.ts", + "default": "./cjs/defaults/genesis.js" + }, + "default": { + "types": "./defaults/genesis.d.ts", + "default": "./defaults/genesis.js" + } + }, + "./defaults/icons": { + "module": { + "types": "./defaults/icons.d.ts", + "default": "./defaults/icons.js" + }, + "require": { + "types": "./cjs/defaults/icons.d.ts", + "default": "./cjs/defaults/icons.js" + }, + "default": { + "types": "./defaults/icons.d.ts", + "default": "./defaults/icons.js" + } + }, + "./defaults/ledger": { + "module": { + "types": "./defaults/ledger.d.ts", + "default": "./defaults/ledger.js" + }, + "require": { + "types": "./cjs/defaults/ledger.d.ts", + "default": "./cjs/defaults/ledger.js" + }, + "default": { + "types": "./defaults/ledger.d.ts", + "default": "./defaults/ledger.js" + } + }, + "./defaults/testnets": { + "module": { + "types": "./defaults/testnets.d.ts", + "default": "./defaults/testnets.js" + }, + "require": { + "types": "./cjs/defaults/testnets.d.ts", + "default": "./cjs/defaults/testnets.js" + }, + "default": { + "types": "./defaults/testnets.d.ts", + "default": "./defaults/testnets.js" + } + }, + "./interfaces": { + "module": { + "types": "./interfaces.d.ts", + "default": "./interfaces.js" + }, + "require": { + "types": "./cjs/interfaces.d.ts", + "default": "./cjs/interfaces.js" + }, + "default": { + "types": "./interfaces.d.ts", + "default": "./interfaces.js" + } + }, + "./package.json": { + "require": "./cjs/package.json", + "default": "./package.json" + }, + "./packageDetect": { + "module": { + "types": "./packageDetect.d.ts", + "default": "./packageDetect.js" + }, + "require": { + "types": "./cjs/packageDetect.d.ts", + "default": "./cjs/packageDetect.js" + }, + "default": { + "types": "./packageDetect.d.ts", + "default": "./packageDetect.js" + } + }, + "./packageInfo.js": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./packageInfo": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./types": { + "module": { + "types": "./types.d.ts", + "default": "./types.js" + }, + "require": { + "types": "./cjs/types.d.ts", + "default": "./cjs/types.js" + }, + "default": { + "types": "./types.d.ts", + "default": "./types.js" + } + } + }, "dependencies": { - "@pezkuwi/util": "workspace:*", + "@pezkuwi/util": "14.0.11", "@substrate/ss58-registry": "^1.51.0", "tslib": "^2.8.0" - }, - "devDependencies": { - "@pezkuwi/hw-ledger": "workspace:*" } } diff --git a/packages/networks/packageDetect.d.ts b/packages/networks/packageDetect.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/networks/packageDetect.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/networks/packageDetect.js b/packages/networks/packageDetect.js new file mode 100644 index 0000000..47ccfce --- /dev/null +++ b/packages/networks/packageDetect.js @@ -0,0 +1,3 @@ +import { detectPackage } from '@pezkuwi/util'; +import { packageInfo } from './packageInfo.js'; +detectPackage(packageInfo, null, []); diff --git a/packages/networks/packageInfo.d.ts b/packages/networks/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/networks/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/networks/packageInfo.js b/packages/networks/packageInfo.js new file mode 100644 index 0000000..d41ef26 --- /dev/null +++ b/packages/networks/packageInfo.js @@ -0,0 +1 @@ +export const packageInfo = { name: '@pezkuwi/networks', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; diff --git a/packages/networks/src/interfaces.ts b/packages/networks/src/interfaces.ts index 4a067f3..0b6214f 100644 --- a/packages/networks/src/interfaces.ts +++ b/packages/networks/src/interfaces.ts @@ -17,7 +17,7 @@ const customNetworks: KnownBizinikiwi[] = [ prefix: 0, standardAccount: '*25519', symbols: ['PZW'], - website: 'https://pezkuwi.com' + website: 'https://pezkuwichain.io' }, { decimals: [12], @@ -26,7 +26,7 @@ const customNetworks: KnownBizinikiwi[] = [ prefix: 2, standardAccount: '*25519', symbols: ['ZGS'], - website: 'https://zagros.pezkuwi.com' + website: 'https://zagros.pezkuwichain.io' }, { decimals: [12], @@ -35,7 +35,7 @@ const customNetworks: KnownBizinikiwi[] = [ prefix: 42, standardAccount: '*25519', symbols: ['BZN'], - website: 'https://bizinikiwi.com' + website: 'https://bizinikiwi.pezkuwichain.io' }, { decimals: [18], @@ -44,7 +44,7 @@ const customNetworks: KnownBizinikiwi[] = [ prefix: 1453, standardAccount: '*25519', symbols: ['PZC'], - website: 'https://chain.pezkuwi.com' + website: 'https://network.pezkuwichain.io' } ]; diff --git a/packages/networks/types.d.ts b/packages/networks/types.d.ts new file mode 100644 index 0000000..4187e1b --- /dev/null +++ b/packages/networks/types.d.ts @@ -0,0 +1,31 @@ +import type { RegistryEntry } from '@substrate/ss58-registry'; +import type { HexString } from '@pezkuwi/util/types'; +export type Icon = 'beachball' | 'empty' | 'jdenticon' | 'polkadot' | 'substrate'; +export type KnownIcon = Record; +export type KnownLedger = Record; +export type KnownGenesis = Record; +export type KnownBizinikiwi = RegistryEntry; +export type KnownTestnet = Record; +export interface BizinikwiNetwork extends KnownBizinikiwi { + /** The genesisHash for the chain */ + genesisHash: HexString[]; + /** Does the chain has support for Ledger devices */ + hasLedgerSupport: boolean; + /** The IdentityIcon to use for the chain */ + icon: Icon; + /** Flag set when we don't include this chain */ + isIgnored: boolean; + /** Flag to indicate a testnet */ + isTestnet: boolean; + /** The Ledger-specific/required slip44 for the chain */ + slip44?: number | null; +} +export interface Network extends BizinikwiNetwork { + /** The network assigned to this chain */ + network: string; +} +export interface Ss58Registry { + registry: KnownBizinikiwi[]; + specification: string; + schema: Record; +} diff --git a/packages/networks/types.js b/packages/networks/types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/networks/types.js @@ -0,0 +1 @@ +export {}; diff --git a/packages/util-crypto/address/addressToEvm.d.ts b/packages/util-crypto/address/addressToEvm.d.ts new file mode 100644 index 0000000..5fb9903 --- /dev/null +++ b/packages/util-crypto/address/addressToEvm.d.ts @@ -0,0 +1,5 @@ +/** + * @name addressToEvm + * @summary Converts an SS58 address to its corresponding EVM address. + */ +export declare function addressToEvm(address: string | Uint8Array, ignoreChecksum?: boolean): Uint8Array; diff --git a/packages/util-crypto/address/addressToEvm.js b/packages/util-crypto/address/addressToEvm.js new file mode 100644 index 0000000..dc5680e --- /dev/null +++ b/packages/util-crypto/address/addressToEvm.js @@ -0,0 +1,8 @@ +import { decodeAddress } from './decode.js'; +/** + * @name addressToEvm + * @summary Converts an SS58 address to its corresponding EVM address. + */ +export function addressToEvm(address, ignoreChecksum) { + return decodeAddress(address, ignoreChecksum).subarray(0, 20); +} diff --git a/packages/util-crypto/address/check.d.ts b/packages/util-crypto/address/check.d.ts new file mode 100644 index 0000000..1153144 --- /dev/null +++ b/packages/util-crypto/address/check.d.ts @@ -0,0 +1,8 @@ +import type { Prefix } from './types.js'; +/** + * @name checkAddress + * @summary Validates an ss58 address. + * @description + * From the provided input, validate that the address is a valid input. + */ +export declare function checkAddress(address: string, prefix: Prefix): [boolean, string | null]; diff --git a/packages/util-crypto/address/check.js b/packages/util-crypto/address/check.js new file mode 100644 index 0000000..911b296 --- /dev/null +++ b/packages/util-crypto/address/check.js @@ -0,0 +1,26 @@ +import { base58Decode } from '../base58/index.js'; +import { checkAddressChecksum } from './checksum.js'; +import { defaults } from './defaults.js'; +/** + * @name checkAddress + * @summary Validates an ss58 address. + * @description + * From the provided input, validate that the address is a valid input. + */ +export function checkAddress(address, prefix) { + let decoded; + try { + decoded = base58Decode(address); + } + catch (error) { + return [false, error.message]; + } + const [isValid, , , ss58Decoded] = checkAddressChecksum(decoded); + if (ss58Decoded !== prefix) { + return [false, `Prefix mismatch, expected ${prefix}, found ${ss58Decoded}`]; + } + else if (!defaults.allowedEncodedLengths.includes(decoded.length)) { + return [false, 'Invalid decoded address length']; + } + return [isValid, isValid ? null : 'Invalid decoded address checksum']; +} diff --git a/packages/util-crypto/address/checksum.d.ts b/packages/util-crypto/address/checksum.d.ts new file mode 100644 index 0000000..1f39be6 --- /dev/null +++ b/packages/util-crypto/address/checksum.d.ts @@ -0,0 +1 @@ +export declare function checkAddressChecksum(decoded: Uint8Array): [boolean, number, number, number]; diff --git a/packages/util-crypto/address/checksum.js b/packages/util-crypto/address/checksum.js new file mode 100644 index 0000000..70b8545 --- /dev/null +++ b/packages/util-crypto/address/checksum.js @@ -0,0 +1,16 @@ +import { sshash } from './sshash.js'; +export function checkAddressChecksum(decoded) { + const ss58Length = (decoded[0] & 0b0100_0000) ? 2 : 1; + const ss58Decoded = ss58Length === 1 + ? decoded[0] + : ((decoded[0] & 0b0011_1111) << 2) | (decoded[1] >> 6) | ((decoded[1] & 0b0011_1111) << 8); + // 32/33 bytes public + 2 bytes checksum + prefix + const isPublicKey = [34 + ss58Length, 35 + ss58Length].includes(decoded.length); + const length = decoded.length - (isPublicKey ? 2 : 1); + // calculate the hash and do the checksum byte checks + const hash = sshash(decoded.subarray(0, length)); + const isValid = (decoded[0] & 0b1000_0000) === 0 && ![46, 47].includes(decoded[0]) && (isPublicKey + ? decoded[decoded.length - 2] === hash[0] && decoded[decoded.length - 1] === hash[1] + : decoded[decoded.length - 1] === hash[0]); + return [isValid, length, ss58Length, ss58Decoded]; +} diff --git a/packages/util-crypto/address/decode.d.ts b/packages/util-crypto/address/decode.d.ts new file mode 100644 index 0000000..937dbd4 --- /dev/null +++ b/packages/util-crypto/address/decode.d.ts @@ -0,0 +1,2 @@ +import type { Prefix } from './types.js'; +export declare function decodeAddress(encoded?: string | Uint8Array | null, ignoreChecksum?: boolean, ss58Format?: Prefix): Uint8Array; diff --git a/packages/util-crypto/address/decode.js b/packages/util-crypto/address/decode.js new file mode 100644 index 0000000..440beed --- /dev/null +++ b/packages/util-crypto/address/decode.js @@ -0,0 +1,29 @@ +import { isHex, isU8a, u8aToU8a } from '@pezkuwi/util'; +import { base58Decode } from '../base58/index.js'; +import { checkAddressChecksum } from './checksum.js'; +import { defaults } from './defaults.js'; +export function decodeAddress(encoded, ignoreChecksum, ss58Format = -1) { + if (!encoded) { + throw new Error('Invalid empty address passed'); + } + if (isU8a(encoded) || isHex(encoded)) { + return u8aToU8a(encoded); + } + try { + const decoded = base58Decode(encoded); + if (!defaults.allowedEncodedLengths.includes(decoded.length)) { + throw new Error('Invalid decoded address length'); + } + const [isValid, endPos, ss58Length, ss58Decoded] = checkAddressChecksum(decoded); + if (!isValid && !ignoreChecksum) { + throw new Error('Invalid decoded address checksum'); + } + else if (ss58Format !== -1 && ss58Format !== ss58Decoded) { + throw new Error(`Expected ss58Format ${ss58Format}, received ${ss58Decoded}`); + } + return decoded.slice(ss58Length, endPos); + } + catch (error) { + throw new Error(`Decoding ${encoded}: ${error.message}`); + } +} diff --git a/packages/util-crypto/address/defaults.d.ts b/packages/util-crypto/address/defaults.d.ts new file mode 100644 index 0000000..658612d --- /dev/null +++ b/packages/util-crypto/address/defaults.d.ts @@ -0,0 +1,6 @@ +export declare const defaults: { + allowedDecodedLengths: number[]; + allowedEncodedLengths: number[]; + allowedPrefix: number[]; + prefix: number; +}; diff --git a/packages/util-crypto/address/defaults.js b/packages/util-crypto/address/defaults.js new file mode 100644 index 0000000..bc548d7 --- /dev/null +++ b/packages/util-crypto/address/defaults.js @@ -0,0 +1,8 @@ +import { availableNetworks } from '../networks.js'; +export const defaults = { + allowedDecodedLengths: [1, 2, 4, 8, 32, 33], + // publicKey has prefix + 2 checksum bytes, short only prefix + 1 checksum byte + allowedEncodedLengths: [3, 4, 6, 10, 35, 36, 37, 38], + allowedPrefix: availableNetworks.map(({ prefix }) => prefix), + prefix: 42 +}; diff --git a/packages/util-crypto/address/derive.d.ts b/packages/util-crypto/address/derive.d.ts new file mode 100644 index 0000000..16718d7 --- /dev/null +++ b/packages/util-crypto/address/derive.d.ts @@ -0,0 +1,8 @@ +import type { Prefix } from './types.js'; +/** + * @name deriveAddress + * @summary Creates a sr25519 derived address from the supplied and path. + * @description + * Creates a sr25519 derived address based on the input address/publicKey and the uri supplied. + */ +export declare function deriveAddress(who: string | Uint8Array, suri: string, ss58Format?: Prefix): string; diff --git a/packages/util-crypto/address/derive.js b/packages/util-crypto/address/derive.js new file mode 100644 index 0000000..8767c31 --- /dev/null +++ b/packages/util-crypto/address/derive.js @@ -0,0 +1,24 @@ +import { keyExtractPath } from '../key/index.js'; +import { sr25519DerivePublic } from '../sr25519/index.js'; +import { decodeAddress } from './decode.js'; +import { encodeAddress } from './encode.js'; +function filterHard({ isHard }) { + return isHard; +} +/** + * @name deriveAddress + * @summary Creates a sr25519 derived address from the supplied and path. + * @description + * Creates a sr25519 derived address based on the input address/publicKey and the uri supplied. + */ +export function deriveAddress(who, suri, ss58Format) { + const { path } = keyExtractPath(suri); + if (!path.length || path.every(filterHard)) { + throw new Error('Expected suri to contain a combination of non-hard paths'); + } + let publicKey = decodeAddress(who); + for (const { chainCode } of path) { + publicKey = sr25519DerivePublic(publicKey, chainCode); + } + return encodeAddress(publicKey, ss58Format); +} diff --git a/packages/util-crypto/address/encode.d.ts b/packages/util-crypto/address/encode.d.ts new file mode 100644 index 0000000..788b2af --- /dev/null +++ b/packages/util-crypto/address/encode.d.ts @@ -0,0 +1,2 @@ +import type { Prefix } from './types.js'; +export declare function encodeAddress(key: string | Uint8Array, ss58Format?: Prefix): string; diff --git a/packages/util-crypto/address/encode.js b/packages/util-crypto/address/encode.js new file mode 100644 index 0000000..67f9295 --- /dev/null +++ b/packages/util-crypto/address/encode.js @@ -0,0 +1,23 @@ +import { u8aConcat } from '@pezkuwi/util'; +import { base58Encode } from '../base58/index.js'; +import { decodeAddress } from './decode.js'; +import { defaults } from './defaults.js'; +import { sshash } from './sshash.js'; +export function encodeAddress(key, ss58Format = defaults.prefix) { + // decode it, this means we can re-encode an address + const u8a = decodeAddress(key); + if ((ss58Format < 0) || (ss58Format > 16383 && !ss58Exceptions.includes(ss58Format)) || [46, 47].includes(ss58Format)) { + throw new Error('Out of range ss58Format specified'); + } + else if (!defaults.allowedDecodedLengths.includes(u8a.length)) { + throw new Error(`Expected a valid key to convert, with length ${defaults.allowedDecodedLengths.join(', ')}`); + } + const input = u8aConcat(ss58Format < 64 + ? [ss58Format] + : [ + ((ss58Format & 0b0000_0000_1111_1100) >> 2) | 0b0100_0000, + (ss58Format >> 8) | ((ss58Format & 0b0000_0000_0000_0011) << 6) + ], u8a); + return base58Encode(u8aConcat(input, sshash(input).subarray(0, [32, 33].includes(u8a.length) ? 2 : 1))); +} +const ss58Exceptions = [29972]; diff --git a/packages/util-crypto/address/encodeDerived.d.ts b/packages/util-crypto/address/encodeDerived.d.ts new file mode 100644 index 0000000..46eea7e --- /dev/null +++ b/packages/util-crypto/address/encodeDerived.d.ts @@ -0,0 +1,9 @@ +import type { BN } from '@pezkuwi/util'; +import type { Prefix } from './types.js'; +/** + * @name encodeDerivedAddress + * @summary Creates a derived address as used in Substrate utility. + * @description + * Creates a Substrate derived address based on the input address/publicKey and the index supplied. + */ +export declare function encodeDerivedAddress(who: string | Uint8Array, index: bigint | BN | number, ss58Format?: Prefix): string; diff --git a/packages/util-crypto/address/encodeDerived.js b/packages/util-crypto/address/encodeDerived.js new file mode 100644 index 0000000..e9483b7 --- /dev/null +++ b/packages/util-crypto/address/encodeDerived.js @@ -0,0 +1,12 @@ +import { decodeAddress } from './decode.js'; +import { encodeAddress } from './encode.js'; +import { createKeyDerived } from './keyDerived.js'; +/** + * @name encodeDerivedAddress + * @summary Creates a derived address as used in Substrate utility. + * @description + * Creates a Substrate derived address based on the input address/publicKey and the index supplied. + */ +export function encodeDerivedAddress(who, index, ss58Format) { + return encodeAddress(createKeyDerived(decodeAddress(who), index), ss58Format); +} diff --git a/packages/util-crypto/address/encodeMulti.d.ts b/packages/util-crypto/address/encodeMulti.d.ts new file mode 100644 index 0000000..db67bd0 --- /dev/null +++ b/packages/util-crypto/address/encodeMulti.d.ts @@ -0,0 +1,9 @@ +import type { BN } from '@pezkuwi/util'; +import type { Prefix } from './types.js'; +/** + * @name encodeMultiAddress + * @summary Creates a multisig address. + * @description + * Creates a Substrate multisig address based on the input address and the required threshold. + */ +export declare function encodeMultiAddress(who: (string | Uint8Array)[], threshold: bigint | BN | number, ss58Format?: Prefix): string; diff --git a/packages/util-crypto/address/encodeMulti.js b/packages/util-crypto/address/encodeMulti.js new file mode 100644 index 0000000..ba6a991 --- /dev/null +++ b/packages/util-crypto/address/encodeMulti.js @@ -0,0 +1,11 @@ +import { encodeAddress } from './encode.js'; +import { createKeyMulti } from './keyMulti.js'; +/** + * @name encodeMultiAddress + * @summary Creates a multisig address. + * @description + * Creates a Substrate multisig address based on the input address and the required threshold. + */ +export function encodeMultiAddress(who, threshold, ss58Format) { + return encodeAddress(createKeyMulti(who, threshold), ss58Format); +} diff --git a/packages/util-crypto/address/eq.d.ts b/packages/util-crypto/address/eq.d.ts new file mode 100644 index 0000000..880a2b7 --- /dev/null +++ b/packages/util-crypto/address/eq.d.ts @@ -0,0 +1,15 @@ +/** + * @name addressEq + * @summary Compares two addresses, either in ss58, Uint8Array or hex format. + * @description + * For the input values, return true is the underlying public keys do match. + * @example + *
+ * + * ```javascript + * import { u8aEq } from '@pezkuwi/util'; + * + * u8aEq(new Uint8Array([0x68, 0x65]), new Uint8Array([0x68, 0x65])); // true + * ``` + */ +export declare function addressEq(a: string | Uint8Array, b: string | Uint8Array): boolean; diff --git a/packages/util-crypto/address/eq.js b/packages/util-crypto/address/eq.js new file mode 100644 index 0000000..52ff1de --- /dev/null +++ b/packages/util-crypto/address/eq.js @@ -0,0 +1,19 @@ +import { u8aEq } from '@pezkuwi/util'; +import { decodeAddress } from './decode.js'; +/** + * @name addressEq + * @summary Compares two addresses, either in ss58, Uint8Array or hex format. + * @description + * For the input values, return true is the underlying public keys do match. + * @example + *
+ * + * ```javascript + * import { u8aEq } from '@pezkuwi/util'; + * + * u8aEq(new Uint8Array([0x68, 0x65]), new Uint8Array([0x68, 0x65])); // true + * ``` + */ +export function addressEq(a, b) { + return u8aEq(decodeAddress(a), decodeAddress(b)); +} diff --git a/packages/util-crypto/address/evmToAddress.d.ts b/packages/util-crypto/address/evmToAddress.d.ts new file mode 100644 index 0000000..a19b85a --- /dev/null +++ b/packages/util-crypto/address/evmToAddress.d.ts @@ -0,0 +1,7 @@ +import type { HashType } from '../secp256k1/types.js'; +import type { Prefix } from './types.js'; +/** + * @name evmToAddress + * @summary Converts an EVM address to its corresponding SS58 address. + */ +export declare function evmToAddress(evmAddress: string | Uint8Array, ss58Format?: Prefix, hashType?: HashType): string; diff --git a/packages/util-crypto/address/evmToAddress.js b/packages/util-crypto/address/evmToAddress.js new file mode 100644 index 0000000..1924d67 --- /dev/null +++ b/packages/util-crypto/address/evmToAddress.js @@ -0,0 +1,14 @@ +import { u8aConcat } from '@pezkuwi/util'; +import { hasher } from '../secp256k1/hasher.js'; +import { encodeAddress } from './encode.js'; +/** + * @name evmToAddress + * @summary Converts an EVM address to its corresponding SS58 address. + */ +export function evmToAddress(evmAddress, ss58Format, hashType = 'blake2') { + const message = u8aConcat('evm:', evmAddress); + if (message.length !== 24) { + throw new Error(`Converting ${evmAddress}: Invalid evm address length`); + } + return encodeAddress(hasher(hashType, message), ss58Format); +} diff --git a/packages/util-crypto/address/index.d.ts b/packages/util-crypto/address/index.d.ts new file mode 100644 index 0000000..8ea135b --- /dev/null +++ b/packages/util-crypto/address/index.d.ts @@ -0,0 +1,16 @@ +export { addressToEvm } from './addressToEvm.js'; +export { checkAddress } from './check.js'; +export { checkAddressChecksum } from './checksum.js'; +export { decodeAddress } from './decode.js'; +export { deriveAddress } from './derive.js'; +export { encodeAddress } from './encode.js'; +export { encodeDerivedAddress } from './encodeDerived.js'; +export { encodeMultiAddress } from './encodeMulti.js'; +export { addressEq } from './eq.js'; +export { evmToAddress } from './evmToAddress.js'; +export { isAddress } from './is.js'; +export { createKeyDerived } from './keyDerived.js'; +export { createKeyMulti } from './keyMulti.js'; +export { sortAddresses } from './sort.js'; +export { validateAddress } from './validate.js'; +export { setSS58Format } from './setSS58Format.js'; diff --git a/packages/util-crypto/address/index.js b/packages/util-crypto/address/index.js new file mode 100644 index 0000000..8ea135b --- /dev/null +++ b/packages/util-crypto/address/index.js @@ -0,0 +1,16 @@ +export { addressToEvm } from './addressToEvm.js'; +export { checkAddress } from './check.js'; +export { checkAddressChecksum } from './checksum.js'; +export { decodeAddress } from './decode.js'; +export { deriveAddress } from './derive.js'; +export { encodeAddress } from './encode.js'; +export { encodeDerivedAddress } from './encodeDerived.js'; +export { encodeMultiAddress } from './encodeMulti.js'; +export { addressEq } from './eq.js'; +export { evmToAddress } from './evmToAddress.js'; +export { isAddress } from './is.js'; +export { createKeyDerived } from './keyDerived.js'; +export { createKeyMulti } from './keyMulti.js'; +export { sortAddresses } from './sort.js'; +export { validateAddress } from './validate.js'; +export { setSS58Format } from './setSS58Format.js'; diff --git a/packages/util-crypto/address/is.d.ts b/packages/util-crypto/address/is.d.ts new file mode 100644 index 0000000..f67866a --- /dev/null +++ b/packages/util-crypto/address/is.d.ts @@ -0,0 +1,2 @@ +import type { Prefix } from './types.js'; +export declare function isAddress(address?: string | null, ignoreChecksum?: boolean, ss58Format?: Prefix): address is string; diff --git a/packages/util-crypto/address/is.js b/packages/util-crypto/address/is.js new file mode 100644 index 0000000..70ecb71 --- /dev/null +++ b/packages/util-crypto/address/is.js @@ -0,0 +1,9 @@ +import { validateAddress } from './validate.js'; +export function isAddress(address, ignoreChecksum, ss58Format) { + try { + return validateAddress(address, ignoreChecksum, ss58Format); + } + catch { + return false; + } +} diff --git a/packages/util-crypto/address/keyDerived.d.ts b/packages/util-crypto/address/keyDerived.d.ts new file mode 100644 index 0000000..bfd0b69 --- /dev/null +++ b/packages/util-crypto/address/keyDerived.d.ts @@ -0,0 +1,2 @@ +import type { BN } from '@pezkuwi/util'; +export declare function createKeyDerived(who: string | Uint8Array, index: bigint | BN | number): Uint8Array; diff --git a/packages/util-crypto/address/keyDerived.js b/packages/util-crypto/address/keyDerived.js new file mode 100644 index 0000000..49866bf --- /dev/null +++ b/packages/util-crypto/address/keyDerived.js @@ -0,0 +1,8 @@ +import { bnToU8a, stringToU8a, u8aConcat } from '@pezkuwi/util'; +import { blake2AsU8a } from '../blake2/asU8a.js'; +import { BN_LE_16_OPTS } from '../bn.js'; +import { decodeAddress } from './decode.js'; +const PREFIX = stringToU8a('modlpy/utilisuba'); +export function createKeyDerived(who, index) { + return blake2AsU8a(u8aConcat(PREFIX, decodeAddress(who), bnToU8a(index, BN_LE_16_OPTS))); +} diff --git a/packages/util-crypto/address/keyMulti.d.ts b/packages/util-crypto/address/keyMulti.d.ts new file mode 100644 index 0000000..ce3e622 --- /dev/null +++ b/packages/util-crypto/address/keyMulti.d.ts @@ -0,0 +1,2 @@ +import type { BN } from '@pezkuwi/util'; +export declare function createKeyMulti(who: (string | Uint8Array)[], threshold: bigint | BN | number): Uint8Array; diff --git a/packages/util-crypto/address/keyMulti.js b/packages/util-crypto/address/keyMulti.js new file mode 100644 index 0000000..504a6ba --- /dev/null +++ b/packages/util-crypto/address/keyMulti.js @@ -0,0 +1,8 @@ +import { bnToU8a, compactToU8a, stringToU8a, u8aConcat, u8aSorted } from '@pezkuwi/util'; +import { blake2AsU8a } from '../blake2/asU8a.js'; +import { BN_LE_16_OPTS } from '../bn.js'; +import { addressToU8a } from './util.js'; +const PREFIX = stringToU8a('modlpy/utilisuba'); +export function createKeyMulti(who, threshold) { + return blake2AsU8a(u8aConcat(PREFIX, compactToU8a(who.length), ...u8aSorted(who.map(addressToU8a)), bnToU8a(threshold, BN_LE_16_OPTS))); +} diff --git a/packages/util-crypto/address/setSS58Format.d.ts b/packages/util-crypto/address/setSS58Format.d.ts new file mode 100644 index 0000000..59374fb --- /dev/null +++ b/packages/util-crypto/address/setSS58Format.d.ts @@ -0,0 +1,6 @@ +import type { Prefix } from './types.js'; +/** + * @description Sets the global SS58 format to use for address encoding + * @deprecated Use keyring.setSS58Format + */ +export declare function setSS58Format(prefix: Prefix): void; diff --git a/packages/util-crypto/address/setSS58Format.js b/packages/util-crypto/address/setSS58Format.js new file mode 100644 index 0000000..7000aee --- /dev/null +++ b/packages/util-crypto/address/setSS58Format.js @@ -0,0 +1,11 @@ +import { logger } from '@pezkuwi/util'; +import { defaults } from './defaults.js'; +const l = logger('setSS58Format'); +/** + * @description Sets the global SS58 format to use for address encoding + * @deprecated Use keyring.setSS58Format + */ +export function setSS58Format(prefix) { + l.warn('Global setting of the ss58Format is deprecated and not recommended. Set format on the keyring (if used) or as part of the address encode function'); + defaults.prefix = prefix; +} diff --git a/packages/util-crypto/address/sort.d.ts b/packages/util-crypto/address/sort.d.ts new file mode 100644 index 0000000..a4727c5 --- /dev/null +++ b/packages/util-crypto/address/sort.d.ts @@ -0,0 +1,2 @@ +import type { Prefix } from './types.js'; +export declare function sortAddresses(addresses: (string | Uint8Array)[], ss58Format?: Prefix): string[]; diff --git a/packages/util-crypto/address/sort.js b/packages/util-crypto/address/sort.js new file mode 100644 index 0000000..ebc4fcf --- /dev/null +++ b/packages/util-crypto/address/sort.js @@ -0,0 +1,7 @@ +import { u8aSorted } from '@pezkuwi/util'; +import { encodeAddress } from './encode.js'; +import { addressToU8a } from './util.js'; +export function sortAddresses(addresses, ss58Format) { + const u8aToAddress = (u8a) => encodeAddress(u8a, ss58Format); + return u8aSorted(addresses.map(addressToU8a)).map(u8aToAddress); +} diff --git a/packages/util-crypto/address/sshash.d.ts b/packages/util-crypto/address/sshash.d.ts new file mode 100644 index 0000000..e206a15 --- /dev/null +++ b/packages/util-crypto/address/sshash.d.ts @@ -0,0 +1 @@ +export declare function sshash(key: Uint8Array): Uint8Array; diff --git a/packages/util-crypto/address/sshash.js b/packages/util-crypto/address/sshash.js new file mode 100644 index 0000000..e989b4e --- /dev/null +++ b/packages/util-crypto/address/sshash.js @@ -0,0 +1,6 @@ +import { stringToU8a, u8aConcat } from '@pezkuwi/util'; +import { blake2AsU8a } from '../blake2/asU8a.js'; +const SS58_PREFIX = stringToU8a('SS58PRE'); +export function sshash(key) { + return blake2AsU8a(u8aConcat(SS58_PREFIX, key), 512); +} diff --git a/packages/util-crypto/address/types.d.ts b/packages/util-crypto/address/types.d.ts new file mode 100644 index 0000000..6763033 --- /dev/null +++ b/packages/util-crypto/address/types.d.ts @@ -0,0 +1 @@ +export type Prefix = number; diff --git a/packages/util-crypto/address/types.js b/packages/util-crypto/address/types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/util-crypto/address/types.js @@ -0,0 +1 @@ +export {}; diff --git a/packages/util-crypto/address/util.d.ts b/packages/util-crypto/address/util.d.ts new file mode 100644 index 0000000..fb3e6d4 --- /dev/null +++ b/packages/util-crypto/address/util.d.ts @@ -0,0 +1 @@ +export declare function addressToU8a(who: string | Uint8Array): Uint8Array; diff --git a/packages/util-crypto/address/util.js b/packages/util-crypto/address/util.js new file mode 100644 index 0000000..022e5cd --- /dev/null +++ b/packages/util-crypto/address/util.js @@ -0,0 +1,4 @@ +import { decodeAddress } from './decode.js'; +export function addressToU8a(who) { + return decodeAddress(who); +} diff --git a/packages/util-crypto/address/validate.d.ts b/packages/util-crypto/address/validate.d.ts new file mode 100644 index 0000000..dd9d08c --- /dev/null +++ b/packages/util-crypto/address/validate.d.ts @@ -0,0 +1,2 @@ +import type { Prefix } from './types.js'; +export declare function validateAddress(encoded?: string | null, ignoreChecksum?: boolean, ss58Format?: Prefix): encoded is string; diff --git a/packages/util-crypto/address/validate.js b/packages/util-crypto/address/validate.js new file mode 100644 index 0000000..bdac2b4 --- /dev/null +++ b/packages/util-crypto/address/validate.js @@ -0,0 +1,4 @@ +import { decodeAddress } from './decode.js'; +export function validateAddress(encoded, ignoreChecksum, ss58Format) { + return !!decodeAddress(encoded, ignoreChecksum, ss58Format); +} diff --git a/packages/util-crypto/base32/bs32.d.ts b/packages/util-crypto/base32/bs32.d.ts new file mode 100644 index 0000000..663a6ab --- /dev/null +++ b/packages/util-crypto/base32/bs32.d.ts @@ -0,0 +1,26 @@ +/** + * @name base32Validate + * @summary Validates a base32 value. + * @description + * Validates that the supplied value is valid base32, throwing exceptions if not + */ +export declare const base32Validate: (value?: unknown, ipfsCompat?: boolean) => value is string; +/** +* @name isBase32 +* @description Checks if the input is in base32, returning true/false +*/ +export declare const isBase32: (value?: unknown, ipfsCompat?: boolean) => value is string; +/** + * @name base32Decode + * @summary Delookup a base32 value. + * @description + * From the provided input, decode the base32 and return the result as an `Uint8Array`. + */ +export declare const base32Decode: (value: string, ipfsCompat?: boolean) => Uint8Array; +/** +* @name base32Encode +* @summary Creates a base32 value. +* @description +* From the provided input, create the base32 and return the result as a string. +*/ +export declare const base32Encode: (value: import("@pezkuwi/util/types").U8aLike, ipfsCompat?: boolean) => string; diff --git a/packages/util-crypto/base32/bs32.js b/packages/util-crypto/base32/bs32.js new file mode 100644 index 0000000..28fdc28 --- /dev/null +++ b/packages/util-crypto/base32/bs32.js @@ -0,0 +1,40 @@ +import { utils } from '@scure/base'; +import { createDecode, createEncode, createIs, createValidate } from './helpers.js'; +const chars = 'abcdefghijklmnopqrstuvwxyz234567'; +const config = { + chars, + coder: utils.chain( + // We define our own chain, the default base32 has padding + utils.radix2(5), utils.alphabet(chars), { + decode: (input) => input.split(''), + encode: (input) => input.join('') + }), + ipfs: 'b', + type: 'base32' +}; +/** + * @name base32Validate + * @summary Validates a base32 value. + * @description + * Validates that the supplied value is valid base32, throwing exceptions if not + */ +export const base32Validate = /*#__PURE__*/ createValidate(config); +/** +* @name isBase32 +* @description Checks if the input is in base32, returning true/false +*/ +export const isBase32 = /*#__PURE__*/ createIs(base32Validate); +/** + * @name base32Decode + * @summary Delookup a base32 value. + * @description + * From the provided input, decode the base32 and return the result as an `Uint8Array`. + */ +export const base32Decode = /*#__PURE__*/ createDecode(config, base32Validate); +/** +* @name base32Encode +* @summary Creates a base32 value. +* @description +* From the provided input, create the base32 and return the result as a string. +*/ +export const base32Encode = /*#__PURE__*/ createEncode(config); diff --git a/packages/util-crypto/base32/helpers.d.ts b/packages/util-crypto/base32/helpers.d.ts new file mode 100644 index 0000000..c33650a --- /dev/null +++ b/packages/util-crypto/base32/helpers.d.ts @@ -0,0 +1,25 @@ +import type { U8aLike } from '@pezkuwi/util/types'; +export type { U8aLike } from '@pezkuwi/util/types'; +interface Coder { + decode: (value: string) => Uint8Array; + encode: (value: Uint8Array) => string; +} +interface Config { + chars: string; + coder: Coder; + ipfs?: string; + regex?: RegExp; + type: string; + withPadding?: boolean; +} +type DecodeFn = (value: string, ipfsCompat?: boolean) => Uint8Array; +type EncodeFn = (value: U8aLike, ipfsCompat?: boolean) => string; +type ValidateFn = (value?: unknown, ipfsCompat?: boolean) => value is string; +/** @internal */ +export declare function createDecode({ coder, ipfs }: Config, validate: ValidateFn): DecodeFn; +/** @internal */ +export declare function createEncode({ coder, ipfs }: Config): EncodeFn; +/** @internal */ +export declare function createIs(validate: ValidateFn): ValidateFn; +/** @internal */ +export declare function createValidate({ chars, ipfs, type, withPadding }: Config): ValidateFn; diff --git a/packages/util-crypto/base32/helpers.js b/packages/util-crypto/base32/helpers.js new file mode 100644 index 0000000..0298e52 --- /dev/null +++ b/packages/util-crypto/base32/helpers.js @@ -0,0 +1,61 @@ +import { u8aToU8a } from '@pezkuwi/util'; +/** @internal */ +export function createDecode({ coder, ipfs }, validate) { + return (value, ipfsCompat) => { + validate(value, ipfsCompat); + return coder.decode(ipfs && ipfsCompat + ? value.substring(1) + : value); + }; +} +/** @internal */ +export function createEncode({ coder, ipfs }) { + return (value, ipfsCompat) => { + const out = coder.encode(u8aToU8a(value)); + return ipfs && ipfsCompat + ? `${ipfs}${out}` + : out; + }; +} +/** @internal */ +export function createIs(validate) { + return (value, ipfsCompat) => { + try { + return validate(value, ipfsCompat); + } + catch { + return false; + } + }; +} +/** @internal */ +export function createValidate({ chars, ipfs, type, withPadding }) { + return (value, ipfsCompat) => { + if (typeof value !== 'string') { + throw new Error(`Expected ${type} string input`); + } + else if (ipfs && ipfsCompat && !value.startsWith(ipfs)) { + throw new Error(`Expected ipfs-compatible ${type} to start with '${ipfs}'`); + } + for (let i = (ipfsCompat ? 1 : 0), count = value.length; i < count; i++) { + if (chars.includes(value[i])) { + // all ok, character found + } + else if (withPadding && value[i] === '=') { + if (i === count - 1) { + // last character, everything ok + } + else if (value[i + 1] === '=') { + // next one is also padding, sequence ok + } + else { + throw new Error(`Invalid ${type} padding sequence "${value[i]}${value[i + 1]}" at index ${i}`); + } + } + else { + throw new Error(`Invalid ${type} character "${value[i]}" (0x${value.charCodeAt(i).toString(16)}) at index ${i}`); + } + } + return true; + }; +} diff --git a/packages/util-crypto/base32/index.d.ts b/packages/util-crypto/base32/index.d.ts new file mode 100644 index 0000000..05f41ce --- /dev/null +++ b/packages/util-crypto/base32/index.d.ts @@ -0,0 +1,4 @@ +/** + * @summary Encode and decode base32 values + */ +export { base32Decode, base32Encode, base32Validate, isBase32 } from './bs32.js'; diff --git a/packages/util-crypto/base32/index.js b/packages/util-crypto/base32/index.js new file mode 100644 index 0000000..05f41ce --- /dev/null +++ b/packages/util-crypto/base32/index.js @@ -0,0 +1,4 @@ +/** + * @summary Encode and decode base32 values + */ +export { base32Decode, base32Encode, base32Validate, isBase32 } from './bs32.js'; diff --git a/packages/util-crypto/base58/bs58.d.ts b/packages/util-crypto/base58/bs58.d.ts new file mode 100644 index 0000000..362e7b3 --- /dev/null +++ b/packages/util-crypto/base58/bs58.d.ts @@ -0,0 +1,26 @@ +/** + * @name base58Validate + * @summary Validates a base58 value. + * @description + * Validates that the supplied value is valid base58, throwing exceptions if not + */ +export declare const base58Validate: (value?: unknown, ipfsCompat?: boolean) => value is string; +/** + * @name base58Decode + * @summary Decodes a base58 value. + * @description + * From the provided input, decode the base58 and return the result as an `Uint8Array`. + */ +export declare const base58Decode: (value: string, ipfsCompat?: boolean) => Uint8Array; +/** +* @name base58Encode +* @summary Creates a base58 value. +* @description +* From the provided input, create the base58 and return the result as a string. +*/ +export declare const base58Encode: (value: import("@pezkuwi/util/types").U8aLike, ipfsCompat?: boolean) => string; +/** +* @name isBase58 +* @description Checks if the input is in base58, returning true/false +*/ +export declare const isBase58: (value?: unknown, ipfsCompat?: boolean) => value is string; diff --git a/packages/util-crypto/base58/bs58.js b/packages/util-crypto/base58/bs58.js new file mode 100644 index 0000000..412f45d --- /dev/null +++ b/packages/util-crypto/base58/bs58.js @@ -0,0 +1,34 @@ +import { base58 } from '@scure/base'; +import { createDecode, createEncode, createIs, createValidate } from '../base32/helpers.js'; +const config = { + chars: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz', + coder: base58, + ipfs: 'z', + type: 'base58' +}; +/** + * @name base58Validate + * @summary Validates a base58 value. + * @description + * Validates that the supplied value is valid base58, throwing exceptions if not + */ +export const base58Validate = /*#__PURE__*/ createValidate(config); +/** + * @name base58Decode + * @summary Decodes a base58 value. + * @description + * From the provided input, decode the base58 and return the result as an `Uint8Array`. + */ +export const base58Decode = /*#__PURE__*/ createDecode(config, base58Validate); +/** +* @name base58Encode +* @summary Creates a base58 value. +* @description +* From the provided input, create the base58 and return the result as a string. +*/ +export const base58Encode = /*#__PURE__*/ createEncode(config); +/** +* @name isBase58 +* @description Checks if the input is in base58, returning true/false +*/ +export const isBase58 = /*#__PURE__*/ createIs(base58Validate); diff --git a/packages/util-crypto/base58/index.d.ts b/packages/util-crypto/base58/index.d.ts new file mode 100644 index 0000000..ae26513 --- /dev/null +++ b/packages/util-crypto/base58/index.d.ts @@ -0,0 +1,4 @@ +/** + * @summary Encode and decode base58 values + */ +export { base58Decode, base58Encode, base58Validate, isBase58 } from './bs58.js'; diff --git a/packages/util-crypto/base58/index.js b/packages/util-crypto/base58/index.js new file mode 100644 index 0000000..ae26513 --- /dev/null +++ b/packages/util-crypto/base58/index.js @@ -0,0 +1,4 @@ +/** + * @summary Encode and decode base58 values + */ +export { base58Decode, base58Encode, base58Validate, isBase58 } from './bs58.js'; diff --git a/packages/util-crypto/base64/bs64.d.ts b/packages/util-crypto/base64/bs64.d.ts new file mode 100644 index 0000000..0027129 --- /dev/null +++ b/packages/util-crypto/base64/bs64.d.ts @@ -0,0 +1,26 @@ +/** + * @name base64Validate + * @summary Validates a base64 value. + * @description + * Validates that the supplied value is valid base64 + */ +export declare const base64Validate: (value?: unknown, ipfsCompat?: boolean) => value is string; +/** + * @name isBase64 + * @description Checks if the input is in base64, returning true/false + */ +export declare const isBase64: (value?: unknown, ipfsCompat?: boolean) => value is string; +/** + * @name base64Decode + * @summary Decodes a base64 value. + * @description + * From the provided input, decode the base64 and return the result as an `Uint8Array`. + */ +export declare const base64Decode: (value: string, ipfsCompat?: boolean) => Uint8Array; +/** + * @name base64Encode + * @summary Creates a base64 value. + * @description + * From the provided input, create the base64 and return the result as a string. + */ +export declare const base64Encode: (value: import("@pezkuwi/util/types").U8aLike, ipfsCompat?: boolean) => string; diff --git a/packages/util-crypto/base64/bs64.js b/packages/util-crypto/base64/bs64.js new file mode 100644 index 0000000..ceb159e --- /dev/null +++ b/packages/util-crypto/base64/bs64.js @@ -0,0 +1,34 @@ +import { base64 } from '@scure/base'; +import { createDecode, createEncode, createIs, createValidate } from '../base32/helpers.js'; +const config = { + chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', + coder: base64, + type: 'base64', + withPadding: true +}; +/** + * @name base64Validate + * @summary Validates a base64 value. + * @description + * Validates that the supplied value is valid base64 + */ +export const base64Validate = /*#__PURE__*/ createValidate(config); +/** + * @name isBase64 + * @description Checks if the input is in base64, returning true/false + */ +export const isBase64 = /*#__PURE__*/ createIs(base64Validate); +/** + * @name base64Decode + * @summary Decodes a base64 value. + * @description + * From the provided input, decode the base64 and return the result as an `Uint8Array`. + */ +export const base64Decode = /*#__PURE__*/ createDecode(config, base64Validate); +/** + * @name base64Encode + * @summary Creates a base64 value. + * @description + * From the provided input, create the base64 and return the result as a string. + */ +export const base64Encode = /*#__PURE__*/ createEncode(config); diff --git a/packages/util-crypto/base64/index.d.ts b/packages/util-crypto/base64/index.d.ts new file mode 100644 index 0000000..ec9b279 --- /dev/null +++ b/packages/util-crypto/base64/index.d.ts @@ -0,0 +1,6 @@ +/** + * @summary Encode and decode base64 values + */ +export { base64Decode, base64Encode, base64Validate, isBase64 } from './bs64.js'; +export { base64Pad } from './pad.js'; +export { base64Trim } from './trim.js'; diff --git a/packages/util-crypto/base64/index.js b/packages/util-crypto/base64/index.js new file mode 100644 index 0000000..ec9b279 --- /dev/null +++ b/packages/util-crypto/base64/index.js @@ -0,0 +1,6 @@ +/** + * @summary Encode and decode base64 values + */ +export { base64Decode, base64Encode, base64Validate, isBase64 } from './bs64.js'; +export { base64Pad } from './pad.js'; +export { base64Trim } from './trim.js'; diff --git a/packages/util-crypto/base64/pad.d.ts b/packages/util-crypto/base64/pad.d.ts new file mode 100644 index 0000000..90764f2 --- /dev/null +++ b/packages/util-crypto/base64/pad.d.ts @@ -0,0 +1,5 @@ +/** + * @name base64Pad + * @description Adds padding characters for correct length + */ +export declare function base64Pad(value: string): string; diff --git a/packages/util-crypto/base64/pad.js b/packages/util-crypto/base64/pad.js new file mode 100644 index 0000000..90be715 --- /dev/null +++ b/packages/util-crypto/base64/pad.js @@ -0,0 +1,7 @@ +/** + * @name base64Pad + * @description Adds padding characters for correct length + */ +export function base64Pad(value) { + return value.padEnd(value.length + (value.length % 4), '='); +} diff --git a/packages/util-crypto/base64/trim.d.ts b/packages/util-crypto/base64/trim.d.ts new file mode 100644 index 0000000..4daf3e9 --- /dev/null +++ b/packages/util-crypto/base64/trim.d.ts @@ -0,0 +1,5 @@ +/** + * @name base64Trim + * @description Trims padding characters + */ +export declare function base64Trim(value: string): string; diff --git a/packages/util-crypto/base64/trim.js b/packages/util-crypto/base64/trim.js new file mode 100644 index 0000000..39ea72c --- /dev/null +++ b/packages/util-crypto/base64/trim.js @@ -0,0 +1,10 @@ +/** + * @name base64Trim + * @description Trims padding characters + */ +export function base64Trim(value) { + while (value.length && value.endsWith('=')) { + value = value.slice(0, -1); + } + return value; +} diff --git a/packages/util-crypto/blake2/asU8a.d.ts b/packages/util-crypto/blake2/asU8a.d.ts new file mode 100644 index 0000000..1da59c5 --- /dev/null +++ b/packages/util-crypto/blake2/asU8a.d.ts @@ -0,0 +1,20 @@ +/** + * @name blake2AsU8a + * @summary Creates a blake2b u8a from the input. + * @description + * From a `Uint8Array` input, create the blake2b and return the result as a u8a with the specified `bitLength`. + * @example + *
+ * + * ```javascript + * import { blake2AsU8a } from '@pezkuwi/util-crypto'; + * + * blake2AsU8a('abc'); // => [0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d] + * ``` + */ +export declare function blake2AsU8a(data: string | Uint8Array, bitLength?: 64 | 128 | 256 | 384 | 512, key?: Uint8Array | null, onlyJs?: boolean): Uint8Array; +/** + * @name blake2AsHex + * @description Creates a blake2b hex from the input. + */ +export declare const blake2AsHex: (data: string | Uint8Array, bitLength?: 256 | 512 | 64 | 128 | 384 | undefined, key?: Uint8Array | null | undefined, onlyJs?: boolean | undefined) => import("@pezkuwi/util/types").HexString; diff --git a/packages/util-crypto/blake2/asU8a.js b/packages/util-crypto/blake2/asU8a.js new file mode 100644 index 0000000..b0ce698 --- /dev/null +++ b/packages/util-crypto/blake2/asU8a.js @@ -0,0 +1,32 @@ +import { blake2b as blake2bJs } from '@noble/hashes/blake2b'; +import { hasBigInt, u8aToU8a } from '@pezkuwi/util'; +import { blake2b, isReady } from '@pezkuwi/wasm-crypto'; +import { createAsHex } from '../helpers.js'; +/** + * @name blake2AsU8a + * @summary Creates a blake2b u8a from the input. + * @description + * From a `Uint8Array` input, create the blake2b and return the result as a u8a with the specified `bitLength`. + * @example + *
+ * + * ```javascript + * import { blake2AsU8a } from '@pezkuwi/util-crypto'; + * + * blake2AsU8a('abc'); // => [0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d] + * ``` + */ +export function blake2AsU8a(data, bitLength = 256, key, onlyJs) { + const byteLength = Math.ceil(bitLength / 8); + const u8a = u8aToU8a(data); + return !hasBigInt || (!onlyJs && isReady()) + ? blake2b(u8a, u8aToU8a(key), byteLength) + : key + ? blake2bJs(u8a, { dkLen: byteLength, key }) + : blake2bJs(u8a, { dkLen: byteLength }); +} +/** + * @name blake2AsHex + * @description Creates a blake2b hex from the input. + */ +export const blake2AsHex = /*#__PURE__*/ createAsHex(blake2AsU8a); diff --git a/packages/util-crypto/blake2/index.d.ts b/packages/util-crypto/blake2/index.d.ts new file mode 100644 index 0000000..25b6d7e --- /dev/null +++ b/packages/util-crypto/blake2/index.d.ts @@ -0,0 +1,4 @@ +/** + * @summary Create blake2b values with specified bitlengths + */ +export { blake2AsHex, blake2AsU8a } from './asU8a.js'; diff --git a/packages/util-crypto/blake2/index.js b/packages/util-crypto/blake2/index.js new file mode 100644 index 0000000..25b6d7e --- /dev/null +++ b/packages/util-crypto/blake2/index.js @@ -0,0 +1,4 @@ +/** + * @summary Create blake2b values with specified bitlengths + */ +export { blake2AsHex, blake2AsU8a } from './asU8a.js'; diff --git a/packages/util-crypto/bn.d.ts b/packages/util-crypto/bn.d.ts new file mode 100644 index 0000000..9222de6 --- /dev/null +++ b/packages/util-crypto/bn.d.ts @@ -0,0 +1,30 @@ +export declare const BN_BE_OPTS: { + isLe: boolean; +}; +export declare const BN_LE_OPTS: { + isLe: boolean; +}; +export declare const BN_LE_16_OPTS: { + bitLength: number; + isLe: boolean; +}; +export declare const BN_BE_32_OPTS: { + bitLength: number; + isLe: boolean; +}; +export declare const BN_LE_32_OPTS: { + bitLength: number; + isLe: boolean; +}; +export declare const BN_BE_256_OPTS: { + bitLength: number; + isLe: boolean; +}; +export declare const BN_LE_256_OPTS: { + bitLength: number; + isLe: boolean; +}; +export declare const BN_LE_512_OPTS: { + bitLength: number; + isLe: boolean; +}; diff --git a/packages/util-crypto/bn.js b/packages/util-crypto/bn.js new file mode 100644 index 0000000..0f0f309 --- /dev/null +++ b/packages/util-crypto/bn.js @@ -0,0 +1,8 @@ +export const BN_BE_OPTS = { isLe: false }; +export const BN_LE_OPTS = { isLe: true }; +export const BN_LE_16_OPTS = { bitLength: 16, isLe: true }; +export const BN_BE_32_OPTS = { bitLength: 32, isLe: false }; +export const BN_LE_32_OPTS = { bitLength: 32, isLe: true }; +export const BN_BE_256_OPTS = { bitLength: 256, isLe: false }; +export const BN_LE_256_OPTS = { bitLength: 256, isLe: true }; +export const BN_LE_512_OPTS = { bitLength: 512, isLe: true }; diff --git a/packages/util-crypto/bundle-pezkuwi-util-crypto.js b/packages/util-crypto/bundle-pezkuwi-util-crypto.js new file mode 100644 index 0000000..fd908db --- /dev/null +++ b/packages/util-crypto/bundle-pezkuwi-util-crypto.js @@ -0,0 +1,8251 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@pezkuwi/util')) : + typeof define === 'function' && define.amd ? define(['exports', '@pezkuwi/util'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.pezkuwiUtilCrypto = {}, global.pezkuwiUtil)); +})(this, (function (exports, util) { 'use strict'; + + const global = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : window; + + var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null; + const packageInfo$2 = { name: '@pezkuwi/x-global', path: (({ url: (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-util-crypto.js', document.baseURI).href)) }) && (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-util-crypto.js', document.baseURI).href))) ? new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-util-crypto.js', document.baseURI).href))).pathname.substring(0, new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-util-crypto.js', document.baseURI).href))).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; + + function evaluateThis(fn) { + return fn('return this'); + } + const xglobal = (typeof globalThis !== 'undefined' + ? globalThis + : typeof global !== 'undefined' + ? global + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : evaluateThis(Function)); + function extractGlobal(name, fallback) { + return typeof xglobal[name] === 'undefined' + ? fallback + : xglobal[name]; + } + function exposeGlobal(name, fallback) { + if (typeof xglobal[name] === 'undefined') { + xglobal[name] = fallback; + } + } + + const build = /*#__PURE__*/Object.freeze({ + __proto__: null, + exposeGlobal: exposeGlobal, + extractGlobal: extractGlobal, + packageInfo: packageInfo$2, + xglobal: xglobal + }); + + function invalidFallback() { + return Number.NaN; + } + const BigInt$1 = extractGlobal('BigInt', invalidFallback); + + exposeGlobal('BigInt', BigInt$1); + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function getAugmentedNamespace(n) { + if (n.__esModule) return n; + var f = n.default; + if (typeof f == "function") { + var a = function a () { + if (this instanceof a) { + return Reflect.construct(f, arguments, this.constructor); + } + return f.apply(this, arguments); + }; + a.prototype = f.prototype; + } else a = {}; + Object.defineProperty(a, '__esModule', {value: true}); + Object.keys(n).forEach(function (k) { + var d = Object.getOwnPropertyDescriptor(n, k); + Object.defineProperty(a, k, d.get ? d : { + enumerable: true, + get: function () { + return n[k]; + } + }); + }); + return a; + } + + var browser = {}; + + const require$$0 = /*@__PURE__*/getAugmentedNamespace(build); + + var packageInfo$1 = {}; + + Object.defineProperty(packageInfo$1, "__esModule", { value: true }); + packageInfo$1.packageInfo = void 0; + packageInfo$1.packageInfo = { name: '@pezkuwi/x-randomvalues', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; + + (function (exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.crypto = exports$1.packageInfo = void 0; + exports$1.getRandomValues = getRandomValues; + const x_global_1 = require$$0; + var packageInfo_js_1 = packageInfo$1; + Object.defineProperty(exports$1, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); + exports$1.crypto = x_global_1.xglobal.crypto; + function getRandomValues(arr) { + return exports$1.crypto.getRandomValues(arr); + } + } (browser)); + getDefaultExportFromCjs(browser); + + const DEFAULT_CRYPTO = { getRandomValues: browser.getRandomValues }; + const DEFAULT_SELF = { crypto: DEFAULT_CRYPTO }; + class Wbg { + #bridge; + constructor(bridge) { + this.#bridge = bridge; + } + abort = () => { + throw new Error('abort'); + }; + __wbindgen_is_undefined = (idx) => { + return this.#bridge.getObject(idx) === undefined; + }; + __wbindgen_throw = (ptr, len) => { + throw new Error(this.#bridge.getString(ptr, len)); + }; + __wbg_self_1b7a39e3a92c949c = () => { + return this.#bridge.addObject(DEFAULT_SELF); + }; + __wbg_require_604837428532a733 = (ptr, len) => { + throw new Error(`Unable to require ${this.#bridge.getString(ptr, len)}`); + }; + __wbg_crypto_968f1772287e2df0 = (_idx) => { + return this.#bridge.addObject(DEFAULT_CRYPTO); + }; + __wbg_getRandomValues_a3d34b4fee3c2869 = (_idx) => { + return this.#bridge.addObject(DEFAULT_CRYPTO.getRandomValues); + }; + __wbg_getRandomValues_f5e14ab7ac8e995d = (_arg0, ptr, len) => { + DEFAULT_CRYPTO.getRandomValues(this.#bridge.getU8a(ptr, len)); + }; + __wbg_randomFillSync_d5bd2d655fdf256a = (_idx, _ptr, _len) => { + throw new Error('randomFillsync is not available'); + }; + __wbindgen_object_drop_ref = (idx) => { + this.#bridge.takeObject(idx); + }; + } + + class Bridge { + #createWasm; + #heap; + #wbg; + #cachegetInt32; + #cachegetUint8; + #heapNext; + #wasm; + #wasmError; + #wasmPromise; + #type; + constructor(createWasm) { + this.#createWasm = createWasm; + this.#cachegetInt32 = null; + this.#cachegetUint8 = null; + this.#heap = new Array(32) + .fill(undefined) + .concat(undefined, null, true, false); + this.#heapNext = this.#heap.length; + this.#type = 'none'; + this.#wasm = null; + this.#wasmError = null; + this.#wasmPromise = null; + this.#wbg = { ...new Wbg(this) }; + } + get error() { + return this.#wasmError; + } + get type() { + return this.#type; + } + get wasm() { + return this.#wasm; + } + async init(createWasm) { + if (!this.#wasmPromise || createWasm) { + this.#wasmPromise = (createWasm || this.#createWasm)(this.#wbg); + } + const { error, type, wasm } = await this.#wasmPromise; + this.#type = type; + this.#wasm = wasm; + this.#wasmError = error; + return this.#wasm; + } + getObject(idx) { + return this.#heap[idx]; + } + dropObject(idx) { + if (idx < 36) { + return; + } + this.#heap[idx] = this.#heapNext; + this.#heapNext = idx; + } + takeObject(idx) { + const ret = this.getObject(idx); + this.dropObject(idx); + return ret; + } + addObject(obj) { + if (this.#heapNext === this.#heap.length) { + this.#heap.push(this.#heap.length + 1); + } + const idx = this.#heapNext; + this.#heapNext = this.#heap[idx]; + this.#heap[idx] = obj; + return idx; + } + getInt32() { + if (this.#cachegetInt32 === null || this.#cachegetInt32.buffer !== this.#wasm.memory.buffer) { + this.#cachegetInt32 = new Int32Array(this.#wasm.memory.buffer); + } + return this.#cachegetInt32; + } + getUint8() { + if (this.#cachegetUint8 === null || this.#cachegetUint8.buffer !== this.#wasm.memory.buffer) { + this.#cachegetUint8 = new Uint8Array(this.#wasm.memory.buffer); + } + return this.#cachegetUint8; + } + getU8a(ptr, len) { + return this.getUint8().subarray(ptr / 1, ptr / 1 + len); + } + getString(ptr, len) { + return util.u8aToString(this.getU8a(ptr, len)); + } + allocU8a(arg) { + const ptr = this.#wasm.__wbindgen_malloc(arg.length * 1); + this.getUint8().set(arg, ptr / 1); + return [ptr, arg.length]; + } + allocString(arg) { + return this.allocU8a(util.stringToU8a(arg)); + } + resultU8a() { + const r0 = this.getInt32()[8 / 4 + 0]; + const r1 = this.getInt32()[8 / 4 + 1]; + const ret = this.getU8a(r0, r1).slice(); + this.#wasm.__wbindgen_free(r0, r1 * 1); + return ret; + } + resultString() { + return util.u8aToString(this.resultU8a()); + } + } + + function createWasmFn(root, wasmBytes, asmFn) { + return async (wbg) => { + const result = { + error: null, + type: 'none', + wasm: null + }; + try { + if (!wasmBytes?.length) { + throw new Error('No WebAssembly provided for initialization'); + } + else if (typeof WebAssembly !== 'object' || typeof WebAssembly.instantiate !== 'function') { + throw new Error('WebAssembly is not available in your environment'); + } + const source = await WebAssembly.instantiate(wasmBytes, { wbg }); + result.wasm = source.instance.exports; + result.type = 'wasm'; + } + catch (error) { + { + result.error = `FATAL: Unable to initialize @pezkuwi/wasm-${root}:: ${error.message}`; + console.error(result.error); + } + } + return result; + }; + } + + const CHR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + const map = new Array(256); + for (let i = 0, count = CHR.length; i < count; i++) { + map[CHR.charCodeAt(i)] = i; + } + function base64Decode$1(data, out) { + let byte = 0; + let bits = 0; + let pos = -1; + for (let i = 0, last = out.length - 1; pos !== last; i++) { + byte = (byte << 6) | map[data.charCodeAt(i)]; + if ((bits += 6) >= 8) { + out[++pos] = (byte >>> (bits -= 8)) & 0xff; + } + } + return out; + } + + const u8 = Uint8Array, u16 = Uint16Array, u32$1 = Uint32Array; + const clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]); + const fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0, 0]); + const fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 0, 0]); + const freb = (eb, start) => { + const b = new u16(31); + for (let i = 0; i < 31; ++i) { + b[i] = start += 1 << eb[i - 1]; + } + const r = new u32$1(b[30]); + for (let i = 1; i < 30; ++i) { + for (let j = b[i]; j < b[i + 1]; ++j) { + r[j] = ((j - b[i]) << 5) | i; + } + } + return [b, r]; + }; + const [fl, revfl] = freb(fleb, 2); + fl[28] = 258, revfl[258] = 28; + const [fd] = freb(fdeb, 0); + const rev = new u16(32768); + for (let i = 0; i < 32768; ++i) { + let x = ((i & 0xAAAA) >>> 1) | ((i & 0x5555) << 1); + x = ((x & 0xCCCC) >>> 2) | ((x & 0x3333) << 2); + x = ((x & 0xF0F0) >>> 4) | ((x & 0x0F0F) << 4); + rev[i] = (((x & 0xFF00) >>> 8) | ((x & 0x00FF) << 8)) >>> 1; + } + const hMap = ((cd, mb, r) => { + const s = cd.length; + let i = 0; + const l = new u16(mb); + for (; i < s; ++i) { + if (cd[i]) + ++l[cd[i] - 1]; + } + const le = new u16(mb); + for (i = 1; i < mb; ++i) { + le[i] = (le[i - 1] + l[i - 1]) << 1; + } + let co; + { + co = new u16(1 << mb); + const rvb = 15 - mb; + for (i = 0; i < s; ++i) { + if (cd[i]) { + const sv = (i << 4) | cd[i]; + const r = mb - cd[i]; + let v = le[cd[i] - 1]++ << r; + for (const m = v | ((1 << r) - 1); v <= m; ++v) { + co[rev[v] >> rvb] = sv; + } + } + } + } + return co; + }); + const flt = new u8(288); + for (let i = 0; i < 144; ++i) + flt[i] = 8; + for (let i = 144; i < 256; ++i) + flt[i] = 9; + for (let i = 256; i < 280; ++i) + flt[i] = 7; + for (let i = 280; i < 288; ++i) + flt[i] = 8; + const fdt = new u8(32); + for (let i = 0; i < 32; ++i) + fdt[i] = 5; + const flrm = hMap(flt, 9); + const fdrm = hMap(fdt, 5); + const bits = (d, p, m) => { + const o = p >>> 3; + return ((d[o] | (d[o + 1] << 8)) >>> (p & 7)) & m; + }; + const bits16 = (d, p) => { + const o = p >>> 3; + return ((d[o] | (d[o + 1] << 8) | (d[o + 2] << 16)) >>> (p & 7)); + }; + const shft = (p) => (p >>> 3) + (p & 7 && 1); + const slc = (v, s, e) => { + if (e == null || e > v.length) + e = v.length; + const n = new (v instanceof u16 ? u16 : v instanceof u32$1 ? u32$1 : u8)(e - s); + n.set(v.subarray(s, e)); + return n; + }; + const max = (a) => { + let m = a[0]; + for (let i = 1, count = a.length; i < count; ++i) { + if (a[i] > m) + m = a[i]; + } + return m; + }; + const inflt = (dat, buf, st) => { + const noSt = !st || st.i; + if (!st) + st = {}; + const sl = dat.length; + const noBuf = !buf || !noSt; + if (!buf) + buf = new u8(sl * 3); + const cbuf = (l) => { + let bl = buf.length; + if (l > bl) { + const nbuf = new u8(Math.max(bl << 1, l)); + nbuf.set(buf); + buf = nbuf; + } + }; + let final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n; + if (final && !lm) + return buf; + const tbts = sl << 3; + do { + if (!lm) { + st.f = final = bits(dat, pos, 1); + const type = bits(dat, pos + 1, 3); + pos += 3; + if (!type) { + const s = shft(pos) + 4, l = dat[s - 4] | (dat[s - 3] << 8), t = s + l; + if (t > sl) { + if (noSt) + throw 'unexpected EOF'; + break; + } + if (noBuf) + cbuf(bt + l); + buf.set(dat.subarray(s, t), bt); + st.b = bt += l, st.p = pos = t << 3; + continue; + } + else if (type == 1) + lm = flrm, dm = fdrm, lbt = 9, dbt = 5; + else if (type == 2) { + const hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4; + const tl = hLit + bits(dat, pos + 5, 31) + 1; + pos += 14; + const ldt = new u8(tl); + const clt = new u8(19); + for (let i = 0; i < hcLen; ++i) { + clt[clim[i]] = bits(dat, pos + i * 3, 7); + } + pos += hcLen * 3; + const clb = max(clt), clbmsk = (1 << clb) - 1; + if (!noSt && pos + tl * (clb + 7) > tbts) + break; + const clm = hMap(clt, clb); + for (let i = 0; i < tl;) { + const r = clm[bits(dat, pos, clbmsk)]; + pos += r & 15; + const s = r >>> 4; + if (s < 16) { + ldt[i++] = s; + } + else { + let c = 0, n = 0; + if (s == 16) + n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1]; + else if (s == 17) + n = 3 + bits(dat, pos, 7), pos += 3; + else if (s == 18) + n = 11 + bits(dat, pos, 127), pos += 7; + while (n--) + ldt[i++] = c; + } + } + const lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit); + lbt = max(lt); + dbt = max(dt); + lm = hMap(lt, lbt); + dm = hMap(dt, dbt); + } + else + throw 'invalid block type'; + if (pos > tbts) + throw 'unexpected EOF'; + } + if (noBuf) + cbuf(bt + 131072); + const lms = (1 << lbt) - 1, dms = (1 << dbt) - 1; + const mxa = lbt + dbt + 18; + while (noSt || pos + mxa < tbts) { + const c = lm[bits16(dat, pos) & lms], sym = c >>> 4; + pos += c & 15; + if (pos > tbts) + throw 'unexpected EOF'; + if (!c) + throw 'invalid length/literal'; + if (sym < 256) + buf[bt++] = sym; + else if (sym == 256) { + lm = undefined; + break; + } + else { + let add = sym - 254; + if (sym > 264) { + const i = sym - 257, b = fleb[i]; + add = bits(dat, pos, (1 << b) - 1) + fl[i]; + pos += b; + } + const d = dm[bits16(dat, pos) & dms], dsym = d >>> 4; + if (!d) + throw 'invalid distance'; + pos += d & 15; + let dt = fd[dsym]; + if (dsym > 3) { + const b = fdeb[dsym]; + dt += bits16(dat, pos) & ((1 << b) - 1), pos += b; + } + if (pos > tbts) + throw 'unexpected EOF'; + if (noBuf) + cbuf(bt + 131072); + const end = bt + add; + for (; bt < end; bt += 4) { + buf[bt] = buf[bt - dt]; + buf[bt + 1] = buf[bt + 1 - dt]; + buf[bt + 2] = buf[bt + 2 - dt]; + buf[bt + 3] = buf[bt + 3 - dt]; + } + bt = end; + } + } + st.l = lm, st.p = pos, st.b = bt; + if (lm) + final = 1, st.m = lbt, st.d = dm, st.n = dbt; + } while (!final); + return bt == buf.length ? buf : slc(buf, 0, bt); + }; + const zlv = (d) => { + if ((d[0] & 15) != 8 || (d[0] >>> 4) > 7 || ((d[0] << 8 | d[1]) % 31)) + throw 'invalid zlib data'; + if (d[1] & 32) + throw 'invalid zlib data: preset dictionaries not supported'; + }; + function unzlibSync(data, out) { + return inflt((zlv(data), data.subarray(2, -4)), out); + } + + var lenIn = 168782; + var lenOut = 335277; + var bytes_1 = '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'; + + const wasmBytes = unzlibSync(base64Decode$1(bytes_1, new Uint8Array(lenIn)), new Uint8Array(lenOut)); + + const createWasm = createWasmFn('crypto', wasmBytes); + + const bridge = new Bridge(createWasm); + async function initBridge(createWasm) { + return bridge.init(createWasm); + } + + function withWasm(fn) { + return (...params) => { + if (!bridge.wasm) { + throw new Error('The WASM interface has not been initialized. Ensure that you wait for the initialization Promise with waitReady() from @pezkuwi/wasm-crypto (or cryptoWaitReady() from @pezkuwi/util-crypto) before attempting to use WASM-only interfaces.'); + } + return fn(bridge.wasm, ...params); + }; + } + const bip39Generate = withWasm((wasm, words) => { + wasm.ext_bip39_generate(8, words); + return bridge.resultString(); + }); + const bip39ToEntropy = withWasm((wasm, phrase) => { + wasm.ext_bip39_to_entropy(8, ...bridge.allocString(phrase)); + return bridge.resultU8a(); + }); + const bip39ToMiniSecret = withWasm((wasm, phrase, password) => { + wasm.ext_bip39_to_mini_secret(8, ...bridge.allocString(phrase), ...bridge.allocString(password)); + return bridge.resultU8a(); + }); + const bip39ToSeed = withWasm((wasm, phrase, password) => { + wasm.ext_bip39_to_seed(8, ...bridge.allocString(phrase), ...bridge.allocString(password)); + return bridge.resultU8a(); + }); + const bip39Validate = withWasm((wasm, phrase) => { + const ret = wasm.ext_bip39_validate(...bridge.allocString(phrase)); + return ret !== 0; + }); + const ed25519KeypairFromSeed = withWasm((wasm, seed) => { + wasm.ext_ed_from_seed(8, ...bridge.allocU8a(seed)); + return bridge.resultU8a(); + }); + const ed25519Sign$1 = withWasm((wasm, pubkey, seckey, message) => { + wasm.ext_ed_sign(8, ...bridge.allocU8a(pubkey), ...bridge.allocU8a(seckey), ...bridge.allocU8a(message)); + return bridge.resultU8a(); + }); + const ed25519Verify$1 = withWasm((wasm, signature, message, pubkey) => { + const ret = wasm.ext_ed_verify(...bridge.allocU8a(signature), ...bridge.allocU8a(message), ...bridge.allocU8a(pubkey)); + return ret !== 0; + }); + const secp256k1FromSeed = withWasm((wasm, seckey) => { + wasm.ext_secp_from_seed(8, ...bridge.allocU8a(seckey)); + return bridge.resultU8a(); + }); + const secp256k1Compress$1 = withWasm((wasm, pubkey) => { + wasm.ext_secp_pub_compress(8, ...bridge.allocU8a(pubkey)); + return bridge.resultU8a(); + }); + const secp256k1Expand$1 = withWasm((wasm, pubkey) => { + wasm.ext_secp_pub_expand(8, ...bridge.allocU8a(pubkey)); + return bridge.resultU8a(); + }); + const secp256k1Recover$1 = withWasm((wasm, msgHash, sig, recovery) => { + wasm.ext_secp_recover(8, ...bridge.allocU8a(msgHash), ...bridge.allocU8a(sig), recovery); + return bridge.resultU8a(); + }); + const secp256k1Sign$1 = withWasm((wasm, msgHash, seckey) => { + wasm.ext_secp_sign(8, ...bridge.allocU8a(msgHash), ...bridge.allocU8a(seckey)); + return bridge.resultU8a(); + }); + const blake2b$2 = withWasm((wasm, data, key, size) => { + wasm.ext_blake2b(8, ...bridge.allocU8a(data), ...bridge.allocU8a(key), size); + return bridge.resultU8a(); + }); + const hmacSha256 = withWasm((wasm, key, data) => { + wasm.ext_hmac_sha256(8, ...bridge.allocU8a(key), ...bridge.allocU8a(data)); + return bridge.resultU8a(); + }); + const hmacSha512 = withWasm((wasm, key, data) => { + wasm.ext_hmac_sha512(8, ...bridge.allocU8a(key), ...bridge.allocU8a(data)); + return bridge.resultU8a(); + }); + const keccak256 = withWasm((wasm, data) => { + wasm.ext_keccak256(8, ...bridge.allocU8a(data)); + return bridge.resultU8a(); + }); + const keccak512 = withWasm((wasm, data) => { + wasm.ext_keccak512(8, ...bridge.allocU8a(data)); + return bridge.resultU8a(); + }); + const pbkdf2$1 = withWasm((wasm, data, salt, rounds) => { + wasm.ext_pbkdf2(8, ...bridge.allocU8a(data), ...bridge.allocU8a(salt), rounds); + return bridge.resultU8a(); + }); + const scrypt$1 = withWasm((wasm, password, salt, log2n, r, p) => { + wasm.ext_scrypt(8, ...bridge.allocU8a(password), ...bridge.allocU8a(salt), log2n, r, p); + return bridge.resultU8a(); + }); + const sha256$2 = withWasm((wasm, data) => { + wasm.ext_sha256(8, ...bridge.allocU8a(data)); + return bridge.resultU8a(); + }); + const sha512$2 = withWasm((wasm, data) => { + wasm.ext_sha512(8, ...bridge.allocU8a(data)); + return bridge.resultU8a(); + }); + const twox = withWasm((wasm, data, rounds) => { + wasm.ext_twox(8, ...bridge.allocU8a(data), rounds); + return bridge.resultU8a(); + }); + function isReady() { + return !!bridge.wasm; + } + async function waitReady() { + try { + const wasm = await initBridge(); + return !!wasm; + } + catch { + return false; + } + } + + const cryptoIsReady = isReady; + function cryptoWaitReady() { + return waitReady() + .then(() => { + if (!isReady()) { + throw new Error('Unable to initialize @pezkuwi/util-crypto'); + } + return true; + }) + .catch(() => false); + } + + cryptoWaitReady().catch(() => { + }); + + const packageInfo = { name: '@pezkuwi/util-crypto', path: (({ url: (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-util-crypto.js', document.baseURI).href)) }) && (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-util-crypto.js', document.baseURI).href))) ? new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-util-crypto.js', document.baseURI).href))).pathname.substring(0, new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-util-crypto.js', document.baseURI).href))).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; + + /*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */ + function isBytes$2(a) { + return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array'); + } + function abytes$2(b, ...lengths) { + if (!isBytes$2(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)); + } + } + 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$1(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`); + } + function chain(...args) { + const id = (a) => a; + const wrap = (a, b) => (c) => a(b(c)); + const encode = args.map((x) => x.encode).reduceRight(wrap, id); + const decode = args.map((x) => x.decode).reduce(wrap, id); + return { encode, decode }; + } + function alphabet(letters) { + const lettersA = typeof letters === 'string' ? letters.split('') : letters; + const len = lettersA.length; + astrArr('alphabet', lettersA); + 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; + }); + }, + }; + } + 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); + }, + }; + } + function padding(bits, chr = '=') { + anumber$1(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); + }, + }; + } + function normalize$1(fn) { + afn(fn); + return { encode: (from) => from, decode: (to) => fn(to) }; + } + function convertRadix(data, from, to) { + 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$1(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 = (from, to) => from + (to - gcd(from, to)); + const powers = (() => { + let res = []; + for (let i = 0; i < 40; i++) + res.push(2 ** i); + return res; + })(); + 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; + const max = powers[from]; + const mask = powers[to] - 1; + const res = []; + for (const n of data) { + anumber$1(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; + } + 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; + } + function radix(num) { + anumber$1(num); + const _256 = 2 ** 8; + return { + encode: (bytes) => { + if (!isBytes$2(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)); + }, + }; + } + function radix2(bits, revPadding = false) { + anumber$1(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$2(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$1(len); + afn(fn); + return { + encode(data) { + if (!isBytes$2(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$2(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; + }, + }; + } + const utils = { + alphabet, chain, checksum, convertRadix, convertRadix2, radix, radix2, join, padding, + }; + chain(radix2(4), alphabet('0123456789ABCDEF'), join('')); + chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join('')); + chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), join('')); + chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join('')); + chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), join('')); + chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize$1((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1'))); + const hasBase64Builtin = (() => typeof Uint8Array.from([]).toBase64 === 'function' && + typeof Uint8Array.fromBase64 === 'function')(); + const decodeBase64Builtin = (s, isUrl) => { + astr('base64', s); + const re = /^[A-Za-z0-9=+/]+$/; + const alphabet = 'base64'; + if (s.length > 0 && !re.test(s)) + throw new Error('invalid base64'); + return Uint8Array.fromBase64(s, { alphabet, lastChunkHandling: 'strict' }); + }; + const base64 = hasBase64Builtin ? { + encode(b) { abytes$2(b); return b.toBase64(); }, + decode(s) { return decodeBase64Builtin(s); }, + } : chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join('')); + chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), join('')); + hasBase64Builtin ? { + } : chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join('')); + chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), join('')); + const genBase58 = (abc) => chain(radix(58), alphabet(abc), join('')); + const base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'); + genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'); + genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz'); + 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)); + } + 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$2(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})`); + 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, + }; + } + genBech32('bech32'); + genBech32('bech32m'); + const hasHexBuiltin$1 = (() => typeof Uint8Array.from([]).toHex === 'function' && + typeof Uint8Array.fromHex === 'function')(); + const hexBuiltin = { + }; + hasHexBuiltin$1 + ? hexBuiltin + : chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize$1((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(); + })); + + function createDecode({ coder, ipfs }, validate) { + return (value, ipfsCompat) => { + validate(value, ipfsCompat); + return coder.decode(ipfs && ipfsCompat + ? value.substring(1) + : value); + }; + } + function createEncode({ coder, ipfs }) { + return (value, ipfsCompat) => { + const out = coder.encode(util.u8aToU8a(value)); + return ipfs && ipfsCompat + ? `${ipfs}${out}` + : out; + }; + } + function createIs(validate) { + return (value, ipfsCompat) => { + try { + return validate(value, ipfsCompat); + } + catch { + return false; + } + }; + } + function createValidate({ chars, ipfs, type, withPadding }) { + return (value, ipfsCompat) => { + if (typeof value !== 'string') { + throw new Error(`Expected ${type} string input`); + } + else if (ipfs && ipfsCompat && !value.startsWith(ipfs)) { + throw new Error(`Expected ipfs-compatible ${type} to start with '${ipfs}'`); + } + for (let i = (ipfsCompat ? 1 : 0), count = value.length; i < count; i++) { + if (chars.includes(value[i])) ; + else if (withPadding && value[i] === '=') { + if (i === count - 1) ; + else if (value[i + 1] === '=') ; + else { + throw new Error(`Invalid ${type} padding sequence "${value[i]}${value[i + 1]}" at index ${i}`); + } + } + else { + throw new Error(`Invalid ${type} character "${value[i]}" (0x${value.charCodeAt(i).toString(16)}) at index ${i}`); + } + } + return true; + }; + } + + const config$2 = { + chars: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz', + coder: base58, + ipfs: 'z', + type: 'base58' + }; + const base58Validate = createValidate(config$2); + const base58Decode = createDecode(config$2, base58Validate); + const base58Encode = createEncode(config$2); + const isBase58 = createIs(base58Validate); + + const crypto = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined; + + /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */ + function isBytes$1(a) { + return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array'); + } + function anumber(n) { + if (!Number.isSafeInteger(n) || n < 0) + throw new Error('positive integer expected, got ' + n); + } + function abytes$1(b, ...lengths) { + if (!isBytes$1(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 ahash(h) { + if (typeof h !== 'function' || typeof h.create !== 'function') + throw new Error('Hash should be wrapped by utils.createHasher'); + anumber(h.outputLen); + anumber(h.blockLen); + } + function aexists(instance, checkFinished = true) { + if (instance.destroyed) + throw new Error('Hash instance has been destroyed'); + if (checkFinished && instance.finished) + throw new Error('Hash#digest() has already been called'); + } + function aoutput(out, instance) { + abytes$1(out); + const min = instance.outputLen; + if (out.length < min) { + throw new Error('digestInto() expects output buffer of length at least ' + min); + } + } + function u32(arr) { + return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4)); + } + function clean(...arrays) { + for (let i = 0; i < arrays.length; i++) { + arrays[i].fill(0); + } + } + function createView(arr) { + return new DataView(arr.buffer, arr.byteOffset, arr.byteLength); + } + function rotr(word, shift) { + return (word << (32 - shift)) | (word >>> shift); + } + function rotl$1(word, shift) { + return (word << shift) | ((word >>> (32 - shift)) >>> 0); + } + const isLE = (() => new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)(); + function byteSwap(word) { + return (((word << 24) & 0xff000000) | + ((word << 8) & 0xff0000) | + ((word >>> 8) & 0xff00) | + ((word >>> 24) & 0xff)); + } + const swap8IfBE = isLE + ? (n) => n + : (n) => byteSwap(n); + function byteSwap32(arr) { + for (let i = 0; i < arr.length; i++) { + arr[i] = byteSwap(arr[i]); + } + return arr; + } + const swap32IfBE = isLE + ? (u) => u + : byteSwap32; + const hasHexBuiltin = (() => + typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')(); + const hexes = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0')); + function bytesToHex(bytes) { + abytes$1(bytes); + if (hasHexBuiltin) + return bytes.toHex(); + let hex = ''; + for (let i = 0; i < bytes.length; i++) { + hex += hexes[bytes[i]]; + } + return hex; + } + const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 }; + function asciiToBase16(ch) { + if (ch >= asciis._0 && ch <= asciis._9) + return ch - asciis._0; + if (ch >= asciis.A && ch <= asciis.F) + return ch - (asciis.A - 10); + if (ch >= asciis.a && ch <= asciis.f) + return ch - (asciis.a - 10); + return; + } + function hexToBytes(hex) { + if (typeof hex !== 'string') + throw new Error('hex string expected, got ' + typeof hex); + if (hasHexBuiltin) + return Uint8Array.fromHex(hex); + const hl = hex.length; + const al = hl / 2; + if (hl % 2) + throw new Error('hex string expected, got unpadded hex of length ' + hl); + const array = new Uint8Array(al); + for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) { + const n1 = asciiToBase16(hex.charCodeAt(hi)); + const n2 = asciiToBase16(hex.charCodeAt(hi + 1)); + if (n1 === undefined || n2 === undefined) { + const char = hex[hi] + hex[hi + 1]; + throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi); + } + array[ai] = n1 * 16 + n2; + } + return array; + } + function utf8ToBytes(str) { + if (typeof str !== 'string') + throw new Error('string expected'); + return new Uint8Array(new TextEncoder().encode(str)); + } + function toBytes(data) { + if (typeof data === 'string') + data = utf8ToBytes(data); + abytes$1(data); + return data; + } + function kdfInputToBytes(data) { + if (typeof data === 'string') + data = utf8ToBytes(data); + abytes$1(data); + return data; + } + function concatBytes(...arrays) { + let sum = 0; + for (let i = 0; i < arrays.length; i++) { + const a = arrays[i]; + abytes$1(a); + sum += a.length; + } + const res = new Uint8Array(sum); + for (let i = 0, pad = 0; i < arrays.length; i++) { + const a = arrays[i]; + res.set(a, pad); + pad += a.length; + } + return res; + } + function checkOpts(defaults, opts) { + if (opts !== undefined && {}.toString.call(opts) !== '[object Object]') + throw new Error('options should be object or undefined'); + const merged = Object.assign(defaults, opts); + return merged; + } + class Hash { + } + function createHasher$1(hashCons) { + const hashC = (msg) => hashCons().update(toBytes(msg)).digest(); + const tmp = hashCons(); + hashC.outputLen = tmp.outputLen; + hashC.blockLen = tmp.blockLen; + hashC.create = () => hashCons(); + return hashC; + } + function createOptHasher(hashCons) { + const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest(); + const tmp = hashCons({}); + hashC.outputLen = tmp.outputLen; + hashC.blockLen = tmp.blockLen; + hashC.create = (opts) => hashCons(opts); + return hashC; + } + function createXOFer(hashCons) { + const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest(); + const tmp = hashCons({}); + hashC.outputLen = tmp.outputLen; + hashC.blockLen = tmp.blockLen; + hashC.create = (opts) => hashCons(opts); + return hashC; + } + function randomBytes(bytesLength = 32) { + if (crypto && typeof crypto.getRandomValues === 'function') { + return crypto.getRandomValues(new Uint8Array(bytesLength)); + } + if (crypto && typeof crypto.randomBytes === 'function') { + return Uint8Array.from(crypto.randomBytes(bytesLength)); + } + throw new Error('crypto.getRandomValues must be defined'); + } + + const BSIGMA = Uint8Array.from([ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, + 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, + 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, + 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, + 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, + 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11, + 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10, + 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5, + 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, + 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, + 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, + 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, + 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, + ]); + function G1s(a, b, c, d, x) { + a = (a + b + x) | 0; + d = rotr(d ^ a, 16); + c = (c + d) | 0; + b = rotr(b ^ c, 12); + return { a, b, c, d }; + } + function G2s(a, b, c, d, x) { + a = (a + b + x) | 0; + d = rotr(d ^ a, 8); + c = (c + d) | 0; + b = rotr(b ^ c, 7); + return { a, b, c, d }; + } + + function setBigUint64(view, byteOffset, value, isLE) { + if (typeof view.setBigUint64 === 'function') + return view.setBigUint64(byteOffset, value, isLE); + const _32n = BigInt(32); + const _u32_max = BigInt(0xffffffff); + const wh = Number((value >> _32n) & _u32_max); + const wl = Number(value & _u32_max); + const h = isLE ? 4 : 0; + const l = isLE ? 0 : 4; + view.setUint32(byteOffset + h, wh, isLE); + view.setUint32(byteOffset + l, wl, isLE); + } + function Chi(a, b, c) { + return (a & b) ^ (~a & c); + } + function Maj(a, b, c) { + return (a & b) ^ (a & c) ^ (b & c); + } + class HashMD extends Hash { + constructor(blockLen, outputLen, padOffset, isLE) { + super(); + this.finished = false; + this.length = 0; + this.pos = 0; + this.destroyed = false; + this.blockLen = blockLen; + this.outputLen = outputLen; + this.padOffset = padOffset; + this.isLE = isLE; + this.buffer = new Uint8Array(blockLen); + this.view = createView(this.buffer); + } + update(data) { + aexists(this); + data = toBytes(data); + abytes$1(data); + const { view, buffer, blockLen } = this; + const len = data.length; + for (let pos = 0; pos < len;) { + const take = Math.min(blockLen - this.pos, len - pos); + if (take === blockLen) { + const dataView = createView(data); + for (; blockLen <= len - pos; pos += blockLen) + this.process(dataView, pos); + continue; + } + buffer.set(data.subarray(pos, pos + take), this.pos); + this.pos += take; + pos += take; + if (this.pos === blockLen) { + this.process(view, 0); + this.pos = 0; + } + } + this.length += data.length; + this.roundClean(); + return this; + } + digestInto(out) { + aexists(this); + aoutput(out, this); + this.finished = true; + const { buffer, view, blockLen, isLE } = this; + let { pos } = this; + buffer[pos++] = 0b10000000; + clean(this.buffer.subarray(pos)); + if (this.padOffset > blockLen - pos) { + this.process(view, 0); + pos = 0; + } + for (let i = pos; i < blockLen; i++) + buffer[i] = 0; + setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE); + this.process(view, 0); + const oview = createView(out); + const len = this.outputLen; + if (len % 4) + throw new Error('_sha2: outputLen should be aligned to 32bit'); + const outLen = len / 4; + const state = this.get(); + if (outLen > state.length) + throw new Error('_sha2: outputLen bigger than state'); + for (let i = 0; i < outLen; i++) + oview.setUint32(4 * i, state[i], isLE); + } + digest() { + const { buffer, outputLen } = this; + this.digestInto(buffer); + const res = buffer.slice(0, outputLen); + this.destroy(); + return res; + } + _cloneInto(to) { + to || (to = new this.constructor()); + to.set(...this.get()); + const { blockLen, buffer, length, finished, destroyed, pos } = this; + to.destroyed = destroyed; + to.finished = finished; + to.length = length; + to.pos = pos; + if (length % blockLen) + to.buffer.set(buffer); + return to; + } + clone() { + return this._cloneInto(); + } + } + const SHA256_IV = Uint32Array.from([ + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, + ]); + const SHA224_IV = Uint32Array.from([ + 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4, + ]); + const SHA384_IV = Uint32Array.from([ + 0xcbbb9d5d, 0xc1059ed8, 0x629a292a, 0x367cd507, 0x9159015a, 0x3070dd17, 0x152fecd8, 0xf70e5939, + 0x67332667, 0xffc00b31, 0x8eb44a87, 0x68581511, 0xdb0c2e0d, 0x64f98fa7, 0x47b5481d, 0xbefa4fa4, + ]); + const SHA512_IV = Uint32Array.from([ + 0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1, + 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179, + ]); + + const U32_MASK64 = BigInt(2 ** 32 - 1); + const _32n$1 = BigInt(32); + function fromBig(n, le = false) { + if (le) + return { h: Number(n & U32_MASK64), l: Number((n >> _32n$1) & U32_MASK64) }; + return { h: Number((n >> _32n$1) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 }; + } + function split(lst, le = false) { + const len = lst.length; + let Ah = new Uint32Array(len); + let Al = new Uint32Array(len); + for (let i = 0; i < len; i++) { + const { h, l } = fromBig(lst[i], le); + [Ah[i], Al[i]] = [h, l]; + } + return [Ah, Al]; + } + const shrSH = (h, _l, s) => h >>> s; + const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s); + const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s)); + const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s); + const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32)); + const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s)); + const rotr32H = (_h, l) => l; + const rotr32L = (h, _l) => h; + const rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s)); + const rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s)); + const rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s)); + const rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s)); + function add(Ah, Al, Bh, Bl) { + const l = (Al >>> 0) + (Bl >>> 0); + return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 }; + } + const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0); + const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0; + const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0); + const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0; + const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0); + const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0; + + const B2B_IV = Uint32Array.from([ + 0xf3bcc908, 0x6a09e667, 0x84caa73b, 0xbb67ae85, 0xfe94f82b, 0x3c6ef372, 0x5f1d36f1, 0xa54ff53a, + 0xade682d1, 0x510e527f, 0x2b3e6c1f, 0x9b05688c, 0xfb41bd6b, 0x1f83d9ab, 0x137e2179, 0x5be0cd19, + ]); + const BBUF = new Uint32Array(32); + function G1b(a, b, c, d, msg, x) { + const Xl = msg[x], Xh = msg[x + 1]; + let Al = BBUF[2 * a], Ah = BBUF[2 * a + 1]; + let Bl = BBUF[2 * b], Bh = BBUF[2 * b + 1]; + let Cl = BBUF[2 * c], Ch = BBUF[2 * c + 1]; + let Dl = BBUF[2 * d], Dh = BBUF[2 * d + 1]; + let ll = add3L(Al, Bl, Xl); + Ah = add3H(ll, Ah, Bh, Xh); + Al = ll | 0; + ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); + ({ Dh, Dl } = { Dh: rotr32H(Dh, Dl), Dl: rotr32L(Dh) }); + ({ h: Ch, l: Cl } = add(Ch, Cl, Dh, Dl)); + ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); + ({ Bh, Bl } = { Bh: rotrSH(Bh, Bl, 24), Bl: rotrSL(Bh, Bl, 24) }); + (BBUF[2 * a] = Al), (BBUF[2 * a + 1] = Ah); + (BBUF[2 * b] = Bl), (BBUF[2 * b + 1] = Bh); + (BBUF[2 * c] = Cl), (BBUF[2 * c + 1] = Ch); + (BBUF[2 * d] = Dl), (BBUF[2 * d + 1] = Dh); + } + function G2b(a, b, c, d, msg, x) { + const Xl = msg[x], Xh = msg[x + 1]; + let Al = BBUF[2 * a], Ah = BBUF[2 * a + 1]; + let Bl = BBUF[2 * b], Bh = BBUF[2 * b + 1]; + let Cl = BBUF[2 * c], Ch = BBUF[2 * c + 1]; + let Dl = BBUF[2 * d], Dh = BBUF[2 * d + 1]; + let ll = add3L(Al, Bl, Xl); + Ah = add3H(ll, Ah, Bh, Xh); + Al = ll | 0; + ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); + ({ Dh, Dl } = { Dh: rotrSH(Dh, Dl, 16), Dl: rotrSL(Dh, Dl, 16) }); + ({ h: Ch, l: Cl } = add(Ch, Cl, Dh, Dl)); + ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); + ({ Bh, Bl } = { Bh: rotrBH(Bh, Bl, 63), Bl: rotrBL(Bh, Bl, 63) }); + (BBUF[2 * a] = Al), (BBUF[2 * a + 1] = Ah); + (BBUF[2 * b] = Bl), (BBUF[2 * b + 1] = Bh); + (BBUF[2 * c] = Cl), (BBUF[2 * c + 1] = Ch); + (BBUF[2 * d] = Dl), (BBUF[2 * d + 1] = Dh); + } + function checkBlake2Opts(outputLen, opts = {}, keyLen, saltLen, persLen) { + anumber(keyLen); + if (outputLen < 0 || outputLen > keyLen) + throw new Error('outputLen bigger than keyLen'); + const { key, salt, personalization } = opts; + if (key !== undefined && (key.length < 1 || key.length > keyLen)) + throw new Error('key length must be undefined or 1..' + keyLen); + if (salt !== undefined && salt.length !== saltLen) + throw new Error('salt must be undefined or ' + saltLen); + if (personalization !== undefined && personalization.length !== persLen) + throw new Error('personalization must be undefined or ' + persLen); + } + class BLAKE2 extends Hash { + constructor(blockLen, outputLen) { + super(); + this.finished = false; + this.destroyed = false; + this.length = 0; + this.pos = 0; + anumber(blockLen); + anumber(outputLen); + this.blockLen = blockLen; + this.outputLen = outputLen; + this.buffer = new Uint8Array(blockLen); + this.buffer32 = u32(this.buffer); + } + update(data) { + aexists(this); + data = toBytes(data); + abytes$1(data); + const { blockLen, buffer, buffer32 } = this; + const len = data.length; + const offset = data.byteOffset; + const buf = data.buffer; + for (let pos = 0; pos < len;) { + if (this.pos === blockLen) { + swap32IfBE(buffer32); + this.compress(buffer32, 0, false); + swap32IfBE(buffer32); + this.pos = 0; + } + const take = Math.min(blockLen - this.pos, len - pos); + const dataOffset = offset + pos; + if (take === blockLen && !(dataOffset % 4) && pos + take < len) { + const data32 = new Uint32Array(buf, dataOffset, Math.floor((len - pos) / 4)); + swap32IfBE(data32); + for (let pos32 = 0; pos + blockLen < len; pos32 += buffer32.length, pos += blockLen) { + this.length += blockLen; + this.compress(data32, pos32, false); + } + swap32IfBE(data32); + continue; + } + buffer.set(data.subarray(pos, pos + take), this.pos); + this.pos += take; + this.length += take; + pos += take; + } + return this; + } + digestInto(out) { + aexists(this); + aoutput(out, this); + const { pos, buffer32 } = this; + this.finished = true; + clean(this.buffer.subarray(pos)); + swap32IfBE(buffer32); + this.compress(buffer32, 0, true); + swap32IfBE(buffer32); + const out32 = u32(out); + this.get().forEach((v, i) => (out32[i] = swap8IfBE(v))); + } + digest() { + const { buffer, outputLen } = this; + this.digestInto(buffer); + const res = buffer.slice(0, outputLen); + this.destroy(); + return res; + } + _cloneInto(to) { + const { buffer, length, finished, destroyed, outputLen, pos } = this; + to || (to = new this.constructor({ dkLen: outputLen })); + to.set(...this.get()); + to.buffer.set(buffer); + to.destroyed = destroyed; + to.finished = finished; + to.length = length; + to.pos = pos; + to.outputLen = outputLen; + return to; + } + clone() { + return this._cloneInto(); + } + } + class BLAKE2b extends BLAKE2 { + constructor(opts = {}) { + const olen = opts.dkLen === undefined ? 64 : opts.dkLen; + super(128, olen); + this.v0l = B2B_IV[0] | 0; + this.v0h = B2B_IV[1] | 0; + this.v1l = B2B_IV[2] | 0; + this.v1h = B2B_IV[3] | 0; + this.v2l = B2B_IV[4] | 0; + this.v2h = B2B_IV[5] | 0; + this.v3l = B2B_IV[6] | 0; + this.v3h = B2B_IV[7] | 0; + this.v4l = B2B_IV[8] | 0; + this.v4h = B2B_IV[9] | 0; + this.v5l = B2B_IV[10] | 0; + this.v5h = B2B_IV[11] | 0; + this.v6l = B2B_IV[12] | 0; + this.v6h = B2B_IV[13] | 0; + this.v7l = B2B_IV[14] | 0; + this.v7h = B2B_IV[15] | 0; + checkBlake2Opts(olen, opts, 64, 16, 16); + let { key, personalization, salt } = opts; + let keyLength = 0; + if (key !== undefined) { + key = toBytes(key); + keyLength = key.length; + } + this.v0l ^= this.outputLen | (keyLength << 8) | (0x01 << 16) | (0x01 << 24); + if (salt !== undefined) { + salt = toBytes(salt); + const slt = u32(salt); + this.v4l ^= swap8IfBE(slt[0]); + this.v4h ^= swap8IfBE(slt[1]); + this.v5l ^= swap8IfBE(slt[2]); + this.v5h ^= swap8IfBE(slt[3]); + } + if (personalization !== undefined) { + personalization = toBytes(personalization); + const pers = u32(personalization); + this.v6l ^= swap8IfBE(pers[0]); + this.v6h ^= swap8IfBE(pers[1]); + this.v7l ^= swap8IfBE(pers[2]); + this.v7h ^= swap8IfBE(pers[3]); + } + if (key !== undefined) { + const tmp = new Uint8Array(this.blockLen); + tmp.set(key); + this.update(tmp); + } + } + get() { + let { v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h } = this; + return [v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h]; + } + set(v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h) { + this.v0l = v0l | 0; + this.v0h = v0h | 0; + this.v1l = v1l | 0; + this.v1h = v1h | 0; + this.v2l = v2l | 0; + this.v2h = v2h | 0; + this.v3l = v3l | 0; + this.v3h = v3h | 0; + this.v4l = v4l | 0; + this.v4h = v4h | 0; + this.v5l = v5l | 0; + this.v5h = v5h | 0; + this.v6l = v6l | 0; + this.v6h = v6h | 0; + this.v7l = v7l | 0; + this.v7h = v7h | 0; + } + compress(msg, offset, isLast) { + this.get().forEach((v, i) => (BBUF[i] = v)); + BBUF.set(B2B_IV, 16); + let { h, l } = fromBig(BigInt(this.length)); + BBUF[24] = B2B_IV[8] ^ l; + BBUF[25] = B2B_IV[9] ^ h; + if (isLast) { + BBUF[28] = ~BBUF[28]; + BBUF[29] = ~BBUF[29]; + } + let j = 0; + const s = BSIGMA; + for (let i = 0; i < 12; i++) { + G1b(0, 4, 8, 12, msg, offset + 2 * s[j++]); + G2b(0, 4, 8, 12, msg, offset + 2 * s[j++]); + G1b(1, 5, 9, 13, msg, offset + 2 * s[j++]); + G2b(1, 5, 9, 13, msg, offset + 2 * s[j++]); + G1b(2, 6, 10, 14, msg, offset + 2 * s[j++]); + G2b(2, 6, 10, 14, msg, offset + 2 * s[j++]); + G1b(3, 7, 11, 15, msg, offset + 2 * s[j++]); + G2b(3, 7, 11, 15, msg, offset + 2 * s[j++]); + G1b(0, 5, 10, 15, msg, offset + 2 * s[j++]); + G2b(0, 5, 10, 15, msg, offset + 2 * s[j++]); + G1b(1, 6, 11, 12, msg, offset + 2 * s[j++]); + G2b(1, 6, 11, 12, msg, offset + 2 * s[j++]); + G1b(2, 7, 8, 13, msg, offset + 2 * s[j++]); + G2b(2, 7, 8, 13, msg, offset + 2 * s[j++]); + G1b(3, 4, 9, 14, msg, offset + 2 * s[j++]); + G2b(3, 4, 9, 14, msg, offset + 2 * s[j++]); + } + this.v0l ^= BBUF[0] ^ BBUF[16]; + this.v0h ^= BBUF[1] ^ BBUF[17]; + this.v1l ^= BBUF[2] ^ BBUF[18]; + this.v1h ^= BBUF[3] ^ BBUF[19]; + this.v2l ^= BBUF[4] ^ BBUF[20]; + this.v2h ^= BBUF[5] ^ BBUF[21]; + this.v3l ^= BBUF[6] ^ BBUF[22]; + this.v3h ^= BBUF[7] ^ BBUF[23]; + this.v4l ^= BBUF[8] ^ BBUF[24]; + this.v4h ^= BBUF[9] ^ BBUF[25]; + this.v5l ^= BBUF[10] ^ BBUF[26]; + this.v5h ^= BBUF[11] ^ BBUF[27]; + this.v6l ^= BBUF[12] ^ BBUF[28]; + this.v6h ^= BBUF[13] ^ BBUF[29]; + this.v7l ^= BBUF[14] ^ BBUF[30]; + this.v7h ^= BBUF[15] ^ BBUF[31]; + clean(BBUF); + } + destroy() { + this.destroyed = true; + clean(this.buffer32); + this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + } + } + const blake2b$1 = createOptHasher((opts) => new BLAKE2b(opts)); + function compress(s, offset, msg, rounds, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) { + let j = 0; + for (let i = 0; i < rounds; i++) { + ({ a: v0, b: v4, c: v8, d: v12 } = G1s(v0, v4, v8, v12, msg[offset + s[j++]])); + ({ a: v0, b: v4, c: v8, d: v12 } = G2s(v0, v4, v8, v12, msg[offset + s[j++]])); + ({ a: v1, b: v5, c: v9, d: v13 } = G1s(v1, v5, v9, v13, msg[offset + s[j++]])); + ({ a: v1, b: v5, c: v9, d: v13 } = G2s(v1, v5, v9, v13, msg[offset + s[j++]])); + ({ a: v2, b: v6, c: v10, d: v14 } = G1s(v2, v6, v10, v14, msg[offset + s[j++]])); + ({ a: v2, b: v6, c: v10, d: v14 } = G2s(v2, v6, v10, v14, msg[offset + s[j++]])); + ({ a: v3, b: v7, c: v11, d: v15 } = G1s(v3, v7, v11, v15, msg[offset + s[j++]])); + ({ a: v3, b: v7, c: v11, d: v15 } = G2s(v3, v7, v11, v15, msg[offset + s[j++]])); + ({ a: v0, b: v5, c: v10, d: v15 } = G1s(v0, v5, v10, v15, msg[offset + s[j++]])); + ({ a: v0, b: v5, c: v10, d: v15 } = G2s(v0, v5, v10, v15, msg[offset + s[j++]])); + ({ a: v1, b: v6, c: v11, d: v12 } = G1s(v1, v6, v11, v12, msg[offset + s[j++]])); + ({ a: v1, b: v6, c: v11, d: v12 } = G2s(v1, v6, v11, v12, msg[offset + s[j++]])); + ({ a: v2, b: v7, c: v8, d: v13 } = G1s(v2, v7, v8, v13, msg[offset + s[j++]])); + ({ a: v2, b: v7, c: v8, d: v13 } = G2s(v2, v7, v8, v13, msg[offset + s[j++]])); + ({ a: v3, b: v4, c: v9, d: v14 } = G1s(v3, v4, v9, v14, msg[offset + s[j++]])); + ({ a: v3, b: v4, c: v9, d: v14 } = G2s(v3, v4, v9, v14, msg[offset + s[j++]])); + } + return { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 }; + } + const B2S_IV = SHA256_IV; + class BLAKE2s extends BLAKE2 { + constructor(opts = {}) { + const olen = opts.dkLen === undefined ? 32 : opts.dkLen; + super(64, olen); + this.v0 = B2S_IV[0] | 0; + this.v1 = B2S_IV[1] | 0; + this.v2 = B2S_IV[2] | 0; + this.v3 = B2S_IV[3] | 0; + this.v4 = B2S_IV[4] | 0; + this.v5 = B2S_IV[5] | 0; + this.v6 = B2S_IV[6] | 0; + this.v7 = B2S_IV[7] | 0; + checkBlake2Opts(olen, opts, 32, 8, 8); + let { key, personalization, salt } = opts; + let keyLength = 0; + if (key !== undefined) { + key = toBytes(key); + keyLength = key.length; + } + this.v0 ^= this.outputLen | (keyLength << 8) | (0x01 << 16) | (0x01 << 24); + if (salt !== undefined) { + salt = toBytes(salt); + const slt = u32(salt); + this.v4 ^= swap8IfBE(slt[0]); + this.v5 ^= swap8IfBE(slt[1]); + } + if (personalization !== undefined) { + personalization = toBytes(personalization); + const pers = u32(personalization); + this.v6 ^= swap8IfBE(pers[0]); + this.v7 ^= swap8IfBE(pers[1]); + } + if (key !== undefined) { + abytes$1(key); + const tmp = new Uint8Array(this.blockLen); + tmp.set(key); + this.update(tmp); + } + } + get() { + const { v0, v1, v2, v3, v4, v5, v6, v7 } = this; + return [v0, v1, v2, v3, v4, v5, v6, v7]; + } + set(v0, v1, v2, v3, v4, v5, v6, v7) { + this.v0 = v0 | 0; + this.v1 = v1 | 0; + this.v2 = v2 | 0; + this.v3 = v3 | 0; + this.v4 = v4 | 0; + this.v5 = v5 | 0; + this.v6 = v6 | 0; + this.v7 = v7 | 0; + } + compress(msg, offset, isLast) { + const { h, l } = fromBig(BigInt(this.length)); + const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = compress(BSIGMA, offset, msg, 10, this.v0, this.v1, this.v2, this.v3, this.v4, this.v5, this.v6, this.v7, B2S_IV[0], B2S_IV[1], B2S_IV[2], B2S_IV[3], l ^ B2S_IV[4], h ^ B2S_IV[5], isLast ? ~B2S_IV[6] : B2S_IV[6], B2S_IV[7]); + this.v0 ^= v0 ^ v8; + this.v1 ^= v1 ^ v9; + this.v2 ^= v2 ^ v10; + this.v3 ^= v3 ^ v11; + this.v4 ^= v4 ^ v12; + this.v5 ^= v5 ^ v13; + this.v6 ^= v6 ^ v14; + this.v7 ^= v7 ^ v15; + } + destroy() { + this.destroyed = true; + clean(this.buffer32); + this.set(0, 0, 0, 0, 0, 0, 0, 0); + } + } + createOptHasher((opts) => new BLAKE2s(opts)); + + const blake2b = blake2b$1; + + function createAsHex(fn) { + return (...args) => util.u8aToHex(fn(...args)); + } + function createBitHasher(bitLength, fn) { + return (data, onlyJs) => fn(data, bitLength, onlyJs); + } + function createDualHasher(wa, js) { + return (value, bitLength = 256, onlyJs) => { + const u8a = util.u8aToU8a(value); + return !util.hasBigInt || (!onlyJs && isReady()) + ? wa[bitLength](u8a) + : js[bitLength](u8a); + }; + } + + function blake2AsU8a(data, bitLength = 256, key, onlyJs) { + const byteLength = Math.ceil(bitLength / 8); + const u8a = util.u8aToU8a(data); + return !util.hasBigInt || (!onlyJs && isReady()) + ? blake2b$2(u8a, util.u8aToU8a(key), byteLength) + : key + ? blake2b(u8a, { dkLen: byteLength, key }) + : blake2b(u8a, { dkLen: byteLength }); + } + const blake2AsHex = createAsHex(blake2AsU8a); + + const SS58_PREFIX = util.stringToU8a('SS58PRE'); + function sshash(key) { + return blake2AsU8a(util.u8aConcat(SS58_PREFIX, key), 512); + } + + function checkAddressChecksum(decoded) { + const ss58Length = (decoded[0] & 0b0100_0000) ? 2 : 1; + const ss58Decoded = ss58Length === 1 + ? decoded[0] + : ((decoded[0] & 0b0011_1111) << 2) | (decoded[1] >> 6) | ((decoded[1] & 0b0011_1111) << 8); + const isPublicKey = [34 + ss58Length, 35 + ss58Length].includes(decoded.length); + const length = decoded.length - (isPublicKey ? 2 : 1); + const hash = sshash(decoded.subarray(0, length)); + const isValid = (decoded[0] & 0b1000_0000) === 0 && ![46, 47].includes(decoded[0]) && (isPublicKey + ? decoded[decoded.length - 2] === hash[0] && decoded[decoded.length - 1] === hash[1] + : decoded[decoded.length - 1] === hash[0]); + return [isValid, length, ss58Length, ss58Decoded]; + } + + const knownGenesis = { + acala: [ + '0xfc41b9bd8ef8fe53d58c7ea67c794c7ec9a73daf05e6d54b14ff6342c99ba64c' + ], + ajuna: [ + '0xe358eb1d11b31255a286c12e44fe6780b7edb171d657905a97e39f71d9c6c3ee' + ], + 'aleph-node': [ + '0x70255b4d28de0fc4e1a193d7e175ad1ccef431598211c55538f1018651a0344e' + ], + astar: [ + '0x9eb76c5184c4ab8679d2d5d819fdf90b9c001403e9e17da2e14b6d8aec4029c6' + ], + basilisk: [ + '0xa85cfb9b9fd4d622a5b28289a02347af987d8f73fa3108450e2b4a11c1ce5755' + ], + bifrost: [ + '0x262e1b2ad728475fd6fe88e62d34c200abe6fd693931ddad144059b1eb884e5b' + ], + 'bifrost-kusama': [ + '0x9f28c6a68e0fc9646eff64935684f6eeeece527e37bbe1f213d22caa1d9d6bed' + ], + bittensor: [ + '0x2f0555cc76fc2840a25a6ea3b9637146806f1f44b090c175ffde2a7e5ab36c03' + ], + centrifuge: [ + '0xb3db41421702df9a7fcac62b53ffeac85f7853cc4e689e0b93aeb3db18c09d82', + '0x67dddf2673b69e5f875f6f25277495834398eafd67f492e09f3f3345e003d1b5' + ], + cere: [ + '0x81443836a9a24caaa23f1241897d1235717535711d1d3fe24eae4fdc942c092c' + ], + composable: [ + '0xdaab8df776eb52ec604a5df5d388bb62a050a0aaec4556a64265b9d42755552d' + ], + creditcoin3: [ + '0x4436a7d64e363df85e065a894721002a86643283f9707338bf195d360ba2ee71', + '0xfc4ec97a1c1f119c4353aecb4a17c7c0cf7b40d5d660143d8bad9117e9866572', + '0xfc9df99a665f964aed6649f275055e54df5e3420489538ed31d7788f53d11ef6' + ], + darwinia: [ + '0xe71578b37a7c799b0ab4ee87ffa6f059a6b98f71f06fb8c84a8d88013a548ad6' + ], + dentnet: [ + '0x0313f6a011d128d22f996703cbab05162e2fdc9e031493314fe6db79979c5ca7' + ], + 'dock-mainnet': [ + '0x6bfe24dca2a3be10f22212678ac13a6446ec764103c0f3471c71609eac384aae', + '0xf73467c6544aa68df2ee546b135f955c46b90fa627e9b5d7935f41061bb8a5a9' + ], + edgeware: [ + '0x742a2ca70c2fda6cee4f8df98d64c4c670a052d9568058982dad9d5a7a135c5b' + ], + encointer: [ + '0x7dd99936c1e9e6d1ce7d90eb6f33bea8393b4bf87677d675aa63c9cb3e8c5b5b' + ], + enjin: [ + '0xd8761d3c88f26dc12875c00d3165f7d67243d56fc85b4cf19937601a7916e5a9' + ], + equilibrium: [ + '0x6f1a800de3daff7f5e037ddf66ab22ce03ab91874debeddb1086f5f7dbd48925' + ], + frequency: [ + '0x4a587bf17a404e3572747add7aab7bbe56e805a5479c6c436f07f36fcc8d3ae1' + ], + genshiro: [ + '0x9b8cefc0eb5c568b527998bdd76c184e2b76ae561be76e4667072230217ea243' + ], + hydradx: [ + '0xafdc188f45c71dacbaa0b62e16a91f726c7b8699a9748cdf715459de6b7f366d', + '0xd2a620c27ec5cbc5621ff9a522689895074f7cca0d08e7134a7804e1a3ba86fc', + '0x10af6e84234477d84dc572bac0789813b254aa490767ed06fb9591191d1073f9', + '0x3d75507dd46301767e601265791da1d9cb47b6ebc94e87347b635e5bf58bd047', + '0x0ed32bfcab4a83517fac88f2aa7cbc2f88d3ab93be9a12b6188a036bf8a943c2' + ], + integritee: [ + '0xcdedc8eadbfa209d3f207bba541e57c3c58a667b05a2e1d1e86353c9000758da', + '0xe13e7af377c64e83f95e0d70d5e5c3c01d697a84538776c5b9bbe0e7d7b6034c' + ], + 'interlay-parachain': [ + '0xbf88efe70e9e0e916416e8bed61f2b45717f517d7f3523e33c7b001e5ffcbc72' + ], + karura: [ + '0xbaf5aabe40646d11f0ee8abbdc64f4a4b7674925cba08e4a05ff9ebed6e2126b' + ], + khala: [ + '0xd43540ba6d3eb4897c28a77d48cb5b729fea37603cbbfc7a86a73b72adb3be8d' + ], + kulupu: [ + '0xf7a99d3cb92853d00d5275c971c132c074636256583fee53b3bbe60d7b8769ba' + ], + kusama: [ + '0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe', + '0xe3777fa922cafbff200cadeaea1a76bd7898ad5b89f7848999058b50e715f636', + '0x3fd7b9eb6a00376e5be61f01abb429ffb0b104be05eaff4d458da48fcd425baf' + ], + dicle: [ + '0xd9d3cd7c1e5d890d969b957f4c5b71a111bbeeabc968f1d0d4538c2663f080a7' + ], + liberland: [ + '0x6bd89e052d67a45bb60a9a23e8581053d5e0d619f15cb9865946937e690c42d6' + ], + matrixchain: [ + '0x3af4ff48ec76d2efc8476730f423ac07e25ad48f5f4c9dc39c778b164d808615' + ], + mythos: [ + '0xf6ee56e9c5277df5b4ce6ae9983ee88f3cbed27d31beeb98f9f84f997a1ab0b9' + ], + nodle: [ + '0x97da7ede98d7bad4e36b4d734b6055425a3be036da2a332ea5a7037656427a21' + ], + origintrail: [ + '0xe7e0962324a3b86c83404dbea483f25fb5dab4c224791c81b756cfc948006174' + ], + p3d: [ + '0x6c5894837ad89b6d92b114a2fb3eafa8fe3d26a54848e3447015442cd6ef4e66' + ], + parallel: [ + '0xe61a41c53f5dcd0beb09df93b34402aada44cb05117b71059cce40a2723a4e97' + ], + peaq: [ + '0xd2a5d385932d1f650dae03ef8e2748983779ee342c614f80854d32b8cd8fa48c' + ], + pendulum: [ + '0x5d3c298622d5634ed019bf61ea4b71655030015bde9beb0d6a24743714462c86' + ], + phala: [ + '0x1bb969d85965e4bb5a651abbedf21a54b6b31a21f66b5401cc3f1e286268d736' + ], + picasso: [ + '0x6811a339673c9daa897944dcdac99c6e2939cc88245ed21951a0a3c9a2be75bc', + '0xe8e7f0f4c4f5a00720b4821dbfddefea7490bcf0b19009961cc46957984e2c1c' + ], + polimec: [ + '0x7eb9354488318e7549c722669dcbdcdc526f1fef1420e7944667212f3601fdbd' + ], + polkadex: [ + '0x3920bcb4960a1eef5580cd5367ff3f430eef052774f78468852f7b9cb39f8a3c' + ], + polkadot: [ + '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3' + ], + pezkuwi: [ + '0x41693961995d879073269a008d0a52832caa3e0ae73869f02127f3d5daa4934c' + ], + polymesh: [ + '0x6fbd74e5e1d0a61d52ccfe9d4adaed16dd3a7caa37c6bc4d0c2fa12e8b2f4063' + ], + quartz: [ + '0xcd4d732201ebe5d6b014edda071c4203e16867305332301dc8d092044b28e554' + ], + rococo: [ + '0x6408de7737c59c238890533af25896a2c20608d8b380bb01029acb392781063e', + '0xaaf2cd1b74b5f726895921259421b534124726263982522174147046b8827897', + '0x037f5f3c8e67b314062025fc886fcd6238ea25a4a9b45dce8d246815c9ebe770', + '0xc196f81260cf1686172b47a79cf002120735d7cb0eb1474e8adce56618456fff', + '0xf6e9983c37baf68846fedafe21e56718790e39fb1c582abc408b81bc7b208f9a', + '0x5fce687da39305dfe682b117f0820b319348e8bb37eb16cf34acbf6a202de9d9', + '0xe7c3d5edde7db964317cd9b51a3a059d7cd99f81bdbce14990047354334c9779', + '0x1611e1dbf0405379b861e2e27daa90f480b2e6d3682414a80835a52e8cb8a215', + '0x343442f12fa715489a8714e79a7b264ea88c0d5b8c66b684a7788a516032f6b9', + '0x78bcd530c6b3a068bc17473cf5d2aff9c287102bed9af3ae3c41c33b9d6c6147', + '0x47381ee0697153d64404fc578392c8fd5cba9073391908f46c888498415647bd', + '0x19c0e4fa8ab75f5ac7865e0b8f74ff91eb9a100d336f423cd013a8befba40299' + ], + pezkuwichain: [ + '0x32154fd2c844f928c82964ff66168b41b15fc235f3a956d14393734c1ed4326b' + ], + sora: [ + '0x7e4e32d0feafd4f9c9414b0be86373f9a1efa904809b683453a9af6856d38ad5' + ], + stafi: [ + '0x290a4149f09ea0e402c74c1c7e96ae4239588577fe78932f94f5404c68243d80' + ], + statemine: [ + '0x48239ef607d7928874027a43a67689209727dfb3d3dc5e5b03a39bdc2eda771a' + ], + statemint: [ + '0x68d56f15f85d3136970ec16946040bc1752654e906147f7e43e9d539d7c3de2f' + ], + subsocial: [ + '0x0bd72c1c305172e1275278aaeb3f161e02eccb7a819e63f62d47bd53a28189f8' + ], + ternoa: [ + '0x6859c81ca95ef624c9dfe4dc6e3381c33e5d6509e35e147092bfbc780f777c4e' + ], + unique: [ + '0x84322d9cddbf35088f1e54e9a85c967a41a56a4f43445768125e61af166c7d31' + ], + vara: [ + '0xfe1b4c55fd4d668101126434206571a7838a8b6b93a6d1b95d607e78e6c53763' + ], + vtb: [ + '0x286bc8414c7000ce1d6ee6a834e29a54c1784814b76243eb77ed0b2c5573c60f', + '0x7483b89572fb2bd687c7b9a93b242d0b237f9aba463aba07ec24503931038aaa' + ], + westend: [ + '0xe143f23803ac50e8f6f8e62695d1ce9e4e1d68aa36c1cd2cfd15340213f3423e' + ], + zagros: [ + '0x297f5a4d105b4b28312586ff1915572ffe4ee015ff772b76399ecbff25a22026' + ], + xxnetwork: [ + '0x50dd5d206917bf10502c68fb4d18a59fc8aa31586f4e8856b493e43544aa82aa' + ], + zeitgeist: [ + '0x1bf2a2ecb4a868de66ea8610f2ce7c8c43706561b6476031315f6640fe38e060' + ] + }; + + const knownIcon = { + centrifuge: 'polkadot', + kusama: 'polkadot', + polkadot: 'polkadot', + sora: 'polkadot', + statemine: 'polkadot', + statemint: 'polkadot', + westmint: 'polkadot' + }; + + const knownLedger = { + acala: 0x00000313, + ajuna: 0x00000162, + 'aleph-node': 0x00000283, + astar: 0x0000032a, + bifrost: 0x00000314, + 'bifrost-kusama': 0x00000314, + bittensor: 0x00000162, + centrifuge: 0x000002eb, + composable: 0x00000162, + creditcoin3: 0x00000162, + darwinia: 0x00000162, + dentnet: 0x000002de, + 'dock-mainnet': 0x00000252, + edgeware: 0x0000020b, + encointer: 0x000001b2, + enjin: 0x00000483, + equilibrium: 0x05f5e0fd, + frequency: 0x0000082b, + genshiro: 0x05f5e0fc, + hydradx: 0x00000162, + integritee: 0x000007df, + 'interlay-parachain': 0x00000162, + karura: 0x000002ae, + khala: 0x000001b2, + kusama: 0x000001b2, + liberland: 0x000002ff, + matrixchain: 0x00000483, + mythos: 0x0000003c, + nodle: 0x000003eb, + origintrail: 0x00000162, + parallel: 0x00000162, + peaq: 0x00000d0a, + pendulum: 0x00000162, + phala: 0x00000162, + picasso: 0x000001b2, + polimec: 0x00000d10, + polkadex: 0x0000031f, + polkadot: 0x00000162, + polymesh: 0x00000253, + quartz: 0x00000277, + sora: 0x00000269, + stafi: 0x0000038b, + statemine: 0x000001b2, + statemint: 0x00000162, + ternoa: 0x00003e3, + unique: 0x00000295, + vara: 0x00001370, + vtb: 0x000002b6, + xxnetwork: 0x000007a3, + zeitgeist: 0x00000162 + }; + + const knownTestnet = { + '': true, + 'cess-testnet': true, + 'dock-testnet': true, + jupiter: true, + 'mathchain-testnet': true, + p3dt: true, + subspace_testnet: true, + 'zero-alphaville': true + }; + + const UNSORTED = [0, 2, 42]; + const TESTNETS = ['testnet']; + const customNetworks = [ + { + decimals: [10], + displayName: 'Pezkuwi Relay Chain', + network: 'pezkuwi', + prefix: 0, + standardAccount: '*25519', + symbols: ['PZW'], + website: 'https://pezkuwi.com' + }, + { + decimals: [12], + displayName: 'Zagros Relay Chain', + network: 'zagros', + prefix: 2, + standardAccount: '*25519', + symbols: ['ZGS'], + website: 'https://zagros.pezkuwi.com' + }, + { + decimals: [12], + displayName: 'Bizinikiwi', + network: 'bizinikiwi', + prefix: 42, + standardAccount: '*25519', + symbols: ['BZN'], + website: 'https://bizinikiwi.com' + }, + { + decimals: [18], + displayName: 'PezkuwiChain', + network: 'pezkuwichain', + prefix: 1453, + standardAccount: '*25519', + symbols: ['PZC'], + website: 'https://chain.pezkuwi.com' + } + ]; + function toExpanded(o) { + const network = o.network || ''; + const nameParts = network.replace(/_/g, '-').split('-'); + const n = o; + n.slip44 = knownLedger[network]; + n.hasLedgerSupport = !!n.slip44; + n.genesisHash = knownGenesis[network] || []; + n.icon = knownIcon[network] || 'substrate'; + n.isTestnet = !!knownTestnet[network] || TESTNETS.includes(nameParts[nameParts.length - 1]); + n.isIgnored = n.isTestnet || (!(o.standardAccount && + o.decimals?.length && + o.symbols?.length) && + o.prefix !== 42); + return n; + } + function filterSelectable({ genesisHash, prefix }) { + return !!genesisHash.length || prefix === 42; + } + function filterAvailable(n) { + return !n.isIgnored && !!n.network; + } + function sortNetworks(a, b) { + const isUnSortedA = UNSORTED.includes(a.prefix); + const isUnSortedB = UNSORTED.includes(b.prefix); + return isUnSortedA === isUnSortedB + ? isUnSortedA + ? 0 + : a.displayName.localeCompare(b.displayName) + : isUnSortedA + ? -1 + : 1; + } + const allNetworks = customNetworks.map(toExpanded); + const availableNetworks = allNetworks.filter(filterAvailable).sort(sortNetworks); + const selectableNetworks = availableNetworks.filter(filterSelectable); + + const defaults = { + allowedDecodedLengths: [1, 2, 4, 8, 32, 33], + allowedEncodedLengths: [3, 4, 6, 10, 35, 36, 37, 38], + allowedPrefix: availableNetworks.map(({ prefix }) => prefix), + prefix: 42 + }; + + function decodeAddress(encoded, ignoreChecksum, ss58Format = -1) { + if (!encoded) { + throw new Error('Invalid empty address passed'); + } + if (util.isU8a(encoded) || util.isHex(encoded)) { + return util.u8aToU8a(encoded); + } + try { + const decoded = base58Decode(encoded); + if (!defaults.allowedEncodedLengths.includes(decoded.length)) { + throw new Error('Invalid decoded address length'); + } + const [isValid, endPos, ss58Length, ss58Decoded] = checkAddressChecksum(decoded); + if (!isValid && !ignoreChecksum) { + throw new Error('Invalid decoded address checksum'); + } + else if (ss58Format !== -1 && ss58Format !== ss58Decoded) { + throw new Error(`Expected ss58Format ${ss58Format}, received ${ss58Decoded}`); + } + return decoded.slice(ss58Length, endPos); + } + catch (error) { + throw new Error(`Decoding ${encoded}: ${error.message}`); + } + } + + function addressToEvm(address, ignoreChecksum) { + return decodeAddress(address, ignoreChecksum).subarray(0, 20); + } + + function checkAddress(address, prefix) { + let decoded; + try { + decoded = base58Decode(address); + } + catch (error) { + return [false, error.message]; + } + const [isValid, , , ss58Decoded] = checkAddressChecksum(decoded); + if (ss58Decoded !== prefix) { + return [false, `Prefix mismatch, expected ${prefix}, found ${ss58Decoded}`]; + } + else if (!defaults.allowedEncodedLengths.includes(decoded.length)) { + return [false, 'Invalid decoded address length']; + } + return [isValid, isValid ? null : 'Invalid decoded address checksum']; + } + + const BN_BE_OPTS = { isLe: false }; + const BN_LE_OPTS = { isLe: true }; + const BN_LE_16_OPTS = { bitLength: 16, isLe: true }; + const BN_BE_32_OPTS = { bitLength: 32, isLe: false }; + const BN_LE_32_OPTS = { bitLength: 32, isLe: true }; + const BN_BE_256_OPTS = { bitLength: 256, isLe: false }; + const BN_LE_256_OPTS = { bitLength: 256, isLe: true }; + const BN_LE_512_OPTS = { bitLength: 512, isLe: true }; + + const RE_NUMBER = /^\d+$/; + const JUNCTION_ID_LEN = 32; + class DeriveJunction { + #chainCode = new Uint8Array(32); + #isHard = false; + static from(value) { + const result = new DeriveJunction(); + const [code, isHard] = value.startsWith('/') + ? [value.substring(1), true] + : [value, false]; + result.soft(RE_NUMBER.test(code) + ? new util.BN(code, 10) + : code); + return isHard + ? result.harden() + : result; + } + get chainCode() { + return this.#chainCode; + } + get isHard() { + return this.#isHard; + } + get isSoft() { + return !this.#isHard; + } + hard(value) { + return this.soft(value).harden(); + } + harden() { + this.#isHard = true; + return this; + } + soft(value) { + if (util.isNumber(value) || util.isBn(value) || util.isBigInt(value)) { + return this.soft(util.bnToU8a(value, BN_LE_256_OPTS)); + } + else if (util.isHex(value)) { + return this.soft(util.hexToU8a(value)); + } + else if (util.isString(value)) { + return this.soft(util.compactAddLength(util.stringToU8a(value))); + } + else if (value.length > JUNCTION_ID_LEN) { + return this.soft(blake2AsU8a(value)); + } + this.#chainCode.fill(0); + this.#chainCode.set(value, 0); + return this; + } + soften() { + this.#isHard = false; + return this; + } + } + + const RE_JUNCTION = /\/(\/?)([^/]+)/g; + function keyExtractPath(derivePath) { + const parts = derivePath.match(RE_JUNCTION); + const path = []; + let constructed = ''; + if (parts) { + constructed = parts.join(''); + for (const p of parts) { + path.push(DeriveJunction.from(p.substring(1))); + } + } + if (constructed !== derivePath) { + throw new Error(`Re-constructed path "${constructed}" does not match input`); + } + return { + parts, + path + }; + } + + const RE_CAPTURE = /^((0x[a-fA-F0-9]+|[\p{L}\d]+(?: [\p{L}\d]+)*))((\/\/?[^/]+)*)(\/\/\/(.*))?$/u; + function keyExtractSuri(suri) { + const normalizedSuri = suri.normalize('NFC'); + const matches = normalizedSuri.match(RE_CAPTURE); + if (matches === null) { + throw new Error('Unable to match provided value to a secret URI'); + } + const [, phrase, , derivePath, , , password] = matches; + const { path } = keyExtractPath(derivePath); + return { + derivePath, + password, + path, + phrase + }; + } + + const HDKD$2 = util.compactAddLength(util.stringToU8a('Secp256k1HDKD')); + function secp256k1DeriveHard(seed, chainCode) { + if (!util.isU8a(chainCode) || chainCode.length !== 32) { + throw new Error('Invalid chainCode passed to derive'); + } + return blake2AsU8a(util.u8aConcat(HDKD$2, seed, chainCode), 256); + } + + const SHA256_K = Uint32Array.from([ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + ]); + const SHA256_W = new Uint32Array(64); + class SHA256 extends HashMD { + constructor(outputLen = 32) { + super(64, outputLen, 8, false); + this.A = SHA256_IV[0] | 0; + this.B = SHA256_IV[1] | 0; + this.C = SHA256_IV[2] | 0; + this.D = SHA256_IV[3] | 0; + this.E = SHA256_IV[4] | 0; + this.F = SHA256_IV[5] | 0; + this.G = SHA256_IV[6] | 0; + this.H = SHA256_IV[7] | 0; + } + get() { + const { A, B, C, D, E, F, G, H } = this; + return [A, B, C, D, E, F, G, H]; + } + set(A, B, C, D, E, F, G, H) { + this.A = A | 0; + this.B = B | 0; + this.C = C | 0; + this.D = D | 0; + this.E = E | 0; + this.F = F | 0; + this.G = G | 0; + this.H = H | 0; + } + process(view, offset) { + for (let i = 0; i < 16; i++, offset += 4) + SHA256_W[i] = view.getUint32(offset, false); + for (let i = 16; i < 64; i++) { + const W15 = SHA256_W[i - 15]; + const W2 = SHA256_W[i - 2]; + const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3); + const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10); + SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0; + } + let { A, B, C, D, E, F, G, H } = this; + for (let i = 0; i < 64; i++) { + const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25); + const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0; + const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22); + const T2 = (sigma0 + Maj(A, B, C)) | 0; + H = G; + G = F; + F = E; + E = (D + T1) | 0; + D = C; + C = B; + B = A; + A = (T1 + T2) | 0; + } + A = (A + this.A) | 0; + B = (B + this.B) | 0; + C = (C + this.C) | 0; + D = (D + this.D) | 0; + E = (E + this.E) | 0; + F = (F + this.F) | 0; + G = (G + this.G) | 0; + H = (H + this.H) | 0; + this.set(A, B, C, D, E, F, G, H); + } + roundClean() { + clean(SHA256_W); + } + destroy() { + this.set(0, 0, 0, 0, 0, 0, 0, 0); + clean(this.buffer); + } + } + class SHA224 extends SHA256 { + constructor() { + super(28); + this.A = SHA224_IV[0] | 0; + this.B = SHA224_IV[1] | 0; + this.C = SHA224_IV[2] | 0; + this.D = SHA224_IV[3] | 0; + this.E = SHA224_IV[4] | 0; + this.F = SHA224_IV[5] | 0; + this.G = SHA224_IV[6] | 0; + this.H = SHA224_IV[7] | 0; + } + } + const K512 = (() => split([ + '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc', + '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118', + '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2', + '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694', + '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65', + '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5', + '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4', + '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70', + '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df', + '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b', + '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30', + '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8', + '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8', + '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3', + '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec', + '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b', + '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178', + '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b', + '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c', + '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817' + ].map(n => BigInt(n))))(); + const SHA512_Kh = (() => K512[0])(); + const SHA512_Kl = (() => K512[1])(); + const SHA512_W_H = new Uint32Array(80); + const SHA512_W_L = new Uint32Array(80); + class SHA512 extends HashMD { + constructor(outputLen = 64) { + super(128, outputLen, 16, false); + this.Ah = SHA512_IV[0] | 0; + this.Al = SHA512_IV[1] | 0; + this.Bh = SHA512_IV[2] | 0; + this.Bl = SHA512_IV[3] | 0; + this.Ch = SHA512_IV[4] | 0; + this.Cl = SHA512_IV[5] | 0; + this.Dh = SHA512_IV[6] | 0; + this.Dl = SHA512_IV[7] | 0; + this.Eh = SHA512_IV[8] | 0; + this.El = SHA512_IV[9] | 0; + this.Fh = SHA512_IV[10] | 0; + this.Fl = SHA512_IV[11] | 0; + this.Gh = SHA512_IV[12] | 0; + this.Gl = SHA512_IV[13] | 0; + this.Hh = SHA512_IV[14] | 0; + this.Hl = SHA512_IV[15] | 0; + } + get() { + const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this; + return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl]; + } + set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) { + this.Ah = Ah | 0; + this.Al = Al | 0; + this.Bh = Bh | 0; + this.Bl = Bl | 0; + this.Ch = Ch | 0; + this.Cl = Cl | 0; + this.Dh = Dh | 0; + this.Dl = Dl | 0; + this.Eh = Eh | 0; + this.El = El | 0; + this.Fh = Fh | 0; + this.Fl = Fl | 0; + this.Gh = Gh | 0; + this.Gl = Gl | 0; + this.Hh = Hh | 0; + this.Hl = Hl | 0; + } + process(view, offset) { + for (let i = 0; i < 16; i++, offset += 4) { + SHA512_W_H[i] = view.getUint32(offset); + SHA512_W_L[i] = view.getUint32((offset += 4)); + } + for (let i = 16; i < 80; i++) { + const W15h = SHA512_W_H[i - 15] | 0; + const W15l = SHA512_W_L[i - 15] | 0; + const s0h = rotrSH(W15h, W15l, 1) ^ rotrSH(W15h, W15l, 8) ^ shrSH(W15h, W15l, 7); + const s0l = rotrSL(W15h, W15l, 1) ^ rotrSL(W15h, W15l, 8) ^ shrSL(W15h, W15l, 7); + const W2h = SHA512_W_H[i - 2] | 0; + const W2l = SHA512_W_L[i - 2] | 0; + const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6); + const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6); + const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]); + const SUMh = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]); + SHA512_W_H[i] = SUMh | 0; + SHA512_W_L[i] = SUMl | 0; + } + let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this; + for (let i = 0; i < 80; i++) { + const sigma1h = rotrSH(Eh, El, 14) ^ rotrSH(Eh, El, 18) ^ rotrBH(Eh, El, 41); + const sigma1l = rotrSL(Eh, El, 14) ^ rotrSL(Eh, El, 18) ^ rotrBL(Eh, El, 41); + const CHIh = (Eh & Fh) ^ (~Eh & Gh); + const CHIl = (El & Fl) ^ (~El & Gl); + const T1ll = add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]); + const T1h = add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]); + const T1l = T1ll | 0; + const sigma0h = rotrSH(Ah, Al, 28) ^ rotrBH(Ah, Al, 34) ^ rotrBH(Ah, Al, 39); + const sigma0l = rotrSL(Ah, Al, 28) ^ rotrBL(Ah, Al, 34) ^ rotrBL(Ah, Al, 39); + const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch); + const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl); + Hh = Gh | 0; + Hl = Gl | 0; + Gh = Fh | 0; + Gl = Fl | 0; + Fh = Eh | 0; + Fl = El | 0; + ({ h: Eh, l: El } = add(Dh | 0, Dl | 0, T1h | 0, T1l | 0)); + Dh = Ch | 0; + Dl = Cl | 0; + Ch = Bh | 0; + Cl = Bl | 0; + Bh = Ah | 0; + Bl = Al | 0; + const All = add3L(T1l, sigma0l, MAJl); + Ah = add3H(All, T1h, sigma0h, MAJh); + Al = All | 0; + } + ({ h: Ah, l: Al } = add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0)); + ({ h: Bh, l: Bl } = add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0)); + ({ h: Ch, l: Cl } = add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0)); + ({ h: Dh, l: Dl } = add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0)); + ({ h: Eh, l: El } = add(this.Eh | 0, this.El | 0, Eh | 0, El | 0)); + ({ h: Fh, l: Fl } = add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0)); + ({ h: Gh, l: Gl } = add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0)); + ({ h: Hh, l: Hl } = add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0)); + this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl); + } + roundClean() { + clean(SHA512_W_H, SHA512_W_L); + } + destroy() { + clean(this.buffer); + this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + } + } + class SHA384 extends SHA512 { + constructor() { + super(48); + this.Ah = SHA384_IV[0] | 0; + this.Al = SHA384_IV[1] | 0; + this.Bh = SHA384_IV[2] | 0; + this.Bl = SHA384_IV[3] | 0; + this.Ch = SHA384_IV[4] | 0; + this.Cl = SHA384_IV[5] | 0; + this.Dh = SHA384_IV[6] | 0; + this.Dl = SHA384_IV[7] | 0; + this.Eh = SHA384_IV[8] | 0; + this.El = SHA384_IV[9] | 0; + this.Fh = SHA384_IV[10] | 0; + this.Fl = SHA384_IV[11] | 0; + this.Gh = SHA384_IV[12] | 0; + this.Gl = SHA384_IV[13] | 0; + this.Hh = SHA384_IV[14] | 0; + this.Hl = SHA384_IV[15] | 0; + } + } + const T224_IV = Uint32Array.from([ + 0x8c3d37c8, 0x19544da2, 0x73e19966, 0x89dcd4d6, 0x1dfab7ae, 0x32ff9c82, 0x679dd514, 0x582f9fcf, + 0x0f6d2b69, 0x7bd44da8, 0x77e36f73, 0x04c48942, 0x3f9d85a8, 0x6a1d36c8, 0x1112e6ad, 0x91d692a1, + ]); + const T256_IV = Uint32Array.from([ + 0x22312194, 0xfc2bf72c, 0x9f555fa3, 0xc84c64c2, 0x2393b86b, 0x6f53b151, 0x96387719, 0x5940eabd, + 0x96283ee2, 0xa88effe3, 0xbe5e1e25, 0x53863992, 0x2b0199fc, 0x2c85b8aa, 0x0eb72ddc, 0x81c52ca2, + ]); + class SHA512_224 extends SHA512 { + constructor() { + super(28); + this.Ah = T224_IV[0] | 0; + this.Al = T224_IV[1] | 0; + this.Bh = T224_IV[2] | 0; + this.Bl = T224_IV[3] | 0; + this.Ch = T224_IV[4] | 0; + this.Cl = T224_IV[5] | 0; + this.Dh = T224_IV[6] | 0; + this.Dl = T224_IV[7] | 0; + this.Eh = T224_IV[8] | 0; + this.El = T224_IV[9] | 0; + this.Fh = T224_IV[10] | 0; + this.Fl = T224_IV[11] | 0; + this.Gh = T224_IV[12] | 0; + this.Gl = T224_IV[13] | 0; + this.Hh = T224_IV[14] | 0; + this.Hl = T224_IV[15] | 0; + } + } + class SHA512_256 extends SHA512 { + constructor() { + super(32); + this.Ah = T256_IV[0] | 0; + this.Al = T256_IV[1] | 0; + this.Bh = T256_IV[2] | 0; + this.Bl = T256_IV[3] | 0; + this.Ch = T256_IV[4] | 0; + this.Cl = T256_IV[5] | 0; + this.Dh = T256_IV[6] | 0; + this.Dl = T256_IV[7] | 0; + this.Eh = T256_IV[8] | 0; + this.El = T256_IV[9] | 0; + this.Fh = T256_IV[10] | 0; + this.Fl = T256_IV[11] | 0; + this.Gh = T256_IV[12] | 0; + this.Gl = T256_IV[13] | 0; + this.Hh = T256_IV[14] | 0; + this.Hl = T256_IV[15] | 0; + } + } + const sha256$1 = createHasher$1(() => new SHA256()); + createHasher$1(() => new SHA224()); + const sha512$1 = createHasher$1(() => new SHA512()); + createHasher$1(() => new SHA384()); + createHasher$1(() => new SHA512_256()); + createHasher$1(() => new SHA512_224()); + + class HMAC extends Hash { + constructor(hash, _key) { + super(); + this.finished = false; + this.destroyed = false; + ahash(hash); + const key = toBytes(_key); + this.iHash = hash.create(); + if (typeof this.iHash.update !== 'function') + throw new Error('Expected instance of class which extends utils.Hash'); + this.blockLen = this.iHash.blockLen; + this.outputLen = this.iHash.outputLen; + const blockLen = this.blockLen; + const pad = new Uint8Array(blockLen); + pad.set(key.length > blockLen ? hash.create().update(key).digest() : key); + for (let i = 0; i < pad.length; i++) + pad[i] ^= 0x36; + this.iHash.update(pad); + this.oHash = hash.create(); + for (let i = 0; i < pad.length; i++) + pad[i] ^= 0x36 ^ 0x5c; + this.oHash.update(pad); + clean(pad); + } + update(buf) { + aexists(this); + this.iHash.update(buf); + return this; + } + digestInto(out) { + aexists(this); + abytes$1(out, this.outputLen); + this.finished = true; + this.iHash.digestInto(out); + this.oHash.update(out); + this.oHash.digestInto(out); + this.destroy(); + } + digest() { + const out = new Uint8Array(this.oHash.outputLen); + this.digestInto(out); + return out; + } + _cloneInto(to) { + to || (to = Object.create(Object.getPrototypeOf(this), {})); + const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this; + to = to; + to.finished = finished; + to.destroyed = destroyed; + to.blockLen = blockLen; + to.outputLen = outputLen; + to.oHash = oHash._cloneInto(to.oHash); + to.iHash = iHash._cloneInto(to.iHash); + return to; + } + clone() { + return this._cloneInto(); + } + destroy() { + this.destroyed = true; + this.oHash.destroy(); + this.iHash.destroy(); + } + } + const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest(); + hmac.create = (hash, key) => new HMAC(hash, key); + + /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ + const _0n$9 = BigInt(0); + const _1n$8 = BigInt(1); + function _abool2(value, title = '') { + if (typeof value !== 'boolean') { + const prefix = title && `"${title}"`; + throw new Error(prefix + 'expected boolean, got type=' + typeof value); + } + return value; + } + function _abytes2(value, length, title = '') { + const bytes = isBytes$1(value); + const len = value?.length; + const needsLen = length !== undefined; + if (!bytes || (needsLen && len !== length)) { + const prefix = title && `"${title}" `; + const ofLen = needsLen ? ` of length ${length}` : ''; + const got = bytes ? `length=${len}` : `type=${typeof value}`; + throw new Error(prefix + 'expected Uint8Array' + ofLen + ', got ' + got); + } + return value; + } + function numberToHexUnpadded(num) { + const hex = num.toString(16); + return hex.length & 1 ? '0' + hex : hex; + } + function hexToNumber(hex) { + if (typeof hex !== 'string') + throw new Error('hex string expected, got ' + typeof hex); + return hex === '' ? _0n$9 : BigInt('0x' + hex); + } + function bytesToNumberBE(bytes) { + return hexToNumber(bytesToHex(bytes)); + } + function bytesToNumberLE$1(bytes) { + abytes$1(bytes); + return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse())); + } + function numberToBytesBE(n, len) { + return hexToBytes(n.toString(16).padStart(len * 2, '0')); + } + function numberToBytesLE$1(n, len) { + return numberToBytesBE(n, len).reverse(); + } + function ensureBytes(title, hex, expectedLength) { + let res; + if (typeof hex === 'string') { + try { + res = hexToBytes(hex); + } + catch (e) { + throw new Error(title + ' must be hex string or Uint8Array, cause: ' + e); + } + } + else if (isBytes$1(hex)) { + res = Uint8Array.from(hex); + } + else { + throw new Error(title + ' must be hex string or Uint8Array'); + } + const len = res.length; + if (typeof expectedLength === 'number' && len !== expectedLength) + throw new Error(title + ' of length ' + expectedLength + ' expected, got ' + len); + return res; + } + function equalBytes(a, b) { + if (a.length !== b.length) + return false; + let diff = 0; + for (let i = 0; i < a.length; i++) + diff |= a[i] ^ b[i]; + return diff === 0; + } + function copyBytes(bytes) { + return Uint8Array.from(bytes); + } + const isPosBig = (n) => typeof n === 'bigint' && _0n$9 <= n; + function inRange(n, min, max) { + return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max; + } + function aInRange$1(title, n, min, max) { + if (!inRange(n, min, max)) + throw new Error('expected valid ' + title + ': ' + min + ' <= n < ' + max + ', got ' + n); + } + function bitLen(n) { + let len; + for (len = 0; n > _0n$9; n >>= _1n$8, len += 1) + ; + return len; + } + const bitMask$1 = (n) => (_1n$8 << BigInt(n)) - _1n$8; + function createHmacDrbg(hashLen, qByteLen, hmacFn) { + if (typeof hashLen !== 'number' || hashLen < 2) + throw new Error('hashLen must be a number'); + if (typeof qByteLen !== 'number' || qByteLen < 2) + throw new Error('qByteLen must be a number'); + if (typeof hmacFn !== 'function') + throw new Error('hmacFn must be a function'); + const u8n = (len) => new Uint8Array(len); + const u8of = (byte) => Uint8Array.of(byte); + let v = u8n(hashLen); + let k = u8n(hashLen); + let i = 0; + const reset = () => { + v.fill(1); + k.fill(0); + i = 0; + }; + const h = (...b) => hmacFn(k, v, ...b); + const reseed = (seed = u8n(0)) => { + k = h(u8of(0x00), seed); + v = h(); + if (seed.length === 0) + return; + k = h(u8of(0x01), seed); + v = h(); + }; + const gen = () => { + if (i++ >= 1000) + throw new Error('drbg: tried 1000 values'); + let len = 0; + const out = []; + while (len < qByteLen) { + v = h(); + const sl = v.slice(); + out.push(sl); + len += v.length; + } + return concatBytes(...out); + }; + const genUntil = (seed, pred) => { + reset(); + reseed(seed); + let res = undefined; + while (!(res = pred(gen()))) + reseed(); + reset(); + return res; + }; + return genUntil; + } + function isHash(val) { + return typeof val === 'function' && Number.isSafeInteger(val.outputLen); + } + function _validateObject(object, fields, optFields = {}) { + if (!object || typeof object !== 'object') + throw new Error('expected valid options object'); + function checkField(fieldName, expectedType, isOpt) { + const val = object[fieldName]; + if (isOpt && val === undefined) + return; + const current = typeof val; + if (current !== expectedType || val === null) + throw new Error(`param "${fieldName}" is invalid: expected ${expectedType}, got ${current}`); + } + Object.entries(fields).forEach(([k, v]) => checkField(k, v, false)); + Object.entries(optFields).forEach(([k, v]) => checkField(k, v, true)); + } + const notImplemented = () => { + throw new Error('not implemented'); + }; + function memoized(fn) { + const map = new WeakMap(); + return (arg, ...args) => { + const val = map.get(arg); + if (val !== undefined) + return val; + const computed = fn(arg, ...args); + map.set(arg, computed); + return computed; + }; + } + + /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ + const _0n$8 = BigInt(0), _1n$7 = BigInt(1), _2n$6 = BigInt(2), _3n$3 = BigInt(3); + const _4n$1 = BigInt(4), _5n$1 = BigInt(5), _7n$2 = BigInt(7); + const _8n$2 = BigInt(8), _9n = BigInt(9), _16n$1 = BigInt(16); + function mod(a, b) { + const result = a % b; + return result >= _0n$8 ? result : b + result; + } + function pow2(x, power, modulo) { + let res = x; + while (power-- > _0n$8) { + res *= res; + res %= modulo; + } + return res; + } + function invert(number, modulo) { + if (number === _0n$8) + throw new Error('invert: expected non-zero number'); + if (modulo <= _0n$8) + throw new Error('invert: expected positive modulus, got ' + modulo); + let a = mod(number, modulo); + let b = modulo; + let x = _0n$8, u = _1n$7; + while (a !== _0n$8) { + const q = b / a; + const r = b % a; + const m = x - u * q; + b = a, a = r, x = u, u = m; + } + const gcd = b; + if (gcd !== _1n$7) + throw new Error('invert: does not exist'); + return mod(x, modulo); + } + function assertIsSquare(Fp, root, n) { + if (!Fp.eql(Fp.sqr(root), n)) + throw new Error('Cannot find square root'); + } + function sqrt3mod4(Fp, n) { + const p1div4 = (Fp.ORDER + _1n$7) / _4n$1; + const root = Fp.pow(n, p1div4); + assertIsSquare(Fp, root, n); + return root; + } + function sqrt5mod8(Fp, n) { + const p5div8 = (Fp.ORDER - _5n$1) / _8n$2; + const n2 = Fp.mul(n, _2n$6); + const v = Fp.pow(n2, p5div8); + const nv = Fp.mul(n, v); + const i = Fp.mul(Fp.mul(nv, _2n$6), v); + const root = Fp.mul(nv, Fp.sub(i, Fp.ONE)); + assertIsSquare(Fp, root, n); + return root; + } + function sqrt9mod16(P) { + const Fp_ = Field(P); + const tn = tonelliShanks(P); + const c1 = tn(Fp_, Fp_.neg(Fp_.ONE)); + const c2 = tn(Fp_, c1); + const c3 = tn(Fp_, Fp_.neg(c1)); + const c4 = (P + _7n$2) / _16n$1; + return (Fp, n) => { + let tv1 = Fp.pow(n, c4); + let tv2 = Fp.mul(tv1, c1); + const tv3 = Fp.mul(tv1, c2); + const tv4 = Fp.mul(tv1, c3); + const e1 = Fp.eql(Fp.sqr(tv2), n); + const e2 = Fp.eql(Fp.sqr(tv3), n); + tv1 = Fp.cmov(tv1, tv2, e1); + tv2 = Fp.cmov(tv4, tv3, e2); + const e3 = Fp.eql(Fp.sqr(tv2), n); + const root = Fp.cmov(tv1, tv2, e3); + assertIsSquare(Fp, root, n); + return root; + }; + } + function tonelliShanks(P) { + if (P < _3n$3) + throw new Error('sqrt is not defined for small field'); + let Q = P - _1n$7; + let S = 0; + while (Q % _2n$6 === _0n$8) { + Q /= _2n$6; + S++; + } + let Z = _2n$6; + const _Fp = Field(P); + while (FpLegendre(_Fp, Z) === 1) { + if (Z++ > 1000) + throw new Error('Cannot find square root: probably non-prime P'); + } + if (S === 1) + return sqrt3mod4; + let cc = _Fp.pow(Z, Q); + const Q1div2 = (Q + _1n$7) / _2n$6; + return function tonelliSlow(Fp, n) { + if (Fp.is0(n)) + return n; + if (FpLegendre(Fp, n) !== 1) + throw new Error('Cannot find square root'); + let M = S; + let c = Fp.mul(Fp.ONE, cc); + let t = Fp.pow(n, Q); + let R = Fp.pow(n, Q1div2); + while (!Fp.eql(t, Fp.ONE)) { + if (Fp.is0(t)) + return Fp.ZERO; + let i = 1; + let t_tmp = Fp.sqr(t); + while (!Fp.eql(t_tmp, Fp.ONE)) { + i++; + t_tmp = Fp.sqr(t_tmp); + if (i === M) + throw new Error('Cannot find square root'); + } + const exponent = _1n$7 << BigInt(M - i - 1); + const b = Fp.pow(c, exponent); + M = i; + c = Fp.sqr(b); + t = Fp.mul(t, c); + R = Fp.mul(R, b); + } + return R; + }; + } + function FpSqrt(P) { + if (P % _4n$1 === _3n$3) + return sqrt3mod4; + if (P % _8n$2 === _5n$1) + return sqrt5mod8; + if (P % _16n$1 === _9n) + return sqrt9mod16(P); + return tonelliShanks(P); + } + const isNegativeLE = (num, modulo) => (mod(num, modulo) & _1n$7) === _1n$7; + const FIELD_FIELDS = [ + 'create', 'isValid', 'is0', 'neg', 'inv', 'sqrt', 'sqr', + 'eql', 'add', 'sub', 'mul', 'pow', 'div', + 'addN', 'subN', 'mulN', 'sqrN' + ]; + function validateField(field) { + const initial = { + ORDER: 'bigint', + MASK: 'bigint', + BYTES: 'number', + BITS: 'number', + }; + const opts = FIELD_FIELDS.reduce((map, val) => { + map[val] = 'function'; + return map; + }, initial); + _validateObject(field, opts); + return field; + } + function FpPow(Fp, num, power) { + if (power < _0n$8) + throw new Error('invalid exponent, negatives unsupported'); + if (power === _0n$8) + return Fp.ONE; + if (power === _1n$7) + return num; + let p = Fp.ONE; + let d = num; + while (power > _0n$8) { + if (power & _1n$7) + p = Fp.mul(p, d); + d = Fp.sqr(d); + power >>= _1n$7; + } + return p; + } + function FpInvertBatch(Fp, nums, passZero = false) { + const inverted = new Array(nums.length).fill(passZero ? Fp.ZERO : undefined); + const multipliedAcc = nums.reduce((acc, num, i) => { + if (Fp.is0(num)) + return acc; + inverted[i] = acc; + return Fp.mul(acc, num); + }, Fp.ONE); + const invertedAcc = Fp.inv(multipliedAcc); + nums.reduceRight((acc, num, i) => { + if (Fp.is0(num)) + return acc; + inverted[i] = Fp.mul(acc, inverted[i]); + return Fp.mul(acc, num); + }, invertedAcc); + return inverted; + } + function FpLegendre(Fp, n) { + const p1mod2 = (Fp.ORDER - _1n$7) / _2n$6; + const powered = Fp.pow(n, p1mod2); + const yes = Fp.eql(powered, Fp.ONE); + const zero = Fp.eql(powered, Fp.ZERO); + const no = Fp.eql(powered, Fp.neg(Fp.ONE)); + if (!yes && !zero && !no) + throw new Error('invalid Legendre symbol result'); + return yes ? 1 : zero ? 0 : -1; + } + function nLength(n, nBitLength) { + if (nBitLength !== undefined) + anumber(nBitLength); + const _nBitLength = nBitLength !== undefined ? nBitLength : n.toString(2).length; + const nByteLength = Math.ceil(_nBitLength / 8); + return { nBitLength: _nBitLength, nByteLength }; + } + function Field(ORDER, bitLenOrOpts, + isLE = false, opts = {}) { + if (ORDER <= _0n$8) + throw new Error('invalid field: expected ORDER > 0, got ' + ORDER); + let _nbitLength = undefined; + let _sqrt = undefined; + let modFromBytes = false; + let allowedLengths = undefined; + if (typeof bitLenOrOpts === 'object' && bitLenOrOpts != null) { + if (opts.sqrt || isLE) + throw new Error('cannot specify opts in two arguments'); + const _opts = bitLenOrOpts; + if (_opts.BITS) + _nbitLength = _opts.BITS; + if (_opts.sqrt) + _sqrt = _opts.sqrt; + if (typeof _opts.isLE === 'boolean') + isLE = _opts.isLE; + if (typeof _opts.modFromBytes === 'boolean') + modFromBytes = _opts.modFromBytes; + allowedLengths = _opts.allowedLengths; + } + else { + if (typeof bitLenOrOpts === 'number') + _nbitLength = bitLenOrOpts; + if (opts.sqrt) + _sqrt = opts.sqrt; + } + const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, _nbitLength); + if (BYTES > 2048) + throw new Error('invalid field: expected ORDER of <= 2048 bytes'); + let sqrtP; + const f = Object.freeze({ + ORDER, + isLE, + BITS, + BYTES, + MASK: bitMask$1(BITS), + ZERO: _0n$8, + ONE: _1n$7, + allowedLengths: allowedLengths, + create: (num) => mod(num, ORDER), + isValid: (num) => { + if (typeof num !== 'bigint') + throw new Error('invalid field element: expected bigint, got ' + typeof num); + return _0n$8 <= num && num < ORDER; + }, + is0: (num) => num === _0n$8, + isValidNot0: (num) => !f.is0(num) && f.isValid(num), + isOdd: (num) => (num & _1n$7) === _1n$7, + neg: (num) => mod(-num, ORDER), + eql: (lhs, rhs) => lhs === rhs, + sqr: (num) => mod(num * num, ORDER), + add: (lhs, rhs) => mod(lhs + rhs, ORDER), + sub: (lhs, rhs) => mod(lhs - rhs, ORDER), + mul: (lhs, rhs) => mod(lhs * rhs, ORDER), + pow: (num, power) => FpPow(f, num, power), + div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER), + sqrN: (num) => num * num, + addN: (lhs, rhs) => lhs + rhs, + subN: (lhs, rhs) => lhs - rhs, + mulN: (lhs, rhs) => lhs * rhs, + inv: (num) => invert(num, ORDER), + sqrt: _sqrt || + ((n) => { + if (!sqrtP) + sqrtP = FpSqrt(ORDER); + return sqrtP(f, n); + }), + toBytes: (num) => (isLE ? numberToBytesLE$1(num, BYTES) : numberToBytesBE(num, BYTES)), + fromBytes: (bytes, skipValidation = true) => { + if (allowedLengths) { + if (!allowedLengths.includes(bytes.length) || bytes.length > BYTES) { + throw new Error('Field.fromBytes: expected ' + allowedLengths + ' bytes, got ' + bytes.length); + } + const padded = new Uint8Array(BYTES); + padded.set(bytes, isLE ? 0 : padded.length - bytes.length); + bytes = padded; + } + if (bytes.length !== BYTES) + throw new Error('Field.fromBytes: expected ' + BYTES + ' bytes, got ' + bytes.length); + let scalar = isLE ? bytesToNumberLE$1(bytes) : bytesToNumberBE(bytes); + if (modFromBytes) + scalar = mod(scalar, ORDER); + if (!skipValidation) + if (!f.isValid(scalar)) + throw new Error('invalid field element: outside of range 0..ORDER'); + return scalar; + }, + invertBatch: (lst) => FpInvertBatch(f, lst), + cmov: (a, b, c) => (c ? b : a), + }); + return Object.freeze(f); + } + function FpSqrtEven(Fp, elm) { + if (!Fp.isOdd) + throw new Error("Field doesn't have isOdd"); + const root = Fp.sqrt(elm); + return Fp.isOdd(root) ? Fp.neg(root) : root; + } + function getFieldBytesLength(fieldOrder) { + if (typeof fieldOrder !== 'bigint') + throw new Error('field order must be bigint'); + const bitLength = fieldOrder.toString(2).length; + return Math.ceil(bitLength / 8); + } + function getMinHashLength(fieldOrder) { + const length = getFieldBytesLength(fieldOrder); + return length + Math.ceil(length / 2); + } + function mapHashToField(key, fieldOrder, isLE = false) { + const len = key.length; + const fieldLen = getFieldBytesLength(fieldOrder); + const minLen = getMinHashLength(fieldOrder); + if (len < 16 || len < minLen || len > 1024) + throw new Error('expected ' + minLen + '-1024 bytes of input, got ' + len); + const num = isLE ? bytesToNumberLE$1(key) : bytesToNumberBE(key); + const reduced = mod(num, fieldOrder - _1n$7) + _1n$7; + return isLE ? numberToBytesLE$1(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen); + } + + /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ + const _0n$7 = BigInt(0); + const _1n$6 = BigInt(1); + function negateCt(condition, item) { + const neg = item.negate(); + return condition ? neg : item; + } + function normalizeZ(c, points) { + const invertedZs = FpInvertBatch(c.Fp, points.map((p) => p.Z)); + return points.map((p, i) => c.fromAffine(p.toAffine(invertedZs[i]))); + } + function validateW(W, bits) { + if (!Number.isSafeInteger(W) || W <= 0 || W > bits) + throw new Error('invalid window size, expected [1..' + bits + '], got W=' + W); + } + function calcWOpts(W, scalarBits) { + validateW(W, scalarBits); + const windows = Math.ceil(scalarBits / W) + 1; + const windowSize = 2 ** (W - 1); + const maxNumber = 2 ** W; + const mask = bitMask$1(W); + const shiftBy = BigInt(W); + return { windows, windowSize, mask, maxNumber, shiftBy }; + } + function calcOffsets(n, window, wOpts) { + const { windowSize, mask, maxNumber, shiftBy } = wOpts; + let wbits = Number(n & mask); + let nextN = n >> shiftBy; + if (wbits > windowSize) { + wbits -= maxNumber; + nextN += _1n$6; + } + const offsetStart = window * windowSize; + const offset = offsetStart + Math.abs(wbits) - 1; + const isZero = wbits === 0; + const isNeg = wbits < 0; + const isNegF = window % 2 !== 0; + const offsetF = offsetStart; + return { nextN, offset, isZero, isNeg, isNegF, offsetF }; + } + function validateMSMPoints(points, c) { + if (!Array.isArray(points)) + throw new Error('array expected'); + points.forEach((p, i) => { + if (!(p instanceof c)) + throw new Error('invalid point at index ' + i); + }); + } + function validateMSMScalars(scalars, field) { + if (!Array.isArray(scalars)) + throw new Error('array of scalars expected'); + scalars.forEach((s, i) => { + if (!field.isValid(s)) + throw new Error('invalid scalar at index ' + i); + }); + } + const pointPrecomputes = new WeakMap(); + const pointWindowSizes = new WeakMap(); + function getW(P) { + return pointWindowSizes.get(P) || 1; + } + function assert0(n) { + if (n !== _0n$7) + throw new Error('invalid wNAF'); + } + class wNAF { + constructor(Point, bits) { + this.BASE = Point.BASE; + this.ZERO = Point.ZERO; + this.Fn = Point.Fn; + this.bits = bits; + } + _unsafeLadder(elm, n, p = this.ZERO) { + let d = elm; + while (n > _0n$7) { + if (n & _1n$6) + p = p.add(d); + d = d.double(); + n >>= _1n$6; + } + return p; + } + precomputeWindow(point, W) { + const { windows, windowSize } = calcWOpts(W, this.bits); + const points = []; + let p = point; + let base = p; + for (let window = 0; window < windows; window++) { + base = p; + points.push(base); + for (let i = 1; i < windowSize; i++) { + base = base.add(p); + points.push(base); + } + p = base.double(); + } + return points; + } + wNAF(W, precomputes, n) { + if (!this.Fn.isValid(n)) + throw new Error('invalid scalar'); + let p = this.ZERO; + let f = this.BASE; + const wo = calcWOpts(W, this.bits); + for (let window = 0; window < wo.windows; window++) { + const { nextN, offset, isZero, isNeg, isNegF, offsetF } = calcOffsets(n, window, wo); + n = nextN; + if (isZero) { + f = f.add(negateCt(isNegF, precomputes[offsetF])); + } + else { + p = p.add(negateCt(isNeg, precomputes[offset])); + } + } + assert0(n); + return { p, f }; + } + wNAFUnsafe(W, precomputes, n, acc = this.ZERO) { + const wo = calcWOpts(W, this.bits); + for (let window = 0; window < wo.windows; window++) { + if (n === _0n$7) + break; + const { nextN, offset, isZero, isNeg } = calcOffsets(n, window, wo); + n = nextN; + if (isZero) { + continue; + } + else { + const item = precomputes[offset]; + acc = acc.add(isNeg ? item.negate() : item); + } + } + assert0(n); + return acc; + } + getPrecomputes(W, point, transform) { + let comp = pointPrecomputes.get(point); + if (!comp) { + comp = this.precomputeWindow(point, W); + if (W !== 1) { + if (typeof transform === 'function') + comp = transform(comp); + pointPrecomputes.set(point, comp); + } + } + return comp; + } + cached(point, scalar, transform) { + const W = getW(point); + return this.wNAF(W, this.getPrecomputes(W, point, transform), scalar); + } + unsafe(point, scalar, transform, prev) { + const W = getW(point); + if (W === 1) + return this._unsafeLadder(point, scalar, prev); + return this.wNAFUnsafe(W, this.getPrecomputes(W, point, transform), scalar, prev); + } + createCache(P, W) { + validateW(W, this.bits); + pointWindowSizes.set(P, W); + pointPrecomputes.delete(P); + } + hasCache(elm) { + return getW(elm) !== 1; + } + } + function mulEndoUnsafe(Point, point, k1, k2) { + let acc = point; + let p1 = Point.ZERO; + let p2 = Point.ZERO; + while (k1 > _0n$7 || k2 > _0n$7) { + if (k1 & _1n$6) + p1 = p1.add(acc); + if (k2 & _1n$6) + p2 = p2.add(acc); + acc = acc.double(); + k1 >>= _1n$6; + k2 >>= _1n$6; + } + return { p1, p2 }; + } + function pippenger(c, fieldN, points, scalars) { + validateMSMPoints(points, c); + validateMSMScalars(scalars, fieldN); + const plength = points.length; + const slength = scalars.length; + if (plength !== slength) + throw new Error('arrays of points and scalars must have equal length'); + const zero = c.ZERO; + const wbits = bitLen(BigInt(plength)); + let windowSize = 1; + if (wbits > 12) + windowSize = wbits - 3; + else if (wbits > 4) + windowSize = wbits - 2; + else if (wbits > 0) + windowSize = 2; + const MASK = bitMask$1(windowSize); + const buckets = new Array(Number(MASK) + 1).fill(zero); + const lastBits = Math.floor((fieldN.BITS - 1) / windowSize) * windowSize; + let sum = zero; + for (let i = lastBits; i >= 0; i -= windowSize) { + buckets.fill(zero); + for (let j = 0; j < slength; j++) { + const scalar = scalars[j]; + const wbits = Number((scalar >> BigInt(i)) & MASK); + buckets[wbits] = buckets[wbits].add(points[j]); + } + let resI = zero; + for (let j = buckets.length - 1, sumI = zero; j > 0; j--) { + sumI = sumI.add(buckets[j]); + resI = resI.add(sumI); + } + sum = sum.add(resI); + if (i !== 0) + for (let j = 0; j < windowSize; j++) + sum = sum.double(); + } + return sum; + } + function createField(order, field, isLE) { + if (field) { + if (field.ORDER !== order) + throw new Error('Field.ORDER must match order: Fp == p, Fn == n'); + validateField(field); + return field; + } + else { + return Field(order, { isLE }); + } + } + function _createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) { + if (FpFnLE === undefined) + FpFnLE = type === 'edwards'; + if (!CURVE || typeof CURVE !== 'object') + throw new Error(`expected valid ${type} CURVE object`); + for (const p of ['p', 'n', 'h']) { + const val = CURVE[p]; + if (!(typeof val === 'bigint' && val > _0n$7)) + throw new Error(`CURVE.${p} must be positive bigint`); + } + const Fp = createField(CURVE.p, curveOpts.Fp, FpFnLE); + const Fn = createField(CURVE.n, curveOpts.Fn, FpFnLE); + const _b = type === 'weierstrass' ? 'b' : 'd'; + const params = ['Gx', 'Gy', 'a', _b]; + for (const p of params) { + if (!Fp.isValid(CURVE[p])) + throw new Error(`CURVE.${p} must be valid field element of CURVE.Fp`); + } + CURVE = Object.freeze(Object.assign({}, CURVE)); + return { CURVE, Fp, Fn }; + } + + /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ + const divNearest = (num, den) => (num + (num >= 0 ? den : -den) / _2n$5) / den; + function _splitEndoScalar(k, basis, n) { + const [[a1, b1], [a2, b2]] = basis; + const c1 = divNearest(b2 * k, n); + const c2 = divNearest(-b1 * k, n); + let k1 = k - c1 * a1 - c2 * a2; + let k2 = -c1 * b1 - c2 * b2; + const k1neg = k1 < _0n$6; + const k2neg = k2 < _0n$6; + if (k1neg) + k1 = -k1; + if (k2neg) + k2 = -k2; + const MAX_NUM = bitMask$1(Math.ceil(bitLen(n) / 2)) + _1n$5; + if (k1 < _0n$6 || k1 >= MAX_NUM || k2 < _0n$6 || k2 >= MAX_NUM) { + throw new Error('splitScalar (endomorphism): failed, k=' + k); + } + return { k1neg, k1, k2neg, k2 }; + } + function validateSigFormat(format) { + if (!['compact', 'recovered', 'der'].includes(format)) + throw new Error('Signature format must be "compact", "recovered", or "der"'); + return format; + } + function validateSigOpts(opts, def) { + const optsn = {}; + for (let optName of Object.keys(def)) { + optsn[optName] = opts[optName] === undefined ? def[optName] : opts[optName]; + } + _abool2(optsn.lowS, 'lowS'); + _abool2(optsn.prehash, 'prehash'); + if (optsn.format !== undefined) + validateSigFormat(optsn.format); + return optsn; + } + class DERErr extends Error { + constructor(m = '') { + super(m); + } + } + const DER = { + Err: DERErr, + _tlv: { + encode: (tag, data) => { + const { Err: E } = DER; + if (tag < 0 || tag > 256) + throw new E('tlv.encode: wrong tag'); + if (data.length & 1) + throw new E('tlv.encode: unpadded data'); + const dataLen = data.length / 2; + const len = numberToHexUnpadded(dataLen); + if ((len.length / 2) & 128) + throw new E('tlv.encode: long form length too big'); + const lenLen = dataLen > 127 ? numberToHexUnpadded((len.length / 2) | 128) : ''; + const t = numberToHexUnpadded(tag); + return t + lenLen + len + data; + }, + decode(tag, data) { + const { Err: E } = DER; + let pos = 0; + if (tag < 0 || tag > 256) + throw new E('tlv.encode: wrong tag'); + if (data.length < 2 || data[pos++] !== tag) + throw new E('tlv.decode: wrong tlv'); + const first = data[pos++]; + const isLong = !!(first & 128); + let length = 0; + if (!isLong) + length = first; + else { + const lenLen = first & 127; + if (!lenLen) + throw new E('tlv.decode(long): indefinite length not supported'); + if (lenLen > 4) + throw new E('tlv.decode(long): byte length is too big'); + const lengthBytes = data.subarray(pos, pos + lenLen); + if (lengthBytes.length !== lenLen) + throw new E('tlv.decode: length bytes not complete'); + if (lengthBytes[0] === 0) + throw new E('tlv.decode(long): zero leftmost byte'); + for (const b of lengthBytes) + length = (length << 8) | b; + pos += lenLen; + if (length < 128) + throw new E('tlv.decode(long): not minimal encoding'); + } + const v = data.subarray(pos, pos + length); + if (v.length !== length) + throw new E('tlv.decode: wrong value length'); + return { v, l: data.subarray(pos + length) }; + }, + }, + _int: { + encode(num) { + const { Err: E } = DER; + if (num < _0n$6) + throw new E('integer: negative integers are not allowed'); + let hex = numberToHexUnpadded(num); + if (Number.parseInt(hex[0], 16) & 0b1000) + hex = '00' + hex; + if (hex.length & 1) + throw new E('unexpected DER parsing assertion: unpadded hex'); + return hex; + }, + decode(data) { + const { Err: E } = DER; + if (data[0] & 128) + throw new E('invalid signature integer: negative'); + if (data[0] === 0x00 && !(data[1] & 128)) + throw new E('invalid signature integer: unnecessary leading zero'); + return bytesToNumberBE(data); + }, + }, + toSig(hex) { + const { Err: E, _int: int, _tlv: tlv } = DER; + const data = ensureBytes('signature', hex); + const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data); + if (seqLeftBytes.length) + throw new E('invalid signature: left bytes after parsing'); + const { v: rBytes, l: rLeftBytes } = tlv.decode(0x02, seqBytes); + const { v: sBytes, l: sLeftBytes } = tlv.decode(0x02, rLeftBytes); + if (sLeftBytes.length) + throw new E('invalid signature: left bytes after parsing'); + return { r: int.decode(rBytes), s: int.decode(sBytes) }; + }, + hexFromSig(sig) { + const { _tlv: tlv, _int: int } = DER; + const rs = tlv.encode(0x02, int.encode(sig.r)); + const ss = tlv.encode(0x02, int.encode(sig.s)); + const seq = rs + ss; + return tlv.encode(0x30, seq); + }, + }; + const _0n$6 = BigInt(0), _1n$5 = BigInt(1), _2n$5 = BigInt(2), _3n$2 = BigInt(3), _4n = BigInt(4); + function _normFnElement(Fn, key) { + const { BYTES: expected } = Fn; + let num; + if (typeof key === 'bigint') { + num = key; + } + else { + let bytes = ensureBytes('private key', key); + try { + num = Fn.fromBytes(bytes); + } + catch (error) { + throw new Error(`invalid private key: expected ui8a of size ${expected}, got ${typeof key}`); + } + } + if (!Fn.isValidNot0(num)) + throw new Error('invalid private key: out of range [1..N-1]'); + return num; + } + function weierstrassN(params, extraOpts = {}) { + const validated = _createCurveFields('weierstrass', params, extraOpts); + const { Fp, Fn } = validated; + let CURVE = validated.CURVE; + const { h: cofactor, n: CURVE_ORDER } = CURVE; + _validateObject(extraOpts, {}, { + allowInfinityPoint: 'boolean', + clearCofactor: 'function', + isTorsionFree: 'function', + fromBytes: 'function', + toBytes: 'function', + endo: 'object', + wrapPrivateKey: 'boolean', + }); + const { endo } = extraOpts; + if (endo) { + if (!Fp.is0(CURVE.a) || typeof endo.beta !== 'bigint' || !Array.isArray(endo.basises)) { + throw new Error('invalid endo: expected "beta": bigint and "basises": array'); + } + } + const lengths = getWLengths(Fp, Fn); + function assertCompressionIsSupported() { + if (!Fp.isOdd) + throw new Error('compression is not supported: Field does not have .isOdd()'); + } + function pointToBytes(_c, point, isCompressed) { + const { x, y } = point.toAffine(); + const bx = Fp.toBytes(x); + _abool2(isCompressed, 'isCompressed'); + if (isCompressed) { + assertCompressionIsSupported(); + const hasEvenY = !Fp.isOdd(y); + return concatBytes(pprefix(hasEvenY), bx); + } + else { + return concatBytes(Uint8Array.of(0x04), bx, Fp.toBytes(y)); + } + } + function pointFromBytes(bytes) { + _abytes2(bytes, undefined, 'Point'); + const { publicKey: comp, publicKeyUncompressed: uncomp } = lengths; + const length = bytes.length; + const head = bytes[0]; + const tail = bytes.subarray(1); + if (length === comp && (head === 0x02 || head === 0x03)) { + const x = Fp.fromBytes(tail); + if (!Fp.isValid(x)) + throw new Error('bad point: is not on curve, wrong x'); + const y2 = weierstrassEquation(x); + let y; + try { + y = Fp.sqrt(y2); + } + catch (sqrtError) { + const err = sqrtError instanceof Error ? ': ' + sqrtError.message : ''; + throw new Error('bad point: is not on curve, sqrt error' + err); + } + assertCompressionIsSupported(); + const isYOdd = Fp.isOdd(y); + const isHeadOdd = (head & 1) === 1; + if (isHeadOdd !== isYOdd) + y = Fp.neg(y); + return { x, y }; + } + else if (length === uncomp && head === 0x04) { + const L = Fp.BYTES; + const x = Fp.fromBytes(tail.subarray(0, L)); + const y = Fp.fromBytes(tail.subarray(L, L * 2)); + if (!isValidXY(x, y)) + throw new Error('bad point: is not on curve'); + return { x, y }; + } + else { + throw new Error(`bad point: got length ${length}, expected compressed=${comp} or uncompressed=${uncomp}`); + } + } + const encodePoint = extraOpts.toBytes || pointToBytes; + const decodePoint = extraOpts.fromBytes || pointFromBytes; + function weierstrassEquation(x) { + const x2 = Fp.sqr(x); + const x3 = Fp.mul(x2, x); + return Fp.add(Fp.add(x3, Fp.mul(x, CURVE.a)), CURVE.b); + } + function isValidXY(x, y) { + const left = Fp.sqr(y); + const right = weierstrassEquation(x); + return Fp.eql(left, right); + } + if (!isValidXY(CURVE.Gx, CURVE.Gy)) + throw new Error('bad curve params: generator point'); + const _4a3 = Fp.mul(Fp.pow(CURVE.a, _3n$2), _4n); + const _27b2 = Fp.mul(Fp.sqr(CURVE.b), BigInt(27)); + if (Fp.is0(Fp.add(_4a3, _27b2))) + throw new Error('bad curve params: a or b'); + function acoord(title, n, banZero = false) { + if (!Fp.isValid(n) || (banZero && Fp.is0(n))) + throw new Error(`bad point coordinate ${title}`); + return n; + } + function aprjpoint(other) { + if (!(other instanceof Point)) + throw new Error('ProjectivePoint expected'); + } + function splitEndoScalarN(k) { + if (!endo || !endo.basises) + throw new Error('no endo'); + return _splitEndoScalar(k, endo.basises, Fn.ORDER); + } + const toAffineMemo = memoized((p, iz) => { + const { X, Y, Z } = p; + if (Fp.eql(Z, Fp.ONE)) + return { x: X, y: Y }; + const is0 = p.is0(); + if (iz == null) + iz = is0 ? Fp.ONE : Fp.inv(Z); + const x = Fp.mul(X, iz); + const y = Fp.mul(Y, iz); + const zz = Fp.mul(Z, iz); + if (is0) + return { x: Fp.ZERO, y: Fp.ZERO }; + if (!Fp.eql(zz, Fp.ONE)) + throw new Error('invZ was invalid'); + return { x, y }; + }); + const assertValidMemo = memoized((p) => { + if (p.is0()) { + if (extraOpts.allowInfinityPoint && !Fp.is0(p.Y)) + return; + throw new Error('bad point: ZERO'); + } + const { x, y } = p.toAffine(); + if (!Fp.isValid(x) || !Fp.isValid(y)) + throw new Error('bad point: x or y not field elements'); + if (!isValidXY(x, y)) + throw new Error('bad point: equation left != right'); + if (!p.isTorsionFree()) + throw new Error('bad point: not in prime-order subgroup'); + return true; + }); + function finishEndo(endoBeta, k1p, k2p, k1neg, k2neg) { + k2p = new Point(Fp.mul(k2p.X, endoBeta), k2p.Y, k2p.Z); + k1p = negateCt(k1neg, k1p); + k2p = negateCt(k2neg, k2p); + return k1p.add(k2p); + } + class Point { + constructor(X, Y, Z) { + this.X = acoord('x', X); + this.Y = acoord('y', Y, true); + this.Z = acoord('z', Z); + Object.freeze(this); + } + static CURVE() { + return CURVE; + } + static fromAffine(p) { + const { x, y } = p || {}; + if (!p || !Fp.isValid(x) || !Fp.isValid(y)) + throw new Error('invalid affine point'); + if (p instanceof Point) + throw new Error('projective point not allowed'); + if (Fp.is0(x) && Fp.is0(y)) + return Point.ZERO; + return new Point(x, y, Fp.ONE); + } + static fromBytes(bytes) { + const P = Point.fromAffine(decodePoint(_abytes2(bytes, undefined, 'point'))); + P.assertValidity(); + return P; + } + static fromHex(hex) { + return Point.fromBytes(ensureBytes('pointHex', hex)); + } + get x() { + return this.toAffine().x; + } + get y() { + return this.toAffine().y; + } + precompute(windowSize = 8, isLazy = true) { + wnaf.createCache(this, windowSize); + if (!isLazy) + this.multiply(_3n$2); + return this; + } + assertValidity() { + assertValidMemo(this); + } + hasEvenY() { + const { y } = this.toAffine(); + if (!Fp.isOdd) + throw new Error("Field doesn't support isOdd"); + return !Fp.isOdd(y); + } + equals(other) { + aprjpoint(other); + const { X: X1, Y: Y1, Z: Z1 } = this; + const { X: X2, Y: Y2, Z: Z2 } = other; + const U1 = Fp.eql(Fp.mul(X1, Z2), Fp.mul(X2, Z1)); + const U2 = Fp.eql(Fp.mul(Y1, Z2), Fp.mul(Y2, Z1)); + return U1 && U2; + } + negate() { + return new Point(this.X, Fp.neg(this.Y), this.Z); + } + double() { + const { a, b } = CURVE; + const b3 = Fp.mul(b, _3n$2); + const { X: X1, Y: Y1, Z: Z1 } = this; + let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; + let t0 = Fp.mul(X1, X1); + let t1 = Fp.mul(Y1, Y1); + let t2 = Fp.mul(Z1, Z1); + let t3 = Fp.mul(X1, Y1); + t3 = Fp.add(t3, t3); + Z3 = Fp.mul(X1, Z1); + Z3 = Fp.add(Z3, Z3); + X3 = Fp.mul(a, Z3); + Y3 = Fp.mul(b3, t2); + Y3 = Fp.add(X3, Y3); + X3 = Fp.sub(t1, Y3); + Y3 = Fp.add(t1, Y3); + Y3 = Fp.mul(X3, Y3); + X3 = Fp.mul(t3, X3); + Z3 = Fp.mul(b3, Z3); + t2 = Fp.mul(a, t2); + t3 = Fp.sub(t0, t2); + t3 = Fp.mul(a, t3); + t3 = Fp.add(t3, Z3); + Z3 = Fp.add(t0, t0); + t0 = Fp.add(Z3, t0); + t0 = Fp.add(t0, t2); + t0 = Fp.mul(t0, t3); + Y3 = Fp.add(Y3, t0); + t2 = Fp.mul(Y1, Z1); + t2 = Fp.add(t2, t2); + t0 = Fp.mul(t2, t3); + X3 = Fp.sub(X3, t0); + Z3 = Fp.mul(t2, t1); + Z3 = Fp.add(Z3, Z3); + Z3 = Fp.add(Z3, Z3); + return new Point(X3, Y3, Z3); + } + add(other) { + aprjpoint(other); + const { X: X1, Y: Y1, Z: Z1 } = this; + const { X: X2, Y: Y2, Z: Z2 } = other; + let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; + const a = CURVE.a; + const b3 = Fp.mul(CURVE.b, _3n$2); + let t0 = Fp.mul(X1, X2); + let t1 = Fp.mul(Y1, Y2); + let t2 = Fp.mul(Z1, Z2); + let t3 = Fp.add(X1, Y1); + let t4 = Fp.add(X2, Y2); + t3 = Fp.mul(t3, t4); + t4 = Fp.add(t0, t1); + t3 = Fp.sub(t3, t4); + t4 = Fp.add(X1, Z1); + let t5 = Fp.add(X2, Z2); + t4 = Fp.mul(t4, t5); + t5 = Fp.add(t0, t2); + t4 = Fp.sub(t4, t5); + t5 = Fp.add(Y1, Z1); + X3 = Fp.add(Y2, Z2); + t5 = Fp.mul(t5, X3); + X3 = Fp.add(t1, t2); + t5 = Fp.sub(t5, X3); + Z3 = Fp.mul(a, t4); + X3 = Fp.mul(b3, t2); + Z3 = Fp.add(X3, Z3); + X3 = Fp.sub(t1, Z3); + Z3 = Fp.add(t1, Z3); + Y3 = Fp.mul(X3, Z3); + t1 = Fp.add(t0, t0); + t1 = Fp.add(t1, t0); + t2 = Fp.mul(a, t2); + t4 = Fp.mul(b3, t4); + t1 = Fp.add(t1, t2); + t2 = Fp.sub(t0, t2); + t2 = Fp.mul(a, t2); + t4 = Fp.add(t4, t2); + t0 = Fp.mul(t1, t4); + Y3 = Fp.add(Y3, t0); + t0 = Fp.mul(t5, t4); + X3 = Fp.mul(t3, X3); + X3 = Fp.sub(X3, t0); + t0 = Fp.mul(t3, t1); + Z3 = Fp.mul(t5, Z3); + Z3 = Fp.add(Z3, t0); + return new Point(X3, Y3, Z3); + } + subtract(other) { + return this.add(other.negate()); + } + is0() { + return this.equals(Point.ZERO); + } + multiply(scalar) { + const { endo } = extraOpts; + if (!Fn.isValidNot0(scalar)) + throw new Error('invalid scalar: out of range'); + let point, fake; + const mul = (n) => wnaf.cached(this, n, (p) => normalizeZ(Point, p)); + if (endo) { + const { k1neg, k1, k2neg, k2 } = splitEndoScalarN(scalar); + const { p: k1p, f: k1f } = mul(k1); + const { p: k2p, f: k2f } = mul(k2); + fake = k1f.add(k2f); + point = finishEndo(endo.beta, k1p, k2p, k1neg, k2neg); + } + else { + const { p, f } = mul(scalar); + point = p; + fake = f; + } + return normalizeZ(Point, [point, fake])[0]; + } + multiplyUnsafe(sc) { + const { endo } = extraOpts; + const p = this; + if (!Fn.isValid(sc)) + throw new Error('invalid scalar: out of range'); + if (sc === _0n$6 || p.is0()) + return Point.ZERO; + if (sc === _1n$5) + return p; + if (wnaf.hasCache(this)) + return this.multiply(sc); + if (endo) { + const { k1neg, k1, k2neg, k2 } = splitEndoScalarN(sc); + const { p1, p2 } = mulEndoUnsafe(Point, p, k1, k2); + return finishEndo(endo.beta, p1, p2, k1neg, k2neg); + } + else { + return wnaf.unsafe(p, sc); + } + } + multiplyAndAddUnsafe(Q, a, b) { + const sum = this.multiplyUnsafe(a).add(Q.multiplyUnsafe(b)); + return sum.is0() ? undefined : sum; + } + toAffine(invertedZ) { + return toAffineMemo(this, invertedZ); + } + isTorsionFree() { + const { isTorsionFree } = extraOpts; + if (cofactor === _1n$5) + return true; + if (isTorsionFree) + return isTorsionFree(Point, this); + return wnaf.unsafe(this, CURVE_ORDER).is0(); + } + clearCofactor() { + const { clearCofactor } = extraOpts; + if (cofactor === _1n$5) + return this; + if (clearCofactor) + return clearCofactor(Point, this); + return this.multiplyUnsafe(cofactor); + } + isSmallOrder() { + return this.multiplyUnsafe(cofactor).is0(); + } + toBytes(isCompressed = true) { + _abool2(isCompressed, 'isCompressed'); + this.assertValidity(); + return encodePoint(Point, this, isCompressed); + } + toHex(isCompressed = true) { + return bytesToHex(this.toBytes(isCompressed)); + } + toString() { + return ``; + } + get px() { + return this.X; + } + get py() { + return this.X; + } + get pz() { + return this.Z; + } + toRawBytes(isCompressed = true) { + return this.toBytes(isCompressed); + } + _setWindowSize(windowSize) { + this.precompute(windowSize); + } + static normalizeZ(points) { + return normalizeZ(Point, points); + } + static msm(points, scalars) { + return pippenger(Point, Fn, points, scalars); + } + static fromPrivateKey(privateKey) { + return Point.BASE.multiply(_normFnElement(Fn, privateKey)); + } + } + Point.BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE); + Point.ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO); + Point.Fp = Fp; + Point.Fn = Fn; + const bits = Fn.BITS; + const wnaf = new wNAF(Point, extraOpts.endo ? Math.ceil(bits / 2) : bits); + Point.BASE.precompute(8); + return Point; + } + function pprefix(hasEvenY) { + return Uint8Array.of(hasEvenY ? 0x02 : 0x03); + } + function SWUFpSqrtRatio(Fp, Z) { + const q = Fp.ORDER; + let l = _0n$6; + for (let o = q - _1n$5; o % _2n$5 === _0n$6; o /= _2n$5) + l += _1n$5; + const c1 = l; + const _2n_pow_c1_1 = _2n$5 << (c1 - _1n$5 - _1n$5); + const _2n_pow_c1 = _2n_pow_c1_1 * _2n$5; + const c2 = (q - _1n$5) / _2n_pow_c1; + const c3 = (c2 - _1n$5) / _2n$5; + const c4 = _2n_pow_c1 - _1n$5; + const c5 = _2n_pow_c1_1; + const c6 = Fp.pow(Z, c2); + const c7 = Fp.pow(Z, (c2 + _1n$5) / _2n$5); + let sqrtRatio = (u, v) => { + let tv1 = c6; + let tv2 = Fp.pow(v, c4); + let tv3 = Fp.sqr(tv2); + tv3 = Fp.mul(tv3, v); + let tv5 = Fp.mul(u, tv3); + tv5 = Fp.pow(tv5, c3); + tv5 = Fp.mul(tv5, tv2); + tv2 = Fp.mul(tv5, v); + tv3 = Fp.mul(tv5, u); + let tv4 = Fp.mul(tv3, tv2); + tv5 = Fp.pow(tv4, c5); + let isQR = Fp.eql(tv5, Fp.ONE); + tv2 = Fp.mul(tv3, c7); + tv5 = Fp.mul(tv4, tv1); + tv3 = Fp.cmov(tv2, tv3, isQR); + tv4 = Fp.cmov(tv5, tv4, isQR); + for (let i = c1; i > _1n$5; i--) { + let tv5 = i - _2n$5; + tv5 = _2n$5 << (tv5 - _1n$5); + let tvv5 = Fp.pow(tv4, tv5); + const e1 = Fp.eql(tvv5, Fp.ONE); + tv2 = Fp.mul(tv3, tv1); + tv1 = Fp.mul(tv1, tv1); + tvv5 = Fp.mul(tv4, tv1); + tv3 = Fp.cmov(tv2, tv3, e1); + tv4 = Fp.cmov(tvv5, tv4, e1); + } + return { isValid: isQR, value: tv3 }; + }; + if (Fp.ORDER % _4n === _3n$2) { + const c1 = (Fp.ORDER - _3n$2) / _4n; + const c2 = Fp.sqrt(Fp.neg(Z)); + sqrtRatio = (u, v) => { + let tv1 = Fp.sqr(v); + const tv2 = Fp.mul(u, v); + tv1 = Fp.mul(tv1, tv2); + let y1 = Fp.pow(tv1, c1); + y1 = Fp.mul(y1, tv2); + const y2 = Fp.mul(y1, c2); + const tv3 = Fp.mul(Fp.sqr(y1), v); + const isQR = Fp.eql(tv3, u); + let y = Fp.cmov(y2, y1, isQR); + return { isValid: isQR, value: y }; + }; + } + return sqrtRatio; + } + function mapToCurveSimpleSWU(Fp, opts) { + validateField(Fp); + const { A, B, Z } = opts; + if (!Fp.isValid(A) || !Fp.isValid(B) || !Fp.isValid(Z)) + throw new Error('mapToCurveSimpleSWU: invalid opts'); + const sqrtRatio = SWUFpSqrtRatio(Fp, Z); + if (!Fp.isOdd) + throw new Error('Field does not have .isOdd()'); + return (u) => { + let tv1, tv2, tv3, tv4, tv5, tv6, x, y; + tv1 = Fp.sqr(u); + tv1 = Fp.mul(tv1, Z); + tv2 = Fp.sqr(tv1); + tv2 = Fp.add(tv2, tv1); + tv3 = Fp.add(tv2, Fp.ONE); + tv3 = Fp.mul(tv3, B); + tv4 = Fp.cmov(Z, Fp.neg(tv2), !Fp.eql(tv2, Fp.ZERO)); + tv4 = Fp.mul(tv4, A); + tv2 = Fp.sqr(tv3); + tv6 = Fp.sqr(tv4); + tv5 = Fp.mul(tv6, A); + tv2 = Fp.add(tv2, tv5); + tv2 = Fp.mul(tv2, tv3); + tv6 = Fp.mul(tv6, tv4); + tv5 = Fp.mul(tv6, B); + tv2 = Fp.add(tv2, tv5); + x = Fp.mul(tv1, tv3); + const { isValid, value } = sqrtRatio(tv2, tv6); + y = Fp.mul(tv1, u); + y = Fp.mul(y, value); + x = Fp.cmov(x, tv3, isValid); + y = Fp.cmov(y, value, isValid); + const e1 = Fp.isOdd(u) === Fp.isOdd(y); + y = Fp.cmov(Fp.neg(y), y, e1); + const tv4_inv = FpInvertBatch(Fp, [tv4], true)[0]; + x = Fp.mul(x, tv4_inv); + return { x, y }; + }; + } + function getWLengths(Fp, Fn) { + return { + secretKey: Fn.BYTES, + publicKey: 1 + Fp.BYTES, + publicKeyUncompressed: 1 + 2 * Fp.BYTES, + publicKeyHasPrefix: true, + signature: 2 * Fn.BYTES, + }; + } + function ecdh(Point, ecdhOpts = {}) { + const { Fn } = Point; + const randomBytes_ = ecdhOpts.randomBytes || randomBytes; + const lengths = Object.assign(getWLengths(Point.Fp, Fn), { seed: getMinHashLength(Fn.ORDER) }); + function isValidSecretKey(secretKey) { + try { + return !!_normFnElement(Fn, secretKey); + } + catch (error) { + return false; + } + } + function isValidPublicKey(publicKey, isCompressed) { + const { publicKey: comp, publicKeyUncompressed } = lengths; + try { + const l = publicKey.length; + if (isCompressed === true && l !== comp) + return false; + if (isCompressed === false && l !== publicKeyUncompressed) + return false; + return !!Point.fromBytes(publicKey); + } + catch (error) { + return false; + } + } + function randomSecretKey(seed = randomBytes_(lengths.seed)) { + return mapHashToField(_abytes2(seed, lengths.seed, 'seed'), Fn.ORDER); + } + function getPublicKey(secretKey, isCompressed = true) { + return Point.BASE.multiply(_normFnElement(Fn, secretKey)).toBytes(isCompressed); + } + function keygen(seed) { + const secretKey = randomSecretKey(seed); + return { secretKey, publicKey: getPublicKey(secretKey) }; + } + function isProbPub(item) { + if (typeof item === 'bigint') + return false; + if (item instanceof Point) + return true; + const { secretKey, publicKey, publicKeyUncompressed } = lengths; + if (Fn.allowedLengths || secretKey === publicKey) + return undefined; + const l = ensureBytes('key', item).length; + return l === publicKey || l === publicKeyUncompressed; + } + function getSharedSecret(secretKeyA, publicKeyB, isCompressed = true) { + if (isProbPub(secretKeyA) === true) + throw new Error('first arg must be private key'); + if (isProbPub(publicKeyB) === false) + throw new Error('second arg must be public key'); + const s = _normFnElement(Fn, secretKeyA); + const b = Point.fromHex(publicKeyB); + return b.multiply(s).toBytes(isCompressed); + } + const utils = { + isValidSecretKey, + isValidPublicKey, + randomSecretKey, + isValidPrivateKey: isValidSecretKey, + randomPrivateKey: randomSecretKey, + normPrivateKeyToScalar: (key) => _normFnElement(Fn, key), + precompute(windowSize = 8, point = Point.BASE) { + return point.precompute(windowSize, false); + }, + }; + return Object.freeze({ getPublicKey, getSharedSecret, keygen, Point, utils, lengths }); + } + function ecdsa(Point, hash, ecdsaOpts = {}) { + ahash(hash); + _validateObject(ecdsaOpts, {}, { + hmac: 'function', + lowS: 'boolean', + randomBytes: 'function', + bits2int: 'function', + bits2int_modN: 'function', + }); + const randomBytes$1 = ecdsaOpts.randomBytes || randomBytes; + const hmac$1 = ecdsaOpts.hmac || + ((key, ...msgs) => hmac(hash, key, concatBytes(...msgs))); + const { Fp, Fn } = Point; + const { ORDER: CURVE_ORDER, BITS: fnBits } = Fn; + const { keygen, getPublicKey, getSharedSecret, utils, lengths } = ecdh(Point, ecdsaOpts); + const defaultSigOpts = { + prehash: false, + lowS: typeof ecdsaOpts.lowS === 'boolean' ? ecdsaOpts.lowS : false, + format: undefined, + extraEntropy: false, + }; + const defaultSigOpts_format = 'compact'; + function isBiggerThanHalfOrder(number) { + const HALF = CURVE_ORDER >> _1n$5; + return number > HALF; + } + function validateRS(title, num) { + if (!Fn.isValidNot0(num)) + throw new Error(`invalid signature ${title}: out of range 1..Point.Fn.ORDER`); + return num; + } + function validateSigLength(bytes, format) { + validateSigFormat(format); + const size = lengths.signature; + const sizer = format === 'compact' ? size : format === 'recovered' ? size + 1 : undefined; + return _abytes2(bytes, sizer, `${format} signature`); + } + class Signature { + constructor(r, s, recovery) { + this.r = validateRS('r', r); + this.s = validateRS('s', s); + if (recovery != null) + this.recovery = recovery; + Object.freeze(this); + } + static fromBytes(bytes, format = defaultSigOpts_format) { + validateSigLength(bytes, format); + let recid; + if (format === 'der') { + const { r, s } = DER.toSig(_abytes2(bytes)); + return new Signature(r, s); + } + if (format === 'recovered') { + recid = bytes[0]; + format = 'compact'; + bytes = bytes.subarray(1); + } + const L = Fn.BYTES; + const r = bytes.subarray(0, L); + const s = bytes.subarray(L, L * 2); + return new Signature(Fn.fromBytes(r), Fn.fromBytes(s), recid); + } + static fromHex(hex, format) { + return this.fromBytes(hexToBytes(hex), format); + } + addRecoveryBit(recovery) { + return new Signature(this.r, this.s, recovery); + } + recoverPublicKey(messageHash) { + const FIELD_ORDER = Fp.ORDER; + const { r, s, recovery: rec } = this; + if (rec == null || ![0, 1, 2, 3].includes(rec)) + throw new Error('recovery id invalid'); + const hasCofactor = CURVE_ORDER * _2n$5 < FIELD_ORDER; + if (hasCofactor && rec > 1) + throw new Error('recovery id is ambiguous for h>1 curve'); + const radj = rec === 2 || rec === 3 ? r + CURVE_ORDER : r; + if (!Fp.isValid(radj)) + throw new Error('recovery id 2 or 3 invalid'); + const x = Fp.toBytes(radj); + const R = Point.fromBytes(concatBytes(pprefix((rec & 1) === 0), x)); + const ir = Fn.inv(radj); + const h = bits2int_modN(ensureBytes('msgHash', messageHash)); + const u1 = Fn.create(-h * ir); + const u2 = Fn.create(s * ir); + const Q = Point.BASE.multiplyUnsafe(u1).add(R.multiplyUnsafe(u2)); + if (Q.is0()) + throw new Error('point at infinify'); + Q.assertValidity(); + return Q; + } + hasHighS() { + return isBiggerThanHalfOrder(this.s); + } + toBytes(format = defaultSigOpts_format) { + validateSigFormat(format); + if (format === 'der') + return hexToBytes(DER.hexFromSig(this)); + const r = Fn.toBytes(this.r); + const s = Fn.toBytes(this.s); + if (format === 'recovered') { + if (this.recovery == null) + throw new Error('recovery bit must be present'); + return concatBytes(Uint8Array.of(this.recovery), r, s); + } + return concatBytes(r, s); + } + toHex(format) { + return bytesToHex(this.toBytes(format)); + } + assertValidity() { } + static fromCompact(hex) { + return Signature.fromBytes(ensureBytes('sig', hex), 'compact'); + } + static fromDER(hex) { + return Signature.fromBytes(ensureBytes('sig', hex), 'der'); + } + normalizeS() { + return this.hasHighS() ? new Signature(this.r, Fn.neg(this.s), this.recovery) : this; + } + toDERRawBytes() { + return this.toBytes('der'); + } + toDERHex() { + return bytesToHex(this.toBytes('der')); + } + toCompactRawBytes() { + return this.toBytes('compact'); + } + toCompactHex() { + return bytesToHex(this.toBytes('compact')); + } + } + const bits2int = ecdsaOpts.bits2int || + function bits2int_def(bytes) { + if (bytes.length > 8192) + throw new Error('input is too large'); + const num = bytesToNumberBE(bytes); + const delta = bytes.length * 8 - fnBits; + return delta > 0 ? num >> BigInt(delta) : num; + }; + const bits2int_modN = ecdsaOpts.bits2int_modN || + function bits2int_modN_def(bytes) { + return Fn.create(bits2int(bytes)); + }; + const ORDER_MASK = bitMask$1(fnBits); + function int2octets(num) { + aInRange$1('num < 2^' + fnBits, num, _0n$6, ORDER_MASK); + return Fn.toBytes(num); + } + function validateMsgAndHash(message, prehash) { + _abytes2(message, undefined, 'message'); + return prehash ? _abytes2(hash(message), undefined, 'prehashed message') : message; + } + function prepSig(message, privateKey, opts) { + if (['recovered', 'canonical'].some((k) => k in opts)) + throw new Error('sign() legacy options not supported'); + const { lowS, prehash, extraEntropy } = validateSigOpts(opts, defaultSigOpts); + message = validateMsgAndHash(message, prehash); + const h1int = bits2int_modN(message); + const d = _normFnElement(Fn, privateKey); + const seedArgs = [int2octets(d), int2octets(h1int)]; + if (extraEntropy != null && extraEntropy !== false) { + const e = extraEntropy === true ? randomBytes$1(lengths.secretKey) : extraEntropy; + seedArgs.push(ensureBytes('extraEntropy', e)); + } + const seed = concatBytes(...seedArgs); + const m = h1int; + function k2sig(kBytes) { + const k = bits2int(kBytes); + if (!Fn.isValidNot0(k)) + return; + const ik = Fn.inv(k); + const q = Point.BASE.multiply(k).toAffine(); + const r = Fn.create(q.x); + if (r === _0n$6) + return; + const s = Fn.create(ik * Fn.create(m + r * d)); + if (s === _0n$6) + return; + let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n$5); + let normS = s; + if (lowS && isBiggerThanHalfOrder(s)) { + normS = Fn.neg(s); + recovery ^= 1; + } + return new Signature(r, normS, recovery); + } + return { seed, k2sig }; + } + function sign(message, secretKey, opts = {}) { + message = ensureBytes('message', message); + const { seed, k2sig } = prepSig(message, secretKey, opts); + const drbg = createHmacDrbg(hash.outputLen, Fn.BYTES, hmac$1); + const sig = drbg(seed, k2sig); + return sig; + } + function tryParsingSig(sg) { + let sig = undefined; + const isHex = typeof sg === 'string' || isBytes$1(sg); + const isObj = !isHex && + sg !== null && + typeof sg === 'object' && + typeof sg.r === 'bigint' && + typeof sg.s === 'bigint'; + if (!isHex && !isObj) + throw new Error('invalid signature, expected Uint8Array, hex string or Signature instance'); + if (isObj) { + sig = new Signature(sg.r, sg.s); + } + else if (isHex) { + try { + sig = Signature.fromBytes(ensureBytes('sig', sg), 'der'); + } + catch (derError) { + if (!(derError instanceof DER.Err)) + throw derError; + } + if (!sig) { + try { + sig = Signature.fromBytes(ensureBytes('sig', sg), 'compact'); + } + catch (error) { + return false; + } + } + } + if (!sig) + return false; + return sig; + } + function verify(signature, message, publicKey, opts = {}) { + const { lowS, prehash, format } = validateSigOpts(opts, defaultSigOpts); + publicKey = ensureBytes('publicKey', publicKey); + message = validateMsgAndHash(ensureBytes('message', message), prehash); + if ('strict' in opts) + throw new Error('options.strict was renamed to lowS'); + const sig = format === undefined + ? tryParsingSig(signature) + : Signature.fromBytes(ensureBytes('sig', signature), format); + if (sig === false) + return false; + try { + const P = Point.fromBytes(publicKey); + if (lowS && sig.hasHighS()) + return false; + const { r, s } = sig; + const h = bits2int_modN(message); + const is = Fn.inv(s); + const u1 = Fn.create(h * is); + const u2 = Fn.create(r * is); + const R = Point.BASE.multiplyUnsafe(u1).add(P.multiplyUnsafe(u2)); + if (R.is0()) + return false; + const v = Fn.create(R.x); + return v === r; + } + catch (e) { + return false; + } + } + function recoverPublicKey(signature, message, opts = {}) { + const { prehash } = validateSigOpts(opts, defaultSigOpts); + message = validateMsgAndHash(message, prehash); + return Signature.fromBytes(signature, 'recovered').recoverPublicKey(message).toBytes(); + } + return Object.freeze({ + keygen, + getPublicKey, + getSharedSecret, + utils, + lengths, + Point, + sign, + verify, + recoverPublicKey, + Signature, + hash, + }); + } + function _weierstrass_legacy_opts_to_new(c) { + const CURVE = { + a: c.a, + b: c.b, + p: c.Fp.ORDER, + n: c.n, + h: c.h, + Gx: c.Gx, + Gy: c.Gy, + }; + const Fp = c.Fp; + let allowedLengths = c.allowedPrivateKeyLengths + ? Array.from(new Set(c.allowedPrivateKeyLengths.map((l) => Math.ceil(l / 2)))) + : undefined; + const Fn = Field(CURVE.n, { + BITS: c.nBitLength, + allowedLengths: allowedLengths, + modFromBytes: c.wrapPrivateKey, + }); + const curveOpts = { + Fp, + Fn, + allowInfinityPoint: c.allowInfinityPoint, + endo: c.endo, + isTorsionFree: c.isTorsionFree, + clearCofactor: c.clearCofactor, + fromBytes: c.fromBytes, + toBytes: c.toBytes, + }; + return { CURVE, curveOpts }; + } + function _ecdsa_legacy_opts_to_new(c) { + const { CURVE, curveOpts } = _weierstrass_legacy_opts_to_new(c); + const ecdsaOpts = { + hmac: c.hmac, + randomBytes: c.randomBytes, + lowS: c.lowS, + bits2int: c.bits2int, + bits2int_modN: c.bits2int_modN, + }; + return { CURVE, curveOpts, hash: c.hash, ecdsaOpts }; + } + function _ecdsa_new_output_to_legacy(c, _ecdsa) { + const Point = _ecdsa.Point; + return Object.assign({}, _ecdsa, { + ProjectivePoint: Point, + CURVE: Object.assign({}, c, nLength(Point.Fn.ORDER, Point.Fn.BITS)), + }); + } + function weierstrass(c) { + const { CURVE, curveOpts, hash, ecdsaOpts } = _ecdsa_legacy_opts_to_new(c); + const Point = weierstrassN(CURVE, curveOpts); + const signs = ecdsa(Point, hash, ecdsaOpts); + return _ecdsa_new_output_to_legacy(c, signs); + } + + /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ + function createCurve(curveDef, defHash) { + const create = (hash) => weierstrass({ ...curveDef, hash: hash }); + return { ...create(defHash), create }; + } + + const os2ip = bytesToNumberBE; + function i2osp(value, length) { + anum(value); + anum(length); + if (value < 0 || value >= 1 << (8 * length)) + throw new Error('invalid I2OSP input: ' + value); + const res = Array.from({ length }).fill(0); + for (let i = length - 1; i >= 0; i--) { + res[i] = value & 0xff; + value >>>= 8; + } + return new Uint8Array(res); + } + function strxor(a, b) { + const arr = new Uint8Array(a.length); + for (let i = 0; i < a.length; i++) { + arr[i] = a[i] ^ b[i]; + } + return arr; + } + function anum(item) { + if (!Number.isSafeInteger(item)) + throw new Error('number expected'); + } + function normDST(DST) { + if (!isBytes$1(DST) && typeof DST !== 'string') + throw new Error('DST must be Uint8Array or string'); + return typeof DST === 'string' ? utf8ToBytes(DST) : DST; + } + function expand_message_xmd(msg, DST, lenInBytes, H) { + abytes$1(msg); + anum(lenInBytes); + DST = normDST(DST); + if (DST.length > 255) + DST = H(concatBytes(utf8ToBytes('H2C-OVERSIZE-DST-'), DST)); + const { outputLen: b_in_bytes, blockLen: r_in_bytes } = H; + const ell = Math.ceil(lenInBytes / b_in_bytes); + if (lenInBytes > 65535 || ell > 255) + throw new Error('expand_message_xmd: invalid lenInBytes'); + const DST_prime = concatBytes(DST, i2osp(DST.length, 1)); + const Z_pad = i2osp(0, r_in_bytes); + const l_i_b_str = i2osp(lenInBytes, 2); + const b = new Array(ell); + const b_0 = H(concatBytes(Z_pad, msg, l_i_b_str, i2osp(0, 1), DST_prime)); + b[0] = H(concatBytes(b_0, i2osp(1, 1), DST_prime)); + for (let i = 1; i <= ell; i++) { + const args = [strxor(b_0, b[i - 1]), i2osp(i + 1, 1), DST_prime]; + b[i] = H(concatBytes(...args)); + } + const pseudo_random_bytes = concatBytes(...b); + return pseudo_random_bytes.slice(0, lenInBytes); + } + function expand_message_xof(msg, DST, lenInBytes, k, H) { + abytes$1(msg); + anum(lenInBytes); + DST = normDST(DST); + if (DST.length > 255) { + const dkLen = Math.ceil((2 * k) / 8); + DST = H.create({ dkLen }).update(utf8ToBytes('H2C-OVERSIZE-DST-')).update(DST).digest(); + } + if (lenInBytes > 65535 || DST.length > 255) + throw new Error('expand_message_xof: invalid lenInBytes'); + return (H.create({ dkLen: lenInBytes }) + .update(msg) + .update(i2osp(lenInBytes, 2)) + .update(DST) + .update(i2osp(DST.length, 1)) + .digest()); + } + function hash_to_field(msg, count, options) { + _validateObject(options, { + p: 'bigint', + m: 'number', + k: 'number', + hash: 'function', + }); + const { p, k, m, hash, expand, DST } = options; + if (!isHash(options.hash)) + throw new Error('expected valid hash'); + abytes$1(msg); + anum(count); + const log2p = p.toString(2).length; + const L = Math.ceil((log2p + k) / 8); + const len_in_bytes = count * m * L; + let prb; + if (expand === 'xmd') { + prb = expand_message_xmd(msg, DST, len_in_bytes, hash); + } + else if (expand === 'xof') { + prb = expand_message_xof(msg, DST, len_in_bytes, k, hash); + } + else if (expand === '_internal_pass') { + prb = msg; + } + else { + throw new Error('expand must be "xmd" or "xof"'); + } + const u = new Array(count); + for (let i = 0; i < count; i++) { + const e = new Array(m); + for (let j = 0; j < m; j++) { + const elm_offset = L * (j + i * m); + const tv = prb.subarray(elm_offset, elm_offset + L); + e[j] = mod(os2ip(tv), p); + } + u[i] = e; + } + return u; + } + function isogenyMap(field, map) { + const coeff = map.map((i) => Array.from(i).reverse()); + return (x, y) => { + const [xn, xd, yn, yd] = coeff.map((val) => val.reduce((acc, i) => field.add(field.mul(acc, x), i))); + const [xd_inv, yd_inv] = FpInvertBatch(field, [xd, yd], true); + x = field.mul(xn, xd_inv); + y = field.mul(y, field.mul(yn, yd_inv)); + return { x, y }; + }; + } + const _DST_scalar = utf8ToBytes('HashToScalar-'); + function createHasher(Point, mapToCurve, defaults) { + if (typeof mapToCurve !== 'function') + throw new Error('mapToCurve() must be defined'); + function map(num) { + return Point.fromAffine(mapToCurve(num)); + } + function clear(initial) { + const P = initial.clearCofactor(); + if (P.equals(Point.ZERO)) + return Point.ZERO; + P.assertValidity(); + return P; + } + return { + defaults, + hashToCurve(msg, options) { + const opts = Object.assign({}, defaults, options); + const u = hash_to_field(msg, 2, opts); + const u0 = map(u[0]); + const u1 = map(u[1]); + return clear(u0.add(u1)); + }, + encodeToCurve(msg, options) { + const optsDst = defaults.encodeDST ? { DST: defaults.encodeDST } : {}; + const opts = Object.assign({}, defaults, optsDst, options); + const u = hash_to_field(msg, 1, opts); + const u0 = map(u[0]); + return clear(u0); + }, + mapToCurve(scalars) { + if (!Array.isArray(scalars)) + throw new Error('expected array of bigints'); + for (const i of scalars) + if (typeof i !== 'bigint') + throw new Error('expected array of bigints'); + return clear(map(scalars)); + }, + hashToScalar(msg, options) { + const N = Point.Fn.ORDER; + const opts = Object.assign({}, defaults, { p: N, m: 1, DST: _DST_scalar }, options); + return hash_to_field(msg, 1, opts)[0][0]; + }, + }; + } + + /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ + const secp256k1_CURVE = { + p: BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'), + n: BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'), + h: BigInt(1), + a: BigInt(0), + b: BigInt(7), + Gx: BigInt('0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), + Gy: BigInt('0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'), + }; + const secp256k1_ENDO = { + beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'), + basises: [ + [BigInt('0x3086d221a7d46bcde86c90e49284eb15'), -BigInt('0xe4437ed6010e88286f547fa90abfe4c3')], + [BigInt('0x114ca50f7a8e2f3f657c1108d9d44cfd8'), BigInt('0x3086d221a7d46bcde86c90e49284eb15')], + ], + }; + const _0n$5 = BigInt(0); + const _1n$4 = BigInt(1); + const _2n$4 = BigInt(2); + function sqrtMod(y) { + const P = secp256k1_CURVE.p; + const _3n = BigInt(3), _6n = BigInt(6), _11n = BigInt(11), _22n = BigInt(22); + const _23n = BigInt(23), _44n = BigInt(44), _88n = BigInt(88); + const b2 = (y * y * y) % P; + const b3 = (b2 * b2 * y) % P; + const b6 = (pow2(b3, _3n, P) * b3) % P; + const b9 = (pow2(b6, _3n, P) * b3) % P; + const b11 = (pow2(b9, _2n$4, P) * b2) % P; + const b22 = (pow2(b11, _11n, P) * b11) % P; + const b44 = (pow2(b22, _22n, P) * b22) % P; + const b88 = (pow2(b44, _44n, P) * b44) % P; + const b176 = (pow2(b88, _88n, P) * b88) % P; + const b220 = (pow2(b176, _44n, P) * b44) % P; + const b223 = (pow2(b220, _3n, P) * b3) % P; + const t1 = (pow2(b223, _23n, P) * b22) % P; + const t2 = (pow2(t1, _6n, P) * b2) % P; + const root = pow2(t2, _2n$4, P); + if (!Fpk1.eql(Fpk1.sqr(root), y)) + throw new Error('Cannot find square root'); + return root; + } + const Fpk1 = Field(secp256k1_CURVE.p, { sqrt: sqrtMod }); + const secp256k1 = createCurve({ ...secp256k1_CURVE, Fp: Fpk1, lowS: true, endo: secp256k1_ENDO }, sha256$1); + const TAGGED_HASH_PREFIXES = {}; + function taggedHash(tag, ...messages) { + let tagP = TAGGED_HASH_PREFIXES[tag]; + if (tagP === undefined) { + const tagH = sha256$1(utf8ToBytes(tag)); + tagP = concatBytes(tagH, tagH); + TAGGED_HASH_PREFIXES[tag] = tagP; + } + return sha256$1(concatBytes(tagP, ...messages)); + } + const pointToBytes = (point) => point.toBytes(true).slice(1); + const Pointk1 = (() => secp256k1.Point)(); + const hasEven = (y) => y % _2n$4 === _0n$5; + function schnorrGetExtPubKey(priv) { + const { Fn, BASE } = Pointk1; + const d_ = _normFnElement(Fn, priv); + const p = BASE.multiply(d_); + const scalar = hasEven(p.y) ? d_ : Fn.neg(d_); + return { scalar, bytes: pointToBytes(p) }; + } + function lift_x(x) { + const Fp = Fpk1; + if (!Fp.isValidNot0(x)) + throw new Error('invalid x: Fail if x ≥ p'); + const xx = Fp.create(x * x); + const c = Fp.create(xx * x + BigInt(7)); + let y = Fp.sqrt(c); + if (!hasEven(y)) + y = Fp.neg(y); + const p = Pointk1.fromAffine({ x, y }); + p.assertValidity(); + return p; + } + const num = bytesToNumberBE; + function challenge(...args) { + return Pointk1.Fn.create(num(taggedHash('BIP0340/challenge', ...args))); + } + function schnorrGetPublicKey(secretKey) { + return schnorrGetExtPubKey(secretKey).bytes; + } + function schnorrSign(message, secretKey, auxRand = randomBytes(32)) { + const { Fn } = Pointk1; + const m = ensureBytes('message', message); + const { bytes: px, scalar: d } = schnorrGetExtPubKey(secretKey); + const a = ensureBytes('auxRand', auxRand, 32); + const t = Fn.toBytes(d ^ num(taggedHash('BIP0340/aux', a))); + const rand = taggedHash('BIP0340/nonce', t, px, m); + const { bytes: rx, scalar: k } = schnorrGetExtPubKey(rand); + const e = challenge(rx, px, m); + const sig = new Uint8Array(64); + sig.set(rx, 0); + sig.set(Fn.toBytes(Fn.create(k + e * d)), 32); + if (!schnorrVerify(sig, m, px)) + throw new Error('sign: Invalid signature produced'); + return sig; + } + function schnorrVerify(signature, message, publicKey) { + const { Fn, BASE } = Pointk1; + const sig = ensureBytes('signature', signature, 64); + const m = ensureBytes('message', message); + const pub = ensureBytes('publicKey', publicKey, 32); + try { + const P = lift_x(num(pub)); + const r = num(sig.subarray(0, 32)); + if (!inRange(r, _1n$4, secp256k1_CURVE.p)) + return false; + const s = num(sig.subarray(32, 64)); + if (!inRange(s, _1n$4, secp256k1_CURVE.n)) + return false; + const e = challenge(Fn.toBytes(r), pointToBytes(P), m); + const R = BASE.multiplyUnsafe(s).add(P.multiplyUnsafe(Fn.neg(e))); + const { x, y } = R.toAffine(); + if (R.is0() || !hasEven(y) || x !== r) + return false; + return true; + } + catch (error) { + return false; + } + } + (() => { + const size = 32; + const seedLength = 48; + const randomSecretKey = (seed = randomBytes(seedLength)) => { + return mapHashToField(seed, secp256k1_CURVE.n); + }; + secp256k1.utils.randomSecretKey; + function keygen(seed) { + const secretKey = randomSecretKey(seed); + return { secretKey, publicKey: schnorrGetPublicKey(secretKey) }; + } + return { + keygen, + getPublicKey: schnorrGetPublicKey, + sign: schnorrSign, + verify: schnorrVerify, + Point: Pointk1, + utils: { + randomSecretKey: randomSecretKey, + randomPrivateKey: randomSecretKey, + taggedHash, + lift_x, + pointToBytes, + numberToBytesBE, + bytesToNumberBE, + mod, + }, + lengths: { + secretKey: size, + publicKey: size, + publicKeyHasPrefix: false, + signature: size * 2, + seed: seedLength, + }, + }; + })(); + const isoMap = (() => isogenyMap(Fpk1, [ + [ + '0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa8c7', + '0x7d3d4c80bc321d5b9f315cea7fd44c5d595d2fc0bf63b92dfff1044f17c6581', + '0x534c328d23f234e6e2a413deca25caece4506144037c40314ecbd0b53d9dd262', + '0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa88c', + ], + [ + '0xd35771193d94918a9ca34ccbb7b640dd86cd409542f8487d9fe6b745781eb49b', + '0xedadc6f64383dc1df7c4b2d51b54225406d36b641f5e41bbc52a56612a8c6d14', + '0x0000000000000000000000000000000000000000000000000000000000000001', + ], + [ + '0x4bda12f684bda12f684bda12f684bda12f684bda12f684bda12f684b8e38e23c', + '0xc75e0c32d5cb7c0fa9d0a54b12a0a6d5647ab046d686da6fdffc90fc201d71a3', + '0x29a6194691f91a73715209ef6512e576722830a201be2018a765e85a9ecee931', + '0x2f684bda12f684bda12f684bda12f684bda12f684bda12f684bda12f38e38d84', + ], + [ + '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffff93b', + '0x7a06534bb8bdb49fd5e9e6632722c2989467c1bfc8e8d978dfb425d2685c2573', + '0x6484aa716545ca2cf3a70c3fa8fe337e0a3d21162f0d6299a7bf8192bfd2a76f', + '0x0000000000000000000000000000000000000000000000000000000000000001', + ], + ].map((i) => i.map((j) => BigInt(j)))))(); + const mapSWU = (() => mapToCurveSimpleSWU(Fpk1, { + A: BigInt('0x3f8731abdd661adca08a5558f0f5d272e953d363cb6f0e5d405447c01a444533'), + B: BigInt('1771'), + Z: Fpk1.create(BigInt('-11')), + }))(); + (() => createHasher(secp256k1.Point, (scalars) => { + const { x, y } = mapSWU(Fpk1.create(scalars[0])); + return isoMap(x, y); + }, { + DST: 'secp256k1_XMD:SHA-256_SSWU_RO_', + encodeDST: 'secp256k1_XMD:SHA-256_SSWU_NU_', + p: Fpk1.ORDER, + m: 1, + k: 128, + expand: 'xmd', + hash: sha256$1, + }))(); + + function secp256k1PairFromSeed(seed, onlyJs) { + if (seed.length !== 32) { + throw new Error('Expected valid 32-byte private key as a seed'); + } + if (!util.hasBigInt || (!onlyJs && isReady())) { + const full = secp256k1FromSeed(seed); + const publicKey = full.slice(32); + if (util.u8aEmpty(publicKey)) { + throw new Error('Invalid publicKey generated from WASM interface'); + } + return { + publicKey, + secretKey: full.slice(0, 32) + }; + } + return { + publicKey: secp256k1.getPublicKey(seed, true), + secretKey: seed + }; + } + + function createSeedDeriveFn(fromSeed, derive) { + return (keypair, { chainCode, isHard }) => { + if (!isHard) { + throw new Error('A soft key was found in the path and is not supported'); + } + return fromSeed(derive(keypair.secretKey.subarray(0, 32), chainCode)); + }; + } + + const keyHdkdEcdsa = createSeedDeriveFn(secp256k1PairFromSeed, secp256k1DeriveHard); + + const HDKD$1 = util.compactAddLength(util.stringToU8a('Ed25519HDKD')); + function ed25519DeriveHard(seed, chainCode) { + if (!util.isU8a(chainCode) || chainCode.length !== 32) { + throw new Error('Invalid chainCode passed to derive'); + } + return blake2AsU8a(util.u8aConcat(HDKD$1, seed, chainCode)); + } + + function randomAsU8a(length = 32) { + return browser.getRandomValues(new Uint8Array(length)); + } + const randomAsHex = createAsHex(randomAsU8a); + + const BN_53 = new util.BN(0b11111111111111111111111111111111111111111111111111111); + function randomAsNumber() { + return util.hexToBn(randomAsHex(8)).and(BN_53).toNumber(); + } + + /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ + const _0n$4 = BigInt(0), _1n$3 = BigInt(1), _2n$3 = BigInt(2), _8n$1 = BigInt(8); + function isEdValidXY(Fp, CURVE, x, y) { + const x2 = Fp.sqr(x); + const y2 = Fp.sqr(y); + const left = Fp.add(Fp.mul(CURVE.a, x2), y2); + const right = Fp.add(Fp.ONE, Fp.mul(CURVE.d, Fp.mul(x2, y2))); + return Fp.eql(left, right); + } + function edwards(params, extraOpts = {}) { + const validated = _createCurveFields('edwards', params, extraOpts, extraOpts.FpFnLE); + const { Fp, Fn } = validated; + let CURVE = validated.CURVE; + const { h: cofactor } = CURVE; + _validateObject(extraOpts, {}, { uvRatio: 'function' }); + const MASK = _2n$3 << (BigInt(Fn.BYTES * 8) - _1n$3); + const modP = (n) => Fp.create(n); + const uvRatio = extraOpts.uvRatio || + ((u, v) => { + try { + return { isValid: true, value: Fp.sqrt(Fp.div(u, v)) }; + } + catch (e) { + return { isValid: false, value: _0n$4 }; + } + }); + if (!isEdValidXY(Fp, CURVE, CURVE.Gx, CURVE.Gy)) + throw new Error('bad curve params: generator point'); + function acoord(title, n, banZero = false) { + const min = banZero ? _1n$3 : _0n$4; + aInRange$1('coordinate ' + title, n, min, MASK); + return n; + } + function aextpoint(other) { + if (!(other instanceof Point)) + throw new Error('ExtendedPoint expected'); + } + const toAffineMemo = memoized((p, iz) => { + const { X, Y, Z } = p; + const is0 = p.is0(); + if (iz == null) + iz = is0 ? _8n$1 : Fp.inv(Z); + const x = modP(X * iz); + const y = modP(Y * iz); + const zz = Fp.mul(Z, iz); + if (is0) + return { x: _0n$4, y: _1n$3 }; + if (zz !== _1n$3) + throw new Error('invZ was invalid'); + return { x, y }; + }); + const assertValidMemo = memoized((p) => { + const { a, d } = CURVE; + if (p.is0()) + throw new Error('bad point: ZERO'); + const { X, Y, Z, T } = p; + const X2 = modP(X * X); + const Y2 = modP(Y * Y); + const Z2 = modP(Z * Z); + const Z4 = modP(Z2 * Z2); + const aX2 = modP(X2 * a); + const left = modP(Z2 * modP(aX2 + Y2)); + const right = modP(Z4 + modP(d * modP(X2 * Y2))); + if (left !== right) + throw new Error('bad point: equation left != right (1)'); + const XY = modP(X * Y); + const ZT = modP(Z * T); + if (XY !== ZT) + throw new Error('bad point: equation left != right (2)'); + return true; + }); + class Point { + constructor(X, Y, Z, T) { + this.X = acoord('x', X); + this.Y = acoord('y', Y); + this.Z = acoord('z', Z, true); + this.T = acoord('t', T); + Object.freeze(this); + } + static CURVE() { + return CURVE; + } + static fromAffine(p) { + if (p instanceof Point) + throw new Error('extended point not allowed'); + const { x, y } = p || {}; + acoord('x', x); + acoord('y', y); + return new Point(x, y, _1n$3, modP(x * y)); + } + static fromBytes(bytes, zip215 = false) { + const len = Fp.BYTES; + const { a, d } = CURVE; + bytes = copyBytes(_abytes2(bytes, len, 'point')); + _abool2(zip215, 'zip215'); + const normed = copyBytes(bytes); + const lastByte = bytes[len - 1]; + normed[len - 1] = lastByte & -129; + const y = bytesToNumberLE$1(normed); + const max = zip215 ? MASK : Fp.ORDER; + aInRange$1('point.y', y, _0n$4, max); + const y2 = modP(y * y); + const u = modP(y2 - _1n$3); + const v = modP(d * y2 - a); + let { isValid, value: x } = uvRatio(u, v); + if (!isValid) + throw new Error('bad point: invalid y coordinate'); + const isXOdd = (x & _1n$3) === _1n$3; + const isLastByteOdd = (lastByte & 0x80) !== 0; + if (!zip215 && x === _0n$4 && isLastByteOdd) + throw new Error('bad point: x=0 and x_0=1'); + if (isLastByteOdd !== isXOdd) + x = modP(-x); + return Point.fromAffine({ x, y }); + } + static fromHex(bytes, zip215 = false) { + return Point.fromBytes(ensureBytes('point', bytes), zip215); + } + get x() { + return this.toAffine().x; + } + get y() { + return this.toAffine().y; + } + precompute(windowSize = 8, isLazy = true) { + wnaf.createCache(this, windowSize); + if (!isLazy) + this.multiply(_2n$3); + return this; + } + assertValidity() { + assertValidMemo(this); + } + equals(other) { + aextpoint(other); + const { X: X1, Y: Y1, Z: Z1 } = this; + const { X: X2, Y: Y2, Z: Z2 } = other; + const X1Z2 = modP(X1 * Z2); + const X2Z1 = modP(X2 * Z1); + const Y1Z2 = modP(Y1 * Z2); + const Y2Z1 = modP(Y2 * Z1); + return X1Z2 === X2Z1 && Y1Z2 === Y2Z1; + } + is0() { + return this.equals(Point.ZERO); + } + negate() { + return new Point(modP(-this.X), this.Y, this.Z, modP(-this.T)); + } + double() { + const { a } = CURVE; + const { X: X1, Y: Y1, Z: Z1 } = this; + const A = modP(X1 * X1); + const B = modP(Y1 * Y1); + const C = modP(_2n$3 * modP(Z1 * Z1)); + const D = modP(a * A); + const x1y1 = X1 + Y1; + const E = modP(modP(x1y1 * x1y1) - A - B); + const G = D + B; + const F = G - C; + const H = D - B; + const X3 = modP(E * F); + const Y3 = modP(G * H); + const T3 = modP(E * H); + const Z3 = modP(F * G); + return new Point(X3, Y3, Z3, T3); + } + add(other) { + aextpoint(other); + const { a, d } = CURVE; + const { X: X1, Y: Y1, Z: Z1, T: T1 } = this; + const { X: X2, Y: Y2, Z: Z2, T: T2 } = other; + const A = modP(X1 * X2); + const B = modP(Y1 * Y2); + const C = modP(T1 * d * T2); + const D = modP(Z1 * Z2); + const E = modP((X1 + Y1) * (X2 + Y2) - A - B); + const F = D - C; + const G = D + C; + const H = modP(B - a * A); + const X3 = modP(E * F); + const Y3 = modP(G * H); + const T3 = modP(E * H); + const Z3 = modP(F * G); + return new Point(X3, Y3, Z3, T3); + } + subtract(other) { + return this.add(other.negate()); + } + multiply(scalar) { + if (!Fn.isValidNot0(scalar)) + throw new Error('invalid scalar: expected 1 <= sc < curve.n'); + const { p, f } = wnaf.cached(this, scalar, (p) => normalizeZ(Point, p)); + return normalizeZ(Point, [p, f])[0]; + } + multiplyUnsafe(scalar, acc = Point.ZERO) { + if (!Fn.isValid(scalar)) + throw new Error('invalid scalar: expected 0 <= sc < curve.n'); + if (scalar === _0n$4) + return Point.ZERO; + if (this.is0() || scalar === _1n$3) + return this; + return wnaf.unsafe(this, scalar, (p) => normalizeZ(Point, p), acc); + } + isSmallOrder() { + return this.multiplyUnsafe(cofactor).is0(); + } + isTorsionFree() { + return wnaf.unsafe(this, CURVE.n).is0(); + } + toAffine(invertedZ) { + return toAffineMemo(this, invertedZ); + } + clearCofactor() { + if (cofactor === _1n$3) + return this; + return this.multiplyUnsafe(cofactor); + } + toBytes() { + const { x, y } = this.toAffine(); + const bytes = Fp.toBytes(y); + bytes[bytes.length - 1] |= x & _1n$3 ? 0x80 : 0; + return bytes; + } + toHex() { + return bytesToHex(this.toBytes()); + } + toString() { + return ``; + } + get ex() { + return this.X; + } + get ey() { + return this.Y; + } + get ez() { + return this.Z; + } + get et() { + return this.T; + } + static normalizeZ(points) { + return normalizeZ(Point, points); + } + static msm(points, scalars) { + return pippenger(Point, Fn, points, scalars); + } + _setWindowSize(windowSize) { + this.precompute(windowSize); + } + toRawBytes() { + return this.toBytes(); + } + } + Point.BASE = new Point(CURVE.Gx, CURVE.Gy, _1n$3, modP(CURVE.Gx * CURVE.Gy)); + Point.ZERO = new Point(_0n$4, _1n$3, _1n$3, _0n$4); + Point.Fp = Fp; + Point.Fn = Fn; + const wnaf = new wNAF(Point, Fn.BITS); + Point.BASE.precompute(8); + return Point; + } + class PrimeEdwardsPoint { + constructor(ep) { + this.ep = ep; + } + static fromBytes(_bytes) { + notImplemented(); + } + static fromHex(_hex) { + notImplemented(); + } + get x() { + return this.toAffine().x; + } + get y() { + return this.toAffine().y; + } + clearCofactor() { + return this; + } + assertValidity() { + this.ep.assertValidity(); + } + toAffine(invertedZ) { + return this.ep.toAffine(invertedZ); + } + toHex() { + return bytesToHex(this.toBytes()); + } + toString() { + return this.toHex(); + } + isTorsionFree() { + return true; + } + isSmallOrder() { + return false; + } + add(other) { + this.assertSame(other); + return this.init(this.ep.add(other.ep)); + } + subtract(other) { + this.assertSame(other); + return this.init(this.ep.subtract(other.ep)); + } + multiply(scalar) { + return this.init(this.ep.multiply(scalar)); + } + multiplyUnsafe(scalar) { + return this.init(this.ep.multiplyUnsafe(scalar)); + } + double() { + return this.init(this.ep.double()); + } + negate() { + return this.init(this.ep.negate()); + } + precompute(windowSize, isLazy) { + return this.init(this.ep.precompute(windowSize, isLazy)); + } + toRawBytes() { + return this.toBytes(); + } + } + function eddsa(Point, cHash, eddsaOpts = {}) { + if (typeof cHash !== 'function') + throw new Error('"hash" function param is required'); + _validateObject(eddsaOpts, {}, { + adjustScalarBytes: 'function', + randomBytes: 'function', + domain: 'function', + prehash: 'function', + mapToCurve: 'function', + }); + const { prehash } = eddsaOpts; + const { BASE, Fp, Fn } = Point; + const randomBytes$1 = eddsaOpts.randomBytes || randomBytes; + const adjustScalarBytes = eddsaOpts.adjustScalarBytes || ((bytes) => bytes); + const domain = eddsaOpts.domain || + ((data, ctx, phflag) => { + _abool2(phflag, 'phflag'); + if (ctx.length || phflag) + throw new Error('Contexts/pre-hash are not supported'); + return data; + }); + function modN_LE(hash) { + return Fn.create(bytesToNumberLE$1(hash)); + } + function getPrivateScalar(key) { + const len = lengths.secretKey; + key = ensureBytes('private key', key, len); + const hashed = ensureBytes('hashed private key', cHash(key), 2 * len); + const head = adjustScalarBytes(hashed.slice(0, len)); + const prefix = hashed.slice(len, 2 * len); + const scalar = modN_LE(head); + return { head, prefix, scalar }; + } + function getExtendedPublicKey(secretKey) { + const { head, prefix, scalar } = getPrivateScalar(secretKey); + const point = BASE.multiply(scalar); + const pointBytes = point.toBytes(); + return { head, prefix, scalar, point, pointBytes }; + } + function getPublicKey(secretKey) { + return getExtendedPublicKey(secretKey).pointBytes; + } + function hashDomainToScalar(context = Uint8Array.of(), ...msgs) { + const msg = concatBytes(...msgs); + return modN_LE(cHash(domain(msg, ensureBytes('context', context), !!prehash))); + } + function sign(msg, secretKey, options = {}) { + msg = ensureBytes('message', msg); + if (prehash) + msg = prehash(msg); + const { prefix, scalar, pointBytes } = getExtendedPublicKey(secretKey); + const r = hashDomainToScalar(options.context, prefix, msg); + const R = BASE.multiply(r).toBytes(); + const k = hashDomainToScalar(options.context, R, pointBytes, msg); + const s = Fn.create(r + k * scalar); + if (!Fn.isValid(s)) + throw new Error('sign failed: invalid s'); + const rs = concatBytes(R, Fn.toBytes(s)); + return _abytes2(rs, lengths.signature, 'result'); + } + const verifyOpts = { zip215: true }; + function verify(sig, msg, publicKey, options = verifyOpts) { + const { context, zip215 } = options; + const len = lengths.signature; + sig = ensureBytes('signature', sig, len); + msg = ensureBytes('message', msg); + publicKey = ensureBytes('publicKey', publicKey, lengths.publicKey); + if (zip215 !== undefined) + _abool2(zip215, 'zip215'); + if (prehash) + msg = prehash(msg); + const mid = len / 2; + const r = sig.subarray(0, mid); + const s = bytesToNumberLE$1(sig.subarray(mid, len)); + let A, R, SB; + try { + A = Point.fromBytes(publicKey, zip215); + R = Point.fromBytes(r, zip215); + SB = BASE.multiplyUnsafe(s); + } + catch (error) { + return false; + } + if (!zip215 && A.isSmallOrder()) + return false; + const k = hashDomainToScalar(context, R.toBytes(), A.toBytes(), msg); + const RkA = R.add(A.multiplyUnsafe(k)); + return RkA.subtract(SB).clearCofactor().is0(); + } + const _size = Fp.BYTES; + const lengths = { + secretKey: _size, + publicKey: _size, + signature: 2 * _size, + seed: _size, + }; + function randomSecretKey(seed = randomBytes$1(lengths.seed)) { + return _abytes2(seed, lengths.seed, 'seed'); + } + function keygen(seed) { + const secretKey = utils.randomSecretKey(seed); + return { secretKey, publicKey: getPublicKey(secretKey) }; + } + function isValidSecretKey(key) { + return isBytes$1(key) && key.length === Fn.BYTES; + } + function isValidPublicKey(key, zip215) { + try { + return !!Point.fromBytes(key, zip215); + } + catch (error) { + return false; + } + } + const utils = { + getExtendedPublicKey, + randomSecretKey, + isValidSecretKey, + isValidPublicKey, + toMontgomery(publicKey) { + const { y } = Point.fromBytes(publicKey); + const size = lengths.publicKey; + const is25519 = size === 32; + if (!is25519 && size !== 57) + throw new Error('only defined for 25519 and 448'); + const u = is25519 ? Fp.div(_1n$3 + y, _1n$3 - y) : Fp.div(y - _1n$3, y + _1n$3); + return Fp.toBytes(u); + }, + toMontgomerySecret(secretKey) { + const size = lengths.secretKey; + _abytes2(secretKey, size); + const hashed = cHash(secretKey.subarray(0, size)); + return adjustScalarBytes(hashed).subarray(0, size); + }, + randomPrivateKey: randomSecretKey, + precompute(windowSize = 8, point = Point.BASE) { + return point.precompute(windowSize, false); + }, + }; + return Object.freeze({ + keygen, + getPublicKey, + sign, + verify, + utils, + Point, + lengths, + }); + } + function _eddsa_legacy_opts_to_new(c) { + const CURVE = { + a: c.a, + d: c.d, + p: c.Fp.ORDER, + n: c.n, + h: c.h, + Gx: c.Gx, + Gy: c.Gy, + }; + const Fp = c.Fp; + const Fn = Field(CURVE.n, c.nBitLength, true); + const curveOpts = { Fp, Fn, uvRatio: c.uvRatio }; + const eddsaOpts = { + randomBytes: c.randomBytes, + adjustScalarBytes: c.adjustScalarBytes, + domain: c.domain, + prehash: c.prehash, + mapToCurve: c.mapToCurve, + }; + return { CURVE, curveOpts, hash: c.hash, eddsaOpts }; + } + function _eddsa_new_output_to_legacy(c, eddsa) { + const Point = eddsa.Point; + const legacy = Object.assign({}, eddsa, { + ExtendedPoint: Point, + CURVE: c, + nBitLength: Point.Fn.BITS, + nByteLength: Point.Fn.BYTES, + }); + return legacy; + } + function twistedEdwards(c) { + const { CURVE, curveOpts, hash, eddsaOpts } = _eddsa_legacy_opts_to_new(c); + const Point = edwards(CURVE, curveOpts); + const EDDSA = eddsa(Point, hash, eddsaOpts); + return _eddsa_new_output_to_legacy(c, EDDSA); + } + + /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ + const _0n$3 = BigInt(0); + const _1n$2 = BigInt(1); + const _2n$2 = BigInt(2); + function validateOpts(curve) { + _validateObject(curve, { + adjustScalarBytes: 'function', + powPminus2: 'function', + }); + return Object.freeze({ ...curve }); + } + function montgomery(curveDef) { + const CURVE = validateOpts(curveDef); + const { P, type, adjustScalarBytes, powPminus2, randomBytes: rand } = CURVE; + const is25519 = type === 'x25519'; + if (!is25519 && type !== 'x448') + throw new Error('invalid type'); + const randomBytes_ = rand || randomBytes; + const montgomeryBits = is25519 ? 255 : 448; + const fieldLen = is25519 ? 32 : 56; + const Gu = is25519 ? BigInt(9) : BigInt(5); + const a24 = is25519 ? BigInt(121665) : BigInt(39081); + const minScalar = is25519 ? _2n$2 ** BigInt(254) : _2n$2 ** BigInt(447); + const maxAdded = is25519 + ? BigInt(8) * _2n$2 ** BigInt(251) - _1n$2 + : BigInt(4) * _2n$2 ** BigInt(445) - _1n$2; + const maxScalar = minScalar + maxAdded + _1n$2; + const modP = (n) => mod(n, P); + const GuBytes = encodeU(Gu); + function encodeU(u) { + return numberToBytesLE$1(modP(u), fieldLen); + } + function decodeU(u) { + const _u = ensureBytes('u coordinate', u, fieldLen); + if (is25519) + _u[31] &= 127; + return modP(bytesToNumberLE$1(_u)); + } + function decodeScalar(scalar) { + return bytesToNumberLE$1(adjustScalarBytes(ensureBytes('scalar', scalar, fieldLen))); + } + function scalarMult(scalar, u) { + const pu = montgomeryLadder(decodeU(u), decodeScalar(scalar)); + if (pu === _0n$3) + throw new Error('invalid private or public key received'); + return encodeU(pu); + } + function scalarMultBase(scalar) { + return scalarMult(scalar, GuBytes); + } + function cswap(swap, x_2, x_3) { + const dummy = modP(swap * (x_2 - x_3)); + x_2 = modP(x_2 - dummy); + x_3 = modP(x_3 + dummy); + return { x_2, x_3 }; + } + function montgomeryLadder(u, scalar) { + aInRange$1('u', u, _0n$3, P); + aInRange$1('scalar', scalar, minScalar, maxScalar); + const k = scalar; + const x_1 = u; + let x_2 = _1n$2; + let z_2 = _0n$3; + let x_3 = u; + let z_3 = _1n$2; + let swap = _0n$3; + for (let t = BigInt(montgomeryBits - 1); t >= _0n$3; t--) { + const k_t = (k >> t) & _1n$2; + swap ^= k_t; + ({ x_2, x_3 } = cswap(swap, x_2, x_3)); + ({ x_2: z_2, x_3: z_3 } = cswap(swap, z_2, z_3)); + swap = k_t; + const A = x_2 + z_2; + const AA = modP(A * A); + const B = x_2 - z_2; + const BB = modP(B * B); + const E = AA - BB; + const C = x_3 + z_3; + const D = x_3 - z_3; + const DA = modP(D * A); + const CB = modP(C * B); + const dacb = DA + CB; + const da_cb = DA - CB; + x_3 = modP(dacb * dacb); + z_3 = modP(x_1 * modP(da_cb * da_cb)); + x_2 = modP(AA * BB); + z_2 = modP(E * (AA + modP(a24 * E))); + } + ({ x_2, x_3 } = cswap(swap, x_2, x_3)); + ({ x_2: z_2, x_3: z_3 } = cswap(swap, z_2, z_3)); + const z2 = powPminus2(z_2); + return modP(x_2 * z2); + } + const lengths = { + secretKey: fieldLen, + publicKey: fieldLen, + seed: fieldLen, + }; + const randomSecretKey = (seed = randomBytes_(fieldLen)) => { + abytes$1(seed, lengths.seed); + return seed; + }; + function keygen(seed) { + const secretKey = randomSecretKey(seed); + return { secretKey, publicKey: scalarMultBase(secretKey) }; + } + const utils = { + randomSecretKey, + randomPrivateKey: randomSecretKey, + }; + return { + keygen, + getSharedSecret: (secretKey, publicKey) => scalarMult(secretKey, publicKey), + getPublicKey: (secretKey) => scalarMultBase(secretKey), + scalarMult, + scalarMultBase, + utils, + GuBytes: GuBytes.slice(), + lengths, + }; + } + + /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ + const _0n$2 = BigInt(0), _1n$1 = BigInt(1), _2n$1 = BigInt(2), _3n$1 = BigInt(3); + const _5n = BigInt(5), _8n = BigInt(8); + const ed25519_CURVE_p = BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed'); + const ed25519_CURVE = (() => ({ + p: ed25519_CURVE_p, + n: BigInt('0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed'), + h: _8n, + a: BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec'), + d: BigInt('0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3'), + Gx: BigInt('0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a'), + Gy: BigInt('0x6666666666666666666666666666666666666666666666666666666666666658'), + }))(); + function ed25519_pow_2_252_3(x) { + const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80); + const P = ed25519_CURVE_p; + const x2 = (x * x) % P; + const b2 = (x2 * x) % P; + const b4 = (pow2(b2, _2n$1, P) * b2) % P; + const b5 = (pow2(b4, _1n$1, P) * x) % P; + const b10 = (pow2(b5, _5n, P) * b5) % P; + const b20 = (pow2(b10, _10n, P) * b10) % P; + const b40 = (pow2(b20, _20n, P) * b20) % P; + const b80 = (pow2(b40, _40n, P) * b40) % P; + const b160 = (pow2(b80, _80n, P) * b80) % P; + const b240 = (pow2(b160, _80n, P) * b80) % P; + const b250 = (pow2(b240, _10n, P) * b10) % P; + const pow_p_5_8 = (pow2(b250, _2n$1, P) * x) % P; + return { pow_p_5_8, b2 }; + } + function adjustScalarBytes(bytes) { + bytes[0] &= 248; + bytes[31] &= 127; + bytes[31] |= 64; + return bytes; + } + const ED25519_SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752'); + function uvRatio(u, v) { + const P = ed25519_CURVE_p; + const v3 = mod(v * v * v, P); + const v7 = mod(v3 * v3 * v, P); + const pow = ed25519_pow_2_252_3(u * v7).pow_p_5_8; + let x = mod(u * v3 * pow, P); + const vx2 = mod(v * x * x, P); + const root1 = x; + const root2 = mod(x * ED25519_SQRT_M1, P); + const useRoot1 = vx2 === u; + const useRoot2 = vx2 === mod(-u, P); + const noRoot = vx2 === mod(-u * ED25519_SQRT_M1, P); + if (useRoot1) + x = root1; + if (useRoot2 || noRoot) + x = root2; + if (isNegativeLE(x, P)) + x = mod(-x, P); + return { isValid: useRoot1 || useRoot2, value: x }; + } + const Fp = (() => Field(ed25519_CURVE.p, { isLE: true }))(); + const Fn = (() => Field(ed25519_CURVE.n, { isLE: true }))(); + const ed25519Defaults = (() => ({ + ...ed25519_CURVE, + Fp, + hash: sha512$1, + adjustScalarBytes, + uvRatio, + }))(); + const ed25519 = (() => twistedEdwards(ed25519Defaults))(); + function ed25519_domain(data, ctx, phflag) { + if (ctx.length > 255) + throw new Error('Context is too big'); + return concatBytes(utf8ToBytes('SigEd25519 no Ed25519 collisions'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data); + } + (() => twistedEdwards({ + ...ed25519Defaults, + domain: ed25519_domain, + }))(); + (() => twistedEdwards(Object.assign({}, ed25519Defaults, { + domain: ed25519_domain, + prehash: sha512$1, + })))(); + (() => { + const P = Fp.ORDER; + return montgomery({ + P, + type: 'x25519', + powPminus2: (x) => { + const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x); + return mod(pow2(pow_p_5_8, _3n$1, P) * b2, P); + }, + adjustScalarBytes, + }); + })(); + const ELL2_C1 = (() => (ed25519_CURVE_p + _3n$1) / _8n)(); + const ELL2_C2 = (() => Fp.pow(_2n$1, ELL2_C1))(); + const ELL2_C3 = (() => Fp.sqrt(Fp.neg(Fp.ONE)))(); + function map_to_curve_elligator2_curve25519(u) { + const ELL2_C4 = (ed25519_CURVE_p - _5n) / _8n; + const ELL2_J = BigInt(486662); + let tv1 = Fp.sqr(u); + tv1 = Fp.mul(tv1, _2n$1); + let xd = Fp.add(tv1, Fp.ONE); + let x1n = Fp.neg(ELL2_J); + let tv2 = Fp.sqr(xd); + let gxd = Fp.mul(tv2, xd); + let gx1 = Fp.mul(tv1, ELL2_J); + gx1 = Fp.mul(gx1, x1n); + gx1 = Fp.add(gx1, tv2); + gx1 = Fp.mul(gx1, x1n); + let tv3 = Fp.sqr(gxd); + tv2 = Fp.sqr(tv3); + tv3 = Fp.mul(tv3, gxd); + tv3 = Fp.mul(tv3, gx1); + tv2 = Fp.mul(tv2, tv3); + let y11 = Fp.pow(tv2, ELL2_C4); + y11 = Fp.mul(y11, tv3); + let y12 = Fp.mul(y11, ELL2_C3); + tv2 = Fp.sqr(y11); + tv2 = Fp.mul(tv2, gxd); + let e1 = Fp.eql(tv2, gx1); + let y1 = Fp.cmov(y12, y11, e1); + let x2n = Fp.mul(x1n, tv1); + let y21 = Fp.mul(y11, u); + y21 = Fp.mul(y21, ELL2_C2); + let y22 = Fp.mul(y21, ELL2_C3); + let gx2 = Fp.mul(gx1, tv1); + tv2 = Fp.sqr(y21); + tv2 = Fp.mul(tv2, gxd); + let e2 = Fp.eql(tv2, gx2); + let y2 = Fp.cmov(y22, y21, e2); + tv2 = Fp.sqr(y1); + tv2 = Fp.mul(tv2, gxd); + let e3 = Fp.eql(tv2, gx1); + let xn = Fp.cmov(x2n, x1n, e3); + let y = Fp.cmov(y2, y1, e3); + let e4 = Fp.isOdd(y); + y = Fp.cmov(y, Fp.neg(y), e3 !== e4); + return { xMn: xn, xMd: xd, yMn: y, yMd: _1n$1 }; + } + const ELL2_C1_EDWARDS = (() => FpSqrtEven(Fp, Fp.neg(BigInt(486664))))(); + function map_to_curve_elligator2_edwards25519(u) { + const { xMn, xMd, yMn, yMd } = map_to_curve_elligator2_curve25519(u); + let xn = Fp.mul(xMn, yMd); + xn = Fp.mul(xn, ELL2_C1_EDWARDS); + let xd = Fp.mul(xMd, yMn); + let yn = Fp.sub(xMn, xMd); + let yd = Fp.add(xMn, xMd); + let tv1 = Fp.mul(xd, yd); + let e = Fp.eql(tv1, Fp.ZERO); + xn = Fp.cmov(xn, Fp.ZERO, e); + xd = Fp.cmov(xd, Fp.ONE, e); + yn = Fp.cmov(yn, Fp.ONE, e); + yd = Fp.cmov(yd, Fp.ONE, e); + const [xd_inv, yd_inv] = FpInvertBatch(Fp, [xd, yd], true); + return { x: Fp.mul(xn, xd_inv), y: Fp.mul(yn, yd_inv) }; + } + (() => createHasher(ed25519.Point, (scalars) => map_to_curve_elligator2_edwards25519(scalars[0]), { + DST: 'edwards25519_XMD:SHA-512_ELL2_RO_', + encodeDST: 'edwards25519_XMD:SHA-512_ELL2_NU_', + p: ed25519_CURVE_p, + m: 1, + k: 128, + expand: 'xmd', + hash: sha512$1, + }))(); + const SQRT_M1 = ED25519_SQRT_M1; + const SQRT_AD_MINUS_ONE = BigInt('25063068953384623474111414158702152701244531502492656460079210482610430750235'); + const INVSQRT_A_MINUS_D = BigInt('54469307008909316920995813868745141605393597292927456921205312896311721017578'); + const ONE_MINUS_D_SQ = BigInt('1159843021668779879193775521855586647937357759715417654439879720876111806838'); + const D_MINUS_ONE_SQ = BigInt('40440834346308536858101042469323190826248399146238708352240133220865137265952'); + const invertSqrt = (number) => uvRatio(_1n$1, number); + const MAX_255B = BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'); + const bytes255ToNumberLE = (bytes) => ed25519.Point.Fp.create(bytesToNumberLE$1(bytes) & MAX_255B); + function calcElligatorRistrettoMap(r0) { + const { d } = ed25519_CURVE; + const P = ed25519_CURVE_p; + const mod = (n) => Fp.create(n); + const r = mod(SQRT_M1 * r0 * r0); + const Ns = mod((r + _1n$1) * ONE_MINUS_D_SQ); + let c = BigInt(-1); + const D = mod((c - d * r) * mod(r + d)); + let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D); + let s_ = mod(s * r0); + if (!isNegativeLE(s_, P)) + s_ = mod(-s_); + if (!Ns_D_is_sq) + s = s_; + if (!Ns_D_is_sq) + c = r; + const Nt = mod(c * (r - _1n$1) * D_MINUS_ONE_SQ - D); + const s2 = s * s; + const W0 = mod((s + s) * D); + const W1 = mod(Nt * SQRT_AD_MINUS_ONE); + const W2 = mod(_1n$1 - s2); + const W3 = mod(_1n$1 + s2); + return new ed25519.Point(mod(W0 * W3), mod(W2 * W1), mod(W1 * W3), mod(W0 * W2)); + } + function ristretto255_map(bytes) { + abytes$1(bytes, 64); + const r1 = bytes255ToNumberLE(bytes.subarray(0, 32)); + const R1 = calcElligatorRistrettoMap(r1); + const r2 = bytes255ToNumberLE(bytes.subarray(32, 64)); + const R2 = calcElligatorRistrettoMap(r2); + return new _RistrettoPoint(R1.add(R2)); + } + class _RistrettoPoint extends PrimeEdwardsPoint { + constructor(ep) { + super(ep); + } + static fromAffine(ap) { + return new _RistrettoPoint(ed25519.Point.fromAffine(ap)); + } + assertSame(other) { + if (!(other instanceof _RistrettoPoint)) + throw new Error('RistrettoPoint expected'); + } + init(ep) { + return new _RistrettoPoint(ep); + } + static hashToCurve(hex) { + return ristretto255_map(ensureBytes('ristrettoHash', hex, 64)); + } + static fromBytes(bytes) { + abytes$1(bytes, 32); + const { a, d } = ed25519_CURVE; + const P = ed25519_CURVE_p; + const mod = (n) => Fp.create(n); + const s = bytes255ToNumberLE(bytes); + if (!equalBytes(Fp.toBytes(s), bytes) || isNegativeLE(s, P)) + throw new Error('invalid ristretto255 encoding 1'); + const s2 = mod(s * s); + const u1 = mod(_1n$1 + a * s2); + const u2 = mod(_1n$1 - a * s2); + const u1_2 = mod(u1 * u1); + const u2_2 = mod(u2 * u2); + const v = mod(a * d * u1_2 - u2_2); + const { isValid, value: I } = invertSqrt(mod(v * u2_2)); + const Dx = mod(I * u2); + const Dy = mod(I * Dx * v); + let x = mod((s + s) * Dx); + if (isNegativeLE(x, P)) + x = mod(-x); + const y = mod(u1 * Dy); + const t = mod(x * y); + if (!isValid || isNegativeLE(t, P) || y === _0n$2) + throw new Error('invalid ristretto255 encoding 2'); + return new _RistrettoPoint(new ed25519.Point(x, y, _1n$1, t)); + } + static fromHex(hex) { + return _RistrettoPoint.fromBytes(ensureBytes('ristrettoHex', hex, 32)); + } + static msm(points, scalars) { + return pippenger(_RistrettoPoint, ed25519.Point.Fn, points, scalars); + } + toBytes() { + let { X, Y, Z, T } = this.ep; + const P = ed25519_CURVE_p; + const mod = (n) => Fp.create(n); + const u1 = mod(mod(Z + Y) * mod(Z - Y)); + const u2 = mod(X * Y); + const u2sq = mod(u2 * u2); + const { value: invsqrt } = invertSqrt(mod(u1 * u2sq)); + const D1 = mod(invsqrt * u1); + const D2 = mod(invsqrt * u2); + const zInv = mod(D1 * D2 * T); + let D; + if (isNegativeLE(T * zInv, P)) { + let _x = mod(Y * SQRT_M1); + let _y = mod(X * SQRT_M1); + X = _x; + Y = _y; + D = mod(D1 * INVSQRT_A_MINUS_D); + } + else { + D = D2; + } + if (isNegativeLE(X * zInv, P)) + Y = mod(-Y); + let s = mod((Z - Y) * D); + if (isNegativeLE(s, P)) + s = mod(-s); + return Fp.toBytes(s); + } + equals(other) { + this.assertSame(other); + const { X: X1, Y: Y1 } = this.ep; + const { X: X2, Y: Y2 } = other.ep; + const mod = (n) => Fp.create(n); + const one = mod(X1 * Y2) === mod(Y1 * X2); + const two = mod(Y1 * Y2) === mod(X1 * X2); + return one || two; + } + is0() { + return this.equals(_RistrettoPoint.ZERO); + } + } + _RistrettoPoint.BASE = + (() => new _RistrettoPoint(ed25519.Point.BASE))(); + _RistrettoPoint.ZERO = + (() => new _RistrettoPoint(ed25519.Point.ZERO))(); + _RistrettoPoint.Fp = + (() => Fp)(); + _RistrettoPoint.Fn = + (() => Fn)(); + const RistrettoPoint = _RistrettoPoint; + + function ed25519PairFromSeed(seed, onlyJs) { + if (!util.hasBigInt || (!onlyJs && isReady())) { + const full = ed25519KeypairFromSeed(seed); + return { + publicKey: full.slice(32), + secretKey: full.slice(0, 64) + }; + } + const publicKey = ed25519.getPublicKey(seed); + return { + publicKey, + secretKey: util.u8aConcatStrict([seed, publicKey]) + }; + } + + function ed25519PairFromRandom() { + return ed25519PairFromSeed(randomAsU8a()); + } + + function ed25519PairFromSecret(secretKey) { + if (secretKey.length !== 64) { + throw new Error('Invalid secretKey provided'); + } + return { + publicKey: secretKey.slice(32), + secretKey + }; + } + + function ed25519PairFromString(value) { + return ed25519PairFromSeed(blake2AsU8a(util.stringToU8a(value))); + } + + function ed25519Sign(message, { publicKey, secretKey }, onlyJs) { + if (!secretKey) { + throw new Error('Expected a valid secretKey'); + } + else if (!publicKey) { + throw new Error('Expected a valid publicKey'); + } + const messageU8a = util.u8aToU8a(message); + const privateU8a = secretKey.subarray(0, 32); + return !util.hasBigInt || (!onlyJs && isReady()) + ? ed25519Sign$1(publicKey, privateU8a, messageU8a) + : ed25519.sign(messageU8a, privateU8a); + } + + function ed25519Verify(message, signature, publicKey, onlyJs) { + const messageU8a = util.u8aToU8a(message); + const publicKeyU8a = util.u8aToU8a(publicKey); + const signatureU8a = util.u8aToU8a(signature); + if (publicKeyU8a.length !== 32) { + throw new Error(`Invalid publicKey, received ${publicKeyU8a.length}, expected 32`); + } + else if (signatureU8a.length !== 64) { + throw new Error(`Invalid signature, received ${signatureU8a.length} bytes, expected 64`); + } + try { + return !util.hasBigInt || (!onlyJs && isReady()) + ? ed25519Verify$1(signatureU8a, messageU8a, publicKeyU8a) + : ed25519.verify(signatureU8a, messageU8a, publicKeyU8a); + } + catch { + return false; + } + } + + const keyHdkdEd25519 = createSeedDeriveFn(ed25519PairFromSeed, ed25519DeriveHard); + + const isBytes = isBytes$1; + const bytesToNumberLE = bytesToNumberLE$1; + const numberToBytesLE = numberToBytesLE$1; + const aInRange = aInRange$1; + const bitMask = bitMask$1; + + const _0n$1 = BigInt(0); + const _1n = BigInt(1); + const _2n = BigInt(2); + const _7n$1 = BigInt(7); + const _256n$1 = BigInt(256); + const _0x71n = BigInt(0x71); + const SHA3_PI = []; + const SHA3_ROTL = []; + const _SHA3_IOTA = []; + for (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) { + [x, y] = [y, (2 * x + 3 * y) % 5]; + SHA3_PI.push(2 * (5 * y + x)); + SHA3_ROTL.push((((round + 1) * (round + 2)) / 2) % 64); + let t = _0n$1; + for (let j = 0; j < 7; j++) { + R = ((R << _1n) ^ ((R >> _7n$1) * _0x71n)) % _256n$1; + if (R & _2n) + t ^= _1n << ((_1n << BigInt(j)) - _1n); + } + _SHA3_IOTA.push(t); + } + const IOTAS = split(_SHA3_IOTA, true); + const SHA3_IOTA_H = IOTAS[0]; + const SHA3_IOTA_L = IOTAS[1]; + const rotlH = (h, l, s) => (s > 32 ? rotlBH(h, l, s) : rotlSH(h, l, s)); + const rotlL = (h, l, s) => (s > 32 ? rotlBL(h, l, s) : rotlSL(h, l, s)); + function keccakP(s, rounds = 24) { + const B = new Uint32Array(5 * 2); + for (let round = 24 - rounds; round < 24; round++) { + for (let x = 0; x < 10; x++) + B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40]; + for (let x = 0; x < 10; x += 2) { + const idx1 = (x + 8) % 10; + const idx0 = (x + 2) % 10; + const B0 = B[idx0]; + const B1 = B[idx0 + 1]; + const Th = rotlH(B0, B1, 1) ^ B[idx1]; + const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1]; + for (let y = 0; y < 50; y += 10) { + s[x + y] ^= Th; + s[x + y + 1] ^= Tl; + } + } + let curH = s[2]; + let curL = s[3]; + for (let t = 0; t < 24; t++) { + const shift = SHA3_ROTL[t]; + const Th = rotlH(curH, curL, shift); + const Tl = rotlL(curH, curL, shift); + const PI = SHA3_PI[t]; + curH = s[PI]; + curL = s[PI + 1]; + s[PI] = Th; + s[PI + 1] = Tl; + } + for (let y = 0; y < 50; y += 10) { + for (let x = 0; x < 10; x++) + B[x] = s[y + x]; + for (let x = 0; x < 10; x++) + s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10]; + } + s[0] ^= SHA3_IOTA_H[round]; + s[1] ^= SHA3_IOTA_L[round]; + } + clean(B); + } + class Keccak extends Hash { + constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) { + super(); + this.pos = 0; + this.posOut = 0; + this.finished = false; + this.destroyed = false; + this.enableXOF = false; + this.blockLen = blockLen; + this.suffix = suffix; + this.outputLen = outputLen; + this.enableXOF = enableXOF; + this.rounds = rounds; + anumber(outputLen); + if (!(0 < blockLen && blockLen < 200)) + throw new Error('only keccak-f1600 function is supported'); + this.state = new Uint8Array(200); + this.state32 = u32(this.state); + } + clone() { + return this._cloneInto(); + } + keccak() { + swap32IfBE(this.state32); + keccakP(this.state32, this.rounds); + swap32IfBE(this.state32); + this.posOut = 0; + this.pos = 0; + } + update(data) { + aexists(this); + data = toBytes(data); + abytes$1(data); + const { blockLen, state } = this; + const len = data.length; + for (let pos = 0; pos < len;) { + const take = Math.min(blockLen - this.pos, len - pos); + for (let i = 0; i < take; i++) + state[this.pos++] ^= data[pos++]; + if (this.pos === blockLen) + this.keccak(); + } + return this; + } + finish() { + if (this.finished) + return; + this.finished = true; + const { state, suffix, pos, blockLen } = this; + state[pos] ^= suffix; + if ((suffix & 0x80) !== 0 && pos === blockLen - 1) + this.keccak(); + state[blockLen - 1] ^= 0x80; + this.keccak(); + } + writeInto(out) { + aexists(this, false); + abytes$1(out); + this.finish(); + const bufferOut = this.state; + const { blockLen } = this; + for (let pos = 0, len = out.length; pos < len;) { + if (this.posOut >= blockLen) + this.keccak(); + const take = Math.min(blockLen - this.posOut, len - pos); + out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos); + this.posOut += take; + pos += take; + } + return out; + } + xofInto(out) { + if (!this.enableXOF) + throw new Error('XOF is not possible for this instance'); + return this.writeInto(out); + } + xof(bytes) { + anumber(bytes); + return this.xofInto(new Uint8Array(bytes)); + } + digestInto(out) { + aoutput(out, this); + if (this.finished) + throw new Error('digest() was already called'); + this.writeInto(out); + this.destroy(); + return out; + } + digest() { + return this.digestInto(new Uint8Array(this.outputLen)); + } + destroy() { + this.destroyed = true; + clean(this.state); + } + _cloneInto(to) { + const { blockLen, suffix, outputLen, rounds, enableXOF } = this; + to || (to = new Keccak(blockLen, suffix, outputLen, enableXOF, rounds)); + to.state32.set(this.state32); + to.pos = this.pos; + to.posOut = this.posOut; + to.finished = this.finished; + to.rounds = rounds; + to.suffix = suffix; + to.outputLen = outputLen; + to.enableXOF = enableXOF; + to.destroyed = this.destroyed; + return to; + } + } + const gen = (suffix, blockLen, outputLen) => createHasher$1(() => new Keccak(blockLen, suffix, outputLen)); + (() => gen(0x06, 144, 224 / 8))(); + (() => gen(0x06, 136, 256 / 8))(); + (() => gen(0x06, 104, 384 / 8))(); + (() => gen(0x06, 72, 512 / 8))(); + (() => gen(0x01, 144, 224 / 8))(); + const keccak_256 = (() => gen(0x01, 136, 256 / 8))(); + (() => gen(0x01, 104, 384 / 8))(); + const keccak_512 = (() => gen(0x01, 72, 512 / 8))(); + const genShake = (suffix, blockLen, outputLen) => createXOFer((opts = {}) => new Keccak(blockLen, suffix, opts.dkLen === undefined ? outputLen : opts.dkLen, true)); + (() => genShake(0x1f, 168, 128 / 8))(); + (() => genShake(0x1f, 136, 256 / 8))(); + + const sha512 = sha512$1; + + const _0n = BigInt(0), _3n = BigInt(3); + function toData(d) { + if (typeof d === 'string') + return utf8ToBytes(d); + if (isBytes(d)) + return d; + throw new Error('Wrong data'); + } + function abytes(title, b, ...lengths) { + if (!isBytes(b)) + throw new Error(`${title}: Uint8Array expected`); + if (lengths.length && !lengths.includes(b.length)) + throw new Error(`${title}: Uint8Array expected of length ${lengths}, not of length=${b.length}`); + } + function checkU32(title, n) { + if (!Number.isSafeInteger(n) || n < 0 || n > 4294967295) + throw new Error(`${title}: wrong u32 integer: ${n}`); + return n; + } + function cleanBytes(...list) { + for (const t of list) + t.fill(0); + } + const EMPTY = Uint8Array.of(); + const CURVE_ORDER = ed25519.CURVE.n; + function parseScalar(title, bytes) { + abytes(title, bytes, 32); + const n = bytesToNumberLE(bytes); + aInRange(title, n, _0n, CURVE_ORDER); + return n; + } + const modN = (n) => mod(n, CURVE_ORDER); + const STROBE_R = 166; + const Flags = { + I: 1, + A: 1 << 1, + C: 1 << 2, + T: 1 << 3, + M: 1 << 4, + K: 1 << 5, + }; + class Strobe128 { + constructor(protocolLabel) { + this.state = new Uint8Array(200); + this.pos = 0; + this.posBegin = 0; + this.curFlags = 0; + this.state.set([1, STROBE_R + 2, 1, 0, 1, 96], 0); + this.state.set(utf8ToBytes('STROBEv1.0.2'), 6); + this.state32 = u32(this.state); + this.keccakF1600(); + this.metaAD(protocolLabel, false); + } + keccakF1600() { + keccakP(this.state32); + } + runF() { + this.state[this.pos] ^= this.posBegin; + this.state[this.pos + 1] ^= 0x04; + this.state[STROBE_R + 1] ^= 0x80; + this.keccakF1600(); + this.pos = 0; + this.posBegin = 0; + } + absorb(data) { + for (let i = 0; i < data.length; i++) { + this.state[this.pos++] ^= data[i]; + if (this.pos === STROBE_R) + this.runF(); + } + } + squeeze(len) { + const data = new Uint8Array(len); + for (let i = 0; i < data.length; i++) { + data[i] = this.state[this.pos]; + this.state[this.pos++] = 0; + if (this.pos === STROBE_R) + this.runF(); + } + return data; + } + overwrite(data) { + for (let i = 0; i < data.length; i++) { + this.state[this.pos++] = data[i]; + if (this.pos === STROBE_R) + this.runF(); + } + } + beginOp(flags, more) { + if (more) { + if (this.curFlags !== flags) { + throw new Error(`Continued op with changed flags from ${this.curFlags.toString(2)} to ${flags.toString(2)}`); + } + return; + } + if ((flags & Flags.T) !== 0) + throw new Error('T flag is not supported'); + const oldBegin = this.posBegin; + this.posBegin = this.pos + 1; + this.curFlags = flags; + this.absorb(new Uint8Array([oldBegin, flags])); + const forceF = (flags & (Flags.C | Flags.K)) !== 0; + if (forceF && this.pos !== 0) + this.runF(); + } + metaAD(data, more) { + this.beginOp(Flags.M | Flags.A, more); + this.absorb(toData(data)); + } + AD(data, more) { + this.beginOp(Flags.A, more); + this.absorb(toData(data)); + } + PRF(len, more) { + this.beginOp(Flags.I | Flags.A | Flags.C, more); + return this.squeeze(len); + } + KEY(data, more) { + this.beginOp(Flags.A | Flags.C, more); + this.overwrite(toData(data)); + } + clone() { + const n = new Strobe128('0'); + n.pos = this.pos; + n.posBegin = this.posBegin; + n.state.set(this.state); + n.curFlags = this.curFlags; + return n; + } + clean() { + this.state.fill(0); + this.pos = 0; + this.curFlags = 0; + this.posBegin = 0; + } + } + class Merlin { + constructor(label) { + this.strobe = new Strobe128('Merlin v1.0'); + this.appendMessage('dom-sep', label); + } + appendMessage(label, message) { + this.strobe.metaAD(label, false); + checkU32('Merlin.appendMessage', message.length); + this.strobe.metaAD(numberToBytesLE(message.length, 4), true); + this.strobe.AD(message, false); + } + challengeBytes(label, len) { + this.strobe.metaAD(label, false); + checkU32('Merlin.challengeBytes', len); + this.strobe.metaAD(numberToBytesLE(len, 4), true); + return this.strobe.PRF(len, false); + } + clean() { + this.strobe.clean(); + } + } + class SigningContext extends Merlin { + constructor(name, rng = randomBytes) { + super(name); + this.rng = rng; + } + label(label) { + this.appendMessage('', label); + } + bytes(bytes) { + this.appendMessage('sign-bytes', bytes); + return this; + } + protoName(label) { + this.appendMessage('proto-name', label); + } + commitPoint(label, point) { + this.appendMessage(label, point.toRawBytes()); + } + challengeScalar(label) { + return modN(bytesToNumberLE(this.challengeBytes(label, 64))); + } + witnessScalar(label, nonceSeeds = []) { + return modN(bytesToNumberLE(this.witnessBytes(label, 64, nonceSeeds))); + } + witnessBytes(label, len, nonceSeeds = []) { + checkU32('SigningContext.witnessBytes', len); + const strobeRng = this.strobe.clone(); + for (const ns of nonceSeeds) { + strobeRng.metaAD(label, false); + checkU32('SigningContext.witnessBytes nonce length', ns.length); + strobeRng.metaAD(numberToBytesLE(ns.length, 4), true); + strobeRng.KEY(ns, false); + } + const random = this.rng(32); + strobeRng.metaAD('rng', false); + strobeRng.KEY(random, false); + strobeRng.metaAD(numberToBytesLE(len, 4), false); + return strobeRng.PRF(len, false); + } + } + const MASK = bitMask(256); + const encodeScalar = (n) => numberToBytesLE((n << _3n) & MASK, 32); + const decodeScalar = (n) => bytesToNumberLE(n) >> _3n; + function getPublicKey(secretKey) { + abytes('secretKey', secretKey, 64); + const scalar = decodeScalar(secretKey.subarray(0, 32)); + return RistrettoPoint.BASE.multiply(scalar).toRawBytes(); + } + function secretFromSeed(seed) { + abytes('seed', seed, 32); + const r = sha512(seed); + r[0] &= 248; + r[31] &= 63; + r[31] |= 64; + const key = encodeScalar(decodeScalar(r.subarray(0, 32))); + const nonce = r.subarray(32, 64); + const res = concatBytes(key, nonce); + cleanBytes(key, nonce, r); + return res; + } + const SUBSTRATE_CONTEXT = utf8ToBytes('substrate'); + function sign(secretKey, message, rng = randomBytes) { + abytes('message', message); + abytes('secretKey', secretKey, 64); + const t = new SigningContext('SigningContext', rng); + t.label(SUBSTRATE_CONTEXT); + t.bytes(message); + const keyScalar = decodeScalar(secretKey.subarray(0, 32)); + const nonce = secretKey.subarray(32, 64); + const pubPoint = RistrettoPoint.fromHex(getPublicKey(secretKey)); + t.protoName('Schnorr-sig'); + t.commitPoint('sign:pk', pubPoint); + const r = t.witnessScalar('signing', [nonce]); + const R = RistrettoPoint.BASE.multiply(r); + t.commitPoint('sign:R', R); + const k = t.challengeScalar('sign:c'); + const s = modN(k * keyScalar + r); + const res = concatBytes(R.toRawBytes(), numberToBytesLE(s, 32)); + res[63] |= 128; + t.clean(); + return res; + } + function verify(message, signature, publicKey) { + abytes('message', message); + abytes('signature', signature, 64); + abytes('publicKey', publicKey, 32); + if ((signature[63] & 128) === 0) + throw new Error('Schnorrkel marker missing'); + const sBytes = Uint8Array.from(signature.subarray(32, 64)); + sBytes[31] &= 127; + const R = RistrettoPoint.fromHex(signature.subarray(0, 32)); + const s = bytesToNumberLE(sBytes); + aInRange('s', s, _0n, CURVE_ORDER); + const t = new SigningContext('SigningContext'); + t.label(SUBSTRATE_CONTEXT); + t.bytes(message); + const pubPoint = RistrettoPoint.fromHex(publicKey); + if (pubPoint.equals(RistrettoPoint.ZERO)) + return false; + t.protoName('Schnorr-sig'); + t.commitPoint('sign:pk', pubPoint); + t.commitPoint('sign:R', R); + const k = t.challengeScalar('sign:c'); + const sP = RistrettoPoint.BASE.multiply(s); + const RR = pubPoint.negate().multiply(k).add(sP); + t.clean(); + cleanBytes(sBytes); + return RR.equals(R); + } + function getSharedSecret(secretKey, publicKey) { + abytes('secretKey', secretKey, 64); + abytes('publicKey', publicKey, 32); + const keyScalar = decodeScalar(secretKey.subarray(0, 32)); + const pubPoint = RistrettoPoint.fromHex(publicKey); + if (pubPoint.equals(RistrettoPoint.ZERO)) + throw new Error('wrong public key (infinity)'); + return pubPoint.multiply(keyScalar).toRawBytes(); + } + const HDKD = { + secretSoft(secretKey, chainCode, rng = randomBytes) { + abytes('secretKey', secretKey, 64); + abytes('chainCode', chainCode, 32); + const masterScalar = decodeScalar(secretKey.subarray(0, 32)); + const masterNonce = secretKey.subarray(32, 64); + const pubPoint = RistrettoPoint.fromHex(getPublicKey(secretKey)); + const t = new SigningContext('SchnorrRistrettoHDKD', rng); + t.bytes(EMPTY); + t.appendMessage('chain-code', chainCode); + t.commitPoint('public-key', pubPoint); + const scalar = t.challengeScalar('HDKD-scalar'); + const hdkdChainCode = t.challengeBytes('HDKD-chaincode', 32); + const nonceSeed = concatBytes(numberToBytesLE(masterScalar, 32), masterNonce); + const nonce = t.witnessBytes('HDKD-nonce', 32, [masterNonce, nonceSeed]); + const key = encodeScalar(modN(masterScalar + scalar)); + const res = concatBytes(key, nonce); + cleanBytes(key, nonce, nonceSeed, hdkdChainCode); + t.clean(); + return res; + }, + publicSoft(publicKey, chainCode) { + abytes('publicKey', publicKey, 32); + abytes('chainCode', chainCode, 32); + const pubPoint = RistrettoPoint.fromHex(publicKey); + const t = new SigningContext('SchnorrRistrettoHDKD'); + t.bytes(EMPTY); + t.appendMessage('chain-code', chainCode); + t.commitPoint('public-key', pubPoint); + const scalar = t.challengeScalar('HDKD-scalar'); + t.challengeBytes('HDKD-chaincode', 32); + t.clean(); + return pubPoint.add(RistrettoPoint.BASE.multiply(scalar)).toRawBytes(); + }, + secretHard(secretKey, chainCode) { + abytes('secretKey', secretKey, 64); + abytes('chainCode', chainCode, 32); + const key = numberToBytesLE(decodeScalar(secretKey.subarray(0, 32)), 32); + const t = new SigningContext('SchnorrRistrettoHDKD'); + t.bytes(EMPTY); + t.appendMessage('chain-code', chainCode); + t.appendMessage('secret-key', key); + const msk = t.challengeBytes('HDKD-hard', 32); + const hdkdChainCode = t.challengeBytes('HDKD-chaincode', 32); + t.clean(); + const res = secretFromSeed(msk); + cleanBytes(key, msk, hdkdChainCode); + t.clean(); + return res; + }, + }; + const dleq = { + proove(keyScalar, nonce, pubPoint, t, input, output) { + t.protoName('DLEQProof'); + t.commitPoint('vrf:h', input); + const r = t.witnessScalar(`proving${'\0'}0`, [nonce]); + const R = RistrettoPoint.BASE.multiply(r); + t.commitPoint('vrf:R=g^r', R); + const Hr = input.multiply(r); + t.commitPoint('vrf:h^r', Hr); + t.commitPoint('vrf:pk', pubPoint); + t.commitPoint('vrf:h^sk', output); + const c = t.challengeScalar('prove'); + const s = modN(r - c * keyScalar); + return { proof: { c, s }, proofBatchable: { R, Hr, s } }; + }, + verify(pubPoint, t, input, output, proof) { + if (pubPoint.equals(RistrettoPoint.ZERO)) + return false; + t.protoName('DLEQProof'); + t.commitPoint('vrf:h', input); + const R = pubPoint.multiply(proof.c).add(RistrettoPoint.BASE.multiply(proof.s)); + t.commitPoint('vrf:R=g^r', R); + const Hr = output.multiply(proof.c).add(input.multiply(proof.s)); + t.commitPoint('vrf:h^r', Hr); + t.commitPoint('vrf:pk', pubPoint); + t.commitPoint('vrf:h^sk', output); + const realC = t.challengeScalar('prove'); + if (proof.c === realC) + return { R, Hr, s: proof.s }; + return false; + }, + }; + function initVRF(ctx, msg, extra, pubPoint, rng = randomBytes) { + const t = new SigningContext('SigningContext', rng); + t.label(ctx); + t.bytes(msg); + t.commitPoint('vrf-nm-pk', pubPoint); + const hash = t.challengeBytes('VRFHash', 64); + const input = RistrettoPoint.hashToCurve(hash); + const transcript = new SigningContext('VRF', rng); + if (extra.length) + transcript.label(extra); + t.clean(); + cleanBytes(hash); + return { input, t: transcript }; + } + const vrf = { + sign(msg, secretKey, ctx = EMPTY, extra = EMPTY, rng = randomBytes) { + abytes('msg', msg); + abytes('secretKey', secretKey, 64); + abytes('ctx', ctx); + abytes('extra', extra); + const keyScalar = decodeScalar(secretKey.subarray(0, 32)); + const nonce = secretKey.subarray(32, 64); + const pubPoint = RistrettoPoint.fromHex(getPublicKey(secretKey)); + const { input, t } = initVRF(ctx, msg, extra, pubPoint, rng); + const output = input.multiply(keyScalar); + const p = { output }; + const { proof } = dleq.proove(keyScalar, nonce, pubPoint, t, input, output); + const cBytes = numberToBytesLE(proof.c, 32); + const sBytes = numberToBytesLE(proof.s, 32); + const res = concatBytes(p.output.toRawBytes(), cBytes, sBytes); + cleanBytes(nonce, cBytes, sBytes); + return res; + }, + verify(msg, signature, publicKey, ctx = EMPTY, extra = EMPTY, rng = randomBytes) { + abytes('msg', msg); + abytes('signature', signature, 96); + abytes('pubkey', publicKey, 32); + abytes('ctx', ctx); + abytes('extra', extra); + const pubPoint = RistrettoPoint.fromHex(publicKey); + if (pubPoint.equals(RistrettoPoint.ZERO)) + return false; + const proof = { + c: parseScalar('signature.c', signature.subarray(32, 64)), + s: parseScalar('signature.s', signature.subarray(64, 96)), + }; + const { input, t } = initVRF(ctx, msg, extra, pubPoint, rng); + const output = RistrettoPoint.fromHex(signature.subarray(0, 32)); + if (output.equals(RistrettoPoint.ZERO)) + throw new Error('vrf.verify: wrong output point (identity)'); + const proofBatchable = dleq.verify(pubPoint, t, input, output, proof); + return proofBatchable === false ? false : true; + }, + }; + + function createDeriveFn(derive) { + return (keypair, chainCode) => { + if (!util.isU8a(chainCode) || chainCode.length !== 32) { + throw new Error('Invalid chainCode passed to derive'); + } + const secretKey = derive(keypair.secretKey, chainCode); + const publicKey = getPublicKey(secretKey); + return { publicKey, secretKey }; + }; + } + + const sr25519DeriveHard = createDeriveFn(HDKD.secretHard); + + const sr25519DeriveSoft = createDeriveFn(HDKD.secretSoft); + + function keyHdkdSr25519(keypair, { chainCode, isSoft }) { + return isSoft + ? sr25519DeriveSoft(keypair, chainCode) + : sr25519DeriveHard(keypair, chainCode); + } + + const generators = { + ecdsa: keyHdkdEcdsa, + ed25519: keyHdkdEd25519, + ethereum: keyHdkdEcdsa, + sr25519: keyHdkdSr25519 + }; + function keyFromPath(pair, path, type) { + const keyHdkd = generators[type]; + let result = pair; + for (const junction of path) { + result = keyHdkd(result, junction); + } + return result; + } + + function sr25519Agreement(secretKey, publicKey) { + const secretKeyU8a = util.u8aToU8a(secretKey); + const publicKeyU8a = util.u8aToU8a(publicKey); + if (publicKeyU8a.length !== 32) { + throw new Error(`Invalid publicKey, received ${publicKeyU8a.length} bytes, expected 32`); + } + else if (secretKeyU8a.length !== 64) { + throw new Error(`Invalid secretKey, received ${secretKeyU8a.length} bytes, expected 64`); + } + return getSharedSecret(secretKeyU8a, publicKeyU8a); + } + + function sr25519DerivePublic(publicKey, chainCode) { + const publicKeyU8a = util.u8aToU8a(publicKey); + if (!util.isU8a(chainCode) || chainCode.length !== 32) { + throw new Error('Invalid chainCode passed to derive'); + } + else if (publicKeyU8a.length !== 32) { + throw new Error(`Invalid publicKey, received ${publicKeyU8a.length} bytes, expected 32`); + } + return HDKD.publicSoft(publicKeyU8a, chainCode); + } + + function sr25519PairFromSeed(seed) { + const seedU8a = util.u8aToU8a(seed); + if (seedU8a.length !== 32) { + throw new Error(`Expected a seed matching 32 bytes, found ${seedU8a.length}`); + } + const sec = secretFromSeed(seedU8a); + const pub = getPublicKey(sec); + return { + publicKey: pub, + secretKey: sec + }; + } + + function sr25519Sign(message, { publicKey, secretKey }) { + if (publicKey?.length !== 32) { + throw new Error('Expected a valid publicKey, 32-bytes'); + } + else if (secretKey?.length !== 64) { + throw new Error('Expected a valid secretKey, 64-bytes'); + } + return sign(secretKey, util.u8aToU8a(message)); + } + + function sr25519Verify(message, signature, publicKey) { + const publicKeyU8a = util.u8aToU8a(publicKey); + const signatureU8a = util.u8aToU8a(signature); + if (publicKeyU8a.length !== 32) { + throw new Error(`Invalid publicKey, received ${publicKeyU8a.length} bytes, expected 32`); + } + else if (signatureU8a.length !== 64) { + throw new Error(`Invalid signature, received ${signatureU8a.length} bytes, expected 64`); + } + return verify(util.u8aToU8a(message), signatureU8a, publicKeyU8a); + } + + const EMPTY_U8A$1 = new Uint8Array(); + function sr25519VrfSign(message, { secretKey }, context = EMPTY_U8A$1, extra = EMPTY_U8A$1) { + if (secretKey?.length !== 64) { + throw new Error('Invalid secretKey, expected 64-bytes'); + } + return vrf.sign(util.u8aToU8a(message), secretKey, util.u8aToU8a(context), util.u8aToU8a(extra), randomBytes); + } + + const EMPTY_U8A = new Uint8Array(); + function sr25519VrfVerify(message, signOutput, publicKey, context = EMPTY_U8A, extra = EMPTY_U8A) { + const publicKeyU8a = util.u8aToU8a(publicKey); + const proofU8a = util.u8aToU8a(signOutput); + if (publicKeyU8a.length !== 32) { + throw new Error('Invalid publicKey, expected 32-bytes'); + } + else if (proofU8a.length !== 96) { + throw new Error('Invalid vrfSign output, expected 96 bytes'); + } + return vrf.verify(util.u8aToU8a(message), proofU8a, publicKeyU8a, util.u8aToU8a(context), util.u8aToU8a(extra)); + } + + function encodeAddress(key, ss58Format = defaults.prefix) { + const u8a = decodeAddress(key); + if ((ss58Format < 0) || (ss58Format > 16383 && !ss58Exceptions.includes(ss58Format)) || [46, 47].includes(ss58Format)) { + throw new Error('Out of range ss58Format specified'); + } + else if (!defaults.allowedDecodedLengths.includes(u8a.length)) { + throw new Error(`Expected a valid key to convert, with length ${defaults.allowedDecodedLengths.join(', ')}`); + } + const input = util.u8aConcat(ss58Format < 64 + ? [ss58Format] + : [ + ((ss58Format & 0b0000_0000_1111_1100) >> 2) | 0b0100_0000, + (ss58Format >> 8) | ((ss58Format & 0b0000_0000_0000_0011) << 6) + ], u8a); + return base58Encode(util.u8aConcat(input, sshash(input).subarray(0, [32, 33].includes(u8a.length) ? 2 : 1))); + } + const ss58Exceptions = [29972]; + + function filterHard({ isHard }) { + return isHard; + } + function deriveAddress(who, suri, ss58Format) { + const { path } = keyExtractPath(suri); + if (!path.length || path.every(filterHard)) { + throw new Error('Expected suri to contain a combination of non-hard paths'); + } + let publicKey = decodeAddress(who); + for (const { chainCode } of path) { + publicKey = sr25519DerivePublic(publicKey, chainCode); + } + return encodeAddress(publicKey, ss58Format); + } + + const PREFIX$1 = util.stringToU8a('modlpy/utilisuba'); + function createKeyDerived(who, index) { + return blake2AsU8a(util.u8aConcat(PREFIX$1, decodeAddress(who), util.bnToU8a(index, BN_LE_16_OPTS))); + } + + function encodeDerivedAddress(who, index, ss58Format) { + return encodeAddress(createKeyDerived(decodeAddress(who), index), ss58Format); + } + + function addressToU8a(who) { + return decodeAddress(who); + } + + const PREFIX = util.stringToU8a('modlpy/utilisuba'); + function createKeyMulti(who, threshold) { + return blake2AsU8a(util.u8aConcat(PREFIX, util.compactToU8a(who.length), ...util.u8aSorted(who.map(addressToU8a)), util.bnToU8a(threshold, BN_LE_16_OPTS))); + } + + function encodeMultiAddress(who, threshold, ss58Format) { + return encodeAddress(createKeyMulti(who, threshold), ss58Format); + } + + function addressEq(a, b) { + return util.u8aEq(decodeAddress(a), decodeAddress(b)); + } + + const keccakAsU8a = createDualHasher({ 256: keccak256, 512: keccak512 }, { 256: keccak_256, 512: keccak_512 }); + const keccak256AsU8a = createBitHasher(256, keccakAsU8a); + const keccak512AsU8a = createBitHasher(512, keccakAsU8a); + const keccakAsHex = createAsHex(keccakAsU8a); + + function hasher(hashType, data, onlyJs) { + return hashType === 'keccak' + ? keccakAsU8a(data, undefined, onlyJs) + : blake2AsU8a(data, undefined, undefined, onlyJs); + } + + function evmToAddress(evmAddress, ss58Format, hashType = 'blake2') { + const message = util.u8aConcat('evm:', evmAddress); + if (message.length !== 24) { + throw new Error(`Converting ${evmAddress}: Invalid evm address length`); + } + return encodeAddress(hasher(hashType, message), ss58Format); + } + + function validateAddress(encoded, ignoreChecksum, ss58Format) { + return !!decodeAddress(encoded, ignoreChecksum, ss58Format); + } + + function isAddress(address, ignoreChecksum, ss58Format) { + try { + return validateAddress(address, ignoreChecksum, ss58Format); + } + catch { + return false; + } + } + + function sortAddresses(addresses, ss58Format) { + const u8aToAddress = (u8a) => encodeAddress(u8a, ss58Format); + return util.u8aSorted(addresses.map(addressToU8a)).map(u8aToAddress); + } + + const l = util.logger('setSS58Format'); + function setSS58Format(prefix) { + l.warn('Global setting of the ss58Format is deprecated and not recommended. Set format on the keyring (if used) or as part of the address encode function'); + defaults.prefix = prefix; + } + + const chars = 'abcdefghijklmnopqrstuvwxyz234567'; + const config$1 = { + chars, + coder: utils.chain( + utils.radix2(5), utils.alphabet(chars), { + decode: (input) => input.split(''), + encode: (input) => input.join('') + }), + ipfs: 'b', + type: 'base32' + }; + const base32Validate = createValidate(config$1); + const isBase32 = createIs(base32Validate); + const base32Decode = createDecode(config$1, base32Validate); + const base32Encode = createEncode(config$1); + + const config = { + chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', + coder: base64, + type: 'base64', + withPadding: true + }; + const base64Validate = createValidate(config); + const isBase64 = createIs(base64Validate); + const base64Decode = createDecode(config, base64Validate); + const base64Encode = createEncode(config); + + function base64Pad(value) { + return value.padEnd(value.length + (value.length % 4), '='); + } + + function base64Trim(value) { + while (value.length && value.endsWith('=')) { + value = value.slice(0, -1); + } + return value; + } + + function secp256k1Compress(publicKey, onlyJs) { + if (![33, 65].includes(publicKey.length)) { + throw new Error(`Invalid publicKey provided, received ${publicKey.length} bytes input`); + } + if (publicKey.length === 33) { + return publicKey; + } + return !util.hasBigInt || (!onlyJs && isReady()) + ? secp256k1Compress$1(publicKey) + : secp256k1.ProjectivePoint.fromHex(publicKey).toRawBytes(true); + } + + function secp256k1Expand(publicKey, onlyJs) { + if (![33, 65].includes(publicKey.length)) { + throw new Error(`Invalid publicKey provided, received ${publicKey.length} bytes input`); + } + if (publicKey.length === 65) { + return publicKey.subarray(1); + } + if (!util.hasBigInt || (!onlyJs && isReady())) { + return secp256k1Expand$1(publicKey).subarray(1); + } + const { px, py } = secp256k1.ProjectivePoint.fromHex(publicKey); + return util.u8aConcat(util.bnToU8a(px, BN_BE_256_OPTS), util.bnToU8a(py, BN_BE_256_OPTS)); + } + + function secp256k1Recover(msgHash, signature, recovery, hashType = 'blake2', onlyJs) { + const sig = util.u8aToU8a(signature).subarray(0, 64); + const msg = util.u8aToU8a(msgHash); + const publicKey = !util.hasBigInt || (!onlyJs && isReady()) + ? secp256k1Recover$1(msg, sig, recovery) + : secp256k1.Signature + .fromCompact(sig) + .addRecoveryBit(recovery) + .recoverPublicKey(msg) + .toRawBytes(); + if (!publicKey) { + throw new Error('Unable to recover publicKey from signature'); + } + return hashType === 'keccak' + ? secp256k1Expand(publicKey, onlyJs) + : secp256k1Compress(publicKey, onlyJs); + } + + function secp256k1Sign(message, { secretKey }, hashType = 'blake2', onlyJs) { + if (secretKey?.length !== 32) { + throw new Error('Expected valid secp256k1 secretKey, 32-bytes'); + } + const data = hasher(hashType, message, onlyJs); + if (!util.hasBigInt || (!onlyJs && isReady())) { + return secp256k1Sign$1(data, secretKey); + } + const signature = secp256k1.sign(data, secretKey, { lowS: true }); + return util.u8aConcat(util.bnToU8a(signature.r, BN_BE_256_OPTS), util.bnToU8a(signature.s, BN_BE_256_OPTS), new Uint8Array([signature.recovery || 0])); + } + + const N = 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141'.replace(/ /g, ''); + const N_BI = BigInt$1(`0x${N}`); + const N_BN = new util.BN(N, 'hex'); + function addBi(seckey, tweak) { + let res = util.u8aToBigInt(tweak, BN_BE_OPTS); + if (res >= N_BI) { + throw new Error('Tweak parameter is out of range'); + } + res += util.u8aToBigInt(seckey, BN_BE_OPTS); + if (res >= N_BI) { + res -= N_BI; + } + if (res === util._0n) { + throw new Error('Invalid resulting private key'); + } + return util.nToU8a(res, BN_BE_256_OPTS); + } + function addBn(seckey, tweak) { + const res = new util.BN(tweak); + if (res.cmp(N_BN) >= 0) { + throw new Error('Tweak parameter is out of range'); + } + res.iadd(new util.BN(seckey)); + if (res.cmp(N_BN) >= 0) { + res.isub(N_BN); + } + if (res.isZero()) { + throw new Error('Invalid resulting private key'); + } + return util.bnToU8a(res, BN_BE_256_OPTS); + } + function secp256k1PrivateKeyTweakAdd(seckey, tweak, onlyBn) { + if (!util.isU8a(seckey) || seckey.length !== 32) { + throw new Error('Expected seckey to be an Uint8Array with length 32'); + } + else if (!util.isU8a(tweak) || tweak.length !== 32) { + throw new Error('Expected tweak to be an Uint8Array with length 32'); + } + return !util.hasBigInt || onlyBn + ? addBn(seckey, tweak) + : addBi(seckey, tweak); + } + + function secp256k1Verify(msgHash, signature, address, hashType = 'blake2', onlyJs) { + const sig = util.u8aToU8a(signature); + if (sig.length !== 65) { + throw new Error(`Expected signature with 65 bytes, ${sig.length} found instead`); + } + const publicKey = secp256k1Recover(hasher(hashType, msgHash), sig, sig[64], hashType, onlyJs); + const signerAddr = hasher(hashType, publicKey, onlyJs); + const inputAddr = util.u8aToU8a(address); + return util.u8aEq(publicKey, inputAddr) || (hashType === 'keccak' + ? util.u8aEq(signerAddr.slice(-20), inputAddr.slice(-20)) + : util.u8aEq(signerAddr, inputAddr)); + } + + function getH160(u8a) { + if ([33, 65].includes(u8a.length)) { + u8a = keccakAsU8a(secp256k1Expand(u8a)); + } + return u8a.slice(-20); + } + function ethereumEncode(addressOrPublic) { + if (!addressOrPublic) { + return '0x'; + } + const u8aAddress = util.u8aToU8a(addressOrPublic); + if (![20, 32, 33, 65].includes(u8aAddress.length)) { + throw new Error(`Invalid address or publicKey provided, received ${u8aAddress.length} bytes input`); + } + const address = util.u8aToHex(getH160(u8aAddress), -1, false); + const hash = util.u8aToHex(keccakAsU8a(address), -1, false); + let result = ''; + for (let i = 0; i < 40; i++) { + result = `${result}${parseInt(hash[i], 16) > 7 ? address[i].toUpperCase() : address[i]}`; + } + return `0x${result}`; + } + + function isInvalidChar(char, byte) { + return char !== (byte > 7 + ? char.toUpperCase() + : char.toLowerCase()); + } + function isEthereumChecksum(_address) { + const address = _address.replace('0x', ''); + const hash = util.u8aToHex(keccakAsU8a(address.toLowerCase()), -1, false); + for (let i = 0; i < 40; i++) { + if (isInvalidChar(address[i], parseInt(hash[i], 16))) { + return false; + } + } + return true; + } + + function isEthereumAddress(address) { + if (!address || address.length !== 42 || !util.isHex(address)) { + return false; + } + else if (/^(0x)?[0-9a-f]{40}$/.test(address) || /^(0x)?[0-9A-F]{40}$/.test(address)) { + return true; + } + return isEthereumChecksum(address); + } + + const sha256 = sha256$1; + + const JS_HASH = { + 256: sha256, + 512: sha512 + }; + const WA_MHAC = { + 256: hmacSha256, + 512: hmacSha512 + }; + function createSha(bitLength) { + return (key, data, onlyJs) => hmacShaAsU8a(key, data, bitLength, onlyJs); + } + function hmacShaAsU8a(key, data, bitLength = 256, onlyJs) { + const u8aKey = util.u8aToU8a(key); + return !util.hasBigInt || (!onlyJs && isReady()) + ? WA_MHAC[bitLength](u8aKey, data) + : hmac(JS_HASH[bitLength], u8aKey, data); + } + const hmacSha256AsU8a = createSha(256); + const hmacSha512AsU8a = createSha(512); + + const HARDENED = 0x80000000; + function hdValidatePath(path) { + if (!path.startsWith('m/')) { + return false; + } + const parts = path.split('/').slice(1); + for (const p of parts) { + const n = /^\d+'?$/.test(p) + ? parseInt(p.replace(/'$/, ''), 10) + : Number.NaN; + if (isNaN(n) || (n >= HARDENED) || (n < 0)) { + return false; + } + } + return true; + } + + const MASTER_SECRET = util.stringToU8a('Bitcoin seed'); + function createCoded(secretKey, chainCode) { + return { + chainCode, + publicKey: secp256k1PairFromSeed(secretKey).publicKey, + secretKey + }; + } + function deriveChild(hd, index) { + const indexBuffer = util.bnToU8a(index, BN_BE_32_OPTS); + const data = index >= HARDENED + ? util.u8aConcat(new Uint8Array(1), hd.secretKey, indexBuffer) + : util.u8aConcat(hd.publicKey, indexBuffer); + try { + const I = hmacShaAsU8a(hd.chainCode, data, 512); + return createCoded(secp256k1PrivateKeyTweakAdd(hd.secretKey, I.slice(0, 32)), I.slice(32)); + } + catch { + return deriveChild(hd, index + 1); + } + } + function hdEthereum(seed, path = '') { + const I = hmacShaAsU8a(MASTER_SECRET, seed, 512); + let hd = createCoded(I.slice(0, 32), I.slice(32)); + if (!path || path === 'm' || path === 'M' || path === "m'" || path === "M'") { + return hd; + } + if (!hdValidatePath(path)) { + throw new Error('Invalid derivation path'); + } + const parts = path.split('/').slice(1); + for (const p of parts) { + hd = deriveChild(hd, parseInt(p, 10) + ((p.length > 1) && p.endsWith("'") + ? HARDENED + : 0)); + } + return hd; + } + + function pbkdf2Init(hash, _password, _salt, _opts) { + ahash(hash); + const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts); + const { c, dkLen, asyncTick } = opts; + anumber(c); + anumber(dkLen); + anumber(asyncTick); + if (c < 1) + throw new Error('iterations (c) should be >= 1'); + const password = kdfInputToBytes(_password); + const salt = kdfInputToBytes(_salt); + const DK = new Uint8Array(dkLen); + const PRF = hmac.create(hash, password); + const PRFSalt = PRF._cloneInto().update(salt); + return { c, dkLen, asyncTick, DK, PRF, PRFSalt }; + } + function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) { + PRF.destroy(); + PRFSalt.destroy(); + if (prfW) + prfW.destroy(); + clean(u); + return DK; + } + function pbkdf2(hash, password, salt, opts) { + const { c, dkLen, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts); + let prfW; + const arr = new Uint8Array(4); + const view = createView(arr); + const u = new Uint8Array(PRF.outputLen); + for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) { + const Ti = DK.subarray(pos, pos + PRF.outputLen); + view.setInt32(0, ti, false); + (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u); + Ti.set(u.subarray(0, Ti.length)); + for (let ui = 1; ui < c; ui++) { + PRF._cloneInto(prfW).update(u).digestInto(u); + for (let i = 0; i < Ti.length; i++) + Ti[i] ^= u[i]; + } + } + return pbkdf2Output(PRF, PRFSalt, DK, prfW, u); + } + + function pbkdf2Encode(passphrase, salt = randomAsU8a(), rounds = 2048, onlyJs) { + const u8aPass = util.u8aToU8a(passphrase); + const u8aSalt = util.u8aToU8a(salt); + return { + password: !util.hasBigInt || (!onlyJs && isReady()) + ? pbkdf2$1(u8aPass, u8aSalt, rounds) + : pbkdf2(sha512, u8aPass, u8aSalt, { c: rounds, dkLen: 64 }), + rounds, + salt + }; + } + + const shaAsU8a = createDualHasher({ 256: sha256$2, 512: sha512$2 }, { 256: sha256, 512: sha512 }); + const sha256AsU8a = createBitHasher(256, shaAsU8a); + const sha512AsU8a = createBitHasher(512, shaAsU8a); + + const DEFAULT_WORDLIST = 'abandon|ability|able|about|above|absent|absorb|abstract|absurd|abuse|access|accident|account|accuse|achieve|acid|acoustic|acquire|across|act|action|actor|actress|actual|adapt|add|addict|address|adjust|admit|adult|advance|advice|aerobic|affair|afford|afraid|again|age|agent|agree|ahead|aim|air|airport|aisle|alarm|album|alcohol|alert|alien|all|alley|allow|almost|alone|alpha|already|also|alter|always|amateur|amazing|among|amount|amused|analyst|anchor|ancient|anger|angle|angry|animal|ankle|announce|annual|another|answer|antenna|antique|anxiety|any|apart|apology|appear|apple|approve|april|arch|arctic|area|arena|argue|arm|armed|armor|army|around|arrange|arrest|arrive|arrow|art|artefact|artist|artwork|ask|aspect|assault|asset|assist|assume|asthma|athlete|atom|attack|attend|attitude|attract|auction|audit|august|aunt|author|auto|autumn|average|avocado|avoid|awake|aware|away|awesome|awful|awkward|axis|baby|bachelor|bacon|badge|bag|balance|balcony|ball|bamboo|banana|banner|bar|barely|bargain|barrel|base|basic|basket|battle|beach|bean|beauty|because|become|beef|before|begin|behave|behind|believe|below|belt|bench|benefit|best|betray|better|between|beyond|bicycle|bid|bike|bind|biology|bird|birth|bitter|black|blade|blame|blanket|blast|bleak|bless|blind|blood|blossom|blouse|blue|blur|blush|board|boat|body|boil|bomb|bone|bonus|book|boost|border|boring|borrow|boss|bottom|bounce|box|boy|bracket|brain|brand|brass|brave|bread|breeze|brick|bridge|brief|bright|bring|brisk|broccoli|broken|bronze|broom|brother|brown|brush|bubble|buddy|budget|buffalo|build|bulb|bulk|bullet|bundle|bunker|burden|burger|burst|bus|business|busy|butter|buyer|buzz|cabbage|cabin|cable|cactus|cage|cake|call|calm|camera|camp|can|canal|cancel|candy|cannon|canoe|canvas|canyon|capable|capital|captain|car|carbon|card|cargo|carpet|carry|cart|case|cash|casino|castle|casual|cat|catalog|catch|category|cattle|caught|cause|caution|cave|ceiling|celery|cement|census|century|cereal|certain|chair|chalk|champion|change|chaos|chapter|charge|chase|chat|cheap|check|cheese|chef|cherry|chest|chicken|chief|child|chimney|choice|choose|chronic|chuckle|chunk|churn|cigar|cinnamon|circle|citizen|city|civil|claim|clap|clarify|claw|clay|clean|clerk|clever|click|client|cliff|climb|clinic|clip|clock|clog|close|cloth|cloud|clown|club|clump|cluster|clutch|coach|coast|coconut|code|coffee|coil|coin|collect|color|column|combine|come|comfort|comic|common|company|concert|conduct|confirm|congress|connect|consider|control|convince|cook|cool|copper|copy|coral|core|corn|correct|cost|cotton|couch|country|couple|course|cousin|cover|coyote|crack|cradle|craft|cram|crane|crash|crater|crawl|crazy|cream|credit|creek|crew|cricket|crime|crisp|critic|crop|cross|crouch|crowd|crucial|cruel|cruise|crumble|crunch|crush|cry|crystal|cube|culture|cup|cupboard|curious|current|curtain|curve|cushion|custom|cute|cycle|dad|damage|damp|dance|danger|daring|dash|daughter|dawn|day|deal|debate|debris|decade|december|decide|decline|decorate|decrease|deer|defense|define|defy|degree|delay|deliver|demand|demise|denial|dentist|deny|depart|depend|deposit|depth|deputy|derive|describe|desert|design|desk|despair|destroy|detail|detect|develop|device|devote|diagram|dial|diamond|diary|dice|diesel|diet|differ|digital|dignity|dilemma|dinner|dinosaur|direct|dirt|disagree|discover|disease|dish|dismiss|disorder|display|distance|divert|divide|divorce|dizzy|doctor|document|dog|doll|dolphin|domain|donate|donkey|donor|door|dose|double|dove|draft|dragon|drama|drastic|draw|dream|dress|drift|drill|drink|drip|drive|drop|drum|dry|duck|dumb|dune|during|dust|dutch|duty|dwarf|dynamic|eager|eagle|early|earn|earth|easily|east|easy|echo|ecology|economy|edge|edit|educate|effort|egg|eight|either|elbow|elder|electric|elegant|element|elephant|elevator|elite|else|embark|embody|embrace|emerge|emotion|employ|empower|empty|enable|enact|end|endless|endorse|enemy|energy|enforce|engage|engine|enhance|enjoy|enlist|enough|enrich|enroll|ensure|enter|entire|entry|envelope|episode|equal|equip|era|erase|erode|erosion|error|erupt|escape|essay|essence|estate|eternal|ethics|evidence|evil|evoke|evolve|exact|example|excess|exchange|excite|exclude|excuse|execute|exercise|exhaust|exhibit|exile|exist|exit|exotic|expand|expect|expire|explain|expose|express|extend|extra|eye|eyebrow|fabric|face|faculty|fade|faint|faith|fall|false|fame|family|famous|fan|fancy|fantasy|farm|fashion|fat|fatal|father|fatigue|fault|favorite|feature|february|federal|fee|feed|feel|female|fence|festival|fetch|fever|few|fiber|fiction|field|figure|file|film|filter|final|find|fine|finger|finish|fire|firm|first|fiscal|fish|fit|fitness|fix|flag|flame|flash|flat|flavor|flee|flight|flip|float|flock|floor|flower|fluid|flush|fly|foam|focus|fog|foil|fold|follow|food|foot|force|forest|forget|fork|fortune|forum|forward|fossil|foster|found|fox|fragile|frame|frequent|fresh|friend|fringe|frog|front|frost|frown|frozen|fruit|fuel|fun|funny|furnace|fury|future|gadget|gain|galaxy|gallery|game|gap|garage|garbage|garden|garlic|garment|gas|gasp|gate|gather|gauge|gaze|general|genius|genre|gentle|genuine|gesture|ghost|giant|gift|giggle|ginger|giraffe|girl|give|glad|glance|glare|glass|glide|glimpse|globe|gloom|glory|glove|glow|glue|goat|goddess|gold|good|goose|gorilla|gospel|gossip|govern|gown|grab|grace|grain|grant|grape|grass|gravity|great|green|grid|grief|grit|grocery|group|grow|grunt|guard|guess|guide|guilt|guitar|gun|gym|habit|hair|half|hammer|hamster|hand|happy|harbor|hard|harsh|harvest|hat|have|hawk|hazard|head|health|heart|heavy|hedgehog|height|hello|helmet|help|hen|hero|hidden|high|hill|hint|hip|hire|history|hobby|hockey|hold|hole|holiday|hollow|home|honey|hood|hope|horn|horror|horse|hospital|host|hotel|hour|hover|hub|huge|human|humble|humor|hundred|hungry|hunt|hurdle|hurry|hurt|husband|hybrid|ice|icon|idea|identify|idle|ignore|ill|illegal|illness|image|imitate|immense|immune|impact|impose|improve|impulse|inch|include|income|increase|index|indicate|indoor|industry|infant|inflict|inform|inhale|inherit|initial|inject|injury|inmate|inner|innocent|input|inquiry|insane|insect|inside|inspire|install|intact|interest|into|invest|invite|involve|iron|island|isolate|issue|item|ivory|jacket|jaguar|jar|jazz|jealous|jeans|jelly|jewel|job|join|joke|journey|joy|judge|juice|jump|jungle|junior|junk|just|kangaroo|keen|keep|ketchup|key|kick|kid|kidney|kind|kingdom|kiss|kit|kitchen|kite|kitten|kiwi|knee|knife|knock|know|lab|label|labor|ladder|lady|lake|lamp|language|laptop|large|later|latin|laugh|laundry|lava|law|lawn|lawsuit|layer|lazy|leader|leaf|learn|leave|lecture|left|leg|legal|legend|leisure|lemon|lend|length|lens|leopard|lesson|letter|level|liar|liberty|library|license|life|lift|light|like|limb|limit|link|lion|liquid|list|little|live|lizard|load|loan|lobster|local|lock|logic|lonely|long|loop|lottery|loud|lounge|love|loyal|lucky|luggage|lumber|lunar|lunch|luxury|lyrics|machine|mad|magic|magnet|maid|mail|main|major|make|mammal|man|manage|mandate|mango|mansion|manual|maple|marble|march|margin|marine|market|marriage|mask|mass|master|match|material|math|matrix|matter|maximum|maze|meadow|mean|measure|meat|mechanic|medal|media|melody|melt|member|memory|mention|menu|mercy|merge|merit|merry|mesh|message|metal|method|middle|midnight|milk|million|mimic|mind|minimum|minor|minute|miracle|mirror|misery|miss|mistake|mix|mixed|mixture|mobile|model|modify|mom|moment|monitor|monkey|monster|month|moon|moral|more|morning|mosquito|mother|motion|motor|mountain|mouse|move|movie|much|muffin|mule|multiply|muscle|museum|mushroom|music|must|mutual|myself|mystery|myth|naive|name|napkin|narrow|nasty|nation|nature|near|neck|need|negative|neglect|neither|nephew|nerve|nest|net|network|neutral|never|news|next|nice|night|noble|noise|nominee|noodle|normal|north|nose|notable|note|nothing|notice|novel|now|nuclear|number|nurse|nut|oak|obey|object|oblige|obscure|observe|obtain|obvious|occur|ocean|october|odor|off|offer|office|often|oil|okay|old|olive|olympic|omit|once|one|onion|online|only|open|opera|opinion|oppose|option|orange|orbit|orchard|order|ordinary|organ|orient|original|orphan|ostrich|other|outdoor|outer|output|outside|oval|oven|over|own|owner|oxygen|oyster|ozone|pact|paddle|page|pair|palace|palm|panda|panel|panic|panther|paper|parade|parent|park|parrot|party|pass|patch|path|patient|patrol|pattern|pause|pave|payment|peace|peanut|pear|peasant|pelican|pen|penalty|pencil|people|pepper|perfect|permit|person|pet|phone|photo|phrase|physical|piano|picnic|picture|piece|pig|pigeon|pill|pilot|pink|pioneer|pipe|pistol|pitch|pizza|place|planet|plastic|plate|play|please|pledge|pluck|plug|plunge|poem|poet|point|polar|pole|police|pond|pony|pool|popular|portion|position|possible|post|potato|pottery|poverty|powder|power|practice|praise|predict|prefer|prepare|present|pretty|prevent|price|pride|primary|print|priority|prison|private|prize|problem|process|produce|profit|program|project|promote|proof|property|prosper|protect|proud|provide|public|pudding|pull|pulp|pulse|pumpkin|punch|pupil|puppy|purchase|purity|purpose|purse|push|put|puzzle|pyramid|quality|quantum|quarter|question|quick|quit|quiz|quote|rabbit|raccoon|race|rack|radar|radio|rail|rain|raise|rally|ramp|ranch|random|range|rapid|rare|rate|rather|raven|raw|razor|ready|real|reason|rebel|rebuild|recall|receive|recipe|record|recycle|reduce|reflect|reform|refuse|region|regret|regular|reject|relax|release|relief|rely|remain|remember|remind|remove|render|renew|rent|reopen|repair|repeat|replace|report|require|rescue|resemble|resist|resource|response|result|retire|retreat|return|reunion|reveal|review|reward|rhythm|rib|ribbon|rice|rich|ride|ridge|rifle|right|rigid|ring|riot|ripple|risk|ritual|rival|river|road|roast|robot|robust|rocket|romance|roof|rookie|room|rose|rotate|rough|round|route|royal|rubber|rude|rug|rule|run|runway|rural|sad|saddle|sadness|safe|sail|salad|salmon|salon|salt|salute|same|sample|sand|satisfy|satoshi|sauce|sausage|save|say|scale|scan|scare|scatter|scene|scheme|school|science|scissors|scorpion|scout|scrap|screen|script|scrub|sea|search|season|seat|second|secret|section|security|seed|seek|segment|select|sell|seminar|senior|sense|sentence|series|service|session|settle|setup|seven|shadow|shaft|shallow|share|shed|shell|sheriff|shield|shift|shine|ship|shiver|shock|shoe|shoot|shop|short|shoulder|shove|shrimp|shrug|shuffle|shy|sibling|sick|side|siege|sight|sign|silent|silk|silly|silver|similar|simple|since|sing|siren|sister|situate|six|size|skate|sketch|ski|skill|skin|skirt|skull|slab|slam|sleep|slender|slice|slide|slight|slim|slogan|slot|slow|slush|small|smart|smile|smoke|smooth|snack|snake|snap|sniff|snow|soap|soccer|social|sock|soda|soft|solar|soldier|solid|solution|solve|someone|song|soon|sorry|sort|soul|sound|soup|source|south|space|spare|spatial|spawn|speak|special|speed|spell|spend|sphere|spice|spider|spike|spin|spirit|split|spoil|sponsor|spoon|sport|spot|spray|spread|spring|spy|square|squeeze|squirrel|stable|stadium|staff|stage|stairs|stamp|stand|start|state|stay|steak|steel|stem|step|stereo|stick|still|sting|stock|stomach|stone|stool|story|stove|strategy|street|strike|strong|struggle|student|stuff|stumble|style|subject|submit|subway|success|such|sudden|suffer|sugar|suggest|suit|summer|sun|sunny|sunset|super|supply|supreme|sure|surface|surge|surprise|surround|survey|suspect|sustain|swallow|swamp|swap|swarm|swear|sweet|swift|swim|swing|switch|sword|symbol|symptom|syrup|system|table|tackle|tag|tail|talent|talk|tank|tape|target|task|taste|tattoo|taxi|teach|team|tell|ten|tenant|tennis|tent|term|test|text|thank|that|theme|then|theory|there|they|thing|this|thought|three|thrive|throw|thumb|thunder|ticket|tide|tiger|tilt|timber|time|tiny|tip|tired|tissue|title|toast|tobacco|today|toddler|toe|together|toilet|token|tomato|tomorrow|tone|tongue|tonight|tool|tooth|top|topic|topple|torch|tornado|tortoise|toss|total|tourist|toward|tower|town|toy|track|trade|traffic|tragic|train|transfer|trap|trash|travel|tray|treat|tree|trend|trial|tribe|trick|trigger|trim|trip|trophy|trouble|truck|true|truly|trumpet|trust|truth|try|tube|tuition|tumble|tuna|tunnel|turkey|turn|turtle|twelve|twenty|twice|twin|twist|two|type|typical|ugly|umbrella|unable|unaware|uncle|uncover|under|undo|unfair|unfold|unhappy|uniform|unique|unit|universe|unknown|unlock|until|unusual|unveil|update|upgrade|uphold|upon|upper|upset|urban|urge|usage|use|used|useful|useless|usual|utility|vacant|vacuum|vague|valid|valley|valve|van|vanish|vapor|various|vast|vault|vehicle|velvet|vendor|venture|venue|verb|verify|version|very|vessel|veteran|viable|vibrant|vicious|victory|video|view|village|vintage|violin|virtual|virus|visa|visit|visual|vital|vivid|vocal|voice|void|volcano|volume|vote|voyage|wage|wagon|wait|walk|wall|walnut|want|warfare|warm|warrior|wash|wasp|waste|water|wave|way|wealth|weapon|wear|weasel|weather|web|wedding|weekend|weird|welcome|west|wet|whale|what|wheat|wheel|when|where|whip|whisper|wide|width|wife|wild|will|win|window|wine|wing|wink|winner|winter|wire|wisdom|wise|wish|witness|wolf|woman|wonder|wood|wool|word|work|world|worry|worth|wrap|wreck|wrestle|wrist|write|wrong|yard|year|yellow|you|young|youth|zebra|zero|zone|zoo'.split('|'); + + const INVALID_MNEMONIC = 'Invalid mnemonic'; + const INVALID_ENTROPY = 'Invalid entropy'; + const INVALID_CHECKSUM = 'Invalid mnemonic checksum'; + function normalize(str) { + return (str || '').normalize('NFKD'); + } + function binaryToByte(bin) { + return parseInt(bin, 2); + } + function bytesToBinary(bytes) { + return bytes.map((x) => x.toString(2).padStart(8, '0')).join(''); + } + function deriveChecksumBits(entropyBuffer) { + return bytesToBinary(Array.from(sha256AsU8a(entropyBuffer))).slice(0, (entropyBuffer.length * 8) / 32); + } + function mnemonicToSeedSync(mnemonic, password) { + return pbkdf2Encode(util.stringToU8a(normalize(mnemonic)), util.stringToU8a(`mnemonic${normalize(password)}`)).password; + } + function mnemonicToEntropy$1(mnemonic, wordlist = DEFAULT_WORDLIST) { + const words = normalize(mnemonic).split(' '); + if (words.length % 3 !== 0) { + throw new Error(INVALID_MNEMONIC); + } + const bits = words + .map((word) => { + const index = wordlist.indexOf(word); + if (index === -1) { + throw new Error(INVALID_MNEMONIC); + } + return index.toString(2).padStart(11, '0'); + }) + .join(''); + const dividerIndex = Math.floor(bits.length / 33) * 32; + const entropyBits = bits.slice(0, dividerIndex); + const checksumBits = bits.slice(dividerIndex); + const matched = entropyBits.match(/(.{1,8})/g); + const entropyBytes = matched?.map(binaryToByte); + if (!entropyBytes || (entropyBytes.length % 4 !== 0) || (entropyBytes.length < 16) || (entropyBytes.length > 32)) { + throw new Error(INVALID_ENTROPY); + } + const entropy = util.u8aToU8a(entropyBytes); + if (deriveChecksumBits(entropy) !== checksumBits) { + throw new Error(INVALID_CHECKSUM); + } + return entropy; + } + function entropyToMnemonic(entropy, wordlist = DEFAULT_WORDLIST) { + if ((entropy.length % 4 !== 0) || (entropy.length < 16) || (entropy.length > 32)) { + throw new Error(INVALID_ENTROPY); + } + const matched = `${bytesToBinary(Array.from(entropy))}${deriveChecksumBits(entropy)}`.match(/(.{1,11})/g); + const mapped = matched?.map((b) => wordlist[binaryToByte(b)]); + if (!mapped || (mapped.length < 12)) { + throw new Error('Unable to map entropy to mnemonic'); + } + return mapped.join(' '); + } + function generateMnemonic(numWords, wordlist) { + return entropyToMnemonic(randomAsU8a((numWords / 3) * 4), wordlist); + } + function validateMnemonic(mnemonic, wordlist) { + try { + mnemonicToEntropy$1(mnemonic, wordlist); + } + catch { + return false; + } + return true; + } + + function mnemonicGenerate(numWords = 12, wordlist, onlyJs) { + return !util.hasBigInt || (!wordlist && !onlyJs && isReady()) + ? bip39Generate(numWords) + : generateMnemonic(numWords, wordlist); + } + + function mnemonicToEntropy(mnemonic, wordlist, onlyJs) { + return !util.hasBigInt || (!wordlist && !onlyJs && isReady()) + ? bip39ToEntropy(mnemonic) + : mnemonicToEntropy$1(mnemonic, wordlist); + } + + function mnemonicValidate(mnemonic, wordlist, onlyJs) { + return !util.hasBigInt || (!wordlist && !onlyJs && isReady()) + ? bip39Validate(mnemonic) + : validateMnemonic(mnemonic, wordlist); + } + + function mnemonicToLegacySeed(mnemonic, password = '', onlyJs, byteLength = 32) { + if (!mnemonicValidate(mnemonic)) { + throw new Error('Invalid bip39 mnemonic specified'); + } + else if (![32, 64].includes(byteLength)) { + throw new Error(`Invalid seed length ${byteLength}, expected 32 or 64`); + } + return byteLength === 32 + ? !util.hasBigInt || (!onlyJs && isReady()) + ? bip39ToSeed(mnemonic, password) + : mnemonicToSeedSync(mnemonic, password).subarray(0, 32) + : mnemonicToSeedSync(mnemonic, password); + } + + function mnemonicToMiniSecret(mnemonic, password = '', wordlist, onlyJs) { + if (!mnemonicValidate(mnemonic, wordlist, onlyJs)) { + throw new Error('Invalid bip39 mnemonic specified'); + } + else if (!wordlist && !onlyJs && isReady()) { + return bip39ToMiniSecret(mnemonic, password); + } + const entropy = mnemonicToEntropy(mnemonic, wordlist); + const salt = util.stringToU8a(`mnemonic${password}`); + return pbkdf2Encode(entropy, salt).password.slice(0, 32); + } + + function ledgerDerivePrivate(xprv, index) { + const kl = xprv.subarray(0, 32); + const kr = xprv.subarray(32, 64); + const cc = xprv.subarray(64, 96); + const data = util.u8aConcat([0], kl, kr, util.bnToU8a(index, BN_LE_32_OPTS)); + const z = hmacShaAsU8a(cc, data, 512); + data[0] = 0x01; + return util.u8aConcat(util.bnToU8a(util.u8aToBn(kl, BN_LE_OPTS).iadd(util.u8aToBn(z.subarray(0, 28), BN_LE_OPTS).imul(util.BN_EIGHT)), BN_LE_512_OPTS).subarray(0, 32), util.bnToU8a(util.u8aToBn(kr, BN_LE_OPTS).iadd(util.u8aToBn(z.subarray(32, 64), BN_LE_OPTS)), BN_LE_512_OPTS).subarray(0, 32), hmacShaAsU8a(cc, data, 512).subarray(32, 64)); + } + + const ED25519_CRYPTO = 'ed25519 seed'; + function ledgerMaster(mnemonic, password) { + const seed = mnemonicToSeedSync(mnemonic, password); + const chainCode = hmacShaAsU8a(ED25519_CRYPTO, new Uint8Array([1, ...seed]), 256); + let priv; + while (!priv || (priv[31] & 0b0010_0000)) { + priv = hmacShaAsU8a(ED25519_CRYPTO, priv || seed, 512); + } + priv[0] &= 0b1111_1000; + priv[31] &= 0b0111_1111; + priv[31] |= 0b0100_0000; + return util.u8aConcat(priv, chainCode); + } + + function hdLedger(_mnemonic, path) { + const words = _mnemonic + .split(' ') + .map((s) => s.trim()) + .filter((s) => s); + if (![12, 24, 25].includes(words.length)) { + throw new Error('Expected a mnemonic with 24 words (or 25 including a password)'); + } + const [mnemonic, password] = words.length === 25 + ? [words.slice(0, 24).join(' '), words[24]] + : [words.join(' '), '']; + if (!mnemonicValidate(mnemonic)) { + throw new Error('Invalid mnemonic passed to ledger derivation'); + } + else if (!hdValidatePath(path)) { + throw new Error('Invalid derivation path'); + } + const parts = path.split('/').slice(1); + let seed = ledgerMaster(mnemonic, password); + for (const p of parts) { + const n = parseInt(p.replace(/'$/, ''), 10); + seed = ledgerDerivePrivate(seed, (n < HARDENED) ? (n + HARDENED) : n); + } + return ed25519PairFromSeed(seed.slice(0, 32)); + } + + function L32(x, c) { return (x << c) | (x >>> (32 - c)); } + function ld32(x, i) { + let u = x[i + 3] & 0xff; + u = (u << 8) | (x[i + 2] & 0xff); + u = (u << 8) | (x[i + 1] & 0xff); + return (u << 8) | (x[i + 0] & 0xff); + } + function st32(x, j, u) { + for (let i = 0; i < 4; i++) { + x[j + i] = u & 255; + u >>>= 8; + } + } + function vn(x, xi, y, yi, n) { + let d = 0; + for (let i = 0; i < n; i++) + d |= x[xi + i] ^ y[yi + i]; + return (1 & ((d - 1) >>> 8)) - 1; + } + function core(out, inp, k, c, h) { + const w = new Uint32Array(16), x = new Uint32Array(16), y = new Uint32Array(16), t = new Uint32Array(4); + let i, j, m; + for (i = 0; i < 4; i++) { + x[5 * i] = ld32(c, 4 * i); + x[1 + i] = ld32(k, 4 * i); + x[6 + i] = ld32(inp, 4 * i); + x[11 + i] = ld32(k, 16 + 4 * i); + } + for (i = 0; i < 16; i++) + y[i] = x[i]; + for (i = 0; i < 20; i++) { + for (j = 0; j < 4; j++) { + for (m = 0; m < 4; m++) + t[m] = x[(5 * j + 4 * m) % 16]; + t[1] ^= L32((t[0] + t[3]) | 0, 7); + t[2] ^= L32((t[1] + t[0]) | 0, 9); + t[3] ^= L32((t[2] + t[1]) | 0, 13); + t[0] ^= L32((t[3] + t[2]) | 0, 18); + for (m = 0; m < 4; m++) + w[4 * j + (j + m) % 4] = t[m]; + } + for (m = 0; m < 16; m++) + x[m] = w[m]; + } + if (h) { + for (i = 0; i < 16; i++) + x[i] = (x[i] + y[i]) | 0; + for (i = 0; i < 4; i++) { + x[5 * i] = (x[5 * i] - ld32(c, 4 * i)) | 0; + x[6 + i] = (x[6 + i] - ld32(inp, 4 * i)) | 0; + } + for (i = 0; i < 4; i++) { + st32(out, 4 * i, x[5 * i]); + st32(out, 16 + 4 * i, x[6 + i]); + } + } + else { + for (i = 0; i < 16; i++) + st32(out, 4 * i, (x[i] + y[i]) | 0); + } + } + const sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]); + function crypto_stream_salsa20_xor(c, cpos, m, mpos, b, n, k) { + const z = new Uint8Array(16), x = new Uint8Array(64); + let u, i; + if (!b) + return 0; + for (i = 0; i < 16; i++) + z[i] = 0; + for (i = 0; i < 8; i++) + z[i] = n[i]; + while (b >= 64) { + core(x, z, k, sigma, false); + for (i = 0; i < 64; i++) + c[cpos + i] = (m ? m[mpos + i] : 0) ^ x[i]; + u = 1; + for (i = 8; i < 16; i++) { + u = u + (z[i] & 0xff) | 0; + z[i] = u & 0xff; + u >>>= 8; + } + b -= 64; + cpos += 64; + if (m) + mpos += 64; + } + if (b > 0) { + core(x, z, k, sigma, false); + for (i = 0; i < b; i++) + c[cpos + i] = (m ? m[mpos + i] : 0) ^ x[i]; + } + return 0; + } + function crypto_stream_xor(c, cpos, m, mpos, d, n, k) { + const s = new Uint8Array(32); + core(s, n, k, sigma, true); + return crypto_stream_salsa20_xor(c, cpos, m, mpos, d, n.subarray(16), s); + } + function add1305(h, c) { + let u = 0; + for (let j = 0; j < 17; j++) { + u = (u + ((h[j] + c[j]) | 0)) | 0; + h[j] = u & 255; + u >>>= 8; + } + } + const minusp = new Uint32Array([5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252]); + function crypto_onetimeauth(out, outpos, m, mpos, n, k) { + let i, j, u; + const x = new Uint32Array(17), r = new Uint32Array(17), h = new Uint32Array(17), c = new Uint32Array(17), g = new Uint32Array(17); + for (j = 0; j < 17; j++) + r[j] = h[j] = 0; + for (j = 0; j < 16; j++) + r[j] = k[j]; + r[3] &= 15; + r[4] &= 252; + r[7] &= 15; + r[8] &= 252; + r[11] &= 15; + r[12] &= 252; + r[15] &= 15; + while (n > 0) { + for (j = 0; j < 17; j++) + c[j] = 0; + for (j = 0; (j < 16) && (j < n); ++j) + c[j] = m[mpos + j]; + c[j] = 1; + mpos += j; + n -= j; + add1305(h, c); + for (i = 0; i < 17; i++) { + x[i] = 0; + for (j = 0; j < 17; j++) + x[i] = (x[i] + (h[j] * ((j <= i) ? r[i - j] : ((320 * r[i + 17 - j]) | 0))) | 0) | 0; + } + for (i = 0; i < 17; i++) + h[i] = x[i]; + u = 0; + for (j = 0; j < 16; j++) { + u = (u + h[j]) | 0; + h[j] = u & 255; + u >>>= 8; + } + u = (u + h[16]) | 0; + h[16] = u & 3; + u = (5 * (u >>> 2)) | 0; + for (j = 0; j < 16; j++) { + u = (u + h[j]) | 0; + h[j] = u & 255; + u >>>= 8; + } + u = (u + h[16]) | 0; + h[16] = u; + } + for (j = 0; j < 17; j++) + g[j] = h[j]; + add1305(h, minusp); + const s = (-(h[16] >>> 7) | 0); + for (j = 0; j < 17; j++) + h[j] ^= s & (g[j] ^ h[j]); + for (j = 0; j < 16; j++) + c[j] = k[j + 16]; + c[16] = 0; + add1305(h, c); + for (j = 0; j < 16; j++) + out[outpos + j] = h[j]; + return 0; + } + function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) { + const x = new Uint8Array(16); + crypto_onetimeauth(x, 0, m, mpos, n, k); + return vn(h, hpos, x, 0, 16); + } + function crypto_secretbox(c, m, d, n, k) { + if (d < 32) + return -1; + crypto_stream_xor(c, 0, m, 0, d, n, k); + crypto_onetimeauth(c, 16, c, 32, d - 32, c); + for (let i = 0; i < 16; i++) + c[i] = 0; + return 0; + } + function crypto_secretbox_open(m, c, d, n, k) { + const x = new Uint8Array(32); + if (d < 32) + return -1; + crypto_stream_xor(x, 0, null, 0, 32, n, k); + if (crypto_onetimeauth_verify(c, 16, c, 32, d - 32, x) !== 0) + return -1; + crypto_stream_xor(m, 0, c, 0, d, n, k); + for (let i = 0; i < 32; i++) + m[i] = 0; + return 0; + } + const crypto_secretbox_KEYBYTES = 32; + const crypto_secretbox_NONCEBYTES = 24; + const crypto_secretbox_ZEROBYTES = 32; + const crypto_secretbox_BOXZEROBYTES = 16; + function checkLengths(k, n) { + if (k.length !== crypto_secretbox_KEYBYTES) + throw new Error('bad key size'); + if (n.length !== crypto_secretbox_NONCEBYTES) + throw new Error('bad nonce size'); + } + function checkArrayTypes(...args) { + for (let i = 0, count = args.length; i < count; i++) { + if (!(args[i] instanceof Uint8Array)) + throw new TypeError('unexpected type, use Uint8Array'); + } + } + function naclSecretbox(msg, nonce, key) { + checkArrayTypes(msg, nonce, key); + checkLengths(key, nonce); + const m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length); + const c = new Uint8Array(m.length); + for (let i = 0; i < msg.length; i++) + m[i + crypto_secretbox_ZEROBYTES] = msg[i]; + crypto_secretbox(c, m, m.length, nonce, key); + return c.subarray(crypto_secretbox_BOXZEROBYTES); + } + function naclSecretboxOpen(box, nonce, key) { + checkArrayTypes(box, nonce, key); + checkLengths(key, nonce); + const c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length); + const m = new Uint8Array(c.length); + for (let i = 0; i < box.length; i++) + c[i + crypto_secretbox_BOXZEROBYTES] = box[i]; + if (c.length < 32) + return null; + if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) + return null; + return m.subarray(crypto_secretbox_ZEROBYTES); + } + + function naclDecrypt(encrypted, nonce, secret) { + return naclSecretboxOpen(encrypted, nonce, secret); + } + + function naclEncrypt(message, secret, nonce = randomAsU8a(24)) { + return { + encrypted: naclSecretbox(message, nonce, secret), + nonce + }; + } + + function XorAndSalsa(prev, pi, input, ii, out, oi) { + let y00 = prev[pi++] ^ input[ii++], y01 = prev[pi++] ^ input[ii++]; + let y02 = prev[pi++] ^ input[ii++], y03 = prev[pi++] ^ input[ii++]; + let y04 = prev[pi++] ^ input[ii++], y05 = prev[pi++] ^ input[ii++]; + let y06 = prev[pi++] ^ input[ii++], y07 = prev[pi++] ^ input[ii++]; + let y08 = prev[pi++] ^ input[ii++], y09 = prev[pi++] ^ input[ii++]; + let y10 = prev[pi++] ^ input[ii++], y11 = prev[pi++] ^ input[ii++]; + let y12 = prev[pi++] ^ input[ii++], y13 = prev[pi++] ^ input[ii++]; + let y14 = prev[pi++] ^ input[ii++], y15 = prev[pi++] ^ input[ii++]; + let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15; + for (let i = 0; i < 8; i += 2) { + x04 ^= rotl$1(x00 + x12 | 0, 7); + x08 ^= rotl$1(x04 + x00 | 0, 9); + x12 ^= rotl$1(x08 + x04 | 0, 13); + x00 ^= rotl$1(x12 + x08 | 0, 18); + x09 ^= rotl$1(x05 + x01 | 0, 7); + x13 ^= rotl$1(x09 + x05 | 0, 9); + x01 ^= rotl$1(x13 + x09 | 0, 13); + x05 ^= rotl$1(x01 + x13 | 0, 18); + x14 ^= rotl$1(x10 + x06 | 0, 7); + x02 ^= rotl$1(x14 + x10 | 0, 9); + x06 ^= rotl$1(x02 + x14 | 0, 13); + x10 ^= rotl$1(x06 + x02 | 0, 18); + x03 ^= rotl$1(x15 + x11 | 0, 7); + x07 ^= rotl$1(x03 + x15 | 0, 9); + x11 ^= rotl$1(x07 + x03 | 0, 13); + x15 ^= rotl$1(x11 + x07 | 0, 18); + x01 ^= rotl$1(x00 + x03 | 0, 7); + x02 ^= rotl$1(x01 + x00 | 0, 9); + x03 ^= rotl$1(x02 + x01 | 0, 13); + x00 ^= rotl$1(x03 + x02 | 0, 18); + x06 ^= rotl$1(x05 + x04 | 0, 7); + x07 ^= rotl$1(x06 + x05 | 0, 9); + x04 ^= rotl$1(x07 + x06 | 0, 13); + x05 ^= rotl$1(x04 + x07 | 0, 18); + x11 ^= rotl$1(x10 + x09 | 0, 7); + x08 ^= rotl$1(x11 + x10 | 0, 9); + x09 ^= rotl$1(x08 + x11 | 0, 13); + x10 ^= rotl$1(x09 + x08 | 0, 18); + x12 ^= rotl$1(x15 + x14 | 0, 7); + x13 ^= rotl$1(x12 + x15 | 0, 9); + x14 ^= rotl$1(x13 + x12 | 0, 13); + x15 ^= rotl$1(x14 + x13 | 0, 18); + } + out[oi++] = (y00 + x00) | 0; + out[oi++] = (y01 + x01) | 0; + out[oi++] = (y02 + x02) | 0; + out[oi++] = (y03 + x03) | 0; + out[oi++] = (y04 + x04) | 0; + out[oi++] = (y05 + x05) | 0; + out[oi++] = (y06 + x06) | 0; + out[oi++] = (y07 + x07) | 0; + out[oi++] = (y08 + x08) | 0; + out[oi++] = (y09 + x09) | 0; + out[oi++] = (y10 + x10) | 0; + out[oi++] = (y11 + x11) | 0; + out[oi++] = (y12 + x12) | 0; + out[oi++] = (y13 + x13) | 0; + out[oi++] = (y14 + x14) | 0; + out[oi++] = (y15 + x15) | 0; + } + function BlockMix(input, ii, out, oi, r) { + let head = oi + 0; + let tail = oi + 16 * r; + for (let i = 0; i < 16; i++) + out[tail + i] = input[ii + (2 * r - 1) * 16 + i]; + for (let i = 0; i < r; i++, head += 16, ii += 16) { + XorAndSalsa(out, tail, input, ii, out, head); + if (i > 0) + tail += 16; + XorAndSalsa(out, head, input, (ii += 16), out, tail); + } + } + function scryptInit(password, salt, _opts) { + const opts = checkOpts({ + dkLen: 32, + asyncTick: 10, + maxmem: 1024 ** 3 + 1024, + }, _opts); + const { N, r, p, dkLen, asyncTick, maxmem, onProgress } = opts; + anumber(N); + anumber(r); + anumber(p); + anumber(dkLen); + anumber(asyncTick); + anumber(maxmem); + if (onProgress !== undefined && typeof onProgress !== 'function') + throw new Error('progressCb should be function'); + const blockSize = 128 * r; + const blockSize32 = blockSize / 4; + const pow32 = Math.pow(2, 32); + if (N <= 1 || (N & (N - 1)) !== 0 || N > pow32) { + throw new Error('Scrypt: N must be larger than 1, a power of 2, and less than 2^32'); + } + if (p < 0 || p > ((pow32 - 1) * 32) / blockSize) { + throw new Error('Scrypt: p must be a positive integer less than or equal to ((2^32 - 1) * 32) / (128 * r)'); + } + if (dkLen < 0 || dkLen > (pow32 - 1) * 32) { + throw new Error('Scrypt: dkLen should be positive integer less than or equal to (2^32 - 1) * 32'); + } + const memUsed = blockSize * (N + p); + if (memUsed > maxmem) { + throw new Error('Scrypt: memused is bigger than maxMem. Expected 128 * r * (N + p) > maxmem of ' + maxmem); + } + const B = pbkdf2(sha256$1, password, salt, { c: 1, dkLen: blockSize * p }); + const B32 = u32(B); + const V = u32(new Uint8Array(blockSize * N)); + const tmp = u32(new Uint8Array(blockSize)); + let blockMixCb = () => { }; + if (onProgress) { + const totalBlockMix = 2 * N * p; + const callbackPer = Math.max(Math.floor(totalBlockMix / 10000), 1); + let blockMixCnt = 0; + blockMixCb = () => { + blockMixCnt++; + if (onProgress && (!(blockMixCnt % callbackPer) || blockMixCnt === totalBlockMix)) + onProgress(blockMixCnt / totalBlockMix); + }; + } + return { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick }; + } + function scryptOutput(password, dkLen, B, V, tmp) { + const res = pbkdf2(sha256$1, password, B, { c: 1, dkLen }); + clean(B, V, tmp); + return res; + } + function scrypt(password, salt, opts) { + const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb } = scryptInit(password, salt, opts); + swap32IfBE(B32); + for (let pi = 0; pi < p; pi++) { + const Pi = blockSize32 * pi; + for (let i = 0; i < blockSize32; i++) + V[i] = B32[Pi + i]; + for (let i = 0, pos = 0; i < N - 1; i++) { + BlockMix(V, pos, V, (pos += blockSize32), r); + blockMixCb(); + } + BlockMix(V, (N - 1) * blockSize32, B32, Pi, r); + blockMixCb(); + for (let i = 0; i < N; i++) { + const j = B32[Pi + blockSize32 - 16] % N; + for (let k = 0; k < blockSize32; k++) + tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k]; + BlockMix(tmp, 0, B32, Pi, r); + blockMixCb(); + } + } + swap32IfBE(B32); + return scryptOutput(password, dkLen, B, V, tmp); + } + + const ALLOWED_PARAMS = [ + { N: 1 << 13, p: 10, r: 8 }, + { N: 1 << 14, p: 5, r: 8 }, + { N: 1 << 15, p: 3, r: 8 }, + { N: 1 << 15, p: 1, r: 8 }, + { N: 1 << 16, p: 2, r: 8 }, + { N: 1 << 17, p: 1, r: 8 } + ]; + const DEFAULT_PARAMS = { + N: 1 << 17, + p: 1, + r: 8 + }; + + function scryptEncode(passphrase, salt = randomAsU8a(), params = DEFAULT_PARAMS, onlyJs) { + const u8a = util.u8aToU8a(passphrase); + return { + params, + password: !util.hasBigInt || (!onlyJs && isReady()) + ? scrypt$1(u8a, salt, Math.log2(params.N), params.r, params.p) + : scrypt(u8a, salt, util.objectSpread({ dkLen: 64 }, params)), + salt + }; + } + + function scryptFromU8a(data) { + if (!(data instanceof Uint8Array)) { + throw new Error('Expected input to be a Uint8Array'); + } + if (data.length < 32 + 12) { + throw new Error(`Invalid input length: expected 44 bytes, found ${data.length}`); + } + const salt = data.subarray(0, 32); + const N = util.u8aToBn(data.subarray(32, 36), BN_LE_OPTS).toNumber(); + const p = util.u8aToBn(data.subarray(36, 40), BN_LE_OPTS).toNumber(); + const r = util.u8aToBn(data.subarray(40, 44), BN_LE_OPTS).toNumber(); + if (N > (1 << 20) || p > 4 || r > 16) { + throw new Error('Scrypt parameters exceed safe limits'); + } + const isAllowed = ALLOWED_PARAMS.some((preset) => preset.N === N && preset.p === p && preset.r === r); + if (!isAllowed) { + throw new Error('Invalid injected scrypt params found'); + } + return { params: { N, p, r }, salt }; + } + + function scryptToU8a(salt, { N, p, r }) { + return util.u8aConcat(salt, util.bnToU8a(N, BN_LE_32_OPTS), util.bnToU8a(p, BN_LE_32_OPTS), util.bnToU8a(r, BN_LE_32_OPTS)); + } + + const ENCODING = ['scrypt', 'xsalsa20-poly1305']; + const ENCODING_NONE = ['none']; + const ENCODING_VERSION = '3'; + const NONCE_LENGTH = 24; + const SCRYPT_LENGTH = 32 + (3 * 4); + + function jsonDecryptData(encrypted, passphrase, encType = ENCODING) { + if (!encrypted) { + throw new Error('No encrypted data available to decode'); + } + else if (encType.includes('xsalsa20-poly1305') && !passphrase) { + throw new Error('Password required to decode encrypted data'); + } + let encoded = encrypted; + if (passphrase) { + let password; + if (encType.includes('scrypt')) { + const { params, salt } = scryptFromU8a(encrypted); + password = scryptEncode(passphrase, salt, params).password; + encrypted = encrypted.subarray(SCRYPT_LENGTH); + } + else { + password = util.stringToU8a(passphrase); + } + encoded = naclDecrypt(encrypted.subarray(NONCE_LENGTH), encrypted.subarray(0, NONCE_LENGTH), util.u8aFixLength(password, 256, true)); + } + if (!encoded) { + throw new Error('Unable to decode using the supplied passphrase'); + } + return encoded; + } + + function jsonDecrypt({ encoded, encoding }, passphrase) { + if (!encoded) { + throw new Error('No encrypted data available to decode'); + } + return jsonDecryptData(util.isHex(encoded) + ? util.hexToU8a(encoded) + : base64Decode(encoded), passphrase, Array.isArray(encoding.type) + ? encoding.type + : [encoding.type]); + } + + function jsonEncryptFormat(encoded, contentType, isEncrypted) { + return { + encoded: base64Encode(encoded), + encoding: { + content: contentType, + type: isEncrypted + ? ENCODING + : ENCODING_NONE, + version: ENCODING_VERSION + } + }; + } + + function jsonEncrypt(data, contentType, passphrase) { + let isEncrypted = false; + let encoded = data; + if (passphrase) { + const { params, password, salt } = scryptEncode(passphrase); + const { encrypted, nonce } = naclEncrypt(encoded, password.subarray(0, 32)); + isEncrypted = true; + encoded = util.u8aConcat(scryptToU8a(salt, params), nonce, encrypted); + } + return jsonEncryptFormat(encoded, contentType, isEncrypted); + } + + const secp256k1VerifyHasher = (hashType) => (message, signature, publicKey) => secp256k1Verify(message, signature, publicKey, hashType, true); + const VERIFIERS_ECDSA = [ + ['ecdsa', secp256k1VerifyHasher('blake2')], + ['ethereum', secp256k1VerifyHasher('keccak')] + ]; + const VERIFIERS = [ + ['ed25519', ed25519Verify], + ['sr25519', sr25519Verify] + ]; + function verifyDetect(result, { message, publicKey, signature }, verifiers = [...VERIFIERS, ...VERIFIERS_ECDSA]) { + result.isValid = verifiers.some(([crypto, verify]) => { + try { + if (verify(message, signature, publicKey)) { + result.crypto = crypto; + return true; + } + } + catch { + } + return false; + }); + return result; + } + function verifyMultisig(result, { message, publicKey, signature }) { + if (![0, 1, 2].includes(signature[0]) || ![65, 66].includes(signature.length)) { + throw new Error(`Unknown crypto type, expected signature prefix [0..2], found ${signature[0]}`); + } + if (signature.length === 66) { + result = verifyDetect(result, { message, publicKey, signature: signature.subarray(1) }, VERIFIERS_ECDSA); + } + else { + result = verifyDetect(result, { message, publicKey, signature: signature.subarray(1) }, VERIFIERS); + if (!result.isValid) { + result = verifyDetect(result, { message, publicKey, signature }, VERIFIERS_ECDSA); + } + if (!result.isValid) { + result.crypto = 'none'; + } + } + return result; + } + function getVerifyFn(signature) { + return [0, 1, 2].includes(signature[0]) && [65, 66].includes(signature.length) + ? verifyMultisig + : verifyDetect; + } + function signatureVerify(message, signature, addressOrPublicKey) { + const signatureU8a = util.u8aToU8a(signature); + if (![64, 65, 66].includes(signatureU8a.length)) { + throw new Error(`Invalid signature length, expected [64..66] bytes, found ${signatureU8a.length}`); + } + const publicKey = decodeAddress(addressOrPublicKey); + const input = { message: util.u8aToU8a(message), publicKey, signature: signatureU8a }; + const result = { crypto: 'none', isValid: false, isWrapped: util.u8aIsWrapped(input.message, true), publicKey }; + const isWrappedBytes = util.u8aIsWrapped(input.message, false); + const verifyFn = getVerifyFn(signatureU8a); + verifyFn(result, input); + if (result.crypto !== 'none' || (result.isWrapped && !isWrappedBytes)) { + return result; + } + input.message = isWrappedBytes + ? util.u8aUnwrapBytes(input.message) + : util.u8aWrapBytes(input.message); + return verifyFn(result, input); + } + + const P64_1 = BigInt$1('11400714785074694791'); + const P64_2 = BigInt$1('14029467366897019727'); + const P64_3 = BigInt$1('1609587929392839161'); + const P64_4 = BigInt$1('9650029242287828579'); + const P64_5 = BigInt$1('2870177450012600261'); + const U64 = BigInt$1('0xffffffffffffffff'); + const _7n = BigInt$1(7); + const _11n = BigInt$1(11); + const _12n = BigInt$1(12); + const _16n = BigInt$1(16); + const _18n = BigInt$1(18); + const _23n = BigInt$1(23); + const _27n = BigInt$1(27); + const _29n = BigInt$1(29); + const _31n = BigInt$1(31); + const _32n = BigInt$1(32); + const _33n = BigInt$1(33); + const _64n = BigInt$1(64); + const _256n = BigInt$1(256); + function rotl(a, b) { + const c = a & U64; + return ((c << b) | (c >> (_64n - b))) & U64; + } + function fromU8a(u8a, p, count) { + const bigints = new Array(count); + let offset = 0; + for (let i = 0; i < count; i++, offset += 2) { + bigints[i] = BigInt$1(u8a[p + offset] | (u8a[p + 1 + offset] << 8)); + } + let result = util._0n; + for (let i = count - 1; i >= 0; i--) { + result = (result << _16n) + bigints[i]; + } + return result; + } + function init(seed, input) { + const state = { + seed, + u8a: new Uint8Array(32), + u8asize: 0, + v1: seed + P64_1 + P64_2, + v2: seed + P64_2, + v3: seed, + v4: seed - P64_1 + }; + if (input.length < 32) { + state.u8a.set(input); + state.u8asize = input.length; + return state; + } + const limit = input.length - 32; + let p = 0; + if (limit >= 0) { + const adjustV = (v) => P64_1 * rotl(v + P64_2 * fromU8a(input, p, 4), _31n); + do { + state.v1 = adjustV(state.v1); + p += 8; + state.v2 = adjustV(state.v2); + p += 8; + state.v3 = adjustV(state.v3); + p += 8; + state.v4 = adjustV(state.v4); + p += 8; + } while (p <= limit); + } + if (p < input.length) { + state.u8a.set(input.subarray(p, input.length)); + state.u8asize = input.length - p; + } + return state; + } + function xxhash64(input, initSeed) { + const { seed, u8a, u8asize, v1, v2, v3, v4 } = init(BigInt$1(initSeed), input); + let p = 0; + let h64 = U64 & (BigInt$1(input.length) + (input.length >= 32 + ? (((((((((rotl(v1, util._1n) + rotl(v2, _7n) + rotl(v3, _12n) + rotl(v4, _18n)) ^ (P64_1 * rotl(v1 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v2 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v3 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v4 * P64_2, _31n))) * P64_1 + P64_4) + : (seed + P64_5))); + while (p <= (u8asize - 8)) { + h64 = U64 & (P64_4 + P64_1 * rotl(h64 ^ (P64_1 * rotl(P64_2 * fromU8a(u8a, p, 4), _31n)), _27n)); + p += 8; + } + if ((p + 4) <= u8asize) { + h64 = U64 & (P64_3 + P64_2 * rotl(h64 ^ (P64_1 * fromU8a(u8a, p, 2)), _23n)); + p += 4; + } + while (p < u8asize) { + h64 = U64 & (P64_1 * rotl(h64 ^ (P64_5 * BigInt$1(u8a[p++])), _11n)); + } + h64 = U64 & (P64_2 * (h64 ^ (h64 >> _33n))); + h64 = U64 & (P64_3 * (h64 ^ (h64 >> _29n))); + h64 = U64 & (h64 ^ (h64 >> _32n)); + const result = new Uint8Array(8); + for (let i = 7; i >= 0; i--) { + result[i] = Number(h64 % _256n); + h64 = h64 / _256n; + } + return result; + } + + function xxhashAsU8a(data, bitLength = 64, onlyJs) { + const rounds = Math.ceil(bitLength / 64); + const u8a = util.u8aToU8a(data); + if (!util.hasBigInt || (!onlyJs && isReady())) { + return twox(u8a, rounds); + } + const result = new Uint8Array(rounds * 8); + for (let seed = 0; seed < rounds; seed++) { + result.set(xxhash64(u8a, seed).reverse(), seed * 8); + } + return result; + } + const xxhashAsHex = createAsHex(xxhashAsU8a); + + exports.addressEq = addressEq; + exports.addressToEvm = addressToEvm; + exports.allNetworks = allNetworks; + exports.availableNetworks = availableNetworks; + exports.base32Decode = base32Decode; + exports.base32Encode = base32Encode; + exports.base32Validate = base32Validate; + exports.base58Decode = base58Decode; + exports.base58Encode = base58Encode; + exports.base58Validate = base58Validate; + exports.base64Decode = base64Decode; + exports.base64Encode = base64Encode; + exports.base64Pad = base64Pad; + exports.base64Trim = base64Trim; + exports.base64Validate = base64Validate; + exports.blake2AsHex = blake2AsHex; + exports.blake2AsU8a = blake2AsU8a; + exports.checkAddress = checkAddress; + exports.checkAddressChecksum = checkAddressChecksum; + exports.createKeyDerived = createKeyDerived; + exports.createKeyMulti = createKeyMulti; + exports.cryptoIsReady = cryptoIsReady; + exports.cryptoWaitReady = cryptoWaitReady; + exports.decodeAddress = decodeAddress; + exports.deriveAddress = deriveAddress; + exports.ed25519DeriveHard = ed25519DeriveHard; + exports.ed25519PairFromRandom = ed25519PairFromRandom; + exports.ed25519PairFromSecret = ed25519PairFromSecret; + exports.ed25519PairFromSeed = ed25519PairFromSeed; + exports.ed25519PairFromString = ed25519PairFromString; + exports.ed25519Sign = ed25519Sign; + exports.ed25519Verify = ed25519Verify; + exports.encodeAddress = encodeAddress; + exports.encodeDerivedAddress = encodeDerivedAddress; + exports.encodeMultiAddress = encodeMultiAddress; + exports.ethereumEncode = ethereumEncode; + exports.evmToAddress = evmToAddress; + exports.hdEthereum = hdEthereum; + exports.hdLedger = hdLedger; + exports.hdValidatePath = hdValidatePath; + exports.hmacSha256AsU8a = hmacSha256AsU8a; + exports.hmacSha512AsU8a = hmacSha512AsU8a; + exports.hmacShaAsU8a = hmacShaAsU8a; + exports.isAddress = isAddress; + exports.isBase32 = isBase32; + exports.isBase58 = isBase58; + exports.isBase64 = isBase64; + exports.isEthereumAddress = isEthereumAddress; + exports.isEthereumChecksum = isEthereumChecksum; + exports.jsonDecrypt = jsonDecrypt; + exports.jsonDecryptData = jsonDecryptData; + exports.jsonEncrypt = jsonEncrypt; + exports.jsonEncryptFormat = jsonEncryptFormat; + exports.keccak256AsU8a = keccak256AsU8a; + exports.keccak512AsU8a = keccak512AsU8a; + exports.keccakAsHex = keccakAsHex; + exports.keccakAsU8a = keccakAsU8a; + exports.keyExtractPath = keyExtractPath; + exports.keyExtractSuri = keyExtractSuri; + exports.keyFromPath = keyFromPath; + exports.keyHdkdEcdsa = keyHdkdEcdsa; + exports.keyHdkdEd25519 = keyHdkdEd25519; + exports.keyHdkdSr25519 = keyHdkdSr25519; + exports.mnemonicGenerate = mnemonicGenerate; + exports.mnemonicToEntropy = mnemonicToEntropy; + exports.mnemonicToLegacySeed = mnemonicToLegacySeed; + exports.mnemonicToMiniSecret = mnemonicToMiniSecret; + exports.mnemonicValidate = mnemonicValidate; + exports.naclDecrypt = naclDecrypt; + exports.naclEncrypt = naclEncrypt; + exports.packageInfo = packageInfo; + exports.pbkdf2Encode = pbkdf2Encode; + exports.randomAsHex = randomAsHex; + exports.randomAsNumber = randomAsNumber; + exports.randomAsU8a = randomAsU8a; + exports.scryptEncode = scryptEncode; + exports.scryptFromU8a = scryptFromU8a; + exports.scryptToU8a = scryptToU8a; + exports.secp256k1Compress = secp256k1Compress; + exports.secp256k1Expand = secp256k1Expand; + exports.secp256k1PairFromSeed = secp256k1PairFromSeed; + exports.secp256k1PrivateKeyTweakAdd = secp256k1PrivateKeyTweakAdd; + exports.secp256k1Recover = secp256k1Recover; + exports.secp256k1Sign = secp256k1Sign; + exports.secp256k1Verify = secp256k1Verify; + exports.selectableNetworks = selectableNetworks; + exports.setSS58Format = setSS58Format; + exports.sha256AsU8a = sha256AsU8a; + exports.sha512AsU8a = sha512AsU8a; + exports.shaAsU8a = shaAsU8a; + exports.signatureVerify = signatureVerify; + exports.sortAddresses = sortAddresses; + exports.sr25519Agreement = sr25519Agreement; + exports.sr25519DeriveHard = sr25519DeriveHard; + exports.sr25519DerivePublic = sr25519DerivePublic; + exports.sr25519DeriveSoft = sr25519DeriveSoft; + exports.sr25519PairFromSeed = sr25519PairFromSeed; + exports.sr25519Sign = sr25519Sign; + exports.sr25519Verify = sr25519Verify; + exports.sr25519VrfSign = sr25519VrfSign; + exports.sr25519VrfVerify = sr25519VrfVerify; + exports.validateAddress = validateAddress; + exports.xxhashAsHex = xxhashAsHex; + exports.xxhashAsU8a = xxhashAsU8a; + +})); diff --git a/packages/util-crypto/bundle.d.ts b/packages/util-crypto/bundle.d.ts new file mode 100644 index 0000000..57263d8 --- /dev/null +++ b/packages/util-crypto/bundle.d.ts @@ -0,0 +1,26 @@ +import './bundleInit.js'; +export { packageInfo } from './packageInfo.js'; +export * from './address/index.js'; +export * from './base32/index.js'; +export * from './base58/index.js'; +export * from './base64/index.js'; +export * from './blake2/index.js'; +export * from './crypto.js'; +export * from './ed25519/index.js'; +export * from './ethereum/index.js'; +export * from './hd/index.js'; +export * from './hmac/index.js'; +export * from './json/index.js'; +export * from './keccak/index.js'; +export * from './key/index.js'; +export * from './mnemonic/index.js'; +export * from './nacl/index.js'; +export * from './networks.js'; +export * from './pbkdf2/index.js'; +export * from './random/index.js'; +export * from './scrypt/index.js'; +export * from './secp256k1/index.js'; +export * from './sha/index.js'; +export * from './signature/index.js'; +export * from './sr25519/index.js'; +export * from './xxhash/index.js'; diff --git a/packages/util-crypto/bundle.js b/packages/util-crypto/bundle.js new file mode 100644 index 0000000..57263d8 --- /dev/null +++ b/packages/util-crypto/bundle.js @@ -0,0 +1,26 @@ +import './bundleInit.js'; +export { packageInfo } from './packageInfo.js'; +export * from './address/index.js'; +export * from './base32/index.js'; +export * from './base58/index.js'; +export * from './base64/index.js'; +export * from './blake2/index.js'; +export * from './crypto.js'; +export * from './ed25519/index.js'; +export * from './ethereum/index.js'; +export * from './hd/index.js'; +export * from './hmac/index.js'; +export * from './json/index.js'; +export * from './keccak/index.js'; +export * from './key/index.js'; +export * from './mnemonic/index.js'; +export * from './nacl/index.js'; +export * from './networks.js'; +export * from './pbkdf2/index.js'; +export * from './random/index.js'; +export * from './scrypt/index.js'; +export * from './secp256k1/index.js'; +export * from './sha/index.js'; +export * from './signature/index.js'; +export * from './sr25519/index.js'; +export * from './xxhash/index.js'; diff --git a/packages/util-crypto/bundleInit.d.ts b/packages/util-crypto/bundleInit.d.ts new file mode 100644 index 0000000..2328298 --- /dev/null +++ b/packages/util-crypto/bundleInit.d.ts @@ -0,0 +1 @@ +import '@pezkuwi/x-bigint/shim'; diff --git a/packages/util-crypto/bundleInit.js b/packages/util-crypto/bundleInit.js new file mode 100644 index 0000000..9b2e710 --- /dev/null +++ b/packages/util-crypto/bundleInit.js @@ -0,0 +1,5 @@ +import '@pezkuwi/x-bigint/shim'; +import { cryptoWaitReady } from './crypto.js'; +cryptoWaitReady().catch(() => { + // shouldn't happen, logged and caught inside cryptoWaitReady +}); diff --git a/packages/util-crypto/cjs/address/addressToEvm.d.ts b/packages/util-crypto/cjs/address/addressToEvm.d.ts new file mode 100644 index 0000000..5fb9903 --- /dev/null +++ b/packages/util-crypto/cjs/address/addressToEvm.d.ts @@ -0,0 +1,5 @@ +/** + * @name addressToEvm + * @summary Converts an SS58 address to its corresponding EVM address. + */ +export declare function addressToEvm(address: string | Uint8Array, ignoreChecksum?: boolean): Uint8Array; diff --git a/packages/util-crypto/cjs/address/addressToEvm.js b/packages/util-crypto/cjs/address/addressToEvm.js new file mode 100644 index 0000000..01c58ea --- /dev/null +++ b/packages/util-crypto/cjs/address/addressToEvm.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.addressToEvm = addressToEvm; +const decode_js_1 = require("./decode.js"); +/** + * @name addressToEvm + * @summary Converts an SS58 address to its corresponding EVM address. + */ +function addressToEvm(address, ignoreChecksum) { + return (0, decode_js_1.decodeAddress)(address, ignoreChecksum).subarray(0, 20); +} diff --git a/packages/util-crypto/cjs/address/check.d.ts b/packages/util-crypto/cjs/address/check.d.ts new file mode 100644 index 0000000..1153144 --- /dev/null +++ b/packages/util-crypto/cjs/address/check.d.ts @@ -0,0 +1,8 @@ +import type { Prefix } from './types.js'; +/** + * @name checkAddress + * @summary Validates an ss58 address. + * @description + * From the provided input, validate that the address is a valid input. + */ +export declare function checkAddress(address: string, prefix: Prefix): [boolean, string | null]; diff --git a/packages/util-crypto/cjs/address/check.js b/packages/util-crypto/cjs/address/check.js new file mode 100644 index 0000000..ece113c --- /dev/null +++ b/packages/util-crypto/cjs/address/check.js @@ -0,0 +1,29 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.checkAddress = checkAddress; +const index_js_1 = require("../base58/index.js"); +const checksum_js_1 = require("./checksum.js"); +const defaults_js_1 = require("./defaults.js"); +/** + * @name checkAddress + * @summary Validates an ss58 address. + * @description + * From the provided input, validate that the address is a valid input. + */ +function checkAddress(address, prefix) { + let decoded; + try { + decoded = (0, index_js_1.base58Decode)(address); + } + catch (error) { + return [false, error.message]; + } + const [isValid, , , ss58Decoded] = (0, checksum_js_1.checkAddressChecksum)(decoded); + if (ss58Decoded !== prefix) { + return [false, `Prefix mismatch, expected ${prefix}, found ${ss58Decoded}`]; + } + else if (!defaults_js_1.defaults.allowedEncodedLengths.includes(decoded.length)) { + return [false, 'Invalid decoded address length']; + } + return [isValid, isValid ? null : 'Invalid decoded address checksum']; +} diff --git a/packages/util-crypto/cjs/address/checksum.d.ts b/packages/util-crypto/cjs/address/checksum.d.ts new file mode 100644 index 0000000..1f39be6 --- /dev/null +++ b/packages/util-crypto/cjs/address/checksum.d.ts @@ -0,0 +1 @@ +export declare function checkAddressChecksum(decoded: Uint8Array): [boolean, number, number, number]; diff --git a/packages/util-crypto/cjs/address/checksum.js b/packages/util-crypto/cjs/address/checksum.js new file mode 100644 index 0000000..f27bd5b --- /dev/null +++ b/packages/util-crypto/cjs/address/checksum.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.checkAddressChecksum = checkAddressChecksum; +const sshash_js_1 = require("./sshash.js"); +function checkAddressChecksum(decoded) { + const ss58Length = (decoded[0] & 0b0100_0000) ? 2 : 1; + const ss58Decoded = ss58Length === 1 + ? decoded[0] + : ((decoded[0] & 0b0011_1111) << 2) | (decoded[1] >> 6) | ((decoded[1] & 0b0011_1111) << 8); + // 32/33 bytes public + 2 bytes checksum + prefix + const isPublicKey = [34 + ss58Length, 35 + ss58Length].includes(decoded.length); + const length = decoded.length - (isPublicKey ? 2 : 1); + // calculate the hash and do the checksum byte checks + const hash = (0, sshash_js_1.sshash)(decoded.subarray(0, length)); + const isValid = (decoded[0] & 0b1000_0000) === 0 && ![46, 47].includes(decoded[0]) && (isPublicKey + ? decoded[decoded.length - 2] === hash[0] && decoded[decoded.length - 1] === hash[1] + : decoded[decoded.length - 1] === hash[0]); + return [isValid, length, ss58Length, ss58Decoded]; +} diff --git a/packages/util-crypto/cjs/address/decode.d.ts b/packages/util-crypto/cjs/address/decode.d.ts new file mode 100644 index 0000000..937dbd4 --- /dev/null +++ b/packages/util-crypto/cjs/address/decode.d.ts @@ -0,0 +1,2 @@ +import type { Prefix } from './types.js'; +export declare function decodeAddress(encoded?: string | Uint8Array | null, ignoreChecksum?: boolean, ss58Format?: Prefix): Uint8Array; diff --git a/packages/util-crypto/cjs/address/decode.js b/packages/util-crypto/cjs/address/decode.js new file mode 100644 index 0000000..da06098 --- /dev/null +++ b/packages/util-crypto/cjs/address/decode.js @@ -0,0 +1,32 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.decodeAddress = decodeAddress; +const util_1 = require("@pezkuwi/util"); +const index_js_1 = require("../base58/index.js"); +const checksum_js_1 = require("./checksum.js"); +const defaults_js_1 = require("./defaults.js"); +function decodeAddress(encoded, ignoreChecksum, ss58Format = -1) { + if (!encoded) { + throw new Error('Invalid empty address passed'); + } + if ((0, util_1.isU8a)(encoded) || (0, util_1.isHex)(encoded)) { + return (0, util_1.u8aToU8a)(encoded); + } + try { + const decoded = (0, index_js_1.base58Decode)(encoded); + if (!defaults_js_1.defaults.allowedEncodedLengths.includes(decoded.length)) { + throw new Error('Invalid decoded address length'); + } + const [isValid, endPos, ss58Length, ss58Decoded] = (0, checksum_js_1.checkAddressChecksum)(decoded); + if (!isValid && !ignoreChecksum) { + throw new Error('Invalid decoded address checksum'); + } + else if (ss58Format !== -1 && ss58Format !== ss58Decoded) { + throw new Error(`Expected ss58Format ${ss58Format}, received ${ss58Decoded}`); + } + return decoded.slice(ss58Length, endPos); + } + catch (error) { + throw new Error(`Decoding ${encoded}: ${error.message}`); + } +} diff --git a/packages/util-crypto/cjs/address/defaults.d.ts b/packages/util-crypto/cjs/address/defaults.d.ts new file mode 100644 index 0000000..658612d --- /dev/null +++ b/packages/util-crypto/cjs/address/defaults.d.ts @@ -0,0 +1,6 @@ +export declare const defaults: { + allowedDecodedLengths: number[]; + allowedEncodedLengths: number[]; + allowedPrefix: number[]; + prefix: number; +}; diff --git a/packages/util-crypto/cjs/address/defaults.js b/packages/util-crypto/cjs/address/defaults.js new file mode 100644 index 0000000..d32937b --- /dev/null +++ b/packages/util-crypto/cjs/address/defaults.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.defaults = void 0; +const networks_js_1 = require("../networks.js"); +exports.defaults = { + allowedDecodedLengths: [1, 2, 4, 8, 32, 33], + // publicKey has prefix + 2 checksum bytes, short only prefix + 1 checksum byte + allowedEncodedLengths: [3, 4, 6, 10, 35, 36, 37, 38], + allowedPrefix: networks_js_1.availableNetworks.map(({ prefix }) => prefix), + prefix: 42 +}; diff --git a/packages/util-crypto/cjs/address/derive.d.ts b/packages/util-crypto/cjs/address/derive.d.ts new file mode 100644 index 0000000..16718d7 --- /dev/null +++ b/packages/util-crypto/cjs/address/derive.d.ts @@ -0,0 +1,8 @@ +import type { Prefix } from './types.js'; +/** + * @name deriveAddress + * @summary Creates a sr25519 derived address from the supplied and path. + * @description + * Creates a sr25519 derived address based on the input address/publicKey and the uri supplied. + */ +export declare function deriveAddress(who: string | Uint8Array, suri: string, ss58Format?: Prefix): string; diff --git a/packages/util-crypto/cjs/address/derive.js b/packages/util-crypto/cjs/address/derive.js new file mode 100644 index 0000000..652c77c --- /dev/null +++ b/packages/util-crypto/cjs/address/derive.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.deriveAddress = deriveAddress; +const index_js_1 = require("../key/index.js"); +const index_js_2 = require("../sr25519/index.js"); +const decode_js_1 = require("./decode.js"); +const encode_js_1 = require("./encode.js"); +function filterHard({ isHard }) { + return isHard; +} +/** + * @name deriveAddress + * @summary Creates a sr25519 derived address from the supplied and path. + * @description + * Creates a sr25519 derived address based on the input address/publicKey and the uri supplied. + */ +function deriveAddress(who, suri, ss58Format) { + const { path } = (0, index_js_1.keyExtractPath)(suri); + if (!path.length || path.every(filterHard)) { + throw new Error('Expected suri to contain a combination of non-hard paths'); + } + let publicKey = (0, decode_js_1.decodeAddress)(who); + for (const { chainCode } of path) { + publicKey = (0, index_js_2.sr25519DerivePublic)(publicKey, chainCode); + } + return (0, encode_js_1.encodeAddress)(publicKey, ss58Format); +} diff --git a/packages/util-crypto/cjs/address/encode.d.ts b/packages/util-crypto/cjs/address/encode.d.ts new file mode 100644 index 0000000..788b2af --- /dev/null +++ b/packages/util-crypto/cjs/address/encode.d.ts @@ -0,0 +1,2 @@ +import type { Prefix } from './types.js'; +export declare function encodeAddress(key: string | Uint8Array, ss58Format?: Prefix): string; diff --git a/packages/util-crypto/cjs/address/encode.js b/packages/util-crypto/cjs/address/encode.js new file mode 100644 index 0000000..0d1e9af --- /dev/null +++ b/packages/util-crypto/cjs/address/encode.js @@ -0,0 +1,26 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.encodeAddress = encodeAddress; +const util_1 = require("@pezkuwi/util"); +const index_js_1 = require("../base58/index.js"); +const decode_js_1 = require("./decode.js"); +const defaults_js_1 = require("./defaults.js"); +const sshash_js_1 = require("./sshash.js"); +function encodeAddress(key, ss58Format = defaults_js_1.defaults.prefix) { + // decode it, this means we can re-encode an address + const u8a = (0, decode_js_1.decodeAddress)(key); + if ((ss58Format < 0) || (ss58Format > 16383 && !ss58Exceptions.includes(ss58Format)) || [46, 47].includes(ss58Format)) { + throw new Error('Out of range ss58Format specified'); + } + else if (!defaults_js_1.defaults.allowedDecodedLengths.includes(u8a.length)) { + throw new Error(`Expected a valid key to convert, with length ${defaults_js_1.defaults.allowedDecodedLengths.join(', ')}`); + } + const input = (0, util_1.u8aConcat)(ss58Format < 64 + ? [ss58Format] + : [ + ((ss58Format & 0b0000_0000_1111_1100) >> 2) | 0b0100_0000, + (ss58Format >> 8) | ((ss58Format & 0b0000_0000_0000_0011) << 6) + ], u8a); + return (0, index_js_1.base58Encode)((0, util_1.u8aConcat)(input, (0, sshash_js_1.sshash)(input).subarray(0, [32, 33].includes(u8a.length) ? 2 : 1))); +} +const ss58Exceptions = [29972]; diff --git a/packages/util-crypto/cjs/address/encodeDerived.d.ts b/packages/util-crypto/cjs/address/encodeDerived.d.ts new file mode 100644 index 0000000..46eea7e --- /dev/null +++ b/packages/util-crypto/cjs/address/encodeDerived.d.ts @@ -0,0 +1,9 @@ +import type { BN } from '@pezkuwi/util'; +import type { Prefix } from './types.js'; +/** + * @name encodeDerivedAddress + * @summary Creates a derived address as used in Substrate utility. + * @description + * Creates a Substrate derived address based on the input address/publicKey and the index supplied. + */ +export declare function encodeDerivedAddress(who: string | Uint8Array, index: bigint | BN | number, ss58Format?: Prefix): string; diff --git a/packages/util-crypto/cjs/address/encodeDerived.js b/packages/util-crypto/cjs/address/encodeDerived.js new file mode 100644 index 0000000..44c9894 --- /dev/null +++ b/packages/util-crypto/cjs/address/encodeDerived.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.encodeDerivedAddress = encodeDerivedAddress; +const decode_js_1 = require("./decode.js"); +const encode_js_1 = require("./encode.js"); +const keyDerived_js_1 = require("./keyDerived.js"); +/** + * @name encodeDerivedAddress + * @summary Creates a derived address as used in Substrate utility. + * @description + * Creates a Substrate derived address based on the input address/publicKey and the index supplied. + */ +function encodeDerivedAddress(who, index, ss58Format) { + return (0, encode_js_1.encodeAddress)((0, keyDerived_js_1.createKeyDerived)((0, decode_js_1.decodeAddress)(who), index), ss58Format); +} diff --git a/packages/util-crypto/cjs/address/encodeMulti.d.ts b/packages/util-crypto/cjs/address/encodeMulti.d.ts new file mode 100644 index 0000000..db67bd0 --- /dev/null +++ b/packages/util-crypto/cjs/address/encodeMulti.d.ts @@ -0,0 +1,9 @@ +import type { BN } from '@pezkuwi/util'; +import type { Prefix } from './types.js'; +/** + * @name encodeMultiAddress + * @summary Creates a multisig address. + * @description + * Creates a Substrate multisig address based on the input address and the required threshold. + */ +export declare function encodeMultiAddress(who: (string | Uint8Array)[], threshold: bigint | BN | number, ss58Format?: Prefix): string; diff --git a/packages/util-crypto/cjs/address/encodeMulti.js b/packages/util-crypto/cjs/address/encodeMulti.js new file mode 100644 index 0000000..aee6ac1 --- /dev/null +++ b/packages/util-crypto/cjs/address/encodeMulti.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.encodeMultiAddress = encodeMultiAddress; +const encode_js_1 = require("./encode.js"); +const keyMulti_js_1 = require("./keyMulti.js"); +/** + * @name encodeMultiAddress + * @summary Creates a multisig address. + * @description + * Creates a Substrate multisig address based on the input address and the required threshold. + */ +function encodeMultiAddress(who, threshold, ss58Format) { + return (0, encode_js_1.encodeAddress)((0, keyMulti_js_1.createKeyMulti)(who, threshold), ss58Format); +} diff --git a/packages/util-crypto/cjs/address/eq.d.ts b/packages/util-crypto/cjs/address/eq.d.ts new file mode 100644 index 0000000..880a2b7 --- /dev/null +++ b/packages/util-crypto/cjs/address/eq.d.ts @@ -0,0 +1,15 @@ +/** + * @name addressEq + * @summary Compares two addresses, either in ss58, Uint8Array or hex format. + * @description + * For the input values, return true is the underlying public keys do match. + * @example + *
+ * + * ```javascript + * import { u8aEq } from '@pezkuwi/util'; + * + * u8aEq(new Uint8Array([0x68, 0x65]), new Uint8Array([0x68, 0x65])); // true + * ``` + */ +export declare function addressEq(a: string | Uint8Array, b: string | Uint8Array): boolean; diff --git a/packages/util-crypto/cjs/address/eq.js b/packages/util-crypto/cjs/address/eq.js new file mode 100644 index 0000000..fcd2bb4 --- /dev/null +++ b/packages/util-crypto/cjs/address/eq.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.addressEq = addressEq; +const util_1 = require("@pezkuwi/util"); +const decode_js_1 = require("./decode.js"); +/** + * @name addressEq + * @summary Compares two addresses, either in ss58, Uint8Array or hex format. + * @description + * For the input values, return true is the underlying public keys do match. + * @example + *
+ * + * ```javascript + * import { u8aEq } from '@pezkuwi/util'; + * + * u8aEq(new Uint8Array([0x68, 0x65]), new Uint8Array([0x68, 0x65])); // true + * ``` + */ +function addressEq(a, b) { + return (0, util_1.u8aEq)((0, decode_js_1.decodeAddress)(a), (0, decode_js_1.decodeAddress)(b)); +} diff --git a/packages/util-crypto/cjs/address/evmToAddress.d.ts b/packages/util-crypto/cjs/address/evmToAddress.d.ts new file mode 100644 index 0000000..a19b85a --- /dev/null +++ b/packages/util-crypto/cjs/address/evmToAddress.d.ts @@ -0,0 +1,7 @@ +import type { HashType } from '../secp256k1/types.js'; +import type { Prefix } from './types.js'; +/** + * @name evmToAddress + * @summary Converts an EVM address to its corresponding SS58 address. + */ +export declare function evmToAddress(evmAddress: string | Uint8Array, ss58Format?: Prefix, hashType?: HashType): string; diff --git a/packages/util-crypto/cjs/address/evmToAddress.js b/packages/util-crypto/cjs/address/evmToAddress.js new file mode 100644 index 0000000..b6a9c8a --- /dev/null +++ b/packages/util-crypto/cjs/address/evmToAddress.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.evmToAddress = evmToAddress; +const util_1 = require("@pezkuwi/util"); +const hasher_js_1 = require("../secp256k1/hasher.js"); +const encode_js_1 = require("./encode.js"); +/** + * @name evmToAddress + * @summary Converts an EVM address to its corresponding SS58 address. + */ +function evmToAddress(evmAddress, ss58Format, hashType = 'blake2') { + const message = (0, util_1.u8aConcat)('evm:', evmAddress); + if (message.length !== 24) { + throw new Error(`Converting ${evmAddress}: Invalid evm address length`); + } + return (0, encode_js_1.encodeAddress)((0, hasher_js_1.hasher)(hashType, message), ss58Format); +} diff --git a/packages/util-crypto/cjs/address/index.d.ts b/packages/util-crypto/cjs/address/index.d.ts new file mode 100644 index 0000000..8ea135b --- /dev/null +++ b/packages/util-crypto/cjs/address/index.d.ts @@ -0,0 +1,16 @@ +export { addressToEvm } from './addressToEvm.js'; +export { checkAddress } from './check.js'; +export { checkAddressChecksum } from './checksum.js'; +export { decodeAddress } from './decode.js'; +export { deriveAddress } from './derive.js'; +export { encodeAddress } from './encode.js'; +export { encodeDerivedAddress } from './encodeDerived.js'; +export { encodeMultiAddress } from './encodeMulti.js'; +export { addressEq } from './eq.js'; +export { evmToAddress } from './evmToAddress.js'; +export { isAddress } from './is.js'; +export { createKeyDerived } from './keyDerived.js'; +export { createKeyMulti } from './keyMulti.js'; +export { sortAddresses } from './sort.js'; +export { validateAddress } from './validate.js'; +export { setSS58Format } from './setSS58Format.js'; diff --git a/packages/util-crypto/cjs/address/index.js b/packages/util-crypto/cjs/address/index.js new file mode 100644 index 0000000..ffa206f --- /dev/null +++ b/packages/util-crypto/cjs/address/index.js @@ -0,0 +1,35 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.setSS58Format = exports.validateAddress = exports.sortAddresses = exports.createKeyMulti = exports.createKeyDerived = exports.isAddress = exports.evmToAddress = exports.addressEq = exports.encodeMultiAddress = exports.encodeDerivedAddress = exports.encodeAddress = exports.deriveAddress = exports.decodeAddress = exports.checkAddressChecksum = exports.checkAddress = exports.addressToEvm = void 0; +var addressToEvm_js_1 = require("./addressToEvm.js"); +Object.defineProperty(exports, "addressToEvm", { enumerable: true, get: function () { return addressToEvm_js_1.addressToEvm; } }); +var check_js_1 = require("./check.js"); +Object.defineProperty(exports, "checkAddress", { enumerable: true, get: function () { return check_js_1.checkAddress; } }); +var checksum_js_1 = require("./checksum.js"); +Object.defineProperty(exports, "checkAddressChecksum", { enumerable: true, get: function () { return checksum_js_1.checkAddressChecksum; } }); +var decode_js_1 = require("./decode.js"); +Object.defineProperty(exports, "decodeAddress", { enumerable: true, get: function () { return decode_js_1.decodeAddress; } }); +var derive_js_1 = require("./derive.js"); +Object.defineProperty(exports, "deriveAddress", { enumerable: true, get: function () { return derive_js_1.deriveAddress; } }); +var encode_js_1 = require("./encode.js"); +Object.defineProperty(exports, "encodeAddress", { enumerable: true, get: function () { return encode_js_1.encodeAddress; } }); +var encodeDerived_js_1 = require("./encodeDerived.js"); +Object.defineProperty(exports, "encodeDerivedAddress", { enumerable: true, get: function () { return encodeDerived_js_1.encodeDerivedAddress; } }); +var encodeMulti_js_1 = require("./encodeMulti.js"); +Object.defineProperty(exports, "encodeMultiAddress", { enumerable: true, get: function () { return encodeMulti_js_1.encodeMultiAddress; } }); +var eq_js_1 = require("./eq.js"); +Object.defineProperty(exports, "addressEq", { enumerable: true, get: function () { return eq_js_1.addressEq; } }); +var evmToAddress_js_1 = require("./evmToAddress.js"); +Object.defineProperty(exports, "evmToAddress", { enumerable: true, get: function () { return evmToAddress_js_1.evmToAddress; } }); +var is_js_1 = require("./is.js"); +Object.defineProperty(exports, "isAddress", { enumerable: true, get: function () { return is_js_1.isAddress; } }); +var keyDerived_js_1 = require("./keyDerived.js"); +Object.defineProperty(exports, "createKeyDerived", { enumerable: true, get: function () { return keyDerived_js_1.createKeyDerived; } }); +var keyMulti_js_1 = require("./keyMulti.js"); +Object.defineProperty(exports, "createKeyMulti", { enumerable: true, get: function () { return keyMulti_js_1.createKeyMulti; } }); +var sort_js_1 = require("./sort.js"); +Object.defineProperty(exports, "sortAddresses", { enumerable: true, get: function () { return sort_js_1.sortAddresses; } }); +var validate_js_1 = require("./validate.js"); +Object.defineProperty(exports, "validateAddress", { enumerable: true, get: function () { return validate_js_1.validateAddress; } }); +var setSS58Format_js_1 = require("./setSS58Format.js"); +Object.defineProperty(exports, "setSS58Format", { enumerable: true, get: function () { return setSS58Format_js_1.setSS58Format; } }); diff --git a/packages/util-crypto/cjs/address/is.d.ts b/packages/util-crypto/cjs/address/is.d.ts new file mode 100644 index 0000000..f67866a --- /dev/null +++ b/packages/util-crypto/cjs/address/is.d.ts @@ -0,0 +1,2 @@ +import type { Prefix } from './types.js'; +export declare function isAddress(address?: string | null, ignoreChecksum?: boolean, ss58Format?: Prefix): address is string; diff --git a/packages/util-crypto/cjs/address/is.js b/packages/util-crypto/cjs/address/is.js new file mode 100644 index 0000000..18f8476 --- /dev/null +++ b/packages/util-crypto/cjs/address/is.js @@ -0,0 +1,12 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isAddress = isAddress; +const validate_js_1 = require("./validate.js"); +function isAddress(address, ignoreChecksum, ss58Format) { + try { + return (0, validate_js_1.validateAddress)(address, ignoreChecksum, ss58Format); + } + catch { + return false; + } +} diff --git a/packages/util-crypto/cjs/address/keyDerived.d.ts b/packages/util-crypto/cjs/address/keyDerived.d.ts new file mode 100644 index 0000000..bfd0b69 --- /dev/null +++ b/packages/util-crypto/cjs/address/keyDerived.d.ts @@ -0,0 +1,2 @@ +import type { BN } from '@pezkuwi/util'; +export declare function createKeyDerived(who: string | Uint8Array, index: bigint | BN | number): Uint8Array; diff --git a/packages/util-crypto/cjs/address/keyDerived.js b/packages/util-crypto/cjs/address/keyDerived.js new file mode 100644 index 0000000..4531410 --- /dev/null +++ b/packages/util-crypto/cjs/address/keyDerived.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createKeyDerived = createKeyDerived; +const util_1 = require("@pezkuwi/util"); +const asU8a_js_1 = require("../blake2/asU8a.js"); +const bn_js_1 = require("../bn.js"); +const decode_js_1 = require("./decode.js"); +const PREFIX = (0, util_1.stringToU8a)('modlpy/utilisuba'); +function createKeyDerived(who, index) { + return (0, asU8a_js_1.blake2AsU8a)((0, util_1.u8aConcat)(PREFIX, (0, decode_js_1.decodeAddress)(who), (0, util_1.bnToU8a)(index, bn_js_1.BN_LE_16_OPTS))); +} diff --git a/packages/util-crypto/cjs/address/keyMulti.d.ts b/packages/util-crypto/cjs/address/keyMulti.d.ts new file mode 100644 index 0000000..ce3e622 --- /dev/null +++ b/packages/util-crypto/cjs/address/keyMulti.d.ts @@ -0,0 +1,2 @@ +import type { BN } from '@pezkuwi/util'; +export declare function createKeyMulti(who: (string | Uint8Array)[], threshold: bigint | BN | number): Uint8Array; diff --git a/packages/util-crypto/cjs/address/keyMulti.js b/packages/util-crypto/cjs/address/keyMulti.js new file mode 100644 index 0000000..319d74f --- /dev/null +++ b/packages/util-crypto/cjs/address/keyMulti.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createKeyMulti = createKeyMulti; +const util_1 = require("@pezkuwi/util"); +const asU8a_js_1 = require("../blake2/asU8a.js"); +const bn_js_1 = require("../bn.js"); +const util_js_1 = require("./util.js"); +const PREFIX = (0, util_1.stringToU8a)('modlpy/utilisuba'); +function createKeyMulti(who, threshold) { + return (0, asU8a_js_1.blake2AsU8a)((0, util_1.u8aConcat)(PREFIX, (0, util_1.compactToU8a)(who.length), ...(0, util_1.u8aSorted)(who.map(util_js_1.addressToU8a)), (0, util_1.bnToU8a)(threshold, bn_js_1.BN_LE_16_OPTS))); +} diff --git a/packages/util-crypto/cjs/address/setSS58Format.d.ts b/packages/util-crypto/cjs/address/setSS58Format.d.ts new file mode 100644 index 0000000..59374fb --- /dev/null +++ b/packages/util-crypto/cjs/address/setSS58Format.d.ts @@ -0,0 +1,6 @@ +import type { Prefix } from './types.js'; +/** + * @description Sets the global SS58 format to use for address encoding + * @deprecated Use keyring.setSS58Format + */ +export declare function setSS58Format(prefix: Prefix): void; diff --git a/packages/util-crypto/cjs/address/setSS58Format.js b/packages/util-crypto/cjs/address/setSS58Format.js new file mode 100644 index 0000000..1cd3020 --- /dev/null +++ b/packages/util-crypto/cjs/address/setSS58Format.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.setSS58Format = setSS58Format; +const util_1 = require("@pezkuwi/util"); +const defaults_js_1 = require("./defaults.js"); +const l = (0, util_1.logger)('setSS58Format'); +/** + * @description Sets the global SS58 format to use for address encoding + * @deprecated Use keyring.setSS58Format + */ +function setSS58Format(prefix) { + l.warn('Global setting of the ss58Format is deprecated and not recommended. Set format on the keyring (if used) or as part of the address encode function'); + defaults_js_1.defaults.prefix = prefix; +} diff --git a/packages/util-crypto/cjs/address/sort.d.ts b/packages/util-crypto/cjs/address/sort.d.ts new file mode 100644 index 0000000..a4727c5 --- /dev/null +++ b/packages/util-crypto/cjs/address/sort.d.ts @@ -0,0 +1,2 @@ +import type { Prefix } from './types.js'; +export declare function sortAddresses(addresses: (string | Uint8Array)[], ss58Format?: Prefix): string[]; diff --git a/packages/util-crypto/cjs/address/sort.js b/packages/util-crypto/cjs/address/sort.js new file mode 100644 index 0000000..58d3077 --- /dev/null +++ b/packages/util-crypto/cjs/address/sort.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sortAddresses = sortAddresses; +const util_1 = require("@pezkuwi/util"); +const encode_js_1 = require("./encode.js"); +const util_js_1 = require("./util.js"); +function sortAddresses(addresses, ss58Format) { + const u8aToAddress = (u8a) => (0, encode_js_1.encodeAddress)(u8a, ss58Format); + return (0, util_1.u8aSorted)(addresses.map(util_js_1.addressToU8a)).map(u8aToAddress); +} diff --git a/packages/util-crypto/cjs/address/sshash.d.ts b/packages/util-crypto/cjs/address/sshash.d.ts new file mode 100644 index 0000000..e206a15 --- /dev/null +++ b/packages/util-crypto/cjs/address/sshash.d.ts @@ -0,0 +1 @@ +export declare function sshash(key: Uint8Array): Uint8Array; diff --git a/packages/util-crypto/cjs/address/sshash.js b/packages/util-crypto/cjs/address/sshash.js new file mode 100644 index 0000000..1305993 --- /dev/null +++ b/packages/util-crypto/cjs/address/sshash.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sshash = sshash; +const util_1 = require("@pezkuwi/util"); +const asU8a_js_1 = require("../blake2/asU8a.js"); +const SS58_PREFIX = (0, util_1.stringToU8a)('SS58PRE'); +function sshash(key) { + return (0, asU8a_js_1.blake2AsU8a)((0, util_1.u8aConcat)(SS58_PREFIX, key), 512); +} diff --git a/packages/util-crypto/cjs/address/types.d.ts b/packages/util-crypto/cjs/address/types.d.ts new file mode 100644 index 0000000..6763033 --- /dev/null +++ b/packages/util-crypto/cjs/address/types.d.ts @@ -0,0 +1 @@ +export type Prefix = number; diff --git a/packages/util-crypto/cjs/address/types.js b/packages/util-crypto/cjs/address/types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/packages/util-crypto/cjs/address/types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/packages/util-crypto/cjs/address/util.d.ts b/packages/util-crypto/cjs/address/util.d.ts new file mode 100644 index 0000000..fb3e6d4 --- /dev/null +++ b/packages/util-crypto/cjs/address/util.d.ts @@ -0,0 +1 @@ +export declare function addressToU8a(who: string | Uint8Array): Uint8Array; diff --git a/packages/util-crypto/cjs/address/util.js b/packages/util-crypto/cjs/address/util.js new file mode 100644 index 0000000..982dec3 --- /dev/null +++ b/packages/util-crypto/cjs/address/util.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.addressToU8a = addressToU8a; +const decode_js_1 = require("./decode.js"); +function addressToU8a(who) { + return (0, decode_js_1.decodeAddress)(who); +} diff --git a/packages/util-crypto/cjs/address/validate.d.ts b/packages/util-crypto/cjs/address/validate.d.ts new file mode 100644 index 0000000..dd9d08c --- /dev/null +++ b/packages/util-crypto/cjs/address/validate.d.ts @@ -0,0 +1,2 @@ +import type { Prefix } from './types.js'; +export declare function validateAddress(encoded?: string | null, ignoreChecksum?: boolean, ss58Format?: Prefix): encoded is string; diff --git a/packages/util-crypto/cjs/address/validate.js b/packages/util-crypto/cjs/address/validate.js new file mode 100644 index 0000000..7863fbf --- /dev/null +++ b/packages/util-crypto/cjs/address/validate.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.validateAddress = validateAddress; +const decode_js_1 = require("./decode.js"); +function validateAddress(encoded, ignoreChecksum, ss58Format) { + return !!(0, decode_js_1.decodeAddress)(encoded, ignoreChecksum, ss58Format); +} diff --git a/packages/util-crypto/cjs/base32/bs32.d.ts b/packages/util-crypto/cjs/base32/bs32.d.ts new file mode 100644 index 0000000..663a6ab --- /dev/null +++ b/packages/util-crypto/cjs/base32/bs32.d.ts @@ -0,0 +1,26 @@ +/** + * @name base32Validate + * @summary Validates a base32 value. + * @description + * Validates that the supplied value is valid base32, throwing exceptions if not + */ +export declare const base32Validate: (value?: unknown, ipfsCompat?: boolean) => value is string; +/** +* @name isBase32 +* @description Checks if the input is in base32, returning true/false +*/ +export declare const isBase32: (value?: unknown, ipfsCompat?: boolean) => value is string; +/** + * @name base32Decode + * @summary Delookup a base32 value. + * @description + * From the provided input, decode the base32 and return the result as an `Uint8Array`. + */ +export declare const base32Decode: (value: string, ipfsCompat?: boolean) => Uint8Array; +/** +* @name base32Encode +* @summary Creates a base32 value. +* @description +* From the provided input, create the base32 and return the result as a string. +*/ +export declare const base32Encode: (value: import("@pezkuwi/util/types").U8aLike, ipfsCompat?: boolean) => string; diff --git a/packages/util-crypto/cjs/base32/bs32.js b/packages/util-crypto/cjs/base32/bs32.js new file mode 100644 index 0000000..d51b6dc --- /dev/null +++ b/packages/util-crypto/cjs/base32/bs32.js @@ -0,0 +1,43 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.base32Encode = exports.base32Decode = exports.isBase32 = exports.base32Validate = void 0; +const base_1 = require("@scure/base"); +const helpers_js_1 = require("./helpers.js"); +const chars = 'abcdefghijklmnopqrstuvwxyz234567'; +const config = { + chars, + coder: base_1.utils.chain( + // We define our own chain, the default base32 has padding + base_1.utils.radix2(5), base_1.utils.alphabet(chars), { + decode: (input) => input.split(''), + encode: (input) => input.join('') + }), + ipfs: 'b', + type: 'base32' +}; +/** + * @name base32Validate + * @summary Validates a base32 value. + * @description + * Validates that the supplied value is valid base32, throwing exceptions if not + */ +exports.base32Validate = (0, helpers_js_1.createValidate)(config); +/** +* @name isBase32 +* @description Checks if the input is in base32, returning true/false +*/ +exports.isBase32 = (0, helpers_js_1.createIs)(exports.base32Validate); +/** + * @name base32Decode + * @summary Delookup a base32 value. + * @description + * From the provided input, decode the base32 and return the result as an `Uint8Array`. + */ +exports.base32Decode = (0, helpers_js_1.createDecode)(config, exports.base32Validate); +/** +* @name base32Encode +* @summary Creates a base32 value. +* @description +* From the provided input, create the base32 and return the result as a string. +*/ +exports.base32Encode = (0, helpers_js_1.createEncode)(config); diff --git a/packages/util-crypto/cjs/base32/helpers.d.ts b/packages/util-crypto/cjs/base32/helpers.d.ts new file mode 100644 index 0000000..c33650a --- /dev/null +++ b/packages/util-crypto/cjs/base32/helpers.d.ts @@ -0,0 +1,25 @@ +import type { U8aLike } from '@pezkuwi/util/types'; +export type { U8aLike } from '@pezkuwi/util/types'; +interface Coder { + decode: (value: string) => Uint8Array; + encode: (value: Uint8Array) => string; +} +interface Config { + chars: string; + coder: Coder; + ipfs?: string; + regex?: RegExp; + type: string; + withPadding?: boolean; +} +type DecodeFn = (value: string, ipfsCompat?: boolean) => Uint8Array; +type EncodeFn = (value: U8aLike, ipfsCompat?: boolean) => string; +type ValidateFn = (value?: unknown, ipfsCompat?: boolean) => value is string; +/** @internal */ +export declare function createDecode({ coder, ipfs }: Config, validate: ValidateFn): DecodeFn; +/** @internal */ +export declare function createEncode({ coder, ipfs }: Config): EncodeFn; +/** @internal */ +export declare function createIs(validate: ValidateFn): ValidateFn; +/** @internal */ +export declare function createValidate({ chars, ipfs, type, withPadding }: Config): ValidateFn; diff --git a/packages/util-crypto/cjs/base32/helpers.js b/packages/util-crypto/cjs/base32/helpers.js new file mode 100644 index 0000000..a6883c9 --- /dev/null +++ b/packages/util-crypto/cjs/base32/helpers.js @@ -0,0 +1,67 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createDecode = createDecode; +exports.createEncode = createEncode; +exports.createIs = createIs; +exports.createValidate = createValidate; +const util_1 = require("@pezkuwi/util"); +/** @internal */ +function createDecode({ coder, ipfs }, validate) { + return (value, ipfsCompat) => { + validate(value, ipfsCompat); + return coder.decode(ipfs && ipfsCompat + ? value.substring(1) + : value); + }; +} +/** @internal */ +function createEncode({ coder, ipfs }) { + return (value, ipfsCompat) => { + const out = coder.encode((0, util_1.u8aToU8a)(value)); + return ipfs && ipfsCompat + ? `${ipfs}${out}` + : out; + }; +} +/** @internal */ +function createIs(validate) { + return (value, ipfsCompat) => { + try { + return validate(value, ipfsCompat); + } + catch { + return false; + } + }; +} +/** @internal */ +function createValidate({ chars, ipfs, type, withPadding }) { + return (value, ipfsCompat) => { + if (typeof value !== 'string') { + throw new Error(`Expected ${type} string input`); + } + else if (ipfs && ipfsCompat && !value.startsWith(ipfs)) { + throw new Error(`Expected ipfs-compatible ${type} to start with '${ipfs}'`); + } + for (let i = (ipfsCompat ? 1 : 0), count = value.length; i < count; i++) { + if (chars.includes(value[i])) { + // all ok, character found + } + else if (withPadding && value[i] === '=') { + if (i === count - 1) { + // last character, everything ok + } + else if (value[i + 1] === '=') { + // next one is also padding, sequence ok + } + else { + throw new Error(`Invalid ${type} padding sequence "${value[i]}${value[i + 1]}" at index ${i}`); + } + } + else { + throw new Error(`Invalid ${type} character "${value[i]}" (0x${value.charCodeAt(i).toString(16)}) at index ${i}`); + } + } + return true; + }; +} diff --git a/packages/util-crypto/cjs/base32/index.d.ts b/packages/util-crypto/cjs/base32/index.d.ts new file mode 100644 index 0000000..05f41ce --- /dev/null +++ b/packages/util-crypto/cjs/base32/index.d.ts @@ -0,0 +1,4 @@ +/** + * @summary Encode and decode base32 values + */ +export { base32Decode, base32Encode, base32Validate, isBase32 } from './bs32.js'; diff --git a/packages/util-crypto/cjs/base32/index.js b/packages/util-crypto/cjs/base32/index.js new file mode 100644 index 0000000..b2f71fe --- /dev/null +++ b/packages/util-crypto/cjs/base32/index.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isBase32 = exports.base32Validate = exports.base32Encode = exports.base32Decode = void 0; +/** + * @summary Encode and decode base32 values + */ +var bs32_js_1 = require("./bs32.js"); +Object.defineProperty(exports, "base32Decode", { enumerable: true, get: function () { return bs32_js_1.base32Decode; } }); +Object.defineProperty(exports, "base32Encode", { enumerable: true, get: function () { return bs32_js_1.base32Encode; } }); +Object.defineProperty(exports, "base32Validate", { enumerable: true, get: function () { return bs32_js_1.base32Validate; } }); +Object.defineProperty(exports, "isBase32", { enumerable: true, get: function () { return bs32_js_1.isBase32; } }); diff --git a/packages/util-crypto/cjs/base58/bs58.d.ts b/packages/util-crypto/cjs/base58/bs58.d.ts new file mode 100644 index 0000000..362e7b3 --- /dev/null +++ b/packages/util-crypto/cjs/base58/bs58.d.ts @@ -0,0 +1,26 @@ +/** + * @name base58Validate + * @summary Validates a base58 value. + * @description + * Validates that the supplied value is valid base58, throwing exceptions if not + */ +export declare const base58Validate: (value?: unknown, ipfsCompat?: boolean) => value is string; +/** + * @name base58Decode + * @summary Decodes a base58 value. + * @description + * From the provided input, decode the base58 and return the result as an `Uint8Array`. + */ +export declare const base58Decode: (value: string, ipfsCompat?: boolean) => Uint8Array; +/** +* @name base58Encode +* @summary Creates a base58 value. +* @description +* From the provided input, create the base58 and return the result as a string. +*/ +export declare const base58Encode: (value: import("@pezkuwi/util/types").U8aLike, ipfsCompat?: boolean) => string; +/** +* @name isBase58 +* @description Checks if the input is in base58, returning true/false +*/ +export declare const isBase58: (value?: unknown, ipfsCompat?: boolean) => value is string; diff --git a/packages/util-crypto/cjs/base58/bs58.js b/packages/util-crypto/cjs/base58/bs58.js new file mode 100644 index 0000000..11eed9d --- /dev/null +++ b/packages/util-crypto/cjs/base58/bs58.js @@ -0,0 +1,37 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isBase58 = exports.base58Encode = exports.base58Decode = exports.base58Validate = void 0; +const base_1 = require("@scure/base"); +const helpers_js_1 = require("../base32/helpers.js"); +const config = { + chars: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz', + coder: base_1.base58, + ipfs: 'z', + type: 'base58' +}; +/** + * @name base58Validate + * @summary Validates a base58 value. + * @description + * Validates that the supplied value is valid base58, throwing exceptions if not + */ +exports.base58Validate = (0, helpers_js_1.createValidate)(config); +/** + * @name base58Decode + * @summary Decodes a base58 value. + * @description + * From the provided input, decode the base58 and return the result as an `Uint8Array`. + */ +exports.base58Decode = (0, helpers_js_1.createDecode)(config, exports.base58Validate); +/** +* @name base58Encode +* @summary Creates a base58 value. +* @description +* From the provided input, create the base58 and return the result as a string. +*/ +exports.base58Encode = (0, helpers_js_1.createEncode)(config); +/** +* @name isBase58 +* @description Checks if the input is in base58, returning true/false +*/ +exports.isBase58 = (0, helpers_js_1.createIs)(exports.base58Validate); diff --git a/packages/util-crypto/cjs/base58/index.d.ts b/packages/util-crypto/cjs/base58/index.d.ts new file mode 100644 index 0000000..ae26513 --- /dev/null +++ b/packages/util-crypto/cjs/base58/index.d.ts @@ -0,0 +1,4 @@ +/** + * @summary Encode and decode base58 values + */ +export { base58Decode, base58Encode, base58Validate, isBase58 } from './bs58.js'; diff --git a/packages/util-crypto/cjs/base58/index.js b/packages/util-crypto/cjs/base58/index.js new file mode 100644 index 0000000..4247033 --- /dev/null +++ b/packages/util-crypto/cjs/base58/index.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isBase58 = exports.base58Validate = exports.base58Encode = exports.base58Decode = void 0; +/** + * @summary Encode and decode base58 values + */ +var bs58_js_1 = require("./bs58.js"); +Object.defineProperty(exports, "base58Decode", { enumerable: true, get: function () { return bs58_js_1.base58Decode; } }); +Object.defineProperty(exports, "base58Encode", { enumerable: true, get: function () { return bs58_js_1.base58Encode; } }); +Object.defineProperty(exports, "base58Validate", { enumerable: true, get: function () { return bs58_js_1.base58Validate; } }); +Object.defineProperty(exports, "isBase58", { enumerable: true, get: function () { return bs58_js_1.isBase58; } }); diff --git a/packages/util-crypto/cjs/base64/bs64.d.ts b/packages/util-crypto/cjs/base64/bs64.d.ts new file mode 100644 index 0000000..0027129 --- /dev/null +++ b/packages/util-crypto/cjs/base64/bs64.d.ts @@ -0,0 +1,26 @@ +/** + * @name base64Validate + * @summary Validates a base64 value. + * @description + * Validates that the supplied value is valid base64 + */ +export declare const base64Validate: (value?: unknown, ipfsCompat?: boolean) => value is string; +/** + * @name isBase64 + * @description Checks if the input is in base64, returning true/false + */ +export declare const isBase64: (value?: unknown, ipfsCompat?: boolean) => value is string; +/** + * @name base64Decode + * @summary Decodes a base64 value. + * @description + * From the provided input, decode the base64 and return the result as an `Uint8Array`. + */ +export declare const base64Decode: (value: string, ipfsCompat?: boolean) => Uint8Array; +/** + * @name base64Encode + * @summary Creates a base64 value. + * @description + * From the provided input, create the base64 and return the result as a string. + */ +export declare const base64Encode: (value: import("@pezkuwi/util/types").U8aLike, ipfsCompat?: boolean) => string; diff --git a/packages/util-crypto/cjs/base64/bs64.js b/packages/util-crypto/cjs/base64/bs64.js new file mode 100644 index 0000000..b0c3c3a --- /dev/null +++ b/packages/util-crypto/cjs/base64/bs64.js @@ -0,0 +1,37 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.base64Encode = exports.base64Decode = exports.isBase64 = exports.base64Validate = void 0; +const base_1 = require("@scure/base"); +const helpers_js_1 = require("../base32/helpers.js"); +const config = { + chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', + coder: base_1.base64, + type: 'base64', + withPadding: true +}; +/** + * @name base64Validate + * @summary Validates a base64 value. + * @description + * Validates that the supplied value is valid base64 + */ +exports.base64Validate = (0, helpers_js_1.createValidate)(config); +/** + * @name isBase64 + * @description Checks if the input is in base64, returning true/false + */ +exports.isBase64 = (0, helpers_js_1.createIs)(exports.base64Validate); +/** + * @name base64Decode + * @summary Decodes a base64 value. + * @description + * From the provided input, decode the base64 and return the result as an `Uint8Array`. + */ +exports.base64Decode = (0, helpers_js_1.createDecode)(config, exports.base64Validate); +/** + * @name base64Encode + * @summary Creates a base64 value. + * @description + * From the provided input, create the base64 and return the result as a string. + */ +exports.base64Encode = (0, helpers_js_1.createEncode)(config); diff --git a/packages/util-crypto/cjs/base64/index.d.ts b/packages/util-crypto/cjs/base64/index.d.ts new file mode 100644 index 0000000..ec9b279 --- /dev/null +++ b/packages/util-crypto/cjs/base64/index.d.ts @@ -0,0 +1,6 @@ +/** + * @summary Encode and decode base64 values + */ +export { base64Decode, base64Encode, base64Validate, isBase64 } from './bs64.js'; +export { base64Pad } from './pad.js'; +export { base64Trim } from './trim.js'; diff --git a/packages/util-crypto/cjs/base64/index.js b/packages/util-crypto/cjs/base64/index.js new file mode 100644 index 0000000..65a7e2a --- /dev/null +++ b/packages/util-crypto/cjs/base64/index.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.base64Trim = exports.base64Pad = exports.isBase64 = exports.base64Validate = exports.base64Encode = exports.base64Decode = void 0; +/** + * @summary Encode and decode base64 values + */ +var bs64_js_1 = require("./bs64.js"); +Object.defineProperty(exports, "base64Decode", { enumerable: true, get: function () { return bs64_js_1.base64Decode; } }); +Object.defineProperty(exports, "base64Encode", { enumerable: true, get: function () { return bs64_js_1.base64Encode; } }); +Object.defineProperty(exports, "base64Validate", { enumerable: true, get: function () { return bs64_js_1.base64Validate; } }); +Object.defineProperty(exports, "isBase64", { enumerable: true, get: function () { return bs64_js_1.isBase64; } }); +var pad_js_1 = require("./pad.js"); +Object.defineProperty(exports, "base64Pad", { enumerable: true, get: function () { return pad_js_1.base64Pad; } }); +var trim_js_1 = require("./trim.js"); +Object.defineProperty(exports, "base64Trim", { enumerable: true, get: function () { return trim_js_1.base64Trim; } }); diff --git a/packages/util-crypto/cjs/base64/pad.d.ts b/packages/util-crypto/cjs/base64/pad.d.ts new file mode 100644 index 0000000..90764f2 --- /dev/null +++ b/packages/util-crypto/cjs/base64/pad.d.ts @@ -0,0 +1,5 @@ +/** + * @name base64Pad + * @description Adds padding characters for correct length + */ +export declare function base64Pad(value: string): string; diff --git a/packages/util-crypto/cjs/base64/pad.js b/packages/util-crypto/cjs/base64/pad.js new file mode 100644 index 0000000..21a7c16 --- /dev/null +++ b/packages/util-crypto/cjs/base64/pad.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.base64Pad = base64Pad; +/** + * @name base64Pad + * @description Adds padding characters for correct length + */ +function base64Pad(value) { + return value.padEnd(value.length + (value.length % 4), '='); +} diff --git a/packages/util-crypto/cjs/base64/trim.d.ts b/packages/util-crypto/cjs/base64/trim.d.ts new file mode 100644 index 0000000..4daf3e9 --- /dev/null +++ b/packages/util-crypto/cjs/base64/trim.d.ts @@ -0,0 +1,5 @@ +/** + * @name base64Trim + * @description Trims padding characters + */ +export declare function base64Trim(value: string): string; diff --git a/packages/util-crypto/cjs/base64/trim.js b/packages/util-crypto/cjs/base64/trim.js new file mode 100644 index 0000000..ecc2233 --- /dev/null +++ b/packages/util-crypto/cjs/base64/trim.js @@ -0,0 +1,13 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.base64Trim = base64Trim; +/** + * @name base64Trim + * @description Trims padding characters + */ +function base64Trim(value) { + while (value.length && value.endsWith('=')) { + value = value.slice(0, -1); + } + return value; +} diff --git a/packages/util-crypto/cjs/blake2/asU8a.d.ts b/packages/util-crypto/cjs/blake2/asU8a.d.ts new file mode 100644 index 0000000..1da59c5 --- /dev/null +++ b/packages/util-crypto/cjs/blake2/asU8a.d.ts @@ -0,0 +1,20 @@ +/** + * @name blake2AsU8a + * @summary Creates a blake2b u8a from the input. + * @description + * From a `Uint8Array` input, create the blake2b and return the result as a u8a with the specified `bitLength`. + * @example + *
+ * + * ```javascript + * import { blake2AsU8a } from '@pezkuwi/util-crypto'; + * + * blake2AsU8a('abc'); // => [0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d] + * ``` + */ +export declare function blake2AsU8a(data: string | Uint8Array, bitLength?: 64 | 128 | 256 | 384 | 512, key?: Uint8Array | null, onlyJs?: boolean): Uint8Array; +/** + * @name blake2AsHex + * @description Creates a blake2b hex from the input. + */ +export declare const blake2AsHex: (data: string | Uint8Array, bitLength?: 256 | 512 | 64 | 128 | 384 | undefined, key?: Uint8Array | null | undefined, onlyJs?: boolean | undefined) => import("@pezkuwi/util/types").HexString; diff --git a/packages/util-crypto/cjs/blake2/asU8a.js b/packages/util-crypto/cjs/blake2/asU8a.js new file mode 100644 index 0000000..c282152 --- /dev/null +++ b/packages/util-crypto/cjs/blake2/asU8a.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.blake2AsHex = void 0; +exports.blake2AsU8a = blake2AsU8a; +const blake2b_1 = require("@noble/hashes/blake2b"); +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +const helpers_js_1 = require("../helpers.js"); +/** + * @name blake2AsU8a + * @summary Creates a blake2b u8a from the input. + * @description + * From a `Uint8Array` input, create the blake2b and return the result as a u8a with the specified `bitLength`. + * @example + *
+ * + * ```javascript + * import { blake2AsU8a } from '@pezkuwi/util-crypto'; + * + * blake2AsU8a('abc'); // => [0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d] + * ``` + */ +function blake2AsU8a(data, bitLength = 256, key, onlyJs) { + const byteLength = Math.ceil(bitLength / 8); + const u8a = (0, util_1.u8aToU8a)(data); + return !util_1.hasBigInt || (!onlyJs && (0, wasm_crypto_1.isReady)()) + ? (0, wasm_crypto_1.blake2b)(u8a, (0, util_1.u8aToU8a)(key), byteLength) + : key + ? (0, blake2b_1.blake2b)(u8a, { dkLen: byteLength, key }) + : (0, blake2b_1.blake2b)(u8a, { dkLen: byteLength }); +} +/** + * @name blake2AsHex + * @description Creates a blake2b hex from the input. + */ +exports.blake2AsHex = (0, helpers_js_1.createAsHex)(blake2AsU8a); diff --git a/packages/util-crypto/cjs/blake2/index.d.ts b/packages/util-crypto/cjs/blake2/index.d.ts new file mode 100644 index 0000000..25b6d7e --- /dev/null +++ b/packages/util-crypto/cjs/blake2/index.d.ts @@ -0,0 +1,4 @@ +/** + * @summary Create blake2b values with specified bitlengths + */ +export { blake2AsHex, blake2AsU8a } from './asU8a.js'; diff --git a/packages/util-crypto/cjs/blake2/index.js b/packages/util-crypto/cjs/blake2/index.js new file mode 100644 index 0000000..7785822 --- /dev/null +++ b/packages/util-crypto/cjs/blake2/index.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.blake2AsU8a = exports.blake2AsHex = void 0; +/** + * @summary Create blake2b values with specified bitlengths + */ +var asU8a_js_1 = require("./asU8a.js"); +Object.defineProperty(exports, "blake2AsHex", { enumerable: true, get: function () { return asU8a_js_1.blake2AsHex; } }); +Object.defineProperty(exports, "blake2AsU8a", { enumerable: true, get: function () { return asU8a_js_1.blake2AsU8a; } }); diff --git a/packages/util-crypto/cjs/bn.d.ts b/packages/util-crypto/cjs/bn.d.ts new file mode 100644 index 0000000..9222de6 --- /dev/null +++ b/packages/util-crypto/cjs/bn.d.ts @@ -0,0 +1,30 @@ +export declare const BN_BE_OPTS: { + isLe: boolean; +}; +export declare const BN_LE_OPTS: { + isLe: boolean; +}; +export declare const BN_LE_16_OPTS: { + bitLength: number; + isLe: boolean; +}; +export declare const BN_BE_32_OPTS: { + bitLength: number; + isLe: boolean; +}; +export declare const BN_LE_32_OPTS: { + bitLength: number; + isLe: boolean; +}; +export declare const BN_BE_256_OPTS: { + bitLength: number; + isLe: boolean; +}; +export declare const BN_LE_256_OPTS: { + bitLength: number; + isLe: boolean; +}; +export declare const BN_LE_512_OPTS: { + bitLength: number; + isLe: boolean; +}; diff --git a/packages/util-crypto/cjs/bn.js b/packages/util-crypto/cjs/bn.js new file mode 100644 index 0000000..9aab19d --- /dev/null +++ b/packages/util-crypto/cjs/bn.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BN_LE_512_OPTS = exports.BN_LE_256_OPTS = exports.BN_BE_256_OPTS = exports.BN_LE_32_OPTS = exports.BN_BE_32_OPTS = exports.BN_LE_16_OPTS = exports.BN_LE_OPTS = exports.BN_BE_OPTS = void 0; +exports.BN_BE_OPTS = { isLe: false }; +exports.BN_LE_OPTS = { isLe: true }; +exports.BN_LE_16_OPTS = { bitLength: 16, isLe: true }; +exports.BN_BE_32_OPTS = { bitLength: 32, isLe: false }; +exports.BN_LE_32_OPTS = { bitLength: 32, isLe: true }; +exports.BN_BE_256_OPTS = { bitLength: 256, isLe: false }; +exports.BN_LE_256_OPTS = { bitLength: 256, isLe: true }; +exports.BN_LE_512_OPTS = { bitLength: 512, isLe: true }; diff --git a/packages/util-crypto/cjs/bundle.d.ts b/packages/util-crypto/cjs/bundle.d.ts new file mode 100644 index 0000000..57263d8 --- /dev/null +++ b/packages/util-crypto/cjs/bundle.d.ts @@ -0,0 +1,26 @@ +import './bundleInit.js'; +export { packageInfo } from './packageInfo.js'; +export * from './address/index.js'; +export * from './base32/index.js'; +export * from './base58/index.js'; +export * from './base64/index.js'; +export * from './blake2/index.js'; +export * from './crypto.js'; +export * from './ed25519/index.js'; +export * from './ethereum/index.js'; +export * from './hd/index.js'; +export * from './hmac/index.js'; +export * from './json/index.js'; +export * from './keccak/index.js'; +export * from './key/index.js'; +export * from './mnemonic/index.js'; +export * from './nacl/index.js'; +export * from './networks.js'; +export * from './pbkdf2/index.js'; +export * from './random/index.js'; +export * from './scrypt/index.js'; +export * from './secp256k1/index.js'; +export * from './sha/index.js'; +export * from './signature/index.js'; +export * from './sr25519/index.js'; +export * from './xxhash/index.js'; diff --git a/packages/util-crypto/cjs/bundle.js b/packages/util-crypto/cjs/bundle.js new file mode 100644 index 0000000..7c70228 --- /dev/null +++ b/packages/util-crypto/cjs/bundle.js @@ -0,0 +1,31 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +const tslib_1 = require("tslib"); +require("./bundleInit.js"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +tslib_1.__exportStar(require("./address/index.js"), exports); +tslib_1.__exportStar(require("./base32/index.js"), exports); +tslib_1.__exportStar(require("./base58/index.js"), exports); +tslib_1.__exportStar(require("./base64/index.js"), exports); +tslib_1.__exportStar(require("./blake2/index.js"), exports); +tslib_1.__exportStar(require("./crypto.js"), exports); +tslib_1.__exportStar(require("./ed25519/index.js"), exports); +tslib_1.__exportStar(require("./ethereum/index.js"), exports); +tslib_1.__exportStar(require("./hd/index.js"), exports); +tslib_1.__exportStar(require("./hmac/index.js"), exports); +tslib_1.__exportStar(require("./json/index.js"), exports); +tslib_1.__exportStar(require("./keccak/index.js"), exports); +tslib_1.__exportStar(require("./key/index.js"), exports); +tslib_1.__exportStar(require("./mnemonic/index.js"), exports); +tslib_1.__exportStar(require("./nacl/index.js"), exports); +tslib_1.__exportStar(require("./networks.js"), exports); +tslib_1.__exportStar(require("./pbkdf2/index.js"), exports); +tslib_1.__exportStar(require("./random/index.js"), exports); +tslib_1.__exportStar(require("./scrypt/index.js"), exports); +tslib_1.__exportStar(require("./secp256k1/index.js"), exports); +tslib_1.__exportStar(require("./sha/index.js"), exports); +tslib_1.__exportStar(require("./signature/index.js"), exports); +tslib_1.__exportStar(require("./sr25519/index.js"), exports); +tslib_1.__exportStar(require("./xxhash/index.js"), exports); diff --git a/packages/util-crypto/cjs/bundleInit.d.ts b/packages/util-crypto/cjs/bundleInit.d.ts new file mode 100644 index 0000000..2328298 --- /dev/null +++ b/packages/util-crypto/cjs/bundleInit.d.ts @@ -0,0 +1 @@ +import '@pezkuwi/x-bigint/shim'; diff --git a/packages/util-crypto/cjs/bundleInit.js b/packages/util-crypto/cjs/bundleInit.js new file mode 100644 index 0000000..630a596 --- /dev/null +++ b/packages/util-crypto/cjs/bundleInit.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +require("@pezkuwi/x-bigint/shim"); +const crypto_js_1 = require("./crypto.js"); +(0, crypto_js_1.cryptoWaitReady)().catch(() => { + // shouldn't happen, logged and caught inside cryptoWaitReady +}); diff --git a/packages/util-crypto/cjs/crypto.d.ts b/packages/util-crypto/cjs/crypto.d.ts new file mode 100644 index 0000000..094f8b6 --- /dev/null +++ b/packages/util-crypto/cjs/crypto.d.ts @@ -0,0 +1,3 @@ +import { isReady } from '@pezkuwi/wasm-crypto'; +export declare const cryptoIsReady: typeof isReady; +export declare function cryptoWaitReady(): Promise; diff --git a/packages/util-crypto/cjs/crypto.js b/packages/util-crypto/cjs/crypto.js new file mode 100644 index 0000000..b810dc6 --- /dev/null +++ b/packages/util-crypto/cjs/crypto.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.cryptoIsReady = void 0; +exports.cryptoWaitReady = cryptoWaitReady; +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +exports.cryptoIsReady = wasm_crypto_1.isReady; +function cryptoWaitReady() { + return (0, wasm_crypto_1.waitReady)() + .then(() => { + if (!(0, wasm_crypto_1.isReady)()) { + throw new Error('Unable to initialize @pezkuwi/util-crypto'); + } + return true; + }) + .catch(() => false); +} diff --git a/packages/util-crypto/cjs/ed25519/deriveHard.d.ts b/packages/util-crypto/cjs/ed25519/deriveHard.d.ts new file mode 100644 index 0000000..29aba40 --- /dev/null +++ b/packages/util-crypto/cjs/ed25519/deriveHard.d.ts @@ -0,0 +1 @@ +export declare function ed25519DeriveHard(seed: Uint8Array, chainCode: Uint8Array): Uint8Array; diff --git a/packages/util-crypto/cjs/ed25519/deriveHard.js b/packages/util-crypto/cjs/ed25519/deriveHard.js new file mode 100644 index 0000000..c328c8f --- /dev/null +++ b/packages/util-crypto/cjs/ed25519/deriveHard.js @@ -0,0 +1,12 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ed25519DeriveHard = ed25519DeriveHard; +const util_1 = require("@pezkuwi/util"); +const asU8a_js_1 = require("../blake2/asU8a.js"); +const HDKD = (0, util_1.compactAddLength)((0, util_1.stringToU8a)('Ed25519HDKD')); +function ed25519DeriveHard(seed, chainCode) { + if (!(0, util_1.isU8a)(chainCode) || chainCode.length !== 32) { + throw new Error('Invalid chainCode passed to derive'); + } + return (0, asU8a_js_1.blake2AsU8a)((0, util_1.u8aConcat)(HDKD, seed, chainCode)); +} diff --git a/packages/util-crypto/cjs/ed25519/index.d.ts b/packages/util-crypto/cjs/ed25519/index.d.ts new file mode 100644 index 0000000..5a29640 --- /dev/null +++ b/packages/util-crypto/cjs/ed25519/index.d.ts @@ -0,0 +1,10 @@ +/** + * @summary Implements ed25519 operations + */ +export { ed25519DeriveHard } from './deriveHard.js'; +export { ed25519PairFromRandom } from './pair/fromRandom.js'; +export { ed25519PairFromSecret } from './pair/fromSecret.js'; +export { ed25519PairFromSeed } from './pair/fromSeed.js'; +export { ed25519PairFromString } from './pair/fromString.js'; +export { ed25519Sign } from './sign.js'; +export { ed25519Verify } from './verify.js'; diff --git a/packages/util-crypto/cjs/ed25519/index.js b/packages/util-crypto/cjs/ed25519/index.js new file mode 100644 index 0000000..cee2694 --- /dev/null +++ b/packages/util-crypto/cjs/ed25519/index.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ed25519Verify = exports.ed25519Sign = exports.ed25519PairFromString = exports.ed25519PairFromSeed = exports.ed25519PairFromSecret = exports.ed25519PairFromRandom = exports.ed25519DeriveHard = void 0; +/** + * @summary Implements ed25519 operations + */ +var deriveHard_js_1 = require("./deriveHard.js"); +Object.defineProperty(exports, "ed25519DeriveHard", { enumerable: true, get: function () { return deriveHard_js_1.ed25519DeriveHard; } }); +var fromRandom_js_1 = require("./pair/fromRandom.js"); +Object.defineProperty(exports, "ed25519PairFromRandom", { enumerable: true, get: function () { return fromRandom_js_1.ed25519PairFromRandom; } }); +var fromSecret_js_1 = require("./pair/fromSecret.js"); +Object.defineProperty(exports, "ed25519PairFromSecret", { enumerable: true, get: function () { return fromSecret_js_1.ed25519PairFromSecret; } }); +var fromSeed_js_1 = require("./pair/fromSeed.js"); +Object.defineProperty(exports, "ed25519PairFromSeed", { enumerable: true, get: function () { return fromSeed_js_1.ed25519PairFromSeed; } }); +var fromString_js_1 = require("./pair/fromString.js"); +Object.defineProperty(exports, "ed25519PairFromString", { enumerable: true, get: function () { return fromString_js_1.ed25519PairFromString; } }); +var sign_js_1 = require("./sign.js"); +Object.defineProperty(exports, "ed25519Sign", { enumerable: true, get: function () { return sign_js_1.ed25519Sign; } }); +var verify_js_1 = require("./verify.js"); +Object.defineProperty(exports, "ed25519Verify", { enumerable: true, get: function () { return verify_js_1.ed25519Verify; } }); diff --git a/packages/util-crypto/cjs/ed25519/pair/fromRandom.d.ts b/packages/util-crypto/cjs/ed25519/pair/fromRandom.d.ts new file mode 100644 index 0000000..ce5d89e --- /dev/null +++ b/packages/util-crypto/cjs/ed25519/pair/fromRandom.d.ts @@ -0,0 +1,16 @@ +import type { Keypair } from '../../types.js'; +/** + * @name ed25519PairFromRandom + * @summary Creates a new public/secret keypair. + * @description + * Returns a new generate object containing a `publicKey` & `secretKey`. + * @example + *
+ * + * ```javascript + * import { ed25519PairFromRandom } from '@pezkuwi/util-crypto'; + * + * ed25519PairFromRandom(); // => { secretKey: [...], publicKey: [...] } + * ``` + */ +export declare function ed25519PairFromRandom(): Keypair; diff --git a/packages/util-crypto/cjs/ed25519/pair/fromRandom.js b/packages/util-crypto/cjs/ed25519/pair/fromRandom.js new file mode 100644 index 0000000..af4633b --- /dev/null +++ b/packages/util-crypto/cjs/ed25519/pair/fromRandom.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ed25519PairFromRandom = ed25519PairFromRandom; +const index_js_1 = require("../../random/index.js"); +const fromSeed_js_1 = require("./fromSeed.js"); +/** + * @name ed25519PairFromRandom + * @summary Creates a new public/secret keypair. + * @description + * Returns a new generate object containing a `publicKey` & `secretKey`. + * @example + *
+ * + * ```javascript + * import { ed25519PairFromRandom } from '@pezkuwi/util-crypto'; + * + * ed25519PairFromRandom(); // => { secretKey: [...], publicKey: [...] } + * ``` + */ +function ed25519PairFromRandom() { + return (0, fromSeed_js_1.ed25519PairFromSeed)((0, index_js_1.randomAsU8a)()); +} diff --git a/packages/util-crypto/cjs/ed25519/pair/fromSecret.d.ts b/packages/util-crypto/cjs/ed25519/pair/fromSecret.d.ts new file mode 100644 index 0000000..a9bbfb6 --- /dev/null +++ b/packages/util-crypto/cjs/ed25519/pair/fromSecret.d.ts @@ -0,0 +1,16 @@ +import type { Keypair } from '../../types.js'; +/** + * @name ed25519PairFromSecret + * @summary Creates a new public/secret keypair from a secret. + * @description + * Returns a object containing a `publicKey` & `secretKey` generated from the supplied secret. + * @example + *
+ * + * ```javascript + * import { ed25519PairFromSecret } from '@pezkuwi/util-crypto'; + * + * ed25519PairFromSecret(...); // => { secretKey: [...], publicKey: [...] } + * ``` + */ +export declare function ed25519PairFromSecret(secretKey: Uint8Array): Keypair; diff --git a/packages/util-crypto/cjs/ed25519/pair/fromSecret.js b/packages/util-crypto/cjs/ed25519/pair/fromSecret.js new file mode 100644 index 0000000..913f4a2 --- /dev/null +++ b/packages/util-crypto/cjs/ed25519/pair/fromSecret.js @@ -0,0 +1,26 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ed25519PairFromSecret = ed25519PairFromSecret; +/** + * @name ed25519PairFromSecret + * @summary Creates a new public/secret keypair from a secret. + * @description + * Returns a object containing a `publicKey` & `secretKey` generated from the supplied secret. + * @example + *
+ * + * ```javascript + * import { ed25519PairFromSecret } from '@pezkuwi/util-crypto'; + * + * ed25519PairFromSecret(...); // => { secretKey: [...], publicKey: [...] } + * ``` + */ +function ed25519PairFromSecret(secretKey) { + if (secretKey.length !== 64) { + throw new Error('Invalid secretKey provided'); + } + return { + publicKey: secretKey.slice(32), + secretKey + }; +} diff --git a/packages/util-crypto/cjs/ed25519/pair/fromSeed.d.ts b/packages/util-crypto/cjs/ed25519/pair/fromSeed.d.ts new file mode 100644 index 0000000..f854cca --- /dev/null +++ b/packages/util-crypto/cjs/ed25519/pair/fromSeed.d.ts @@ -0,0 +1,16 @@ +import type { Keypair } from '../../types.js'; +/** + * @name ed25519PairFromSeed + * @summary Creates a new public/secret keypair from a seed. + * @description + * Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed. + * @example + *
+ * + * ```javascript + * import { ed25519PairFromSeed } from '@pezkuwi/util-crypto'; + * + * ed25519PairFromSeed(...); // => { secretKey: [...], publicKey: [...] } + * ``` + */ +export declare function ed25519PairFromSeed(seed: Uint8Array, onlyJs?: boolean): Keypair; diff --git a/packages/util-crypto/cjs/ed25519/pair/fromSeed.js b/packages/util-crypto/cjs/ed25519/pair/fromSeed.js new file mode 100644 index 0000000..6251192 --- /dev/null +++ b/packages/util-crypto/cjs/ed25519/pair/fromSeed.js @@ -0,0 +1,34 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ed25519PairFromSeed = ed25519PairFromSeed; +const ed25519_1 = require("@noble/curves/ed25519"); +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +/** + * @name ed25519PairFromSeed + * @summary Creates a new public/secret keypair from a seed. + * @description + * Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed. + * @example + *
+ * + * ```javascript + * import { ed25519PairFromSeed } from '@pezkuwi/util-crypto'; + * + * ed25519PairFromSeed(...); // => { secretKey: [...], publicKey: [...] } + * ``` + */ +function ed25519PairFromSeed(seed, onlyJs) { + if (!util_1.hasBigInt || (!onlyJs && (0, wasm_crypto_1.isReady)())) { + const full = (0, wasm_crypto_1.ed25519KeypairFromSeed)(seed); + return { + publicKey: full.slice(32), + secretKey: full.slice(0, 64) + }; + } + const publicKey = ed25519_1.ed25519.getPublicKey(seed); + return { + publicKey, + secretKey: (0, util_1.u8aConcatStrict)([seed, publicKey]) + }; +} diff --git a/packages/util-crypto/cjs/ed25519/pair/fromString.d.ts b/packages/util-crypto/cjs/ed25519/pair/fromString.d.ts new file mode 100644 index 0000000..6ff5640 --- /dev/null +++ b/packages/util-crypto/cjs/ed25519/pair/fromString.d.ts @@ -0,0 +1,16 @@ +import type { Keypair } from '../../types.js'; +/** + * @name ed25519PairFromString + * @summary Creates a new public/secret keypair from a string. + * @description + * Returns a object containing a `publicKey` & `secretKey` generated from the supplied string. The string is hashed and the value used as the input seed. + * @example + *
+ * + * ```javascript + * import { ed25519PairFromString } from '@pezkuwi/util-crypto'; + * + * ed25519PairFromString('test'); // => { secretKey: [...], publicKey: [...] } + * ``` + */ +export declare function ed25519PairFromString(value: string): Keypair; diff --git a/packages/util-crypto/cjs/ed25519/pair/fromString.js b/packages/util-crypto/cjs/ed25519/pair/fromString.js new file mode 100644 index 0000000..49af192 --- /dev/null +++ b/packages/util-crypto/cjs/ed25519/pair/fromString.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ed25519PairFromString = ed25519PairFromString; +const util_1 = require("@pezkuwi/util"); +const asU8a_js_1 = require("../../blake2/asU8a.js"); +const fromSeed_js_1 = require("./fromSeed.js"); +/** + * @name ed25519PairFromString + * @summary Creates a new public/secret keypair from a string. + * @description + * Returns a object containing a `publicKey` & `secretKey` generated from the supplied string. The string is hashed and the value used as the input seed. + * @example + *
+ * + * ```javascript + * import { ed25519PairFromString } from '@pezkuwi/util-crypto'; + * + * ed25519PairFromString('test'); // => { secretKey: [...], publicKey: [...] } + * ``` + */ +function ed25519PairFromString(value) { + return (0, fromSeed_js_1.ed25519PairFromSeed)((0, asU8a_js_1.blake2AsU8a)((0, util_1.stringToU8a)(value))); +} diff --git a/packages/util-crypto/cjs/ed25519/sign.d.ts b/packages/util-crypto/cjs/ed25519/sign.d.ts new file mode 100644 index 0000000..ce23440 --- /dev/null +++ b/packages/util-crypto/cjs/ed25519/sign.d.ts @@ -0,0 +1,16 @@ +import type { Keypair } from '../types.js'; +/** + * @name ed25519Sign + * @summary Signs a message using the supplied secretKey + * @description + * Returns message signature of `message`, using the `secretKey`. + * @example + *
+ * + * ```javascript + * import { ed25519Sign } from '@pezkuwi/util-crypto'; + * + * ed25519Sign([...], [...]); // => [...] + * ``` + */ +export declare function ed25519Sign(message: string | Uint8Array, { publicKey, secretKey }: Partial, onlyJs?: boolean): Uint8Array; diff --git a/packages/util-crypto/cjs/ed25519/sign.js b/packages/util-crypto/cjs/ed25519/sign.js new file mode 100644 index 0000000..07fa33a --- /dev/null +++ b/packages/util-crypto/cjs/ed25519/sign.js @@ -0,0 +1,33 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ed25519Sign = ed25519Sign; +const ed25519_1 = require("@noble/curves/ed25519"); +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +/** + * @name ed25519Sign + * @summary Signs a message using the supplied secretKey + * @description + * Returns message signature of `message`, using the `secretKey`. + * @example + *
+ * + * ```javascript + * import { ed25519Sign } from '@pezkuwi/util-crypto'; + * + * ed25519Sign([...], [...]); // => [...] + * ``` + */ +function ed25519Sign(message, { publicKey, secretKey }, onlyJs) { + if (!secretKey) { + throw new Error('Expected a valid secretKey'); + } + else if (!publicKey) { + throw new Error('Expected a valid publicKey'); + } + const messageU8a = (0, util_1.u8aToU8a)(message); + const privateU8a = secretKey.subarray(0, 32); + return !util_1.hasBigInt || (!onlyJs && (0, wasm_crypto_1.isReady)()) + ? (0, wasm_crypto_1.ed25519Sign)(publicKey, privateU8a, messageU8a) + : ed25519_1.ed25519.sign(messageU8a, privateU8a); +} diff --git a/packages/util-crypto/cjs/ed25519/verify.d.ts b/packages/util-crypto/cjs/ed25519/verify.d.ts new file mode 100644 index 0000000..ec03efc --- /dev/null +++ b/packages/util-crypto/cjs/ed25519/verify.d.ts @@ -0,0 +1,15 @@ +/** + * @name ed25519Sign + * @summary Verifies the signature on the supplied message. + * @description + * Verifies the `signature` on `message` with the supplied `publicKey`. Returns `true` on sucess, `false` otherwise. + * @example + *
+ * + * ```javascript + * import { ed25519Verify } from '@pezkuwi/util-crypto'; + * + * ed25519Verify([...], [...], [...]); // => true/false + * ``` + */ +export declare function ed25519Verify(message: string | Uint8Array, signature: string | Uint8Array, publicKey: string | Uint8Array, onlyJs?: boolean): boolean; diff --git a/packages/util-crypto/cjs/ed25519/verify.js b/packages/util-crypto/cjs/ed25519/verify.js new file mode 100644 index 0000000..92166e1 --- /dev/null +++ b/packages/util-crypto/cjs/ed25519/verify.js @@ -0,0 +1,39 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ed25519Verify = ed25519Verify; +const ed25519_1 = require("@noble/curves/ed25519"); +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +/** + * @name ed25519Sign + * @summary Verifies the signature on the supplied message. + * @description + * Verifies the `signature` on `message` with the supplied `publicKey`. Returns `true` on sucess, `false` otherwise. + * @example + *
+ * + * ```javascript + * import { ed25519Verify } from '@pezkuwi/util-crypto'; + * + * ed25519Verify([...], [...], [...]); // => true/false + * ``` + */ +function ed25519Verify(message, signature, publicKey, onlyJs) { + const messageU8a = (0, util_1.u8aToU8a)(message); + const publicKeyU8a = (0, util_1.u8aToU8a)(publicKey); + const signatureU8a = (0, util_1.u8aToU8a)(signature); + if (publicKeyU8a.length !== 32) { + throw new Error(`Invalid publicKey, received ${publicKeyU8a.length}, expected 32`); + } + else if (signatureU8a.length !== 64) { + throw new Error(`Invalid signature, received ${signatureU8a.length} bytes, expected 64`); + } + try { + return !util_1.hasBigInt || (!onlyJs && (0, wasm_crypto_1.isReady)()) + ? (0, wasm_crypto_1.ed25519Verify)(signatureU8a, messageU8a, publicKeyU8a) + : ed25519_1.ed25519.verify(signatureU8a, messageU8a, publicKeyU8a); + } + catch { + return false; + } +} diff --git a/packages/util-crypto/cjs/ethereum/encode.d.ts b/packages/util-crypto/cjs/ethereum/encode.d.ts new file mode 100644 index 0000000..a181856 --- /dev/null +++ b/packages/util-crypto/cjs/ethereum/encode.d.ts @@ -0,0 +1,2 @@ +import type { HexString } from '@pezkuwi/util/types'; +export declare function ethereumEncode(addressOrPublic?: string | Uint8Array): HexString; diff --git a/packages/util-crypto/cjs/ethereum/encode.js b/packages/util-crypto/cjs/ethereum/encode.js new file mode 100644 index 0000000..40be1bd --- /dev/null +++ b/packages/util-crypto/cjs/ethereum/encode.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ethereumEncode = ethereumEncode; +const util_1 = require("@pezkuwi/util"); +const index_js_1 = require("../keccak/index.js"); +const index_js_2 = require("../secp256k1/index.js"); +function getH160(u8a) { + if ([33, 65].includes(u8a.length)) { + u8a = (0, index_js_1.keccakAsU8a)((0, index_js_2.secp256k1Expand)(u8a)); + } + return u8a.slice(-20); +} +function ethereumEncode(addressOrPublic) { + if (!addressOrPublic) { + return '0x'; + } + const u8aAddress = (0, util_1.u8aToU8a)(addressOrPublic); + if (![20, 32, 33, 65].includes(u8aAddress.length)) { + throw new Error(`Invalid address or publicKey provided, received ${u8aAddress.length} bytes input`); + } + const address = (0, util_1.u8aToHex)(getH160(u8aAddress), -1, false); + const hash = (0, util_1.u8aToHex)((0, index_js_1.keccakAsU8a)(address), -1, false); + let result = ''; + for (let i = 0; i < 40; i++) { + result = `${result}${parseInt(hash[i], 16) > 7 ? address[i].toUpperCase() : address[i]}`; + } + return `0x${result}`; +} diff --git a/packages/util-crypto/cjs/ethereum/index.d.ts b/packages/util-crypto/cjs/ethereum/index.d.ts new file mode 100644 index 0000000..d5621e7 --- /dev/null +++ b/packages/util-crypto/cjs/ethereum/index.d.ts @@ -0,0 +1,3 @@ +export { ethereumEncode } from './encode.js'; +export { isEthereumAddress } from './isAddress.js'; +export { isEthereumChecksum } from './isChecksum.js'; diff --git a/packages/util-crypto/cjs/ethereum/index.js b/packages/util-crypto/cjs/ethereum/index.js new file mode 100644 index 0000000..3c1776f --- /dev/null +++ b/packages/util-crypto/cjs/ethereum/index.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isEthereumChecksum = exports.isEthereumAddress = exports.ethereumEncode = void 0; +var encode_js_1 = require("./encode.js"); +Object.defineProperty(exports, "ethereumEncode", { enumerable: true, get: function () { return encode_js_1.ethereumEncode; } }); +var isAddress_js_1 = require("./isAddress.js"); +Object.defineProperty(exports, "isEthereumAddress", { enumerable: true, get: function () { return isAddress_js_1.isEthereumAddress; } }); +var isChecksum_js_1 = require("./isChecksum.js"); +Object.defineProperty(exports, "isEthereumChecksum", { enumerable: true, get: function () { return isChecksum_js_1.isEthereumChecksum; } }); diff --git a/packages/util-crypto/cjs/ethereum/isAddress.d.ts b/packages/util-crypto/cjs/ethereum/isAddress.d.ts new file mode 100644 index 0000000..8f1b4f2 --- /dev/null +++ b/packages/util-crypto/cjs/ethereum/isAddress.d.ts @@ -0,0 +1 @@ +export declare function isEthereumAddress(address?: string): boolean; diff --git a/packages/util-crypto/cjs/ethereum/isAddress.js b/packages/util-crypto/cjs/ethereum/isAddress.js new file mode 100644 index 0000000..93cb047 --- /dev/null +++ b/packages/util-crypto/cjs/ethereum/isAddress.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isEthereumAddress = isEthereumAddress; +const util_1 = require("@pezkuwi/util"); +const isChecksum_js_1 = require("./isChecksum.js"); +function isEthereumAddress(address) { + if (!address || address.length !== 42 || !(0, util_1.isHex)(address)) { + return false; + } + else if (/^(0x)?[0-9a-f]{40}$/.test(address) || /^(0x)?[0-9A-F]{40}$/.test(address)) { + return true; + } + return (0, isChecksum_js_1.isEthereumChecksum)(address); +} diff --git a/packages/util-crypto/cjs/ethereum/isChecksum.d.ts b/packages/util-crypto/cjs/ethereum/isChecksum.d.ts new file mode 100644 index 0000000..65a31c1 --- /dev/null +++ b/packages/util-crypto/cjs/ethereum/isChecksum.d.ts @@ -0,0 +1 @@ +export declare function isEthereumChecksum(_address: string): boolean; diff --git a/packages/util-crypto/cjs/ethereum/isChecksum.js b/packages/util-crypto/cjs/ethereum/isChecksum.js new file mode 100644 index 0000000..fa104b7 --- /dev/null +++ b/packages/util-crypto/cjs/ethereum/isChecksum.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isEthereumChecksum = isEthereumChecksum; +const util_1 = require("@pezkuwi/util"); +const index_js_1 = require("../keccak/index.js"); +function isInvalidChar(char, byte) { + return char !== (byte > 7 + ? char.toUpperCase() + : char.toLowerCase()); +} +function isEthereumChecksum(_address) { + const address = _address.replace('0x', ''); + const hash = (0, util_1.u8aToHex)((0, index_js_1.keccakAsU8a)(address.toLowerCase()), -1, false); + for (let i = 0; i < 40; i++) { + if (isInvalidChar(address[i], parseInt(hash[i], 16))) { + return false; + } + } + return true; +} diff --git a/packages/util-crypto/cjs/hd/ethereum/index.d.ts b/packages/util-crypto/cjs/hd/ethereum/index.d.ts new file mode 100644 index 0000000..49a693a --- /dev/null +++ b/packages/util-crypto/cjs/hd/ethereum/index.d.ts @@ -0,0 +1,2 @@ +import type { Keypair } from '../../types.js'; +export declare function hdEthereum(seed: Uint8Array, path?: string): Keypair; diff --git a/packages/util-crypto/cjs/hd/ethereum/index.js b/packages/util-crypto/cjs/hd/ethereum/index.js new file mode 100644 index 0000000..d2abf92 --- /dev/null +++ b/packages/util-crypto/cjs/hd/ethereum/index.js @@ -0,0 +1,47 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hdEthereum = hdEthereum; +const util_1 = require("@pezkuwi/util"); +const bn_js_1 = require("../../bn.js"); +const index_js_1 = require("../../hmac/index.js"); +const index_js_2 = require("../../secp256k1/index.js"); +const validatePath_js_1 = require("../validatePath.js"); +const MASTER_SECRET = (0, util_1.stringToU8a)('Bitcoin seed'); +function createCoded(secretKey, chainCode) { + return { + chainCode, + publicKey: (0, index_js_2.secp256k1PairFromSeed)(secretKey).publicKey, + secretKey + }; +} +function deriveChild(hd, index) { + const indexBuffer = (0, util_1.bnToU8a)(index, bn_js_1.BN_BE_32_OPTS); + const data = index >= validatePath_js_1.HARDENED + ? (0, util_1.u8aConcat)(new Uint8Array(1), hd.secretKey, indexBuffer) + : (0, util_1.u8aConcat)(hd.publicKey, indexBuffer); + try { + const I = (0, index_js_1.hmacShaAsU8a)(hd.chainCode, data, 512); + return createCoded((0, index_js_2.secp256k1PrivateKeyTweakAdd)(hd.secretKey, I.slice(0, 32)), I.slice(32)); + } + catch { + // In case parse256(IL) >= n or ki == 0, proceed with the next value for i + return deriveChild(hd, index + 1); + } +} +function hdEthereum(seed, path = '') { + const I = (0, index_js_1.hmacShaAsU8a)(MASTER_SECRET, seed, 512); + let hd = createCoded(I.slice(0, 32), I.slice(32)); + if (!path || path === 'm' || path === 'M' || path === "m'" || path === "M'") { + return hd; + } + if (!(0, validatePath_js_1.hdValidatePath)(path)) { + throw new Error('Invalid derivation path'); + } + const parts = path.split('/').slice(1); + for (const p of parts) { + hd = deriveChild(hd, parseInt(p, 10) + ((p.length > 1) && p.endsWith("'") + ? validatePath_js_1.HARDENED + : 0)); + } + return hd; +} diff --git a/packages/util-crypto/cjs/hd/index.d.ts b/packages/util-crypto/cjs/hd/index.d.ts new file mode 100644 index 0000000..a29e23a --- /dev/null +++ b/packages/util-crypto/cjs/hd/index.d.ts @@ -0,0 +1,3 @@ +export { hdEthereum } from './ethereum/index.js'; +export { hdLedger } from './ledger/index.js'; +export { hdValidatePath } from './validatePath.js'; diff --git a/packages/util-crypto/cjs/hd/index.js b/packages/util-crypto/cjs/hd/index.js new file mode 100644 index 0000000..a683fc4 --- /dev/null +++ b/packages/util-crypto/cjs/hd/index.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hdValidatePath = exports.hdLedger = exports.hdEthereum = void 0; +var index_js_1 = require("./ethereum/index.js"); +Object.defineProperty(exports, "hdEthereum", { enumerable: true, get: function () { return index_js_1.hdEthereum; } }); +var index_js_2 = require("./ledger/index.js"); +Object.defineProperty(exports, "hdLedger", { enumerable: true, get: function () { return index_js_2.hdLedger; } }); +var validatePath_js_1 = require("./validatePath.js"); +Object.defineProperty(exports, "hdValidatePath", { enumerable: true, get: function () { return validatePath_js_1.hdValidatePath; } }); diff --git a/packages/util-crypto/cjs/hd/ledger/derivePrivate.d.ts b/packages/util-crypto/cjs/hd/ledger/derivePrivate.d.ts new file mode 100644 index 0000000..27ece08 --- /dev/null +++ b/packages/util-crypto/cjs/hd/ledger/derivePrivate.d.ts @@ -0,0 +1 @@ +export declare function ledgerDerivePrivate(xprv: Uint8Array, index: number): Uint8Array; diff --git a/packages/util-crypto/cjs/hd/ledger/derivePrivate.js b/packages/util-crypto/cjs/hd/ledger/derivePrivate.js new file mode 100644 index 0000000..9e619e8 --- /dev/null +++ b/packages/util-crypto/cjs/hd/ledger/derivePrivate.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ledgerDerivePrivate = ledgerDerivePrivate; +const util_1 = require("@pezkuwi/util"); +const bn_js_1 = require("../../bn.js"); +const index_js_1 = require("../../hmac/index.js"); +function ledgerDerivePrivate(xprv, index) { + const kl = xprv.subarray(0, 32); + const kr = xprv.subarray(32, 64); + const cc = xprv.subarray(64, 96); + const data = (0, util_1.u8aConcat)([0], kl, kr, (0, util_1.bnToU8a)(index, bn_js_1.BN_LE_32_OPTS)); + const z = (0, index_js_1.hmacShaAsU8a)(cc, data, 512); + data[0] = 0x01; + return (0, util_1.u8aConcat)((0, util_1.bnToU8a)((0, util_1.u8aToBn)(kl, bn_js_1.BN_LE_OPTS).iadd((0, util_1.u8aToBn)(z.subarray(0, 28), bn_js_1.BN_LE_OPTS).imul(util_1.BN_EIGHT)), bn_js_1.BN_LE_512_OPTS).subarray(0, 32), (0, util_1.bnToU8a)((0, util_1.u8aToBn)(kr, bn_js_1.BN_LE_OPTS).iadd((0, util_1.u8aToBn)(z.subarray(32, 64), bn_js_1.BN_LE_OPTS)), bn_js_1.BN_LE_512_OPTS).subarray(0, 32), (0, index_js_1.hmacShaAsU8a)(cc, data, 512).subarray(32, 64)); +} diff --git a/packages/util-crypto/cjs/hd/ledger/index.d.ts b/packages/util-crypto/cjs/hd/ledger/index.d.ts new file mode 100644 index 0000000..691d037 --- /dev/null +++ b/packages/util-crypto/cjs/hd/ledger/index.d.ts @@ -0,0 +1,2 @@ +import type { Keypair } from '../../types.js'; +export declare function hdLedger(_mnemonic: string, path: string): Keypair; diff --git a/packages/util-crypto/cjs/hd/ledger/index.js b/packages/util-crypto/cjs/hd/ledger/index.js new file mode 100644 index 0000000..dce3405 --- /dev/null +++ b/packages/util-crypto/cjs/hd/ledger/index.js @@ -0,0 +1,33 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hdLedger = hdLedger; +const index_js_1 = require("../../ed25519/index.js"); +const index_js_2 = require("../../mnemonic/index.js"); +const validatePath_js_1 = require("../validatePath.js"); +const derivePrivate_js_1 = require("./derivePrivate.js"); +const master_js_1 = require("./master.js"); +function hdLedger(_mnemonic, path) { + const words = _mnemonic + .split(' ') + .map((s) => s.trim()) + .filter((s) => s); + if (![12, 24, 25].includes(words.length)) { + throw new Error('Expected a mnemonic with 24 words (or 25 including a password)'); + } + const [mnemonic, password] = words.length === 25 + ? [words.slice(0, 24).join(' '), words[24]] + : [words.join(' '), '']; + if (!(0, index_js_2.mnemonicValidate)(mnemonic)) { + throw new Error('Invalid mnemonic passed to ledger derivation'); + } + else if (!(0, validatePath_js_1.hdValidatePath)(path)) { + throw new Error('Invalid derivation path'); + } + const parts = path.split('/').slice(1); + let seed = (0, master_js_1.ledgerMaster)(mnemonic, password); + for (const p of parts) { + const n = parseInt(p.replace(/'$/, ''), 10); + seed = (0, derivePrivate_js_1.ledgerDerivePrivate)(seed, (n < validatePath_js_1.HARDENED) ? (n + validatePath_js_1.HARDENED) : n); + } + return (0, index_js_1.ed25519PairFromSeed)(seed.slice(0, 32)); +} diff --git a/packages/util-crypto/cjs/hd/ledger/master.d.ts b/packages/util-crypto/cjs/hd/ledger/master.d.ts new file mode 100644 index 0000000..47ac68f --- /dev/null +++ b/packages/util-crypto/cjs/hd/ledger/master.d.ts @@ -0,0 +1 @@ +export declare function ledgerMaster(mnemonic: string, password?: string): Uint8Array; diff --git a/packages/util-crypto/cjs/hd/ledger/master.js b/packages/util-crypto/cjs/hd/ledger/master.js new file mode 100644 index 0000000..8125580 --- /dev/null +++ b/packages/util-crypto/cjs/hd/ledger/master.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ledgerMaster = ledgerMaster; +const util_1 = require("@pezkuwi/util"); +const index_js_1 = require("../../hmac/index.js"); +const bip39_js_1 = require("../../mnemonic/bip39.js"); +const ED25519_CRYPTO = 'ed25519 seed'; +function ledgerMaster(mnemonic, password) { + const seed = (0, bip39_js_1.mnemonicToSeedSync)(mnemonic, password); + const chainCode = (0, index_js_1.hmacShaAsU8a)(ED25519_CRYPTO, new Uint8Array([1, ...seed]), 256); + let priv; + while (!priv || (priv[31] & 0b0010_0000)) { + priv = (0, index_js_1.hmacShaAsU8a)(ED25519_CRYPTO, priv || seed, 512); + } + priv[0] &= 0b1111_1000; + priv[31] &= 0b0111_1111; + priv[31] |= 0b0100_0000; + return (0, util_1.u8aConcat)(priv, chainCode); +} diff --git a/packages/util-crypto/cjs/hd/validatePath.d.ts b/packages/util-crypto/cjs/hd/validatePath.d.ts new file mode 100644 index 0000000..6a26040 --- /dev/null +++ b/packages/util-crypto/cjs/hd/validatePath.d.ts @@ -0,0 +1,2 @@ +export declare const HARDENED = 2147483648; +export declare function hdValidatePath(path: string): boolean; diff --git a/packages/util-crypto/cjs/hd/validatePath.js b/packages/util-crypto/cjs/hd/validatePath.js new file mode 100644 index 0000000..dde384d --- /dev/null +++ b/packages/util-crypto/cjs/hd/validatePath.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.HARDENED = void 0; +exports.hdValidatePath = hdValidatePath; +exports.HARDENED = 0x80000000; +function hdValidatePath(path) { + if (!path.startsWith('m/')) { + return false; + } + const parts = path.split('/').slice(1); + for (const p of parts) { + const n = /^\d+'?$/.test(p) + ? parseInt(p.replace(/'$/, ''), 10) + : Number.NaN; + if (isNaN(n) || (n >= exports.HARDENED) || (n < 0)) { + return false; + } + } + return true; +} diff --git a/packages/util-crypto/cjs/helpers.d.ts b/packages/util-crypto/cjs/helpers.d.ts new file mode 100644 index 0000000..7d403bf --- /dev/null +++ b/packages/util-crypto/cjs/helpers.d.ts @@ -0,0 +1,12 @@ +import type { HexString } from '@pezkuwi/util/types'; +export type { HexString } from '@pezkuwi/util/types'; +interface DualHash { + 256: (u8a: Uint8Array) => Uint8Array; + 512: (u8a: Uint8Array) => Uint8Array; +} +/** @internal */ +export declare function createAsHex Uint8Array>(fn: T): (...args: Parameters) => HexString; +/** @internal */ +export declare function createBitHasher(bitLength: 256 | 512, fn: (data: string | Uint8Array, bitLength: 256 | 512, onlyJs?: boolean) => Uint8Array): (data: string | Uint8Array, onlyJs?: boolean) => Uint8Array; +/** @internal */ +export declare function createDualHasher(wa: DualHash, js: DualHash): (value: string | Uint8Array, bitLength?: 256 | 512, onlyJs?: boolean) => Uint8Array; diff --git a/packages/util-crypto/cjs/helpers.js b/packages/util-crypto/cjs/helpers.js new file mode 100644 index 0000000..06086a2 --- /dev/null +++ b/packages/util-crypto/cjs/helpers.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createAsHex = createAsHex; +exports.createBitHasher = createBitHasher; +exports.createDualHasher = createDualHasher; +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +/** @internal */ +function createAsHex(fn) { + return (...args) => (0, util_1.u8aToHex)(fn(...args)); +} +/** @internal */ +function createBitHasher(bitLength, fn) { + return (data, onlyJs) => fn(data, bitLength, onlyJs); +} +/** @internal */ +function createDualHasher(wa, js) { + return (value, bitLength = 256, onlyJs) => { + const u8a = (0, util_1.u8aToU8a)(value); + return !util_1.hasBigInt || (!onlyJs && (0, wasm_crypto_1.isReady)()) + ? wa[bitLength](u8a) + : js[bitLength](u8a); + }; +} diff --git a/packages/util-crypto/cjs/hmac/index.d.ts b/packages/util-crypto/cjs/hmac/index.d.ts new file mode 100644 index 0000000..248ba5c --- /dev/null +++ b/packages/util-crypto/cjs/hmac/index.d.ts @@ -0,0 +1 @@ +export { hmacSha256AsU8a, hmacSha512AsU8a, hmacShaAsU8a } from './shaAsU8a.js'; diff --git a/packages/util-crypto/cjs/hmac/index.js b/packages/util-crypto/cjs/hmac/index.js new file mode 100644 index 0000000..71e2e4b --- /dev/null +++ b/packages/util-crypto/cjs/hmac/index.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hmacShaAsU8a = exports.hmacSha512AsU8a = exports.hmacSha256AsU8a = void 0; +var shaAsU8a_js_1 = require("./shaAsU8a.js"); +Object.defineProperty(exports, "hmacSha256AsU8a", { enumerable: true, get: function () { return shaAsU8a_js_1.hmacSha256AsU8a; } }); +Object.defineProperty(exports, "hmacSha512AsU8a", { enumerable: true, get: function () { return shaAsU8a_js_1.hmacSha512AsU8a; } }); +Object.defineProperty(exports, "hmacShaAsU8a", { enumerable: true, get: function () { return shaAsU8a_js_1.hmacShaAsU8a; } }); diff --git a/packages/util-crypto/cjs/hmac/shaAsU8a.d.ts b/packages/util-crypto/cjs/hmac/shaAsU8a.d.ts new file mode 100644 index 0000000..268cee9 --- /dev/null +++ b/packages/util-crypto/cjs/hmac/shaAsU8a.d.ts @@ -0,0 +1,15 @@ +/** + * @name hmacShaAsU8a + * @description creates a Hmac Sha (256/512) Uint8Array from the key & data + */ +export declare function hmacShaAsU8a(key: Uint8Array | string, data: Uint8Array, bitLength?: 256 | 512, onlyJs?: boolean): Uint8Array; +/** + * @name hmacSha256AsU8a + * @description creates a Hmac Sha256 Uint8Array from the key & data + */ +export declare const hmacSha256AsU8a: (key: Uint8Array | string, data: Uint8Array, onlyJs?: boolean) => Uint8Array; +/** + * @name hmacSha512AsU8a + * @description creates a Hmac Sha512 Uint8Array from the key & data + */ +export declare const hmacSha512AsU8a: (key: Uint8Array | string, data: Uint8Array, onlyJs?: boolean) => Uint8Array; diff --git a/packages/util-crypto/cjs/hmac/shaAsU8a.js b/packages/util-crypto/cjs/hmac/shaAsU8a.js new file mode 100644 index 0000000..c5b2987 --- /dev/null +++ b/packages/util-crypto/cjs/hmac/shaAsU8a.js @@ -0,0 +1,40 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hmacSha512AsU8a = exports.hmacSha256AsU8a = void 0; +exports.hmacShaAsU8a = hmacShaAsU8a; +const hmac_1 = require("@noble/hashes/hmac"); +const sha256_1 = require("@noble/hashes/sha256"); +const sha512_1 = require("@noble/hashes/sha512"); +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +const JS_HASH = { + 256: sha256_1.sha256, + 512: sha512_1.sha512 +}; +const WA_MHAC = { + 256: wasm_crypto_1.hmacSha256, + 512: wasm_crypto_1.hmacSha512 +}; +function createSha(bitLength) { + return (key, data, onlyJs) => hmacShaAsU8a(key, data, bitLength, onlyJs); +} +/** + * @name hmacShaAsU8a + * @description creates a Hmac Sha (256/512) Uint8Array from the key & data + */ +function hmacShaAsU8a(key, data, bitLength = 256, onlyJs) { + const u8aKey = (0, util_1.u8aToU8a)(key); + return !util_1.hasBigInt || (!onlyJs && (0, wasm_crypto_1.isReady)()) + ? WA_MHAC[bitLength](u8aKey, data) + : (0, hmac_1.hmac)(JS_HASH[bitLength], u8aKey, data); +} +/** + * @name hmacSha256AsU8a + * @description creates a Hmac Sha256 Uint8Array from the key & data + */ +exports.hmacSha256AsU8a = createSha(256); +/** + * @name hmacSha512AsU8a + * @description creates a Hmac Sha512 Uint8Array from the key & data + */ +exports.hmacSha512AsU8a = createSha(512); diff --git a/packages/util-crypto/cjs/index.d.ts b/packages/util-crypto/cjs/index.d.ts new file mode 100644 index 0000000..ca3f403 --- /dev/null +++ b/packages/util-crypto/cjs/index.d.ts @@ -0,0 +1,2 @@ +import './packageDetect.js'; +export * from './bundle.js'; diff --git a/packages/util-crypto/cjs/index.js b/packages/util-crypto/cjs/index.js new file mode 100644 index 0000000..6d0bab1 --- /dev/null +++ b/packages/util-crypto/cjs/index.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +require("./packageDetect.js"); +tslib_1.__exportStar(require("./bundle.js"), exports); diff --git a/packages/util-crypto/cjs/json/constants.d.ts b/packages/util-crypto/cjs/json/constants.d.ts new file mode 100644 index 0000000..ad69a81 --- /dev/null +++ b/packages/util-crypto/cjs/json/constants.d.ts @@ -0,0 +1,6 @@ +import type { EncryptedJsonEncoding, EncryptedJsonVersion } from './types.js'; +export declare const ENCODING: EncryptedJsonEncoding[]; +export declare const ENCODING_NONE: EncryptedJsonEncoding[]; +export declare const ENCODING_VERSION: EncryptedJsonVersion; +export declare const NONCE_LENGTH = 24; +export declare const SCRYPT_LENGTH: number; diff --git a/packages/util-crypto/cjs/json/constants.js b/packages/util-crypto/cjs/json/constants.js new file mode 100644 index 0000000..8425dad --- /dev/null +++ b/packages/util-crypto/cjs/json/constants.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.SCRYPT_LENGTH = exports.NONCE_LENGTH = exports.ENCODING_VERSION = exports.ENCODING_NONE = exports.ENCODING = void 0; +exports.ENCODING = ['scrypt', 'xsalsa20-poly1305']; +exports.ENCODING_NONE = ['none']; +exports.ENCODING_VERSION = '3'; +exports.NONCE_LENGTH = 24; +exports.SCRYPT_LENGTH = 32 + (3 * 4); diff --git a/packages/util-crypto/cjs/json/decrypt.d.ts b/packages/util-crypto/cjs/json/decrypt.d.ts new file mode 100644 index 0000000..2d9e098 --- /dev/null +++ b/packages/util-crypto/cjs/json/decrypt.d.ts @@ -0,0 +1,2 @@ +import type { EncryptedJson } from './types.js'; +export declare function jsonDecrypt({ encoded, encoding }: EncryptedJson, passphrase?: string | null): Uint8Array; diff --git a/packages/util-crypto/cjs/json/decrypt.js b/packages/util-crypto/cjs/json/decrypt.js new file mode 100644 index 0000000..9102e87 --- /dev/null +++ b/packages/util-crypto/cjs/json/decrypt.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.jsonDecrypt = jsonDecrypt; +const util_1 = require("@pezkuwi/util"); +const index_js_1 = require("../base64/index.js"); +const decryptData_js_1 = require("./decryptData.js"); +function jsonDecrypt({ encoded, encoding }, passphrase) { + if (!encoded) { + throw new Error('No encrypted data available to decode'); + } + return (0, decryptData_js_1.jsonDecryptData)((0, util_1.isHex)(encoded) + ? (0, util_1.hexToU8a)(encoded) + : (0, index_js_1.base64Decode)(encoded), passphrase, Array.isArray(encoding.type) + ? encoding.type + : [encoding.type]); +} diff --git a/packages/util-crypto/cjs/json/decryptData.d.ts b/packages/util-crypto/cjs/json/decryptData.d.ts new file mode 100644 index 0000000..b4e604a --- /dev/null +++ b/packages/util-crypto/cjs/json/decryptData.d.ts @@ -0,0 +1,2 @@ +import type { EncryptedJsonEncoding } from './types.js'; +export declare function jsonDecryptData(encrypted?: Uint8Array | null, passphrase?: string | null, encType?: EncryptedJsonEncoding[]): Uint8Array; diff --git a/packages/util-crypto/cjs/json/decryptData.js b/packages/util-crypto/cjs/json/decryptData.js new file mode 100644 index 0000000..3910411 --- /dev/null +++ b/packages/util-crypto/cjs/json/decryptData.js @@ -0,0 +1,32 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.jsonDecryptData = jsonDecryptData; +const util_1 = require("@pezkuwi/util"); +const index_js_1 = require("../nacl/index.js"); +const index_js_2 = require("../scrypt/index.js"); +const constants_js_1 = require("./constants.js"); +function jsonDecryptData(encrypted, passphrase, encType = constants_js_1.ENCODING) { + if (!encrypted) { + throw new Error('No encrypted data available to decode'); + } + else if (encType.includes('xsalsa20-poly1305') && !passphrase) { + throw new Error('Password required to decode encrypted data'); + } + let encoded = encrypted; + if (passphrase) { + let password; + if (encType.includes('scrypt')) { + const { params, salt } = (0, index_js_2.scryptFromU8a)(encrypted); + password = (0, index_js_2.scryptEncode)(passphrase, salt, params).password; + encrypted = encrypted.subarray(constants_js_1.SCRYPT_LENGTH); + } + else { + password = (0, util_1.stringToU8a)(passphrase); + } + encoded = (0, index_js_1.naclDecrypt)(encrypted.subarray(constants_js_1.NONCE_LENGTH), encrypted.subarray(0, constants_js_1.NONCE_LENGTH), (0, util_1.u8aFixLength)(password, 256, true)); + } + if (!encoded) { + throw new Error('Unable to decode using the supplied passphrase'); + } + return encoded; +} diff --git a/packages/util-crypto/cjs/json/encrypt.d.ts b/packages/util-crypto/cjs/json/encrypt.d.ts new file mode 100644 index 0000000..b98b235 --- /dev/null +++ b/packages/util-crypto/cjs/json/encrypt.d.ts @@ -0,0 +1,2 @@ +import type { EncryptedJson } from './types.js'; +export declare function jsonEncrypt(data: Uint8Array, contentType: string[], passphrase?: string | null): EncryptedJson; diff --git a/packages/util-crypto/cjs/json/encrypt.js b/packages/util-crypto/cjs/json/encrypt.js new file mode 100644 index 0000000..e8ff9e5 --- /dev/null +++ b/packages/util-crypto/cjs/json/encrypt.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.jsonEncrypt = jsonEncrypt; +const util_1 = require("@pezkuwi/util"); +const index_js_1 = require("../nacl/index.js"); +const index_js_2 = require("../scrypt/index.js"); +const encryptFormat_js_1 = require("./encryptFormat.js"); +function jsonEncrypt(data, contentType, passphrase) { + let isEncrypted = false; + let encoded = data; + if (passphrase) { + const { params, password, salt } = (0, index_js_2.scryptEncode)(passphrase); + const { encrypted, nonce } = (0, index_js_1.naclEncrypt)(encoded, password.subarray(0, 32)); + isEncrypted = true; + encoded = (0, util_1.u8aConcat)((0, index_js_2.scryptToU8a)(salt, params), nonce, encrypted); + } + return (0, encryptFormat_js_1.jsonEncryptFormat)(encoded, contentType, isEncrypted); +} diff --git a/packages/util-crypto/cjs/json/encryptFormat.d.ts b/packages/util-crypto/cjs/json/encryptFormat.d.ts new file mode 100644 index 0000000..468ea4a --- /dev/null +++ b/packages/util-crypto/cjs/json/encryptFormat.d.ts @@ -0,0 +1,2 @@ +import type { EncryptedJson } from './types.js'; +export declare function jsonEncryptFormat(encoded: Uint8Array, contentType: string[], isEncrypted: boolean): EncryptedJson; diff --git a/packages/util-crypto/cjs/json/encryptFormat.js b/packages/util-crypto/cjs/json/encryptFormat.js new file mode 100644 index 0000000..c24d527 --- /dev/null +++ b/packages/util-crypto/cjs/json/encryptFormat.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.jsonEncryptFormat = jsonEncryptFormat; +const index_js_1 = require("../base64/index.js"); +const constants_js_1 = require("./constants.js"); +function jsonEncryptFormat(encoded, contentType, isEncrypted) { + return { + encoded: (0, index_js_1.base64Encode)(encoded), + encoding: { + content: contentType, + type: isEncrypted + ? constants_js_1.ENCODING + : constants_js_1.ENCODING_NONE, + version: constants_js_1.ENCODING_VERSION + } + }; +} diff --git a/packages/util-crypto/cjs/json/index.d.ts b/packages/util-crypto/cjs/json/index.d.ts new file mode 100644 index 0000000..a4c694b --- /dev/null +++ b/packages/util-crypto/cjs/json/index.d.ts @@ -0,0 +1,4 @@ +export { jsonDecrypt } from './decrypt.js'; +export { jsonDecryptData } from './decryptData.js'; +export { jsonEncrypt } from './encrypt.js'; +export { jsonEncryptFormat } from './encryptFormat.js'; diff --git a/packages/util-crypto/cjs/json/index.js b/packages/util-crypto/cjs/json/index.js new file mode 100644 index 0000000..efc776f --- /dev/null +++ b/packages/util-crypto/cjs/json/index.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.jsonEncryptFormat = exports.jsonEncrypt = exports.jsonDecryptData = exports.jsonDecrypt = void 0; +var decrypt_js_1 = require("./decrypt.js"); +Object.defineProperty(exports, "jsonDecrypt", { enumerable: true, get: function () { return decrypt_js_1.jsonDecrypt; } }); +var decryptData_js_1 = require("./decryptData.js"); +Object.defineProperty(exports, "jsonDecryptData", { enumerable: true, get: function () { return decryptData_js_1.jsonDecryptData; } }); +var encrypt_js_1 = require("./encrypt.js"); +Object.defineProperty(exports, "jsonEncrypt", { enumerable: true, get: function () { return encrypt_js_1.jsonEncrypt; } }); +var encryptFormat_js_1 = require("./encryptFormat.js"); +Object.defineProperty(exports, "jsonEncryptFormat", { enumerable: true, get: function () { return encryptFormat_js_1.jsonEncryptFormat; } }); diff --git a/packages/util-crypto/cjs/json/types.d.ts b/packages/util-crypto/cjs/json/types.d.ts new file mode 100644 index 0000000..cb4b881 --- /dev/null +++ b/packages/util-crypto/cjs/json/types.d.ts @@ -0,0 +1,16 @@ +export type EncryptedJsonVersion = '0' | '1' | '2' | '3'; +export type EncryptedJsonEncoding = 'none' | 'scrypt' | 'xsalsa20-poly1305'; +export interface EncryptedJsonDescriptor { + /** Descriptor for the content */ + content: string[]; + /** The encoding (in current/latest versions this is always an array) */ + type: EncryptedJsonEncoding | EncryptedJsonEncoding[]; + /** The version of encoding applied */ + version: EncryptedJsonVersion; +} +export interface EncryptedJson { + /** The encoded string */ + encoded: string; + /** The encoding used */ + encoding: EncryptedJsonDescriptor; +} diff --git a/packages/util-crypto/cjs/json/types.js b/packages/util-crypto/cjs/json/types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/packages/util-crypto/cjs/json/types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/packages/util-crypto/cjs/keccak/asU8a.d.ts b/packages/util-crypto/cjs/keccak/asU8a.d.ts new file mode 100644 index 0000000..3c4e1b5 --- /dev/null +++ b/packages/util-crypto/cjs/keccak/asU8a.d.ts @@ -0,0 +1,30 @@ +/** + * @name keccakAsU8a + * @summary Creates a keccak Uint8Array from the input. + * @description + * From either a `string` or a `Buffer` input, create the keccak and return the result as a `Uint8Array`. + * @example + *
+ * + * ```javascript + * import { keccakAsU8a } from '@pezkuwi/util-crypto'; + * + * keccakAsU8a('123'); // => Uint8Array + * ``` + */ +export declare const keccakAsU8a: (value: string | Uint8Array, bitLength?: 256 | 512, onlyJs?: boolean) => Uint8Array; +/** + * @name keccak256AsU8a + * @description Creates a keccak256 Uint8Array from the input. + */ +export declare const keccak256AsU8a: (data: string | Uint8Array, onlyJs?: boolean) => Uint8Array; +/** + * @name keccak512AsU8a + * @description Creates a keccak512 Uint8Array from the input. + */ +export declare const keccak512AsU8a: (data: string | Uint8Array, onlyJs?: boolean) => Uint8Array; +/** + * @name keccakAsHex + * @description Creates a keccak hex string from the input. + */ +export declare const keccakAsHex: (value: string | Uint8Array, bitLength?: 256 | 512 | undefined, onlyJs?: boolean | undefined) => import("@pezkuwi/util/types").HexString; diff --git a/packages/util-crypto/cjs/keccak/asU8a.js b/packages/util-crypto/cjs/keccak/asU8a.js new file mode 100644 index 0000000..ef48e28 --- /dev/null +++ b/packages/util-crypto/cjs/keccak/asU8a.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.keccakAsHex = exports.keccak512AsU8a = exports.keccak256AsU8a = exports.keccakAsU8a = void 0; +const sha3_1 = require("@noble/hashes/sha3"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +const helpers_js_1 = require("../helpers.js"); +/** + * @name keccakAsU8a + * @summary Creates a keccak Uint8Array from the input. + * @description + * From either a `string` or a `Buffer` input, create the keccak and return the result as a `Uint8Array`. + * @example + *
+ * + * ```javascript + * import { keccakAsU8a } from '@pezkuwi/util-crypto'; + * + * keccakAsU8a('123'); // => Uint8Array + * ``` + */ +exports.keccakAsU8a = (0, helpers_js_1.createDualHasher)({ 256: wasm_crypto_1.keccak256, 512: wasm_crypto_1.keccak512 }, { 256: sha3_1.keccak_256, 512: sha3_1.keccak_512 }); +/** + * @name keccak256AsU8a + * @description Creates a keccak256 Uint8Array from the input. + */ +exports.keccak256AsU8a = (0, helpers_js_1.createBitHasher)(256, exports.keccakAsU8a); +/** + * @name keccak512AsU8a + * @description Creates a keccak512 Uint8Array from the input. + */ +exports.keccak512AsU8a = (0, helpers_js_1.createBitHasher)(512, exports.keccakAsU8a); +/** + * @name keccakAsHex + * @description Creates a keccak hex string from the input. + */ +exports.keccakAsHex = (0, helpers_js_1.createAsHex)(exports.keccakAsU8a); diff --git a/packages/util-crypto/cjs/keccak/index.d.ts b/packages/util-crypto/cjs/keccak/index.d.ts new file mode 100644 index 0000000..ad1f759 --- /dev/null +++ b/packages/util-crypto/cjs/keccak/index.d.ts @@ -0,0 +1,4 @@ +/** + * @summary Create Keccak256/512 values as hex & Uint8Array output + */ +export { keccak256AsU8a, keccak512AsU8a, keccakAsHex, keccakAsU8a } from './asU8a.js'; diff --git a/packages/util-crypto/cjs/keccak/index.js b/packages/util-crypto/cjs/keccak/index.js new file mode 100644 index 0000000..b1d0162 --- /dev/null +++ b/packages/util-crypto/cjs/keccak/index.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.keccakAsU8a = exports.keccakAsHex = exports.keccak512AsU8a = exports.keccak256AsU8a = void 0; +/** + * @summary Create Keccak256/512 values as hex & Uint8Array output + */ +var asU8a_js_1 = require("./asU8a.js"); +Object.defineProperty(exports, "keccak256AsU8a", { enumerable: true, get: function () { return asU8a_js_1.keccak256AsU8a; } }); +Object.defineProperty(exports, "keccak512AsU8a", { enumerable: true, get: function () { return asU8a_js_1.keccak512AsU8a; } }); +Object.defineProperty(exports, "keccakAsHex", { enumerable: true, get: function () { return asU8a_js_1.keccakAsHex; } }); +Object.defineProperty(exports, "keccakAsU8a", { enumerable: true, get: function () { return asU8a_js_1.keccakAsU8a; } }); diff --git a/packages/util-crypto/cjs/key/DeriveJunction.d.ts b/packages/util-crypto/cjs/key/DeriveJunction.d.ts new file mode 100644 index 0000000..652aaef --- /dev/null +++ b/packages/util-crypto/cjs/key/DeriveJunction.d.ts @@ -0,0 +1,12 @@ +import { BN } from '@pezkuwi/util'; +export declare class DeriveJunction { + #private; + static from(value: string): DeriveJunction; + get chainCode(): Uint8Array; + get isHard(): boolean; + get isSoft(): boolean; + hard(value: number | string | bigint | BN | Uint8Array): DeriveJunction; + harden(): DeriveJunction; + soft(value: number | string | bigint | BN | Uint8Array): DeriveJunction; + soften(): DeriveJunction; +} diff --git a/packages/util-crypto/cjs/key/DeriveJunction.js b/packages/util-crypto/cjs/key/DeriveJunction.js new file mode 100644 index 0000000..6eaf1e8 --- /dev/null +++ b/packages/util-crypto/cjs/key/DeriveJunction.js @@ -0,0 +1,62 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DeriveJunction = void 0; +const util_1 = require("@pezkuwi/util"); +const asU8a_js_1 = require("../blake2/asU8a.js"); +const bn_js_1 = require("../bn.js"); +const RE_NUMBER = /^\d+$/; +const JUNCTION_ID_LEN = 32; +class DeriveJunction { + #chainCode = new Uint8Array(32); + #isHard = false; + static from(value) { + const result = new DeriveJunction(); + const [code, isHard] = value.startsWith('/') + ? [value.substring(1), true] + : [value, false]; + result.soft(RE_NUMBER.test(code) + ? new util_1.BN(code, 10) + : code); + return isHard + ? result.harden() + : result; + } + get chainCode() { + return this.#chainCode; + } + get isHard() { + return this.#isHard; + } + get isSoft() { + return !this.#isHard; + } + hard(value) { + return this.soft(value).harden(); + } + harden() { + this.#isHard = true; + return this; + } + soft(value) { + if ((0, util_1.isNumber)(value) || (0, util_1.isBn)(value) || (0, util_1.isBigInt)(value)) { + return this.soft((0, util_1.bnToU8a)(value, bn_js_1.BN_LE_256_OPTS)); + } + else if ((0, util_1.isHex)(value)) { + return this.soft((0, util_1.hexToU8a)(value)); + } + else if ((0, util_1.isString)(value)) { + return this.soft((0, util_1.compactAddLength)((0, util_1.stringToU8a)(value))); + } + else if (value.length > JUNCTION_ID_LEN) { + return this.soft((0, asU8a_js_1.blake2AsU8a)(value)); + } + this.#chainCode.fill(0); + this.#chainCode.set(value, 0); + return this; + } + soften() { + this.#isHard = false; + return this; + } +} +exports.DeriveJunction = DeriveJunction; diff --git a/packages/util-crypto/cjs/key/extractPath.d.ts b/packages/util-crypto/cjs/key/extractPath.d.ts new file mode 100644 index 0000000..c50a96d --- /dev/null +++ b/packages/util-crypto/cjs/key/extractPath.d.ts @@ -0,0 +1,9 @@ +import { DeriveJunction } from './DeriveJunction.js'; +export interface ExtractResult { + parts: string[] | null; + path: DeriveJunction[]; +} +/** + * @description Extract derivation junctions from the supplied path + */ +export declare function keyExtractPath(derivePath: string): ExtractResult; diff --git a/packages/util-crypto/cjs/key/extractPath.js b/packages/util-crypto/cjs/key/extractPath.js new file mode 100644 index 0000000..759739c --- /dev/null +++ b/packages/util-crypto/cjs/key/extractPath.js @@ -0,0 +1,26 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.keyExtractPath = keyExtractPath; +const DeriveJunction_js_1 = require("./DeriveJunction.js"); +const RE_JUNCTION = /\/(\/?)([^/]+)/g; +/** + * @description Extract derivation junctions from the supplied path + */ +function keyExtractPath(derivePath) { + const parts = derivePath.match(RE_JUNCTION); + const path = []; + let constructed = ''; + if (parts) { + constructed = parts.join(''); + for (const p of parts) { + path.push(DeriveJunction_js_1.DeriveJunction.from(p.substring(1))); + } + } + if (constructed !== derivePath) { + throw new Error(`Re-constructed path "${constructed}" does not match input`); + } + return { + parts, + path + }; +} diff --git a/packages/util-crypto/cjs/key/extractSuri.d.ts b/packages/util-crypto/cjs/key/extractSuri.d.ts new file mode 100644 index 0000000..1959e50 --- /dev/null +++ b/packages/util-crypto/cjs/key/extractSuri.d.ts @@ -0,0 +1,11 @@ +import type { DeriveJunction } from './DeriveJunction.js'; +export interface ExtractResult { + derivePath: string; + password?: string; + path: DeriveJunction[]; + phrase: string; +} +/** + * @description Extracts the phrase, path and password from a SURI format for specifying secret keys `//////` (the `///password` may be omitted, and `/` and `//` maybe repeated and mixed). + */ +export declare function keyExtractSuri(suri: string): ExtractResult; diff --git a/packages/util-crypto/cjs/key/extractSuri.js b/packages/util-crypto/cjs/key/extractSuri.js new file mode 100644 index 0000000..5f452c9 --- /dev/null +++ b/packages/util-crypto/cjs/key/extractSuri.js @@ -0,0 +1,25 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.keyExtractSuri = keyExtractSuri; +const extractPath_js_1 = require("./extractPath.js"); +const RE_CAPTURE = /^((0x[a-fA-F0-9]+|[\p{L}\d]+(?: [\p{L}\d]+)*))((\/\/?[^/]+)*)(\/\/\/(.*))?$/u; +/** + * @description Extracts the phrase, path and password from a SURI format for specifying secret keys `//////` (the `///password` may be omitted, and `/` and `//` maybe repeated and mixed). + */ +function keyExtractSuri(suri) { + // Normalize Unicode to NFC to avoid accent-related mismatches + const normalizedSuri = suri.normalize('NFC'); + // eslint-disable-next-line @typescript-eslint/prefer-regexp-exec + const matches = normalizedSuri.match(RE_CAPTURE); + if (matches === null) { + throw new Error('Unable to match provided value to a secret URI'); + } + const [, phrase, , derivePath, , , password] = matches; + const { path } = (0, extractPath_js_1.keyExtractPath)(derivePath); + return { + derivePath, + password, + path, + phrase + }; +} diff --git a/packages/util-crypto/cjs/key/fromPath.d.ts b/packages/util-crypto/cjs/key/fromPath.d.ts new file mode 100644 index 0000000..c19bc98 --- /dev/null +++ b/packages/util-crypto/cjs/key/fromPath.d.ts @@ -0,0 +1,3 @@ +import type { Keypair, KeypairType } from '../types.js'; +import type { DeriveJunction } from './DeriveJunction.js'; +export declare function keyFromPath(pair: Keypair, path: DeriveJunction[], type: KeypairType): Keypair; diff --git a/packages/util-crypto/cjs/key/fromPath.js b/packages/util-crypto/cjs/key/fromPath.js new file mode 100644 index 0000000..ccd677e --- /dev/null +++ b/packages/util-crypto/cjs/key/fromPath.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.keyFromPath = keyFromPath; +const hdkdEcdsa_js_1 = require("./hdkdEcdsa.js"); +const hdkdEd25519_js_1 = require("./hdkdEd25519.js"); +const hdkdSr25519_js_1 = require("./hdkdSr25519.js"); +const generators = { + ecdsa: hdkdEcdsa_js_1.keyHdkdEcdsa, + ed25519: hdkdEd25519_js_1.keyHdkdEd25519, + // FIXME This is Substrate-compatible, not Ethereum-compatible + ethereum: hdkdEcdsa_js_1.keyHdkdEcdsa, + sr25519: hdkdSr25519_js_1.keyHdkdSr25519 +}; +function keyFromPath(pair, path, type) { + const keyHdkd = generators[type]; + let result = pair; + for (const junction of path) { + result = keyHdkd(result, junction); + } + return result; +} diff --git a/packages/util-crypto/cjs/key/hdkdDerive.d.ts b/packages/util-crypto/cjs/key/hdkdDerive.d.ts new file mode 100644 index 0000000..999db52 --- /dev/null +++ b/packages/util-crypto/cjs/key/hdkdDerive.d.ts @@ -0,0 +1,3 @@ +import type { Keypair } from '../types.js'; +import type { DeriveJunction } from './DeriveJunction.js'; +export declare function createSeedDeriveFn(fromSeed: (seed: Uint8Array) => Keypair, derive: (seed: Uint8Array, chainCode: Uint8Array) => Uint8Array): (keypair: Keypair, junction: DeriveJunction) => Keypair; diff --git a/packages/util-crypto/cjs/key/hdkdDerive.js b/packages/util-crypto/cjs/key/hdkdDerive.js new file mode 100644 index 0000000..35aa005 --- /dev/null +++ b/packages/util-crypto/cjs/key/hdkdDerive.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createSeedDeriveFn = createSeedDeriveFn; +function createSeedDeriveFn(fromSeed, derive) { + return (keypair, { chainCode, isHard }) => { + if (!isHard) { + throw new Error('A soft key was found in the path and is not supported'); + } + return fromSeed(derive(keypair.secretKey.subarray(0, 32), chainCode)); + }; +} diff --git a/packages/util-crypto/cjs/key/hdkdEcdsa.d.ts b/packages/util-crypto/cjs/key/hdkdEcdsa.d.ts new file mode 100644 index 0000000..941fd88 --- /dev/null +++ b/packages/util-crypto/cjs/key/hdkdEcdsa.d.ts @@ -0,0 +1 @@ +export declare const keyHdkdEcdsa: (keypair: import("../types.js").Keypair, junction: import("./DeriveJunction.js").DeriveJunction) => import("../types.js").Keypair; diff --git a/packages/util-crypto/cjs/key/hdkdEcdsa.js b/packages/util-crypto/cjs/key/hdkdEcdsa.js new file mode 100644 index 0000000..8ba72b8 --- /dev/null +++ b/packages/util-crypto/cjs/key/hdkdEcdsa.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.keyHdkdEcdsa = void 0; +const deriveHard_js_1 = require("../secp256k1/deriveHard.js"); +const fromSeed_js_1 = require("../secp256k1/pair/fromSeed.js"); +const hdkdDerive_js_1 = require("./hdkdDerive.js"); +exports.keyHdkdEcdsa = (0, hdkdDerive_js_1.createSeedDeriveFn)(fromSeed_js_1.secp256k1PairFromSeed, deriveHard_js_1.secp256k1DeriveHard); diff --git a/packages/util-crypto/cjs/key/hdkdEd25519.d.ts b/packages/util-crypto/cjs/key/hdkdEd25519.d.ts new file mode 100644 index 0000000..987fe0f --- /dev/null +++ b/packages/util-crypto/cjs/key/hdkdEd25519.d.ts @@ -0,0 +1 @@ +export declare const keyHdkdEd25519: (keypair: import("../types.js").Keypair, junction: import("./DeriveJunction.js").DeriveJunction) => import("../types.js").Keypair; diff --git a/packages/util-crypto/cjs/key/hdkdEd25519.js b/packages/util-crypto/cjs/key/hdkdEd25519.js new file mode 100644 index 0000000..0107eae --- /dev/null +++ b/packages/util-crypto/cjs/key/hdkdEd25519.js @@ -0,0 +1,6 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.keyHdkdEd25519 = void 0; +const index_js_1 = require("../ed25519/index.js"); +const hdkdDerive_js_1 = require("./hdkdDerive.js"); +exports.keyHdkdEd25519 = (0, hdkdDerive_js_1.createSeedDeriveFn)(index_js_1.ed25519PairFromSeed, index_js_1.ed25519DeriveHard); diff --git a/packages/util-crypto/cjs/key/hdkdSr25519.d.ts b/packages/util-crypto/cjs/key/hdkdSr25519.d.ts new file mode 100644 index 0000000..76e5460 --- /dev/null +++ b/packages/util-crypto/cjs/key/hdkdSr25519.d.ts @@ -0,0 +1,3 @@ +import type { Keypair } from '../types.js'; +import type { DeriveJunction } from './DeriveJunction.js'; +export declare function keyHdkdSr25519(keypair: Keypair, { chainCode, isSoft }: DeriveJunction): Keypair; diff --git a/packages/util-crypto/cjs/key/hdkdSr25519.js b/packages/util-crypto/cjs/key/hdkdSr25519.js new file mode 100644 index 0000000..76a81aa --- /dev/null +++ b/packages/util-crypto/cjs/key/hdkdSr25519.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.keyHdkdSr25519 = keyHdkdSr25519; +const deriveHard_js_1 = require("../sr25519/deriveHard.js"); +const deriveSoft_js_1 = require("../sr25519/deriveSoft.js"); +function keyHdkdSr25519(keypair, { chainCode, isSoft }) { + return isSoft + ? (0, deriveSoft_js_1.sr25519DeriveSoft)(keypair, chainCode) + : (0, deriveHard_js_1.sr25519DeriveHard)(keypair, chainCode); +} diff --git a/packages/util-crypto/cjs/key/index.d.ts b/packages/util-crypto/cjs/key/index.d.ts new file mode 100644 index 0000000..b9f8fef --- /dev/null +++ b/packages/util-crypto/cjs/key/index.d.ts @@ -0,0 +1,9 @@ +/** + * @summary Create keys from paths, seeds and password + */ +export { keyExtractPath } from './extractPath.js'; +export { keyExtractSuri } from './extractSuri.js'; +export { keyFromPath } from './fromPath.js'; +export { keyHdkdEcdsa } from './hdkdEcdsa.js'; +export { keyHdkdEd25519 } from './hdkdEd25519.js'; +export { keyHdkdSr25519 } from './hdkdSr25519.js'; diff --git a/packages/util-crypto/cjs/key/index.js b/packages/util-crypto/cjs/key/index.js new file mode 100644 index 0000000..5b4a97b --- /dev/null +++ b/packages/util-crypto/cjs/key/index.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.keyHdkdSr25519 = exports.keyHdkdEd25519 = exports.keyHdkdEcdsa = exports.keyFromPath = exports.keyExtractSuri = exports.keyExtractPath = void 0; +/** + * @summary Create keys from paths, seeds and password + */ +var extractPath_js_1 = require("./extractPath.js"); +Object.defineProperty(exports, "keyExtractPath", { enumerable: true, get: function () { return extractPath_js_1.keyExtractPath; } }); +var extractSuri_js_1 = require("./extractSuri.js"); +Object.defineProperty(exports, "keyExtractSuri", { enumerable: true, get: function () { return extractSuri_js_1.keyExtractSuri; } }); +var fromPath_js_1 = require("./fromPath.js"); +Object.defineProperty(exports, "keyFromPath", { enumerable: true, get: function () { return fromPath_js_1.keyFromPath; } }); +var hdkdEcdsa_js_1 = require("./hdkdEcdsa.js"); +Object.defineProperty(exports, "keyHdkdEcdsa", { enumerable: true, get: function () { return hdkdEcdsa_js_1.keyHdkdEcdsa; } }); +var hdkdEd25519_js_1 = require("./hdkdEd25519.js"); +Object.defineProperty(exports, "keyHdkdEd25519", { enumerable: true, get: function () { return hdkdEd25519_js_1.keyHdkdEd25519; } }); +var hdkdSr25519_js_1 = require("./hdkdSr25519.js"); +Object.defineProperty(exports, "keyHdkdSr25519", { enumerable: true, get: function () { return hdkdSr25519_js_1.keyHdkdSr25519; } }); diff --git a/packages/util-crypto/cjs/mnemonic/bip39.d.ts b/packages/util-crypto/cjs/mnemonic/bip39.d.ts new file mode 100644 index 0000000..7954450 --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/bip39.d.ts @@ -0,0 +1,5 @@ +export declare function mnemonicToSeedSync(mnemonic: string, password?: string): Uint8Array; +export declare function mnemonicToEntropy(mnemonic: string, wordlist?: string[]): Uint8Array; +export declare function entropyToMnemonic(entropy: Uint8Array, wordlist?: string[]): string; +export declare function generateMnemonic(numWords: 12 | 15 | 18 | 21 | 24, wordlist?: string[]): string; +export declare function validateMnemonic(mnemonic: string, wordlist?: string[]): boolean; diff --git a/packages/util-crypto/cjs/mnemonic/bip39.js b/packages/util-crypto/cjs/mnemonic/bip39.js new file mode 100644 index 0000000..3692b8a --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/bip39.js @@ -0,0 +1,90 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.mnemonicToSeedSync = mnemonicToSeedSync; +exports.mnemonicToEntropy = mnemonicToEntropy; +exports.entropyToMnemonic = entropyToMnemonic; +exports.generateMnemonic = generateMnemonic; +exports.validateMnemonic = validateMnemonic; +const tslib_1 = require("tslib"); +const util_1 = require("@pezkuwi/util"); +const index_js_1 = require("../pbkdf2/index.js"); +const index_js_2 = require("../random/index.js"); +const index_js_3 = require("../sha/index.js"); +const en_js_1 = tslib_1.__importDefault(require("./wordlists/en.js")); +const INVALID_MNEMONIC = 'Invalid mnemonic'; +const INVALID_ENTROPY = 'Invalid entropy'; +const INVALID_CHECKSUM = 'Invalid mnemonic checksum'; +/** @internal */ +function normalize(str) { + return (str || '').normalize('NFKD'); +} +/** @internal */ +function binaryToByte(bin) { + return parseInt(bin, 2); +} +/** @internal */ +function bytesToBinary(bytes) { + return bytes.map((x) => x.toString(2).padStart(8, '0')).join(''); +} +/** @internal */ +function deriveChecksumBits(entropyBuffer) { + return bytesToBinary(Array.from((0, index_js_3.sha256AsU8a)(entropyBuffer))).slice(0, (entropyBuffer.length * 8) / 32); +} +function mnemonicToSeedSync(mnemonic, password) { + return (0, index_js_1.pbkdf2Encode)((0, util_1.stringToU8a)(normalize(mnemonic)), (0, util_1.stringToU8a)(`mnemonic${normalize(password)}`)).password; +} +function mnemonicToEntropy(mnemonic, wordlist = en_js_1.default) { + const words = normalize(mnemonic).split(' '); + if (words.length % 3 !== 0) { + throw new Error(INVALID_MNEMONIC); + } + // convert word indices to 11 bit binary strings + const bits = words + .map((word) => { + const index = wordlist.indexOf(word); + if (index === -1) { + throw new Error(INVALID_MNEMONIC); + } + return index.toString(2).padStart(11, '0'); + }) + .join(''); + // split the binary string into ENT/CS + const dividerIndex = Math.floor(bits.length / 33) * 32; + const entropyBits = bits.slice(0, dividerIndex); + const checksumBits = bits.slice(dividerIndex); + // calculate the checksum and compare + const matched = entropyBits.match(/(.{1,8})/g); + const entropyBytes = matched?.map(binaryToByte); + if (!entropyBytes || (entropyBytes.length % 4 !== 0) || (entropyBytes.length < 16) || (entropyBytes.length > 32)) { + throw new Error(INVALID_ENTROPY); + } + const entropy = (0, util_1.u8aToU8a)(entropyBytes); + if (deriveChecksumBits(entropy) !== checksumBits) { + throw new Error(INVALID_CHECKSUM); + } + return entropy; +} +function entropyToMnemonic(entropy, wordlist = en_js_1.default) { + // 128 <= ENT <= 256 + if ((entropy.length % 4 !== 0) || (entropy.length < 16) || (entropy.length > 32)) { + throw new Error(INVALID_ENTROPY); + } + const matched = `${bytesToBinary(Array.from(entropy))}${deriveChecksumBits(entropy)}`.match(/(.{1,11})/g); + const mapped = matched?.map((b) => wordlist[binaryToByte(b)]); + if (!mapped || (mapped.length < 12)) { + throw new Error('Unable to map entropy to mnemonic'); + } + return mapped.join(' '); +} +function generateMnemonic(numWords, wordlist) { + return entropyToMnemonic((0, index_js_2.randomAsU8a)((numWords / 3) * 4), wordlist); +} +function validateMnemonic(mnemonic, wordlist) { + try { + mnemonicToEntropy(mnemonic, wordlist); + } + catch { + return false; + } + return true; +} diff --git a/packages/util-crypto/cjs/mnemonic/generate.d.ts b/packages/util-crypto/cjs/mnemonic/generate.d.ts new file mode 100644 index 0000000..6e9646e --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/generate.d.ts @@ -0,0 +1,13 @@ +/** + * @name mnemonicGenerate + * @summary Creates a valid mnemonic string using using [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki). + * @example + *
+ * + * ```javascript + * import { mnemonicGenerate } from '@pezkuwi/util-crypto'; + * + * const mnemonic = mnemonicGenerate(); // => string + * ``` + */ +export declare function mnemonicGenerate(numWords?: 12 | 15 | 18 | 21 | 24, wordlist?: string[], onlyJs?: boolean): string; diff --git a/packages/util-crypto/cjs/mnemonic/generate.js b/packages/util-crypto/cjs/mnemonic/generate.js new file mode 100644 index 0000000..20c4623 --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/generate.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.mnemonicGenerate = mnemonicGenerate; +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +const bip39_js_1 = require("./bip39.js"); +/** + * @name mnemonicGenerate + * @summary Creates a valid mnemonic string using using [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki). + * @example + *
+ * + * ```javascript + * import { mnemonicGenerate } from '@pezkuwi/util-crypto'; + * + * const mnemonic = mnemonicGenerate(); // => string + * ``` + */ +function mnemonicGenerate(numWords = 12, wordlist, onlyJs) { + return !util_1.hasBigInt || (!wordlist && !onlyJs && (0, wasm_crypto_1.isReady)()) + ? (0, wasm_crypto_1.bip39Generate)(numWords) + : (0, bip39_js_1.generateMnemonic)(numWords, wordlist); +} diff --git a/packages/util-crypto/cjs/mnemonic/index.d.ts b/packages/util-crypto/cjs/mnemonic/index.d.ts new file mode 100644 index 0000000..8cbbc5b --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/index.d.ts @@ -0,0 +1,8 @@ +/** + * @summary Create valid mnemonic strings, validate them using BIP39, and convert them to valid seeds + */ +export { mnemonicGenerate } from './generate.js'; +export { mnemonicToEntropy } from './toEntropy.js'; +export { mnemonicToLegacySeed } from './toLegacySeed.js'; +export { mnemonicToMiniSecret } from './toMiniSecret.js'; +export { mnemonicValidate } from './validate.js'; diff --git a/packages/util-crypto/cjs/mnemonic/index.js b/packages/util-crypto/cjs/mnemonic/index.js new file mode 100644 index 0000000..7c6fea2 --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/index.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.mnemonicValidate = exports.mnemonicToMiniSecret = exports.mnemonicToLegacySeed = exports.mnemonicToEntropy = exports.mnemonicGenerate = void 0; +/** + * @summary Create valid mnemonic strings, validate them using BIP39, and convert them to valid seeds + */ +var generate_js_1 = require("./generate.js"); +Object.defineProperty(exports, "mnemonicGenerate", { enumerable: true, get: function () { return generate_js_1.mnemonicGenerate; } }); +var toEntropy_js_1 = require("./toEntropy.js"); +Object.defineProperty(exports, "mnemonicToEntropy", { enumerable: true, get: function () { return toEntropy_js_1.mnemonicToEntropy; } }); +var toLegacySeed_js_1 = require("./toLegacySeed.js"); +Object.defineProperty(exports, "mnemonicToLegacySeed", { enumerable: true, get: function () { return toLegacySeed_js_1.mnemonicToLegacySeed; } }); +var toMiniSecret_js_1 = require("./toMiniSecret.js"); +Object.defineProperty(exports, "mnemonicToMiniSecret", { enumerable: true, get: function () { return toMiniSecret_js_1.mnemonicToMiniSecret; } }); +var validate_js_1 = require("./validate.js"); +Object.defineProperty(exports, "mnemonicValidate", { enumerable: true, get: function () { return validate_js_1.mnemonicValidate; } }); diff --git a/packages/util-crypto/cjs/mnemonic/toEntropy.d.ts b/packages/util-crypto/cjs/mnemonic/toEntropy.d.ts new file mode 100644 index 0000000..d3c7af5 --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/toEntropy.d.ts @@ -0,0 +1 @@ +export declare function mnemonicToEntropy(mnemonic: string, wordlist?: string[], onlyJs?: boolean): Uint8Array; diff --git a/packages/util-crypto/cjs/mnemonic/toEntropy.js b/packages/util-crypto/cjs/mnemonic/toEntropy.js new file mode 100644 index 0000000..9880dfc --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/toEntropy.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.mnemonicToEntropy = mnemonicToEntropy; +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +const bip39_js_1 = require("./bip39.js"); +function mnemonicToEntropy(mnemonic, wordlist, onlyJs) { + return !util_1.hasBigInt || (!wordlist && !onlyJs && (0, wasm_crypto_1.isReady)()) + ? (0, wasm_crypto_1.bip39ToEntropy)(mnemonic) + : (0, bip39_js_1.mnemonicToEntropy)(mnemonic, wordlist); +} diff --git a/packages/util-crypto/cjs/mnemonic/toLegacySeed.d.ts b/packages/util-crypto/cjs/mnemonic/toLegacySeed.d.ts new file mode 100644 index 0000000..8b3ddec --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/toLegacySeed.d.ts @@ -0,0 +1,18 @@ +/** + * @name mnemonicToLegacySeed + * @summary Creates a valid Ethereum/Bitcoin-compatible seed from a mnemonic input + * @example + *
+ * + * ```javascript + * import { mnemonicGenerate, mnemonicToLegacySeed, mnemonicValidate } from '@pezkuwi/util-crypto'; + * + * const mnemonic = mnemonicGenerate(); // => string + * const isValidMnemonic = mnemonicValidate(mnemonic); // => boolean + * + * if (isValidMnemonic) { + * console.log(`Seed generated from mnemonic: ${mnemonicToLegacySeed(mnemonic)}`); => u8a + * } + * ``` + */ +export declare function mnemonicToLegacySeed(mnemonic: string, password?: string, onlyJs?: boolean, byteLength?: 32 | 64): Uint8Array; diff --git a/packages/util-crypto/cjs/mnemonic/toLegacySeed.js b/packages/util-crypto/cjs/mnemonic/toLegacySeed.js new file mode 100644 index 0000000..88d4dc8 --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/toLegacySeed.js @@ -0,0 +1,37 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.mnemonicToLegacySeed = mnemonicToLegacySeed; +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +const bip39_js_1 = require("./bip39.js"); +const validate_js_1 = require("./validate.js"); +/** + * @name mnemonicToLegacySeed + * @summary Creates a valid Ethereum/Bitcoin-compatible seed from a mnemonic input + * @example + *
+ * + * ```javascript + * import { mnemonicGenerate, mnemonicToLegacySeed, mnemonicValidate } from '@pezkuwi/util-crypto'; + * + * const mnemonic = mnemonicGenerate(); // => string + * const isValidMnemonic = mnemonicValidate(mnemonic); // => boolean + * + * if (isValidMnemonic) { + * console.log(`Seed generated from mnemonic: ${mnemonicToLegacySeed(mnemonic)}`); => u8a + * } + * ``` + */ +function mnemonicToLegacySeed(mnemonic, password = '', onlyJs, byteLength = 32) { + if (!(0, validate_js_1.mnemonicValidate)(mnemonic)) { + throw new Error('Invalid bip39 mnemonic specified'); + } + else if (![32, 64].includes(byteLength)) { + throw new Error(`Invalid seed length ${byteLength}, expected 32 or 64`); + } + return byteLength === 32 + ? !util_1.hasBigInt || (!onlyJs && (0, wasm_crypto_1.isReady)()) + ? (0, wasm_crypto_1.bip39ToSeed)(mnemonic, password) + : (0, bip39_js_1.mnemonicToSeedSync)(mnemonic, password).subarray(0, 32) + : (0, bip39_js_1.mnemonicToSeedSync)(mnemonic, password); +} diff --git a/packages/util-crypto/cjs/mnemonic/toMiniSecret.d.ts b/packages/util-crypto/cjs/mnemonic/toMiniSecret.d.ts new file mode 100644 index 0000000..4b91b32 --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/toMiniSecret.d.ts @@ -0,0 +1 @@ +export declare function mnemonicToMiniSecret(mnemonic: string, password?: string, wordlist?: string[], onlyJs?: boolean): Uint8Array; diff --git a/packages/util-crypto/cjs/mnemonic/toMiniSecret.js b/packages/util-crypto/cjs/mnemonic/toMiniSecret.js new file mode 100644 index 0000000..0196f17 --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/toMiniSecret.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.mnemonicToMiniSecret = mnemonicToMiniSecret; +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +const index_js_1 = require("../pbkdf2/index.js"); +const toEntropy_js_1 = require("./toEntropy.js"); +const validate_js_1 = require("./validate.js"); +function mnemonicToMiniSecret(mnemonic, password = '', wordlist, onlyJs) { + if (!(0, validate_js_1.mnemonicValidate)(mnemonic, wordlist, onlyJs)) { + throw new Error('Invalid bip39 mnemonic specified'); + } + else if (!wordlist && !onlyJs && (0, wasm_crypto_1.isReady)()) { + return (0, wasm_crypto_1.bip39ToMiniSecret)(mnemonic, password); + } + const entropy = (0, toEntropy_js_1.mnemonicToEntropy)(mnemonic, wordlist); + const salt = (0, util_1.stringToU8a)(`mnemonic${password}`); + // return the first 32 bytes as the seed + return (0, index_js_1.pbkdf2Encode)(entropy, salt).password.slice(0, 32); +} diff --git a/packages/util-crypto/cjs/mnemonic/validate.d.ts b/packages/util-crypto/cjs/mnemonic/validate.d.ts new file mode 100644 index 0000000..b647713 --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/validate.d.ts @@ -0,0 +1,14 @@ +/** + * @name mnemonicValidate + * @summary Validates a mnemonic input using [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki). + * @example + *
+ * + * ```javascript + * import { mnemonicGenerate, mnemonicValidate } from '@pezkuwi/util-crypto'; + * + * const mnemonic = mnemonicGenerate(); // => string + * const isValidMnemonic = mnemonicValidate(mnemonic); // => boolean + * ``` + */ +export declare function mnemonicValidate(mnemonic: string, wordlist?: string[], onlyJs?: boolean): boolean; diff --git a/packages/util-crypto/cjs/mnemonic/validate.js b/packages/util-crypto/cjs/mnemonic/validate.js new file mode 100644 index 0000000..ee140c3 --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/validate.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.mnemonicValidate = mnemonicValidate; +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +const bip39_js_1 = require("./bip39.js"); +/** + * @name mnemonicValidate + * @summary Validates a mnemonic input using [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki). + * @example + *
+ * + * ```javascript + * import { mnemonicGenerate, mnemonicValidate } from '@pezkuwi/util-crypto'; + * + * const mnemonic = mnemonicGenerate(); // => string + * const isValidMnemonic = mnemonicValidate(mnemonic); // => boolean + * ``` + */ +function mnemonicValidate(mnemonic, wordlist, onlyJs) { + return !util_1.hasBigInt || (!wordlist && !onlyJs && (0, wasm_crypto_1.isReady)()) + ? (0, wasm_crypto_1.bip39Validate)(mnemonic) + : (0, bip39_js_1.validateMnemonic)(mnemonic, wordlist); +} diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/en.d.ts b/packages/util-crypto/cjs/mnemonic/wordlists/en.d.ts new file mode 100644 index 0000000..d451d2b --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/en.d.ts @@ -0,0 +1,2 @@ +declare const _default: string[]; +export default _default; diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/en.js b/packages/util-crypto/cjs/mnemonic/wordlists/en.js new file mode 100644 index 0000000..6a5ee31 --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/en.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = 'abandon|ability|able|about|above|absent|absorb|abstract|absurd|abuse|access|accident|account|accuse|achieve|acid|acoustic|acquire|across|act|action|actor|actress|actual|adapt|add|addict|address|adjust|admit|adult|advance|advice|aerobic|affair|afford|afraid|again|age|agent|agree|ahead|aim|air|airport|aisle|alarm|album|alcohol|alert|alien|all|alley|allow|almost|alone|alpha|already|also|alter|always|amateur|amazing|among|amount|amused|analyst|anchor|ancient|anger|angle|angry|animal|ankle|announce|annual|another|answer|antenna|antique|anxiety|any|apart|apology|appear|apple|approve|april|arch|arctic|area|arena|argue|arm|armed|armor|army|around|arrange|arrest|arrive|arrow|art|artefact|artist|artwork|ask|aspect|assault|asset|assist|assume|asthma|athlete|atom|attack|attend|attitude|attract|auction|audit|august|aunt|author|auto|autumn|average|avocado|avoid|awake|aware|away|awesome|awful|awkward|axis|baby|bachelor|bacon|badge|bag|balance|balcony|ball|bamboo|banana|banner|bar|barely|bargain|barrel|base|basic|basket|battle|beach|bean|beauty|because|become|beef|before|begin|behave|behind|believe|below|belt|bench|benefit|best|betray|better|between|beyond|bicycle|bid|bike|bind|biology|bird|birth|bitter|black|blade|blame|blanket|blast|bleak|bless|blind|blood|blossom|blouse|blue|blur|blush|board|boat|body|boil|bomb|bone|bonus|book|boost|border|boring|borrow|boss|bottom|bounce|box|boy|bracket|brain|brand|brass|brave|bread|breeze|brick|bridge|brief|bright|bring|brisk|broccoli|broken|bronze|broom|brother|brown|brush|bubble|buddy|budget|buffalo|build|bulb|bulk|bullet|bundle|bunker|burden|burger|burst|bus|business|busy|butter|buyer|buzz|cabbage|cabin|cable|cactus|cage|cake|call|calm|camera|camp|can|canal|cancel|candy|cannon|canoe|canvas|canyon|capable|capital|captain|car|carbon|card|cargo|carpet|carry|cart|case|cash|casino|castle|casual|cat|catalog|catch|category|cattle|caught|cause|caution|cave|ceiling|celery|cement|census|century|cereal|certain|chair|chalk|champion|change|chaos|chapter|charge|chase|chat|cheap|check|cheese|chef|cherry|chest|chicken|chief|child|chimney|choice|choose|chronic|chuckle|chunk|churn|cigar|cinnamon|circle|citizen|city|civil|claim|clap|clarify|claw|clay|clean|clerk|clever|click|client|cliff|climb|clinic|clip|clock|clog|close|cloth|cloud|clown|club|clump|cluster|clutch|coach|coast|coconut|code|coffee|coil|coin|collect|color|column|combine|come|comfort|comic|common|company|concert|conduct|confirm|congress|connect|consider|control|convince|cook|cool|copper|copy|coral|core|corn|correct|cost|cotton|couch|country|couple|course|cousin|cover|coyote|crack|cradle|craft|cram|crane|crash|crater|crawl|crazy|cream|credit|creek|crew|cricket|crime|crisp|critic|crop|cross|crouch|crowd|crucial|cruel|cruise|crumble|crunch|crush|cry|crystal|cube|culture|cup|cupboard|curious|current|curtain|curve|cushion|custom|cute|cycle|dad|damage|damp|dance|danger|daring|dash|daughter|dawn|day|deal|debate|debris|decade|december|decide|decline|decorate|decrease|deer|defense|define|defy|degree|delay|deliver|demand|demise|denial|dentist|deny|depart|depend|deposit|depth|deputy|derive|describe|desert|design|desk|despair|destroy|detail|detect|develop|device|devote|diagram|dial|diamond|diary|dice|diesel|diet|differ|digital|dignity|dilemma|dinner|dinosaur|direct|dirt|disagree|discover|disease|dish|dismiss|disorder|display|distance|divert|divide|divorce|dizzy|doctor|document|dog|doll|dolphin|domain|donate|donkey|donor|door|dose|double|dove|draft|dragon|drama|drastic|draw|dream|dress|drift|drill|drink|drip|drive|drop|drum|dry|duck|dumb|dune|during|dust|dutch|duty|dwarf|dynamic|eager|eagle|early|earn|earth|easily|east|easy|echo|ecology|economy|edge|edit|educate|effort|egg|eight|either|elbow|elder|electric|elegant|element|elephant|elevator|elite|else|embark|embody|embrace|emerge|emotion|employ|empower|empty|enable|enact|end|endless|endorse|enemy|energy|enforce|engage|engine|enhance|enjoy|enlist|enough|enrich|enroll|ensure|enter|entire|entry|envelope|episode|equal|equip|era|erase|erode|erosion|error|erupt|escape|essay|essence|estate|eternal|ethics|evidence|evil|evoke|evolve|exact|example|excess|exchange|excite|exclude|excuse|execute|exercise|exhaust|exhibit|exile|exist|exit|exotic|expand|expect|expire|explain|expose|express|extend|extra|eye|eyebrow|fabric|face|faculty|fade|faint|faith|fall|false|fame|family|famous|fan|fancy|fantasy|farm|fashion|fat|fatal|father|fatigue|fault|favorite|feature|february|federal|fee|feed|feel|female|fence|festival|fetch|fever|few|fiber|fiction|field|figure|file|film|filter|final|find|fine|finger|finish|fire|firm|first|fiscal|fish|fit|fitness|fix|flag|flame|flash|flat|flavor|flee|flight|flip|float|flock|floor|flower|fluid|flush|fly|foam|focus|fog|foil|fold|follow|food|foot|force|forest|forget|fork|fortune|forum|forward|fossil|foster|found|fox|fragile|frame|frequent|fresh|friend|fringe|frog|front|frost|frown|frozen|fruit|fuel|fun|funny|furnace|fury|future|gadget|gain|galaxy|gallery|game|gap|garage|garbage|garden|garlic|garment|gas|gasp|gate|gather|gauge|gaze|general|genius|genre|gentle|genuine|gesture|ghost|giant|gift|giggle|ginger|giraffe|girl|give|glad|glance|glare|glass|glide|glimpse|globe|gloom|glory|glove|glow|glue|goat|goddess|gold|good|goose|gorilla|gospel|gossip|govern|gown|grab|grace|grain|grant|grape|grass|gravity|great|green|grid|grief|grit|grocery|group|grow|grunt|guard|guess|guide|guilt|guitar|gun|gym|habit|hair|half|hammer|hamster|hand|happy|harbor|hard|harsh|harvest|hat|have|hawk|hazard|head|health|heart|heavy|hedgehog|height|hello|helmet|help|hen|hero|hidden|high|hill|hint|hip|hire|history|hobby|hockey|hold|hole|holiday|hollow|home|honey|hood|hope|horn|horror|horse|hospital|host|hotel|hour|hover|hub|huge|human|humble|humor|hundred|hungry|hunt|hurdle|hurry|hurt|husband|hybrid|ice|icon|idea|identify|idle|ignore|ill|illegal|illness|image|imitate|immense|immune|impact|impose|improve|impulse|inch|include|income|increase|index|indicate|indoor|industry|infant|inflict|inform|inhale|inherit|initial|inject|injury|inmate|inner|innocent|input|inquiry|insane|insect|inside|inspire|install|intact|interest|into|invest|invite|involve|iron|island|isolate|issue|item|ivory|jacket|jaguar|jar|jazz|jealous|jeans|jelly|jewel|job|join|joke|journey|joy|judge|juice|jump|jungle|junior|junk|just|kangaroo|keen|keep|ketchup|key|kick|kid|kidney|kind|kingdom|kiss|kit|kitchen|kite|kitten|kiwi|knee|knife|knock|know|lab|label|labor|ladder|lady|lake|lamp|language|laptop|large|later|latin|laugh|laundry|lava|law|lawn|lawsuit|layer|lazy|leader|leaf|learn|leave|lecture|left|leg|legal|legend|leisure|lemon|lend|length|lens|leopard|lesson|letter|level|liar|liberty|library|license|life|lift|light|like|limb|limit|link|lion|liquid|list|little|live|lizard|load|loan|lobster|local|lock|logic|lonely|long|loop|lottery|loud|lounge|love|loyal|lucky|luggage|lumber|lunar|lunch|luxury|lyrics|machine|mad|magic|magnet|maid|mail|main|major|make|mammal|man|manage|mandate|mango|mansion|manual|maple|marble|march|margin|marine|market|marriage|mask|mass|master|match|material|math|matrix|matter|maximum|maze|meadow|mean|measure|meat|mechanic|medal|media|melody|melt|member|memory|mention|menu|mercy|merge|merit|merry|mesh|message|metal|method|middle|midnight|milk|million|mimic|mind|minimum|minor|minute|miracle|mirror|misery|miss|mistake|mix|mixed|mixture|mobile|model|modify|mom|moment|monitor|monkey|monster|month|moon|moral|more|morning|mosquito|mother|motion|motor|mountain|mouse|move|movie|much|muffin|mule|multiply|muscle|museum|mushroom|music|must|mutual|myself|mystery|myth|naive|name|napkin|narrow|nasty|nation|nature|near|neck|need|negative|neglect|neither|nephew|nerve|nest|net|network|neutral|never|news|next|nice|night|noble|noise|nominee|noodle|normal|north|nose|notable|note|nothing|notice|novel|now|nuclear|number|nurse|nut|oak|obey|object|oblige|obscure|observe|obtain|obvious|occur|ocean|october|odor|off|offer|office|often|oil|okay|old|olive|olympic|omit|once|one|onion|online|only|open|opera|opinion|oppose|option|orange|orbit|orchard|order|ordinary|organ|orient|original|orphan|ostrich|other|outdoor|outer|output|outside|oval|oven|over|own|owner|oxygen|oyster|ozone|pact|paddle|page|pair|palace|palm|panda|panel|panic|panther|paper|parade|parent|park|parrot|party|pass|patch|path|patient|patrol|pattern|pause|pave|payment|peace|peanut|pear|peasant|pelican|pen|penalty|pencil|people|pepper|perfect|permit|person|pet|phone|photo|phrase|physical|piano|picnic|picture|piece|pig|pigeon|pill|pilot|pink|pioneer|pipe|pistol|pitch|pizza|place|planet|plastic|plate|play|please|pledge|pluck|plug|plunge|poem|poet|point|polar|pole|police|pond|pony|pool|popular|portion|position|possible|post|potato|pottery|poverty|powder|power|practice|praise|predict|prefer|prepare|present|pretty|prevent|price|pride|primary|print|priority|prison|private|prize|problem|process|produce|profit|program|project|promote|proof|property|prosper|protect|proud|provide|public|pudding|pull|pulp|pulse|pumpkin|punch|pupil|puppy|purchase|purity|purpose|purse|push|put|puzzle|pyramid|quality|quantum|quarter|question|quick|quit|quiz|quote|rabbit|raccoon|race|rack|radar|radio|rail|rain|raise|rally|ramp|ranch|random|range|rapid|rare|rate|rather|raven|raw|razor|ready|real|reason|rebel|rebuild|recall|receive|recipe|record|recycle|reduce|reflect|reform|refuse|region|regret|regular|reject|relax|release|relief|rely|remain|remember|remind|remove|render|renew|rent|reopen|repair|repeat|replace|report|require|rescue|resemble|resist|resource|response|result|retire|retreat|return|reunion|reveal|review|reward|rhythm|rib|ribbon|rice|rich|ride|ridge|rifle|right|rigid|ring|riot|ripple|risk|ritual|rival|river|road|roast|robot|robust|rocket|romance|roof|rookie|room|rose|rotate|rough|round|route|royal|rubber|rude|rug|rule|run|runway|rural|sad|saddle|sadness|safe|sail|salad|salmon|salon|salt|salute|same|sample|sand|satisfy|satoshi|sauce|sausage|save|say|scale|scan|scare|scatter|scene|scheme|school|science|scissors|scorpion|scout|scrap|screen|script|scrub|sea|search|season|seat|second|secret|section|security|seed|seek|segment|select|sell|seminar|senior|sense|sentence|series|service|session|settle|setup|seven|shadow|shaft|shallow|share|shed|shell|sheriff|shield|shift|shine|ship|shiver|shock|shoe|shoot|shop|short|shoulder|shove|shrimp|shrug|shuffle|shy|sibling|sick|side|siege|sight|sign|silent|silk|silly|silver|similar|simple|since|sing|siren|sister|situate|six|size|skate|sketch|ski|skill|skin|skirt|skull|slab|slam|sleep|slender|slice|slide|slight|slim|slogan|slot|slow|slush|small|smart|smile|smoke|smooth|snack|snake|snap|sniff|snow|soap|soccer|social|sock|soda|soft|solar|soldier|solid|solution|solve|someone|song|soon|sorry|sort|soul|sound|soup|source|south|space|spare|spatial|spawn|speak|special|speed|spell|spend|sphere|spice|spider|spike|spin|spirit|split|spoil|sponsor|spoon|sport|spot|spray|spread|spring|spy|square|squeeze|squirrel|stable|stadium|staff|stage|stairs|stamp|stand|start|state|stay|steak|steel|stem|step|stereo|stick|still|sting|stock|stomach|stone|stool|story|stove|strategy|street|strike|strong|struggle|student|stuff|stumble|style|subject|submit|subway|success|such|sudden|suffer|sugar|suggest|suit|summer|sun|sunny|sunset|super|supply|supreme|sure|surface|surge|surprise|surround|survey|suspect|sustain|swallow|swamp|swap|swarm|swear|sweet|swift|swim|swing|switch|sword|symbol|symptom|syrup|system|table|tackle|tag|tail|talent|talk|tank|tape|target|task|taste|tattoo|taxi|teach|team|tell|ten|tenant|tennis|tent|term|test|text|thank|that|theme|then|theory|there|they|thing|this|thought|three|thrive|throw|thumb|thunder|ticket|tide|tiger|tilt|timber|time|tiny|tip|tired|tissue|title|toast|tobacco|today|toddler|toe|together|toilet|token|tomato|tomorrow|tone|tongue|tonight|tool|tooth|top|topic|topple|torch|tornado|tortoise|toss|total|tourist|toward|tower|town|toy|track|trade|traffic|tragic|train|transfer|trap|trash|travel|tray|treat|tree|trend|trial|tribe|trick|trigger|trim|trip|trophy|trouble|truck|true|truly|trumpet|trust|truth|try|tube|tuition|tumble|tuna|tunnel|turkey|turn|turtle|twelve|twenty|twice|twin|twist|two|type|typical|ugly|umbrella|unable|unaware|uncle|uncover|under|undo|unfair|unfold|unhappy|uniform|unique|unit|universe|unknown|unlock|until|unusual|unveil|update|upgrade|uphold|upon|upper|upset|urban|urge|usage|use|used|useful|useless|usual|utility|vacant|vacuum|vague|valid|valley|valve|van|vanish|vapor|various|vast|vault|vehicle|velvet|vendor|venture|venue|verb|verify|version|very|vessel|veteran|viable|vibrant|vicious|victory|video|view|village|vintage|violin|virtual|virus|visa|visit|visual|vital|vivid|vocal|voice|void|volcano|volume|vote|voyage|wage|wagon|wait|walk|wall|walnut|want|warfare|warm|warrior|wash|wasp|waste|water|wave|way|wealth|weapon|wear|weasel|weather|web|wedding|weekend|weird|welcome|west|wet|whale|what|wheat|wheel|when|where|whip|whisper|wide|width|wife|wild|will|win|window|wine|wing|wink|winner|winter|wire|wisdom|wise|wish|witness|wolf|woman|wonder|wood|wool|word|work|world|worry|worth|wrap|wreck|wrestle|wrist|write|wrong|yard|year|yellow|you|young|youth|zebra|zero|zone|zoo'.split('|'); diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/es.d.ts b/packages/util-crypto/cjs/mnemonic/wordlists/es.d.ts new file mode 100644 index 0000000..d451d2b --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/es.d.ts @@ -0,0 +1,2 @@ +declare const _default: string[]; +export default _default; diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/es.js b/packages/util-crypto/cjs/mnemonic/wordlists/es.js new file mode 100644 index 0000000..c342a93 --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/es.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = 'ábaco|abdomen|abeja|abierto|abogado|abono|aborto|abrazo|abrir|abuelo|abuso|acabar|academia|acceso|acción|aceite|acelga|acento|aceptar|ácido|aclarar|acné|acoger|acoso|activo|acto|actriz|actuar|acudir|acuerdo|acusar|adicto|admitir|adoptar|adorno|aduana|adulto|aéreo|afectar|afición|afinar|afirmar|ágil|agitar|agonía|agosto|agotar|agregar|agrio|agua|agudo|águila|aguja|ahogo|ahorro|aire|aislar|ajedrez|ajeno|ajuste|alacrán|alambre|alarma|alba|álbum|alcalde|aldea|alegre|alejar|alerta|aleta|alfiler|alga|algodón|aliado|aliento|alivio|alma|almeja|almíbar|altar|alteza|altivo|alto|altura|alumno|alzar|amable|amante|amapola|amargo|amasar|ámbar|ámbito|ameno|amigo|amistad|amor|amparo|amplio|ancho|anciano|ancla|andar|andén|anemia|ángulo|anillo|ánimo|anís|anotar|antena|antiguo|antojo|anual|anular|anuncio|añadir|añejo|año|apagar|aparato|apetito|apio|aplicar|apodo|aporte|apoyo|aprender|aprobar|apuesta|apuro|arado|araña|arar|árbitro|árbol|arbusto|archivo|arco|arder|ardilla|arduo|área|árido|aries|armonía|arnés|aroma|arpa|arpón|arreglo|arroz|arruga|arte|artista|asa|asado|asalto|ascenso|asegurar|aseo|asesor|asiento|asilo|asistir|asno|asombro|áspero|astilla|astro|astuto|asumir|asunto|atajo|ataque|atar|atento|ateo|ático|atleta|átomo|atraer|atroz|atún|audaz|audio|auge|aula|aumento|ausente|autor|aval|avance|avaro|ave|avellana|avena|avestruz|avión|aviso|ayer|ayuda|ayuno|azafrán|azar|azote|azúcar|azufre|azul|baba|babor|bache|bahía|baile|bajar|balanza|balcón|balde|bambú|banco|banda|baño|barba|barco|barniz|barro|báscula|bastón|basura|batalla|batería|batir|batuta|baúl|bazar|bebé|bebida|bello|besar|beso|bestia|bicho|bien|bingo|blanco|bloque|blusa|boa|bobina|bobo|boca|bocina|boda|bodega|boina|bola|bolero|bolsa|bomba|bondad|bonito|bono|bonsái|borde|borrar|bosque|bote|botín|bóveda|bozal|bravo|brazo|brecha|breve|brillo|brinco|brisa|broca|broma|bronce|brote|bruja|brusco|bruto|buceo|bucle|bueno|buey|bufanda|bufón|búho|buitre|bulto|burbuja|burla|burro|buscar|butaca|buzón|caballo|cabeza|cabina|cabra|cacao|cadáver|cadena|caer|café|caída|caimán|caja|cajón|cal|calamar|calcio|caldo|calidad|calle|calma|calor|calvo|cama|cambio|camello|camino|campo|cáncer|candil|canela|canguro|canica|canto|caña|cañón|caoba|caos|capaz|capitán|capote|captar|capucha|cara|carbón|cárcel|careta|carga|cariño|carne|carpeta|carro|carta|casa|casco|casero|caspa|castor|catorce|catre|caudal|causa|cazo|cebolla|ceder|cedro|celda|célebre|celoso|célula|cemento|ceniza|centro|cerca|cerdo|cereza|cero|cerrar|certeza|césped|cetro|chacal|chaleco|champú|chancla|chapa|charla|chico|chiste|chivo|choque|choza|chuleta|chupar|ciclón|ciego|cielo|cien|cierto|cifra|cigarro|cima|cinco|cine|cinta|ciprés|circo|ciruela|cisne|cita|ciudad|clamor|clan|claro|clase|clave|cliente|clima|clínica|cobre|cocción|cochino|cocina|coco|código|codo|cofre|coger|cohete|cojín|cojo|cola|colcha|colegio|colgar|colina|collar|colmo|columna|combate|comer|comida|cómodo|compra|conde|conejo|conga|conocer|consejo|contar|copa|copia|corazón|corbata|corcho|cordón|corona|correr|coser|cosmos|costa|cráneo|cráter|crear|crecer|creído|crema|cría|crimen|cripta|crisis|cromo|crónica|croqueta|crudo|cruz|cuadro|cuarto|cuatro|cubo|cubrir|cuchara|cuello|cuento|cuerda|cuesta|cueva|cuidar|culebra|culpa|culto|cumbre|cumplir|cuna|cuneta|cuota|cupón|cúpula|curar|curioso|curso|curva|cutis|dama|danza|dar|dardo|dátil|deber|débil|década|decir|dedo|defensa|definir|dejar|delfín|delgado|delito|demora|denso|dental|deporte|derecho|derrota|desayuno|deseo|desfile|desnudo|destino|desvío|detalle|detener|deuda|día|diablo|diadema|diamante|diana|diario|dibujo|dictar|diente|dieta|diez|difícil|digno|dilema|diluir|dinero|directo|dirigir|disco|diseño|disfraz|diva|divino|doble|doce|dolor|domingo|don|donar|dorado|dormir|dorso|dos|dosis|dragón|droga|ducha|duda|duelo|dueño|dulce|dúo|duque|durar|dureza|duro|ébano|ebrio|echar|eco|ecuador|edad|edición|edificio|editor|educar|efecto|eficaz|eje|ejemplo|elefante|elegir|elemento|elevar|elipse|élite|elixir|elogio|eludir|embudo|emitir|emoción|empate|empeño|empleo|empresa|enano|encargo|enchufe|encía|enemigo|enero|enfado|enfermo|engaño|enigma|enlace|enorme|enredo|ensayo|enseñar|entero|entrar|envase|envío|época|equipo|erizo|escala|escena|escolar|escribir|escudo|esencia|esfera|esfuerzo|espada|espejo|espía|esposa|espuma|esquí|estar|este|estilo|estufa|etapa|eterno|ética|etnia|evadir|evaluar|evento|evitar|exacto|examen|exceso|excusa|exento|exigir|exilio|existir|éxito|experto|explicar|exponer|extremo|fábrica|fábula|fachada|fácil|factor|faena|faja|falda|fallo|falso|faltar|fama|familia|famoso|faraón|farmacia|farol|farsa|fase|fatiga|fauna|favor|fax|febrero|fecha|feliz|feo|feria|feroz|fértil|fervor|festín|fiable|fianza|fiar|fibra|ficción|ficha|fideo|fiebre|fiel|fiera|fiesta|figura|fijar|fijo|fila|filete|filial|filtro|fin|finca|fingir|finito|firma|flaco|flauta|flecha|flor|flota|fluir|flujo|flúor|fobia|foca|fogata|fogón|folio|folleto|fondo|forma|forro|fortuna|forzar|fosa|foto|fracaso|frágil|franja|frase|fraude|freír|freno|fresa|frío|frito|fruta|fuego|fuente|fuerza|fuga|fumar|función|funda|furgón|furia|fusil|fútbol|futuro|gacela|gafas|gaita|gajo|gala|galería|gallo|gamba|ganar|gancho|ganga|ganso|garaje|garza|gasolina|gastar|gato|gavilán|gemelo|gemir|gen|género|genio|gente|geranio|gerente|germen|gesto|gigante|gimnasio|girar|giro|glaciar|globo|gloria|gol|golfo|goloso|golpe|goma|gordo|gorila|gorra|gota|goteo|gozar|grada|gráfico|grano|grasa|gratis|grave|grieta|grillo|gripe|gris|grito|grosor|grúa|grueso|grumo|grupo|guante|guapo|guardia|guerra|guía|guiño|guion|guiso|guitarra|gusano|gustar|haber|hábil|hablar|hacer|hacha|hada|hallar|hamaca|harina|haz|hazaña|hebilla|hebra|hecho|helado|helio|hembra|herir|hermano|héroe|hervir|hielo|hierro|hígado|higiene|hijo|himno|historia|hocico|hogar|hoguera|hoja|hombre|hongo|honor|honra|hora|hormiga|horno|hostil|hoyo|hueco|huelga|huerta|hueso|huevo|huida|huir|humano|húmedo|humilde|humo|hundir|huracán|hurto|icono|ideal|idioma|ídolo|iglesia|iglú|igual|ilegal|ilusión|imagen|imán|imitar|impar|imperio|imponer|impulso|incapaz|índice|inerte|infiel|informe|ingenio|inicio|inmenso|inmune|innato|insecto|instante|interés|íntimo|intuir|inútil|invierno|ira|iris|ironía|isla|islote|jabalí|jabón|jamón|jarabe|jardín|jarra|jaula|jazmín|jefe|jeringa|jinete|jornada|joroba|joven|joya|juerga|jueves|juez|jugador|jugo|juguete|juicio|junco|jungla|junio|juntar|júpiter|jurar|justo|juvenil|juzgar|kilo|koala|labio|lacio|lacra|lado|ladrón|lagarto|lágrima|laguna|laico|lamer|lámina|lámpara|lana|lancha|langosta|lanza|lápiz|largo|larva|lástima|lata|látex|latir|laurel|lavar|lazo|leal|lección|leche|lector|leer|legión|legumbre|lejano|lengua|lento|leña|león|leopardo|lesión|letal|letra|leve|leyenda|libertad|libro|licor|líder|lidiar|lienzo|liga|ligero|lima|límite|limón|limpio|lince|lindo|línea|lingote|lino|linterna|líquido|liso|lista|litera|litio|litro|llaga|llama|llanto|llave|llegar|llenar|llevar|llorar|llover|lluvia|lobo|loción|loco|locura|lógica|logro|lombriz|lomo|lonja|lote|lucha|lucir|lugar|lujo|luna|lunes|lupa|lustro|luto|luz|maceta|macho|madera|madre|maduro|maestro|mafia|magia|mago|maíz|maldad|maleta|malla|malo|mamá|mambo|mamut|manco|mando|manejar|manga|maniquí|manjar|mano|manso|manta|mañana|mapa|máquina|mar|marco|marea|marfil|margen|marido|mármol|marrón|martes|marzo|masa|máscara|masivo|matar|materia|matiz|matriz|máximo|mayor|mazorca|mecha|medalla|medio|médula|mejilla|mejor|melena|melón|memoria|menor|mensaje|mente|menú|mercado|merengue|mérito|mes|mesón|meta|meter|método|metro|mezcla|miedo|miel|miembro|miga|mil|milagro|militar|millón|mimo|mina|minero|mínimo|minuto|miope|mirar|misa|miseria|misil|mismo|mitad|mito|mochila|moción|moda|modelo|moho|mojar|molde|moler|molino|momento|momia|monarca|moneda|monja|monto|moño|morada|morder|moreno|morir|morro|morsa|mortal|mosca|mostrar|motivo|mover|móvil|mozo|mucho|mudar|mueble|muela|muerte|muestra|mugre|mujer|mula|muleta|multa|mundo|muñeca|mural|muro|músculo|museo|musgo|música|muslo|nácar|nación|nadar|naipe|naranja|nariz|narrar|nasal|natal|nativo|natural|náusea|naval|nave|navidad|necio|néctar|negar|negocio|negro|neón|nervio|neto|neutro|nevar|nevera|nicho|nido|niebla|nieto|niñez|niño|nítido|nivel|nobleza|noche|nómina|noria|norma|norte|nota|noticia|novato|novela|novio|nube|nuca|núcleo|nudillo|nudo|nuera|nueve|nuez|nulo|número|nutria|oasis|obeso|obispo|objeto|obra|obrero|observar|obtener|obvio|oca|ocaso|océano|ochenta|ocho|ocio|ocre|octavo|octubre|oculto|ocupar|ocurrir|odiar|odio|odisea|oeste|ofensa|oferta|oficio|ofrecer|ogro|oído|oír|ojo|ola|oleada|olfato|olivo|olla|olmo|olor|olvido|ombligo|onda|onza|opaco|opción|ópera|opinar|oponer|optar|óptica|opuesto|oración|orador|oral|órbita|orca|orden|oreja|órgano|orgía|orgullo|oriente|origen|orilla|oro|orquesta|oruga|osadía|oscuro|osezno|oso|ostra|otoño|otro|oveja|óvulo|óxido|oxígeno|oyente|ozono|pacto|padre|paella|página|pago|país|pájaro|palabra|palco|paleta|pálido|palma|paloma|palpar|pan|panal|pánico|pantera|pañuelo|papá|papel|papilla|paquete|parar|parcela|pared|parir|paro|párpado|parque|párrafo|parte|pasar|paseo|pasión|paso|pasta|pata|patio|patria|pausa|pauta|pavo|payaso|peatón|pecado|pecera|pecho|pedal|pedir|pegar|peine|pelar|peldaño|pelea|peligro|pellejo|pelo|peluca|pena|pensar|peñón|peón|peor|pepino|pequeño|pera|percha|perder|pereza|perfil|perico|perla|permiso|perro|persona|pesa|pesca|pésimo|pestaña|pétalo|petróleo|pez|pezuña|picar|pichón|pie|piedra|pierna|pieza|pijama|pilar|piloto|pimienta|pino|pintor|pinza|piña|piojo|pipa|pirata|pisar|piscina|piso|pista|pitón|pizca|placa|plan|plata|playa|plaza|pleito|pleno|plomo|pluma|plural|pobre|poco|poder|podio|poema|poesía|poeta|polen|policía|pollo|polvo|pomada|pomelo|pomo|pompa|poner|porción|portal|posada|poseer|posible|poste|potencia|potro|pozo|prado|precoz|pregunta|premio|prensa|preso|previo|primo|príncipe|prisión|privar|proa|probar|proceso|producto|proeza|profesor|programa|prole|promesa|pronto|propio|próximo|prueba|público|puchero|pudor|pueblo|puerta|puesto|pulga|pulir|pulmón|pulpo|pulso|puma|punto|puñal|puño|pupa|pupila|puré|quedar|queja|quemar|querer|queso|quieto|química|quince|quitar|rábano|rabia|rabo|ración|radical|raíz|rama|rampa|rancho|rango|rapaz|rápido|rapto|rasgo|raspa|rato|rayo|raza|razón|reacción|realidad|rebaño|rebote|recaer|receta|rechazo|recoger|recreo|recto|recurso|red|redondo|reducir|reflejo|reforma|refrán|refugio|regalo|regir|regla|regreso|rehén|reino|reír|reja|relato|relevo|relieve|relleno|reloj|remar|remedio|remo|rencor|rendir|renta|reparto|repetir|reposo|reptil|res|rescate|resina|respeto|resto|resumen|retiro|retorno|retrato|reunir|revés|revista|rey|rezar|rico|riego|rienda|riesgo|rifa|rígido|rigor|rincón|riñón|río|riqueza|risa|ritmo|rito|rizo|roble|roce|rociar|rodar|rodeo|rodilla|roer|rojizo|rojo|romero|romper|ron|ronco|ronda|ropa|ropero|rosa|rosca|rostro|rotar|rubí|rubor|rudo|rueda|rugir|ruido|ruina|ruleta|rulo|rumbo|rumor|ruptura|ruta|rutina|sábado|saber|sabio|sable|sacar|sagaz|sagrado|sala|saldo|salero|salir|salmón|salón|salsa|salto|salud|salvar|samba|sanción|sandía|sanear|sangre|sanidad|sano|santo|sapo|saque|sardina|sartén|sastre|satán|sauna|saxofón|sección|seco|secreto|secta|sed|seguir|seis|sello|selva|semana|semilla|senda|sensor|señal|señor|separar|sepia|sequía|ser|serie|sermón|servir|sesenta|sesión|seta|setenta|severo|sexo|sexto|sidra|siesta|siete|siglo|signo|sílaba|silbar|silencio|silla|símbolo|simio|sirena|sistema|sitio|situar|sobre|socio|sodio|sol|solapa|soldado|soledad|sólido|soltar|solución|sombra|sondeo|sonido|sonoro|sonrisa|sopa|soplar|soporte|sordo|sorpresa|sorteo|sostén|sótano|suave|subir|suceso|sudor|suegra|suelo|sueño|suerte|sufrir|sujeto|sultán|sumar|superar|suplir|suponer|supremo|sur|surco|sureño|surgir|susto|sutil|tabaco|tabique|tabla|tabú|taco|tacto|tajo|talar|talco|talento|talla|talón|tamaño|tambor|tango|tanque|tapa|tapete|tapia|tapón|taquilla|tarde|tarea|tarifa|tarjeta|tarot|tarro|tarta|tatuaje|tauro|taza|tazón|teatro|techo|tecla|técnica|tejado|tejer|tejido|tela|teléfono|tema|temor|templo|tenaz|tender|tener|tenis|tenso|teoría|terapia|terco|término|ternura|terror|tesis|tesoro|testigo|tetera|texto|tez|tibio|tiburón|tiempo|tienda|tierra|tieso|tigre|tijera|tilde|timbre|tímido|timo|tinta|tío|típico|tipo|tira|tirón|titán|títere|título|tiza|toalla|tobillo|tocar|tocino|todo|toga|toldo|tomar|tono|tonto|topar|tope|toque|tórax|torero|tormenta|torneo|toro|torpedo|torre|torso|tortuga|tos|tosco|toser|tóxico|trabajo|tractor|traer|tráfico|trago|traje|tramo|trance|trato|trauma|trazar|trébol|tregua|treinta|tren|trepar|tres|tribu|trigo|tripa|triste|triunfo|trofeo|trompa|tronco|tropa|trote|trozo|truco|trueno|trufa|tubería|tubo|tuerto|tumba|tumor|túnel|túnica|turbina|turismo|turno|tutor|ubicar|úlcera|umbral|unidad|unir|universo|uno|untar|uña|urbano|urbe|urgente|urna|usar|usuario|útil|utopía|uva|vaca|vacío|vacuna|vagar|vago|vaina|vajilla|vale|válido|valle|valor|válvula|vampiro|vara|variar|varón|vaso|vecino|vector|vehículo|veinte|vejez|vela|velero|veloz|vena|vencer|venda|veneno|vengar|venir|venta|venus|ver|verano|verbo|verde|vereda|verja|verso|verter|vía|viaje|vibrar|vicio|víctima|vida|vídeo|vidrio|viejo|viernes|vigor|vil|villa|vinagre|vino|viñedo|violín|viral|virgo|virtud|visor|víspera|vista|vitamina|viudo|vivaz|vivero|vivir|vivo|volcán|volumen|volver|voraz|votar|voto|voz|vuelo|vulgar|yacer|yate|yegua|yema|yerno|yeso|yodo|yoga|yogur|zafiro|zanja|zapato|zarza|zona|zorro|zumo|zurdo'.split('|'); diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/fr.d.ts b/packages/util-crypto/cjs/mnemonic/wordlists/fr.d.ts new file mode 100644 index 0000000..d451d2b --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/fr.d.ts @@ -0,0 +1,2 @@ +declare const _default: string[]; +export default _default; diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/fr.js b/packages/util-crypto/cjs/mnemonic/wordlists/fr.js new file mode 100644 index 0000000..b9aa23a --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/fr.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = 'abaisser|abandon|abdiquer|abeille|abolir|aborder|aboutir|aboyer|abrasif|abreuver|abriter|abroger|abrupt|absence|absolu|absurde|abusif|abyssal|académie|acajou|acarien|accabler|accepter|acclamer|accolade|accroche|accuser|acerbe|achat|acheter|aciduler|acier|acompte|acquérir|acronyme|acteur|actif|actuel|adepte|adéquat|adhésif|adjectif|adjuger|admettre|admirer|adopter|adorer|adoucir|adresse|adroit|adulte|adverbe|aérer|aéronef|affaire|affecter|affiche|affreux|affubler|agacer|agencer|agile|agiter|agrafer|agréable|agrume|aider|aiguille|ailier|aimable|aisance|ajouter|ajuster|alarmer|alchimie|alerte|algèbre|algue|aliéner|aliment|alléger|alliage|allouer|allumer|alourdir|alpaga|altesse|alvéole|amateur|ambigu|ambre|aménager|amertume|amidon|amiral|amorcer|amour|amovible|amphibie|ampleur|amusant|analyse|anaphore|anarchie|anatomie|ancien|anéantir|angle|angoisse|anguleux|animal|annexer|annonce|annuel|anodin|anomalie|anonyme|anormal|antenne|antidote|anxieux|apaiser|apéritif|aplanir|apologie|appareil|appeler|apporter|appuyer|aquarium|aqueduc|arbitre|arbuste|ardeur|ardoise|argent|arlequin|armature|armement|armoire|armure|arpenter|arracher|arriver|arroser|arsenic|artériel|article|aspect|asphalte|aspirer|assaut|asservir|assiette|associer|assurer|asticot|astre|astuce|atelier|atome|atrium|atroce|attaque|attentif|attirer|attraper|aubaine|auberge|audace|audible|augurer|aurore|automne|autruche|avaler|avancer|avarice|avenir|averse|aveugle|aviateur|avide|avion|aviser|avoine|avouer|avril|axial|axiome|badge|bafouer|bagage|baguette|baignade|balancer|balcon|baleine|balisage|bambin|bancaire|bandage|banlieue|bannière|banquier|barbier|baril|baron|barque|barrage|bassin|bastion|bataille|bateau|batterie|baudrier|bavarder|belette|bélier|belote|bénéfice|berceau|berger|berline|bermuda|besace|besogne|bétail|beurre|biberon|bicycle|bidule|bijou|bilan|bilingue|billard|binaire|biologie|biopsie|biotype|biscuit|bison|bistouri|bitume|bizarre|blafard|blague|blanchir|blessant|blinder|blond|bloquer|blouson|bobard|bobine|boire|boiser|bolide|bonbon|bondir|bonheur|bonifier|bonus|bordure|borne|botte|boucle|boueux|bougie|boulon|bouquin|bourse|boussole|boutique|boxeur|branche|brasier|brave|brebis|brèche|breuvage|bricoler|brigade|brillant|brioche|brique|brochure|broder|bronzer|brousse|broyeur|brume|brusque|brutal|bruyant|buffle|buisson|bulletin|bureau|burin|bustier|butiner|butoir|buvable|buvette|cabanon|cabine|cachette|cadeau|cadre|caféine|caillou|caisson|calculer|calepin|calibre|calmer|calomnie|calvaire|camarade|caméra|camion|campagne|canal|caneton|canon|cantine|canular|capable|caporal|caprice|capsule|capter|capuche|carabine|carbone|caresser|caribou|carnage|carotte|carreau|carton|cascade|casier|casque|cassure|causer|caution|cavalier|caverne|caviar|cédille|ceinture|céleste|cellule|cendrier|censurer|central|cercle|cérébral|cerise|cerner|cerveau|cesser|chagrin|chaise|chaleur|chambre|chance|chapitre|charbon|chasseur|chaton|chausson|chavirer|chemise|chenille|chéquier|chercher|cheval|chien|chiffre|chignon|chimère|chiot|chlorure|chocolat|choisir|chose|chouette|chrome|chute|cigare|cigogne|cimenter|cinéma|cintrer|circuler|cirer|cirque|citerne|citoyen|citron|civil|clairon|clameur|claquer|classe|clavier|client|cligner|climat|clivage|cloche|clonage|cloporte|cobalt|cobra|cocasse|cocotier|coder|codifier|coffre|cogner|cohésion|coiffer|coincer|colère|colibri|colline|colmater|colonel|combat|comédie|commande|compact|concert|conduire|confier|congeler|connoter|consonne|contact|convexe|copain|copie|corail|corbeau|cordage|corniche|corpus|correct|cortège|cosmique|costume|coton|coude|coupure|courage|couteau|couvrir|coyote|crabe|crainte|cravate|crayon|créature|créditer|crémeux|creuser|crevette|cribler|crier|cristal|critère|croire|croquer|crotale|crucial|cruel|crypter|cubique|cueillir|cuillère|cuisine|cuivre|culminer|cultiver|cumuler|cupide|curatif|curseur|cyanure|cycle|cylindre|cynique|daigner|damier|danger|danseur|dauphin|débattre|débiter|déborder|débrider|débutant|décaler|décembre|déchirer|décider|déclarer|décorer|décrire|décupler|dédale|déductif|déesse|défensif|défiler|défrayer|dégager|dégivrer|déglutir|dégrafer|déjeuner|délice|déloger|demander|demeurer|démolir|dénicher|dénouer|dentelle|dénuder|départ|dépenser|déphaser|déplacer|déposer|déranger|dérober|désastre|descente|désert|désigner|désobéir|dessiner|destrier|détacher|détester|détourer|détresse|devancer|devenir|deviner|devoir|diable|dialogue|diamant|dicter|différer|digérer|digital|digne|diluer|dimanche|diminuer|dioxyde|directif|diriger|discuter|disposer|dissiper|distance|divertir|diviser|docile|docteur|dogme|doigt|domaine|domicile|dompter|donateur|donjon|donner|dopamine|dortoir|dorure|dosage|doseur|dossier|dotation|douanier|double|douceur|douter|doyen|dragon|draper|dresser|dribbler|droiture|duperie|duplexe|durable|durcir|dynastie|éblouir|écarter|écharpe|échelle|éclairer|éclipse|éclore|écluse|école|économie|écorce|écouter|écraser|écrémer|écrivain|écrou|écume|écureuil|édifier|éduquer|effacer|effectif|effigie|effort|effrayer|effusion|égaliser|égarer|éjecter|élaborer|élargir|électron|élégant|éléphant|élève|éligible|élitisme|éloge|élucider|éluder|emballer|embellir|embryon|émeraude|émission|emmener|émotion|émouvoir|empereur|employer|emporter|emprise|émulsion|encadrer|enchère|enclave|encoche|endiguer|endosser|endroit|enduire|énergie|enfance|enfermer|enfouir|engager|engin|englober|énigme|enjamber|enjeu|enlever|ennemi|ennuyeux|enrichir|enrobage|enseigne|entasser|entendre|entier|entourer|entraver|énumérer|envahir|enviable|envoyer|enzyme|éolien|épaissir|épargne|épatant|épaule|épicerie|épidémie|épier|épilogue|épine|épisode|épitaphe|époque|épreuve|éprouver|épuisant|équerre|équipe|ériger|érosion|erreur|éruption|escalier|espadon|espèce|espiègle|espoir|esprit|esquiver|essayer|essence|essieu|essorer|estime|estomac|estrade|étagère|étaler|étanche|étatique|éteindre|étendoir|éternel|éthanol|éthique|ethnie|étirer|étoffer|étoile|étonnant|étourdir|étrange|étroit|étude|euphorie|évaluer|évasion|éventail|évidence|éviter|évolutif|évoquer|exact|exagérer|exaucer|exceller|excitant|exclusif|excuse|exécuter|exemple|exercer|exhaler|exhorter|exigence|exiler|exister|exotique|expédier|explorer|exposer|exprimer|exquis|extensif|extraire|exulter|fable|fabuleux|facette|facile|facture|faiblir|falaise|fameux|famille|farceur|farfelu|farine|farouche|fasciner|fatal|fatigue|faucon|fautif|faveur|favori|fébrile|féconder|fédérer|félin|femme|fémur|fendoir|féodal|fermer|féroce|ferveur|festival|feuille|feutre|février|fiasco|ficeler|fictif|fidèle|figure|filature|filetage|filière|filleul|filmer|filou|filtrer|financer|finir|fiole|firme|fissure|fixer|flairer|flamme|flasque|flatteur|fléau|flèche|fleur|flexion|flocon|flore|fluctuer|fluide|fluvial|folie|fonderie|fongible|fontaine|forcer|forgeron|formuler|fortune|fossile|foudre|fougère|fouiller|foulure|fourmi|fragile|fraise|franchir|frapper|frayeur|frégate|freiner|frelon|frémir|frénésie|frère|friable|friction|frisson|frivole|froid|fromage|frontal|frotter|fruit|fugitif|fuite|fureur|furieux|furtif|fusion|futur|gagner|galaxie|galerie|gambader|garantir|gardien|garnir|garrigue|gazelle|gazon|géant|gélatine|gélule|gendarme|général|génie|genou|gentil|géologie|géomètre|géranium|germe|gestuel|geyser|gibier|gicler|girafe|givre|glace|glaive|glisser|globe|gloire|glorieux|golfeur|gomme|gonfler|gorge|gorille|goudron|gouffre|goulot|goupille|gourmand|goutte|graduel|graffiti|graine|grand|grappin|gratuit|gravir|grenat|griffure|griller|grimper|grogner|gronder|grotte|groupe|gruger|grutier|gruyère|guépard|guerrier|guide|guimauve|guitare|gustatif|gymnaste|gyrostat|habitude|hachoir|halte|hameau|hangar|hanneton|haricot|harmonie|harpon|hasard|hélium|hématome|herbe|hérisson|hermine|héron|hésiter|heureux|hiberner|hibou|hilarant|histoire|hiver|homard|hommage|homogène|honneur|honorer|honteux|horde|horizon|horloge|hormone|horrible|houleux|housse|hublot|huileux|humain|humble|humide|humour|hurler|hydromel|hygiène|hymne|hypnose|idylle|ignorer|iguane|illicite|illusion|image|imbiber|imiter|immense|immobile|immuable|impact|impérial|implorer|imposer|imprimer|imputer|incarner|incendie|incident|incliner|incolore|indexer|indice|inductif|inédit|ineptie|inexact|infini|infliger|informer|infusion|ingérer|inhaler|inhiber|injecter|injure|innocent|inoculer|inonder|inscrire|insecte|insigne|insolite|inspirer|instinct|insulter|intact|intense|intime|intrigue|intuitif|inutile|invasion|inventer|inviter|invoquer|ironique|irradier|irréel|irriter|isoler|ivoire|ivresse|jaguar|jaillir|jambe|janvier|jardin|jauger|jaune|javelot|jetable|jeton|jeudi|jeunesse|joindre|joncher|jongler|joueur|jouissif|journal|jovial|joyau|joyeux|jubiler|jugement|junior|jupon|juriste|justice|juteux|juvénile|kayak|kimono|kiosque|label|labial|labourer|lacérer|lactose|lagune|laine|laisser|laitier|lambeau|lamelle|lampe|lanceur|langage|lanterne|lapin|largeur|larme|laurier|lavabo|lavoir|lecture|légal|léger|légume|lessive|lettre|levier|lexique|lézard|liasse|libérer|libre|licence|licorne|liège|lièvre|ligature|ligoter|ligue|limer|limite|limonade|limpide|linéaire|lingot|lionceau|liquide|lisière|lister|lithium|litige|littoral|livreur|logique|lointain|loisir|lombric|loterie|louer|lourd|loutre|louve|loyal|lubie|lucide|lucratif|lueur|lugubre|luisant|lumière|lunaire|lundi|luron|lutter|luxueux|machine|magasin|magenta|magique|maigre|maillon|maintien|mairie|maison|majorer|malaxer|maléfice|malheur|malice|mallette|mammouth|mandater|maniable|manquant|manteau|manuel|marathon|marbre|marchand|mardi|maritime|marqueur|marron|marteler|mascotte|massif|matériel|matière|matraque|maudire|maussade|mauve|maximal|méchant|méconnu|médaille|médecin|méditer|méduse|meilleur|mélange|mélodie|membre|mémoire|menacer|mener|menhir|mensonge|mentor|mercredi|mérite|merle|messager|mesure|métal|météore|méthode|métier|meuble|miauler|microbe|miette|mignon|migrer|milieu|million|mimique|mince|minéral|minimal|minorer|minute|miracle|miroiter|missile|mixte|mobile|moderne|moelleux|mondial|moniteur|monnaie|monotone|monstre|montagne|monument|moqueur|morceau|morsure|mortier|moteur|motif|mouche|moufle|moulin|mousson|mouton|mouvant|multiple|munition|muraille|murène|murmure|muscle|muséum|musicien|mutation|muter|mutuel|myriade|myrtille|mystère|mythique|nageur|nappe|narquois|narrer|natation|nation|nature|naufrage|nautique|navire|nébuleux|nectar|néfaste|négation|négliger|négocier|neige|nerveux|nettoyer|neurone|neutron|neveu|niche|nickel|nitrate|niveau|noble|nocif|nocturne|noirceur|noisette|nomade|nombreux|nommer|normatif|notable|notifier|notoire|nourrir|nouveau|novateur|novembre|novice|nuage|nuancer|nuire|nuisible|numéro|nuptial|nuque|nutritif|obéir|objectif|obliger|obscur|observer|obstacle|obtenir|obturer|occasion|occuper|océan|octobre|octroyer|octupler|oculaire|odeur|odorant|offenser|officier|offrir|ogive|oiseau|oisillon|olfactif|olivier|ombrage|omettre|onctueux|onduler|onéreux|onirique|opale|opaque|opérer|opinion|opportun|opprimer|opter|optique|orageux|orange|orbite|ordonner|oreille|organe|orgueil|orifice|ornement|orque|ortie|osciller|osmose|ossature|otarie|ouragan|ourson|outil|outrager|ouvrage|ovation|oxyde|oxygène|ozone|paisible|palace|palmarès|palourde|palper|panache|panda|pangolin|paniquer|panneau|panorama|pantalon|papaye|papier|papoter|papyrus|paradoxe|parcelle|paresse|parfumer|parler|parole|parrain|parsemer|partager|parure|parvenir|passion|pastèque|paternel|patience|patron|pavillon|pavoiser|payer|paysage|peigne|peintre|pelage|pélican|pelle|pelouse|peluche|pendule|pénétrer|pénible|pensif|pénurie|pépite|péplum|perdrix|perforer|période|permuter|perplexe|persil|perte|peser|pétale|petit|pétrir|peuple|pharaon|phobie|phoque|photon|phrase|physique|piano|pictural|pièce|pierre|pieuvre|pilote|pinceau|pipette|piquer|pirogue|piscine|piston|pivoter|pixel|pizza|placard|plafond|plaisir|planer|plaque|plastron|plateau|pleurer|plexus|pliage|plomb|plonger|pluie|plumage|pochette|poésie|poète|pointe|poirier|poisson|poivre|polaire|policier|pollen|polygone|pommade|pompier|ponctuel|pondérer|poney|portique|position|posséder|posture|potager|poteau|potion|pouce|poulain|poumon|pourpre|poussin|pouvoir|prairie|pratique|précieux|prédire|préfixe|prélude|prénom|présence|prétexte|prévoir|primitif|prince|prison|priver|problème|procéder|prodige|profond|progrès|proie|projeter|prologue|promener|propre|prospère|protéger|prouesse|proverbe|prudence|pruneau|psychose|public|puceron|puiser|pulpe|pulsar|punaise|punitif|pupitre|purifier|puzzle|pyramide|quasar|querelle|question|quiétude|quitter|quotient|racine|raconter|radieux|ragondin|raideur|raisin|ralentir|rallonge|ramasser|rapide|rasage|ratisser|ravager|ravin|rayonner|réactif|réagir|réaliser|réanimer|recevoir|réciter|réclamer|récolter|recruter|reculer|recycler|rédiger|redouter|refaire|réflexe|réformer|refrain|refuge|régalien|région|réglage|régulier|réitérer|rejeter|rejouer|relatif|relever|relief|remarque|remède|remise|remonter|remplir|remuer|renard|renfort|renifler|renoncer|rentrer|renvoi|replier|reporter|reprise|reptile|requin|réserve|résineux|résoudre|respect|rester|résultat|rétablir|retenir|réticule|retomber|retracer|réunion|réussir|revanche|revivre|révolte|révulsif|richesse|rideau|rieur|rigide|rigoler|rincer|riposter|risible|risque|rituel|rival|rivière|rocheux|romance|rompre|ronce|rondin|roseau|rosier|rotatif|rotor|rotule|rouge|rouille|rouleau|routine|royaume|ruban|rubis|ruche|ruelle|rugueux|ruiner|ruisseau|ruser|rustique|rythme|sabler|saboter|sabre|sacoche|safari|sagesse|saisir|salade|salive|salon|saluer|samedi|sanction|sanglier|sarcasme|sardine|saturer|saugrenu|saumon|sauter|sauvage|savant|savonner|scalpel|scandale|scélérat|scénario|sceptre|schéma|science|scinder|score|scrutin|sculpter|séance|sécable|sécher|secouer|sécréter|sédatif|séduire|seigneur|séjour|sélectif|semaine|sembler|semence|séminal|sénateur|sensible|sentence|séparer|séquence|serein|sergent|sérieux|serrure|sérum|service|sésame|sévir|sevrage|sextuple|sidéral|siècle|siéger|siffler|sigle|signal|silence|silicium|simple|sincère|sinistre|siphon|sirop|sismique|situer|skier|social|socle|sodium|soigneux|soldat|soleil|solitude|soluble|sombre|sommeil|somnoler|sonde|songeur|sonnette|sonore|sorcier|sortir|sosie|sottise|soucieux|soudure|souffle|soulever|soupape|source|soutirer|souvenir|spacieux|spatial|spécial|sphère|spiral|stable|station|sternum|stimulus|stipuler|strict|studieux|stupeur|styliste|sublime|substrat|subtil|subvenir|succès|sucre|suffixe|suggérer|suiveur|sulfate|superbe|supplier|surface|suricate|surmener|surprise|sursaut|survie|suspect|syllabe|symbole|symétrie|synapse|syntaxe|système|tabac|tablier|tactile|tailler|talent|talisman|talonner|tambour|tamiser|tangible|tapis|taquiner|tarder|tarif|tartine|tasse|tatami|tatouage|taupe|taureau|taxer|témoin|temporel|tenaille|tendre|teneur|tenir|tension|terminer|terne|terrible|tétine|texte|thème|théorie|thérapie|thorax|tibia|tiède|timide|tirelire|tiroir|tissu|titane|titre|tituber|toboggan|tolérant|tomate|tonique|tonneau|toponyme|torche|tordre|tornade|torpille|torrent|torse|tortue|totem|toucher|tournage|tousser|toxine|traction|trafic|tragique|trahir|train|trancher|travail|trèfle|tremper|trésor|treuil|triage|tribunal|tricoter|trilogie|triomphe|tripler|triturer|trivial|trombone|tronc|tropical|troupeau|tuile|tulipe|tumulte|tunnel|turbine|tuteur|tutoyer|tuyau|tympan|typhon|typique|tyran|ubuesque|ultime|ultrason|unanime|unifier|union|unique|unitaire|univers|uranium|urbain|urticant|usage|usine|usuel|usure|utile|utopie|vacarme|vaccin|vagabond|vague|vaillant|vaincre|vaisseau|valable|valise|vallon|valve|vampire|vanille|vapeur|varier|vaseux|vassal|vaste|vecteur|vedette|végétal|véhicule|veinard|véloce|vendredi|vénérer|venger|venimeux|ventouse|verdure|vérin|vernir|verrou|verser|vertu|veston|vétéran|vétuste|vexant|vexer|viaduc|viande|victoire|vidange|vidéo|vignette|vigueur|vilain|village|vinaigre|violon|vipère|virement|virtuose|virus|visage|viseur|vision|visqueux|visuel|vital|vitesse|viticole|vitrine|vivace|vivipare|vocation|voguer|voile|voisin|voiture|volaille|volcan|voltiger|volume|vorace|vortex|voter|vouloir|voyage|voyelle|wagon|xénon|yacht|zèbre|zénith|zeste|zoologie'.split('|'); diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/index.d.ts b/packages/util-crypto/cjs/mnemonic/wordlists/index.d.ts new file mode 100644 index 0000000..9c1ccf0 --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/index.d.ts @@ -0,0 +1,8 @@ +export { default as english } from './en.js'; +export { default as spanish } from './es.js'; +export { default as french } from './fr.js'; +export { default as italian } from './it.js'; +export { default as japanese } from './jp.js'; +export { default as korean } from './ko.js'; +export { default as chineseSimplified } from './zh-s.js'; +export { default as chineseTraditional } from './zh-t.js'; diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/index.js b/packages/util-crypto/cjs/mnemonic/wordlists/index.js new file mode 100644 index 0000000..ac3e7c8 --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/index.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.chineseTraditional = exports.chineseSimplified = exports.korean = exports.japanese = exports.italian = exports.french = exports.spanish = exports.english = void 0; +const tslib_1 = require("tslib"); +var en_js_1 = require("./en.js"); +Object.defineProperty(exports, "english", { enumerable: true, get: function () { return tslib_1.__importDefault(en_js_1).default; } }); +var es_js_1 = require("./es.js"); +Object.defineProperty(exports, "spanish", { enumerable: true, get: function () { return tslib_1.__importDefault(es_js_1).default; } }); +var fr_js_1 = require("./fr.js"); +Object.defineProperty(exports, "french", { enumerable: true, get: function () { return tslib_1.__importDefault(fr_js_1).default; } }); +var it_js_1 = require("./it.js"); +Object.defineProperty(exports, "italian", { enumerable: true, get: function () { return tslib_1.__importDefault(it_js_1).default; } }); +var jp_js_1 = require("./jp.js"); +Object.defineProperty(exports, "japanese", { enumerable: true, get: function () { return tslib_1.__importDefault(jp_js_1).default; } }); +var ko_js_1 = require("./ko.js"); +Object.defineProperty(exports, "korean", { enumerable: true, get: function () { return tslib_1.__importDefault(ko_js_1).default; } }); +var zh_s_js_1 = require("./zh-s.js"); +Object.defineProperty(exports, "chineseSimplified", { enumerable: true, get: function () { return tslib_1.__importDefault(zh_s_js_1).default; } }); +var zh_t_js_1 = require("./zh-t.js"); +Object.defineProperty(exports, "chineseTraditional", { enumerable: true, get: function () { return tslib_1.__importDefault(zh_t_js_1).default; } }); diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/it.d.ts b/packages/util-crypto/cjs/mnemonic/wordlists/it.d.ts new file mode 100644 index 0000000..d451d2b --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/it.d.ts @@ -0,0 +1,2 @@ +declare const _default: string[]; +export default _default; diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/it.js b/packages/util-crypto/cjs/mnemonic/wordlists/it.js new file mode 100644 index 0000000..1a9558c --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/it.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = 'abaco|abbaglio|abbinato|abete|abisso|abolire|abrasivo|abrogato|accadere|accenno|accusato|acetone|achille|acido|acqua|acre|acrilico|acrobata|acuto|adagio|addebito|addome|adeguato|aderire|adipe|adottare|adulare|affabile|affetto|affisso|affranto|aforisma|afoso|africano|agave|agente|agevole|aggancio|agire|agitare|agonismo|agricolo|agrumeto|aguzzo|alabarda|alato|albatro|alberato|albo|albume|alce|alcolico|alettone|alfa|algebra|aliante|alibi|alimento|allagato|allegro|allievo|allodola|allusivo|almeno|alogeno|alpaca|alpestre|altalena|alterno|alticcio|altrove|alunno|alveolo|alzare|amalgama|amanita|amarena|ambito|ambrato|ameba|america|ametista|amico|ammasso|ammenda|ammirare|ammonito|amore|ampio|ampliare|amuleto|anacardo|anagrafe|analista|anarchia|anatra|anca|ancella|ancora|andare|andrea|anello|angelo|angolare|angusto|anima|annegare|annidato|anno|annuncio|anonimo|anticipo|anzi|apatico|apertura|apode|apparire|appetito|appoggio|approdo|appunto|aprile|arabica|arachide|aragosta|araldica|arancio|aratura|arazzo|arbitro|archivio|ardito|arenile|argento|argine|arguto|aria|armonia|arnese|arredato|arringa|arrosto|arsenico|arso|artefice|arzillo|asciutto|ascolto|asepsi|asettico|asfalto|asino|asola|aspirato|aspro|assaggio|asse|assoluto|assurdo|asta|astenuto|astice|astratto|atavico|ateismo|atomico|atono|attesa|attivare|attorno|attrito|attuale|ausilio|austria|autista|autonomo|autunno|avanzato|avere|avvenire|avviso|avvolgere|azione|azoto|azzimo|azzurro|babele|baccano|bacino|baco|badessa|badilata|bagnato|baita|balcone|baldo|balena|ballata|balzano|bambino|bandire|baraonda|barbaro|barca|baritono|barlume|barocco|basilico|basso|batosta|battuto|baule|bava|bavosa|becco|beffa|belgio|belva|benda|benevole|benigno|benzina|bere|berlina|beta|bibita|bici|bidone|bifido|biga|bilancia|bimbo|binocolo|biologo|bipede|bipolare|birbante|birra|biscotto|bisesto|bisnonno|bisonte|bisturi|bizzarro|blando|blatta|bollito|bonifico|bordo|bosco|botanico|bottino|bozzolo|braccio|bradipo|brama|branca|bravura|bretella|brevetto|brezza|briglia|brillante|brindare|broccolo|brodo|bronzina|brullo|bruno|bubbone|buca|budino|buffone|buio|bulbo|buono|burlone|burrasca|bussola|busta|cadetto|caduco|calamaro|calcolo|calesse|calibro|calmo|caloria|cambusa|camerata|camicia|cammino|camola|campale|canapa|candela|cane|canino|canotto|cantina|capace|capello|capitolo|capogiro|cappero|capra|capsula|carapace|carcassa|cardo|carisma|carovana|carretto|cartolina|casaccio|cascata|caserma|caso|cassone|castello|casuale|catasta|catena|catrame|cauto|cavillo|cedibile|cedrata|cefalo|celebre|cellulare|cena|cenone|centesimo|ceramica|cercare|certo|cerume|cervello|cesoia|cespo|ceto|chela|chiaro|chicca|chiedere|chimera|china|chirurgo|chitarra|ciao|ciclismo|cifrare|cigno|cilindro|ciottolo|circa|cirrosi|citrico|cittadino|ciuffo|civetta|civile|classico|clinica|cloro|cocco|codardo|codice|coerente|cognome|collare|colmato|colore|colposo|coltivato|colza|coma|cometa|commando|comodo|computer|comune|conciso|condurre|conferma|congelare|coniuge|connesso|conoscere|consumo|continuo|convegno|coperto|copione|coppia|copricapo|corazza|cordata|coricato|cornice|corolla|corpo|corredo|corsia|cortese|cosmico|costante|cottura|covato|cratere|cravatta|creato|credere|cremoso|crescita|creta|criceto|crinale|crisi|critico|croce|cronaca|crostata|cruciale|crusca|cucire|cuculo|cugino|cullato|cupola|curatore|cursore|curvo|cuscino|custode|dado|daino|dalmata|damerino|daniela|dannoso|danzare|datato|davanti|davvero|debutto|decennio|deciso|declino|decollo|decreto|dedicato|definito|deforme|degno|delegare|delfino|delirio|delta|demenza|denotato|dentro|deposito|derapata|derivare|deroga|descritto|deserto|desiderio|desumere|detersivo|devoto|diametro|dicembre|diedro|difeso|diffuso|digerire|digitale|diluvio|dinamico|dinnanzi|dipinto|diploma|dipolo|diradare|dire|dirotto|dirupo|disagio|discreto|disfare|disgelo|disposto|distanza|disumano|dito|divano|divelto|dividere|divorato|doblone|docente|doganale|dogma|dolce|domato|domenica|dominare|dondolo|dono|dormire|dote|dottore|dovuto|dozzina|drago|druido|dubbio|dubitare|ducale|duna|duomo|duplice|duraturo|ebano|eccesso|ecco|eclissi|economia|edera|edicola|edile|editoria|educare|egemonia|egli|egoismo|egregio|elaborato|elargire|elegante|elencato|eletto|elevare|elfico|elica|elmo|elsa|eluso|emanato|emblema|emesso|emiro|emotivo|emozione|empirico|emulo|endemico|enduro|energia|enfasi|enoteca|entrare|enzima|epatite|epilogo|episodio|epocale|eppure|equatore|erario|erba|erboso|erede|eremita|erigere|ermetico|eroe|erosivo|errante|esagono|esame|esanime|esaudire|esca|esempio|esercito|esibito|esigente|esistere|esito|esofago|esortato|esoso|espanso|espresso|essenza|esso|esteso|estimare|estonia|estroso|esultare|etilico|etnico|etrusco|etto|euclideo|europa|evaso|evidenza|evitato|evoluto|evviva|fabbrica|faccenda|fachiro|falco|famiglia|fanale|fanfara|fango|fantasma|fare|farfalla|farinoso|farmaco|fascia|fastoso|fasullo|faticare|fato|favoloso|febbre|fecola|fede|fegato|felpa|feltro|femmina|fendere|fenomeno|fermento|ferro|fertile|fessura|festivo|fetta|feudo|fiaba|fiducia|fifa|figurato|filo|finanza|finestra|finire|fiore|fiscale|fisico|fiume|flacone|flamenco|flebo|flemma|florido|fluente|fluoro|fobico|focaccia|focoso|foderato|foglio|folata|folclore|folgore|fondente|fonetico|fonia|fontana|forbito|forchetta|foresta|formica|fornaio|foro|fortezza|forzare|fosfato|fosso|fracasso|frana|frassino|fratello|freccetta|frenata|fresco|frigo|frollino|fronde|frugale|frutta|fucilata|fucsia|fuggente|fulmine|fulvo|fumante|fumetto|fumoso|fune|funzione|fuoco|furbo|furgone|furore|fuso|futile|gabbiano|gaffe|galateo|gallina|galoppo|gambero|gamma|garanzia|garbo|garofano|garzone|gasdotto|gasolio|gastrico|gatto|gaudio|gazebo|gazzella|geco|gelatina|gelso|gemello|gemmato|gene|genitore|gennaio|genotipo|gergo|ghepardo|ghiaccio|ghisa|giallo|gilda|ginepro|giocare|gioiello|giorno|giove|girato|girone|gittata|giudizio|giurato|giusto|globulo|glutine|gnomo|gobba|golf|gomito|gommone|gonfio|gonna|governo|gracile|grado|grafico|grammo|grande|grattare|gravoso|grazia|greca|gregge|grifone|grigio|grinza|grotta|gruppo|guadagno|guaio|guanto|guardare|gufo|guidare|ibernato|icona|identico|idillio|idolo|idra|idrico|idrogeno|igiene|ignaro|ignorato|ilare|illeso|illogico|illudere|imballo|imbevuto|imbocco|imbuto|immane|immerso|immolato|impacco|impeto|impiego|importo|impronta|inalare|inarcare|inattivo|incanto|incendio|inchino|incisivo|incluso|incontro|incrocio|incubo|indagine|india|indole|inedito|infatti|infilare|inflitto|ingaggio|ingegno|inglese|ingordo|ingrosso|innesco|inodore|inoltrare|inondato|insano|insetto|insieme|insonnia|insulina|intasato|intero|intonaco|intuito|inumidire|invalido|invece|invito|iperbole|ipnotico|ipotesi|ippica|iride|irlanda|ironico|irrigato|irrorare|isolato|isotopo|isterico|istituto|istrice|italia|iterare|labbro|labirinto|lacca|lacerato|lacrima|lacuna|laddove|lago|lampo|lancetta|lanterna|lardoso|larga|laringe|lastra|latenza|latino|lattuga|lavagna|lavoro|legale|leggero|lembo|lentezza|lenza|leone|lepre|lesivo|lessato|lesto|letterale|leva|levigato|libero|lido|lievito|lilla|limatura|limitare|limpido|lineare|lingua|liquido|lira|lirica|lisca|lite|litigio|livrea|locanda|lode|logica|lombare|londra|longevo|loquace|lorenzo|loto|lotteria|luce|lucidato|lumaca|luminoso|lungo|lupo|luppolo|lusinga|lusso|lutto|macabro|macchina|macero|macinato|madama|magico|maglia|magnete|magro|maiolica|malafede|malgrado|malinteso|malsano|malto|malumore|mana|mancia|mandorla|mangiare|manifesto|mannaro|manovra|mansarda|mantide|manubrio|mappa|maratona|marcire|maretta|marmo|marsupio|maschera|massaia|mastino|materasso|matricola|mattone|maturo|mazurca|meandro|meccanico|mecenate|medesimo|meditare|mega|melassa|melis|melodia|meninge|meno|mensola|mercurio|merenda|merlo|meschino|mese|messere|mestolo|metallo|metodo|mettere|miagolare|mica|micelio|michele|microbo|midollo|miele|migliore|milano|milite|mimosa|minerale|mini|minore|mirino|mirtillo|miscela|missiva|misto|misurare|mitezza|mitigare|mitra|mittente|mnemonico|modello|modifica|modulo|mogano|mogio|mole|molosso|monastero|monco|mondina|monetario|monile|monotono|monsone|montato|monviso|mora|mordere|morsicato|mostro|motivato|motosega|motto|movenza|movimento|mozzo|mucca|mucosa|muffa|mughetto|mugnaio|mulatto|mulinello|multiplo|mummia|munto|muovere|murale|musa|muscolo|musica|mutevole|muto|nababbo|nafta|nanometro|narciso|narice|narrato|nascere|nastrare|naturale|nautica|naviglio|nebulosa|necrosi|negativo|negozio|nemmeno|neofita|neretto|nervo|nessuno|nettuno|neutrale|neve|nevrotico|nicchia|ninfa|nitido|nobile|nocivo|nodo|nome|nomina|nordico|normale|norvegese|nostrano|notare|notizia|notturno|novella|nucleo|nulla|numero|nuovo|nutrire|nuvola|nuziale|oasi|obbedire|obbligo|obelisco|oblio|obolo|obsoleto|occasione|occhio|occidente|occorrere|occultare|ocra|oculato|odierno|odorare|offerta|offrire|offuscato|oggetto|oggi|ognuno|olandese|olfatto|oliato|oliva|ologramma|oltre|omaggio|ombelico|ombra|omega|omissione|ondoso|onere|onice|onnivoro|onorevole|onta|operato|opinione|opposto|oracolo|orafo|ordine|orecchino|orefice|orfano|organico|origine|orizzonte|orma|ormeggio|ornativo|orologio|orrendo|orribile|ortensia|ortica|orzata|orzo|osare|oscurare|osmosi|ospedale|ospite|ossa|ossidare|ostacolo|oste|otite|otre|ottagono|ottimo|ottobre|ovale|ovest|ovino|oviparo|ovocito|ovunque|ovviare|ozio|pacchetto|pace|pacifico|padella|padrone|paese|paga|pagina|palazzina|palesare|pallido|palo|palude|pandoro|pannello|paolo|paonazzo|paprica|parabola|parcella|parere|pargolo|pari|parlato|parola|partire|parvenza|parziale|passivo|pasticca|patacca|patologia|pattume|pavone|peccato|pedalare|pedonale|peggio|peloso|penare|pendice|penisola|pennuto|penombra|pensare|pentola|pepe|pepita|perbene|percorso|perdonato|perforare|pergamena|periodo|permesso|perno|perplesso|persuaso|pertugio|pervaso|pesatore|pesista|peso|pestifero|petalo|pettine|petulante|pezzo|piacere|pianta|piattino|piccino|picozza|piega|pietra|piffero|pigiama|pigolio|pigro|pila|pilifero|pillola|pilota|pimpante|pineta|pinna|pinolo|pioggia|piombo|piramide|piretico|pirite|pirolisi|pitone|pizzico|placebo|planare|plasma|platano|plenario|pochezza|poderoso|podismo|poesia|poggiare|polenta|poligono|pollice|polmonite|polpetta|polso|poltrona|polvere|pomice|pomodoro|ponte|popoloso|porfido|poroso|porpora|porre|portata|posa|positivo|possesso|postulato|potassio|potere|pranzo|prassi|pratica|precluso|predica|prefisso|pregiato|prelievo|premere|prenotare|preparato|presenza|pretesto|prevalso|prima|principe|privato|problema|procura|produrre|profumo|progetto|prolunga|promessa|pronome|proposta|proroga|proteso|prova|prudente|prugna|prurito|psiche|pubblico|pudica|pugilato|pugno|pulce|pulito|pulsante|puntare|pupazzo|pupilla|puro|quadro|qualcosa|quasi|querela|quota|raccolto|raddoppio|radicale|radunato|raffica|ragazzo|ragione|ragno|ramarro|ramingo|ramo|randagio|rantolare|rapato|rapina|rappreso|rasatura|raschiato|rasente|rassegna|rastrello|rata|ravveduto|reale|recepire|recinto|recluta|recondito|recupero|reddito|redimere|regalato|registro|regola|regresso|relazione|remare|remoto|renna|replica|reprimere|reputare|resa|residente|responso|restauro|rete|retina|retorica|rettifica|revocato|riassunto|ribadire|ribelle|ribrezzo|ricarica|ricco|ricevere|riciclato|ricordo|ricreduto|ridicolo|ridurre|rifasare|riflesso|riforma|rifugio|rigare|rigettato|righello|rilassato|rilevato|rimanere|rimbalzo|rimedio|rimorchio|rinascita|rincaro|rinforzo|rinnovo|rinomato|rinsavito|rintocco|rinuncia|rinvenire|riparato|ripetuto|ripieno|riportare|ripresa|ripulire|risata|rischio|riserva|risibile|riso|rispetto|ristoro|risultato|risvolto|ritardo|ritegno|ritmico|ritrovo|riunione|riva|riverso|rivincita|rivolto|rizoma|roba|robotico|robusto|roccia|roco|rodaggio|rodere|roditore|rogito|rollio|romantico|rompere|ronzio|rosolare|rospo|rotante|rotondo|rotula|rovescio|rubizzo|rubrica|ruga|rullino|rumine|rumoroso|ruolo|rupe|russare|rustico|sabato|sabbiare|sabotato|sagoma|salasso|saldatura|salgemma|salivare|salmone|salone|saltare|saluto|salvo|sapere|sapido|saporito|saraceno|sarcasmo|sarto|sassoso|satellite|satira|satollo|saturno|savana|savio|saziato|sbadiglio|sbalzo|sbancato|sbarra|sbattere|sbavare|sbendare|sbirciare|sbloccato|sbocciato|sbrinare|sbruffone|sbuffare|scabroso|scadenza|scala|scambiare|scandalo|scapola|scarso|scatenare|scavato|scelto|scenico|scettro|scheda|schiena|sciarpa|scienza|scindere|scippo|sciroppo|scivolo|sclerare|scodella|scolpito|scomparto|sconforto|scoprire|scorta|scossone|scozzese|scriba|scrollare|scrutinio|scuderia|scultore|scuola|scuro|scusare|sdebitare|sdoganare|seccatura|secondo|sedano|seggiola|segnalato|segregato|seguito|selciato|selettivo|sella|selvaggio|semaforo|sembrare|seme|seminato|sempre|senso|sentire|sepolto|sequenza|serata|serbato|sereno|serio|serpente|serraglio|servire|sestina|setola|settimana|sfacelo|sfaldare|sfamato|sfarzoso|sfaticato|sfera|sfida|sfilato|sfinge|sfocato|sfoderare|sfogo|sfoltire|sforzato|sfratto|sfruttato|sfuggito|sfumare|sfuso|sgabello|sgarbato|sgonfiare|sgorbio|sgrassato|sguardo|sibilo|siccome|sierra|sigla|signore|silenzio|sillaba|simbolo|simpatico|simulato|sinfonia|singolo|sinistro|sino|sintesi|sinusoide|sipario|sisma|sistole|situato|slitta|slogatura|sloveno|smarrito|smemorato|smentito|smeraldo|smilzo|smontare|smottato|smussato|snellire|snervato|snodo|sobbalzo|sobrio|soccorso|sociale|sodale|soffitto|sogno|soldato|solenne|solido|sollazzo|solo|solubile|solvente|somatico|somma|sonda|sonetto|sonnifero|sopire|soppeso|sopra|sorgere|sorpasso|sorriso|sorso|sorteggio|sorvolato|sospiro|sosta|sottile|spada|spalla|spargere|spatola|spavento|spazzola|specie|spedire|spegnere|spelatura|speranza|spessore|spettrale|spezzato|spia|spigoloso|spillato|spinoso|spirale|splendido|sportivo|sposo|spranga|sprecare|spronato|spruzzo|spuntino|squillo|sradicare|srotolato|stabile|stacco|staffa|stagnare|stampato|stantio|starnuto|stasera|statuto|stelo|steppa|sterzo|stiletto|stima|stirpe|stivale|stizzoso|stonato|storico|strappo|stregato|stridulo|strozzare|strutto|stuccare|stufo|stupendo|subentro|succoso|sudore|suggerito|sugo|sultano|suonare|superbo|supporto|surgelato|surrogato|sussurro|sutura|svagare|svedese|sveglio|svelare|svenuto|svezia|sviluppo|svista|svizzera|svolta|svuotare|tabacco|tabulato|tacciare|taciturno|tale|talismano|tampone|tannino|tara|tardivo|targato|tariffa|tarpare|tartaruga|tasto|tattico|taverna|tavolata|tazza|teca|tecnico|telefono|temerario|tempo|temuto|tendone|tenero|tensione|tentacolo|teorema|terme|terrazzo|terzetto|tesi|tesserato|testato|tetro|tettoia|tifare|tigella|timbro|tinto|tipico|tipografo|tiraggio|tiro|titanio|titolo|titubante|tizio|tizzone|toccare|tollerare|tolto|tombola|tomo|tonfo|tonsilla|topazio|topologia|toppa|torba|tornare|torrone|tortora|toscano|tossire|tostatura|totano|trabocco|trachea|trafila|tragedia|tralcio|tramonto|transito|trapano|trarre|trasloco|trattato|trave|treccia|tremolio|trespolo|tributo|tricheco|trifoglio|trillo|trincea|trio|tristezza|triturato|trivella|tromba|trono|troppo|trottola|trovare|truccato|tubatura|tuffato|tulipano|tumulto|tunisia|turbare|turchino|tuta|tutela|ubicato|uccello|uccisore|udire|uditivo|uffa|ufficio|uguale|ulisse|ultimato|umano|umile|umorismo|uncinetto|ungere|ungherese|unicorno|unificato|unisono|unitario|unte|uovo|upupa|uragano|urgenza|urlo|usanza|usato|uscito|usignolo|usuraio|utensile|utilizzo|utopia|vacante|vaccinato|vagabondo|vagliato|valanga|valgo|valico|valletta|valoroso|valutare|valvola|vampata|vangare|vanitoso|vano|vantaggio|vanvera|vapore|varano|varcato|variante|vasca|vedetta|vedova|veduto|vegetale|veicolo|velcro|velina|velluto|veloce|venato|vendemmia|vento|verace|verbale|vergogna|verifica|vero|verruca|verticale|vescica|vessillo|vestale|veterano|vetrina|vetusto|viandante|vibrante|vicenda|vichingo|vicinanza|vidimare|vigilia|vigneto|vigore|vile|villano|vimini|vincitore|viola|vipera|virgola|virologo|virulento|viscoso|visione|vispo|vissuto|visura|vita|vitello|vittima|vivanda|vivido|viziare|voce|voga|volatile|volere|volpe|voragine|vulcano|zampogna|zanna|zappato|zattera|zavorra|zefiro|zelante|zelo|zenzero|zerbino|zibetto|zinco|zircone|zitto|zolla|zotico|zucchero|zufolo|zulu|zuppa'.split('|'); diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/jp.d.ts b/packages/util-crypto/cjs/mnemonic/wordlists/jp.d.ts new file mode 100644 index 0000000..d451d2b --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/jp.d.ts @@ -0,0 +1,2 @@ +declare const _default: string[]; +export default _default; diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/jp.js b/packages/util-crypto/cjs/mnemonic/wordlists/jp.js new file mode 100644 index 0000000..c526a41 --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/jp.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = 'あいこくしん|あいさつ|あいだ|あおぞら|あかちゃん|あきる|あけがた|あける|あこがれる|あさい|あさひ|あしあと|あじわう|あずかる|あずき|あそぶ|あたえる|あたためる|あたりまえ|あたる|あつい|あつかう|あっしゅく|あつまり|あつめる|あてな|あてはまる|あひる|あぶら|あぶる|あふれる|あまい|あまど|あまやかす|あまり|あみもの|あめりか|あやまる|あゆむ|あらいぐま|あらし|あらすじ|あらためる|あらゆる|あらわす|ありがとう|あわせる|あわてる|あんい|あんがい|あんこ|あんぜん|あんてい|あんない|あんまり|いいだす|いおん|いがい|いがく|いきおい|いきなり|いきもの|いきる|いくじ|いくぶん|いけばな|いけん|いこう|いこく|いこつ|いさましい|いさん|いしき|いじゅう|いじょう|いじわる|いずみ|いずれ|いせい|いせえび|いせかい|いせき|いぜん|いそうろう|いそがしい|いだい|いだく|いたずら|いたみ|いたりあ|いちおう|いちじ|いちど|いちば|いちぶ|いちりゅう|いつか|いっしゅん|いっせい|いっそう|いったん|いっち|いってい|いっぽう|いてざ|いてん|いどう|いとこ|いない|いなか|いねむり|いのち|いのる|いはつ|いばる|いはん|いびき|いひん|いふく|いへん|いほう|いみん|いもうと|いもたれ|いもり|いやがる|いやす|いよかん|いよく|いらい|いらすと|いりぐち|いりょう|いれい|いれもの|いれる|いろえんぴつ|いわい|いわう|いわかん|いわば|いわゆる|いんげんまめ|いんさつ|いんしょう|いんよう|うえき|うえる|うおざ|うがい|うかぶ|うかべる|うきわ|うくらいな|うくれれ|うけたまわる|うけつけ|うけとる|うけもつ|うける|うごかす|うごく|うこん|うさぎ|うしなう|うしろがみ|うすい|うすぎ|うすぐらい|うすめる|うせつ|うちあわせ|うちがわ|うちき|うちゅう|うっかり|うつくしい|うったえる|うつる|うどん|うなぎ|うなじ|うなずく|うなる|うねる|うのう|うぶげ|うぶごえ|うまれる|うめる|うもう|うやまう|うよく|うらがえす|うらぐち|うらない|うりあげ|うりきれ|うるさい|うれしい|うれゆき|うれる|うろこ|うわき|うわさ|うんこう|うんちん|うんてん|うんどう|えいえん|えいが|えいきょう|えいご|えいせい|えいぶん|えいよう|えいわ|えおり|えがお|えがく|えきたい|えくせる|えしゃく|えすて|えつらん|えのぐ|えほうまき|えほん|えまき|えもじ|えもの|えらい|えらぶ|えりあ|えんえん|えんかい|えんぎ|えんげき|えんしゅう|えんぜつ|えんそく|えんちょう|えんとつ|おいかける|おいこす|おいしい|おいつく|おうえん|おうさま|おうじ|おうせつ|おうたい|おうふく|おうべい|おうよう|おえる|おおい|おおう|おおどおり|おおや|おおよそ|おかえり|おかず|おがむ|おかわり|おぎなう|おきる|おくさま|おくじょう|おくりがな|おくる|おくれる|おこす|おこなう|おこる|おさえる|おさない|おさめる|おしいれ|おしえる|おじぎ|おじさん|おしゃれ|おそらく|おそわる|おたがい|おたく|おだやか|おちつく|おっと|おつり|おでかけ|おとしもの|おとなしい|おどり|おどろかす|おばさん|おまいり|おめでとう|おもいで|おもう|おもたい|おもちゃ|おやつ|おやゆび|およぼす|おらんだ|おろす|おんがく|おんけい|おんしゃ|おんせん|おんだん|おんちゅう|おんどけい|かあつ|かいが|がいき|がいけん|がいこう|かいさつ|かいしゃ|かいすいよく|かいぜん|かいぞうど|かいつう|かいてん|かいとう|かいふく|がいへき|かいほう|かいよう|がいらい|かいわ|かえる|かおり|かかえる|かがく|かがし|かがみ|かくご|かくとく|かざる|がぞう|かたい|かたち|がちょう|がっきゅう|がっこう|がっさん|がっしょう|かなざわし|かのう|がはく|かぶか|かほう|かほご|かまう|かまぼこ|かめれおん|かゆい|かようび|からい|かるい|かろう|かわく|かわら|がんか|かんけい|かんこう|かんしゃ|かんそう|かんたん|かんち|がんばる|きあい|きあつ|きいろ|ぎいん|きうい|きうん|きえる|きおう|きおく|きおち|きおん|きかい|きかく|きかんしゃ|ききて|きくばり|きくらげ|きけんせい|きこう|きこえる|きこく|きさい|きさく|きさま|きさらぎ|ぎじかがく|ぎしき|ぎじたいけん|ぎじにってい|ぎじゅつしゃ|きすう|きせい|きせき|きせつ|きそう|きぞく|きぞん|きたえる|きちょう|きつえん|ぎっちり|きつつき|きつね|きてい|きどう|きどく|きない|きなが|きなこ|きぬごし|きねん|きのう|きのした|きはく|きびしい|きひん|きふく|きぶん|きぼう|きほん|きまる|きみつ|きむずかしい|きめる|きもだめし|きもち|きもの|きゃく|きやく|ぎゅうにく|きよう|きょうりゅう|きらい|きらく|きりん|きれい|きれつ|きろく|ぎろん|きわめる|ぎんいろ|きんかくじ|きんじょ|きんようび|ぐあい|くいず|くうかん|くうき|くうぐん|くうこう|ぐうせい|くうそう|ぐうたら|くうふく|くうぼ|くかん|くきょう|くげん|ぐこう|くさい|くさき|くさばな|くさる|くしゃみ|くしょう|くすのき|くすりゆび|くせげ|くせん|ぐたいてき|くださる|くたびれる|くちこみ|くちさき|くつした|ぐっすり|くつろぐ|くとうてん|くどく|くなん|くねくね|くのう|くふう|くみあわせ|くみたてる|くめる|くやくしょ|くらす|くらべる|くるま|くれる|くろう|くわしい|ぐんかん|ぐんしょく|ぐんたい|ぐんて|けあな|けいかく|けいけん|けいこ|けいさつ|げいじゅつ|けいたい|げいのうじん|けいれき|けいろ|けおとす|けおりもの|げきか|げきげん|げきだん|げきちん|げきとつ|げきは|げきやく|げこう|げこくじょう|げざい|けさき|げざん|けしき|けしごむ|けしょう|げすと|けたば|けちゃっぷ|けちらす|けつあつ|けつい|けつえき|けっこん|けつじょ|けっせき|けってい|けつまつ|げつようび|げつれい|けつろん|げどく|けとばす|けとる|けなげ|けなす|けなみ|けぬき|げねつ|けねん|けはい|げひん|けぶかい|げぼく|けまり|けみかる|けむし|けむり|けもの|けらい|けろけろ|けわしい|けんい|けんえつ|けんお|けんか|げんき|けんげん|けんこう|けんさく|けんしゅう|けんすう|げんそう|けんちく|けんてい|けんとう|けんない|けんにん|げんぶつ|けんま|けんみん|けんめい|けんらん|けんり|こあくま|こいぬ|こいびと|ごうい|こうえん|こうおん|こうかん|ごうきゅう|ごうけい|こうこう|こうさい|こうじ|こうすい|ごうせい|こうそく|こうたい|こうちゃ|こうつう|こうてい|こうどう|こうない|こうはい|ごうほう|ごうまん|こうもく|こうりつ|こえる|こおり|ごかい|ごがつ|ごかん|こくご|こくさい|こくとう|こくない|こくはく|こぐま|こけい|こける|ここのか|こころ|こさめ|こしつ|こすう|こせい|こせき|こぜん|こそだて|こたい|こたえる|こたつ|こちょう|こっか|こつこつ|こつばん|こつぶ|こてい|こてん|ことがら|ことし|ことば|ことり|こなごな|こねこね|このまま|このみ|このよ|ごはん|こひつじ|こふう|こふん|こぼれる|ごまあぶら|こまかい|ごますり|こまつな|こまる|こむぎこ|こもじ|こもち|こもの|こもん|こやく|こやま|こゆう|こゆび|こよい|こよう|こりる|これくしょん|ころっけ|こわもて|こわれる|こんいん|こんかい|こんき|こんしゅう|こんすい|こんだて|こんとん|こんなん|こんびに|こんぽん|こんまけ|こんや|こんれい|こんわく|ざいえき|さいかい|さいきん|ざいげん|ざいこ|さいしょ|さいせい|ざいたく|ざいちゅう|さいてき|ざいりょう|さうな|さかいし|さがす|さかな|さかみち|さがる|さぎょう|さくし|さくひん|さくら|さこく|さこつ|さずかる|ざせき|さたん|さつえい|ざつおん|ざっか|ざつがく|さっきょく|ざっし|さつじん|ざっそう|さつたば|さつまいも|さてい|さといも|さとう|さとおや|さとし|さとる|さのう|さばく|さびしい|さべつ|さほう|さほど|さます|さみしい|さみだれ|さむけ|さめる|さやえんどう|さゆう|さよう|さよく|さらだ|ざるそば|さわやか|さわる|さんいん|さんか|さんきゃく|さんこう|さんさい|ざんしょ|さんすう|さんせい|さんそ|さんち|さんま|さんみ|さんらん|しあい|しあげ|しあさって|しあわせ|しいく|しいん|しうち|しえい|しおけ|しかい|しかく|じかん|しごと|しすう|じだい|したうけ|したぎ|したて|したみ|しちょう|しちりん|しっかり|しつじ|しつもん|してい|してき|してつ|じてん|じどう|しなぎれ|しなもの|しなん|しねま|しねん|しのぐ|しのぶ|しはい|しばかり|しはつ|しはらい|しはん|しひょう|しふく|じぶん|しへい|しほう|しほん|しまう|しまる|しみん|しむける|じむしょ|しめい|しめる|しもん|しゃいん|しゃうん|しゃおん|じゃがいも|しやくしょ|しゃくほう|しゃけん|しゃこ|しゃざい|しゃしん|しゃせん|しゃそう|しゃたい|しゃちょう|しゃっきん|じゃま|しゃりん|しゃれい|じゆう|じゅうしょ|しゅくはく|じゅしん|しゅっせき|しゅみ|しゅらば|じゅんばん|しょうかい|しょくたく|しょっけん|しょどう|しょもつ|しらせる|しらべる|しんか|しんこう|じんじゃ|しんせいじ|しんちく|しんりん|すあげ|すあし|すあな|ずあん|すいえい|すいか|すいとう|ずいぶん|すいようび|すうがく|すうじつ|すうせん|すおどり|すきま|すくう|すくない|すける|すごい|すこし|ずさん|すずしい|すすむ|すすめる|すっかり|ずっしり|ずっと|すてき|すてる|すねる|すのこ|すはだ|すばらしい|ずひょう|ずぶぬれ|すぶり|すふれ|すべて|すべる|ずほう|すぼん|すまい|すめし|すもう|すやき|すらすら|するめ|すれちがう|すろっと|すわる|すんぜん|すんぽう|せあぶら|せいかつ|せいげん|せいじ|せいよう|せおう|せかいかん|せきにん|せきむ|せきゆ|せきらんうん|せけん|せこう|せすじ|せたい|せたけ|せっかく|せっきゃく|ぜっく|せっけん|せっこつ|せっさたくま|せつぞく|せつだん|せつでん|せっぱん|せつび|せつぶん|せつめい|せつりつ|せなか|せのび|せはば|せびろ|せぼね|せまい|せまる|せめる|せもたれ|せりふ|ぜんあく|せんい|せんえい|せんか|せんきょ|せんく|せんげん|ぜんご|せんさい|せんしゅ|せんすい|せんせい|せんぞ|せんたく|せんちょう|せんてい|せんとう|せんぬき|せんねん|せんぱい|ぜんぶ|ぜんぽう|せんむ|せんめんじょ|せんもん|せんやく|せんゆう|せんよう|ぜんら|ぜんりゃく|せんれい|せんろ|そあく|そいとげる|そいね|そうがんきょう|そうき|そうご|そうしん|そうだん|そうなん|そうび|そうめん|そうり|そえもの|そえん|そがい|そげき|そこう|そこそこ|そざい|そしな|そせい|そせん|そそぐ|そだてる|そつう|そつえん|そっかん|そつぎょう|そっけつ|そっこう|そっせん|そっと|そとがわ|そとづら|そなえる|そなた|そふぼ|そぼく|そぼろ|そまつ|そまる|そむく|そむりえ|そめる|そもそも|そよかぜ|そらまめ|そろう|そんかい|そんけい|そんざい|そんしつ|そんぞく|そんちょう|ぞんび|ぞんぶん|そんみん|たあい|たいいん|たいうん|たいえき|たいおう|だいがく|たいき|たいぐう|たいけん|たいこ|たいざい|だいじょうぶ|だいすき|たいせつ|たいそう|だいたい|たいちょう|たいてい|だいどころ|たいない|たいねつ|たいのう|たいはん|だいひょう|たいふう|たいへん|たいほ|たいまつばな|たいみんぐ|たいむ|たいめん|たいやき|たいよう|たいら|たいりょく|たいる|たいわん|たうえ|たえる|たおす|たおる|たおれる|たかい|たかね|たきび|たくさん|たこく|たこやき|たさい|たしざん|だじゃれ|たすける|たずさわる|たそがれ|たたかう|たたく|ただしい|たたみ|たちばな|だっかい|だっきゃく|だっこ|だっしゅつ|だったい|たてる|たとえる|たなばた|たにん|たぬき|たのしみ|たはつ|たぶん|たべる|たぼう|たまご|たまる|だむる|ためいき|ためす|ためる|たもつ|たやすい|たよる|たらす|たりきほんがん|たりょう|たりる|たると|たれる|たれんと|たろっと|たわむれる|だんあつ|たんい|たんおん|たんか|たんき|たんけん|たんご|たんさん|たんじょうび|だんせい|たんそく|たんたい|だんち|たんてい|たんとう|だんな|たんにん|だんねつ|たんのう|たんぴん|だんぼう|たんまつ|たんめい|だんれつ|だんろ|だんわ|ちあい|ちあん|ちいき|ちいさい|ちえん|ちかい|ちから|ちきゅう|ちきん|ちけいず|ちけん|ちこく|ちさい|ちしき|ちしりょう|ちせい|ちそう|ちたい|ちたん|ちちおや|ちつじょ|ちてき|ちてん|ちぬき|ちぬり|ちのう|ちひょう|ちへいせん|ちほう|ちまた|ちみつ|ちみどろ|ちめいど|ちゃんこなべ|ちゅうい|ちゆりょく|ちょうし|ちょさくけん|ちらし|ちらみ|ちりがみ|ちりょう|ちるど|ちわわ|ちんたい|ちんもく|ついか|ついたち|つうか|つうじょう|つうはん|つうわ|つかう|つかれる|つくね|つくる|つけね|つける|つごう|つたえる|つづく|つつじ|つつむ|つとめる|つながる|つなみ|つねづね|つのる|つぶす|つまらない|つまる|つみき|つめたい|つもり|つもる|つよい|つるぼ|つるみく|つわもの|つわり|てあし|てあて|てあみ|ていおん|ていか|ていき|ていけい|ていこく|ていさつ|ていし|ていせい|ていたい|ていど|ていねい|ていひょう|ていへん|ていぼう|てうち|ておくれ|てきとう|てくび|でこぼこ|てさぎょう|てさげ|てすり|てそう|てちがい|てちょう|てつがく|てつづき|でっぱ|てつぼう|てつや|でぬかえ|てぬき|てぬぐい|てのひら|てはい|てぶくろ|てふだ|てほどき|てほん|てまえ|てまきずし|てみじか|てみやげ|てらす|てれび|てわけ|てわたし|でんあつ|てんいん|てんかい|てんき|てんぐ|てんけん|てんごく|てんさい|てんし|てんすう|でんち|てんてき|てんとう|てんない|てんぷら|てんぼうだい|てんめつ|てんらんかい|でんりょく|でんわ|どあい|といれ|どうかん|とうきゅう|どうぐ|とうし|とうむぎ|とおい|とおか|とおく|とおす|とおる|とかい|とかす|ときおり|ときどき|とくい|とくしゅう|とくてん|とくに|とくべつ|とけい|とける|とこや|とさか|としょかん|とそう|とたん|とちゅう|とっきゅう|とっくん|とつぜん|とつにゅう|とどける|ととのえる|とない|となえる|となり|とのさま|とばす|どぶがわ|とほう|とまる|とめる|ともだち|ともる|どようび|とらえる|とんかつ|どんぶり|ないかく|ないこう|ないしょ|ないす|ないせん|ないそう|なおす|ながい|なくす|なげる|なこうど|なさけ|なたでここ|なっとう|なつやすみ|ななおし|なにごと|なにもの|なにわ|なのか|なふだ|なまいき|なまえ|なまみ|なみだ|なめらか|なめる|なやむ|ならう|ならび|ならぶ|なれる|なわとび|なわばり|にあう|にいがた|にうけ|におい|にかい|にがて|にきび|にくしみ|にくまん|にげる|にさんかたんそ|にしき|にせもの|にちじょう|にちようび|にっか|にっき|にっけい|にっこう|にっさん|にっしょく|にっすう|にっせき|にってい|になう|にほん|にまめ|にもつ|にやり|にゅういん|にりんしゃ|にわとり|にんい|にんか|にんき|にんげん|にんしき|にんずう|にんそう|にんたい|にんち|にんてい|にんにく|にんぷ|にんまり|にんむ|にんめい|にんよう|ぬいくぎ|ぬかす|ぬぐいとる|ぬぐう|ぬくもり|ぬすむ|ぬまえび|ぬめり|ぬらす|ぬんちゃく|ねあげ|ねいき|ねいる|ねいろ|ねぐせ|ねくたい|ねくら|ねこぜ|ねこむ|ねさげ|ねすごす|ねそべる|ねだん|ねつい|ねっしん|ねつぞう|ねったいぎょ|ねぶそく|ねふだ|ねぼう|ねほりはほり|ねまき|ねまわし|ねみみ|ねむい|ねむたい|ねもと|ねらう|ねわざ|ねんいり|ねんおし|ねんかん|ねんきん|ねんぐ|ねんざ|ねんし|ねんちゃく|ねんど|ねんぴ|ねんぶつ|ねんまつ|ねんりょう|ねんれい|のいず|のおづま|のがす|のきなみ|のこぎり|のこす|のこる|のせる|のぞく|のぞむ|のたまう|のちほど|のっく|のばす|のはら|のべる|のぼる|のみもの|のやま|のらいぬ|のらねこ|のりもの|のりゆき|のれん|のんき|ばあい|はあく|ばあさん|ばいか|ばいく|はいけん|はいご|はいしん|はいすい|はいせん|はいそう|はいち|ばいばい|はいれつ|はえる|はおる|はかい|ばかり|はかる|はくしゅ|はけん|はこぶ|はさみ|はさん|はしご|ばしょ|はしる|はせる|ぱそこん|はそん|はたん|はちみつ|はつおん|はっかく|はづき|はっきり|はっくつ|はっけん|はっこう|はっさん|はっしん|はったつ|はっちゅう|はってん|はっぴょう|はっぽう|はなす|はなび|はにかむ|はぶらし|はみがき|はむかう|はめつ|はやい|はやし|はらう|はろうぃん|はわい|はんい|はんえい|はんおん|はんかく|はんきょう|ばんぐみ|はんこ|はんしゃ|はんすう|はんだん|ぱんち|ぱんつ|はんてい|はんとし|はんのう|はんぱ|はんぶん|はんぺん|はんぼうき|はんめい|はんらん|はんろん|ひいき|ひうん|ひえる|ひかく|ひかり|ひかる|ひかん|ひくい|ひけつ|ひこうき|ひこく|ひさい|ひさしぶり|ひさん|びじゅつかん|ひしょ|ひそか|ひそむ|ひたむき|ひだり|ひたる|ひつぎ|ひっこし|ひっし|ひつじゅひん|ひっす|ひつぜん|ぴったり|ぴっちり|ひつよう|ひてい|ひとごみ|ひなまつり|ひなん|ひねる|ひはん|ひびく|ひひょう|ひほう|ひまわり|ひまん|ひみつ|ひめい|ひめじし|ひやけ|ひやす|ひよう|びょうき|ひらがな|ひらく|ひりつ|ひりょう|ひるま|ひるやすみ|ひれい|ひろい|ひろう|ひろき|ひろゆき|ひんかく|ひんけつ|ひんこん|ひんしゅ|ひんそう|ぴんち|ひんぱん|びんぼう|ふあん|ふいうち|ふうけい|ふうせん|ぷうたろう|ふうとう|ふうふ|ふえる|ふおん|ふかい|ふきん|ふくざつ|ふくぶくろ|ふこう|ふさい|ふしぎ|ふじみ|ふすま|ふせい|ふせぐ|ふそく|ぶたにく|ふたん|ふちょう|ふつう|ふつか|ふっかつ|ふっき|ふっこく|ぶどう|ふとる|ふとん|ふのう|ふはい|ふひょう|ふへん|ふまん|ふみん|ふめつ|ふめん|ふよう|ふりこ|ふりる|ふるい|ふんいき|ぶんがく|ぶんぐ|ふんしつ|ぶんせき|ふんそう|ぶんぽう|へいあん|へいおん|へいがい|へいき|へいげん|へいこう|へいさ|へいしゃ|へいせつ|へいそ|へいたく|へいてん|へいねつ|へいわ|へきが|へこむ|べにいろ|べにしょうが|へらす|へんかん|べんきょう|べんごし|へんさい|へんたい|べんり|ほあん|ほいく|ぼうぎょ|ほうこく|ほうそう|ほうほう|ほうもん|ほうりつ|ほえる|ほおん|ほかん|ほきょう|ぼきん|ほくろ|ほけつ|ほけん|ほこう|ほこる|ほしい|ほしつ|ほしゅ|ほしょう|ほせい|ほそい|ほそく|ほたて|ほたる|ぽちぶくろ|ほっきょく|ほっさ|ほったん|ほとんど|ほめる|ほんい|ほんき|ほんけ|ほんしつ|ほんやく|まいにち|まかい|まかせる|まがる|まける|まこと|まさつ|まじめ|ますく|まぜる|まつり|まとめ|まなぶ|まぬけ|まねく|まほう|まもる|まゆげ|まよう|まろやか|まわす|まわり|まわる|まんが|まんきつ|まんぞく|まんなか|みいら|みうち|みえる|みがく|みかた|みかん|みけん|みこん|みじかい|みすい|みすえる|みせる|みっか|みつかる|みつける|みてい|みとめる|みなと|みなみかさい|みねらる|みのう|みのがす|みほん|みもと|みやげ|みらい|みりょく|みわく|みんか|みんぞく|むいか|むえき|むえん|むかい|むかう|むかえ|むかし|むぎちゃ|むける|むげん|むさぼる|むしあつい|むしば|むじゅん|むしろ|むすう|むすこ|むすぶ|むすめ|むせる|むせん|むちゅう|むなしい|むのう|むやみ|むよう|むらさき|むりょう|むろん|めいあん|めいうん|めいえん|めいかく|めいきょく|めいさい|めいし|めいそう|めいぶつ|めいれい|めいわく|めぐまれる|めざす|めした|めずらしい|めだつ|めまい|めやす|めんきょ|めんせき|めんどう|もうしあげる|もうどうけん|もえる|もくし|もくてき|もくようび|もちろん|もどる|もらう|もんく|もんだい|やおや|やける|やさい|やさしい|やすい|やすたろう|やすみ|やせる|やそう|やたい|やちん|やっと|やっぱり|やぶる|やめる|ややこしい|やよい|やわらかい|ゆうき|ゆうびんきょく|ゆうべ|ゆうめい|ゆけつ|ゆしゅつ|ゆせん|ゆそう|ゆたか|ゆちゃく|ゆでる|ゆにゅう|ゆびわ|ゆらい|ゆれる|ようい|ようか|ようきゅう|ようじ|ようす|ようちえん|よかぜ|よかん|よきん|よくせい|よくぼう|よけい|よごれる|よさん|よしゅう|よそう|よそく|よっか|よてい|よどがわく|よねつ|よやく|よゆう|よろこぶ|よろしい|らいう|らくがき|らくご|らくさつ|らくだ|らしんばん|らせん|らぞく|らたい|らっか|られつ|りえき|りかい|りきさく|りきせつ|りくぐん|りくつ|りけん|りこう|りせい|りそう|りそく|りてん|りねん|りゆう|りゅうがく|りよう|りょうり|りょかん|りょくちゃ|りょこう|りりく|りれき|りろん|りんご|るいけい|るいさい|るいじ|るいせき|るすばん|るりがわら|れいかん|れいぎ|れいせい|れいぞうこ|れいとう|れいぼう|れきし|れきだい|れんあい|れんけい|れんこん|れんさい|れんしゅう|れんぞく|れんらく|ろうか|ろうご|ろうじん|ろうそく|ろくが|ろこつ|ろじうら|ろしゅつ|ろせん|ろてん|ろめん|ろれつ|ろんぎ|ろんぱ|ろんぶん|ろんり|わかす|わかめ|わかやま|わかれる|わしつ|わじまし|わすれもの|わらう|われる'.split('|'); diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/ko.d.ts b/packages/util-crypto/cjs/mnemonic/wordlists/ko.d.ts new file mode 100644 index 0000000..d451d2b --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/ko.d.ts @@ -0,0 +1,2 @@ +declare const _default: string[]; +export default _default; diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/ko.js b/packages/util-crypto/cjs/mnemonic/wordlists/ko.js new file mode 100644 index 0000000..657ee2b --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/ko.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = '가격|가끔|가난|가능|가득|가르침|가뭄|가방|가상|가슴|가운데|가을|가이드|가입|가장|가정|가족|가죽|각오|각자|간격|간부|간섭|간장|간접|간판|갈등|갈비|갈색|갈증|감각|감기|감소|감수성|감자|감정|갑자기|강남|강당|강도|강력히|강변|강북|강사|강수량|강아지|강원도|강의|강제|강조|같이|개구리|개나리|개방|개별|개선|개성|개인|객관적|거실|거액|거울|거짓|거품|걱정|건강|건물|건설|건조|건축|걸음|검사|검토|게시판|게임|겨울|견해|결과|결국|결론|결석|결승|결심|결정|결혼|경계|경고|경기|경력|경복궁|경비|경상도|경영|경우|경쟁|경제|경주|경찰|경치|경향|경험|계곡|계단|계란|계산|계속|계약|계절|계층|계획|고객|고구려|고궁|고급|고등학생|고무신|고민|고양이|고장|고전|고집|고춧가루|고통|고향|곡식|골목|골짜기|골프|공간|공개|공격|공군|공급|공기|공동|공무원|공부|공사|공식|공업|공연|공원|공장|공짜|공책|공통|공포|공항|공휴일|과목|과일|과장|과정|과학|관객|관계|관광|관념|관람|관련|관리|관습|관심|관점|관찰|광경|광고|광장|광주|괴로움|굉장히|교과서|교문|교복|교실|교양|교육|교장|교직|교통|교환|교훈|구경|구름|구멍|구별|구분|구석|구성|구속|구역|구입|구청|구체적|국가|국기|국내|국립|국물|국민|국수|국어|국왕|국적|국제|국회|군대|군사|군인|궁극적|권리|권위|권투|귀국|귀신|규정|규칙|균형|그날|그냥|그늘|그러나|그룹|그릇|그림|그제서야|그토록|극복|극히|근거|근교|근래|근로|근무|근본|근원|근육|근처|글씨|글자|금강산|금고|금년|금메달|금액|금연|금요일|금지|긍정적|기간|기관|기념|기능|기독교|기둥|기록|기름|기법|기본|기분|기쁨|기숙사|기술|기억|기업|기온|기운|기원|기적|기준|기침|기혼|기획|긴급|긴장|길이|김밥|김치|김포공항|깍두기|깜빡|깨달음|깨소금|껍질|꼭대기|꽃잎|나들이|나란히|나머지|나물|나침반|나흘|낙엽|난방|날개|날씨|날짜|남녀|남대문|남매|남산|남자|남편|남학생|낭비|낱말|내년|내용|내일|냄비|냄새|냇물|냉동|냉면|냉방|냉장고|넥타이|넷째|노동|노란색|노력|노인|녹음|녹차|녹화|논리|논문|논쟁|놀이|농구|농담|농민|농부|농업|농장|농촌|높이|눈동자|눈물|눈썹|뉴욕|느낌|늑대|능동적|능력|다방|다양성|다음|다이어트|다행|단계|단골|단독|단맛|단순|단어|단위|단점|단체|단추|단편|단풍|달걀|달러|달력|달리|닭고기|담당|담배|담요|담임|답변|답장|당근|당분간|당연히|당장|대규모|대낮|대단히|대답|대도시|대략|대량|대륙|대문|대부분|대신|대응|대장|대전|대접|대중|대책|대출|대충|대통령|대학|대한민국|대합실|대형|덩어리|데이트|도대체|도덕|도둑|도망|도서관|도심|도움|도입|도자기|도저히|도전|도중|도착|독감|독립|독서|독일|독창적|동화책|뒷모습|뒷산|딸아이|마누라|마늘|마당|마라톤|마련|마무리|마사지|마약|마요네즈|마을|마음|마이크|마중|마지막|마찬가지|마찰|마흔|막걸리|막내|막상|만남|만두|만세|만약|만일|만점|만족|만화|많이|말기|말씀|말투|맘대로|망원경|매년|매달|매력|매번|매스컴|매일|매장|맥주|먹이|먼저|먼지|멀리|메일|며느리|며칠|면담|멸치|명단|명령|명예|명의|명절|명칭|명함|모금|모니터|모델|모든|모범|모습|모양|모임|모조리|모집|모퉁이|목걸이|목록|목사|목소리|목숨|목적|목표|몰래|몸매|몸무게|몸살|몸속|몸짓|몸통|몹시|무관심|무궁화|무더위|무덤|무릎|무슨|무엇|무역|무용|무조건|무지개|무척|문구|문득|문법|문서|문제|문학|문화|물가|물건|물결|물고기|물론|물리학|물음|물질|물체|미국|미디어|미사일|미술|미역|미용실|미움|미인|미팅|미혼|민간|민족|민주|믿음|밀가루|밀리미터|밑바닥|바가지|바구니|바나나|바늘|바닥|바닷가|바람|바이러스|바탕|박물관|박사|박수|반대|반드시|반말|반발|반성|반응|반장|반죽|반지|반찬|받침|발가락|발걸음|발견|발달|발레|발목|발바닥|발생|발음|발자국|발전|발톱|발표|밤하늘|밥그릇|밥맛|밥상|밥솥|방금|방면|방문|방바닥|방법|방송|방식|방안|방울|방지|방학|방해|방향|배경|배꼽|배달|배드민턴|백두산|백색|백성|백인|백제|백화점|버릇|버섯|버튼|번개|번역|번지|번호|벌금|벌레|벌써|범위|범인|범죄|법률|법원|법적|법칙|베이징|벨트|변경|변동|변명|변신|변호사|변화|별도|별명|별일|병실|병아리|병원|보관|보너스|보라색|보람|보름|보상|보안|보자기|보장|보전|보존|보통|보편적|보험|복도|복사|복숭아|복습|볶음|본격적|본래|본부|본사|본성|본인|본질|볼펜|봉사|봉지|봉투|부근|부끄러움|부담|부동산|부문|부분|부산|부상|부엌|부인|부작용|부장|부정|부족|부지런히|부친|부탁|부품|부회장|북부|북한|분노|분량|분리|분명|분석|분야|분위기|분필|분홍색|불고기|불과|불교|불꽃|불만|불법|불빛|불안|불이익|불행|브랜드|비극|비난|비닐|비둘기|비디오|비로소|비만|비명|비밀|비바람|비빔밥|비상|비용|비율|비중|비타민|비판|빌딩|빗물|빗방울|빗줄기|빛깔|빨간색|빨래|빨리|사건|사계절|사나이|사냥|사람|사랑|사립|사모님|사물|사방|사상|사생활|사설|사슴|사실|사업|사용|사월|사장|사전|사진|사촌|사춘기|사탕|사투리|사흘|산길|산부인과|산업|산책|살림|살인|살짝|삼계탕|삼국|삼십|삼월|삼촌|상관|상금|상대|상류|상반기|상상|상식|상업|상인|상자|상점|상처|상추|상태|상표|상품|상황|새벽|색깔|색연필|생각|생명|생물|생방송|생산|생선|생신|생일|생활|서랍|서른|서명|서민|서비스|서양|서울|서적|서점|서쪽|서클|석사|석유|선거|선물|선배|선생|선수|선원|선장|선전|선택|선풍기|설거지|설날|설렁탕|설명|설문|설사|설악산|설치|설탕|섭씨|성공|성당|성명|성별|성인|성장|성적|성질|성함|세금|세미나|세상|세월|세종대왕|세탁|센터|센티미터|셋째|소규모|소극적|소금|소나기|소년|소득|소망|소문|소설|소속|소아과|소용|소원|소음|소중히|소지품|소질|소풍|소형|속담|속도|속옷|손가락|손길|손녀|손님|손등|손목|손뼉|손실|손질|손톱|손해|솔직히|솜씨|송아지|송이|송편|쇠고기|쇼핑|수건|수년|수단|수돗물|수동적|수면|수명|수박|수상|수석|수술|수시로|수업|수염|수영|수입|수준|수집|수출|수컷|수필|수학|수험생|수화기|숙녀|숙소|숙제|순간|순서|순수|순식간|순위|숟가락|술병|술집|숫자|스님|스물|스스로|스승|스웨터|스위치|스케이트|스튜디오|스트레스|스포츠|슬쩍|슬픔|습관|습기|승객|승리|승부|승용차|승진|시각|시간|시골|시금치|시나리오|시댁|시리즈|시멘트|시민|시부모|시선|시설|시스템|시아버지|시어머니|시월|시인|시일|시작|시장|시절|시점|시중|시즌|시집|시청|시합|시험|식구|식기|식당|식량|식료품|식물|식빵|식사|식생활|식초|식탁|식품|신고|신규|신념|신문|신발|신비|신사|신세|신용|신제품|신청|신체|신화|실감|실내|실력|실례|실망|실수|실습|실시|실장|실정|실질적|실천|실체|실컷|실태|실패|실험|실현|심리|심부름|심사|심장|심정|심판|쌍둥이|씨름|씨앗|아가씨|아나운서|아드님|아들|아쉬움|아스팔트|아시아|아울러|아저씨|아줌마|아직|아침|아파트|아프리카|아픔|아홉|아흔|악기|악몽|악수|안개|안경|안과|안내|안녕|안동|안방|안부|안주|알루미늄|알코올|암시|암컷|압력|앞날|앞문|애인|애정|액수|앨범|야간|야단|야옹|약간|약국|약속|약수|약점|약품|약혼녀|양념|양력|양말|양배추|양주|양파|어둠|어려움|어른|어젯밤|어쨌든|어쩌다가|어쩐지|언니|언덕|언론|언어|얼굴|얼른|얼음|얼핏|엄마|업무|업종|업체|엉덩이|엉망|엉터리|엊그제|에너지|에어컨|엔진|여건|여고생|여관|여군|여권|여대생|여덟|여동생|여든|여론|여름|여섯|여성|여왕|여인|여전히|여직원|여학생|여행|역사|역시|역할|연결|연구|연극|연기|연락|연설|연세|연속|연습|연애|연예인|연인|연장|연주|연출|연필|연합|연휴|열기|열매|열쇠|열심히|열정|열차|열흘|염려|엽서|영국|영남|영상|영양|영역|영웅|영원히|영하|영향|영혼|영화|옆구리|옆방|옆집|예감|예금|예방|예산|예상|예선|예술|예습|예식장|예약|예전|예절|예정|예컨대|옛날|오늘|오락|오랫동안|오렌지|오로지|오른발|오븐|오십|오염|오월|오전|오직|오징어|오페라|오피스텔|오히려|옥상|옥수수|온갖|온라인|온몸|온종일|온통|올가을|올림픽|올해|옷차림|와이셔츠|와인|완성|완전|왕비|왕자|왜냐하면|왠지|외갓집|외국|외로움|외삼촌|외출|외침|외할머니|왼발|왼손|왼쪽|요금|요일|요즘|요청|용기|용서|용어|우산|우선|우승|우연히|우정|우체국|우편|운동|운명|운반|운전|운행|울산|울음|움직임|웃어른|웃음|워낙|원고|원래|원서|원숭이|원인|원장|원피스|월급|월드컵|월세|월요일|웨이터|위반|위법|위성|위원|위험|위협|윗사람|유난히|유럽|유명|유물|유산|유적|유치원|유학|유행|유형|육군|육상|육십|육체|은행|음력|음료|음반|음성|음식|음악|음주|의견|의논|의문|의복|의식|의심|의외로|의욕|의원|의학|이것|이곳|이념|이놈|이달|이대로|이동|이렇게|이력서|이론적|이름|이민|이발소|이별|이불|이빨|이상|이성|이슬|이야기|이용|이웃|이월|이윽고|이익|이전|이중|이튿날|이틀|이혼|인간|인격|인공|인구|인근|인기|인도|인류|인물|인생|인쇄|인연|인원|인재|인종|인천|인체|인터넷|인하|인형|일곱|일기|일단|일대|일등|일반|일본|일부|일상|일생|일손|일요일|일월|일정|일종|일주일|일찍|일체|일치|일행|일회용|임금|임무|입대|입력|입맛|입사|입술|입시|입원|입장|입학|자가용|자격|자극|자동|자랑|자부심|자식|자신|자연|자원|자율|자전거|자정|자존심|자판|작가|작년|작성|작업|작용|작은딸|작품|잔디|잔뜩|잔치|잘못|잠깐|잠수함|잠시|잠옷|잠자리|잡지|장관|장군|장기간|장래|장례|장르|장마|장면|장모|장미|장비|장사|장소|장식|장애인|장인|장점|장차|장학금|재능|재빨리|재산|재생|재작년|재정|재채기|재판|재학|재활용|저것|저고리|저곳|저녁|저런|저렇게|저번|저울|저절로|저축|적극|적당히|적성|적용|적응|전개|전공|전기|전달|전라도|전망|전문|전반|전부|전세|전시|전용|전자|전쟁|전주|전철|전체|전통|전혀|전후|절대|절망|절반|절약|절차|점검|점수|점심|점원|점점|점차|접근|접시|접촉|젓가락|정거장|정도|정류장|정리|정말|정면|정문|정반대|정보|정부|정비|정상|정성|정오|정원|정장|정지|정치|정확히|제공|제과점|제대로|제목|제발|제법|제삿날|제안|제일|제작|제주도|제출|제품|제한|조각|조건|조금|조깅|조명|조미료|조상|조선|조용히|조절|조정|조직|존댓말|존재|졸업|졸음|종교|종로|종류|종소리|종업원|종종|종합|좌석|죄인|주관적|주름|주말|주머니|주먹|주문|주민|주방|주변|주식|주인|주일|주장|주전자|주택|준비|줄거리|줄기|줄무늬|중간|중계방송|중국|중년|중단|중독|중반|중부|중세|중소기업|중순|중앙|중요|중학교|즉석|즉시|즐거움|증가|증거|증권|증상|증세|지각|지갑|지경|지극히|지금|지급|지능|지름길|지리산|지방|지붕|지식|지역|지우개|지원|지적|지점|지진|지출|직선|직업|직원|직장|진급|진동|진로|진료|진리|진짜|진찰|진출|진통|진행|질문|질병|질서|짐작|집단|집안|집중|짜증|찌꺼기|차남|차라리|차량|차림|차별|차선|차츰|착각|찬물|찬성|참가|참기름|참새|참석|참여|참외|참조|찻잔|창가|창고|창구|창문|창밖|창작|창조|채널|채점|책가방|책방|책상|책임|챔피언|처벌|처음|천국|천둥|천장|천재|천천히|철도|철저히|철학|첫날|첫째|청년|청바지|청소|청춘|체계|체력|체온|체육|체중|체험|초등학생|초반|초밥|초상화|초순|초여름|초원|초저녁|초점|초청|초콜릿|촛불|총각|총리|총장|촬영|최근|최상|최선|최신|최악|최종|추석|추억|추진|추천|추측|축구|축소|축제|축하|출근|출발|출산|출신|출연|출입|출장|출판|충격|충고|충돌|충분히|충청도|취업|취직|취향|치약|친구|친척|칠십|칠월|칠판|침대|침묵|침실|칫솔|칭찬|카메라|카운터|칼국수|캐릭터|캠퍼스|캠페인|커튼|컨디션|컬러|컴퓨터|코끼리|코미디|콘서트|콜라|콤플렉스|콩나물|쾌감|쿠데타|크림|큰길|큰딸|큰소리|큰아들|큰어머니|큰일|큰절|클래식|클럽|킬로|타입|타자기|탁구|탁자|탄생|태권도|태양|태풍|택시|탤런트|터널|터미널|테니스|테스트|테이블|텔레비전|토론|토마토|토요일|통계|통과|통로|통신|통역|통일|통장|통제|통증|통합|통화|퇴근|퇴원|퇴직금|튀김|트럭|특급|특별|특성|특수|특징|특히|튼튼히|티셔츠|파란색|파일|파출소|판결|판단|판매|판사|팔십|팔월|팝송|패션|팩스|팩시밀리|팬티|퍼센트|페인트|편견|편의|편지|편히|평가|평균|평생|평소|평양|평일|평화|포스터|포인트|포장|포함|표면|표정|표준|표현|품목|품질|풍경|풍속|풍습|프랑스|프린터|플라스틱|피곤|피망|피아노|필름|필수|필요|필자|필통|핑계|하느님|하늘|하드웨어|하룻밤|하반기|하숙집|하순|하여튼|하지만|하천|하품|하필|학과|학교|학급|학기|학년|학력|학번|학부모|학비|학생|학술|학습|학용품|학원|학위|학자|학점|한계|한글|한꺼번에|한낮|한눈|한동안|한때|한라산|한마디|한문|한번|한복|한식|한여름|한쪽|할머니|할아버지|할인|함께|함부로|합격|합리적|항공|항구|항상|항의|해결|해군|해답|해당|해물|해석|해설|해수욕장|해안|핵심|핸드백|햄버거|햇볕|햇살|행동|행복|행사|행운|행위|향기|향상|향수|허락|허용|헬기|현관|현금|현대|현상|현실|현장|현재|현지|혈액|협력|형부|형사|형수|형식|형제|형태|형편|혜택|호기심|호남|호랑이|호박|호텔|호흡|혹시|홀로|홈페이지|홍보|홍수|홍차|화면|화분|화살|화요일|화장|화학|확보|확인|확장|확정|환갑|환경|환영|환율|환자|활기|활동|활발히|활용|활짝|회견|회관|회복|회색|회원|회장|회전|횟수|횡단보도|효율적|후반|후춧가루|훈련|훨씬|휴식|휴일|흉내|흐름|흑백|흑인|흔적|흔히|흥미|흥분|희곡|희망|희생|흰색|힘껏'.split('|'); diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/zh-s.d.ts b/packages/util-crypto/cjs/mnemonic/wordlists/zh-s.d.ts new file mode 100644 index 0000000..d451d2b --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/zh-s.d.ts @@ -0,0 +1,2 @@ +declare const _default: string[]; +export default _default; diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/zh-s.js b/packages/util-crypto/cjs/mnemonic/wordlists/zh-s.js new file mode 100644 index 0000000..254485a --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/zh-s.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = '的|一|是|在|不|了|有|和|人|这|中|大|为|上|个|国|我|以|要|他|时|来|用|们|生|到|作|地|于|出|就|分|对|成|会|可|主|发|年|动|同|工|也|能|下|过|子|说|产|种|面|而|方|后|多|定|行|学|法|所|民|得|经|十|三|之|进|着|等|部|度|家|电|力|里|如|水|化|高|自|二|理|起|小|物|现|实|加|量|都|两|体|制|机|当|使|点|从|业|本|去|把|性|好|应|开|它|合|还|因|由|其|些|然|前|外|天|政|四|日|那|社|义|事|平|形|相|全|表|间|样|与|关|各|重|新|线|内|数|正|心|反|你|明|看|原|又|么|利|比|或|但|质|气|第|向|道|命|此|变|条|只|没|结|解|问|意|建|月|公|无|系|军|很|情|者|最|立|代|想|已|通|并|提|直|题|党|程|展|五|果|料|象|员|革|位|入|常|文|总|次|品|式|活|设|及|管|特|件|长|求|老|头|基|资|边|流|路|级|少|图|山|统|接|知|较|将|组|见|计|别|她|手|角|期|根|论|运|农|指|几|九|区|强|放|决|西|被|干|做|必|战|先|回|则|任|取|据|处|队|南|给|色|光|门|即|保|治|北|造|百|规|热|领|七|海|口|东|导|器|压|志|世|金|增|争|济|阶|油|思|术|极|交|受|联|什|认|六|共|权|收|证|改|清|美|再|采|转|更|单|风|切|打|白|教|速|花|带|安|场|身|车|例|真|务|具|万|每|目|至|达|走|积|示|议|声|报|斗|完|类|八|离|华|名|确|才|科|张|信|马|节|话|米|整|空|元|况|今|集|温|传|土|许|步|群|广|石|记|需|段|研|界|拉|林|律|叫|且|究|观|越|织|装|影|算|低|持|音|众|书|布|复|容|儿|须|际|商|非|验|连|断|深|难|近|矿|千|周|委|素|技|备|半|办|青|省|列|习|响|约|支|般|史|感|劳|便|团|往|酸|历|市|克|何|除|消|构|府|称|太|准|精|值|号|率|族|维|划|选|标|写|存|候|毛|亲|快|效|斯|院|查|江|型|眼|王|按|格|养|易|置|派|层|片|始|却|专|状|育|厂|京|识|适|属|圆|包|火|住|调|满|县|局|照|参|红|细|引|听|该|铁|价|严|首|底|液|官|德|随|病|苏|失|尔|死|讲|配|女|黄|推|显|谈|罪|神|艺|呢|席|含|企|望|密|批|营|项|防|举|球|英|氧|势|告|李|台|落|木|帮|轮|破|亚|师|围|注|远|字|材|排|供|河|态|封|另|施|减|树|溶|怎|止|案|言|士|均|武|固|叶|鱼|波|视|仅|费|紧|爱|左|章|早|朝|害|续|轻|服|试|食|充|兵|源|判|护|司|足|某|练|差|致|板|田|降|黑|犯|负|击|范|继|兴|似|余|坚|曲|输|修|故|城|夫|够|送|笔|船|占|右|财|吃|富|春|职|觉|汉|画|功|巴|跟|虽|杂|飞|检|吸|助|升|阳|互|初|创|抗|考|投|坏|策|古|径|换|未|跑|留|钢|曾|端|责|站|简|述|钱|副|尽|帝|射|草|冲|承|独|令|限|阿|宣|环|双|请|超|微|让|控|州|良|轴|找|否|纪|益|依|优|顶|础|载|倒|房|突|坐|粉|敌|略|客|袁|冷|胜|绝|析|块|剂|测|丝|协|诉|念|陈|仍|罗|盐|友|洋|错|苦|夜|刑|移|频|逐|靠|混|母|短|皮|终|聚|汽|村|云|哪|既|距|卫|停|烈|央|察|烧|迅|境|若|印|洲|刻|括|激|孔|搞|甚|室|待|核|校|散|侵|吧|甲|游|久|菜|味|旧|模|湖|货|损|预|阻|毫|普|稳|乙|妈|植|息|扩|银|语|挥|酒|守|拿|序|纸|医|缺|雨|吗|针|刘|啊|急|唱|误|训|愿|审|附|获|茶|鲜|粮|斤|孩|脱|硫|肥|善|龙|演|父|渐|血|欢|械|掌|歌|沙|刚|攻|谓|盾|讨|晚|粒|乱|燃|矛|乎|杀|药|宁|鲁|贵|钟|煤|读|班|伯|香|介|迫|句|丰|培|握|兰|担|弦|蛋|沉|假|穿|执|答|乐|谁|顺|烟|缩|征|脸|喜|松|脚|困|异|免|背|星|福|买|染|井|概|慢|怕|磁|倍|祖|皇|促|静|补|评|翻|肉|践|尼|衣|宽|扬|棉|希|伤|操|垂|秋|宜|氢|套|督|振|架|亮|末|宪|庆|编|牛|触|映|雷|销|诗|座|居|抓|裂|胞|呼|娘|景|威|绿|晶|厚|盟|衡|鸡|孙|延|危|胶|屋|乡|临|陆|顾|掉|呀|灯|岁|措|束|耐|剧|玉|赵|跳|哥|季|课|凯|胡|额|款|绍|卷|齐|伟|蒸|殖|永|宗|苗|川|炉|岩|弱|零|杨|奏|沿|露|杆|探|滑|镇|饭|浓|航|怀|赶|库|夺|伊|灵|税|途|灭|赛|归|召|鼓|播|盘|裁|险|康|唯|录|菌|纯|借|糖|盖|横|符|私|努|堂|域|枪|润|幅|哈|竟|熟|虫|泽|脑|壤|碳|欧|遍|侧|寨|敢|彻|虑|斜|薄|庭|纳|弹|饲|伸|折|麦|湿|暗|荷|瓦|塞|床|筑|恶|户|访|塔|奇|透|梁|刀|旋|迹|卡|氯|遇|份|毒|泥|退|洗|摆|灰|彩|卖|耗|夏|择|忙|铜|献|硬|予|繁|圈|雪|函|亦|抽|篇|阵|阴|丁|尺|追|堆|雄|迎|泛|爸|楼|避|谋|吨|野|猪|旗|累|偏|典|馆|索|秦|脂|潮|爷|豆|忽|托|惊|塑|遗|愈|朱|替|纤|粗|倾|尚|痛|楚|谢|奋|购|磨|君|池|旁|碎|骨|监|捕|弟|暴|割|贯|殊|释|词|亡|壁|顿|宝|午|尘|闻|揭|炮|残|冬|桥|妇|警|综|招|吴|付|浮|遭|徐|您|摇|谷|赞|箱|隔|订|男|吹|园|纷|唐|败|宋|玻|巨|耕|坦|荣|闭|湾|键|凡|驻|锅|救|恩|剥|凝|碱|齿|截|炼|麻|纺|禁|废|盛|版|缓|净|睛|昌|婚|涉|筒|嘴|插|岸|朗|庄|街|藏|姑|贸|腐|奴|啦|惯|乘|伙|恢|匀|纱|扎|辩|耳|彪|臣|亿|璃|抵|脉|秀|萨|俄|网|舞|店|喷|纵|寸|汗|挂|洪|贺|闪|柬|爆|烯|津|稻|墙|软|勇|像|滚|厘|蒙|芳|肯|坡|柱|荡|腿|仪|旅|尾|轧|冰|贡|登|黎|削|钻|勒|逃|障|氨|郭|峰|币|港|伏|轨|亩|毕|擦|莫|刺|浪|秘|援|株|健|售|股|岛|甘|泡|睡|童|铸|汤|阀|休|汇|舍|牧|绕|炸|哲|磷|绩|朋|淡|尖|启|陷|柴|呈|徒|颜|泪|稍|忘|泵|蓝|拖|洞|授|镜|辛|壮|锋|贫|虚|弯|摩|泰|幼|廷|尊|窗|纲|弄|隶|疑|氏|宫|姐|震|瑞|怪|尤|琴|循|描|膜|违|夹|腰|缘|珠|穷|森|枝|竹|沟|催|绳|忆|邦|剩|幸|浆|栏|拥|牙|贮|礼|滤|钠|纹|罢|拍|咱|喊|袖|埃|勤|罚|焦|潜|伍|墨|欲|缝|姓|刊|饱|仿|奖|铝|鬼|丽|跨|默|挖|链|扫|喝|袋|炭|污|幕|诸|弧|励|梅|奶|洁|灾|舟|鉴|苯|讼|抱|毁|懂|寒|智|埔|寄|届|跃|渡|挑|丹|艰|贝|碰|拔|爹|戴|码|梦|芽|熔|赤|渔|哭|敬|颗|奔|铅|仲|虎|稀|妹|乏|珍|申|桌|遵|允|隆|螺|仓|魏|锐|晓|氮|兼|隐|碍|赫|拨|忠|肃|缸|牵|抢|博|巧|壳|兄|杜|讯|诚|碧|祥|柯|页|巡|矩|悲|灌|龄|伦|票|寻|桂|铺|圣|恐|恰|郑|趣|抬|荒|腾|贴|柔|滴|猛|阔|辆|妻|填|撤|储|签|闹|扰|紫|砂|递|戏|吊|陶|伐|喂|疗|瓶|婆|抚|臂|摸|忍|虾|蜡|邻|胸|巩|挤|偶|弃|槽|劲|乳|邓|吉|仁|烂|砖|租|乌|舰|伴|瓜|浅|丙|暂|燥|橡|柳|迷|暖|牌|秧|胆|详|簧|踏|瓷|谱|呆|宾|糊|洛|辉|愤|竞|隙|怒|粘|乃|绪|肩|籍|敏|涂|熙|皆|侦|悬|掘|享|纠|醒|狂|锁|淀|恨|牲|霸|爬|赏|逆|玩|陵|祝|秒|浙|貌|役|彼|悉|鸭|趋|凤|晨|畜|辈|秩|卵|署|梯|炎|滩|棋|驱|筛|峡|冒|啥|寿|译|浸|泉|帽|迟|硅|疆|贷|漏|稿|冠|嫩|胁|芯|牢|叛|蚀|奥|鸣|岭|羊|凭|串|塘|绘|酵|融|盆|锡|庙|筹|冻|辅|摄|袭|筋|拒|僚|旱|钾|鸟|漆|沈|眉|疏|添|棒|穗|硝|韩|逼|扭|侨|凉|挺|碗|栽|炒|杯|患|馏|劝|豪|辽|勃|鸿|旦|吏|拜|狗|埋|辊|掩|饮|搬|骂|辞|勾|扣|估|蒋|绒|雾|丈|朵|姆|拟|宇|辑|陕|雕|偿|蓄|崇|剪|倡|厅|咬|驶|薯|刷|斥|番|赋|奉|佛|浇|漫|曼|扇|钙|桃|扶|仔|返|俗|亏|腔|鞋|棱|覆|框|悄|叔|撞|骗|勘|旺|沸|孤|吐|孟|渠|屈|疾|妙|惜|仰|狠|胀|谐|抛|霉|桑|岗|嘛|衰|盗|渗|脏|赖|涌|甜|曹|阅|肌|哩|厉|烃|纬|毅|昨|伪|症|煮|叹|钉|搭|茎|笼|酷|偷|弓|锥|恒|杰|坑|鼻|翼|纶|叙|狱|逮|罐|络|棚|抑|膨|蔬|寺|骤|穆|冶|枯|册|尸|凸|绅|坯|牺|焰|轰|欣|晋|瘦|御|锭|锦|丧|旬|锻|垄|搜|扑|邀|亭|酯|迈|舒|脆|酶|闲|忧|酚|顽|羽|涨|卸|仗|陪|辟|惩|杭|姚|肚|捉|飘|漂|昆|欺|吾|郎|烷|汁|呵|饰|萧|雅|邮|迁|燕|撒|姻|赴|宴|烦|债|帐|斑|铃|旨|醇|董|饼|雏|姿|拌|傅|腹|妥|揉|贤|拆|歪|葡|胺|丢|浩|徽|昂|垫|挡|览|贪|慰|缴|汪|慌|冯|诺|姜|谊|凶|劣|诬|耀|昏|躺|盈|骑|乔|溪|丛|卢|抹|闷|咨|刮|驾|缆|悟|摘|铒|掷|颇|幻|柄|惠|惨|佳|仇|腊|窝|涤|剑|瞧|堡|泼|葱|罩|霍|捞|胎|苍|滨|俩|捅|湘|砍|霞|邵|萄|疯|淮|遂|熊|粪|烘|宿|档|戈|驳|嫂|裕|徙|箭|捐|肠|撑|晒|辨|殿|莲|摊|搅|酱|屏|疫|哀|蔡|堵|沫|皱|畅|叠|阁|莱|敲|辖|钩|痕|坝|巷|饿|祸|丘|玄|溜|曰|逻|彭|尝|卿|妨|艇|吞|韦|怨|矮|歇'.split('|'); diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/zh-t.d.ts b/packages/util-crypto/cjs/mnemonic/wordlists/zh-t.d.ts new file mode 100644 index 0000000..d451d2b --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/zh-t.d.ts @@ -0,0 +1,2 @@ +declare const _default: string[]; +export default _default; diff --git a/packages/util-crypto/cjs/mnemonic/wordlists/zh-t.js b/packages/util-crypto/cjs/mnemonic/wordlists/zh-t.js new file mode 100644 index 0000000..b4b1f1d --- /dev/null +++ b/packages/util-crypto/cjs/mnemonic/wordlists/zh-t.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = '的|一|是|在|不|了|有|和|人|這|中|大|為|上|個|國|我|以|要|他|時|來|用|們|生|到|作|地|於|出|就|分|對|成|會|可|主|發|年|動|同|工|也|能|下|過|子|說|產|種|面|而|方|後|多|定|行|學|法|所|民|得|經|十|三|之|進|著|等|部|度|家|電|力|裡|如|水|化|高|自|二|理|起|小|物|現|實|加|量|都|兩|體|制|機|當|使|點|從|業|本|去|把|性|好|應|開|它|合|還|因|由|其|些|然|前|外|天|政|四|日|那|社|義|事|平|形|相|全|表|間|樣|與|關|各|重|新|線|內|數|正|心|反|你|明|看|原|又|麼|利|比|或|但|質|氣|第|向|道|命|此|變|條|只|沒|結|解|問|意|建|月|公|無|系|軍|很|情|者|最|立|代|想|已|通|並|提|直|題|黨|程|展|五|果|料|象|員|革|位|入|常|文|總|次|品|式|活|設|及|管|特|件|長|求|老|頭|基|資|邊|流|路|級|少|圖|山|統|接|知|較|將|組|見|計|別|她|手|角|期|根|論|運|農|指|幾|九|區|強|放|決|西|被|幹|做|必|戰|先|回|則|任|取|據|處|隊|南|給|色|光|門|即|保|治|北|造|百|規|熱|領|七|海|口|東|導|器|壓|志|世|金|增|爭|濟|階|油|思|術|極|交|受|聯|什|認|六|共|權|收|證|改|清|美|再|採|轉|更|單|風|切|打|白|教|速|花|帶|安|場|身|車|例|真|務|具|萬|每|目|至|達|走|積|示|議|聲|報|鬥|完|類|八|離|華|名|確|才|科|張|信|馬|節|話|米|整|空|元|況|今|集|溫|傳|土|許|步|群|廣|石|記|需|段|研|界|拉|林|律|叫|且|究|觀|越|織|裝|影|算|低|持|音|眾|書|布|复|容|兒|須|際|商|非|驗|連|斷|深|難|近|礦|千|週|委|素|技|備|半|辦|青|省|列|習|響|約|支|般|史|感|勞|便|團|往|酸|歷|市|克|何|除|消|構|府|稱|太|準|精|值|號|率|族|維|劃|選|標|寫|存|候|毛|親|快|效|斯|院|查|江|型|眼|王|按|格|養|易|置|派|層|片|始|卻|專|狀|育|廠|京|識|適|屬|圓|包|火|住|調|滿|縣|局|照|參|紅|細|引|聽|該|鐵|價|嚴|首|底|液|官|德|隨|病|蘇|失|爾|死|講|配|女|黃|推|顯|談|罪|神|藝|呢|席|含|企|望|密|批|營|項|防|舉|球|英|氧|勢|告|李|台|落|木|幫|輪|破|亞|師|圍|注|遠|字|材|排|供|河|態|封|另|施|減|樹|溶|怎|止|案|言|士|均|武|固|葉|魚|波|視|僅|費|緊|愛|左|章|早|朝|害|續|輕|服|試|食|充|兵|源|判|護|司|足|某|練|差|致|板|田|降|黑|犯|負|擊|范|繼|興|似|餘|堅|曲|輸|修|故|城|夫|夠|送|筆|船|佔|右|財|吃|富|春|職|覺|漢|畫|功|巴|跟|雖|雜|飛|檢|吸|助|昇|陽|互|初|創|抗|考|投|壞|策|古|徑|換|未|跑|留|鋼|曾|端|責|站|簡|述|錢|副|盡|帝|射|草|衝|承|獨|令|限|阿|宣|環|雙|請|超|微|讓|控|州|良|軸|找|否|紀|益|依|優|頂|礎|載|倒|房|突|坐|粉|敵|略|客|袁|冷|勝|絕|析|塊|劑|測|絲|協|訴|念|陳|仍|羅|鹽|友|洋|錯|苦|夜|刑|移|頻|逐|靠|混|母|短|皮|終|聚|汽|村|雲|哪|既|距|衛|停|烈|央|察|燒|迅|境|若|印|洲|刻|括|激|孔|搞|甚|室|待|核|校|散|侵|吧|甲|遊|久|菜|味|舊|模|湖|貨|損|預|阻|毫|普|穩|乙|媽|植|息|擴|銀|語|揮|酒|守|拿|序|紙|醫|缺|雨|嗎|針|劉|啊|急|唱|誤|訓|願|審|附|獲|茶|鮮|糧|斤|孩|脫|硫|肥|善|龍|演|父|漸|血|歡|械|掌|歌|沙|剛|攻|謂|盾|討|晚|粒|亂|燃|矛|乎|殺|藥|寧|魯|貴|鐘|煤|讀|班|伯|香|介|迫|句|豐|培|握|蘭|擔|弦|蛋|沉|假|穿|執|答|樂|誰|順|煙|縮|徵|臉|喜|松|腳|困|異|免|背|星|福|買|染|井|概|慢|怕|磁|倍|祖|皇|促|靜|補|評|翻|肉|踐|尼|衣|寬|揚|棉|希|傷|操|垂|秋|宜|氫|套|督|振|架|亮|末|憲|慶|編|牛|觸|映|雷|銷|詩|座|居|抓|裂|胞|呼|娘|景|威|綠|晶|厚|盟|衡|雞|孫|延|危|膠|屋|鄉|臨|陸|顧|掉|呀|燈|歲|措|束|耐|劇|玉|趙|跳|哥|季|課|凱|胡|額|款|紹|卷|齊|偉|蒸|殖|永|宗|苗|川|爐|岩|弱|零|楊|奏|沿|露|桿|探|滑|鎮|飯|濃|航|懷|趕|庫|奪|伊|靈|稅|途|滅|賽|歸|召|鼓|播|盤|裁|險|康|唯|錄|菌|純|借|糖|蓋|橫|符|私|努|堂|域|槍|潤|幅|哈|竟|熟|蟲|澤|腦|壤|碳|歐|遍|側|寨|敢|徹|慮|斜|薄|庭|納|彈|飼|伸|折|麥|濕|暗|荷|瓦|塞|床|築|惡|戶|訪|塔|奇|透|梁|刀|旋|跡|卡|氯|遇|份|毒|泥|退|洗|擺|灰|彩|賣|耗|夏|擇|忙|銅|獻|硬|予|繁|圈|雪|函|亦|抽|篇|陣|陰|丁|尺|追|堆|雄|迎|泛|爸|樓|避|謀|噸|野|豬|旗|累|偏|典|館|索|秦|脂|潮|爺|豆|忽|托|驚|塑|遺|愈|朱|替|纖|粗|傾|尚|痛|楚|謝|奮|購|磨|君|池|旁|碎|骨|監|捕|弟|暴|割|貫|殊|釋|詞|亡|壁|頓|寶|午|塵|聞|揭|炮|殘|冬|橋|婦|警|綜|招|吳|付|浮|遭|徐|您|搖|谷|贊|箱|隔|訂|男|吹|園|紛|唐|敗|宋|玻|巨|耕|坦|榮|閉|灣|鍵|凡|駐|鍋|救|恩|剝|凝|鹼|齒|截|煉|麻|紡|禁|廢|盛|版|緩|淨|睛|昌|婚|涉|筒|嘴|插|岸|朗|莊|街|藏|姑|貿|腐|奴|啦|慣|乘|夥|恢|勻|紗|扎|辯|耳|彪|臣|億|璃|抵|脈|秀|薩|俄|網|舞|店|噴|縱|寸|汗|掛|洪|賀|閃|柬|爆|烯|津|稻|牆|軟|勇|像|滾|厘|蒙|芳|肯|坡|柱|盪|腿|儀|旅|尾|軋|冰|貢|登|黎|削|鑽|勒|逃|障|氨|郭|峰|幣|港|伏|軌|畝|畢|擦|莫|刺|浪|秘|援|株|健|售|股|島|甘|泡|睡|童|鑄|湯|閥|休|匯|舍|牧|繞|炸|哲|磷|績|朋|淡|尖|啟|陷|柴|呈|徒|顏|淚|稍|忘|泵|藍|拖|洞|授|鏡|辛|壯|鋒|貧|虛|彎|摩|泰|幼|廷|尊|窗|綱|弄|隸|疑|氏|宮|姐|震|瑞|怪|尤|琴|循|描|膜|違|夾|腰|緣|珠|窮|森|枝|竹|溝|催|繩|憶|邦|剩|幸|漿|欄|擁|牙|貯|禮|濾|鈉|紋|罷|拍|咱|喊|袖|埃|勤|罰|焦|潛|伍|墨|欲|縫|姓|刊|飽|仿|獎|鋁|鬼|麗|跨|默|挖|鏈|掃|喝|袋|炭|污|幕|諸|弧|勵|梅|奶|潔|災|舟|鑑|苯|訟|抱|毀|懂|寒|智|埔|寄|屆|躍|渡|挑|丹|艱|貝|碰|拔|爹|戴|碼|夢|芽|熔|赤|漁|哭|敬|顆|奔|鉛|仲|虎|稀|妹|乏|珍|申|桌|遵|允|隆|螺|倉|魏|銳|曉|氮|兼|隱|礙|赫|撥|忠|肅|缸|牽|搶|博|巧|殼|兄|杜|訊|誠|碧|祥|柯|頁|巡|矩|悲|灌|齡|倫|票|尋|桂|鋪|聖|恐|恰|鄭|趣|抬|荒|騰|貼|柔|滴|猛|闊|輛|妻|填|撤|儲|簽|鬧|擾|紫|砂|遞|戲|吊|陶|伐|餵|療|瓶|婆|撫|臂|摸|忍|蝦|蠟|鄰|胸|鞏|擠|偶|棄|槽|勁|乳|鄧|吉|仁|爛|磚|租|烏|艦|伴|瓜|淺|丙|暫|燥|橡|柳|迷|暖|牌|秧|膽|詳|簧|踏|瓷|譜|呆|賓|糊|洛|輝|憤|競|隙|怒|粘|乃|緒|肩|籍|敏|塗|熙|皆|偵|懸|掘|享|糾|醒|狂|鎖|淀|恨|牲|霸|爬|賞|逆|玩|陵|祝|秒|浙|貌|役|彼|悉|鴨|趨|鳳|晨|畜|輩|秩|卵|署|梯|炎|灘|棋|驅|篩|峽|冒|啥|壽|譯|浸|泉|帽|遲|矽|疆|貸|漏|稿|冠|嫩|脅|芯|牢|叛|蝕|奧|鳴|嶺|羊|憑|串|塘|繪|酵|融|盆|錫|廟|籌|凍|輔|攝|襲|筋|拒|僚|旱|鉀|鳥|漆|沈|眉|疏|添|棒|穗|硝|韓|逼|扭|僑|涼|挺|碗|栽|炒|杯|患|餾|勸|豪|遼|勃|鴻|旦|吏|拜|狗|埋|輥|掩|飲|搬|罵|辭|勾|扣|估|蔣|絨|霧|丈|朵|姆|擬|宇|輯|陝|雕|償|蓄|崇|剪|倡|廳|咬|駛|薯|刷|斥|番|賦|奉|佛|澆|漫|曼|扇|鈣|桃|扶|仔|返|俗|虧|腔|鞋|棱|覆|框|悄|叔|撞|騙|勘|旺|沸|孤|吐|孟|渠|屈|疾|妙|惜|仰|狠|脹|諧|拋|黴|桑|崗|嘛|衰|盜|滲|臟|賴|湧|甜|曹|閱|肌|哩|厲|烴|緯|毅|昨|偽|症|煮|嘆|釘|搭|莖|籠|酷|偷|弓|錐|恆|傑|坑|鼻|翼|綸|敘|獄|逮|罐|絡|棚|抑|膨|蔬|寺|驟|穆|冶|枯|冊|屍|凸|紳|坯|犧|焰|轟|欣|晉|瘦|禦|錠|錦|喪|旬|鍛|壟|搜|撲|邀|亭|酯|邁|舒|脆|酶|閒|憂|酚|頑|羽|漲|卸|仗|陪|闢|懲|杭|姚|肚|捉|飄|漂|昆|欺|吾|郎|烷|汁|呵|飾|蕭|雅|郵|遷|燕|撒|姻|赴|宴|煩|債|帳|斑|鈴|旨|醇|董|餅|雛|姿|拌|傅|腹|妥|揉|賢|拆|歪|葡|胺|丟|浩|徽|昂|墊|擋|覽|貪|慰|繳|汪|慌|馮|諾|姜|誼|兇|劣|誣|耀|昏|躺|盈|騎|喬|溪|叢|盧|抹|悶|諮|刮|駕|纜|悟|摘|鉺|擲|頗|幻|柄|惠|慘|佳|仇|臘|窩|滌|劍|瞧|堡|潑|蔥|罩|霍|撈|胎|蒼|濱|倆|捅|湘|砍|霞|邵|萄|瘋|淮|遂|熊|糞|烘|宿|檔|戈|駁|嫂|裕|徙|箭|捐|腸|撐|曬|辨|殿|蓮|攤|攪|醬|屏|疫|哀|蔡|堵|沫|皺|暢|疊|閣|萊|敲|轄|鉤|痕|壩|巷|餓|禍|丘|玄|溜|曰|邏|彭|嘗|卿|妨|艇|吞|韋|怨|矮|歇'.split('|'); diff --git a/packages/util-crypto/cjs/nacl/decrypt.d.ts b/packages/util-crypto/cjs/nacl/decrypt.d.ts new file mode 100644 index 0000000..51e2faf --- /dev/null +++ b/packages/util-crypto/cjs/nacl/decrypt.d.ts @@ -0,0 +1,15 @@ +/** + * @name naclDecrypt + * @summary Decrypts a message using the supplied secretKey and nonce + * @description + * Returns an decrypted message, using the `secret` and `nonce`. + * @example + *
+ * + * ```javascript + * import { naclDecrypt } from '@pezkuwi/util-crypto'; + * + * naclDecrypt([...], [...], [...]); // => [...] + * ``` + */ +export declare function naclDecrypt(encrypted: Uint8Array, nonce: Uint8Array, secret: Uint8Array): Uint8Array | null; diff --git a/packages/util-crypto/cjs/nacl/decrypt.js b/packages/util-crypto/cjs/nacl/decrypt.js new file mode 100644 index 0000000..4dbb084 --- /dev/null +++ b/packages/util-crypto/cjs/nacl/decrypt.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.naclDecrypt = naclDecrypt; +const tweetnacl_js_1 = require("./tweetnacl.js"); +/** + * @name naclDecrypt + * @summary Decrypts a message using the supplied secretKey and nonce + * @description + * Returns an decrypted message, using the `secret` and `nonce`. + * @example + *
+ * + * ```javascript + * import { naclDecrypt } from '@pezkuwi/util-crypto'; + * + * naclDecrypt([...], [...], [...]); // => [...] + * ``` + */ +function naclDecrypt(encrypted, nonce, secret) { + return (0, tweetnacl_js_1.naclSecretboxOpen)(encrypted, nonce, secret); +} diff --git a/packages/util-crypto/cjs/nacl/encrypt.d.ts b/packages/util-crypto/cjs/nacl/encrypt.d.ts new file mode 100644 index 0000000..f38f701 --- /dev/null +++ b/packages/util-crypto/cjs/nacl/encrypt.d.ts @@ -0,0 +1,20 @@ +interface Encrypted { + encrypted: Uint8Array; + nonce: Uint8Array; +} +/** + * @name naclEncrypt + * @summary Encrypts a message using the supplied secretKey and nonce + * @description + * Returns an encrypted message, using the `secretKey` and `nonce`. If the `nonce` was not supplied, a random value is generated. + * @example + *
+ * + * ```javascript + * import { naclEncrypt } from '@pezkuwi/util-crypto'; + * + * naclEncrypt([...], [...]); // => [...] + * ``` + */ +export declare function naclEncrypt(message: Uint8Array, secret: Uint8Array, nonce?: Uint8Array): Encrypted; +export {}; diff --git a/packages/util-crypto/cjs/nacl/encrypt.js b/packages/util-crypto/cjs/nacl/encrypt.js new file mode 100644 index 0000000..a69d030 --- /dev/null +++ b/packages/util-crypto/cjs/nacl/encrypt.js @@ -0,0 +1,25 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.naclEncrypt = naclEncrypt; +const asU8a_js_1 = require("../random/asU8a.js"); +const tweetnacl_js_1 = require("./tweetnacl.js"); +/** + * @name naclEncrypt + * @summary Encrypts a message using the supplied secretKey and nonce + * @description + * Returns an encrypted message, using the `secretKey` and `nonce`. If the `nonce` was not supplied, a random value is generated. + * @example + *
+ * + * ```javascript + * import { naclEncrypt } from '@pezkuwi/util-crypto'; + * + * naclEncrypt([...], [...]); // => [...] + * ``` + */ +function naclEncrypt(message, secret, nonce = (0, asU8a_js_1.randomAsU8a)(24)) { + return { + encrypted: (0, tweetnacl_js_1.naclSecretbox)(message, nonce, secret), + nonce + }; +} diff --git a/packages/util-crypto/cjs/nacl/index.d.ts b/packages/util-crypto/cjs/nacl/index.d.ts new file mode 100644 index 0000000..4aaa899 --- /dev/null +++ b/packages/util-crypto/cjs/nacl/index.d.ts @@ -0,0 +1,5 @@ +/** + * @summary Implements [NaCl](http://nacl.cr.yp.to/) secret-key authenticated encryption, public-key authenticated encryption + */ +export { naclDecrypt } from './decrypt.js'; +export { naclEncrypt } from './encrypt.js'; diff --git a/packages/util-crypto/cjs/nacl/index.js b/packages/util-crypto/cjs/nacl/index.js new file mode 100644 index 0000000..c9903f6 --- /dev/null +++ b/packages/util-crypto/cjs/nacl/index.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.naclEncrypt = exports.naclDecrypt = void 0; +/** + * @summary Implements [NaCl](http://nacl.cr.yp.to/) secret-key authenticated encryption, public-key authenticated encryption + */ +var decrypt_js_1 = require("./decrypt.js"); +Object.defineProperty(exports, "naclDecrypt", { enumerable: true, get: function () { return decrypt_js_1.naclDecrypt; } }); +var encrypt_js_1 = require("./encrypt.js"); +Object.defineProperty(exports, "naclEncrypt", { enumerable: true, get: function () { return encrypt_js_1.naclEncrypt; } }); diff --git a/packages/util-crypto/cjs/nacl/tweetnacl.d.ts b/packages/util-crypto/cjs/nacl/tweetnacl.d.ts new file mode 100644 index 0000000..91752b3 --- /dev/null +++ b/packages/util-crypto/cjs/nacl/tweetnacl.d.ts @@ -0,0 +1,2 @@ +export declare function naclSecretbox(msg: Uint8Array, nonce: Uint8Array, key: Uint8Array): Uint8Array; +export declare function naclSecretboxOpen(box: Uint8Array, nonce: Uint8Array, key: Uint8Array): Uint8Array | null; diff --git a/packages/util-crypto/cjs/nacl/tweetnacl.js b/packages/util-crypto/cjs/nacl/tweetnacl.js new file mode 100644 index 0000000..be89a74 --- /dev/null +++ b/packages/util-crypto/cjs/nacl/tweetnacl.js @@ -0,0 +1,238 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.naclSecretbox = naclSecretbox; +exports.naclSecretboxOpen = naclSecretboxOpen; +/* eslint-disable brace-style,camelcase,comma-spacing,curly,one-var,padding-line-between-statements,space-infix-ops */ +function L32(x, c) { return (x << c) | (x >>> (32 - c)); } +function ld32(x, i) { + let u = x[i + 3] & 0xff; + u = (u << 8) | (x[i + 2] & 0xff); + u = (u << 8) | (x[i + 1] & 0xff); + return (u << 8) | (x[i + 0] & 0xff); +} +function st32(x, j, u) { + for (let i = 0; i < 4; i++) { + x[j + i] = u & 255; + u >>>= 8; + } +} +function vn(x, xi, y, yi, n) { + let d = 0; + for (let i = 0; i < n; i++) + d |= x[xi + i] ^ y[yi + i]; + return (1 & ((d - 1) >>> 8)) - 1; +} +function core(out, inp, k, c, h) { + const w = new Uint32Array(16), x = new Uint32Array(16), y = new Uint32Array(16), t = new Uint32Array(4); + let i, j, m; + for (i = 0; i < 4; i++) { + x[5 * i] = ld32(c, 4 * i); + x[1 + i] = ld32(k, 4 * i); + x[6 + i] = ld32(inp, 4 * i); + x[11 + i] = ld32(k, 16 + 4 * i); + } + for (i = 0; i < 16; i++) + y[i] = x[i]; + for (i = 0; i < 20; i++) { + for (j = 0; j < 4; j++) { + for (m = 0; m < 4; m++) + t[m] = x[(5 * j + 4 * m) % 16]; + t[1] ^= L32((t[0] + t[3]) | 0, 7); + t[2] ^= L32((t[1] + t[0]) | 0, 9); + t[3] ^= L32((t[2] + t[1]) | 0, 13); + t[0] ^= L32((t[3] + t[2]) | 0, 18); + for (m = 0; m < 4; m++) + w[4 * j + (j + m) % 4] = t[m]; + } + for (m = 0; m < 16; m++) + x[m] = w[m]; + } + if (h) { + for (i = 0; i < 16; i++) + x[i] = (x[i] + y[i]) | 0; + for (i = 0; i < 4; i++) { + x[5 * i] = (x[5 * i] - ld32(c, 4 * i)) | 0; + x[6 + i] = (x[6 + i] - ld32(inp, 4 * i)) | 0; + } + for (i = 0; i < 4; i++) { + st32(out, 4 * i, x[5 * i]); + st32(out, 16 + 4 * i, x[6 + i]); + } + } + else { + for (i = 0; i < 16; i++) + st32(out, 4 * i, (x[i] + y[i]) | 0); + } +} +const sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]); +function crypto_stream_salsa20_xor(c, cpos, m, mpos, b, n, k) { + const z = new Uint8Array(16), x = new Uint8Array(64); + let u, i; + if (!b) + return 0; + for (i = 0; i < 16; i++) + z[i] = 0; + for (i = 0; i < 8; i++) + z[i] = n[i]; + while (b >= 64) { + core(x, z, k, sigma, false); + for (i = 0; i < 64; i++) + c[cpos + i] = (m ? m[mpos + i] : 0) ^ x[i]; + u = 1; + for (i = 8; i < 16; i++) { + u = u + (z[i] & 0xff) | 0; + z[i] = u & 0xff; + u >>>= 8; + } + b -= 64; + cpos += 64; + if (m) + mpos += 64; + } + if (b > 0) { + core(x, z, k, sigma, false); + for (i = 0; i < b; i++) + c[cpos + i] = (m ? m[mpos + i] : 0) ^ x[i]; + } + return 0; +} +function crypto_stream_xor(c, cpos, m, mpos, d, n, k) { + const s = new Uint8Array(32); + core(s, n, k, sigma, true); + return crypto_stream_salsa20_xor(c, cpos, m, mpos, d, n.subarray(16), s); +} +function add1305(h, c) { + let u = 0; + for (let j = 0; j < 17; j++) { + u = (u + ((h[j] + c[j]) | 0)) | 0; + h[j] = u & 255; + u >>>= 8; + } +} +const minusp = new Uint32Array([5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252]); +function crypto_onetimeauth(out, outpos, m, mpos, n, k) { + let i, j, u; + const x = new Uint32Array(17), r = new Uint32Array(17), h = new Uint32Array(17), c = new Uint32Array(17), g = new Uint32Array(17); + for (j = 0; j < 17; j++) + r[j] = h[j] = 0; + for (j = 0; j < 16; j++) + r[j] = k[j]; + r[3] &= 15; + r[4] &= 252; + r[7] &= 15; + r[8] &= 252; + r[11] &= 15; + r[12] &= 252; + r[15] &= 15; + while (n > 0) { + for (j = 0; j < 17; j++) + c[j] = 0; + for (j = 0; (j < 16) && (j < n); ++j) + c[j] = m[mpos + j]; + c[j] = 1; + mpos += j; + n -= j; + add1305(h, c); + for (i = 0; i < 17; i++) { + x[i] = 0; + for (j = 0; j < 17; j++) + x[i] = (x[i] + (h[j] * ((j <= i) ? r[i - j] : ((320 * r[i + 17 - j]) | 0))) | 0) | 0; + } + for (i = 0; i < 17; i++) + h[i] = x[i]; + u = 0; + for (j = 0; j < 16; j++) { + u = (u + h[j]) | 0; + h[j] = u & 255; + u >>>= 8; + } + u = (u + h[16]) | 0; + h[16] = u & 3; + u = (5 * (u >>> 2)) | 0; + for (j = 0; j < 16; j++) { + u = (u + h[j]) | 0; + h[j] = u & 255; + u >>>= 8; + } + u = (u + h[16]) | 0; + h[16] = u; + } + for (j = 0; j < 17; j++) + g[j] = h[j]; + add1305(h, minusp); + const s = (-(h[16] >>> 7) | 0); + for (j = 0; j < 17; j++) + h[j] ^= s & (g[j] ^ h[j]); + for (j = 0; j < 16; j++) + c[j] = k[j + 16]; + c[16] = 0; + add1305(h, c); + for (j = 0; j < 16; j++) + out[outpos + j] = h[j]; + return 0; +} +function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) { + const x = new Uint8Array(16); + crypto_onetimeauth(x, 0, m, mpos, n, k); + return vn(h, hpos, x, 0, 16); +} +function crypto_secretbox(c, m, d, n, k) { + if (d < 32) + return -1; + crypto_stream_xor(c, 0, m, 0, d, n, k); + crypto_onetimeauth(c, 16, c, 32, d - 32, c); + for (let i = 0; i < 16; i++) + c[i] = 0; + return 0; +} +function crypto_secretbox_open(m, c, d, n, k) { + const x = new Uint8Array(32); + if (d < 32) + return -1; + crypto_stream_xor(x, 0, null, 0, 32, n, k); + if (crypto_onetimeauth_verify(c, 16, c, 32, d - 32, x) !== 0) + return -1; + crypto_stream_xor(m, 0, c, 0, d, n, k); + for (let i = 0; i < 32; i++) + m[i] = 0; + return 0; +} +const crypto_secretbox_KEYBYTES = 32; +const crypto_secretbox_NONCEBYTES = 24; +const crypto_secretbox_ZEROBYTES = 32; +const crypto_secretbox_BOXZEROBYTES = 16; +function checkLengths(k, n) { + if (k.length !== crypto_secretbox_KEYBYTES) + throw new Error('bad key size'); + if (n.length !== crypto_secretbox_NONCEBYTES) + throw new Error('bad nonce size'); +} +function checkArrayTypes(...args) { + for (let i = 0, count = args.length; i < count; i++) { + if (!(args[i] instanceof Uint8Array)) + throw new TypeError('unexpected type, use Uint8Array'); + } +} +function naclSecretbox(msg, nonce, key) { + checkArrayTypes(msg, nonce, key); + checkLengths(key, nonce); + const m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length); + const c = new Uint8Array(m.length); + for (let i = 0; i < msg.length; i++) + m[i + crypto_secretbox_ZEROBYTES] = msg[i]; + crypto_secretbox(c, m, m.length, nonce, key); + return c.subarray(crypto_secretbox_BOXZEROBYTES); +} +function naclSecretboxOpen(box, nonce, key) { + checkArrayTypes(box, nonce, key); + checkLengths(key, nonce); + const c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length); + const m = new Uint8Array(c.length); + for (let i = 0; i < box.length; i++) + c[i + crypto_secretbox_BOXZEROBYTES] = box[i]; + if (c.length < 32) + return null; + if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) + return null; + return m.subarray(crypto_secretbox_ZEROBYTES); +} diff --git a/packages/util-crypto/cjs/networks.d.ts b/packages/util-crypto/cjs/networks.d.ts new file mode 100644 index 0000000..1f36543 --- /dev/null +++ b/packages/util-crypto/cjs/networks.d.ts @@ -0,0 +1 @@ +export { allNetworks, availableNetworks, selectableNetworks } from '@pezkuwi/networks'; diff --git a/packages/util-crypto/cjs/networks.js b/packages/util-crypto/cjs/networks.js new file mode 100644 index 0000000..4e958ce --- /dev/null +++ b/packages/util-crypto/cjs/networks.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.selectableNetworks = exports.availableNetworks = exports.allNetworks = void 0; +var networks_1 = require("@pezkuwi/networks"); +Object.defineProperty(exports, "allNetworks", { enumerable: true, get: function () { return networks_1.allNetworks; } }); +Object.defineProperty(exports, "availableNetworks", { enumerable: true, get: function () { return networks_1.availableNetworks; } }); +Object.defineProperty(exports, "selectableNetworks", { enumerable: true, get: function () { return networks_1.selectableNetworks; } }); diff --git a/packages/util-crypto/cjs/package.json b/packages/util-crypto/cjs/package.json new file mode 100644 index 0000000..5bbefff --- /dev/null +++ b/packages/util-crypto/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/util-crypto/cjs/packageDetect.d.ts b/packages/util-crypto/cjs/packageDetect.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/util-crypto/cjs/packageDetect.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/util-crypto/cjs/packageDetect.js b/packages/util-crypto/cjs/packageDetect.js new file mode 100644 index 0000000..00c411c --- /dev/null +++ b/packages/util-crypto/cjs/packageDetect.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const packageInfo_1 = require("@pezkuwi/networks/cjs/packageInfo"); +const util_1 = require("@pezkuwi/util"); +const packageInfo_2 = require("@pezkuwi/util/cjs/packageInfo"); +const x_randomvalues_1 = require("@pezkuwi/x-randomvalues"); +const packageInfo_js_1 = require("./packageInfo.js"); +(0, util_1.detectPackage)(packageInfo_js_1.packageInfo, null, [packageInfo_1.packageInfo, x_randomvalues_1.packageInfo, packageInfo_2.packageInfo]); diff --git a/packages/util-crypto/cjs/packageInfo.d.ts b/packages/util-crypto/cjs/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/util-crypto/cjs/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/util-crypto/cjs/packageInfo.js b/packages/util-crypto/cjs/packageInfo.js new file mode 100644 index 0000000..14f4856 --- /dev/null +++ b/packages/util-crypto/cjs/packageInfo.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +exports.packageInfo = { name: '@pezkuwi/util-crypto', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; diff --git a/packages/util-crypto/cjs/pbkdf2/encode.d.ts b/packages/util-crypto/cjs/pbkdf2/encode.d.ts new file mode 100644 index 0000000..cc745b0 --- /dev/null +++ b/packages/util-crypto/cjs/pbkdf2/encode.d.ts @@ -0,0 +1,7 @@ +interface Result { + password: Uint8Array; + rounds: number; + salt: Uint8Array; +} +export declare function pbkdf2Encode(passphrase?: string | Uint8Array, salt?: Uint8Array, rounds?: number, onlyJs?: boolean): Result; +export {}; diff --git a/packages/util-crypto/cjs/pbkdf2/encode.js b/packages/util-crypto/cjs/pbkdf2/encode.js new file mode 100644 index 0000000..0d9dd98 --- /dev/null +++ b/packages/util-crypto/cjs/pbkdf2/encode.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.pbkdf2Encode = pbkdf2Encode; +const pbkdf2_1 = require("@noble/hashes/pbkdf2"); +const sha512_1 = require("@noble/hashes/sha512"); +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +const asU8a_js_1 = require("../random/asU8a.js"); +function pbkdf2Encode(passphrase, salt = (0, asU8a_js_1.randomAsU8a)(), rounds = 2048, onlyJs) { + const u8aPass = (0, util_1.u8aToU8a)(passphrase); + const u8aSalt = (0, util_1.u8aToU8a)(salt); + return { + password: !util_1.hasBigInt || (!onlyJs && (0, wasm_crypto_1.isReady)()) + ? (0, wasm_crypto_1.pbkdf2)(u8aPass, u8aSalt, rounds) + : (0, pbkdf2_1.pbkdf2)(sha512_1.sha512, u8aPass, u8aSalt, { c: rounds, dkLen: 64 }), + rounds, + salt + }; +} diff --git a/packages/util-crypto/cjs/pbkdf2/index.d.ts b/packages/util-crypto/cjs/pbkdf2/index.d.ts new file mode 100644 index 0000000..8c1dd5d --- /dev/null +++ b/packages/util-crypto/cjs/pbkdf2/index.d.ts @@ -0,0 +1 @@ +export { pbkdf2Encode } from './encode.js'; diff --git a/packages/util-crypto/cjs/pbkdf2/index.js b/packages/util-crypto/cjs/pbkdf2/index.js new file mode 100644 index 0000000..b2ac6ff --- /dev/null +++ b/packages/util-crypto/cjs/pbkdf2/index.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.pbkdf2Encode = void 0; +var encode_js_1 = require("./encode.js"); +Object.defineProperty(exports, "pbkdf2Encode", { enumerable: true, get: function () { return encode_js_1.pbkdf2Encode; } }); diff --git a/packages/util-crypto/cjs/random/asNumber.d.ts b/packages/util-crypto/cjs/random/asNumber.d.ts new file mode 100644 index 0000000..c1fb451 --- /dev/null +++ b/packages/util-crypto/cjs/random/asNumber.d.ts @@ -0,0 +1,15 @@ +/** + * @name randomAsNumber + * @summary Creates a random number from random bytes. + * @description + * Returns a random number generated from the secure bytes. + * @example + *
+ * + * ```javascript + * import { randomAsNumber } from '@pezkuwi/util-crypto'; + * + * randomAsNumber(); // => + * ``` + */ +export declare function randomAsNumber(): number; diff --git a/packages/util-crypto/cjs/random/asNumber.js b/packages/util-crypto/cjs/random/asNumber.js new file mode 100644 index 0000000..97e7784 --- /dev/null +++ b/packages/util-crypto/cjs/random/asNumber.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.randomAsNumber = randomAsNumber; +const util_1 = require("@pezkuwi/util"); +const asU8a_js_1 = require("./asU8a.js"); +const BN_53 = new util_1.BN(0b11111111111111111111111111111111111111111111111111111); +/** + * @name randomAsNumber + * @summary Creates a random number from random bytes. + * @description + * Returns a random number generated from the secure bytes. + * @example + *
+ * + * ```javascript + * import { randomAsNumber } from '@pezkuwi/util-crypto'; + * + * randomAsNumber(); // => + * ``` + */ +function randomAsNumber() { + return (0, util_1.hexToBn)((0, asU8a_js_1.randomAsHex)(8)).and(BN_53).toNumber(); +} diff --git a/packages/util-crypto/cjs/random/asU8a.d.ts b/packages/util-crypto/cjs/random/asU8a.d.ts new file mode 100644 index 0000000..1d9cf89 --- /dev/null +++ b/packages/util-crypto/cjs/random/asU8a.d.ts @@ -0,0 +1,20 @@ +/** + * @name randomAsU8a + * @summary Creates a Uint8Array filled with random bytes. + * @description + * Returns a `Uint8Array` with the specified (optional) length filled with random bytes. + * @example + *
+ * + * ```javascript + * import { randomAsU8a } from '@pezkuwi/util-crypto'; + * + * randomAsU8a(); // => Uint8Array([...]) + * ``` + */ +export declare function randomAsU8a(length?: number): Uint8Array; +/** + * @name randomAsHex + * @description Creates a hex string filled with random bytes. + */ +export declare const randomAsHex: (length?: number | undefined) => import("@pezkuwi/util/types").HexString; diff --git a/packages/util-crypto/cjs/random/asU8a.js b/packages/util-crypto/cjs/random/asU8a.js new file mode 100644 index 0000000..65077da --- /dev/null +++ b/packages/util-crypto/cjs/random/asU8a.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.randomAsHex = void 0; +exports.randomAsU8a = randomAsU8a; +const x_randomvalues_1 = require("@pezkuwi/x-randomvalues"); +const helpers_js_1 = require("../helpers.js"); +/** + * @name randomAsU8a + * @summary Creates a Uint8Array filled with random bytes. + * @description + * Returns a `Uint8Array` with the specified (optional) length filled with random bytes. + * @example + *
+ * + * ```javascript + * import { randomAsU8a } from '@pezkuwi/util-crypto'; + * + * randomAsU8a(); // => Uint8Array([...]) + * ``` + */ +function randomAsU8a(length = 32) { + return (0, x_randomvalues_1.getRandomValues)(new Uint8Array(length)); +} +/** + * @name randomAsHex + * @description Creates a hex string filled with random bytes. + */ +exports.randomAsHex = (0, helpers_js_1.createAsHex)(randomAsU8a); diff --git a/packages/util-crypto/cjs/random/index.d.ts b/packages/util-crypto/cjs/random/index.d.ts new file mode 100644 index 0000000..cdc2b7d --- /dev/null +++ b/packages/util-crypto/cjs/random/index.d.ts @@ -0,0 +1,5 @@ +/** + * @summary Returns a sequence of secure random bytes in a variety of formats + */ +export { randomAsNumber } from './asNumber.js'; +export { randomAsHex, randomAsU8a } from './asU8a.js'; diff --git a/packages/util-crypto/cjs/random/index.js b/packages/util-crypto/cjs/random/index.js new file mode 100644 index 0000000..4761a61 --- /dev/null +++ b/packages/util-crypto/cjs/random/index.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.randomAsU8a = exports.randomAsHex = exports.randomAsNumber = void 0; +/** + * @summary Returns a sequence of secure random bytes in a variety of formats + */ +var asNumber_js_1 = require("./asNumber.js"); +Object.defineProperty(exports, "randomAsNumber", { enumerable: true, get: function () { return asNumber_js_1.randomAsNumber; } }); +var asU8a_js_1 = require("./asU8a.js"); +Object.defineProperty(exports, "randomAsHex", { enumerable: true, get: function () { return asU8a_js_1.randomAsHex; } }); +Object.defineProperty(exports, "randomAsU8a", { enumerable: true, get: function () { return asU8a_js_1.randomAsU8a; } }); diff --git a/packages/util-crypto/cjs/scrypt/defaults.d.ts b/packages/util-crypto/cjs/scrypt/defaults.d.ts new file mode 100644 index 0000000..8b9c36d --- /dev/null +++ b/packages/util-crypto/cjs/scrypt/defaults.d.ts @@ -0,0 +1,3 @@ +import type { ScryptParams } from './types.js'; +export declare const ALLOWED_PARAMS: ScryptParams[]; +export declare const DEFAULT_PARAMS: ScryptParams; diff --git a/packages/util-crypto/cjs/scrypt/defaults.js b/packages/util-crypto/cjs/scrypt/defaults.js new file mode 100644 index 0000000..fe36727 --- /dev/null +++ b/packages/util-crypto/cjs/scrypt/defaults.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DEFAULT_PARAMS = exports.ALLOWED_PARAMS = void 0; +exports.ALLOWED_PARAMS = [ + { N: 1 << 13, p: 10, r: 8 }, + { N: 1 << 14, p: 5, r: 8 }, + { N: 1 << 15, p: 3, r: 8 }, + { N: 1 << 15, p: 1, r: 8 }, + { N: 1 << 16, p: 2, r: 8 }, + { N: 1 << 17, p: 1, r: 8 } +]; +exports.DEFAULT_PARAMS = { + N: 1 << 17, + p: 1, + r: 8 +}; diff --git a/packages/util-crypto/cjs/scrypt/encode.d.ts b/packages/util-crypto/cjs/scrypt/encode.d.ts new file mode 100644 index 0000000..2fbfb46 --- /dev/null +++ b/packages/util-crypto/cjs/scrypt/encode.d.ts @@ -0,0 +1,8 @@ +import type { ScryptParams } from './types.js'; +interface Result { + params: ScryptParams; + password: Uint8Array; + salt: Uint8Array; +} +export declare function scryptEncode(passphrase?: string | Uint8Array, salt?: Uint8Array, params?: ScryptParams, onlyJs?: boolean): Result; +export {}; diff --git a/packages/util-crypto/cjs/scrypt/encode.js b/packages/util-crypto/cjs/scrypt/encode.js new file mode 100644 index 0000000..ea8f69d --- /dev/null +++ b/packages/util-crypto/cjs/scrypt/encode.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.scryptEncode = scryptEncode; +const scrypt_1 = require("@noble/hashes/scrypt"); +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +const asU8a_js_1 = require("../random/asU8a.js"); +const defaults_js_1 = require("./defaults.js"); +function scryptEncode(passphrase, salt = (0, asU8a_js_1.randomAsU8a)(), params = defaults_js_1.DEFAULT_PARAMS, onlyJs) { + const u8a = (0, util_1.u8aToU8a)(passphrase); + return { + params, + password: !util_1.hasBigInt || (!onlyJs && (0, wasm_crypto_1.isReady)()) + ? (0, wasm_crypto_1.scrypt)(u8a, salt, Math.log2(params.N), params.r, params.p) + : (0, scrypt_1.scrypt)(u8a, salt, (0, util_1.objectSpread)({ dkLen: 64 }, params)), + salt + }; +} diff --git a/packages/util-crypto/cjs/scrypt/fromU8a.d.ts b/packages/util-crypto/cjs/scrypt/fromU8a.d.ts new file mode 100644 index 0000000..b0bf75e --- /dev/null +++ b/packages/util-crypto/cjs/scrypt/fromU8a.d.ts @@ -0,0 +1,7 @@ +import type { ScryptParams } from './types.js'; +interface Result { + params: ScryptParams; + salt: Uint8Array; +} +export declare function scryptFromU8a(data: Uint8Array): Result; +export {}; diff --git a/packages/util-crypto/cjs/scrypt/fromU8a.js b/packages/util-crypto/cjs/scrypt/fromU8a.js new file mode 100644 index 0000000..79cb54b --- /dev/null +++ b/packages/util-crypto/cjs/scrypt/fromU8a.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.scryptFromU8a = scryptFromU8a; +const util_1 = require("@pezkuwi/util"); +const bn_js_1 = require("../bn.js"); +const defaults_js_1 = require("./defaults.js"); +function scryptFromU8a(data) { + if (!(data instanceof Uint8Array)) { + throw new Error('Expected input to be a Uint8Array'); + } + // Ensure the input is exactly 44 bytes: 32 for salt + 3 * 4 for N, p, r + if (data.length < 32 + 12) { + throw new Error(`Invalid input length: expected 44 bytes, found ${data.length}`); + } + const salt = data.subarray(0, 32); + const N = (0, util_1.u8aToBn)(data.subarray(32, 36), bn_js_1.BN_LE_OPTS).toNumber(); + const p = (0, util_1.u8aToBn)(data.subarray(36, 40), bn_js_1.BN_LE_OPTS).toNumber(); + const r = (0, util_1.u8aToBn)(data.subarray(40, 44), bn_js_1.BN_LE_OPTS).toNumber(); + if (N > (1 << 20) || p > 4 || r > 16) { + throw new Error('Scrypt parameters exceed safe limits'); + } + const isAllowed = defaults_js_1.ALLOWED_PARAMS.some((preset) => preset.N === N && preset.p === p && preset.r === r); + if (!isAllowed) { + throw new Error('Invalid injected scrypt params found'); + } + return { params: { N, p, r }, salt }; +} diff --git a/packages/util-crypto/cjs/scrypt/index.d.ts b/packages/util-crypto/cjs/scrypt/index.d.ts new file mode 100644 index 0000000..5cd1784 --- /dev/null +++ b/packages/util-crypto/cjs/scrypt/index.d.ts @@ -0,0 +1,3 @@ +export { scryptEncode } from './encode.js'; +export { scryptFromU8a } from './fromU8a.js'; +export { scryptToU8a } from './toU8a.js'; diff --git a/packages/util-crypto/cjs/scrypt/index.js b/packages/util-crypto/cjs/scrypt/index.js new file mode 100644 index 0000000..2d3ae7e --- /dev/null +++ b/packages/util-crypto/cjs/scrypt/index.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.scryptToU8a = exports.scryptFromU8a = exports.scryptEncode = void 0; +var encode_js_1 = require("./encode.js"); +Object.defineProperty(exports, "scryptEncode", { enumerable: true, get: function () { return encode_js_1.scryptEncode; } }); +var fromU8a_js_1 = require("./fromU8a.js"); +Object.defineProperty(exports, "scryptFromU8a", { enumerable: true, get: function () { return fromU8a_js_1.scryptFromU8a; } }); +var toU8a_js_1 = require("./toU8a.js"); +Object.defineProperty(exports, "scryptToU8a", { enumerable: true, get: function () { return toU8a_js_1.scryptToU8a; } }); diff --git a/packages/util-crypto/cjs/scrypt/toU8a.d.ts b/packages/util-crypto/cjs/scrypt/toU8a.d.ts new file mode 100644 index 0000000..17bd6de --- /dev/null +++ b/packages/util-crypto/cjs/scrypt/toU8a.d.ts @@ -0,0 +1,2 @@ +import type { ScryptParams } from './types.js'; +export declare function scryptToU8a(salt: Uint8Array, { N, p, r }: ScryptParams): Uint8Array; diff --git a/packages/util-crypto/cjs/scrypt/toU8a.js b/packages/util-crypto/cjs/scrypt/toU8a.js new file mode 100644 index 0000000..ea9d0fc --- /dev/null +++ b/packages/util-crypto/cjs/scrypt/toU8a.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.scryptToU8a = scryptToU8a; +const util_1 = require("@pezkuwi/util"); +const bn_js_1 = require("../bn.js"); +function scryptToU8a(salt, { N, p, r }) { + return (0, util_1.u8aConcat)(salt, (0, util_1.bnToU8a)(N, bn_js_1.BN_LE_32_OPTS), (0, util_1.bnToU8a)(p, bn_js_1.BN_LE_32_OPTS), (0, util_1.bnToU8a)(r, bn_js_1.BN_LE_32_OPTS)); +} diff --git a/packages/util-crypto/cjs/scrypt/types.d.ts b/packages/util-crypto/cjs/scrypt/types.d.ts new file mode 100644 index 0000000..3d5c89e --- /dev/null +++ b/packages/util-crypto/cjs/scrypt/types.d.ts @@ -0,0 +1,6 @@ +/** The params that control scrypt generation */ +export interface ScryptParams { + N: number; + p: number; + r: number; +} diff --git a/packages/util-crypto/cjs/scrypt/types.js b/packages/util-crypto/cjs/scrypt/types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/packages/util-crypto/cjs/scrypt/types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/packages/util-crypto/cjs/secp256k1/compress.d.ts b/packages/util-crypto/cjs/secp256k1/compress.d.ts new file mode 100644 index 0000000..8e66a56 --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/compress.d.ts @@ -0,0 +1 @@ +export declare function secp256k1Compress(publicKey: Uint8Array, onlyJs?: boolean): Uint8Array; diff --git a/packages/util-crypto/cjs/secp256k1/compress.js b/packages/util-crypto/cjs/secp256k1/compress.js new file mode 100644 index 0000000..f349a46 --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/compress.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.secp256k1Compress = secp256k1Compress; +const secp256k1_1 = require("@noble/curves/secp256k1"); +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +function secp256k1Compress(publicKey, onlyJs) { + if (![33, 65].includes(publicKey.length)) { + throw new Error(`Invalid publicKey provided, received ${publicKey.length} bytes input`); + } + if (publicKey.length === 33) { + return publicKey; + } + return !util_1.hasBigInt || (!onlyJs && (0, wasm_crypto_1.isReady)()) + ? (0, wasm_crypto_1.secp256k1Compress)(publicKey) + : secp256k1_1.secp256k1.ProjectivePoint.fromHex(publicKey).toRawBytes(true); +} diff --git a/packages/util-crypto/cjs/secp256k1/deriveHard.d.ts b/packages/util-crypto/cjs/secp256k1/deriveHard.d.ts new file mode 100644 index 0000000..cd064c0 --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/deriveHard.d.ts @@ -0,0 +1 @@ +export declare function secp256k1DeriveHard(seed: Uint8Array, chainCode: Uint8Array): Uint8Array; diff --git a/packages/util-crypto/cjs/secp256k1/deriveHard.js b/packages/util-crypto/cjs/secp256k1/deriveHard.js new file mode 100644 index 0000000..414452d --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/deriveHard.js @@ -0,0 +1,13 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.secp256k1DeriveHard = secp256k1DeriveHard; +const util_1 = require("@pezkuwi/util"); +const asU8a_js_1 = require("../blake2/asU8a.js"); +const HDKD = (0, util_1.compactAddLength)((0, util_1.stringToU8a)('Secp256k1HDKD')); +function secp256k1DeriveHard(seed, chainCode) { + if (!(0, util_1.isU8a)(chainCode) || chainCode.length !== 32) { + throw new Error('Invalid chainCode passed to derive'); + } + // NOTE This is specific to the Substrate HDD derivation, so always use the blake2 hasher + return (0, asU8a_js_1.blake2AsU8a)((0, util_1.u8aConcat)(HDKD, seed, chainCode), 256); +} diff --git a/packages/util-crypto/cjs/secp256k1/expand.d.ts b/packages/util-crypto/cjs/secp256k1/expand.d.ts new file mode 100644 index 0000000..193bf02 --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/expand.d.ts @@ -0,0 +1 @@ +export declare function secp256k1Expand(publicKey: Uint8Array, onlyJs?: boolean): Uint8Array; diff --git a/packages/util-crypto/cjs/secp256k1/expand.js b/packages/util-crypto/cjs/secp256k1/expand.js new file mode 100644 index 0000000..c31e5a1 --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/expand.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.secp256k1Expand = secp256k1Expand; +const secp256k1_1 = require("@noble/curves/secp256k1"); +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +const bn_js_1 = require("../bn.js"); +function secp256k1Expand(publicKey, onlyJs) { + if (![33, 65].includes(publicKey.length)) { + throw new Error(`Invalid publicKey provided, received ${publicKey.length} bytes input`); + } + if (publicKey.length === 65) { + return publicKey.subarray(1); + } + if (!util_1.hasBigInt || (!onlyJs && (0, wasm_crypto_1.isReady)())) { + return (0, wasm_crypto_1.secp256k1Expand)(publicKey).subarray(1); + } + const { px, py } = secp256k1_1.secp256k1.ProjectivePoint.fromHex(publicKey); + return (0, util_1.u8aConcat)((0, util_1.bnToU8a)(px, bn_js_1.BN_BE_256_OPTS), (0, util_1.bnToU8a)(py, bn_js_1.BN_BE_256_OPTS)); +} diff --git a/packages/util-crypto/cjs/secp256k1/hasher.d.ts b/packages/util-crypto/cjs/secp256k1/hasher.d.ts new file mode 100644 index 0000000..3acdcd5 --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/hasher.d.ts @@ -0,0 +1,2 @@ +import type { HashType } from './types.js'; +export declare function hasher(hashType: HashType, data: Uint8Array | string, onlyJs?: boolean): Uint8Array; diff --git a/packages/util-crypto/cjs/secp256k1/hasher.js b/packages/util-crypto/cjs/secp256k1/hasher.js new file mode 100644 index 0000000..e8bcb35 --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/hasher.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hasher = hasher; +const index_js_1 = require("../blake2/index.js"); +const index_js_2 = require("../keccak/index.js"); +function hasher(hashType, data, onlyJs) { + return hashType === 'keccak' + ? (0, index_js_2.keccakAsU8a)(data, undefined, onlyJs) + : (0, index_js_1.blake2AsU8a)(data, undefined, undefined, onlyJs); +} diff --git a/packages/util-crypto/cjs/secp256k1/index.d.ts b/packages/util-crypto/cjs/secp256k1/index.d.ts new file mode 100644 index 0000000..06bdece --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/index.d.ts @@ -0,0 +1,7 @@ +export { secp256k1Compress } from './compress.js'; +export { secp256k1Expand } from './expand.js'; +export { secp256k1PairFromSeed } from './pair/fromSeed.js'; +export { secp256k1Recover } from './recover.js'; +export { secp256k1Sign } from './sign.js'; +export { secp256k1PrivateKeyTweakAdd } from './tweakAdd.js'; +export { secp256k1Verify } from './verify.js'; diff --git a/packages/util-crypto/cjs/secp256k1/index.js b/packages/util-crypto/cjs/secp256k1/index.js new file mode 100644 index 0000000..47126ef --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/index.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.secp256k1Verify = exports.secp256k1PrivateKeyTweakAdd = exports.secp256k1Sign = exports.secp256k1Recover = exports.secp256k1PairFromSeed = exports.secp256k1Expand = exports.secp256k1Compress = void 0; +var compress_js_1 = require("./compress.js"); +Object.defineProperty(exports, "secp256k1Compress", { enumerable: true, get: function () { return compress_js_1.secp256k1Compress; } }); +var expand_js_1 = require("./expand.js"); +Object.defineProperty(exports, "secp256k1Expand", { enumerable: true, get: function () { return expand_js_1.secp256k1Expand; } }); +var fromSeed_js_1 = require("./pair/fromSeed.js"); +Object.defineProperty(exports, "secp256k1PairFromSeed", { enumerable: true, get: function () { return fromSeed_js_1.secp256k1PairFromSeed; } }); +var recover_js_1 = require("./recover.js"); +Object.defineProperty(exports, "secp256k1Recover", { enumerable: true, get: function () { return recover_js_1.secp256k1Recover; } }); +var sign_js_1 = require("./sign.js"); +Object.defineProperty(exports, "secp256k1Sign", { enumerable: true, get: function () { return sign_js_1.secp256k1Sign; } }); +var tweakAdd_js_1 = require("./tweakAdd.js"); +Object.defineProperty(exports, "secp256k1PrivateKeyTweakAdd", { enumerable: true, get: function () { return tweakAdd_js_1.secp256k1PrivateKeyTweakAdd; } }); +var verify_js_1 = require("./verify.js"); +Object.defineProperty(exports, "secp256k1Verify", { enumerable: true, get: function () { return verify_js_1.secp256k1Verify; } }); diff --git a/packages/util-crypto/cjs/secp256k1/pair/fromSeed.d.ts b/packages/util-crypto/cjs/secp256k1/pair/fromSeed.d.ts new file mode 100644 index 0000000..2dd2cc8 --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/pair/fromSeed.d.ts @@ -0,0 +1,6 @@ +import type { Keypair } from '../../types.js'; +/** + * @name secp256k1PairFromSeed + * @description Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed. + */ +export declare function secp256k1PairFromSeed(seed: Uint8Array, onlyJs?: boolean): Keypair; diff --git a/packages/util-crypto/cjs/secp256k1/pair/fromSeed.js b/packages/util-crypto/cjs/secp256k1/pair/fromSeed.js new file mode 100644 index 0000000..dbcc917 --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/pair/fromSeed.js @@ -0,0 +1,34 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.secp256k1PairFromSeed = secp256k1PairFromSeed; +const secp256k1_1 = require("@noble/curves/secp256k1"); +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +/** + * @name secp256k1PairFromSeed + * @description Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed. + */ +function secp256k1PairFromSeed(seed, onlyJs) { + if (seed.length !== 32) { + throw new Error('Expected valid 32-byte private key as a seed'); + } + if (!util_1.hasBigInt || (!onlyJs && (0, wasm_crypto_1.isReady)())) { + const full = (0, wasm_crypto_1.secp256k1FromSeed)(seed); + const publicKey = full.slice(32); + // There is an issue with the secp256k1 when running in an ASM.js environment where + // it seems that the lazy static section yields invalid results on the _first_ run. + // If this happens, fail outright, we cannot allow invalid return values + // https://github.com/polkadot-js/wasm/issues/307 + if ((0, util_1.u8aEmpty)(publicKey)) { + throw new Error('Invalid publicKey generated from WASM interface'); + } + return { + publicKey, + secretKey: full.slice(0, 32) + }; + } + return { + publicKey: secp256k1_1.secp256k1.getPublicKey(seed, true), + secretKey: seed + }; +} diff --git a/packages/util-crypto/cjs/secp256k1/recover.d.ts b/packages/util-crypto/cjs/secp256k1/recover.d.ts new file mode 100644 index 0000000..d82d6a3 --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/recover.d.ts @@ -0,0 +1,6 @@ +import type { HashType } from './types.js'; +/** + * @name secp256k1Recover + * @description Recovers a publicKey from the supplied signature + */ +export declare function secp256k1Recover(msgHash: string | Uint8Array, signature: string | Uint8Array, recovery: number, hashType?: HashType, onlyJs?: boolean): Uint8Array; diff --git a/packages/util-crypto/cjs/secp256k1/recover.js b/packages/util-crypto/cjs/secp256k1/recover.js new file mode 100644 index 0000000..e104242 --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/recover.js @@ -0,0 +1,29 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.secp256k1Recover = secp256k1Recover; +const secp256k1_1 = require("@noble/curves/secp256k1"); +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +const compress_js_1 = require("./compress.js"); +const expand_js_1 = require("./expand.js"); +/** + * @name secp256k1Recover + * @description Recovers a publicKey from the supplied signature + */ +function secp256k1Recover(msgHash, signature, recovery, hashType = 'blake2', onlyJs) { + const sig = (0, util_1.u8aToU8a)(signature).subarray(0, 64); + const msg = (0, util_1.u8aToU8a)(msgHash); + const publicKey = !util_1.hasBigInt || (!onlyJs && (0, wasm_crypto_1.isReady)()) + ? (0, wasm_crypto_1.secp256k1Recover)(msg, sig, recovery) + : secp256k1_1.secp256k1.Signature + .fromCompact(sig) + .addRecoveryBit(recovery) + .recoverPublicKey(msg) + .toRawBytes(); + if (!publicKey) { + throw new Error('Unable to recover publicKey from signature'); + } + return hashType === 'keccak' + ? (0, expand_js_1.secp256k1Expand)(publicKey, onlyJs) + : (0, compress_js_1.secp256k1Compress)(publicKey, onlyJs); +} diff --git a/packages/util-crypto/cjs/secp256k1/sign.d.ts b/packages/util-crypto/cjs/secp256k1/sign.d.ts new file mode 100644 index 0000000..5a86fc6 --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/sign.d.ts @@ -0,0 +1,7 @@ +import type { Keypair } from '../types.js'; +import type { HashType } from './types.js'; +/** + * @name secp256k1Sign + * @description Returns message signature of `message`, using the supplied pair + */ +export declare function secp256k1Sign(message: Uint8Array | string, { secretKey }: Partial, hashType?: HashType, onlyJs?: boolean): Uint8Array; diff --git a/packages/util-crypto/cjs/secp256k1/sign.js b/packages/util-crypto/cjs/secp256k1/sign.js new file mode 100644 index 0000000..8a3d6b2 --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/sign.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.secp256k1Sign = secp256k1Sign; +const secp256k1_1 = require("@noble/curves/secp256k1"); +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +const bn_js_1 = require("../bn.js"); +const hasher_js_1 = require("./hasher.js"); +/** + * @name secp256k1Sign + * @description Returns message signature of `message`, using the supplied pair + */ +function secp256k1Sign(message, { secretKey }, hashType = 'blake2', onlyJs) { + if (secretKey?.length !== 32) { + throw new Error('Expected valid secp256k1 secretKey, 32-bytes'); + } + const data = (0, hasher_js_1.hasher)(hashType, message, onlyJs); + if (!util_1.hasBigInt || (!onlyJs && (0, wasm_crypto_1.isReady)())) { + return (0, wasm_crypto_1.secp256k1Sign)(data, secretKey); + } + const signature = secp256k1_1.secp256k1.sign(data, secretKey, { lowS: true }); + return (0, util_1.u8aConcat)((0, util_1.bnToU8a)(signature.r, bn_js_1.BN_BE_256_OPTS), (0, util_1.bnToU8a)(signature.s, bn_js_1.BN_BE_256_OPTS), new Uint8Array([signature.recovery || 0])); +} diff --git a/packages/util-crypto/cjs/secp256k1/tweakAdd.d.ts b/packages/util-crypto/cjs/secp256k1/tweakAdd.d.ts new file mode 100644 index 0000000..ed6591e --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/tweakAdd.d.ts @@ -0,0 +1 @@ +export declare function secp256k1PrivateKeyTweakAdd(seckey: Uint8Array, tweak: Uint8Array, onlyBn?: boolean): Uint8Array; diff --git a/packages/util-crypto/cjs/secp256k1/tweakAdd.js b/packages/util-crypto/cjs/secp256k1/tweakAdd.js new file mode 100644 index 0000000..53ec58e --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/tweakAdd.js @@ -0,0 +1,48 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.secp256k1PrivateKeyTweakAdd = secp256k1PrivateKeyTweakAdd; +const util_1 = require("@pezkuwi/util"); +const x_bigint_1 = require("@pezkuwi/x-bigint"); +const bn_js_1 = require("../bn.js"); +const N = 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141'.replace(/ /g, ''); +const N_BI = (0, x_bigint_1.BigInt)(`0x${N}`); +const N_BN = new util_1.BN(N, 'hex'); +function addBi(seckey, tweak) { + let res = (0, util_1.u8aToBigInt)(tweak, bn_js_1.BN_BE_OPTS); + if (res >= N_BI) { + throw new Error('Tweak parameter is out of range'); + } + res += (0, util_1.u8aToBigInt)(seckey, bn_js_1.BN_BE_OPTS); + if (res >= N_BI) { + res -= N_BI; + } + if (res === util_1._0n) { + throw new Error('Invalid resulting private key'); + } + return (0, util_1.nToU8a)(res, bn_js_1.BN_BE_256_OPTS); +} +function addBn(seckey, tweak) { + const res = new util_1.BN(tweak); + if (res.cmp(N_BN) >= 0) { + throw new Error('Tweak parameter is out of range'); + } + res.iadd(new util_1.BN(seckey)); + if (res.cmp(N_BN) >= 0) { + res.isub(N_BN); + } + if (res.isZero()) { + throw new Error('Invalid resulting private key'); + } + return (0, util_1.bnToU8a)(res, bn_js_1.BN_BE_256_OPTS); +} +function secp256k1PrivateKeyTweakAdd(seckey, tweak, onlyBn) { + if (!(0, util_1.isU8a)(seckey) || seckey.length !== 32) { + throw new Error('Expected seckey to be an Uint8Array with length 32'); + } + else if (!(0, util_1.isU8a)(tweak) || tweak.length !== 32) { + throw new Error('Expected tweak to be an Uint8Array with length 32'); + } + return !util_1.hasBigInt || onlyBn + ? addBn(seckey, tweak) + : addBi(seckey, tweak); +} diff --git a/packages/util-crypto/cjs/secp256k1/types.d.ts b/packages/util-crypto/cjs/secp256k1/types.d.ts new file mode 100644 index 0000000..016b877 --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/types.d.ts @@ -0,0 +1 @@ +export type HashType = 'blake2' | 'keccak'; diff --git a/packages/util-crypto/cjs/secp256k1/types.js b/packages/util-crypto/cjs/secp256k1/types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/packages/util-crypto/cjs/secp256k1/verify.d.ts b/packages/util-crypto/cjs/secp256k1/verify.d.ts new file mode 100644 index 0000000..bf6b8d3 --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/verify.d.ts @@ -0,0 +1,6 @@ +import type { HashType } from './types.js'; +/** + * @name secp256k1Verify + * @description Verifies the signature of `message`, using the supplied pair + */ +export declare function secp256k1Verify(msgHash: string | Uint8Array, signature: string | Uint8Array, address: string | Uint8Array, hashType?: HashType, onlyJs?: boolean): boolean; diff --git a/packages/util-crypto/cjs/secp256k1/verify.js b/packages/util-crypto/cjs/secp256k1/verify.js new file mode 100644 index 0000000..95c98ad --- /dev/null +++ b/packages/util-crypto/cjs/secp256k1/verify.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.secp256k1Verify = secp256k1Verify; +const util_1 = require("@pezkuwi/util"); +const hasher_js_1 = require("./hasher.js"); +const recover_js_1 = require("./recover.js"); +/** + * @name secp256k1Verify + * @description Verifies the signature of `message`, using the supplied pair + */ +function secp256k1Verify(msgHash, signature, address, hashType = 'blake2', onlyJs) { + const sig = (0, util_1.u8aToU8a)(signature); + if (sig.length !== 65) { + throw new Error(`Expected signature with 65 bytes, ${sig.length} found instead`); + } + const publicKey = (0, recover_js_1.secp256k1Recover)((0, hasher_js_1.hasher)(hashType, msgHash), sig, sig[64], hashType, onlyJs); + const signerAddr = (0, hasher_js_1.hasher)(hashType, publicKey, onlyJs); + const inputAddr = (0, util_1.u8aToU8a)(address); + // for Ethereum (keccak) the last 20 bytes is the address + return (0, util_1.u8aEq)(publicKey, inputAddr) || (hashType === 'keccak' + ? (0, util_1.u8aEq)(signerAddr.slice(-20), inputAddr.slice(-20)) + : (0, util_1.u8aEq)(signerAddr, inputAddr)); +} diff --git a/packages/util-crypto/cjs/sha/asU8a.d.ts b/packages/util-crypto/cjs/sha/asU8a.d.ts new file mode 100644 index 0000000..974b164 --- /dev/null +++ b/packages/util-crypto/cjs/sha/asU8a.d.ts @@ -0,0 +1,15 @@ +/** + * @name shaAsU8a + * @summary Creates a sha Uint8Array from the input. + */ +export declare const shaAsU8a: (value: string | Uint8Array, bitLength?: 256 | 512, onlyJs?: boolean) => Uint8Array; +/** + * @name sha256AsU8a + * @summary Creates a sha256 Uint8Array from the input. + */ +export declare const sha256AsU8a: (data: string | Uint8Array, onlyJs?: boolean) => Uint8Array; +/** + * @name sha512AsU8a + * @summary Creates a sha512 Uint8Array from the input. + */ +export declare const sha512AsU8a: (data: string | Uint8Array, onlyJs?: boolean) => Uint8Array; diff --git a/packages/util-crypto/cjs/sha/asU8a.js b/packages/util-crypto/cjs/sha/asU8a.js new file mode 100644 index 0000000..ff7b7cd --- /dev/null +++ b/packages/util-crypto/cjs/sha/asU8a.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sha512AsU8a = exports.sha256AsU8a = exports.shaAsU8a = void 0; +const sha256_1 = require("@noble/hashes/sha256"); +const sha512_1 = require("@noble/hashes/sha512"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +const helpers_js_1 = require("../helpers.js"); +/** + * @name shaAsU8a + * @summary Creates a sha Uint8Array from the input. + */ +exports.shaAsU8a = (0, helpers_js_1.createDualHasher)({ 256: wasm_crypto_1.sha256, 512: wasm_crypto_1.sha512 }, { 256: sha256_1.sha256, 512: sha512_1.sha512 }); +/** + * @name sha256AsU8a + * @summary Creates a sha256 Uint8Array from the input. + */ +exports.sha256AsU8a = (0, helpers_js_1.createBitHasher)(256, exports.shaAsU8a); +/** + * @name sha512AsU8a + * @summary Creates a sha512 Uint8Array from the input. + */ +exports.sha512AsU8a = (0, helpers_js_1.createBitHasher)(512, exports.shaAsU8a); diff --git a/packages/util-crypto/cjs/sha/index.d.ts b/packages/util-crypto/cjs/sha/index.d.ts new file mode 100644 index 0000000..9bc6226 --- /dev/null +++ b/packages/util-crypto/cjs/sha/index.d.ts @@ -0,0 +1,4 @@ +/** + * @summary Implements Sha-256/512 hashing functions for a variety of input and outputs + */ +export { sha256AsU8a, sha512AsU8a, shaAsU8a } from './asU8a.js'; diff --git a/packages/util-crypto/cjs/sha/index.js b/packages/util-crypto/cjs/sha/index.js new file mode 100644 index 0000000..fdef0fb --- /dev/null +++ b/packages/util-crypto/cjs/sha/index.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.shaAsU8a = exports.sha512AsU8a = exports.sha256AsU8a = void 0; +/** + * @summary Implements Sha-256/512 hashing functions for a variety of input and outputs + */ +var asU8a_js_1 = require("./asU8a.js"); +Object.defineProperty(exports, "sha256AsU8a", { enumerable: true, get: function () { return asU8a_js_1.sha256AsU8a; } }); +Object.defineProperty(exports, "sha512AsU8a", { enumerable: true, get: function () { return asU8a_js_1.sha512AsU8a; } }); +Object.defineProperty(exports, "shaAsU8a", { enumerable: true, get: function () { return asU8a_js_1.shaAsU8a; } }); diff --git a/packages/util-crypto/cjs/signature/index.d.ts b/packages/util-crypto/cjs/signature/index.d.ts new file mode 100644 index 0000000..685361c --- /dev/null +++ b/packages/util-crypto/cjs/signature/index.d.ts @@ -0,0 +1,4 @@ +/** + * @summary Utilities for working with signatures + */ +export { signatureVerify } from './verify.js'; diff --git a/packages/util-crypto/cjs/signature/index.js b/packages/util-crypto/cjs/signature/index.js new file mode 100644 index 0000000..5858b2b --- /dev/null +++ b/packages/util-crypto/cjs/signature/index.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.signatureVerify = void 0; +/** + * @summary Utilities for working with signatures + */ +var verify_js_1 = require("./verify.js"); +Object.defineProperty(exports, "signatureVerify", { enumerable: true, get: function () { return verify_js_1.signatureVerify; } }); diff --git a/packages/util-crypto/cjs/signature/verify.d.ts b/packages/util-crypto/cjs/signature/verify.d.ts new file mode 100644 index 0000000..1bfdaca --- /dev/null +++ b/packages/util-crypto/cjs/signature/verify.d.ts @@ -0,0 +1,2 @@ +import type { VerifyResult } from '../types.js'; +export declare function signatureVerify(message: string | Uint8Array, signature: string | Uint8Array, addressOrPublicKey: string | Uint8Array): VerifyResult; diff --git a/packages/util-crypto/cjs/signature/verify.js b/packages/util-crypto/cjs/signature/verify.js new file mode 100644 index 0000000..74947be --- /dev/null +++ b/packages/util-crypto/cjs/signature/verify.js @@ -0,0 +1,81 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.signatureVerify = signatureVerify; +const util_1 = require("@pezkuwi/util"); +const decode_js_1 = require("../address/decode.js"); +const verify_js_1 = require("../ed25519/verify.js"); +const verify_js_2 = require("../secp256k1/verify.js"); +const verify_js_3 = require("../sr25519/verify.js"); +const secp256k1VerifyHasher = (hashType) => (message, signature, publicKey) => (0, verify_js_2.secp256k1Verify)(message, signature, publicKey, hashType, true); +const VERIFIERS_ECDSA = [ + ['ecdsa', secp256k1VerifyHasher('blake2')], + ['ethereum', secp256k1VerifyHasher('keccak')] +]; +const VERIFIERS = [ + ['ed25519', verify_js_1.ed25519Verify], + ['sr25519', verify_js_3.sr25519Verify] +]; +function verifyDetect(result, { message, publicKey, signature }, verifiers = [...VERIFIERS, ...VERIFIERS_ECDSA]) { + result.isValid = verifiers.some(([crypto, verify]) => { + try { + if (verify(message, signature, publicKey)) { + result.crypto = crypto; + return true; + } + } + catch { + // do nothing, result.isValid still set to false + } + return false; + }); + return result; +} +function verifyMultisig(result, { message, publicKey, signature }) { + if (![0, 1, 2].includes(signature[0]) || ![65, 66].includes(signature.length)) { + throw new Error(`Unknown crypto type, expected signature prefix [0..2], found ${signature[0]}`); + } + // If the signature is 66 bytes it must be an ecdsa signature + // containing: prefix [1 byte] + signature [65] bytes. + // Remove the and then verify + if (signature.length === 66) { + result = verifyDetect(result, { message, publicKey, signature: signature.subarray(1) }, VERIFIERS_ECDSA); + } + else { + // The signature contains 65 bytes which is either + // - A ed25519 or sr25519 signature [1 byte prefix + 64 bytes] + // - An ecdsa signature [65 bytes] + result = verifyDetect(result, { message, publicKey, signature: signature.subarray(1) }, VERIFIERS); + if (!result.isValid) { + result = verifyDetect(result, { message, publicKey, signature }, VERIFIERS_ECDSA); + } + // If both failed, explicitly set crypto to 'none' + if (!result.isValid) { + result.crypto = 'none'; + } + } + return result; +} +function getVerifyFn(signature) { + return [0, 1, 2].includes(signature[0]) && [65, 66].includes(signature.length) + ? verifyMultisig + : verifyDetect; +} +function signatureVerify(message, signature, addressOrPublicKey) { + const signatureU8a = (0, util_1.u8aToU8a)(signature); + if (![64, 65, 66].includes(signatureU8a.length)) { + throw new Error(`Invalid signature length, expected [64..66] bytes, found ${signatureU8a.length}`); + } + const publicKey = (0, decode_js_1.decodeAddress)(addressOrPublicKey); + const input = { message: (0, util_1.u8aToU8a)(message), publicKey, signature: signatureU8a }; + const result = { crypto: 'none', isValid: false, isWrapped: (0, util_1.u8aIsWrapped)(input.message, true), publicKey }; + const isWrappedBytes = (0, util_1.u8aIsWrapped)(input.message, false); + const verifyFn = getVerifyFn(signatureU8a); + verifyFn(result, input); + if (result.crypto !== 'none' || (result.isWrapped && !isWrappedBytes)) { + return result; + } + input.message = isWrappedBytes + ? (0, util_1.u8aUnwrapBytes)(input.message) + : (0, util_1.u8aWrapBytes)(input.message); + return verifyFn(result, input); +} diff --git a/packages/util-crypto/cjs/sr25519/agreement.d.ts b/packages/util-crypto/cjs/sr25519/agreement.d.ts new file mode 100644 index 0000000..a316893 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/agreement.d.ts @@ -0,0 +1,5 @@ +/** + * @name sr25519Agreement + * @description Key agreement between other's public key and self secret key + */ +export declare function sr25519Agreement(secretKey: string | Uint8Array, publicKey: string | Uint8Array): Uint8Array; diff --git a/packages/util-crypto/cjs/sr25519/agreement.js b/packages/util-crypto/cjs/sr25519/agreement.js new file mode 100644 index 0000000..e5d2a40 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/agreement.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sr25519Agreement = sr25519Agreement; +const sr25519_1 = require("@scure/sr25519"); +const util_1 = require("@pezkuwi/util"); +/** + * @name sr25519Agreement + * @description Key agreement between other's public key and self secret key + */ +function sr25519Agreement(secretKey, publicKey) { + const secretKeyU8a = (0, util_1.u8aToU8a)(secretKey); + const publicKeyU8a = (0, util_1.u8aToU8a)(publicKey); + if (publicKeyU8a.length !== 32) { + throw new Error(`Invalid publicKey, received ${publicKeyU8a.length} bytes, expected 32`); + } + else if (secretKeyU8a.length !== 64) { + throw new Error(`Invalid secretKey, received ${secretKeyU8a.length} bytes, expected 64`); + } + return (0, sr25519_1.getSharedSecret)(secretKeyU8a, publicKeyU8a); +} diff --git a/packages/util-crypto/cjs/sr25519/derive.d.ts b/packages/util-crypto/cjs/sr25519/derive.d.ts new file mode 100644 index 0000000..a9b3a68 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/derive.d.ts @@ -0,0 +1,2 @@ +import type { Keypair } from '../types.js'; +export declare function createDeriveFn(derive: (pair: Uint8Array, cc: Uint8Array) => Uint8Array): (keypair: Keypair, chainCode: Uint8Array) => Keypair; diff --git a/packages/util-crypto/cjs/sr25519/derive.js b/packages/util-crypto/cjs/sr25519/derive.js new file mode 100644 index 0000000..05d93bd --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/derive.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createDeriveFn = createDeriveFn; +const tslib_1 = require("tslib"); +const sr25519 = tslib_1.__importStar(require("@scure/sr25519")); +const util_1 = require("@pezkuwi/util"); +function createDeriveFn(derive) { + return (keypair, chainCode) => { + if (!(0, util_1.isU8a)(chainCode) || chainCode.length !== 32) { + throw new Error('Invalid chainCode passed to derive'); + } + const secretKey = derive(keypair.secretKey, chainCode); + const publicKey = sr25519.getPublicKey(secretKey); + return { publicKey, secretKey }; + }; +} diff --git a/packages/util-crypto/cjs/sr25519/deriveHard.d.ts b/packages/util-crypto/cjs/sr25519/deriveHard.d.ts new file mode 100644 index 0000000..471f9e0 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/deriveHard.d.ts @@ -0,0 +1 @@ +export declare const sr25519DeriveHard: (keypair: import("../types.js").Keypair, chainCode: Uint8Array) => import("../types.js").Keypair; diff --git a/packages/util-crypto/cjs/sr25519/deriveHard.js b/packages/util-crypto/cjs/sr25519/deriveHard.js new file mode 100644 index 0000000..a381538 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/deriveHard.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sr25519DeriveHard = void 0; +const tslib_1 = require("tslib"); +const sr25519 = tslib_1.__importStar(require("@scure/sr25519")); +const derive_js_1 = require("./derive.js"); +exports.sr25519DeriveHard = (0, derive_js_1.createDeriveFn)(sr25519.HDKD.secretHard); diff --git a/packages/util-crypto/cjs/sr25519/derivePublic.d.ts b/packages/util-crypto/cjs/sr25519/derivePublic.d.ts new file mode 100644 index 0000000..dcd1687 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/derivePublic.d.ts @@ -0,0 +1 @@ +export declare function sr25519DerivePublic(publicKey: string | Uint8Array, chainCode: Uint8Array): Uint8Array; diff --git a/packages/util-crypto/cjs/sr25519/derivePublic.js b/packages/util-crypto/cjs/sr25519/derivePublic.js new file mode 100644 index 0000000..1a5f004 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/derivePublic.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sr25519DerivePublic = sr25519DerivePublic; +const tslib_1 = require("tslib"); +const sr25519 = tslib_1.__importStar(require("@scure/sr25519")); +const util_1 = require("@pezkuwi/util"); +function sr25519DerivePublic(publicKey, chainCode) { + const publicKeyU8a = (0, util_1.u8aToU8a)(publicKey); + if (!(0, util_1.isU8a)(chainCode) || chainCode.length !== 32) { + throw new Error('Invalid chainCode passed to derive'); + } + else if (publicKeyU8a.length !== 32) { + throw new Error(`Invalid publicKey, received ${publicKeyU8a.length} bytes, expected 32`); + } + return sr25519.HDKD.publicSoft(publicKeyU8a, chainCode); +} diff --git a/packages/util-crypto/cjs/sr25519/deriveSoft.d.ts b/packages/util-crypto/cjs/sr25519/deriveSoft.d.ts new file mode 100644 index 0000000..4bd044e --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/deriveSoft.d.ts @@ -0,0 +1 @@ +export declare const sr25519DeriveSoft: (keypair: import("../types.js").Keypair, chainCode: Uint8Array) => import("../types.js").Keypair; diff --git a/packages/util-crypto/cjs/sr25519/deriveSoft.js b/packages/util-crypto/cjs/sr25519/deriveSoft.js new file mode 100644 index 0000000..21c3b73 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/deriveSoft.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sr25519DeriveSoft = void 0; +const tslib_1 = require("tslib"); +const sr25519 = tslib_1.__importStar(require("@scure/sr25519")); +const derive_js_1 = require("./derive.js"); +exports.sr25519DeriveSoft = (0, derive_js_1.createDeriveFn)(sr25519.HDKD.secretSoft); diff --git a/packages/util-crypto/cjs/sr25519/index.d.ts b/packages/util-crypto/cjs/sr25519/index.d.ts new file mode 100644 index 0000000..3fdb022 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/index.d.ts @@ -0,0 +1,9 @@ +export { sr25519Agreement } from './agreement.js'; +export { sr25519DeriveHard } from './deriveHard.js'; +export { sr25519DerivePublic } from './derivePublic.js'; +export { sr25519DeriveSoft } from './deriveSoft.js'; +export { sr25519PairFromSeed } from './pair/fromSeed.js'; +export { sr25519Sign } from './sign.js'; +export { sr25519Verify } from './verify.js'; +export { sr25519VrfSign } from './vrfSign.js'; +export { sr25519VrfVerify } from './vrfVerify.js'; diff --git a/packages/util-crypto/cjs/sr25519/index.js b/packages/util-crypto/cjs/sr25519/index.js new file mode 100644 index 0000000..9e27b57 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/index.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sr25519VrfVerify = exports.sr25519VrfSign = exports.sr25519Verify = exports.sr25519Sign = exports.sr25519PairFromSeed = exports.sr25519DeriveSoft = exports.sr25519DerivePublic = exports.sr25519DeriveHard = exports.sr25519Agreement = void 0; +var agreement_js_1 = require("./agreement.js"); +Object.defineProperty(exports, "sr25519Agreement", { enumerable: true, get: function () { return agreement_js_1.sr25519Agreement; } }); +var deriveHard_js_1 = require("./deriveHard.js"); +Object.defineProperty(exports, "sr25519DeriveHard", { enumerable: true, get: function () { return deriveHard_js_1.sr25519DeriveHard; } }); +var derivePublic_js_1 = require("./derivePublic.js"); +Object.defineProperty(exports, "sr25519DerivePublic", { enumerable: true, get: function () { return derivePublic_js_1.sr25519DerivePublic; } }); +var deriveSoft_js_1 = require("./deriveSoft.js"); +Object.defineProperty(exports, "sr25519DeriveSoft", { enumerable: true, get: function () { return deriveSoft_js_1.sr25519DeriveSoft; } }); +var fromSeed_js_1 = require("./pair/fromSeed.js"); +Object.defineProperty(exports, "sr25519PairFromSeed", { enumerable: true, get: function () { return fromSeed_js_1.sr25519PairFromSeed; } }); +var sign_js_1 = require("./sign.js"); +Object.defineProperty(exports, "sr25519Sign", { enumerable: true, get: function () { return sign_js_1.sr25519Sign; } }); +var verify_js_1 = require("./verify.js"); +Object.defineProperty(exports, "sr25519Verify", { enumerable: true, get: function () { return verify_js_1.sr25519Verify; } }); +var vrfSign_js_1 = require("./vrfSign.js"); +Object.defineProperty(exports, "sr25519VrfSign", { enumerable: true, get: function () { return vrfSign_js_1.sr25519VrfSign; } }); +var vrfVerify_js_1 = require("./vrfVerify.js"); +Object.defineProperty(exports, "sr25519VrfVerify", { enumerable: true, get: function () { return vrfVerify_js_1.sr25519VrfVerify; } }); diff --git a/packages/util-crypto/cjs/sr25519/pair/fromSeed.d.ts b/packages/util-crypto/cjs/sr25519/pair/fromSeed.d.ts new file mode 100644 index 0000000..cc9e13c --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/pair/fromSeed.d.ts @@ -0,0 +1,6 @@ +import type { Keypair } from '../../types.js'; +/** + * @name sr25519PairFromSeed + * @description Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed. + */ +export declare function sr25519PairFromSeed(seed: string | Uint8Array): Keypair; diff --git a/packages/util-crypto/cjs/sr25519/pair/fromSeed.js b/packages/util-crypto/cjs/sr25519/pair/fromSeed.js new file mode 100644 index 0000000..a8c2cab --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/pair/fromSeed.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sr25519PairFromSeed = sr25519PairFromSeed; +const tslib_1 = require("tslib"); +const sr25519 = tslib_1.__importStar(require("@scure/sr25519")); +const util_1 = require("@pezkuwi/util"); +/** + * @name sr25519PairFromSeed + * @description Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed. + */ +function sr25519PairFromSeed(seed) { + const seedU8a = (0, util_1.u8aToU8a)(seed); + if (seedU8a.length !== 32) { + throw new Error(`Expected a seed matching 32 bytes, found ${seedU8a.length}`); + } + const sec = sr25519.secretFromSeed(seedU8a); + const pub = sr25519.getPublicKey(sec); + return { + publicKey: pub, + secretKey: sec + }; +} diff --git a/packages/util-crypto/cjs/sr25519/pair/fromU8a.d.ts b/packages/util-crypto/cjs/sr25519/pair/fromU8a.d.ts new file mode 100644 index 0000000..472a9cd --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/pair/fromU8a.d.ts @@ -0,0 +1,2 @@ +import type { Keypair } from '../../types.js'; +export declare function sr25519PairFromU8a(full: string | Uint8Array): Keypair; diff --git a/packages/util-crypto/cjs/sr25519/pair/fromU8a.js b/packages/util-crypto/cjs/sr25519/pair/fromU8a.js new file mode 100644 index 0000000..f1bba4b --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/pair/fromU8a.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sr25519PairFromU8a = sr25519PairFromU8a; +const util_1 = require("@pezkuwi/util"); +const SEC_LEN = 64; +const PUB_LEN = 32; +const TOT_LEN = SEC_LEN + PUB_LEN; +function sr25519PairFromU8a(full) { + const fullU8a = (0, util_1.u8aToU8a)(full); + if (fullU8a.length !== TOT_LEN) { + throw new Error(`Expected keypair with ${TOT_LEN} bytes, found ${fullU8a.length}`); + } + return { + publicKey: fullU8a.slice(SEC_LEN, TOT_LEN), + secretKey: fullU8a.slice(0, SEC_LEN) + }; +} diff --git a/packages/util-crypto/cjs/sr25519/pair/toU8a.d.ts b/packages/util-crypto/cjs/sr25519/pair/toU8a.d.ts new file mode 100644 index 0000000..1472b5a --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/pair/toU8a.d.ts @@ -0,0 +1,2 @@ +import type { Keypair } from '../../types.js'; +export declare function sr25519KeypairToU8a({ publicKey, secretKey }: Keypair): Uint8Array; diff --git a/packages/util-crypto/cjs/sr25519/pair/toU8a.js b/packages/util-crypto/cjs/sr25519/pair/toU8a.js new file mode 100644 index 0000000..920e060 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/pair/toU8a.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sr25519KeypairToU8a = sr25519KeypairToU8a; +const util_1 = require("@pezkuwi/util"); +function sr25519KeypairToU8a({ publicKey, secretKey }) { + return (0, util_1.u8aConcat)(secretKey, publicKey).slice(); +} diff --git a/packages/util-crypto/cjs/sr25519/sign.d.ts b/packages/util-crypto/cjs/sr25519/sign.d.ts new file mode 100644 index 0000000..b63958c --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/sign.d.ts @@ -0,0 +1,6 @@ +import type { Keypair } from '../types.js'; +/** + * @name sr25519Sign + * @description Returns message signature of `message`, using the supplied pair + */ +export declare function sr25519Sign(message: string | Uint8Array, { publicKey, secretKey }: Partial): Uint8Array; diff --git a/packages/util-crypto/cjs/sr25519/sign.js b/packages/util-crypto/cjs/sr25519/sign.js new file mode 100644 index 0000000..d4b5dd4 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/sign.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sr25519Sign = sr25519Sign; +const tslib_1 = require("tslib"); +const sr25519 = tslib_1.__importStar(require("@scure/sr25519")); +const util_1 = require("@pezkuwi/util"); +/** + * @name sr25519Sign + * @description Returns message signature of `message`, using the supplied pair + */ +function sr25519Sign(message, { publicKey, secretKey }) { + if (publicKey?.length !== 32) { + throw new Error('Expected a valid publicKey, 32-bytes'); + } + else if (secretKey?.length !== 64) { + throw new Error('Expected a valid secretKey, 64-bytes'); + } + return sr25519.sign(secretKey, (0, util_1.u8aToU8a)(message)); +} diff --git a/packages/util-crypto/cjs/sr25519/verify.d.ts b/packages/util-crypto/cjs/sr25519/verify.d.ts new file mode 100644 index 0000000..e6560ed --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/verify.d.ts @@ -0,0 +1,5 @@ +/** + * @name sr25519Verify + * @description Verifies the signature of `message`, using the supplied pair + */ +export declare function sr25519Verify(message: string | Uint8Array, signature: string | Uint8Array, publicKey: string | Uint8Array): boolean; diff --git a/packages/util-crypto/cjs/sr25519/verify.js b/packages/util-crypto/cjs/sr25519/verify.js new file mode 100644 index 0000000..98fd1f7 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/verify.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sr25519Verify = sr25519Verify; +const tslib_1 = require("tslib"); +const sr25519 = tslib_1.__importStar(require("@scure/sr25519")); +const util_1 = require("@pezkuwi/util"); +/** + * @name sr25519Verify + * @description Verifies the signature of `message`, using the supplied pair + */ +function sr25519Verify(message, signature, publicKey) { + const publicKeyU8a = (0, util_1.u8aToU8a)(publicKey); + const signatureU8a = (0, util_1.u8aToU8a)(signature); + if (publicKeyU8a.length !== 32) { + throw new Error(`Invalid publicKey, received ${publicKeyU8a.length} bytes, expected 32`); + } + else if (signatureU8a.length !== 64) { + throw new Error(`Invalid signature, received ${signatureU8a.length} bytes, expected 64`); + } + return sr25519.verify((0, util_1.u8aToU8a)(message), signatureU8a, publicKeyU8a); +} diff --git a/packages/util-crypto/cjs/sr25519/vrfSign.d.ts b/packages/util-crypto/cjs/sr25519/vrfSign.d.ts new file mode 100644 index 0000000..b3519f0 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/vrfSign.d.ts @@ -0,0 +1,6 @@ +import type { Keypair } from '../types.js'; +/** + * @name sr25519VrfSign + * @description Sign with sr25519 vrf signing (deterministic) + */ +export declare function sr25519VrfSign(message: string | Uint8Array, { secretKey }: Partial, context?: string | Uint8Array, extra?: string | Uint8Array): Uint8Array; diff --git a/packages/util-crypto/cjs/sr25519/vrfSign.js b/packages/util-crypto/cjs/sr25519/vrfSign.js new file mode 100644 index 0000000..a07d5c8 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/vrfSign.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sr25519VrfSign = sr25519VrfSign; +const tslib_1 = require("tslib"); +const utils_1 = require("@noble/hashes/utils"); +const sr25519 = tslib_1.__importStar(require("@scure/sr25519")); +const util_1 = require("@pezkuwi/util"); +const EMPTY_U8A = new Uint8Array(); +/** + * @name sr25519VrfSign + * @description Sign with sr25519 vrf signing (deterministic) + */ +function sr25519VrfSign(message, { secretKey }, context = EMPTY_U8A, extra = EMPTY_U8A) { + if (secretKey?.length !== 64) { + throw new Error('Invalid secretKey, expected 64-bytes'); + } + return sr25519.vrf.sign((0, util_1.u8aToU8a)(message), secretKey, (0, util_1.u8aToU8a)(context), (0, util_1.u8aToU8a)(extra), utils_1.randomBytes); + // return vrfSign(secretKey, u8aToU8a(context), u8aToU8a(message), u8aToU8a(extra)); +} diff --git a/packages/util-crypto/cjs/sr25519/vrfVerify.d.ts b/packages/util-crypto/cjs/sr25519/vrfVerify.d.ts new file mode 100644 index 0000000..11148c7 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/vrfVerify.d.ts @@ -0,0 +1,5 @@ +/** + * @name sr25519VrfVerify + * @description Verify with sr25519 vrf verification + */ +export declare function sr25519VrfVerify(message: string | Uint8Array, signOutput: string | Uint8Array, publicKey: string | Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): boolean; diff --git a/packages/util-crypto/cjs/sr25519/vrfVerify.js b/packages/util-crypto/cjs/sr25519/vrfVerify.js new file mode 100644 index 0000000..a500620 --- /dev/null +++ b/packages/util-crypto/cjs/sr25519/vrfVerify.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sr25519VrfVerify = sr25519VrfVerify; +const tslib_1 = require("tslib"); +const sr25519 = tslib_1.__importStar(require("@scure/sr25519")); +const util_1 = require("@pezkuwi/util"); +const EMPTY_U8A = new Uint8Array(); +/** + * @name sr25519VrfVerify + * @description Verify with sr25519 vrf verification + */ +function sr25519VrfVerify(message, signOutput, publicKey, context = EMPTY_U8A, extra = EMPTY_U8A) { + const publicKeyU8a = (0, util_1.u8aToU8a)(publicKey); + const proofU8a = (0, util_1.u8aToU8a)(signOutput); + if (publicKeyU8a.length !== 32) { + throw new Error('Invalid publicKey, expected 32-bytes'); + } + else if (proofU8a.length !== 96) { + throw new Error('Invalid vrfSign output, expected 96 bytes'); + } + return sr25519.vrf.verify((0, util_1.u8aToU8a)(message), proofU8a, publicKeyU8a, (0, util_1.u8aToU8a)(context), (0, util_1.u8aToU8a)(extra)); +} diff --git a/packages/util-crypto/cjs/types.d.ts b/packages/util-crypto/cjs/types.d.ts new file mode 100644 index 0000000..3d41bc3 --- /dev/null +++ b/packages/util-crypto/cjs/types.d.ts @@ -0,0 +1,26 @@ +export * from './address/types.js'; +export * from './json/types.js'; +export interface Keypair { + /** The publicKey for this pair */ + publicKey: Uint8Array; + /** The secretKey for this pair */ + secretKey: Uint8Array; +} +export interface Seedpair { + /** The publicKey for this pair */ + publicKey: Uint8Array; + /** The seed used to construct the pair */ + seed: Uint8Array; +} +/** The supported types of pairs */ +export type KeypairType = 'ed25519' | 'sr25519' | 'ecdsa' | 'ethereum'; +export interface VerifyResult { + /** The detected crypto interface, or 'none' if not detected */ + crypto: 'none' | KeypairType; + /** The validity for this result, false if invalid */ + isValid: boolean; + /** Flag to indicate if the passed data was wrapped in ... */ + isWrapped: boolean; + /** The extracted publicKey */ + publicKey: Uint8Array; +} diff --git a/packages/util-crypto/cjs/types.js b/packages/util-crypto/cjs/types.js new file mode 100644 index 0000000..c8dd0a3 --- /dev/null +++ b/packages/util-crypto/cjs/types.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +tslib_1.__exportStar(require("./address/types.js"), exports); +tslib_1.__exportStar(require("./json/types.js"), exports); diff --git a/packages/util-crypto/cjs/xxhash/asU8a.d.ts b/packages/util-crypto/cjs/xxhash/asU8a.d.ts new file mode 100644 index 0000000..084b9ba --- /dev/null +++ b/packages/util-crypto/cjs/xxhash/asU8a.d.ts @@ -0,0 +1,20 @@ +/** + * @name xxhashAsU8a + * @summary Creates a xxhash64 u8a from the input. + * @description + * From either a `string`, `Uint8Array` or a `Buffer` input, create the xxhash64 and return the result as a `Uint8Array` with the specified `bitLength`. + * @example + *
+ * + * ```javascript + * import { xxhashAsU8a } from '@pezkuwi/util-crypto'; + * + * xxhashAsU8a('abc'); // => 0x44bc2cf5ad770999 + * ``` + */ +export declare function xxhashAsU8a(data: string | Uint8Array, bitLength?: 64 | 128 | 192 | 256 | 320 | 384 | 448 | 512, onlyJs?: boolean): Uint8Array; +/** + * @name xxhashAsHex + * @description Creates a xxhash64 hex from the input. + */ +export declare const xxhashAsHex: (data: string | Uint8Array, bitLength?: 256 | 512 | 64 | 128 | 384 | 320 | 192 | 448 | undefined, onlyJs?: boolean | undefined) => import("@pezkuwi/util/types").HexString; diff --git a/packages/util-crypto/cjs/xxhash/asU8a.js b/packages/util-crypto/cjs/xxhash/asU8a.js new file mode 100644 index 0000000..899c936 --- /dev/null +++ b/packages/util-crypto/cjs/xxhash/asU8a.js @@ -0,0 +1,39 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.xxhashAsHex = void 0; +exports.xxhashAsU8a = xxhashAsU8a; +const util_1 = require("@pezkuwi/util"); +const wasm_crypto_1 = require("@pezkuwi/wasm-crypto"); +const helpers_js_1 = require("../helpers.js"); +const xxhash64_js_1 = require("./xxhash64.js"); +/** + * @name xxhashAsU8a + * @summary Creates a xxhash64 u8a from the input. + * @description + * From either a `string`, `Uint8Array` or a `Buffer` input, create the xxhash64 and return the result as a `Uint8Array` with the specified `bitLength`. + * @example + *
+ * + * ```javascript + * import { xxhashAsU8a } from '@pezkuwi/util-crypto'; + * + * xxhashAsU8a('abc'); // => 0x44bc2cf5ad770999 + * ``` + */ +function xxhashAsU8a(data, bitLength = 64, onlyJs) { + const rounds = Math.ceil(bitLength / 64); + const u8a = (0, util_1.u8aToU8a)(data); + if (!util_1.hasBigInt || (!onlyJs && (0, wasm_crypto_1.isReady)())) { + return (0, wasm_crypto_1.twox)(u8a, rounds); + } + const result = new Uint8Array(rounds * 8); + for (let seed = 0; seed < rounds; seed++) { + result.set((0, xxhash64_js_1.xxhash64)(u8a, seed).reverse(), seed * 8); + } + return result; +} +/** + * @name xxhashAsHex + * @description Creates a xxhash64 hex from the input. + */ +exports.xxhashAsHex = (0, helpers_js_1.createAsHex)(xxhashAsU8a); diff --git a/packages/util-crypto/cjs/xxhash/index.d.ts b/packages/util-crypto/cjs/xxhash/index.d.ts new file mode 100644 index 0000000..d81cae2 --- /dev/null +++ b/packages/util-crypto/cjs/xxhash/index.d.ts @@ -0,0 +1,4 @@ +/** + * @summary Create xxhash64 values with specified bitlengths + */ +export { xxhashAsHex, xxhashAsU8a } from './asU8a.js'; diff --git a/packages/util-crypto/cjs/xxhash/index.js b/packages/util-crypto/cjs/xxhash/index.js new file mode 100644 index 0000000..fa89935 --- /dev/null +++ b/packages/util-crypto/cjs/xxhash/index.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.xxhashAsU8a = exports.xxhashAsHex = void 0; +/** + * @summary Create xxhash64 values with specified bitlengths + */ +var asU8a_js_1 = require("./asU8a.js"); +Object.defineProperty(exports, "xxhashAsHex", { enumerable: true, get: function () { return asU8a_js_1.xxhashAsHex; } }); +Object.defineProperty(exports, "xxhashAsU8a", { enumerable: true, get: function () { return asU8a_js_1.xxhashAsU8a; } }); diff --git a/packages/util-crypto/cjs/xxhash/xxhash64.d.ts b/packages/util-crypto/cjs/xxhash/xxhash64.d.ts new file mode 100644 index 0000000..7dcfcc2 --- /dev/null +++ b/packages/util-crypto/cjs/xxhash/xxhash64.d.ts @@ -0,0 +1 @@ +export declare function xxhash64(input: Uint8Array, initSeed: bigint | number): Uint8Array; diff --git a/packages/util-crypto/cjs/xxhash/xxhash64.js b/packages/util-crypto/cjs/xxhash/xxhash64.js new file mode 100644 index 0000000..e71cc3d --- /dev/null +++ b/packages/util-crypto/cjs/xxhash/xxhash64.js @@ -0,0 +1,103 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.xxhash64 = xxhash64; +const util_1 = require("@pezkuwi/util"); +const x_bigint_1 = require("@pezkuwi/x-bigint"); +const P64_1 = (0, x_bigint_1.BigInt)('11400714785074694791'); +const P64_2 = (0, x_bigint_1.BigInt)('14029467366897019727'); +const P64_3 = (0, x_bigint_1.BigInt)('1609587929392839161'); +const P64_4 = (0, x_bigint_1.BigInt)('9650029242287828579'); +const P64_5 = (0, x_bigint_1.BigInt)('2870177450012600261'); +const U64 = (0, x_bigint_1.BigInt)('0xffffffffffffffff'); +const _7n = (0, x_bigint_1.BigInt)(7); +const _11n = (0, x_bigint_1.BigInt)(11); +const _12n = (0, x_bigint_1.BigInt)(12); +const _16n = (0, x_bigint_1.BigInt)(16); +const _18n = (0, x_bigint_1.BigInt)(18); +const _23n = (0, x_bigint_1.BigInt)(23); +const _27n = (0, x_bigint_1.BigInt)(27); +const _29n = (0, x_bigint_1.BigInt)(29); +const _31n = (0, x_bigint_1.BigInt)(31); +const _32n = (0, x_bigint_1.BigInt)(32); +const _33n = (0, x_bigint_1.BigInt)(33); +const _64n = (0, x_bigint_1.BigInt)(64); +const _256n = (0, x_bigint_1.BigInt)(256); +function rotl(a, b) { + const c = a & U64; + return ((c << b) | (c >> (_64n - b))) & U64; +} +function fromU8a(u8a, p, count) { + const bigints = new Array(count); + let offset = 0; + for (let i = 0; i < count; i++, offset += 2) { + bigints[i] = (0, x_bigint_1.BigInt)(u8a[p + offset] | (u8a[p + 1 + offset] << 8)); + } + let result = util_1._0n; + for (let i = count - 1; i >= 0; i--) { + result = (result << _16n) + bigints[i]; + } + return result; +} +function init(seed, input) { + const state = { + seed, + u8a: new Uint8Array(32), + u8asize: 0, + v1: seed + P64_1 + P64_2, + v2: seed + P64_2, + v3: seed, + v4: seed - P64_1 + }; + if (input.length < 32) { + state.u8a.set(input); + state.u8asize = input.length; + return state; + } + const limit = input.length - 32; + let p = 0; + if (limit >= 0) { + const adjustV = (v) => P64_1 * rotl(v + P64_2 * fromU8a(input, p, 4), _31n); + do { + state.v1 = adjustV(state.v1); + p += 8; + state.v2 = adjustV(state.v2); + p += 8; + state.v3 = adjustV(state.v3); + p += 8; + state.v4 = adjustV(state.v4); + p += 8; + } while (p <= limit); + } + if (p < input.length) { + state.u8a.set(input.subarray(p, input.length)); + state.u8asize = input.length - p; + } + return state; +} +function xxhash64(input, initSeed) { + const { seed, u8a, u8asize, v1, v2, v3, v4 } = init((0, x_bigint_1.BigInt)(initSeed), input); + let p = 0; + let h64 = U64 & ((0, x_bigint_1.BigInt)(input.length) + (input.length >= 32 + ? (((((((((rotl(v1, util_1._1n) + rotl(v2, _7n) + rotl(v3, _12n) + rotl(v4, _18n)) ^ (P64_1 * rotl(v1 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v2 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v3 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v4 * P64_2, _31n))) * P64_1 + P64_4) + : (seed + P64_5))); + while (p <= (u8asize - 8)) { + h64 = U64 & (P64_4 + P64_1 * rotl(h64 ^ (P64_1 * rotl(P64_2 * fromU8a(u8a, p, 4), _31n)), _27n)); + p += 8; + } + if ((p + 4) <= u8asize) { + h64 = U64 & (P64_3 + P64_2 * rotl(h64 ^ (P64_1 * fromU8a(u8a, p, 2)), _23n)); + p += 4; + } + while (p < u8asize) { + h64 = U64 & (P64_1 * rotl(h64 ^ (P64_5 * (0, x_bigint_1.BigInt)(u8a[p++])), _11n)); + } + h64 = U64 & (P64_2 * (h64 ^ (h64 >> _33n))); + h64 = U64 & (P64_3 * (h64 ^ (h64 >> _29n))); + h64 = U64 & (h64 ^ (h64 >> _32n)); + const result = new Uint8Array(8); + for (let i = 7; i >= 0; i--) { + result[i] = Number(h64 % _256n); + h64 = h64 / _256n; + } + return result; +} diff --git a/packages/util-crypto/crypto.d.ts b/packages/util-crypto/crypto.d.ts new file mode 100644 index 0000000..094f8b6 --- /dev/null +++ b/packages/util-crypto/crypto.d.ts @@ -0,0 +1,3 @@ +import { isReady } from '@pezkuwi/wasm-crypto'; +export declare const cryptoIsReady: typeof isReady; +export declare function cryptoWaitReady(): Promise; diff --git a/packages/util-crypto/crypto.js b/packages/util-crypto/crypto.js new file mode 100644 index 0000000..3d6e622 --- /dev/null +++ b/packages/util-crypto/crypto.js @@ -0,0 +1,12 @@ +import { isReady, waitReady } from '@pezkuwi/wasm-crypto'; +export const cryptoIsReady = isReady; +export function cryptoWaitReady() { + return waitReady() + .then(() => { + if (!isReady()) { + throw new Error('Unable to initialize @pezkuwi/util-crypto'); + } + return true; + }) + .catch(() => false); +} diff --git a/packages/util-crypto/ed25519/deriveHard.d.ts b/packages/util-crypto/ed25519/deriveHard.d.ts new file mode 100644 index 0000000..29aba40 --- /dev/null +++ b/packages/util-crypto/ed25519/deriveHard.d.ts @@ -0,0 +1 @@ +export declare function ed25519DeriveHard(seed: Uint8Array, chainCode: Uint8Array): Uint8Array; diff --git a/packages/util-crypto/ed25519/deriveHard.js b/packages/util-crypto/ed25519/deriveHard.js new file mode 100644 index 0000000..aa4399a --- /dev/null +++ b/packages/util-crypto/ed25519/deriveHard.js @@ -0,0 +1,9 @@ +import { compactAddLength, isU8a, stringToU8a, u8aConcat } from '@pezkuwi/util'; +import { blake2AsU8a } from '../blake2/asU8a.js'; +const HDKD = compactAddLength(stringToU8a('Ed25519HDKD')); +export function ed25519DeriveHard(seed, chainCode) { + if (!isU8a(chainCode) || chainCode.length !== 32) { + throw new Error('Invalid chainCode passed to derive'); + } + return blake2AsU8a(u8aConcat(HDKD, seed, chainCode)); +} diff --git a/packages/util-crypto/ed25519/index.d.ts b/packages/util-crypto/ed25519/index.d.ts new file mode 100644 index 0000000..5a29640 --- /dev/null +++ b/packages/util-crypto/ed25519/index.d.ts @@ -0,0 +1,10 @@ +/** + * @summary Implements ed25519 operations + */ +export { ed25519DeriveHard } from './deriveHard.js'; +export { ed25519PairFromRandom } from './pair/fromRandom.js'; +export { ed25519PairFromSecret } from './pair/fromSecret.js'; +export { ed25519PairFromSeed } from './pair/fromSeed.js'; +export { ed25519PairFromString } from './pair/fromString.js'; +export { ed25519Sign } from './sign.js'; +export { ed25519Verify } from './verify.js'; diff --git a/packages/util-crypto/ed25519/index.js b/packages/util-crypto/ed25519/index.js new file mode 100644 index 0000000..5a29640 --- /dev/null +++ b/packages/util-crypto/ed25519/index.js @@ -0,0 +1,10 @@ +/** + * @summary Implements ed25519 operations + */ +export { ed25519DeriveHard } from './deriveHard.js'; +export { ed25519PairFromRandom } from './pair/fromRandom.js'; +export { ed25519PairFromSecret } from './pair/fromSecret.js'; +export { ed25519PairFromSeed } from './pair/fromSeed.js'; +export { ed25519PairFromString } from './pair/fromString.js'; +export { ed25519Sign } from './sign.js'; +export { ed25519Verify } from './verify.js'; diff --git a/packages/util-crypto/ed25519/pair/fromRandom.d.ts b/packages/util-crypto/ed25519/pair/fromRandom.d.ts new file mode 100644 index 0000000..ce5d89e --- /dev/null +++ b/packages/util-crypto/ed25519/pair/fromRandom.d.ts @@ -0,0 +1,16 @@ +import type { Keypair } from '../../types.js'; +/** + * @name ed25519PairFromRandom + * @summary Creates a new public/secret keypair. + * @description + * Returns a new generate object containing a `publicKey` & `secretKey`. + * @example + *
+ * + * ```javascript + * import { ed25519PairFromRandom } from '@pezkuwi/util-crypto'; + * + * ed25519PairFromRandom(); // => { secretKey: [...], publicKey: [...] } + * ``` + */ +export declare function ed25519PairFromRandom(): Keypair; diff --git a/packages/util-crypto/ed25519/pair/fromRandom.js b/packages/util-crypto/ed25519/pair/fromRandom.js new file mode 100644 index 0000000..1768360 --- /dev/null +++ b/packages/util-crypto/ed25519/pair/fromRandom.js @@ -0,0 +1,19 @@ +import { randomAsU8a } from '../../random/index.js'; +import { ed25519PairFromSeed } from './fromSeed.js'; +/** + * @name ed25519PairFromRandom + * @summary Creates a new public/secret keypair. + * @description + * Returns a new generate object containing a `publicKey` & `secretKey`. + * @example + *
+ * + * ```javascript + * import { ed25519PairFromRandom } from '@pezkuwi/util-crypto'; + * + * ed25519PairFromRandom(); // => { secretKey: [...], publicKey: [...] } + * ``` + */ +export function ed25519PairFromRandom() { + return ed25519PairFromSeed(randomAsU8a()); +} diff --git a/packages/util-crypto/ed25519/pair/fromSecret.d.ts b/packages/util-crypto/ed25519/pair/fromSecret.d.ts new file mode 100644 index 0000000..a9bbfb6 --- /dev/null +++ b/packages/util-crypto/ed25519/pair/fromSecret.d.ts @@ -0,0 +1,16 @@ +import type { Keypair } from '../../types.js'; +/** + * @name ed25519PairFromSecret + * @summary Creates a new public/secret keypair from a secret. + * @description + * Returns a object containing a `publicKey` & `secretKey` generated from the supplied secret. + * @example + *
+ * + * ```javascript + * import { ed25519PairFromSecret } from '@pezkuwi/util-crypto'; + * + * ed25519PairFromSecret(...); // => { secretKey: [...], publicKey: [...] } + * ``` + */ +export declare function ed25519PairFromSecret(secretKey: Uint8Array): Keypair; diff --git a/packages/util-crypto/ed25519/pair/fromSecret.js b/packages/util-crypto/ed25519/pair/fromSecret.js new file mode 100644 index 0000000..59dba35 --- /dev/null +++ b/packages/util-crypto/ed25519/pair/fromSecret.js @@ -0,0 +1,23 @@ +/** + * @name ed25519PairFromSecret + * @summary Creates a new public/secret keypair from a secret. + * @description + * Returns a object containing a `publicKey` & `secretKey` generated from the supplied secret. + * @example + *
+ * + * ```javascript + * import { ed25519PairFromSecret } from '@pezkuwi/util-crypto'; + * + * ed25519PairFromSecret(...); // => { secretKey: [...], publicKey: [...] } + * ``` + */ +export function ed25519PairFromSecret(secretKey) { + if (secretKey.length !== 64) { + throw new Error('Invalid secretKey provided'); + } + return { + publicKey: secretKey.slice(32), + secretKey + }; +} diff --git a/packages/util-crypto/ed25519/pair/fromSeed.d.ts b/packages/util-crypto/ed25519/pair/fromSeed.d.ts new file mode 100644 index 0000000..f854cca --- /dev/null +++ b/packages/util-crypto/ed25519/pair/fromSeed.d.ts @@ -0,0 +1,16 @@ +import type { Keypair } from '../../types.js'; +/** + * @name ed25519PairFromSeed + * @summary Creates a new public/secret keypair from a seed. + * @description + * Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed. + * @example + *
+ * + * ```javascript + * import { ed25519PairFromSeed } from '@pezkuwi/util-crypto'; + * + * ed25519PairFromSeed(...); // => { secretKey: [...], publicKey: [...] } + * ``` + */ +export declare function ed25519PairFromSeed(seed: Uint8Array, onlyJs?: boolean): Keypair; diff --git a/packages/util-crypto/ed25519/pair/fromSeed.js b/packages/util-crypto/ed25519/pair/fromSeed.js new file mode 100644 index 0000000..6ab5149 --- /dev/null +++ b/packages/util-crypto/ed25519/pair/fromSeed.js @@ -0,0 +1,31 @@ +import { ed25519 } from '@noble/curves/ed25519'; +import { hasBigInt, u8aConcatStrict } from '@pezkuwi/util'; +import { ed25519KeypairFromSeed, isReady } from '@pezkuwi/wasm-crypto'; +/** + * @name ed25519PairFromSeed + * @summary Creates a new public/secret keypair from a seed. + * @description + * Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed. + * @example + *
+ * + * ```javascript + * import { ed25519PairFromSeed } from '@pezkuwi/util-crypto'; + * + * ed25519PairFromSeed(...); // => { secretKey: [...], publicKey: [...] } + * ``` + */ +export function ed25519PairFromSeed(seed, onlyJs) { + if (!hasBigInt || (!onlyJs && isReady())) { + const full = ed25519KeypairFromSeed(seed); + return { + publicKey: full.slice(32), + secretKey: full.slice(0, 64) + }; + } + const publicKey = ed25519.getPublicKey(seed); + return { + publicKey, + secretKey: u8aConcatStrict([seed, publicKey]) + }; +} diff --git a/packages/util-crypto/ed25519/pair/fromString.d.ts b/packages/util-crypto/ed25519/pair/fromString.d.ts new file mode 100644 index 0000000..6ff5640 --- /dev/null +++ b/packages/util-crypto/ed25519/pair/fromString.d.ts @@ -0,0 +1,16 @@ +import type { Keypair } from '../../types.js'; +/** + * @name ed25519PairFromString + * @summary Creates a new public/secret keypair from a string. + * @description + * Returns a object containing a `publicKey` & `secretKey` generated from the supplied string. The string is hashed and the value used as the input seed. + * @example + *
+ * + * ```javascript + * import { ed25519PairFromString } from '@pezkuwi/util-crypto'; + * + * ed25519PairFromString('test'); // => { secretKey: [...], publicKey: [...] } + * ``` + */ +export declare function ed25519PairFromString(value: string): Keypair; diff --git a/packages/util-crypto/ed25519/pair/fromString.js b/packages/util-crypto/ed25519/pair/fromString.js new file mode 100644 index 0000000..d080ab9 --- /dev/null +++ b/packages/util-crypto/ed25519/pair/fromString.js @@ -0,0 +1,20 @@ +import { stringToU8a } from '@pezkuwi/util'; +import { blake2AsU8a } from '../../blake2/asU8a.js'; +import { ed25519PairFromSeed } from './fromSeed.js'; +/** + * @name ed25519PairFromString + * @summary Creates a new public/secret keypair from a string. + * @description + * Returns a object containing a `publicKey` & `secretKey` generated from the supplied string. The string is hashed and the value used as the input seed. + * @example + *
+ * + * ```javascript + * import { ed25519PairFromString } from '@pezkuwi/util-crypto'; + * + * ed25519PairFromString('test'); // => { secretKey: [...], publicKey: [...] } + * ``` + */ +export function ed25519PairFromString(value) { + return ed25519PairFromSeed(blake2AsU8a(stringToU8a(value))); +} diff --git a/packages/util-crypto/ed25519/sign.d.ts b/packages/util-crypto/ed25519/sign.d.ts new file mode 100644 index 0000000..ce23440 --- /dev/null +++ b/packages/util-crypto/ed25519/sign.d.ts @@ -0,0 +1,16 @@ +import type { Keypair } from '../types.js'; +/** + * @name ed25519Sign + * @summary Signs a message using the supplied secretKey + * @description + * Returns message signature of `message`, using the `secretKey`. + * @example + *
+ * + * ```javascript + * import { ed25519Sign } from '@pezkuwi/util-crypto'; + * + * ed25519Sign([...], [...]); // => [...] + * ``` + */ +export declare function ed25519Sign(message: string | Uint8Array, { publicKey, secretKey }: Partial, onlyJs?: boolean): Uint8Array; diff --git a/packages/util-crypto/ed25519/sign.js b/packages/util-crypto/ed25519/sign.js new file mode 100644 index 0000000..b637794 --- /dev/null +++ b/packages/util-crypto/ed25519/sign.js @@ -0,0 +1,30 @@ +import { ed25519 } from '@noble/curves/ed25519'; +import { hasBigInt, u8aToU8a } from '@pezkuwi/util'; +import { ed25519Sign as wasmSign, isReady } from '@pezkuwi/wasm-crypto'; +/** + * @name ed25519Sign + * @summary Signs a message using the supplied secretKey + * @description + * Returns message signature of `message`, using the `secretKey`. + * @example + *
+ * + * ```javascript + * import { ed25519Sign } from '@pezkuwi/util-crypto'; + * + * ed25519Sign([...], [...]); // => [...] + * ``` + */ +export function ed25519Sign(message, { publicKey, secretKey }, onlyJs) { + if (!secretKey) { + throw new Error('Expected a valid secretKey'); + } + else if (!publicKey) { + throw new Error('Expected a valid publicKey'); + } + const messageU8a = u8aToU8a(message); + const privateU8a = secretKey.subarray(0, 32); + return !hasBigInt || (!onlyJs && isReady()) + ? wasmSign(publicKey, privateU8a, messageU8a) + : ed25519.sign(messageU8a, privateU8a); +} diff --git a/packages/util-crypto/ed25519/verify.d.ts b/packages/util-crypto/ed25519/verify.d.ts new file mode 100644 index 0000000..ec03efc --- /dev/null +++ b/packages/util-crypto/ed25519/verify.d.ts @@ -0,0 +1,15 @@ +/** + * @name ed25519Sign + * @summary Verifies the signature on the supplied message. + * @description + * Verifies the `signature` on `message` with the supplied `publicKey`. Returns `true` on sucess, `false` otherwise. + * @example + *
+ * + * ```javascript + * import { ed25519Verify } from '@pezkuwi/util-crypto'; + * + * ed25519Verify([...], [...], [...]); // => true/false + * ``` + */ +export declare function ed25519Verify(message: string | Uint8Array, signature: string | Uint8Array, publicKey: string | Uint8Array, onlyJs?: boolean): boolean; diff --git a/packages/util-crypto/ed25519/verify.js b/packages/util-crypto/ed25519/verify.js new file mode 100644 index 0000000..b86931c --- /dev/null +++ b/packages/util-crypto/ed25519/verify.js @@ -0,0 +1,36 @@ +import { ed25519 } from '@noble/curves/ed25519'; +import { hasBigInt, u8aToU8a } from '@pezkuwi/util'; +import { ed25519Verify as wasmVerify, isReady } from '@pezkuwi/wasm-crypto'; +/** + * @name ed25519Sign + * @summary Verifies the signature on the supplied message. + * @description + * Verifies the `signature` on `message` with the supplied `publicKey`. Returns `true` on sucess, `false` otherwise. + * @example + *
+ * + * ```javascript + * import { ed25519Verify } from '@pezkuwi/util-crypto'; + * + * ed25519Verify([...], [...], [...]); // => true/false + * ``` + */ +export function ed25519Verify(message, signature, publicKey, onlyJs) { + const messageU8a = u8aToU8a(message); + const publicKeyU8a = u8aToU8a(publicKey); + const signatureU8a = u8aToU8a(signature); + if (publicKeyU8a.length !== 32) { + throw new Error(`Invalid publicKey, received ${publicKeyU8a.length}, expected 32`); + } + else if (signatureU8a.length !== 64) { + throw new Error(`Invalid signature, received ${signatureU8a.length} bytes, expected 64`); + } + try { + return !hasBigInt || (!onlyJs && isReady()) + ? wasmVerify(signatureU8a, messageU8a, publicKeyU8a) + : ed25519.verify(signatureU8a, messageU8a, publicKeyU8a); + } + catch { + return false; + } +} diff --git a/packages/util-crypto/ethereum/encode.d.ts b/packages/util-crypto/ethereum/encode.d.ts new file mode 100644 index 0000000..a181856 --- /dev/null +++ b/packages/util-crypto/ethereum/encode.d.ts @@ -0,0 +1,2 @@ +import type { HexString } from '@pezkuwi/util/types'; +export declare function ethereumEncode(addressOrPublic?: string | Uint8Array): HexString; diff --git a/packages/util-crypto/ethereum/encode.js b/packages/util-crypto/ethereum/encode.js new file mode 100644 index 0000000..fc23c09 --- /dev/null +++ b/packages/util-crypto/ethereum/encode.js @@ -0,0 +1,25 @@ +import { u8aToHex, u8aToU8a } from '@pezkuwi/util'; +import { keccakAsU8a } from '../keccak/index.js'; +import { secp256k1Expand } from '../secp256k1/index.js'; +function getH160(u8a) { + if ([33, 65].includes(u8a.length)) { + u8a = keccakAsU8a(secp256k1Expand(u8a)); + } + return u8a.slice(-20); +} +export function ethereumEncode(addressOrPublic) { + if (!addressOrPublic) { + return '0x'; + } + const u8aAddress = u8aToU8a(addressOrPublic); + if (![20, 32, 33, 65].includes(u8aAddress.length)) { + throw new Error(`Invalid address or publicKey provided, received ${u8aAddress.length} bytes input`); + } + const address = u8aToHex(getH160(u8aAddress), -1, false); + const hash = u8aToHex(keccakAsU8a(address), -1, false); + let result = ''; + for (let i = 0; i < 40; i++) { + result = `${result}${parseInt(hash[i], 16) > 7 ? address[i].toUpperCase() : address[i]}`; + } + return `0x${result}`; +} diff --git a/packages/util-crypto/ethereum/index.d.ts b/packages/util-crypto/ethereum/index.d.ts new file mode 100644 index 0000000..d5621e7 --- /dev/null +++ b/packages/util-crypto/ethereum/index.d.ts @@ -0,0 +1,3 @@ +export { ethereumEncode } from './encode.js'; +export { isEthereumAddress } from './isAddress.js'; +export { isEthereumChecksum } from './isChecksum.js'; diff --git a/packages/util-crypto/ethereum/index.js b/packages/util-crypto/ethereum/index.js new file mode 100644 index 0000000..d5621e7 --- /dev/null +++ b/packages/util-crypto/ethereum/index.js @@ -0,0 +1,3 @@ +export { ethereumEncode } from './encode.js'; +export { isEthereumAddress } from './isAddress.js'; +export { isEthereumChecksum } from './isChecksum.js'; diff --git a/packages/util-crypto/ethereum/isAddress.d.ts b/packages/util-crypto/ethereum/isAddress.d.ts new file mode 100644 index 0000000..8f1b4f2 --- /dev/null +++ b/packages/util-crypto/ethereum/isAddress.d.ts @@ -0,0 +1 @@ +export declare function isEthereumAddress(address?: string): boolean; diff --git a/packages/util-crypto/ethereum/isAddress.js b/packages/util-crypto/ethereum/isAddress.js new file mode 100644 index 0000000..39ffb35 --- /dev/null +++ b/packages/util-crypto/ethereum/isAddress.js @@ -0,0 +1,11 @@ +import { isHex } from '@pezkuwi/util'; +import { isEthereumChecksum } from './isChecksum.js'; +export function isEthereumAddress(address) { + if (!address || address.length !== 42 || !isHex(address)) { + return false; + } + else if (/^(0x)?[0-9a-f]{40}$/.test(address) || /^(0x)?[0-9A-F]{40}$/.test(address)) { + return true; + } + return isEthereumChecksum(address); +} diff --git a/packages/util-crypto/ethereum/isChecksum.d.ts b/packages/util-crypto/ethereum/isChecksum.d.ts new file mode 100644 index 0000000..65a31c1 --- /dev/null +++ b/packages/util-crypto/ethereum/isChecksum.d.ts @@ -0,0 +1 @@ +export declare function isEthereumChecksum(_address: string): boolean; diff --git a/packages/util-crypto/ethereum/isChecksum.js b/packages/util-crypto/ethereum/isChecksum.js new file mode 100644 index 0000000..6a4dad8 --- /dev/null +++ b/packages/util-crypto/ethereum/isChecksum.js @@ -0,0 +1,17 @@ +import { u8aToHex } from '@pezkuwi/util'; +import { keccakAsU8a } from '../keccak/index.js'; +function isInvalidChar(char, byte) { + return char !== (byte > 7 + ? char.toUpperCase() + : char.toLowerCase()); +} +export function isEthereumChecksum(_address) { + const address = _address.replace('0x', ''); + const hash = u8aToHex(keccakAsU8a(address.toLowerCase()), -1, false); + for (let i = 0; i < 40; i++) { + if (isInvalidChar(address[i], parseInt(hash[i], 16))) { + return false; + } + } + return true; +} diff --git a/packages/util-crypto/hd/ethereum/index.d.ts b/packages/util-crypto/hd/ethereum/index.d.ts new file mode 100644 index 0000000..49a693a --- /dev/null +++ b/packages/util-crypto/hd/ethereum/index.d.ts @@ -0,0 +1,2 @@ +import type { Keypair } from '../../types.js'; +export declare function hdEthereum(seed: Uint8Array, path?: string): Keypair; diff --git a/packages/util-crypto/hd/ethereum/index.js b/packages/util-crypto/hd/ethereum/index.js new file mode 100644 index 0000000..93b0b16 --- /dev/null +++ b/packages/util-crypto/hd/ethereum/index.js @@ -0,0 +1,44 @@ +import { bnToU8a, stringToU8a, u8aConcat } from '@pezkuwi/util'; +import { BN_BE_32_OPTS } from '../../bn.js'; +import { hmacShaAsU8a } from '../../hmac/index.js'; +import { secp256k1PairFromSeed, secp256k1PrivateKeyTweakAdd } from '../../secp256k1/index.js'; +import { HARDENED, hdValidatePath } from '../validatePath.js'; +const MASTER_SECRET = stringToU8a('Bitcoin seed'); +function createCoded(secretKey, chainCode) { + return { + chainCode, + publicKey: secp256k1PairFromSeed(secretKey).publicKey, + secretKey + }; +} +function deriveChild(hd, index) { + const indexBuffer = bnToU8a(index, BN_BE_32_OPTS); + const data = index >= HARDENED + ? u8aConcat(new Uint8Array(1), hd.secretKey, indexBuffer) + : u8aConcat(hd.publicKey, indexBuffer); + try { + const I = hmacShaAsU8a(hd.chainCode, data, 512); + return createCoded(secp256k1PrivateKeyTweakAdd(hd.secretKey, I.slice(0, 32)), I.slice(32)); + } + catch { + // In case parse256(IL) >= n or ki == 0, proceed with the next value for i + return deriveChild(hd, index + 1); + } +} +export function hdEthereum(seed, path = '') { + const I = hmacShaAsU8a(MASTER_SECRET, seed, 512); + let hd = createCoded(I.slice(0, 32), I.slice(32)); + if (!path || path === 'm' || path === 'M' || path === "m'" || path === "M'") { + return hd; + } + if (!hdValidatePath(path)) { + throw new Error('Invalid derivation path'); + } + const parts = path.split('/').slice(1); + for (const p of parts) { + hd = deriveChild(hd, parseInt(p, 10) + ((p.length > 1) && p.endsWith("'") + ? HARDENED + : 0)); + } + return hd; +} diff --git a/packages/util-crypto/hd/index.d.ts b/packages/util-crypto/hd/index.d.ts new file mode 100644 index 0000000..a29e23a --- /dev/null +++ b/packages/util-crypto/hd/index.d.ts @@ -0,0 +1,3 @@ +export { hdEthereum } from './ethereum/index.js'; +export { hdLedger } from './ledger/index.js'; +export { hdValidatePath } from './validatePath.js'; diff --git a/packages/util-crypto/hd/index.js b/packages/util-crypto/hd/index.js new file mode 100644 index 0000000..a29e23a --- /dev/null +++ b/packages/util-crypto/hd/index.js @@ -0,0 +1,3 @@ +export { hdEthereum } from './ethereum/index.js'; +export { hdLedger } from './ledger/index.js'; +export { hdValidatePath } from './validatePath.js'; diff --git a/packages/util-crypto/hd/ledger/derivePrivate.d.ts b/packages/util-crypto/hd/ledger/derivePrivate.d.ts new file mode 100644 index 0000000..27ece08 --- /dev/null +++ b/packages/util-crypto/hd/ledger/derivePrivate.d.ts @@ -0,0 +1 @@ +export declare function ledgerDerivePrivate(xprv: Uint8Array, index: number): Uint8Array; diff --git a/packages/util-crypto/hd/ledger/derivePrivate.js b/packages/util-crypto/hd/ledger/derivePrivate.js new file mode 100644 index 0000000..d11ac9c --- /dev/null +++ b/packages/util-crypto/hd/ledger/derivePrivate.js @@ -0,0 +1,12 @@ +import { BN_EIGHT, bnToU8a, u8aConcat, u8aToBn } from '@pezkuwi/util'; +import { BN_LE_32_OPTS, BN_LE_512_OPTS, BN_LE_OPTS } from '../../bn.js'; +import { hmacShaAsU8a } from '../../hmac/index.js'; +export function ledgerDerivePrivate(xprv, index) { + const kl = xprv.subarray(0, 32); + const kr = xprv.subarray(32, 64); + const cc = xprv.subarray(64, 96); + const data = u8aConcat([0], kl, kr, bnToU8a(index, BN_LE_32_OPTS)); + const z = hmacShaAsU8a(cc, data, 512); + data[0] = 0x01; + return u8aConcat(bnToU8a(u8aToBn(kl, BN_LE_OPTS).iadd(u8aToBn(z.subarray(0, 28), BN_LE_OPTS).imul(BN_EIGHT)), BN_LE_512_OPTS).subarray(0, 32), bnToU8a(u8aToBn(kr, BN_LE_OPTS).iadd(u8aToBn(z.subarray(32, 64), BN_LE_OPTS)), BN_LE_512_OPTS).subarray(0, 32), hmacShaAsU8a(cc, data, 512).subarray(32, 64)); +} diff --git a/packages/util-crypto/hd/ledger/index.d.ts b/packages/util-crypto/hd/ledger/index.d.ts new file mode 100644 index 0000000..691d037 --- /dev/null +++ b/packages/util-crypto/hd/ledger/index.d.ts @@ -0,0 +1,2 @@ +import type { Keypair } from '../../types.js'; +export declare function hdLedger(_mnemonic: string, path: string): Keypair; diff --git a/packages/util-crypto/hd/ledger/index.js b/packages/util-crypto/hd/ledger/index.js new file mode 100644 index 0000000..78f557b --- /dev/null +++ b/packages/util-crypto/hd/ledger/index.js @@ -0,0 +1,30 @@ +import { ed25519PairFromSeed } from '../../ed25519/index.js'; +import { mnemonicValidate } from '../../mnemonic/index.js'; +import { HARDENED, hdValidatePath } from '../validatePath.js'; +import { ledgerDerivePrivate } from './derivePrivate.js'; +import { ledgerMaster } from './master.js'; +export function hdLedger(_mnemonic, path) { + const words = _mnemonic + .split(' ') + .map((s) => s.trim()) + .filter((s) => s); + if (![12, 24, 25].includes(words.length)) { + throw new Error('Expected a mnemonic with 24 words (or 25 including a password)'); + } + const [mnemonic, password] = words.length === 25 + ? [words.slice(0, 24).join(' '), words[24]] + : [words.join(' '), '']; + if (!mnemonicValidate(mnemonic)) { + throw new Error('Invalid mnemonic passed to ledger derivation'); + } + else if (!hdValidatePath(path)) { + throw new Error('Invalid derivation path'); + } + const parts = path.split('/').slice(1); + let seed = ledgerMaster(mnemonic, password); + for (const p of parts) { + const n = parseInt(p.replace(/'$/, ''), 10); + seed = ledgerDerivePrivate(seed, (n < HARDENED) ? (n + HARDENED) : n); + } + return ed25519PairFromSeed(seed.slice(0, 32)); +} diff --git a/packages/util-crypto/hd/ledger/master.d.ts b/packages/util-crypto/hd/ledger/master.d.ts new file mode 100644 index 0000000..47ac68f --- /dev/null +++ b/packages/util-crypto/hd/ledger/master.d.ts @@ -0,0 +1 @@ +export declare function ledgerMaster(mnemonic: string, password?: string): Uint8Array; diff --git a/packages/util-crypto/hd/ledger/master.js b/packages/util-crypto/hd/ledger/master.js new file mode 100644 index 0000000..c5fd106 --- /dev/null +++ b/packages/util-crypto/hd/ledger/master.js @@ -0,0 +1,16 @@ +import { u8aConcat } from '@pezkuwi/util'; +import { hmacShaAsU8a } from '../../hmac/index.js'; +import { mnemonicToSeedSync } from '../../mnemonic/bip39.js'; +const ED25519_CRYPTO = 'ed25519 seed'; +export function ledgerMaster(mnemonic, password) { + const seed = mnemonicToSeedSync(mnemonic, password); + const chainCode = hmacShaAsU8a(ED25519_CRYPTO, new Uint8Array([1, ...seed]), 256); + let priv; + while (!priv || (priv[31] & 0b0010_0000)) { + priv = hmacShaAsU8a(ED25519_CRYPTO, priv || seed, 512); + } + priv[0] &= 0b1111_1000; + priv[31] &= 0b0111_1111; + priv[31] |= 0b0100_0000; + return u8aConcat(priv, chainCode); +} diff --git a/packages/util-crypto/hd/validatePath.d.ts b/packages/util-crypto/hd/validatePath.d.ts new file mode 100644 index 0000000..6a26040 --- /dev/null +++ b/packages/util-crypto/hd/validatePath.d.ts @@ -0,0 +1,2 @@ +export declare const HARDENED = 2147483648; +export declare function hdValidatePath(path: string): boolean; diff --git a/packages/util-crypto/hd/validatePath.js b/packages/util-crypto/hd/validatePath.js new file mode 100644 index 0000000..1f60c9e --- /dev/null +++ b/packages/util-crypto/hd/validatePath.js @@ -0,0 +1,16 @@ +export const HARDENED = 0x80000000; +export function hdValidatePath(path) { + if (!path.startsWith('m/')) { + return false; + } + const parts = path.split('/').slice(1); + for (const p of parts) { + const n = /^\d+'?$/.test(p) + ? parseInt(p.replace(/'$/, ''), 10) + : Number.NaN; + if (isNaN(n) || (n >= HARDENED) || (n < 0)) { + return false; + } + } + return true; +} diff --git a/packages/util-crypto/helpers.d.ts b/packages/util-crypto/helpers.d.ts new file mode 100644 index 0000000..7d403bf --- /dev/null +++ b/packages/util-crypto/helpers.d.ts @@ -0,0 +1,12 @@ +import type { HexString } from '@pezkuwi/util/types'; +export type { HexString } from '@pezkuwi/util/types'; +interface DualHash { + 256: (u8a: Uint8Array) => Uint8Array; + 512: (u8a: Uint8Array) => Uint8Array; +} +/** @internal */ +export declare function createAsHex Uint8Array>(fn: T): (...args: Parameters) => HexString; +/** @internal */ +export declare function createBitHasher(bitLength: 256 | 512, fn: (data: string | Uint8Array, bitLength: 256 | 512, onlyJs?: boolean) => Uint8Array): (data: string | Uint8Array, onlyJs?: boolean) => Uint8Array; +/** @internal */ +export declare function createDualHasher(wa: DualHash, js: DualHash): (value: string | Uint8Array, bitLength?: 256 | 512, onlyJs?: boolean) => Uint8Array; diff --git a/packages/util-crypto/helpers.js b/packages/util-crypto/helpers.js new file mode 100644 index 0000000..8db067f --- /dev/null +++ b/packages/util-crypto/helpers.js @@ -0,0 +1,19 @@ +import { hasBigInt, u8aToHex, u8aToU8a } from '@pezkuwi/util'; +import { isReady } from '@pezkuwi/wasm-crypto'; +/** @internal */ +export function createAsHex(fn) { + return (...args) => u8aToHex(fn(...args)); +} +/** @internal */ +export function createBitHasher(bitLength, fn) { + return (data, onlyJs) => fn(data, bitLength, onlyJs); +} +/** @internal */ +export function createDualHasher(wa, js) { + return (value, bitLength = 256, onlyJs) => { + const u8a = u8aToU8a(value); + return !hasBigInt || (!onlyJs && isReady()) + ? wa[bitLength](u8a) + : js[bitLength](u8a); + }; +} diff --git a/packages/util-crypto/hmac/index.d.ts b/packages/util-crypto/hmac/index.d.ts new file mode 100644 index 0000000..248ba5c --- /dev/null +++ b/packages/util-crypto/hmac/index.d.ts @@ -0,0 +1 @@ +export { hmacSha256AsU8a, hmacSha512AsU8a, hmacShaAsU8a } from './shaAsU8a.js'; diff --git a/packages/util-crypto/hmac/index.js b/packages/util-crypto/hmac/index.js new file mode 100644 index 0000000..248ba5c --- /dev/null +++ b/packages/util-crypto/hmac/index.js @@ -0,0 +1 @@ +export { hmacSha256AsU8a, hmacSha512AsU8a, hmacShaAsU8a } from './shaAsU8a.js'; diff --git a/packages/util-crypto/hmac/shaAsU8a.d.ts b/packages/util-crypto/hmac/shaAsU8a.d.ts new file mode 100644 index 0000000..268cee9 --- /dev/null +++ b/packages/util-crypto/hmac/shaAsU8a.d.ts @@ -0,0 +1,15 @@ +/** + * @name hmacShaAsU8a + * @description creates a Hmac Sha (256/512) Uint8Array from the key & data + */ +export declare function hmacShaAsU8a(key: Uint8Array | string, data: Uint8Array, bitLength?: 256 | 512, onlyJs?: boolean): Uint8Array; +/** + * @name hmacSha256AsU8a + * @description creates a Hmac Sha256 Uint8Array from the key & data + */ +export declare const hmacSha256AsU8a: (key: Uint8Array | string, data: Uint8Array, onlyJs?: boolean) => Uint8Array; +/** + * @name hmacSha512AsU8a + * @description creates a Hmac Sha512 Uint8Array from the key & data + */ +export declare const hmacSha512AsU8a: (key: Uint8Array | string, data: Uint8Array, onlyJs?: boolean) => Uint8Array; diff --git a/packages/util-crypto/hmac/shaAsU8a.js b/packages/util-crypto/hmac/shaAsU8a.js new file mode 100644 index 0000000..3744e4a --- /dev/null +++ b/packages/util-crypto/hmac/shaAsU8a.js @@ -0,0 +1,36 @@ +import { hmac } from '@noble/hashes/hmac'; +import { sha256 } from '@noble/hashes/sha256'; +import { sha512 } from '@noble/hashes/sha512'; +import { hasBigInt, u8aToU8a } from '@pezkuwi/util'; +import { hmacSha256, hmacSha512, isReady } from '@pezkuwi/wasm-crypto'; +const JS_HASH = { + 256: sha256, + 512: sha512 +}; +const WA_MHAC = { + 256: hmacSha256, + 512: hmacSha512 +}; +function createSha(bitLength) { + return (key, data, onlyJs) => hmacShaAsU8a(key, data, bitLength, onlyJs); +} +/** + * @name hmacShaAsU8a + * @description creates a Hmac Sha (256/512) Uint8Array from the key & data + */ +export function hmacShaAsU8a(key, data, bitLength = 256, onlyJs) { + const u8aKey = u8aToU8a(key); + return !hasBigInt || (!onlyJs && isReady()) + ? WA_MHAC[bitLength](u8aKey, data) + : hmac(JS_HASH[bitLength], u8aKey, data); +} +/** + * @name hmacSha256AsU8a + * @description creates a Hmac Sha256 Uint8Array from the key & data + */ +export const hmacSha256AsU8a = /*#__PURE__*/ createSha(256); +/** + * @name hmacSha512AsU8a + * @description creates a Hmac Sha512 Uint8Array from the key & data + */ +export const hmacSha512AsU8a = /*#__PURE__*/ createSha(512); diff --git a/packages/util-crypto/index.d.ts b/packages/util-crypto/index.d.ts new file mode 100644 index 0000000..ca3f403 --- /dev/null +++ b/packages/util-crypto/index.d.ts @@ -0,0 +1,2 @@ +import './packageDetect.js'; +export * from './bundle.js'; diff --git a/packages/util-crypto/index.js b/packages/util-crypto/index.js new file mode 100644 index 0000000..ca3f403 --- /dev/null +++ b/packages/util-crypto/index.js @@ -0,0 +1,2 @@ +import './packageDetect.js'; +export * from './bundle.js'; diff --git a/packages/util-crypto/json/constants.d.ts b/packages/util-crypto/json/constants.d.ts new file mode 100644 index 0000000..ad69a81 --- /dev/null +++ b/packages/util-crypto/json/constants.d.ts @@ -0,0 +1,6 @@ +import type { EncryptedJsonEncoding, EncryptedJsonVersion } from './types.js'; +export declare const ENCODING: EncryptedJsonEncoding[]; +export declare const ENCODING_NONE: EncryptedJsonEncoding[]; +export declare const ENCODING_VERSION: EncryptedJsonVersion; +export declare const NONCE_LENGTH = 24; +export declare const SCRYPT_LENGTH: number; diff --git a/packages/util-crypto/json/constants.js b/packages/util-crypto/json/constants.js new file mode 100644 index 0000000..3113bb4 --- /dev/null +++ b/packages/util-crypto/json/constants.js @@ -0,0 +1,5 @@ +export const ENCODING = ['scrypt', 'xsalsa20-poly1305']; +export const ENCODING_NONE = ['none']; +export const ENCODING_VERSION = '3'; +export const NONCE_LENGTH = 24; +export const SCRYPT_LENGTH = 32 + (3 * 4); diff --git a/packages/util-crypto/json/decrypt.d.ts b/packages/util-crypto/json/decrypt.d.ts new file mode 100644 index 0000000..2d9e098 --- /dev/null +++ b/packages/util-crypto/json/decrypt.d.ts @@ -0,0 +1,2 @@ +import type { EncryptedJson } from './types.js'; +export declare function jsonDecrypt({ encoded, encoding }: EncryptedJson, passphrase?: string | null): Uint8Array; diff --git a/packages/util-crypto/json/decrypt.js b/packages/util-crypto/json/decrypt.js new file mode 100644 index 0000000..0274e92 --- /dev/null +++ b/packages/util-crypto/json/decrypt.js @@ -0,0 +1,13 @@ +import { hexToU8a, isHex } from '@pezkuwi/util'; +import { base64Decode } from '../base64/index.js'; +import { jsonDecryptData } from './decryptData.js'; +export function jsonDecrypt({ encoded, encoding }, passphrase) { + if (!encoded) { + throw new Error('No encrypted data available to decode'); + } + return jsonDecryptData(isHex(encoded) + ? hexToU8a(encoded) + : base64Decode(encoded), passphrase, Array.isArray(encoding.type) + ? encoding.type + : [encoding.type]); +} diff --git a/packages/util-crypto/json/decryptData.d.ts b/packages/util-crypto/json/decryptData.d.ts new file mode 100644 index 0000000..b4e604a --- /dev/null +++ b/packages/util-crypto/json/decryptData.d.ts @@ -0,0 +1,2 @@ +import type { EncryptedJsonEncoding } from './types.js'; +export declare function jsonDecryptData(encrypted?: Uint8Array | null, passphrase?: string | null, encType?: EncryptedJsonEncoding[]): Uint8Array; diff --git a/packages/util-crypto/json/decryptData.js b/packages/util-crypto/json/decryptData.js new file mode 100644 index 0000000..229b0e8 --- /dev/null +++ b/packages/util-crypto/json/decryptData.js @@ -0,0 +1,29 @@ +import { stringToU8a, u8aFixLength } from '@pezkuwi/util'; +import { naclDecrypt } from '../nacl/index.js'; +import { scryptEncode, scryptFromU8a } from '../scrypt/index.js'; +import { ENCODING, NONCE_LENGTH, SCRYPT_LENGTH } from './constants.js'; +export function jsonDecryptData(encrypted, passphrase, encType = ENCODING) { + if (!encrypted) { + throw new Error('No encrypted data available to decode'); + } + else if (encType.includes('xsalsa20-poly1305') && !passphrase) { + throw new Error('Password required to decode encrypted data'); + } + let encoded = encrypted; + if (passphrase) { + let password; + if (encType.includes('scrypt')) { + const { params, salt } = scryptFromU8a(encrypted); + password = scryptEncode(passphrase, salt, params).password; + encrypted = encrypted.subarray(SCRYPT_LENGTH); + } + else { + password = stringToU8a(passphrase); + } + encoded = naclDecrypt(encrypted.subarray(NONCE_LENGTH), encrypted.subarray(0, NONCE_LENGTH), u8aFixLength(password, 256, true)); + } + if (!encoded) { + throw new Error('Unable to decode using the supplied passphrase'); + } + return encoded; +} diff --git a/packages/util-crypto/json/encrypt.d.ts b/packages/util-crypto/json/encrypt.d.ts new file mode 100644 index 0000000..b98b235 --- /dev/null +++ b/packages/util-crypto/json/encrypt.d.ts @@ -0,0 +1,2 @@ +import type { EncryptedJson } from './types.js'; +export declare function jsonEncrypt(data: Uint8Array, contentType: string[], passphrase?: string | null): EncryptedJson; diff --git a/packages/util-crypto/json/encrypt.js b/packages/util-crypto/json/encrypt.js new file mode 100644 index 0000000..1b57911 --- /dev/null +++ b/packages/util-crypto/json/encrypt.js @@ -0,0 +1,15 @@ +import { u8aConcat } from '@pezkuwi/util'; +import { naclEncrypt } from '../nacl/index.js'; +import { scryptEncode, scryptToU8a } from '../scrypt/index.js'; +import { jsonEncryptFormat } from './encryptFormat.js'; +export function jsonEncrypt(data, contentType, passphrase) { + let isEncrypted = false; + let encoded = data; + if (passphrase) { + const { params, password, salt } = scryptEncode(passphrase); + const { encrypted, nonce } = naclEncrypt(encoded, password.subarray(0, 32)); + isEncrypted = true; + encoded = u8aConcat(scryptToU8a(salt, params), nonce, encrypted); + } + return jsonEncryptFormat(encoded, contentType, isEncrypted); +} diff --git a/packages/util-crypto/json/encryptFormat.d.ts b/packages/util-crypto/json/encryptFormat.d.ts new file mode 100644 index 0000000..468ea4a --- /dev/null +++ b/packages/util-crypto/json/encryptFormat.d.ts @@ -0,0 +1,2 @@ +import type { EncryptedJson } from './types.js'; +export declare function jsonEncryptFormat(encoded: Uint8Array, contentType: string[], isEncrypted: boolean): EncryptedJson; diff --git a/packages/util-crypto/json/encryptFormat.js b/packages/util-crypto/json/encryptFormat.js new file mode 100644 index 0000000..1a34235 --- /dev/null +++ b/packages/util-crypto/json/encryptFormat.js @@ -0,0 +1,14 @@ +import { base64Encode } from '../base64/index.js'; +import { ENCODING, ENCODING_NONE, ENCODING_VERSION } from './constants.js'; +export function jsonEncryptFormat(encoded, contentType, isEncrypted) { + return { + encoded: base64Encode(encoded), + encoding: { + content: contentType, + type: isEncrypted + ? ENCODING + : ENCODING_NONE, + version: ENCODING_VERSION + } + }; +} diff --git a/packages/util-crypto/json/index.d.ts b/packages/util-crypto/json/index.d.ts new file mode 100644 index 0000000..a4c694b --- /dev/null +++ b/packages/util-crypto/json/index.d.ts @@ -0,0 +1,4 @@ +export { jsonDecrypt } from './decrypt.js'; +export { jsonDecryptData } from './decryptData.js'; +export { jsonEncrypt } from './encrypt.js'; +export { jsonEncryptFormat } from './encryptFormat.js'; diff --git a/packages/util-crypto/json/index.js b/packages/util-crypto/json/index.js new file mode 100644 index 0000000..a4c694b --- /dev/null +++ b/packages/util-crypto/json/index.js @@ -0,0 +1,4 @@ +export { jsonDecrypt } from './decrypt.js'; +export { jsonDecryptData } from './decryptData.js'; +export { jsonEncrypt } from './encrypt.js'; +export { jsonEncryptFormat } from './encryptFormat.js'; diff --git a/packages/util-crypto/json/types.d.ts b/packages/util-crypto/json/types.d.ts new file mode 100644 index 0000000..cb4b881 --- /dev/null +++ b/packages/util-crypto/json/types.d.ts @@ -0,0 +1,16 @@ +export type EncryptedJsonVersion = '0' | '1' | '2' | '3'; +export type EncryptedJsonEncoding = 'none' | 'scrypt' | 'xsalsa20-poly1305'; +export interface EncryptedJsonDescriptor { + /** Descriptor for the content */ + content: string[]; + /** The encoding (in current/latest versions this is always an array) */ + type: EncryptedJsonEncoding | EncryptedJsonEncoding[]; + /** The version of encoding applied */ + version: EncryptedJsonVersion; +} +export interface EncryptedJson { + /** The encoded string */ + encoded: string; + /** The encoding used */ + encoding: EncryptedJsonDescriptor; +} diff --git a/packages/util-crypto/json/types.js b/packages/util-crypto/json/types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/util-crypto/json/types.js @@ -0,0 +1 @@ +export {}; diff --git a/packages/util-crypto/keccak/asU8a.d.ts b/packages/util-crypto/keccak/asU8a.d.ts new file mode 100644 index 0000000..3c4e1b5 --- /dev/null +++ b/packages/util-crypto/keccak/asU8a.d.ts @@ -0,0 +1,30 @@ +/** + * @name keccakAsU8a + * @summary Creates a keccak Uint8Array from the input. + * @description + * From either a `string` or a `Buffer` input, create the keccak and return the result as a `Uint8Array`. + * @example + *
+ * + * ```javascript + * import { keccakAsU8a } from '@pezkuwi/util-crypto'; + * + * keccakAsU8a('123'); // => Uint8Array + * ``` + */ +export declare const keccakAsU8a: (value: string | Uint8Array, bitLength?: 256 | 512, onlyJs?: boolean) => Uint8Array; +/** + * @name keccak256AsU8a + * @description Creates a keccak256 Uint8Array from the input. + */ +export declare const keccak256AsU8a: (data: string | Uint8Array, onlyJs?: boolean) => Uint8Array; +/** + * @name keccak512AsU8a + * @description Creates a keccak512 Uint8Array from the input. + */ +export declare const keccak512AsU8a: (data: string | Uint8Array, onlyJs?: boolean) => Uint8Array; +/** + * @name keccakAsHex + * @description Creates a keccak hex string from the input. + */ +export declare const keccakAsHex: (value: string | Uint8Array, bitLength?: 256 | 512 | undefined, onlyJs?: boolean | undefined) => import("@pezkuwi/util/types").HexString; diff --git a/packages/util-crypto/keccak/asU8a.js b/packages/util-crypto/keccak/asU8a.js new file mode 100644 index 0000000..99206e6 --- /dev/null +++ b/packages/util-crypto/keccak/asU8a.js @@ -0,0 +1,33 @@ +import { keccak_256 as keccak256Js, keccak_512 as keccak512Js } from '@noble/hashes/sha3'; +import { keccak256, keccak512 } from '@pezkuwi/wasm-crypto'; +import { createAsHex, createBitHasher, createDualHasher } from '../helpers.js'; +/** + * @name keccakAsU8a + * @summary Creates a keccak Uint8Array from the input. + * @description + * From either a `string` or a `Buffer` input, create the keccak and return the result as a `Uint8Array`. + * @example + *
+ * + * ```javascript + * import { keccakAsU8a } from '@pezkuwi/util-crypto'; + * + * keccakAsU8a('123'); // => Uint8Array + * ``` + */ +export const keccakAsU8a = /*#__PURE__*/ createDualHasher({ 256: keccak256, 512: keccak512 }, { 256: keccak256Js, 512: keccak512Js }); +/** + * @name keccak256AsU8a + * @description Creates a keccak256 Uint8Array from the input. + */ +export const keccak256AsU8a = /*#__PURE__*/ createBitHasher(256, keccakAsU8a); +/** + * @name keccak512AsU8a + * @description Creates a keccak512 Uint8Array from the input. + */ +export const keccak512AsU8a = /*#__PURE__*/ createBitHasher(512, keccakAsU8a); +/** + * @name keccakAsHex + * @description Creates a keccak hex string from the input. + */ +export const keccakAsHex = /*#__PURE__*/ createAsHex(keccakAsU8a); diff --git a/packages/util-crypto/keccak/index.d.ts b/packages/util-crypto/keccak/index.d.ts new file mode 100644 index 0000000..ad1f759 --- /dev/null +++ b/packages/util-crypto/keccak/index.d.ts @@ -0,0 +1,4 @@ +/** + * @summary Create Keccak256/512 values as hex & Uint8Array output + */ +export { keccak256AsU8a, keccak512AsU8a, keccakAsHex, keccakAsU8a } from './asU8a.js'; diff --git a/packages/util-crypto/keccak/index.js b/packages/util-crypto/keccak/index.js new file mode 100644 index 0000000..ad1f759 --- /dev/null +++ b/packages/util-crypto/keccak/index.js @@ -0,0 +1,4 @@ +/** + * @summary Create Keccak256/512 values as hex & Uint8Array output + */ +export { keccak256AsU8a, keccak512AsU8a, keccakAsHex, keccakAsU8a } from './asU8a.js'; diff --git a/packages/util-crypto/key/DeriveJunction.d.ts b/packages/util-crypto/key/DeriveJunction.d.ts new file mode 100644 index 0000000..652aaef --- /dev/null +++ b/packages/util-crypto/key/DeriveJunction.d.ts @@ -0,0 +1,12 @@ +import { BN } from '@pezkuwi/util'; +export declare class DeriveJunction { + #private; + static from(value: string): DeriveJunction; + get chainCode(): Uint8Array; + get isHard(): boolean; + get isSoft(): boolean; + hard(value: number | string | bigint | BN | Uint8Array): DeriveJunction; + harden(): DeriveJunction; + soft(value: number | string | bigint | BN | Uint8Array): DeriveJunction; + soften(): DeriveJunction; +} diff --git a/packages/util-crypto/key/DeriveJunction.js b/packages/util-crypto/key/DeriveJunction.js new file mode 100644 index 0000000..d7bdb52 --- /dev/null +++ b/packages/util-crypto/key/DeriveJunction.js @@ -0,0 +1,58 @@ +import { BN, bnToU8a, compactAddLength, hexToU8a, isBigInt, isBn, isHex, isNumber, isString, stringToU8a } from '@pezkuwi/util'; +import { blake2AsU8a } from '../blake2/asU8a.js'; +import { BN_LE_256_OPTS } from '../bn.js'; +const RE_NUMBER = /^\d+$/; +const JUNCTION_ID_LEN = 32; +export class DeriveJunction { + #chainCode = new Uint8Array(32); + #isHard = false; + static from(value) { + const result = new DeriveJunction(); + const [code, isHard] = value.startsWith('/') + ? [value.substring(1), true] + : [value, false]; + result.soft(RE_NUMBER.test(code) + ? new BN(code, 10) + : code); + return isHard + ? result.harden() + : result; + } + get chainCode() { + return this.#chainCode; + } + get isHard() { + return this.#isHard; + } + get isSoft() { + return !this.#isHard; + } + hard(value) { + return this.soft(value).harden(); + } + harden() { + this.#isHard = true; + return this; + } + soft(value) { + if (isNumber(value) || isBn(value) || isBigInt(value)) { + return this.soft(bnToU8a(value, BN_LE_256_OPTS)); + } + else if (isHex(value)) { + return this.soft(hexToU8a(value)); + } + else if (isString(value)) { + return this.soft(compactAddLength(stringToU8a(value))); + } + else if (value.length > JUNCTION_ID_LEN) { + return this.soft(blake2AsU8a(value)); + } + this.#chainCode.fill(0); + this.#chainCode.set(value, 0); + return this; + } + soften() { + this.#isHard = false; + return this; + } +} diff --git a/packages/util-crypto/key/extractPath.d.ts b/packages/util-crypto/key/extractPath.d.ts new file mode 100644 index 0000000..c50a96d --- /dev/null +++ b/packages/util-crypto/key/extractPath.d.ts @@ -0,0 +1,9 @@ +import { DeriveJunction } from './DeriveJunction.js'; +export interface ExtractResult { + parts: string[] | null; + path: DeriveJunction[]; +} +/** + * @description Extract derivation junctions from the supplied path + */ +export declare function keyExtractPath(derivePath: string): ExtractResult; diff --git a/packages/util-crypto/key/extractPath.js b/packages/util-crypto/key/extractPath.js new file mode 100644 index 0000000..b94863a --- /dev/null +++ b/packages/util-crypto/key/extractPath.js @@ -0,0 +1,23 @@ +import { DeriveJunction } from './DeriveJunction.js'; +const RE_JUNCTION = /\/(\/?)([^/]+)/g; +/** + * @description Extract derivation junctions from the supplied path + */ +export function keyExtractPath(derivePath) { + const parts = derivePath.match(RE_JUNCTION); + const path = []; + let constructed = ''; + if (parts) { + constructed = parts.join(''); + for (const p of parts) { + path.push(DeriveJunction.from(p.substring(1))); + } + } + if (constructed !== derivePath) { + throw new Error(`Re-constructed path "${constructed}" does not match input`); + } + return { + parts, + path + }; +} diff --git a/packages/util-crypto/key/extractSuri.d.ts b/packages/util-crypto/key/extractSuri.d.ts new file mode 100644 index 0000000..1959e50 --- /dev/null +++ b/packages/util-crypto/key/extractSuri.d.ts @@ -0,0 +1,11 @@ +import type { DeriveJunction } from './DeriveJunction.js'; +export interface ExtractResult { + derivePath: string; + password?: string; + path: DeriveJunction[]; + phrase: string; +} +/** + * @description Extracts the phrase, path and password from a SURI format for specifying secret keys `//////` (the `///password` may be omitted, and `/` and `//` maybe repeated and mixed). + */ +export declare function keyExtractSuri(suri: string): ExtractResult; diff --git a/packages/util-crypto/key/extractSuri.js b/packages/util-crypto/key/extractSuri.js new file mode 100644 index 0000000..51bf2ac --- /dev/null +++ b/packages/util-crypto/key/extractSuri.js @@ -0,0 +1,22 @@ +import { keyExtractPath } from './extractPath.js'; +const RE_CAPTURE = /^((0x[a-fA-F0-9]+|[\p{L}\d]+(?: [\p{L}\d]+)*))((\/\/?[^/]+)*)(\/\/\/(.*))?$/u; +/** + * @description Extracts the phrase, path and password from a SURI format for specifying secret keys `//////` (the `///password` may be omitted, and `/` and `//` maybe repeated and mixed). + */ +export function keyExtractSuri(suri) { + // Normalize Unicode to NFC to avoid accent-related mismatches + const normalizedSuri = suri.normalize('NFC'); + // eslint-disable-next-line @typescript-eslint/prefer-regexp-exec + const matches = normalizedSuri.match(RE_CAPTURE); + if (matches === null) { + throw new Error('Unable to match provided value to a secret URI'); + } + const [, phrase, , derivePath, , , password] = matches; + const { path } = keyExtractPath(derivePath); + return { + derivePath, + password, + path, + phrase + }; +} diff --git a/packages/util-crypto/key/fromPath.d.ts b/packages/util-crypto/key/fromPath.d.ts new file mode 100644 index 0000000..c19bc98 --- /dev/null +++ b/packages/util-crypto/key/fromPath.d.ts @@ -0,0 +1,3 @@ +import type { Keypair, KeypairType } from '../types.js'; +import type { DeriveJunction } from './DeriveJunction.js'; +export declare function keyFromPath(pair: Keypair, path: DeriveJunction[], type: KeypairType): Keypair; diff --git a/packages/util-crypto/key/fromPath.js b/packages/util-crypto/key/fromPath.js new file mode 100644 index 0000000..398b76b --- /dev/null +++ b/packages/util-crypto/key/fromPath.js @@ -0,0 +1,18 @@ +import { keyHdkdEcdsa } from './hdkdEcdsa.js'; +import { keyHdkdEd25519 } from './hdkdEd25519.js'; +import { keyHdkdSr25519 } from './hdkdSr25519.js'; +const generators = { + ecdsa: keyHdkdEcdsa, + ed25519: keyHdkdEd25519, + // FIXME This is Substrate-compatible, not Ethereum-compatible + ethereum: keyHdkdEcdsa, + sr25519: keyHdkdSr25519 +}; +export function keyFromPath(pair, path, type) { + const keyHdkd = generators[type]; + let result = pair; + for (const junction of path) { + result = keyHdkd(result, junction); + } + return result; +} diff --git a/packages/util-crypto/key/hdkdDerive.d.ts b/packages/util-crypto/key/hdkdDerive.d.ts new file mode 100644 index 0000000..999db52 --- /dev/null +++ b/packages/util-crypto/key/hdkdDerive.d.ts @@ -0,0 +1,3 @@ +import type { Keypair } from '../types.js'; +import type { DeriveJunction } from './DeriveJunction.js'; +export declare function createSeedDeriveFn(fromSeed: (seed: Uint8Array) => Keypair, derive: (seed: Uint8Array, chainCode: Uint8Array) => Uint8Array): (keypair: Keypair, junction: DeriveJunction) => Keypair; diff --git a/packages/util-crypto/key/hdkdDerive.js b/packages/util-crypto/key/hdkdDerive.js new file mode 100644 index 0000000..bf51952 --- /dev/null +++ b/packages/util-crypto/key/hdkdDerive.js @@ -0,0 +1,8 @@ +export function createSeedDeriveFn(fromSeed, derive) { + return (keypair, { chainCode, isHard }) => { + if (!isHard) { + throw new Error('A soft key was found in the path and is not supported'); + } + return fromSeed(derive(keypair.secretKey.subarray(0, 32), chainCode)); + }; +} diff --git a/packages/util-crypto/key/hdkdEcdsa.d.ts b/packages/util-crypto/key/hdkdEcdsa.d.ts new file mode 100644 index 0000000..941fd88 --- /dev/null +++ b/packages/util-crypto/key/hdkdEcdsa.d.ts @@ -0,0 +1 @@ +export declare const keyHdkdEcdsa: (keypair: import("../types.js").Keypair, junction: import("./DeriveJunction.js").DeriveJunction) => import("../types.js").Keypair; diff --git a/packages/util-crypto/key/hdkdEcdsa.js b/packages/util-crypto/key/hdkdEcdsa.js new file mode 100644 index 0000000..5dd492d --- /dev/null +++ b/packages/util-crypto/key/hdkdEcdsa.js @@ -0,0 +1,4 @@ +import { secp256k1DeriveHard } from '../secp256k1/deriveHard.js'; +import { secp256k1PairFromSeed } from '../secp256k1/pair/fromSeed.js'; +import { createSeedDeriveFn } from './hdkdDerive.js'; +export const keyHdkdEcdsa = /*#__PURE__*/ createSeedDeriveFn(secp256k1PairFromSeed, secp256k1DeriveHard); diff --git a/packages/util-crypto/key/hdkdEd25519.d.ts b/packages/util-crypto/key/hdkdEd25519.d.ts new file mode 100644 index 0000000..987fe0f --- /dev/null +++ b/packages/util-crypto/key/hdkdEd25519.d.ts @@ -0,0 +1 @@ +export declare const keyHdkdEd25519: (keypair: import("../types.js").Keypair, junction: import("./DeriveJunction.js").DeriveJunction) => import("../types.js").Keypair; diff --git a/packages/util-crypto/key/hdkdEd25519.js b/packages/util-crypto/key/hdkdEd25519.js new file mode 100644 index 0000000..31b5c03 --- /dev/null +++ b/packages/util-crypto/key/hdkdEd25519.js @@ -0,0 +1,3 @@ +import { ed25519DeriveHard, ed25519PairFromSeed } from '../ed25519/index.js'; +import { createSeedDeriveFn } from './hdkdDerive.js'; +export const keyHdkdEd25519 = /*#__PURE__*/ createSeedDeriveFn(ed25519PairFromSeed, ed25519DeriveHard); diff --git a/packages/util-crypto/key/hdkdSr25519.d.ts b/packages/util-crypto/key/hdkdSr25519.d.ts new file mode 100644 index 0000000..76e5460 --- /dev/null +++ b/packages/util-crypto/key/hdkdSr25519.d.ts @@ -0,0 +1,3 @@ +import type { Keypair } from '../types.js'; +import type { DeriveJunction } from './DeriveJunction.js'; +export declare function keyHdkdSr25519(keypair: Keypair, { chainCode, isSoft }: DeriveJunction): Keypair; diff --git a/packages/util-crypto/key/hdkdSr25519.js b/packages/util-crypto/key/hdkdSr25519.js new file mode 100644 index 0000000..fc4407e --- /dev/null +++ b/packages/util-crypto/key/hdkdSr25519.js @@ -0,0 +1,7 @@ +import { sr25519DeriveHard } from '../sr25519/deriveHard.js'; +import { sr25519DeriveSoft } from '../sr25519/deriveSoft.js'; +export function keyHdkdSr25519(keypair, { chainCode, isSoft }) { + return isSoft + ? sr25519DeriveSoft(keypair, chainCode) + : sr25519DeriveHard(keypair, chainCode); +} diff --git a/packages/util-crypto/key/index.d.ts b/packages/util-crypto/key/index.d.ts new file mode 100644 index 0000000..b9f8fef --- /dev/null +++ b/packages/util-crypto/key/index.d.ts @@ -0,0 +1,9 @@ +/** + * @summary Create keys from paths, seeds and password + */ +export { keyExtractPath } from './extractPath.js'; +export { keyExtractSuri } from './extractSuri.js'; +export { keyFromPath } from './fromPath.js'; +export { keyHdkdEcdsa } from './hdkdEcdsa.js'; +export { keyHdkdEd25519 } from './hdkdEd25519.js'; +export { keyHdkdSr25519 } from './hdkdSr25519.js'; diff --git a/packages/util-crypto/key/index.js b/packages/util-crypto/key/index.js new file mode 100644 index 0000000..b9f8fef --- /dev/null +++ b/packages/util-crypto/key/index.js @@ -0,0 +1,9 @@ +/** + * @summary Create keys from paths, seeds and password + */ +export { keyExtractPath } from './extractPath.js'; +export { keyExtractSuri } from './extractSuri.js'; +export { keyFromPath } from './fromPath.js'; +export { keyHdkdEcdsa } from './hdkdEcdsa.js'; +export { keyHdkdEd25519 } from './hdkdEd25519.js'; +export { keyHdkdSr25519 } from './hdkdSr25519.js'; diff --git a/packages/util-crypto/mnemonic/bip39.d.ts b/packages/util-crypto/mnemonic/bip39.d.ts new file mode 100644 index 0000000..7954450 --- /dev/null +++ b/packages/util-crypto/mnemonic/bip39.d.ts @@ -0,0 +1,5 @@ +export declare function mnemonicToSeedSync(mnemonic: string, password?: string): Uint8Array; +export declare function mnemonicToEntropy(mnemonic: string, wordlist?: string[]): Uint8Array; +export declare function entropyToMnemonic(entropy: Uint8Array, wordlist?: string[]): string; +export declare function generateMnemonic(numWords: 12 | 15 | 18 | 21 | 24, wordlist?: string[]): string; +export declare function validateMnemonic(mnemonic: string, wordlist?: string[]): boolean; diff --git a/packages/util-crypto/mnemonic/bip39.js b/packages/util-crypto/mnemonic/bip39.js new file mode 100644 index 0000000..4027759 --- /dev/null +++ b/packages/util-crypto/mnemonic/bip39.js @@ -0,0 +1,82 @@ +import { stringToU8a, u8aToU8a } from '@pezkuwi/util'; +import { pbkdf2Encode } from '../pbkdf2/index.js'; +import { randomAsU8a } from '../random/index.js'; +import { sha256AsU8a } from '../sha/index.js'; +import DEFAULT_WORDLIST from './wordlists/en.js'; +const INVALID_MNEMONIC = 'Invalid mnemonic'; +const INVALID_ENTROPY = 'Invalid entropy'; +const INVALID_CHECKSUM = 'Invalid mnemonic checksum'; +/** @internal */ +function normalize(str) { + return (str || '').normalize('NFKD'); +} +/** @internal */ +function binaryToByte(bin) { + return parseInt(bin, 2); +} +/** @internal */ +function bytesToBinary(bytes) { + return bytes.map((x) => x.toString(2).padStart(8, '0')).join(''); +} +/** @internal */ +function deriveChecksumBits(entropyBuffer) { + return bytesToBinary(Array.from(sha256AsU8a(entropyBuffer))).slice(0, (entropyBuffer.length * 8) / 32); +} +export function mnemonicToSeedSync(mnemonic, password) { + return pbkdf2Encode(stringToU8a(normalize(mnemonic)), stringToU8a(`mnemonic${normalize(password)}`)).password; +} +export function mnemonicToEntropy(mnemonic, wordlist = DEFAULT_WORDLIST) { + const words = normalize(mnemonic).split(' '); + if (words.length % 3 !== 0) { + throw new Error(INVALID_MNEMONIC); + } + // convert word indices to 11 bit binary strings + const bits = words + .map((word) => { + const index = wordlist.indexOf(word); + if (index === -1) { + throw new Error(INVALID_MNEMONIC); + } + return index.toString(2).padStart(11, '0'); + }) + .join(''); + // split the binary string into ENT/CS + const dividerIndex = Math.floor(bits.length / 33) * 32; + const entropyBits = bits.slice(0, dividerIndex); + const checksumBits = bits.slice(dividerIndex); + // calculate the checksum and compare + const matched = entropyBits.match(/(.{1,8})/g); + const entropyBytes = matched?.map(binaryToByte); + if (!entropyBytes || (entropyBytes.length % 4 !== 0) || (entropyBytes.length < 16) || (entropyBytes.length > 32)) { + throw new Error(INVALID_ENTROPY); + } + const entropy = u8aToU8a(entropyBytes); + if (deriveChecksumBits(entropy) !== checksumBits) { + throw new Error(INVALID_CHECKSUM); + } + return entropy; +} +export function entropyToMnemonic(entropy, wordlist = DEFAULT_WORDLIST) { + // 128 <= ENT <= 256 + if ((entropy.length % 4 !== 0) || (entropy.length < 16) || (entropy.length > 32)) { + throw new Error(INVALID_ENTROPY); + } + const matched = `${bytesToBinary(Array.from(entropy))}${deriveChecksumBits(entropy)}`.match(/(.{1,11})/g); + const mapped = matched?.map((b) => wordlist[binaryToByte(b)]); + if (!mapped || (mapped.length < 12)) { + throw new Error('Unable to map entropy to mnemonic'); + } + return mapped.join(' '); +} +export function generateMnemonic(numWords, wordlist) { + return entropyToMnemonic(randomAsU8a((numWords / 3) * 4), wordlist); +} +export function validateMnemonic(mnemonic, wordlist) { + try { + mnemonicToEntropy(mnemonic, wordlist); + } + catch { + return false; + } + return true; +} diff --git a/packages/util-crypto/mnemonic/generate.d.ts b/packages/util-crypto/mnemonic/generate.d.ts new file mode 100644 index 0000000..6e9646e --- /dev/null +++ b/packages/util-crypto/mnemonic/generate.d.ts @@ -0,0 +1,13 @@ +/** + * @name mnemonicGenerate + * @summary Creates a valid mnemonic string using using [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki). + * @example + *
+ * + * ```javascript + * import { mnemonicGenerate } from '@pezkuwi/util-crypto'; + * + * const mnemonic = mnemonicGenerate(); // => string + * ``` + */ +export declare function mnemonicGenerate(numWords?: 12 | 15 | 18 | 21 | 24, wordlist?: string[], onlyJs?: boolean): string; diff --git a/packages/util-crypto/mnemonic/generate.js b/packages/util-crypto/mnemonic/generate.js new file mode 100644 index 0000000..62f0168 --- /dev/null +++ b/packages/util-crypto/mnemonic/generate.js @@ -0,0 +1,20 @@ +import { hasBigInt } from '@pezkuwi/util'; +import { bip39Generate, isReady } from '@pezkuwi/wasm-crypto'; +import { generateMnemonic } from './bip39.js'; +/** + * @name mnemonicGenerate + * @summary Creates a valid mnemonic string using using [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki). + * @example + *
+ * + * ```javascript + * import { mnemonicGenerate } from '@pezkuwi/util-crypto'; + * + * const mnemonic = mnemonicGenerate(); // => string + * ``` + */ +export function mnemonicGenerate(numWords = 12, wordlist, onlyJs) { + return !hasBigInt || (!wordlist && !onlyJs && isReady()) + ? bip39Generate(numWords) + : generateMnemonic(numWords, wordlist); +} diff --git a/packages/util-crypto/mnemonic/index.d.ts b/packages/util-crypto/mnemonic/index.d.ts new file mode 100644 index 0000000..8cbbc5b --- /dev/null +++ b/packages/util-crypto/mnemonic/index.d.ts @@ -0,0 +1,8 @@ +/** + * @summary Create valid mnemonic strings, validate them using BIP39, and convert them to valid seeds + */ +export { mnemonicGenerate } from './generate.js'; +export { mnemonicToEntropy } from './toEntropy.js'; +export { mnemonicToLegacySeed } from './toLegacySeed.js'; +export { mnemonicToMiniSecret } from './toMiniSecret.js'; +export { mnemonicValidate } from './validate.js'; diff --git a/packages/util-crypto/mnemonic/index.js b/packages/util-crypto/mnemonic/index.js new file mode 100644 index 0000000..8cbbc5b --- /dev/null +++ b/packages/util-crypto/mnemonic/index.js @@ -0,0 +1,8 @@ +/** + * @summary Create valid mnemonic strings, validate them using BIP39, and convert them to valid seeds + */ +export { mnemonicGenerate } from './generate.js'; +export { mnemonicToEntropy } from './toEntropy.js'; +export { mnemonicToLegacySeed } from './toLegacySeed.js'; +export { mnemonicToMiniSecret } from './toMiniSecret.js'; +export { mnemonicValidate } from './validate.js'; diff --git a/packages/util-crypto/mnemonic/toEntropy.d.ts b/packages/util-crypto/mnemonic/toEntropy.d.ts new file mode 100644 index 0000000..d3c7af5 --- /dev/null +++ b/packages/util-crypto/mnemonic/toEntropy.d.ts @@ -0,0 +1 @@ +export declare function mnemonicToEntropy(mnemonic: string, wordlist?: string[], onlyJs?: boolean): Uint8Array; diff --git a/packages/util-crypto/mnemonic/toEntropy.js b/packages/util-crypto/mnemonic/toEntropy.js new file mode 100644 index 0000000..1662f92 --- /dev/null +++ b/packages/util-crypto/mnemonic/toEntropy.js @@ -0,0 +1,8 @@ +import { hasBigInt } from '@pezkuwi/util'; +import { bip39ToEntropy, isReady } from '@pezkuwi/wasm-crypto'; +import { mnemonicToEntropy as jsToEntropy } from './bip39.js'; +export function mnemonicToEntropy(mnemonic, wordlist, onlyJs) { + return !hasBigInt || (!wordlist && !onlyJs && isReady()) + ? bip39ToEntropy(mnemonic) + : jsToEntropy(mnemonic, wordlist); +} diff --git a/packages/util-crypto/mnemonic/toLegacySeed.d.ts b/packages/util-crypto/mnemonic/toLegacySeed.d.ts new file mode 100644 index 0000000..8b3ddec --- /dev/null +++ b/packages/util-crypto/mnemonic/toLegacySeed.d.ts @@ -0,0 +1,18 @@ +/** + * @name mnemonicToLegacySeed + * @summary Creates a valid Ethereum/Bitcoin-compatible seed from a mnemonic input + * @example + *
+ * + * ```javascript + * import { mnemonicGenerate, mnemonicToLegacySeed, mnemonicValidate } from '@pezkuwi/util-crypto'; + * + * const mnemonic = mnemonicGenerate(); // => string + * const isValidMnemonic = mnemonicValidate(mnemonic); // => boolean + * + * if (isValidMnemonic) { + * console.log(`Seed generated from mnemonic: ${mnemonicToLegacySeed(mnemonic)}`); => u8a + * } + * ``` + */ +export declare function mnemonicToLegacySeed(mnemonic: string, password?: string, onlyJs?: boolean, byteLength?: 32 | 64): Uint8Array; diff --git a/packages/util-crypto/mnemonic/toLegacySeed.js b/packages/util-crypto/mnemonic/toLegacySeed.js new file mode 100644 index 0000000..9c6c94f --- /dev/null +++ b/packages/util-crypto/mnemonic/toLegacySeed.js @@ -0,0 +1,34 @@ +import { hasBigInt } from '@pezkuwi/util'; +import { bip39ToSeed, isReady } from '@pezkuwi/wasm-crypto'; +import { mnemonicToSeedSync } from './bip39.js'; +import { mnemonicValidate } from './validate.js'; +/** + * @name mnemonicToLegacySeed + * @summary Creates a valid Ethereum/Bitcoin-compatible seed from a mnemonic input + * @example + *
+ * + * ```javascript + * import { mnemonicGenerate, mnemonicToLegacySeed, mnemonicValidate } from '@pezkuwi/util-crypto'; + * + * const mnemonic = mnemonicGenerate(); // => string + * const isValidMnemonic = mnemonicValidate(mnemonic); // => boolean + * + * if (isValidMnemonic) { + * console.log(`Seed generated from mnemonic: ${mnemonicToLegacySeed(mnemonic)}`); => u8a + * } + * ``` + */ +export function mnemonicToLegacySeed(mnemonic, password = '', onlyJs, byteLength = 32) { + if (!mnemonicValidate(mnemonic)) { + throw new Error('Invalid bip39 mnemonic specified'); + } + else if (![32, 64].includes(byteLength)) { + throw new Error(`Invalid seed length ${byteLength}, expected 32 or 64`); + } + return byteLength === 32 + ? !hasBigInt || (!onlyJs && isReady()) + ? bip39ToSeed(mnemonic, password) + : mnemonicToSeedSync(mnemonic, password).subarray(0, 32) + : mnemonicToSeedSync(mnemonic, password); +} diff --git a/packages/util-crypto/mnemonic/toMiniSecret.d.ts b/packages/util-crypto/mnemonic/toMiniSecret.d.ts new file mode 100644 index 0000000..4b91b32 --- /dev/null +++ b/packages/util-crypto/mnemonic/toMiniSecret.d.ts @@ -0,0 +1 @@ +export declare function mnemonicToMiniSecret(mnemonic: string, password?: string, wordlist?: string[], onlyJs?: boolean): Uint8Array; diff --git a/packages/util-crypto/mnemonic/toMiniSecret.js b/packages/util-crypto/mnemonic/toMiniSecret.js new file mode 100644 index 0000000..0653078 --- /dev/null +++ b/packages/util-crypto/mnemonic/toMiniSecret.js @@ -0,0 +1,17 @@ +import { stringToU8a } from '@pezkuwi/util'; +import { bip39ToMiniSecret, isReady } from '@pezkuwi/wasm-crypto'; +import { pbkdf2Encode } from '../pbkdf2/index.js'; +import { mnemonicToEntropy } from './toEntropy.js'; +import { mnemonicValidate } from './validate.js'; +export function mnemonicToMiniSecret(mnemonic, password = '', wordlist, onlyJs) { + if (!mnemonicValidate(mnemonic, wordlist, onlyJs)) { + throw new Error('Invalid bip39 mnemonic specified'); + } + else if (!wordlist && !onlyJs && isReady()) { + return bip39ToMiniSecret(mnemonic, password); + } + const entropy = mnemonicToEntropy(mnemonic, wordlist); + const salt = stringToU8a(`mnemonic${password}`); + // return the first 32 bytes as the seed + return pbkdf2Encode(entropy, salt).password.slice(0, 32); +} diff --git a/packages/util-crypto/mnemonic/validate.d.ts b/packages/util-crypto/mnemonic/validate.d.ts new file mode 100644 index 0000000..b647713 --- /dev/null +++ b/packages/util-crypto/mnemonic/validate.d.ts @@ -0,0 +1,14 @@ +/** + * @name mnemonicValidate + * @summary Validates a mnemonic input using [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki). + * @example + *
+ * + * ```javascript + * import { mnemonicGenerate, mnemonicValidate } from '@pezkuwi/util-crypto'; + * + * const mnemonic = mnemonicGenerate(); // => string + * const isValidMnemonic = mnemonicValidate(mnemonic); // => boolean + * ``` + */ +export declare function mnemonicValidate(mnemonic: string, wordlist?: string[], onlyJs?: boolean): boolean; diff --git a/packages/util-crypto/mnemonic/validate.js b/packages/util-crypto/mnemonic/validate.js new file mode 100644 index 0000000..c6dcc24 --- /dev/null +++ b/packages/util-crypto/mnemonic/validate.js @@ -0,0 +1,21 @@ +import { hasBigInt } from '@pezkuwi/util'; +import { bip39Validate, isReady } from '@pezkuwi/wasm-crypto'; +import { validateMnemonic } from './bip39.js'; +/** + * @name mnemonicValidate + * @summary Validates a mnemonic input using [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki). + * @example + *
+ * + * ```javascript + * import { mnemonicGenerate, mnemonicValidate } from '@pezkuwi/util-crypto'; + * + * const mnemonic = mnemonicGenerate(); // => string + * const isValidMnemonic = mnemonicValidate(mnemonic); // => boolean + * ``` + */ +export function mnemonicValidate(mnemonic, wordlist, onlyJs) { + return !hasBigInt || (!wordlist && !onlyJs && isReady()) + ? bip39Validate(mnemonic) + : validateMnemonic(mnemonic, wordlist); +} diff --git a/packages/util-crypto/mnemonic/wordlists/en.d.ts b/packages/util-crypto/mnemonic/wordlists/en.d.ts new file mode 100644 index 0000000..d451d2b --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/en.d.ts @@ -0,0 +1,2 @@ +declare const _default: string[]; +export default _default; diff --git a/packages/util-crypto/mnemonic/wordlists/en.js b/packages/util-crypto/mnemonic/wordlists/en.js new file mode 100644 index 0000000..4600b2d --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/en.js @@ -0,0 +1 @@ +export default 'abandon|ability|able|about|above|absent|absorb|abstract|absurd|abuse|access|accident|account|accuse|achieve|acid|acoustic|acquire|across|act|action|actor|actress|actual|adapt|add|addict|address|adjust|admit|adult|advance|advice|aerobic|affair|afford|afraid|again|age|agent|agree|ahead|aim|air|airport|aisle|alarm|album|alcohol|alert|alien|all|alley|allow|almost|alone|alpha|already|also|alter|always|amateur|amazing|among|amount|amused|analyst|anchor|ancient|anger|angle|angry|animal|ankle|announce|annual|another|answer|antenna|antique|anxiety|any|apart|apology|appear|apple|approve|april|arch|arctic|area|arena|argue|arm|armed|armor|army|around|arrange|arrest|arrive|arrow|art|artefact|artist|artwork|ask|aspect|assault|asset|assist|assume|asthma|athlete|atom|attack|attend|attitude|attract|auction|audit|august|aunt|author|auto|autumn|average|avocado|avoid|awake|aware|away|awesome|awful|awkward|axis|baby|bachelor|bacon|badge|bag|balance|balcony|ball|bamboo|banana|banner|bar|barely|bargain|barrel|base|basic|basket|battle|beach|bean|beauty|because|become|beef|before|begin|behave|behind|believe|below|belt|bench|benefit|best|betray|better|between|beyond|bicycle|bid|bike|bind|biology|bird|birth|bitter|black|blade|blame|blanket|blast|bleak|bless|blind|blood|blossom|blouse|blue|blur|blush|board|boat|body|boil|bomb|bone|bonus|book|boost|border|boring|borrow|boss|bottom|bounce|box|boy|bracket|brain|brand|brass|brave|bread|breeze|brick|bridge|brief|bright|bring|brisk|broccoli|broken|bronze|broom|brother|brown|brush|bubble|buddy|budget|buffalo|build|bulb|bulk|bullet|bundle|bunker|burden|burger|burst|bus|business|busy|butter|buyer|buzz|cabbage|cabin|cable|cactus|cage|cake|call|calm|camera|camp|can|canal|cancel|candy|cannon|canoe|canvas|canyon|capable|capital|captain|car|carbon|card|cargo|carpet|carry|cart|case|cash|casino|castle|casual|cat|catalog|catch|category|cattle|caught|cause|caution|cave|ceiling|celery|cement|census|century|cereal|certain|chair|chalk|champion|change|chaos|chapter|charge|chase|chat|cheap|check|cheese|chef|cherry|chest|chicken|chief|child|chimney|choice|choose|chronic|chuckle|chunk|churn|cigar|cinnamon|circle|citizen|city|civil|claim|clap|clarify|claw|clay|clean|clerk|clever|click|client|cliff|climb|clinic|clip|clock|clog|close|cloth|cloud|clown|club|clump|cluster|clutch|coach|coast|coconut|code|coffee|coil|coin|collect|color|column|combine|come|comfort|comic|common|company|concert|conduct|confirm|congress|connect|consider|control|convince|cook|cool|copper|copy|coral|core|corn|correct|cost|cotton|couch|country|couple|course|cousin|cover|coyote|crack|cradle|craft|cram|crane|crash|crater|crawl|crazy|cream|credit|creek|crew|cricket|crime|crisp|critic|crop|cross|crouch|crowd|crucial|cruel|cruise|crumble|crunch|crush|cry|crystal|cube|culture|cup|cupboard|curious|current|curtain|curve|cushion|custom|cute|cycle|dad|damage|damp|dance|danger|daring|dash|daughter|dawn|day|deal|debate|debris|decade|december|decide|decline|decorate|decrease|deer|defense|define|defy|degree|delay|deliver|demand|demise|denial|dentist|deny|depart|depend|deposit|depth|deputy|derive|describe|desert|design|desk|despair|destroy|detail|detect|develop|device|devote|diagram|dial|diamond|diary|dice|diesel|diet|differ|digital|dignity|dilemma|dinner|dinosaur|direct|dirt|disagree|discover|disease|dish|dismiss|disorder|display|distance|divert|divide|divorce|dizzy|doctor|document|dog|doll|dolphin|domain|donate|donkey|donor|door|dose|double|dove|draft|dragon|drama|drastic|draw|dream|dress|drift|drill|drink|drip|drive|drop|drum|dry|duck|dumb|dune|during|dust|dutch|duty|dwarf|dynamic|eager|eagle|early|earn|earth|easily|east|easy|echo|ecology|economy|edge|edit|educate|effort|egg|eight|either|elbow|elder|electric|elegant|element|elephant|elevator|elite|else|embark|embody|embrace|emerge|emotion|employ|empower|empty|enable|enact|end|endless|endorse|enemy|energy|enforce|engage|engine|enhance|enjoy|enlist|enough|enrich|enroll|ensure|enter|entire|entry|envelope|episode|equal|equip|era|erase|erode|erosion|error|erupt|escape|essay|essence|estate|eternal|ethics|evidence|evil|evoke|evolve|exact|example|excess|exchange|excite|exclude|excuse|execute|exercise|exhaust|exhibit|exile|exist|exit|exotic|expand|expect|expire|explain|expose|express|extend|extra|eye|eyebrow|fabric|face|faculty|fade|faint|faith|fall|false|fame|family|famous|fan|fancy|fantasy|farm|fashion|fat|fatal|father|fatigue|fault|favorite|feature|february|federal|fee|feed|feel|female|fence|festival|fetch|fever|few|fiber|fiction|field|figure|file|film|filter|final|find|fine|finger|finish|fire|firm|first|fiscal|fish|fit|fitness|fix|flag|flame|flash|flat|flavor|flee|flight|flip|float|flock|floor|flower|fluid|flush|fly|foam|focus|fog|foil|fold|follow|food|foot|force|forest|forget|fork|fortune|forum|forward|fossil|foster|found|fox|fragile|frame|frequent|fresh|friend|fringe|frog|front|frost|frown|frozen|fruit|fuel|fun|funny|furnace|fury|future|gadget|gain|galaxy|gallery|game|gap|garage|garbage|garden|garlic|garment|gas|gasp|gate|gather|gauge|gaze|general|genius|genre|gentle|genuine|gesture|ghost|giant|gift|giggle|ginger|giraffe|girl|give|glad|glance|glare|glass|glide|glimpse|globe|gloom|glory|glove|glow|glue|goat|goddess|gold|good|goose|gorilla|gospel|gossip|govern|gown|grab|grace|grain|grant|grape|grass|gravity|great|green|grid|grief|grit|grocery|group|grow|grunt|guard|guess|guide|guilt|guitar|gun|gym|habit|hair|half|hammer|hamster|hand|happy|harbor|hard|harsh|harvest|hat|have|hawk|hazard|head|health|heart|heavy|hedgehog|height|hello|helmet|help|hen|hero|hidden|high|hill|hint|hip|hire|history|hobby|hockey|hold|hole|holiday|hollow|home|honey|hood|hope|horn|horror|horse|hospital|host|hotel|hour|hover|hub|huge|human|humble|humor|hundred|hungry|hunt|hurdle|hurry|hurt|husband|hybrid|ice|icon|idea|identify|idle|ignore|ill|illegal|illness|image|imitate|immense|immune|impact|impose|improve|impulse|inch|include|income|increase|index|indicate|indoor|industry|infant|inflict|inform|inhale|inherit|initial|inject|injury|inmate|inner|innocent|input|inquiry|insane|insect|inside|inspire|install|intact|interest|into|invest|invite|involve|iron|island|isolate|issue|item|ivory|jacket|jaguar|jar|jazz|jealous|jeans|jelly|jewel|job|join|joke|journey|joy|judge|juice|jump|jungle|junior|junk|just|kangaroo|keen|keep|ketchup|key|kick|kid|kidney|kind|kingdom|kiss|kit|kitchen|kite|kitten|kiwi|knee|knife|knock|know|lab|label|labor|ladder|lady|lake|lamp|language|laptop|large|later|latin|laugh|laundry|lava|law|lawn|lawsuit|layer|lazy|leader|leaf|learn|leave|lecture|left|leg|legal|legend|leisure|lemon|lend|length|lens|leopard|lesson|letter|level|liar|liberty|library|license|life|lift|light|like|limb|limit|link|lion|liquid|list|little|live|lizard|load|loan|lobster|local|lock|logic|lonely|long|loop|lottery|loud|lounge|love|loyal|lucky|luggage|lumber|lunar|lunch|luxury|lyrics|machine|mad|magic|magnet|maid|mail|main|major|make|mammal|man|manage|mandate|mango|mansion|manual|maple|marble|march|margin|marine|market|marriage|mask|mass|master|match|material|math|matrix|matter|maximum|maze|meadow|mean|measure|meat|mechanic|medal|media|melody|melt|member|memory|mention|menu|mercy|merge|merit|merry|mesh|message|metal|method|middle|midnight|milk|million|mimic|mind|minimum|minor|minute|miracle|mirror|misery|miss|mistake|mix|mixed|mixture|mobile|model|modify|mom|moment|monitor|monkey|monster|month|moon|moral|more|morning|mosquito|mother|motion|motor|mountain|mouse|move|movie|much|muffin|mule|multiply|muscle|museum|mushroom|music|must|mutual|myself|mystery|myth|naive|name|napkin|narrow|nasty|nation|nature|near|neck|need|negative|neglect|neither|nephew|nerve|nest|net|network|neutral|never|news|next|nice|night|noble|noise|nominee|noodle|normal|north|nose|notable|note|nothing|notice|novel|now|nuclear|number|nurse|nut|oak|obey|object|oblige|obscure|observe|obtain|obvious|occur|ocean|october|odor|off|offer|office|often|oil|okay|old|olive|olympic|omit|once|one|onion|online|only|open|opera|opinion|oppose|option|orange|orbit|orchard|order|ordinary|organ|orient|original|orphan|ostrich|other|outdoor|outer|output|outside|oval|oven|over|own|owner|oxygen|oyster|ozone|pact|paddle|page|pair|palace|palm|panda|panel|panic|panther|paper|parade|parent|park|parrot|party|pass|patch|path|patient|patrol|pattern|pause|pave|payment|peace|peanut|pear|peasant|pelican|pen|penalty|pencil|people|pepper|perfect|permit|person|pet|phone|photo|phrase|physical|piano|picnic|picture|piece|pig|pigeon|pill|pilot|pink|pioneer|pipe|pistol|pitch|pizza|place|planet|plastic|plate|play|please|pledge|pluck|plug|plunge|poem|poet|point|polar|pole|police|pond|pony|pool|popular|portion|position|possible|post|potato|pottery|poverty|powder|power|practice|praise|predict|prefer|prepare|present|pretty|prevent|price|pride|primary|print|priority|prison|private|prize|problem|process|produce|profit|program|project|promote|proof|property|prosper|protect|proud|provide|public|pudding|pull|pulp|pulse|pumpkin|punch|pupil|puppy|purchase|purity|purpose|purse|push|put|puzzle|pyramid|quality|quantum|quarter|question|quick|quit|quiz|quote|rabbit|raccoon|race|rack|radar|radio|rail|rain|raise|rally|ramp|ranch|random|range|rapid|rare|rate|rather|raven|raw|razor|ready|real|reason|rebel|rebuild|recall|receive|recipe|record|recycle|reduce|reflect|reform|refuse|region|regret|regular|reject|relax|release|relief|rely|remain|remember|remind|remove|render|renew|rent|reopen|repair|repeat|replace|report|require|rescue|resemble|resist|resource|response|result|retire|retreat|return|reunion|reveal|review|reward|rhythm|rib|ribbon|rice|rich|ride|ridge|rifle|right|rigid|ring|riot|ripple|risk|ritual|rival|river|road|roast|robot|robust|rocket|romance|roof|rookie|room|rose|rotate|rough|round|route|royal|rubber|rude|rug|rule|run|runway|rural|sad|saddle|sadness|safe|sail|salad|salmon|salon|salt|salute|same|sample|sand|satisfy|satoshi|sauce|sausage|save|say|scale|scan|scare|scatter|scene|scheme|school|science|scissors|scorpion|scout|scrap|screen|script|scrub|sea|search|season|seat|second|secret|section|security|seed|seek|segment|select|sell|seminar|senior|sense|sentence|series|service|session|settle|setup|seven|shadow|shaft|shallow|share|shed|shell|sheriff|shield|shift|shine|ship|shiver|shock|shoe|shoot|shop|short|shoulder|shove|shrimp|shrug|shuffle|shy|sibling|sick|side|siege|sight|sign|silent|silk|silly|silver|similar|simple|since|sing|siren|sister|situate|six|size|skate|sketch|ski|skill|skin|skirt|skull|slab|slam|sleep|slender|slice|slide|slight|slim|slogan|slot|slow|slush|small|smart|smile|smoke|smooth|snack|snake|snap|sniff|snow|soap|soccer|social|sock|soda|soft|solar|soldier|solid|solution|solve|someone|song|soon|sorry|sort|soul|sound|soup|source|south|space|spare|spatial|spawn|speak|special|speed|spell|spend|sphere|spice|spider|spike|spin|spirit|split|spoil|sponsor|spoon|sport|spot|spray|spread|spring|spy|square|squeeze|squirrel|stable|stadium|staff|stage|stairs|stamp|stand|start|state|stay|steak|steel|stem|step|stereo|stick|still|sting|stock|stomach|stone|stool|story|stove|strategy|street|strike|strong|struggle|student|stuff|stumble|style|subject|submit|subway|success|such|sudden|suffer|sugar|suggest|suit|summer|sun|sunny|sunset|super|supply|supreme|sure|surface|surge|surprise|surround|survey|suspect|sustain|swallow|swamp|swap|swarm|swear|sweet|swift|swim|swing|switch|sword|symbol|symptom|syrup|system|table|tackle|tag|tail|talent|talk|tank|tape|target|task|taste|tattoo|taxi|teach|team|tell|ten|tenant|tennis|tent|term|test|text|thank|that|theme|then|theory|there|they|thing|this|thought|three|thrive|throw|thumb|thunder|ticket|tide|tiger|tilt|timber|time|tiny|tip|tired|tissue|title|toast|tobacco|today|toddler|toe|together|toilet|token|tomato|tomorrow|tone|tongue|tonight|tool|tooth|top|topic|topple|torch|tornado|tortoise|toss|total|tourist|toward|tower|town|toy|track|trade|traffic|tragic|train|transfer|trap|trash|travel|tray|treat|tree|trend|trial|tribe|trick|trigger|trim|trip|trophy|trouble|truck|true|truly|trumpet|trust|truth|try|tube|tuition|tumble|tuna|tunnel|turkey|turn|turtle|twelve|twenty|twice|twin|twist|two|type|typical|ugly|umbrella|unable|unaware|uncle|uncover|under|undo|unfair|unfold|unhappy|uniform|unique|unit|universe|unknown|unlock|until|unusual|unveil|update|upgrade|uphold|upon|upper|upset|urban|urge|usage|use|used|useful|useless|usual|utility|vacant|vacuum|vague|valid|valley|valve|van|vanish|vapor|various|vast|vault|vehicle|velvet|vendor|venture|venue|verb|verify|version|very|vessel|veteran|viable|vibrant|vicious|victory|video|view|village|vintage|violin|virtual|virus|visa|visit|visual|vital|vivid|vocal|voice|void|volcano|volume|vote|voyage|wage|wagon|wait|walk|wall|walnut|want|warfare|warm|warrior|wash|wasp|waste|water|wave|way|wealth|weapon|wear|weasel|weather|web|wedding|weekend|weird|welcome|west|wet|whale|what|wheat|wheel|when|where|whip|whisper|wide|width|wife|wild|will|win|window|wine|wing|wink|winner|winter|wire|wisdom|wise|wish|witness|wolf|woman|wonder|wood|wool|word|work|world|worry|worth|wrap|wreck|wrestle|wrist|write|wrong|yard|year|yellow|you|young|youth|zebra|zero|zone|zoo'.split('|'); diff --git a/packages/util-crypto/mnemonic/wordlists/es.d.ts b/packages/util-crypto/mnemonic/wordlists/es.d.ts new file mode 100644 index 0000000..d451d2b --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/es.d.ts @@ -0,0 +1,2 @@ +declare const _default: string[]; +export default _default; diff --git a/packages/util-crypto/mnemonic/wordlists/es.js b/packages/util-crypto/mnemonic/wordlists/es.js new file mode 100644 index 0000000..734fcf8 --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/es.js @@ -0,0 +1 @@ +export default 'ábaco|abdomen|abeja|abierto|abogado|abono|aborto|abrazo|abrir|abuelo|abuso|acabar|academia|acceso|acción|aceite|acelga|acento|aceptar|ácido|aclarar|acné|acoger|acoso|activo|acto|actriz|actuar|acudir|acuerdo|acusar|adicto|admitir|adoptar|adorno|aduana|adulto|aéreo|afectar|afición|afinar|afirmar|ágil|agitar|agonía|agosto|agotar|agregar|agrio|agua|agudo|águila|aguja|ahogo|ahorro|aire|aislar|ajedrez|ajeno|ajuste|alacrán|alambre|alarma|alba|álbum|alcalde|aldea|alegre|alejar|alerta|aleta|alfiler|alga|algodón|aliado|aliento|alivio|alma|almeja|almíbar|altar|alteza|altivo|alto|altura|alumno|alzar|amable|amante|amapola|amargo|amasar|ámbar|ámbito|ameno|amigo|amistad|amor|amparo|amplio|ancho|anciano|ancla|andar|andén|anemia|ángulo|anillo|ánimo|anís|anotar|antena|antiguo|antojo|anual|anular|anuncio|añadir|añejo|año|apagar|aparato|apetito|apio|aplicar|apodo|aporte|apoyo|aprender|aprobar|apuesta|apuro|arado|araña|arar|árbitro|árbol|arbusto|archivo|arco|arder|ardilla|arduo|área|árido|aries|armonía|arnés|aroma|arpa|arpón|arreglo|arroz|arruga|arte|artista|asa|asado|asalto|ascenso|asegurar|aseo|asesor|asiento|asilo|asistir|asno|asombro|áspero|astilla|astro|astuto|asumir|asunto|atajo|ataque|atar|atento|ateo|ático|atleta|átomo|atraer|atroz|atún|audaz|audio|auge|aula|aumento|ausente|autor|aval|avance|avaro|ave|avellana|avena|avestruz|avión|aviso|ayer|ayuda|ayuno|azafrán|azar|azote|azúcar|azufre|azul|baba|babor|bache|bahía|baile|bajar|balanza|balcón|balde|bambú|banco|banda|baño|barba|barco|barniz|barro|báscula|bastón|basura|batalla|batería|batir|batuta|baúl|bazar|bebé|bebida|bello|besar|beso|bestia|bicho|bien|bingo|blanco|bloque|blusa|boa|bobina|bobo|boca|bocina|boda|bodega|boina|bola|bolero|bolsa|bomba|bondad|bonito|bono|bonsái|borde|borrar|bosque|bote|botín|bóveda|bozal|bravo|brazo|brecha|breve|brillo|brinco|brisa|broca|broma|bronce|brote|bruja|brusco|bruto|buceo|bucle|bueno|buey|bufanda|bufón|búho|buitre|bulto|burbuja|burla|burro|buscar|butaca|buzón|caballo|cabeza|cabina|cabra|cacao|cadáver|cadena|caer|café|caída|caimán|caja|cajón|cal|calamar|calcio|caldo|calidad|calle|calma|calor|calvo|cama|cambio|camello|camino|campo|cáncer|candil|canela|canguro|canica|canto|caña|cañón|caoba|caos|capaz|capitán|capote|captar|capucha|cara|carbón|cárcel|careta|carga|cariño|carne|carpeta|carro|carta|casa|casco|casero|caspa|castor|catorce|catre|caudal|causa|cazo|cebolla|ceder|cedro|celda|célebre|celoso|célula|cemento|ceniza|centro|cerca|cerdo|cereza|cero|cerrar|certeza|césped|cetro|chacal|chaleco|champú|chancla|chapa|charla|chico|chiste|chivo|choque|choza|chuleta|chupar|ciclón|ciego|cielo|cien|cierto|cifra|cigarro|cima|cinco|cine|cinta|ciprés|circo|ciruela|cisne|cita|ciudad|clamor|clan|claro|clase|clave|cliente|clima|clínica|cobre|cocción|cochino|cocina|coco|código|codo|cofre|coger|cohete|cojín|cojo|cola|colcha|colegio|colgar|colina|collar|colmo|columna|combate|comer|comida|cómodo|compra|conde|conejo|conga|conocer|consejo|contar|copa|copia|corazón|corbata|corcho|cordón|corona|correr|coser|cosmos|costa|cráneo|cráter|crear|crecer|creído|crema|cría|crimen|cripta|crisis|cromo|crónica|croqueta|crudo|cruz|cuadro|cuarto|cuatro|cubo|cubrir|cuchara|cuello|cuento|cuerda|cuesta|cueva|cuidar|culebra|culpa|culto|cumbre|cumplir|cuna|cuneta|cuota|cupón|cúpula|curar|curioso|curso|curva|cutis|dama|danza|dar|dardo|dátil|deber|débil|década|decir|dedo|defensa|definir|dejar|delfín|delgado|delito|demora|denso|dental|deporte|derecho|derrota|desayuno|deseo|desfile|desnudo|destino|desvío|detalle|detener|deuda|día|diablo|diadema|diamante|diana|diario|dibujo|dictar|diente|dieta|diez|difícil|digno|dilema|diluir|dinero|directo|dirigir|disco|diseño|disfraz|diva|divino|doble|doce|dolor|domingo|don|donar|dorado|dormir|dorso|dos|dosis|dragón|droga|ducha|duda|duelo|dueño|dulce|dúo|duque|durar|dureza|duro|ébano|ebrio|echar|eco|ecuador|edad|edición|edificio|editor|educar|efecto|eficaz|eje|ejemplo|elefante|elegir|elemento|elevar|elipse|élite|elixir|elogio|eludir|embudo|emitir|emoción|empate|empeño|empleo|empresa|enano|encargo|enchufe|encía|enemigo|enero|enfado|enfermo|engaño|enigma|enlace|enorme|enredo|ensayo|enseñar|entero|entrar|envase|envío|época|equipo|erizo|escala|escena|escolar|escribir|escudo|esencia|esfera|esfuerzo|espada|espejo|espía|esposa|espuma|esquí|estar|este|estilo|estufa|etapa|eterno|ética|etnia|evadir|evaluar|evento|evitar|exacto|examen|exceso|excusa|exento|exigir|exilio|existir|éxito|experto|explicar|exponer|extremo|fábrica|fábula|fachada|fácil|factor|faena|faja|falda|fallo|falso|faltar|fama|familia|famoso|faraón|farmacia|farol|farsa|fase|fatiga|fauna|favor|fax|febrero|fecha|feliz|feo|feria|feroz|fértil|fervor|festín|fiable|fianza|fiar|fibra|ficción|ficha|fideo|fiebre|fiel|fiera|fiesta|figura|fijar|fijo|fila|filete|filial|filtro|fin|finca|fingir|finito|firma|flaco|flauta|flecha|flor|flota|fluir|flujo|flúor|fobia|foca|fogata|fogón|folio|folleto|fondo|forma|forro|fortuna|forzar|fosa|foto|fracaso|frágil|franja|frase|fraude|freír|freno|fresa|frío|frito|fruta|fuego|fuente|fuerza|fuga|fumar|función|funda|furgón|furia|fusil|fútbol|futuro|gacela|gafas|gaita|gajo|gala|galería|gallo|gamba|ganar|gancho|ganga|ganso|garaje|garza|gasolina|gastar|gato|gavilán|gemelo|gemir|gen|género|genio|gente|geranio|gerente|germen|gesto|gigante|gimnasio|girar|giro|glaciar|globo|gloria|gol|golfo|goloso|golpe|goma|gordo|gorila|gorra|gota|goteo|gozar|grada|gráfico|grano|grasa|gratis|grave|grieta|grillo|gripe|gris|grito|grosor|grúa|grueso|grumo|grupo|guante|guapo|guardia|guerra|guía|guiño|guion|guiso|guitarra|gusano|gustar|haber|hábil|hablar|hacer|hacha|hada|hallar|hamaca|harina|haz|hazaña|hebilla|hebra|hecho|helado|helio|hembra|herir|hermano|héroe|hervir|hielo|hierro|hígado|higiene|hijo|himno|historia|hocico|hogar|hoguera|hoja|hombre|hongo|honor|honra|hora|hormiga|horno|hostil|hoyo|hueco|huelga|huerta|hueso|huevo|huida|huir|humano|húmedo|humilde|humo|hundir|huracán|hurto|icono|ideal|idioma|ídolo|iglesia|iglú|igual|ilegal|ilusión|imagen|imán|imitar|impar|imperio|imponer|impulso|incapaz|índice|inerte|infiel|informe|ingenio|inicio|inmenso|inmune|innato|insecto|instante|interés|íntimo|intuir|inútil|invierno|ira|iris|ironía|isla|islote|jabalí|jabón|jamón|jarabe|jardín|jarra|jaula|jazmín|jefe|jeringa|jinete|jornada|joroba|joven|joya|juerga|jueves|juez|jugador|jugo|juguete|juicio|junco|jungla|junio|juntar|júpiter|jurar|justo|juvenil|juzgar|kilo|koala|labio|lacio|lacra|lado|ladrón|lagarto|lágrima|laguna|laico|lamer|lámina|lámpara|lana|lancha|langosta|lanza|lápiz|largo|larva|lástima|lata|látex|latir|laurel|lavar|lazo|leal|lección|leche|lector|leer|legión|legumbre|lejano|lengua|lento|leña|león|leopardo|lesión|letal|letra|leve|leyenda|libertad|libro|licor|líder|lidiar|lienzo|liga|ligero|lima|límite|limón|limpio|lince|lindo|línea|lingote|lino|linterna|líquido|liso|lista|litera|litio|litro|llaga|llama|llanto|llave|llegar|llenar|llevar|llorar|llover|lluvia|lobo|loción|loco|locura|lógica|logro|lombriz|lomo|lonja|lote|lucha|lucir|lugar|lujo|luna|lunes|lupa|lustro|luto|luz|maceta|macho|madera|madre|maduro|maestro|mafia|magia|mago|maíz|maldad|maleta|malla|malo|mamá|mambo|mamut|manco|mando|manejar|manga|maniquí|manjar|mano|manso|manta|mañana|mapa|máquina|mar|marco|marea|marfil|margen|marido|mármol|marrón|martes|marzo|masa|máscara|masivo|matar|materia|matiz|matriz|máximo|mayor|mazorca|mecha|medalla|medio|médula|mejilla|mejor|melena|melón|memoria|menor|mensaje|mente|menú|mercado|merengue|mérito|mes|mesón|meta|meter|método|metro|mezcla|miedo|miel|miembro|miga|mil|milagro|militar|millón|mimo|mina|minero|mínimo|minuto|miope|mirar|misa|miseria|misil|mismo|mitad|mito|mochila|moción|moda|modelo|moho|mojar|molde|moler|molino|momento|momia|monarca|moneda|monja|monto|moño|morada|morder|moreno|morir|morro|morsa|mortal|mosca|mostrar|motivo|mover|móvil|mozo|mucho|mudar|mueble|muela|muerte|muestra|mugre|mujer|mula|muleta|multa|mundo|muñeca|mural|muro|músculo|museo|musgo|música|muslo|nácar|nación|nadar|naipe|naranja|nariz|narrar|nasal|natal|nativo|natural|náusea|naval|nave|navidad|necio|néctar|negar|negocio|negro|neón|nervio|neto|neutro|nevar|nevera|nicho|nido|niebla|nieto|niñez|niño|nítido|nivel|nobleza|noche|nómina|noria|norma|norte|nota|noticia|novato|novela|novio|nube|nuca|núcleo|nudillo|nudo|nuera|nueve|nuez|nulo|número|nutria|oasis|obeso|obispo|objeto|obra|obrero|observar|obtener|obvio|oca|ocaso|océano|ochenta|ocho|ocio|ocre|octavo|octubre|oculto|ocupar|ocurrir|odiar|odio|odisea|oeste|ofensa|oferta|oficio|ofrecer|ogro|oído|oír|ojo|ola|oleada|olfato|olivo|olla|olmo|olor|olvido|ombligo|onda|onza|opaco|opción|ópera|opinar|oponer|optar|óptica|opuesto|oración|orador|oral|órbita|orca|orden|oreja|órgano|orgía|orgullo|oriente|origen|orilla|oro|orquesta|oruga|osadía|oscuro|osezno|oso|ostra|otoño|otro|oveja|óvulo|óxido|oxígeno|oyente|ozono|pacto|padre|paella|página|pago|país|pájaro|palabra|palco|paleta|pálido|palma|paloma|palpar|pan|panal|pánico|pantera|pañuelo|papá|papel|papilla|paquete|parar|parcela|pared|parir|paro|párpado|parque|párrafo|parte|pasar|paseo|pasión|paso|pasta|pata|patio|patria|pausa|pauta|pavo|payaso|peatón|pecado|pecera|pecho|pedal|pedir|pegar|peine|pelar|peldaño|pelea|peligro|pellejo|pelo|peluca|pena|pensar|peñón|peón|peor|pepino|pequeño|pera|percha|perder|pereza|perfil|perico|perla|permiso|perro|persona|pesa|pesca|pésimo|pestaña|pétalo|petróleo|pez|pezuña|picar|pichón|pie|piedra|pierna|pieza|pijama|pilar|piloto|pimienta|pino|pintor|pinza|piña|piojo|pipa|pirata|pisar|piscina|piso|pista|pitón|pizca|placa|plan|plata|playa|plaza|pleito|pleno|plomo|pluma|plural|pobre|poco|poder|podio|poema|poesía|poeta|polen|policía|pollo|polvo|pomada|pomelo|pomo|pompa|poner|porción|portal|posada|poseer|posible|poste|potencia|potro|pozo|prado|precoz|pregunta|premio|prensa|preso|previo|primo|príncipe|prisión|privar|proa|probar|proceso|producto|proeza|profesor|programa|prole|promesa|pronto|propio|próximo|prueba|público|puchero|pudor|pueblo|puerta|puesto|pulga|pulir|pulmón|pulpo|pulso|puma|punto|puñal|puño|pupa|pupila|puré|quedar|queja|quemar|querer|queso|quieto|química|quince|quitar|rábano|rabia|rabo|ración|radical|raíz|rama|rampa|rancho|rango|rapaz|rápido|rapto|rasgo|raspa|rato|rayo|raza|razón|reacción|realidad|rebaño|rebote|recaer|receta|rechazo|recoger|recreo|recto|recurso|red|redondo|reducir|reflejo|reforma|refrán|refugio|regalo|regir|regla|regreso|rehén|reino|reír|reja|relato|relevo|relieve|relleno|reloj|remar|remedio|remo|rencor|rendir|renta|reparto|repetir|reposo|reptil|res|rescate|resina|respeto|resto|resumen|retiro|retorno|retrato|reunir|revés|revista|rey|rezar|rico|riego|rienda|riesgo|rifa|rígido|rigor|rincón|riñón|río|riqueza|risa|ritmo|rito|rizo|roble|roce|rociar|rodar|rodeo|rodilla|roer|rojizo|rojo|romero|romper|ron|ronco|ronda|ropa|ropero|rosa|rosca|rostro|rotar|rubí|rubor|rudo|rueda|rugir|ruido|ruina|ruleta|rulo|rumbo|rumor|ruptura|ruta|rutina|sábado|saber|sabio|sable|sacar|sagaz|sagrado|sala|saldo|salero|salir|salmón|salón|salsa|salto|salud|salvar|samba|sanción|sandía|sanear|sangre|sanidad|sano|santo|sapo|saque|sardina|sartén|sastre|satán|sauna|saxofón|sección|seco|secreto|secta|sed|seguir|seis|sello|selva|semana|semilla|senda|sensor|señal|señor|separar|sepia|sequía|ser|serie|sermón|servir|sesenta|sesión|seta|setenta|severo|sexo|sexto|sidra|siesta|siete|siglo|signo|sílaba|silbar|silencio|silla|símbolo|simio|sirena|sistema|sitio|situar|sobre|socio|sodio|sol|solapa|soldado|soledad|sólido|soltar|solución|sombra|sondeo|sonido|sonoro|sonrisa|sopa|soplar|soporte|sordo|sorpresa|sorteo|sostén|sótano|suave|subir|suceso|sudor|suegra|suelo|sueño|suerte|sufrir|sujeto|sultán|sumar|superar|suplir|suponer|supremo|sur|surco|sureño|surgir|susto|sutil|tabaco|tabique|tabla|tabú|taco|tacto|tajo|talar|talco|talento|talla|talón|tamaño|tambor|tango|tanque|tapa|tapete|tapia|tapón|taquilla|tarde|tarea|tarifa|tarjeta|tarot|tarro|tarta|tatuaje|tauro|taza|tazón|teatro|techo|tecla|técnica|tejado|tejer|tejido|tela|teléfono|tema|temor|templo|tenaz|tender|tener|tenis|tenso|teoría|terapia|terco|término|ternura|terror|tesis|tesoro|testigo|tetera|texto|tez|tibio|tiburón|tiempo|tienda|tierra|tieso|tigre|tijera|tilde|timbre|tímido|timo|tinta|tío|típico|tipo|tira|tirón|titán|títere|título|tiza|toalla|tobillo|tocar|tocino|todo|toga|toldo|tomar|tono|tonto|topar|tope|toque|tórax|torero|tormenta|torneo|toro|torpedo|torre|torso|tortuga|tos|tosco|toser|tóxico|trabajo|tractor|traer|tráfico|trago|traje|tramo|trance|trato|trauma|trazar|trébol|tregua|treinta|tren|trepar|tres|tribu|trigo|tripa|triste|triunfo|trofeo|trompa|tronco|tropa|trote|trozo|truco|trueno|trufa|tubería|tubo|tuerto|tumba|tumor|túnel|túnica|turbina|turismo|turno|tutor|ubicar|úlcera|umbral|unidad|unir|universo|uno|untar|uña|urbano|urbe|urgente|urna|usar|usuario|útil|utopía|uva|vaca|vacío|vacuna|vagar|vago|vaina|vajilla|vale|válido|valle|valor|válvula|vampiro|vara|variar|varón|vaso|vecino|vector|vehículo|veinte|vejez|vela|velero|veloz|vena|vencer|venda|veneno|vengar|venir|venta|venus|ver|verano|verbo|verde|vereda|verja|verso|verter|vía|viaje|vibrar|vicio|víctima|vida|vídeo|vidrio|viejo|viernes|vigor|vil|villa|vinagre|vino|viñedo|violín|viral|virgo|virtud|visor|víspera|vista|vitamina|viudo|vivaz|vivero|vivir|vivo|volcán|volumen|volver|voraz|votar|voto|voz|vuelo|vulgar|yacer|yate|yegua|yema|yerno|yeso|yodo|yoga|yogur|zafiro|zanja|zapato|zarza|zona|zorro|zumo|zurdo'.split('|'); diff --git a/packages/util-crypto/mnemonic/wordlists/fr.d.ts b/packages/util-crypto/mnemonic/wordlists/fr.d.ts new file mode 100644 index 0000000..d451d2b --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/fr.d.ts @@ -0,0 +1,2 @@ +declare const _default: string[]; +export default _default; diff --git a/packages/util-crypto/mnemonic/wordlists/fr.js b/packages/util-crypto/mnemonic/wordlists/fr.js new file mode 100644 index 0000000..0dc4fbc --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/fr.js @@ -0,0 +1 @@ +export default 'abaisser|abandon|abdiquer|abeille|abolir|aborder|aboutir|aboyer|abrasif|abreuver|abriter|abroger|abrupt|absence|absolu|absurde|abusif|abyssal|académie|acajou|acarien|accabler|accepter|acclamer|accolade|accroche|accuser|acerbe|achat|acheter|aciduler|acier|acompte|acquérir|acronyme|acteur|actif|actuel|adepte|adéquat|adhésif|adjectif|adjuger|admettre|admirer|adopter|adorer|adoucir|adresse|adroit|adulte|adverbe|aérer|aéronef|affaire|affecter|affiche|affreux|affubler|agacer|agencer|agile|agiter|agrafer|agréable|agrume|aider|aiguille|ailier|aimable|aisance|ajouter|ajuster|alarmer|alchimie|alerte|algèbre|algue|aliéner|aliment|alléger|alliage|allouer|allumer|alourdir|alpaga|altesse|alvéole|amateur|ambigu|ambre|aménager|amertume|amidon|amiral|amorcer|amour|amovible|amphibie|ampleur|amusant|analyse|anaphore|anarchie|anatomie|ancien|anéantir|angle|angoisse|anguleux|animal|annexer|annonce|annuel|anodin|anomalie|anonyme|anormal|antenne|antidote|anxieux|apaiser|apéritif|aplanir|apologie|appareil|appeler|apporter|appuyer|aquarium|aqueduc|arbitre|arbuste|ardeur|ardoise|argent|arlequin|armature|armement|armoire|armure|arpenter|arracher|arriver|arroser|arsenic|artériel|article|aspect|asphalte|aspirer|assaut|asservir|assiette|associer|assurer|asticot|astre|astuce|atelier|atome|atrium|atroce|attaque|attentif|attirer|attraper|aubaine|auberge|audace|audible|augurer|aurore|automne|autruche|avaler|avancer|avarice|avenir|averse|aveugle|aviateur|avide|avion|aviser|avoine|avouer|avril|axial|axiome|badge|bafouer|bagage|baguette|baignade|balancer|balcon|baleine|balisage|bambin|bancaire|bandage|banlieue|bannière|banquier|barbier|baril|baron|barque|barrage|bassin|bastion|bataille|bateau|batterie|baudrier|bavarder|belette|bélier|belote|bénéfice|berceau|berger|berline|bermuda|besace|besogne|bétail|beurre|biberon|bicycle|bidule|bijou|bilan|bilingue|billard|binaire|biologie|biopsie|biotype|biscuit|bison|bistouri|bitume|bizarre|blafard|blague|blanchir|blessant|blinder|blond|bloquer|blouson|bobard|bobine|boire|boiser|bolide|bonbon|bondir|bonheur|bonifier|bonus|bordure|borne|botte|boucle|boueux|bougie|boulon|bouquin|bourse|boussole|boutique|boxeur|branche|brasier|brave|brebis|brèche|breuvage|bricoler|brigade|brillant|brioche|brique|brochure|broder|bronzer|brousse|broyeur|brume|brusque|brutal|bruyant|buffle|buisson|bulletin|bureau|burin|bustier|butiner|butoir|buvable|buvette|cabanon|cabine|cachette|cadeau|cadre|caféine|caillou|caisson|calculer|calepin|calibre|calmer|calomnie|calvaire|camarade|caméra|camion|campagne|canal|caneton|canon|cantine|canular|capable|caporal|caprice|capsule|capter|capuche|carabine|carbone|caresser|caribou|carnage|carotte|carreau|carton|cascade|casier|casque|cassure|causer|caution|cavalier|caverne|caviar|cédille|ceinture|céleste|cellule|cendrier|censurer|central|cercle|cérébral|cerise|cerner|cerveau|cesser|chagrin|chaise|chaleur|chambre|chance|chapitre|charbon|chasseur|chaton|chausson|chavirer|chemise|chenille|chéquier|chercher|cheval|chien|chiffre|chignon|chimère|chiot|chlorure|chocolat|choisir|chose|chouette|chrome|chute|cigare|cigogne|cimenter|cinéma|cintrer|circuler|cirer|cirque|citerne|citoyen|citron|civil|clairon|clameur|claquer|classe|clavier|client|cligner|climat|clivage|cloche|clonage|cloporte|cobalt|cobra|cocasse|cocotier|coder|codifier|coffre|cogner|cohésion|coiffer|coincer|colère|colibri|colline|colmater|colonel|combat|comédie|commande|compact|concert|conduire|confier|congeler|connoter|consonne|contact|convexe|copain|copie|corail|corbeau|cordage|corniche|corpus|correct|cortège|cosmique|costume|coton|coude|coupure|courage|couteau|couvrir|coyote|crabe|crainte|cravate|crayon|créature|créditer|crémeux|creuser|crevette|cribler|crier|cristal|critère|croire|croquer|crotale|crucial|cruel|crypter|cubique|cueillir|cuillère|cuisine|cuivre|culminer|cultiver|cumuler|cupide|curatif|curseur|cyanure|cycle|cylindre|cynique|daigner|damier|danger|danseur|dauphin|débattre|débiter|déborder|débrider|débutant|décaler|décembre|déchirer|décider|déclarer|décorer|décrire|décupler|dédale|déductif|déesse|défensif|défiler|défrayer|dégager|dégivrer|déglutir|dégrafer|déjeuner|délice|déloger|demander|demeurer|démolir|dénicher|dénouer|dentelle|dénuder|départ|dépenser|déphaser|déplacer|déposer|déranger|dérober|désastre|descente|désert|désigner|désobéir|dessiner|destrier|détacher|détester|détourer|détresse|devancer|devenir|deviner|devoir|diable|dialogue|diamant|dicter|différer|digérer|digital|digne|diluer|dimanche|diminuer|dioxyde|directif|diriger|discuter|disposer|dissiper|distance|divertir|diviser|docile|docteur|dogme|doigt|domaine|domicile|dompter|donateur|donjon|donner|dopamine|dortoir|dorure|dosage|doseur|dossier|dotation|douanier|double|douceur|douter|doyen|dragon|draper|dresser|dribbler|droiture|duperie|duplexe|durable|durcir|dynastie|éblouir|écarter|écharpe|échelle|éclairer|éclipse|éclore|écluse|école|économie|écorce|écouter|écraser|écrémer|écrivain|écrou|écume|écureuil|édifier|éduquer|effacer|effectif|effigie|effort|effrayer|effusion|égaliser|égarer|éjecter|élaborer|élargir|électron|élégant|éléphant|élève|éligible|élitisme|éloge|élucider|éluder|emballer|embellir|embryon|émeraude|émission|emmener|émotion|émouvoir|empereur|employer|emporter|emprise|émulsion|encadrer|enchère|enclave|encoche|endiguer|endosser|endroit|enduire|énergie|enfance|enfermer|enfouir|engager|engin|englober|énigme|enjamber|enjeu|enlever|ennemi|ennuyeux|enrichir|enrobage|enseigne|entasser|entendre|entier|entourer|entraver|énumérer|envahir|enviable|envoyer|enzyme|éolien|épaissir|épargne|épatant|épaule|épicerie|épidémie|épier|épilogue|épine|épisode|épitaphe|époque|épreuve|éprouver|épuisant|équerre|équipe|ériger|érosion|erreur|éruption|escalier|espadon|espèce|espiègle|espoir|esprit|esquiver|essayer|essence|essieu|essorer|estime|estomac|estrade|étagère|étaler|étanche|étatique|éteindre|étendoir|éternel|éthanol|éthique|ethnie|étirer|étoffer|étoile|étonnant|étourdir|étrange|étroit|étude|euphorie|évaluer|évasion|éventail|évidence|éviter|évolutif|évoquer|exact|exagérer|exaucer|exceller|excitant|exclusif|excuse|exécuter|exemple|exercer|exhaler|exhorter|exigence|exiler|exister|exotique|expédier|explorer|exposer|exprimer|exquis|extensif|extraire|exulter|fable|fabuleux|facette|facile|facture|faiblir|falaise|fameux|famille|farceur|farfelu|farine|farouche|fasciner|fatal|fatigue|faucon|fautif|faveur|favori|fébrile|féconder|fédérer|félin|femme|fémur|fendoir|féodal|fermer|féroce|ferveur|festival|feuille|feutre|février|fiasco|ficeler|fictif|fidèle|figure|filature|filetage|filière|filleul|filmer|filou|filtrer|financer|finir|fiole|firme|fissure|fixer|flairer|flamme|flasque|flatteur|fléau|flèche|fleur|flexion|flocon|flore|fluctuer|fluide|fluvial|folie|fonderie|fongible|fontaine|forcer|forgeron|formuler|fortune|fossile|foudre|fougère|fouiller|foulure|fourmi|fragile|fraise|franchir|frapper|frayeur|frégate|freiner|frelon|frémir|frénésie|frère|friable|friction|frisson|frivole|froid|fromage|frontal|frotter|fruit|fugitif|fuite|fureur|furieux|furtif|fusion|futur|gagner|galaxie|galerie|gambader|garantir|gardien|garnir|garrigue|gazelle|gazon|géant|gélatine|gélule|gendarme|général|génie|genou|gentil|géologie|géomètre|géranium|germe|gestuel|geyser|gibier|gicler|girafe|givre|glace|glaive|glisser|globe|gloire|glorieux|golfeur|gomme|gonfler|gorge|gorille|goudron|gouffre|goulot|goupille|gourmand|goutte|graduel|graffiti|graine|grand|grappin|gratuit|gravir|grenat|griffure|griller|grimper|grogner|gronder|grotte|groupe|gruger|grutier|gruyère|guépard|guerrier|guide|guimauve|guitare|gustatif|gymnaste|gyrostat|habitude|hachoir|halte|hameau|hangar|hanneton|haricot|harmonie|harpon|hasard|hélium|hématome|herbe|hérisson|hermine|héron|hésiter|heureux|hiberner|hibou|hilarant|histoire|hiver|homard|hommage|homogène|honneur|honorer|honteux|horde|horizon|horloge|hormone|horrible|houleux|housse|hublot|huileux|humain|humble|humide|humour|hurler|hydromel|hygiène|hymne|hypnose|idylle|ignorer|iguane|illicite|illusion|image|imbiber|imiter|immense|immobile|immuable|impact|impérial|implorer|imposer|imprimer|imputer|incarner|incendie|incident|incliner|incolore|indexer|indice|inductif|inédit|ineptie|inexact|infini|infliger|informer|infusion|ingérer|inhaler|inhiber|injecter|injure|innocent|inoculer|inonder|inscrire|insecte|insigne|insolite|inspirer|instinct|insulter|intact|intense|intime|intrigue|intuitif|inutile|invasion|inventer|inviter|invoquer|ironique|irradier|irréel|irriter|isoler|ivoire|ivresse|jaguar|jaillir|jambe|janvier|jardin|jauger|jaune|javelot|jetable|jeton|jeudi|jeunesse|joindre|joncher|jongler|joueur|jouissif|journal|jovial|joyau|joyeux|jubiler|jugement|junior|jupon|juriste|justice|juteux|juvénile|kayak|kimono|kiosque|label|labial|labourer|lacérer|lactose|lagune|laine|laisser|laitier|lambeau|lamelle|lampe|lanceur|langage|lanterne|lapin|largeur|larme|laurier|lavabo|lavoir|lecture|légal|léger|légume|lessive|lettre|levier|lexique|lézard|liasse|libérer|libre|licence|licorne|liège|lièvre|ligature|ligoter|ligue|limer|limite|limonade|limpide|linéaire|lingot|lionceau|liquide|lisière|lister|lithium|litige|littoral|livreur|logique|lointain|loisir|lombric|loterie|louer|lourd|loutre|louve|loyal|lubie|lucide|lucratif|lueur|lugubre|luisant|lumière|lunaire|lundi|luron|lutter|luxueux|machine|magasin|magenta|magique|maigre|maillon|maintien|mairie|maison|majorer|malaxer|maléfice|malheur|malice|mallette|mammouth|mandater|maniable|manquant|manteau|manuel|marathon|marbre|marchand|mardi|maritime|marqueur|marron|marteler|mascotte|massif|matériel|matière|matraque|maudire|maussade|mauve|maximal|méchant|méconnu|médaille|médecin|méditer|méduse|meilleur|mélange|mélodie|membre|mémoire|menacer|mener|menhir|mensonge|mentor|mercredi|mérite|merle|messager|mesure|métal|météore|méthode|métier|meuble|miauler|microbe|miette|mignon|migrer|milieu|million|mimique|mince|minéral|minimal|minorer|minute|miracle|miroiter|missile|mixte|mobile|moderne|moelleux|mondial|moniteur|monnaie|monotone|monstre|montagne|monument|moqueur|morceau|morsure|mortier|moteur|motif|mouche|moufle|moulin|mousson|mouton|mouvant|multiple|munition|muraille|murène|murmure|muscle|muséum|musicien|mutation|muter|mutuel|myriade|myrtille|mystère|mythique|nageur|nappe|narquois|narrer|natation|nation|nature|naufrage|nautique|navire|nébuleux|nectar|néfaste|négation|négliger|négocier|neige|nerveux|nettoyer|neurone|neutron|neveu|niche|nickel|nitrate|niveau|noble|nocif|nocturne|noirceur|noisette|nomade|nombreux|nommer|normatif|notable|notifier|notoire|nourrir|nouveau|novateur|novembre|novice|nuage|nuancer|nuire|nuisible|numéro|nuptial|nuque|nutritif|obéir|objectif|obliger|obscur|observer|obstacle|obtenir|obturer|occasion|occuper|océan|octobre|octroyer|octupler|oculaire|odeur|odorant|offenser|officier|offrir|ogive|oiseau|oisillon|olfactif|olivier|ombrage|omettre|onctueux|onduler|onéreux|onirique|opale|opaque|opérer|opinion|opportun|opprimer|opter|optique|orageux|orange|orbite|ordonner|oreille|organe|orgueil|orifice|ornement|orque|ortie|osciller|osmose|ossature|otarie|ouragan|ourson|outil|outrager|ouvrage|ovation|oxyde|oxygène|ozone|paisible|palace|palmarès|palourde|palper|panache|panda|pangolin|paniquer|panneau|panorama|pantalon|papaye|papier|papoter|papyrus|paradoxe|parcelle|paresse|parfumer|parler|parole|parrain|parsemer|partager|parure|parvenir|passion|pastèque|paternel|patience|patron|pavillon|pavoiser|payer|paysage|peigne|peintre|pelage|pélican|pelle|pelouse|peluche|pendule|pénétrer|pénible|pensif|pénurie|pépite|péplum|perdrix|perforer|période|permuter|perplexe|persil|perte|peser|pétale|petit|pétrir|peuple|pharaon|phobie|phoque|photon|phrase|physique|piano|pictural|pièce|pierre|pieuvre|pilote|pinceau|pipette|piquer|pirogue|piscine|piston|pivoter|pixel|pizza|placard|plafond|plaisir|planer|plaque|plastron|plateau|pleurer|plexus|pliage|plomb|plonger|pluie|plumage|pochette|poésie|poète|pointe|poirier|poisson|poivre|polaire|policier|pollen|polygone|pommade|pompier|ponctuel|pondérer|poney|portique|position|posséder|posture|potager|poteau|potion|pouce|poulain|poumon|pourpre|poussin|pouvoir|prairie|pratique|précieux|prédire|préfixe|prélude|prénom|présence|prétexte|prévoir|primitif|prince|prison|priver|problème|procéder|prodige|profond|progrès|proie|projeter|prologue|promener|propre|prospère|protéger|prouesse|proverbe|prudence|pruneau|psychose|public|puceron|puiser|pulpe|pulsar|punaise|punitif|pupitre|purifier|puzzle|pyramide|quasar|querelle|question|quiétude|quitter|quotient|racine|raconter|radieux|ragondin|raideur|raisin|ralentir|rallonge|ramasser|rapide|rasage|ratisser|ravager|ravin|rayonner|réactif|réagir|réaliser|réanimer|recevoir|réciter|réclamer|récolter|recruter|reculer|recycler|rédiger|redouter|refaire|réflexe|réformer|refrain|refuge|régalien|région|réglage|régulier|réitérer|rejeter|rejouer|relatif|relever|relief|remarque|remède|remise|remonter|remplir|remuer|renard|renfort|renifler|renoncer|rentrer|renvoi|replier|reporter|reprise|reptile|requin|réserve|résineux|résoudre|respect|rester|résultat|rétablir|retenir|réticule|retomber|retracer|réunion|réussir|revanche|revivre|révolte|révulsif|richesse|rideau|rieur|rigide|rigoler|rincer|riposter|risible|risque|rituel|rival|rivière|rocheux|romance|rompre|ronce|rondin|roseau|rosier|rotatif|rotor|rotule|rouge|rouille|rouleau|routine|royaume|ruban|rubis|ruche|ruelle|rugueux|ruiner|ruisseau|ruser|rustique|rythme|sabler|saboter|sabre|sacoche|safari|sagesse|saisir|salade|salive|salon|saluer|samedi|sanction|sanglier|sarcasme|sardine|saturer|saugrenu|saumon|sauter|sauvage|savant|savonner|scalpel|scandale|scélérat|scénario|sceptre|schéma|science|scinder|score|scrutin|sculpter|séance|sécable|sécher|secouer|sécréter|sédatif|séduire|seigneur|séjour|sélectif|semaine|sembler|semence|séminal|sénateur|sensible|sentence|séparer|séquence|serein|sergent|sérieux|serrure|sérum|service|sésame|sévir|sevrage|sextuple|sidéral|siècle|siéger|siffler|sigle|signal|silence|silicium|simple|sincère|sinistre|siphon|sirop|sismique|situer|skier|social|socle|sodium|soigneux|soldat|soleil|solitude|soluble|sombre|sommeil|somnoler|sonde|songeur|sonnette|sonore|sorcier|sortir|sosie|sottise|soucieux|soudure|souffle|soulever|soupape|source|soutirer|souvenir|spacieux|spatial|spécial|sphère|spiral|stable|station|sternum|stimulus|stipuler|strict|studieux|stupeur|styliste|sublime|substrat|subtil|subvenir|succès|sucre|suffixe|suggérer|suiveur|sulfate|superbe|supplier|surface|suricate|surmener|surprise|sursaut|survie|suspect|syllabe|symbole|symétrie|synapse|syntaxe|système|tabac|tablier|tactile|tailler|talent|talisman|talonner|tambour|tamiser|tangible|tapis|taquiner|tarder|tarif|tartine|tasse|tatami|tatouage|taupe|taureau|taxer|témoin|temporel|tenaille|tendre|teneur|tenir|tension|terminer|terne|terrible|tétine|texte|thème|théorie|thérapie|thorax|tibia|tiède|timide|tirelire|tiroir|tissu|titane|titre|tituber|toboggan|tolérant|tomate|tonique|tonneau|toponyme|torche|tordre|tornade|torpille|torrent|torse|tortue|totem|toucher|tournage|tousser|toxine|traction|trafic|tragique|trahir|train|trancher|travail|trèfle|tremper|trésor|treuil|triage|tribunal|tricoter|trilogie|triomphe|tripler|triturer|trivial|trombone|tronc|tropical|troupeau|tuile|tulipe|tumulte|tunnel|turbine|tuteur|tutoyer|tuyau|tympan|typhon|typique|tyran|ubuesque|ultime|ultrason|unanime|unifier|union|unique|unitaire|univers|uranium|urbain|urticant|usage|usine|usuel|usure|utile|utopie|vacarme|vaccin|vagabond|vague|vaillant|vaincre|vaisseau|valable|valise|vallon|valve|vampire|vanille|vapeur|varier|vaseux|vassal|vaste|vecteur|vedette|végétal|véhicule|veinard|véloce|vendredi|vénérer|venger|venimeux|ventouse|verdure|vérin|vernir|verrou|verser|vertu|veston|vétéran|vétuste|vexant|vexer|viaduc|viande|victoire|vidange|vidéo|vignette|vigueur|vilain|village|vinaigre|violon|vipère|virement|virtuose|virus|visage|viseur|vision|visqueux|visuel|vital|vitesse|viticole|vitrine|vivace|vivipare|vocation|voguer|voile|voisin|voiture|volaille|volcan|voltiger|volume|vorace|vortex|voter|vouloir|voyage|voyelle|wagon|xénon|yacht|zèbre|zénith|zeste|zoologie'.split('|'); diff --git a/packages/util-crypto/mnemonic/wordlists/index.d.ts b/packages/util-crypto/mnemonic/wordlists/index.d.ts new file mode 100644 index 0000000..9c1ccf0 --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/index.d.ts @@ -0,0 +1,8 @@ +export { default as english } from './en.js'; +export { default as spanish } from './es.js'; +export { default as french } from './fr.js'; +export { default as italian } from './it.js'; +export { default as japanese } from './jp.js'; +export { default as korean } from './ko.js'; +export { default as chineseSimplified } from './zh-s.js'; +export { default as chineseTraditional } from './zh-t.js'; diff --git a/packages/util-crypto/mnemonic/wordlists/index.js b/packages/util-crypto/mnemonic/wordlists/index.js new file mode 100644 index 0000000..9c1ccf0 --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/index.js @@ -0,0 +1,8 @@ +export { default as english } from './en.js'; +export { default as spanish } from './es.js'; +export { default as french } from './fr.js'; +export { default as italian } from './it.js'; +export { default as japanese } from './jp.js'; +export { default as korean } from './ko.js'; +export { default as chineseSimplified } from './zh-s.js'; +export { default as chineseTraditional } from './zh-t.js'; diff --git a/packages/util-crypto/mnemonic/wordlists/it.d.ts b/packages/util-crypto/mnemonic/wordlists/it.d.ts new file mode 100644 index 0000000..d451d2b --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/it.d.ts @@ -0,0 +1,2 @@ +declare const _default: string[]; +export default _default; diff --git a/packages/util-crypto/mnemonic/wordlists/it.js b/packages/util-crypto/mnemonic/wordlists/it.js new file mode 100644 index 0000000..d5ec3b9 --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/it.js @@ -0,0 +1 @@ +export default 'abaco|abbaglio|abbinato|abete|abisso|abolire|abrasivo|abrogato|accadere|accenno|accusato|acetone|achille|acido|acqua|acre|acrilico|acrobata|acuto|adagio|addebito|addome|adeguato|aderire|adipe|adottare|adulare|affabile|affetto|affisso|affranto|aforisma|afoso|africano|agave|agente|agevole|aggancio|agire|agitare|agonismo|agricolo|agrumeto|aguzzo|alabarda|alato|albatro|alberato|albo|albume|alce|alcolico|alettone|alfa|algebra|aliante|alibi|alimento|allagato|allegro|allievo|allodola|allusivo|almeno|alogeno|alpaca|alpestre|altalena|alterno|alticcio|altrove|alunno|alveolo|alzare|amalgama|amanita|amarena|ambito|ambrato|ameba|america|ametista|amico|ammasso|ammenda|ammirare|ammonito|amore|ampio|ampliare|amuleto|anacardo|anagrafe|analista|anarchia|anatra|anca|ancella|ancora|andare|andrea|anello|angelo|angolare|angusto|anima|annegare|annidato|anno|annuncio|anonimo|anticipo|anzi|apatico|apertura|apode|apparire|appetito|appoggio|approdo|appunto|aprile|arabica|arachide|aragosta|araldica|arancio|aratura|arazzo|arbitro|archivio|ardito|arenile|argento|argine|arguto|aria|armonia|arnese|arredato|arringa|arrosto|arsenico|arso|artefice|arzillo|asciutto|ascolto|asepsi|asettico|asfalto|asino|asola|aspirato|aspro|assaggio|asse|assoluto|assurdo|asta|astenuto|astice|astratto|atavico|ateismo|atomico|atono|attesa|attivare|attorno|attrito|attuale|ausilio|austria|autista|autonomo|autunno|avanzato|avere|avvenire|avviso|avvolgere|azione|azoto|azzimo|azzurro|babele|baccano|bacino|baco|badessa|badilata|bagnato|baita|balcone|baldo|balena|ballata|balzano|bambino|bandire|baraonda|barbaro|barca|baritono|barlume|barocco|basilico|basso|batosta|battuto|baule|bava|bavosa|becco|beffa|belgio|belva|benda|benevole|benigno|benzina|bere|berlina|beta|bibita|bici|bidone|bifido|biga|bilancia|bimbo|binocolo|biologo|bipede|bipolare|birbante|birra|biscotto|bisesto|bisnonno|bisonte|bisturi|bizzarro|blando|blatta|bollito|bonifico|bordo|bosco|botanico|bottino|bozzolo|braccio|bradipo|brama|branca|bravura|bretella|brevetto|brezza|briglia|brillante|brindare|broccolo|brodo|bronzina|brullo|bruno|bubbone|buca|budino|buffone|buio|bulbo|buono|burlone|burrasca|bussola|busta|cadetto|caduco|calamaro|calcolo|calesse|calibro|calmo|caloria|cambusa|camerata|camicia|cammino|camola|campale|canapa|candela|cane|canino|canotto|cantina|capace|capello|capitolo|capogiro|cappero|capra|capsula|carapace|carcassa|cardo|carisma|carovana|carretto|cartolina|casaccio|cascata|caserma|caso|cassone|castello|casuale|catasta|catena|catrame|cauto|cavillo|cedibile|cedrata|cefalo|celebre|cellulare|cena|cenone|centesimo|ceramica|cercare|certo|cerume|cervello|cesoia|cespo|ceto|chela|chiaro|chicca|chiedere|chimera|china|chirurgo|chitarra|ciao|ciclismo|cifrare|cigno|cilindro|ciottolo|circa|cirrosi|citrico|cittadino|ciuffo|civetta|civile|classico|clinica|cloro|cocco|codardo|codice|coerente|cognome|collare|colmato|colore|colposo|coltivato|colza|coma|cometa|commando|comodo|computer|comune|conciso|condurre|conferma|congelare|coniuge|connesso|conoscere|consumo|continuo|convegno|coperto|copione|coppia|copricapo|corazza|cordata|coricato|cornice|corolla|corpo|corredo|corsia|cortese|cosmico|costante|cottura|covato|cratere|cravatta|creato|credere|cremoso|crescita|creta|criceto|crinale|crisi|critico|croce|cronaca|crostata|cruciale|crusca|cucire|cuculo|cugino|cullato|cupola|curatore|cursore|curvo|cuscino|custode|dado|daino|dalmata|damerino|daniela|dannoso|danzare|datato|davanti|davvero|debutto|decennio|deciso|declino|decollo|decreto|dedicato|definito|deforme|degno|delegare|delfino|delirio|delta|demenza|denotato|dentro|deposito|derapata|derivare|deroga|descritto|deserto|desiderio|desumere|detersivo|devoto|diametro|dicembre|diedro|difeso|diffuso|digerire|digitale|diluvio|dinamico|dinnanzi|dipinto|diploma|dipolo|diradare|dire|dirotto|dirupo|disagio|discreto|disfare|disgelo|disposto|distanza|disumano|dito|divano|divelto|dividere|divorato|doblone|docente|doganale|dogma|dolce|domato|domenica|dominare|dondolo|dono|dormire|dote|dottore|dovuto|dozzina|drago|druido|dubbio|dubitare|ducale|duna|duomo|duplice|duraturo|ebano|eccesso|ecco|eclissi|economia|edera|edicola|edile|editoria|educare|egemonia|egli|egoismo|egregio|elaborato|elargire|elegante|elencato|eletto|elevare|elfico|elica|elmo|elsa|eluso|emanato|emblema|emesso|emiro|emotivo|emozione|empirico|emulo|endemico|enduro|energia|enfasi|enoteca|entrare|enzima|epatite|epilogo|episodio|epocale|eppure|equatore|erario|erba|erboso|erede|eremita|erigere|ermetico|eroe|erosivo|errante|esagono|esame|esanime|esaudire|esca|esempio|esercito|esibito|esigente|esistere|esito|esofago|esortato|esoso|espanso|espresso|essenza|esso|esteso|estimare|estonia|estroso|esultare|etilico|etnico|etrusco|etto|euclideo|europa|evaso|evidenza|evitato|evoluto|evviva|fabbrica|faccenda|fachiro|falco|famiglia|fanale|fanfara|fango|fantasma|fare|farfalla|farinoso|farmaco|fascia|fastoso|fasullo|faticare|fato|favoloso|febbre|fecola|fede|fegato|felpa|feltro|femmina|fendere|fenomeno|fermento|ferro|fertile|fessura|festivo|fetta|feudo|fiaba|fiducia|fifa|figurato|filo|finanza|finestra|finire|fiore|fiscale|fisico|fiume|flacone|flamenco|flebo|flemma|florido|fluente|fluoro|fobico|focaccia|focoso|foderato|foglio|folata|folclore|folgore|fondente|fonetico|fonia|fontana|forbito|forchetta|foresta|formica|fornaio|foro|fortezza|forzare|fosfato|fosso|fracasso|frana|frassino|fratello|freccetta|frenata|fresco|frigo|frollino|fronde|frugale|frutta|fucilata|fucsia|fuggente|fulmine|fulvo|fumante|fumetto|fumoso|fune|funzione|fuoco|furbo|furgone|furore|fuso|futile|gabbiano|gaffe|galateo|gallina|galoppo|gambero|gamma|garanzia|garbo|garofano|garzone|gasdotto|gasolio|gastrico|gatto|gaudio|gazebo|gazzella|geco|gelatina|gelso|gemello|gemmato|gene|genitore|gennaio|genotipo|gergo|ghepardo|ghiaccio|ghisa|giallo|gilda|ginepro|giocare|gioiello|giorno|giove|girato|girone|gittata|giudizio|giurato|giusto|globulo|glutine|gnomo|gobba|golf|gomito|gommone|gonfio|gonna|governo|gracile|grado|grafico|grammo|grande|grattare|gravoso|grazia|greca|gregge|grifone|grigio|grinza|grotta|gruppo|guadagno|guaio|guanto|guardare|gufo|guidare|ibernato|icona|identico|idillio|idolo|idra|idrico|idrogeno|igiene|ignaro|ignorato|ilare|illeso|illogico|illudere|imballo|imbevuto|imbocco|imbuto|immane|immerso|immolato|impacco|impeto|impiego|importo|impronta|inalare|inarcare|inattivo|incanto|incendio|inchino|incisivo|incluso|incontro|incrocio|incubo|indagine|india|indole|inedito|infatti|infilare|inflitto|ingaggio|ingegno|inglese|ingordo|ingrosso|innesco|inodore|inoltrare|inondato|insano|insetto|insieme|insonnia|insulina|intasato|intero|intonaco|intuito|inumidire|invalido|invece|invito|iperbole|ipnotico|ipotesi|ippica|iride|irlanda|ironico|irrigato|irrorare|isolato|isotopo|isterico|istituto|istrice|italia|iterare|labbro|labirinto|lacca|lacerato|lacrima|lacuna|laddove|lago|lampo|lancetta|lanterna|lardoso|larga|laringe|lastra|latenza|latino|lattuga|lavagna|lavoro|legale|leggero|lembo|lentezza|lenza|leone|lepre|lesivo|lessato|lesto|letterale|leva|levigato|libero|lido|lievito|lilla|limatura|limitare|limpido|lineare|lingua|liquido|lira|lirica|lisca|lite|litigio|livrea|locanda|lode|logica|lombare|londra|longevo|loquace|lorenzo|loto|lotteria|luce|lucidato|lumaca|luminoso|lungo|lupo|luppolo|lusinga|lusso|lutto|macabro|macchina|macero|macinato|madama|magico|maglia|magnete|magro|maiolica|malafede|malgrado|malinteso|malsano|malto|malumore|mana|mancia|mandorla|mangiare|manifesto|mannaro|manovra|mansarda|mantide|manubrio|mappa|maratona|marcire|maretta|marmo|marsupio|maschera|massaia|mastino|materasso|matricola|mattone|maturo|mazurca|meandro|meccanico|mecenate|medesimo|meditare|mega|melassa|melis|melodia|meninge|meno|mensola|mercurio|merenda|merlo|meschino|mese|messere|mestolo|metallo|metodo|mettere|miagolare|mica|micelio|michele|microbo|midollo|miele|migliore|milano|milite|mimosa|minerale|mini|minore|mirino|mirtillo|miscela|missiva|misto|misurare|mitezza|mitigare|mitra|mittente|mnemonico|modello|modifica|modulo|mogano|mogio|mole|molosso|monastero|monco|mondina|monetario|monile|monotono|monsone|montato|monviso|mora|mordere|morsicato|mostro|motivato|motosega|motto|movenza|movimento|mozzo|mucca|mucosa|muffa|mughetto|mugnaio|mulatto|mulinello|multiplo|mummia|munto|muovere|murale|musa|muscolo|musica|mutevole|muto|nababbo|nafta|nanometro|narciso|narice|narrato|nascere|nastrare|naturale|nautica|naviglio|nebulosa|necrosi|negativo|negozio|nemmeno|neofita|neretto|nervo|nessuno|nettuno|neutrale|neve|nevrotico|nicchia|ninfa|nitido|nobile|nocivo|nodo|nome|nomina|nordico|normale|norvegese|nostrano|notare|notizia|notturno|novella|nucleo|nulla|numero|nuovo|nutrire|nuvola|nuziale|oasi|obbedire|obbligo|obelisco|oblio|obolo|obsoleto|occasione|occhio|occidente|occorrere|occultare|ocra|oculato|odierno|odorare|offerta|offrire|offuscato|oggetto|oggi|ognuno|olandese|olfatto|oliato|oliva|ologramma|oltre|omaggio|ombelico|ombra|omega|omissione|ondoso|onere|onice|onnivoro|onorevole|onta|operato|opinione|opposto|oracolo|orafo|ordine|orecchino|orefice|orfano|organico|origine|orizzonte|orma|ormeggio|ornativo|orologio|orrendo|orribile|ortensia|ortica|orzata|orzo|osare|oscurare|osmosi|ospedale|ospite|ossa|ossidare|ostacolo|oste|otite|otre|ottagono|ottimo|ottobre|ovale|ovest|ovino|oviparo|ovocito|ovunque|ovviare|ozio|pacchetto|pace|pacifico|padella|padrone|paese|paga|pagina|palazzina|palesare|pallido|palo|palude|pandoro|pannello|paolo|paonazzo|paprica|parabola|parcella|parere|pargolo|pari|parlato|parola|partire|parvenza|parziale|passivo|pasticca|patacca|patologia|pattume|pavone|peccato|pedalare|pedonale|peggio|peloso|penare|pendice|penisola|pennuto|penombra|pensare|pentola|pepe|pepita|perbene|percorso|perdonato|perforare|pergamena|periodo|permesso|perno|perplesso|persuaso|pertugio|pervaso|pesatore|pesista|peso|pestifero|petalo|pettine|petulante|pezzo|piacere|pianta|piattino|piccino|picozza|piega|pietra|piffero|pigiama|pigolio|pigro|pila|pilifero|pillola|pilota|pimpante|pineta|pinna|pinolo|pioggia|piombo|piramide|piretico|pirite|pirolisi|pitone|pizzico|placebo|planare|plasma|platano|plenario|pochezza|poderoso|podismo|poesia|poggiare|polenta|poligono|pollice|polmonite|polpetta|polso|poltrona|polvere|pomice|pomodoro|ponte|popoloso|porfido|poroso|porpora|porre|portata|posa|positivo|possesso|postulato|potassio|potere|pranzo|prassi|pratica|precluso|predica|prefisso|pregiato|prelievo|premere|prenotare|preparato|presenza|pretesto|prevalso|prima|principe|privato|problema|procura|produrre|profumo|progetto|prolunga|promessa|pronome|proposta|proroga|proteso|prova|prudente|prugna|prurito|psiche|pubblico|pudica|pugilato|pugno|pulce|pulito|pulsante|puntare|pupazzo|pupilla|puro|quadro|qualcosa|quasi|querela|quota|raccolto|raddoppio|radicale|radunato|raffica|ragazzo|ragione|ragno|ramarro|ramingo|ramo|randagio|rantolare|rapato|rapina|rappreso|rasatura|raschiato|rasente|rassegna|rastrello|rata|ravveduto|reale|recepire|recinto|recluta|recondito|recupero|reddito|redimere|regalato|registro|regola|regresso|relazione|remare|remoto|renna|replica|reprimere|reputare|resa|residente|responso|restauro|rete|retina|retorica|rettifica|revocato|riassunto|ribadire|ribelle|ribrezzo|ricarica|ricco|ricevere|riciclato|ricordo|ricreduto|ridicolo|ridurre|rifasare|riflesso|riforma|rifugio|rigare|rigettato|righello|rilassato|rilevato|rimanere|rimbalzo|rimedio|rimorchio|rinascita|rincaro|rinforzo|rinnovo|rinomato|rinsavito|rintocco|rinuncia|rinvenire|riparato|ripetuto|ripieno|riportare|ripresa|ripulire|risata|rischio|riserva|risibile|riso|rispetto|ristoro|risultato|risvolto|ritardo|ritegno|ritmico|ritrovo|riunione|riva|riverso|rivincita|rivolto|rizoma|roba|robotico|robusto|roccia|roco|rodaggio|rodere|roditore|rogito|rollio|romantico|rompere|ronzio|rosolare|rospo|rotante|rotondo|rotula|rovescio|rubizzo|rubrica|ruga|rullino|rumine|rumoroso|ruolo|rupe|russare|rustico|sabato|sabbiare|sabotato|sagoma|salasso|saldatura|salgemma|salivare|salmone|salone|saltare|saluto|salvo|sapere|sapido|saporito|saraceno|sarcasmo|sarto|sassoso|satellite|satira|satollo|saturno|savana|savio|saziato|sbadiglio|sbalzo|sbancato|sbarra|sbattere|sbavare|sbendare|sbirciare|sbloccato|sbocciato|sbrinare|sbruffone|sbuffare|scabroso|scadenza|scala|scambiare|scandalo|scapola|scarso|scatenare|scavato|scelto|scenico|scettro|scheda|schiena|sciarpa|scienza|scindere|scippo|sciroppo|scivolo|sclerare|scodella|scolpito|scomparto|sconforto|scoprire|scorta|scossone|scozzese|scriba|scrollare|scrutinio|scuderia|scultore|scuola|scuro|scusare|sdebitare|sdoganare|seccatura|secondo|sedano|seggiola|segnalato|segregato|seguito|selciato|selettivo|sella|selvaggio|semaforo|sembrare|seme|seminato|sempre|senso|sentire|sepolto|sequenza|serata|serbato|sereno|serio|serpente|serraglio|servire|sestina|setola|settimana|sfacelo|sfaldare|sfamato|sfarzoso|sfaticato|sfera|sfida|sfilato|sfinge|sfocato|sfoderare|sfogo|sfoltire|sforzato|sfratto|sfruttato|sfuggito|sfumare|sfuso|sgabello|sgarbato|sgonfiare|sgorbio|sgrassato|sguardo|sibilo|siccome|sierra|sigla|signore|silenzio|sillaba|simbolo|simpatico|simulato|sinfonia|singolo|sinistro|sino|sintesi|sinusoide|sipario|sisma|sistole|situato|slitta|slogatura|sloveno|smarrito|smemorato|smentito|smeraldo|smilzo|smontare|smottato|smussato|snellire|snervato|snodo|sobbalzo|sobrio|soccorso|sociale|sodale|soffitto|sogno|soldato|solenne|solido|sollazzo|solo|solubile|solvente|somatico|somma|sonda|sonetto|sonnifero|sopire|soppeso|sopra|sorgere|sorpasso|sorriso|sorso|sorteggio|sorvolato|sospiro|sosta|sottile|spada|spalla|spargere|spatola|spavento|spazzola|specie|spedire|spegnere|spelatura|speranza|spessore|spettrale|spezzato|spia|spigoloso|spillato|spinoso|spirale|splendido|sportivo|sposo|spranga|sprecare|spronato|spruzzo|spuntino|squillo|sradicare|srotolato|stabile|stacco|staffa|stagnare|stampato|stantio|starnuto|stasera|statuto|stelo|steppa|sterzo|stiletto|stima|stirpe|stivale|stizzoso|stonato|storico|strappo|stregato|stridulo|strozzare|strutto|stuccare|stufo|stupendo|subentro|succoso|sudore|suggerito|sugo|sultano|suonare|superbo|supporto|surgelato|surrogato|sussurro|sutura|svagare|svedese|sveglio|svelare|svenuto|svezia|sviluppo|svista|svizzera|svolta|svuotare|tabacco|tabulato|tacciare|taciturno|tale|talismano|tampone|tannino|tara|tardivo|targato|tariffa|tarpare|tartaruga|tasto|tattico|taverna|tavolata|tazza|teca|tecnico|telefono|temerario|tempo|temuto|tendone|tenero|tensione|tentacolo|teorema|terme|terrazzo|terzetto|tesi|tesserato|testato|tetro|tettoia|tifare|tigella|timbro|tinto|tipico|tipografo|tiraggio|tiro|titanio|titolo|titubante|tizio|tizzone|toccare|tollerare|tolto|tombola|tomo|tonfo|tonsilla|topazio|topologia|toppa|torba|tornare|torrone|tortora|toscano|tossire|tostatura|totano|trabocco|trachea|trafila|tragedia|tralcio|tramonto|transito|trapano|trarre|trasloco|trattato|trave|treccia|tremolio|trespolo|tributo|tricheco|trifoglio|trillo|trincea|trio|tristezza|triturato|trivella|tromba|trono|troppo|trottola|trovare|truccato|tubatura|tuffato|tulipano|tumulto|tunisia|turbare|turchino|tuta|tutela|ubicato|uccello|uccisore|udire|uditivo|uffa|ufficio|uguale|ulisse|ultimato|umano|umile|umorismo|uncinetto|ungere|ungherese|unicorno|unificato|unisono|unitario|unte|uovo|upupa|uragano|urgenza|urlo|usanza|usato|uscito|usignolo|usuraio|utensile|utilizzo|utopia|vacante|vaccinato|vagabondo|vagliato|valanga|valgo|valico|valletta|valoroso|valutare|valvola|vampata|vangare|vanitoso|vano|vantaggio|vanvera|vapore|varano|varcato|variante|vasca|vedetta|vedova|veduto|vegetale|veicolo|velcro|velina|velluto|veloce|venato|vendemmia|vento|verace|verbale|vergogna|verifica|vero|verruca|verticale|vescica|vessillo|vestale|veterano|vetrina|vetusto|viandante|vibrante|vicenda|vichingo|vicinanza|vidimare|vigilia|vigneto|vigore|vile|villano|vimini|vincitore|viola|vipera|virgola|virologo|virulento|viscoso|visione|vispo|vissuto|visura|vita|vitello|vittima|vivanda|vivido|viziare|voce|voga|volatile|volere|volpe|voragine|vulcano|zampogna|zanna|zappato|zattera|zavorra|zefiro|zelante|zelo|zenzero|zerbino|zibetto|zinco|zircone|zitto|zolla|zotico|zucchero|zufolo|zulu|zuppa'.split('|'); diff --git a/packages/util-crypto/mnemonic/wordlists/jp.d.ts b/packages/util-crypto/mnemonic/wordlists/jp.d.ts new file mode 100644 index 0000000..d451d2b --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/jp.d.ts @@ -0,0 +1,2 @@ +declare const _default: string[]; +export default _default; diff --git a/packages/util-crypto/mnemonic/wordlists/jp.js b/packages/util-crypto/mnemonic/wordlists/jp.js new file mode 100644 index 0000000..1fe8339 --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/jp.js @@ -0,0 +1 @@ +export default 'あいこくしん|あいさつ|あいだ|あおぞら|あかちゃん|あきる|あけがた|あける|あこがれる|あさい|あさひ|あしあと|あじわう|あずかる|あずき|あそぶ|あたえる|あたためる|あたりまえ|あたる|あつい|あつかう|あっしゅく|あつまり|あつめる|あてな|あてはまる|あひる|あぶら|あぶる|あふれる|あまい|あまど|あまやかす|あまり|あみもの|あめりか|あやまる|あゆむ|あらいぐま|あらし|あらすじ|あらためる|あらゆる|あらわす|ありがとう|あわせる|あわてる|あんい|あんがい|あんこ|あんぜん|あんてい|あんない|あんまり|いいだす|いおん|いがい|いがく|いきおい|いきなり|いきもの|いきる|いくじ|いくぶん|いけばな|いけん|いこう|いこく|いこつ|いさましい|いさん|いしき|いじゅう|いじょう|いじわる|いずみ|いずれ|いせい|いせえび|いせかい|いせき|いぜん|いそうろう|いそがしい|いだい|いだく|いたずら|いたみ|いたりあ|いちおう|いちじ|いちど|いちば|いちぶ|いちりゅう|いつか|いっしゅん|いっせい|いっそう|いったん|いっち|いってい|いっぽう|いてざ|いてん|いどう|いとこ|いない|いなか|いねむり|いのち|いのる|いはつ|いばる|いはん|いびき|いひん|いふく|いへん|いほう|いみん|いもうと|いもたれ|いもり|いやがる|いやす|いよかん|いよく|いらい|いらすと|いりぐち|いりょう|いれい|いれもの|いれる|いろえんぴつ|いわい|いわう|いわかん|いわば|いわゆる|いんげんまめ|いんさつ|いんしょう|いんよう|うえき|うえる|うおざ|うがい|うかぶ|うかべる|うきわ|うくらいな|うくれれ|うけたまわる|うけつけ|うけとる|うけもつ|うける|うごかす|うごく|うこん|うさぎ|うしなう|うしろがみ|うすい|うすぎ|うすぐらい|うすめる|うせつ|うちあわせ|うちがわ|うちき|うちゅう|うっかり|うつくしい|うったえる|うつる|うどん|うなぎ|うなじ|うなずく|うなる|うねる|うのう|うぶげ|うぶごえ|うまれる|うめる|うもう|うやまう|うよく|うらがえす|うらぐち|うらない|うりあげ|うりきれ|うるさい|うれしい|うれゆき|うれる|うろこ|うわき|うわさ|うんこう|うんちん|うんてん|うんどう|えいえん|えいが|えいきょう|えいご|えいせい|えいぶん|えいよう|えいわ|えおり|えがお|えがく|えきたい|えくせる|えしゃく|えすて|えつらん|えのぐ|えほうまき|えほん|えまき|えもじ|えもの|えらい|えらぶ|えりあ|えんえん|えんかい|えんぎ|えんげき|えんしゅう|えんぜつ|えんそく|えんちょう|えんとつ|おいかける|おいこす|おいしい|おいつく|おうえん|おうさま|おうじ|おうせつ|おうたい|おうふく|おうべい|おうよう|おえる|おおい|おおう|おおどおり|おおや|おおよそ|おかえり|おかず|おがむ|おかわり|おぎなう|おきる|おくさま|おくじょう|おくりがな|おくる|おくれる|おこす|おこなう|おこる|おさえる|おさない|おさめる|おしいれ|おしえる|おじぎ|おじさん|おしゃれ|おそらく|おそわる|おたがい|おたく|おだやか|おちつく|おっと|おつり|おでかけ|おとしもの|おとなしい|おどり|おどろかす|おばさん|おまいり|おめでとう|おもいで|おもう|おもたい|おもちゃ|おやつ|おやゆび|およぼす|おらんだ|おろす|おんがく|おんけい|おんしゃ|おんせん|おんだん|おんちゅう|おんどけい|かあつ|かいが|がいき|がいけん|がいこう|かいさつ|かいしゃ|かいすいよく|かいぜん|かいぞうど|かいつう|かいてん|かいとう|かいふく|がいへき|かいほう|かいよう|がいらい|かいわ|かえる|かおり|かかえる|かがく|かがし|かがみ|かくご|かくとく|かざる|がぞう|かたい|かたち|がちょう|がっきゅう|がっこう|がっさん|がっしょう|かなざわし|かのう|がはく|かぶか|かほう|かほご|かまう|かまぼこ|かめれおん|かゆい|かようび|からい|かるい|かろう|かわく|かわら|がんか|かんけい|かんこう|かんしゃ|かんそう|かんたん|かんち|がんばる|きあい|きあつ|きいろ|ぎいん|きうい|きうん|きえる|きおう|きおく|きおち|きおん|きかい|きかく|きかんしゃ|ききて|きくばり|きくらげ|きけんせい|きこう|きこえる|きこく|きさい|きさく|きさま|きさらぎ|ぎじかがく|ぎしき|ぎじたいけん|ぎじにってい|ぎじゅつしゃ|きすう|きせい|きせき|きせつ|きそう|きぞく|きぞん|きたえる|きちょう|きつえん|ぎっちり|きつつき|きつね|きてい|きどう|きどく|きない|きなが|きなこ|きぬごし|きねん|きのう|きのした|きはく|きびしい|きひん|きふく|きぶん|きぼう|きほん|きまる|きみつ|きむずかしい|きめる|きもだめし|きもち|きもの|きゃく|きやく|ぎゅうにく|きよう|きょうりゅう|きらい|きらく|きりん|きれい|きれつ|きろく|ぎろん|きわめる|ぎんいろ|きんかくじ|きんじょ|きんようび|ぐあい|くいず|くうかん|くうき|くうぐん|くうこう|ぐうせい|くうそう|ぐうたら|くうふく|くうぼ|くかん|くきょう|くげん|ぐこう|くさい|くさき|くさばな|くさる|くしゃみ|くしょう|くすのき|くすりゆび|くせげ|くせん|ぐたいてき|くださる|くたびれる|くちこみ|くちさき|くつした|ぐっすり|くつろぐ|くとうてん|くどく|くなん|くねくね|くのう|くふう|くみあわせ|くみたてる|くめる|くやくしょ|くらす|くらべる|くるま|くれる|くろう|くわしい|ぐんかん|ぐんしょく|ぐんたい|ぐんて|けあな|けいかく|けいけん|けいこ|けいさつ|げいじゅつ|けいたい|げいのうじん|けいれき|けいろ|けおとす|けおりもの|げきか|げきげん|げきだん|げきちん|げきとつ|げきは|げきやく|げこう|げこくじょう|げざい|けさき|げざん|けしき|けしごむ|けしょう|げすと|けたば|けちゃっぷ|けちらす|けつあつ|けつい|けつえき|けっこん|けつじょ|けっせき|けってい|けつまつ|げつようび|げつれい|けつろん|げどく|けとばす|けとる|けなげ|けなす|けなみ|けぬき|げねつ|けねん|けはい|げひん|けぶかい|げぼく|けまり|けみかる|けむし|けむり|けもの|けらい|けろけろ|けわしい|けんい|けんえつ|けんお|けんか|げんき|けんげん|けんこう|けんさく|けんしゅう|けんすう|げんそう|けんちく|けんてい|けんとう|けんない|けんにん|げんぶつ|けんま|けんみん|けんめい|けんらん|けんり|こあくま|こいぬ|こいびと|ごうい|こうえん|こうおん|こうかん|ごうきゅう|ごうけい|こうこう|こうさい|こうじ|こうすい|ごうせい|こうそく|こうたい|こうちゃ|こうつう|こうてい|こうどう|こうない|こうはい|ごうほう|ごうまん|こうもく|こうりつ|こえる|こおり|ごかい|ごがつ|ごかん|こくご|こくさい|こくとう|こくない|こくはく|こぐま|こけい|こける|ここのか|こころ|こさめ|こしつ|こすう|こせい|こせき|こぜん|こそだて|こたい|こたえる|こたつ|こちょう|こっか|こつこつ|こつばん|こつぶ|こてい|こてん|ことがら|ことし|ことば|ことり|こなごな|こねこね|このまま|このみ|このよ|ごはん|こひつじ|こふう|こふん|こぼれる|ごまあぶら|こまかい|ごますり|こまつな|こまる|こむぎこ|こもじ|こもち|こもの|こもん|こやく|こやま|こゆう|こゆび|こよい|こよう|こりる|これくしょん|ころっけ|こわもて|こわれる|こんいん|こんかい|こんき|こんしゅう|こんすい|こんだて|こんとん|こんなん|こんびに|こんぽん|こんまけ|こんや|こんれい|こんわく|ざいえき|さいかい|さいきん|ざいげん|ざいこ|さいしょ|さいせい|ざいたく|ざいちゅう|さいてき|ざいりょう|さうな|さかいし|さがす|さかな|さかみち|さがる|さぎょう|さくし|さくひん|さくら|さこく|さこつ|さずかる|ざせき|さたん|さつえい|ざつおん|ざっか|ざつがく|さっきょく|ざっし|さつじん|ざっそう|さつたば|さつまいも|さてい|さといも|さとう|さとおや|さとし|さとる|さのう|さばく|さびしい|さべつ|さほう|さほど|さます|さみしい|さみだれ|さむけ|さめる|さやえんどう|さゆう|さよう|さよく|さらだ|ざるそば|さわやか|さわる|さんいん|さんか|さんきゃく|さんこう|さんさい|ざんしょ|さんすう|さんせい|さんそ|さんち|さんま|さんみ|さんらん|しあい|しあげ|しあさって|しあわせ|しいく|しいん|しうち|しえい|しおけ|しかい|しかく|じかん|しごと|しすう|じだい|したうけ|したぎ|したて|したみ|しちょう|しちりん|しっかり|しつじ|しつもん|してい|してき|してつ|じてん|じどう|しなぎれ|しなもの|しなん|しねま|しねん|しのぐ|しのぶ|しはい|しばかり|しはつ|しはらい|しはん|しひょう|しふく|じぶん|しへい|しほう|しほん|しまう|しまる|しみん|しむける|じむしょ|しめい|しめる|しもん|しゃいん|しゃうん|しゃおん|じゃがいも|しやくしょ|しゃくほう|しゃけん|しゃこ|しゃざい|しゃしん|しゃせん|しゃそう|しゃたい|しゃちょう|しゃっきん|じゃま|しゃりん|しゃれい|じゆう|じゅうしょ|しゅくはく|じゅしん|しゅっせき|しゅみ|しゅらば|じゅんばん|しょうかい|しょくたく|しょっけん|しょどう|しょもつ|しらせる|しらべる|しんか|しんこう|じんじゃ|しんせいじ|しんちく|しんりん|すあげ|すあし|すあな|ずあん|すいえい|すいか|すいとう|ずいぶん|すいようび|すうがく|すうじつ|すうせん|すおどり|すきま|すくう|すくない|すける|すごい|すこし|ずさん|すずしい|すすむ|すすめる|すっかり|ずっしり|ずっと|すてき|すてる|すねる|すのこ|すはだ|すばらしい|ずひょう|ずぶぬれ|すぶり|すふれ|すべて|すべる|ずほう|すぼん|すまい|すめし|すもう|すやき|すらすら|するめ|すれちがう|すろっと|すわる|すんぜん|すんぽう|せあぶら|せいかつ|せいげん|せいじ|せいよう|せおう|せかいかん|せきにん|せきむ|せきゆ|せきらんうん|せけん|せこう|せすじ|せたい|せたけ|せっかく|せっきゃく|ぜっく|せっけん|せっこつ|せっさたくま|せつぞく|せつだん|せつでん|せっぱん|せつび|せつぶん|せつめい|せつりつ|せなか|せのび|せはば|せびろ|せぼね|せまい|せまる|せめる|せもたれ|せりふ|ぜんあく|せんい|せんえい|せんか|せんきょ|せんく|せんげん|ぜんご|せんさい|せんしゅ|せんすい|せんせい|せんぞ|せんたく|せんちょう|せんてい|せんとう|せんぬき|せんねん|せんぱい|ぜんぶ|ぜんぽう|せんむ|せんめんじょ|せんもん|せんやく|せんゆう|せんよう|ぜんら|ぜんりゃく|せんれい|せんろ|そあく|そいとげる|そいね|そうがんきょう|そうき|そうご|そうしん|そうだん|そうなん|そうび|そうめん|そうり|そえもの|そえん|そがい|そげき|そこう|そこそこ|そざい|そしな|そせい|そせん|そそぐ|そだてる|そつう|そつえん|そっかん|そつぎょう|そっけつ|そっこう|そっせん|そっと|そとがわ|そとづら|そなえる|そなた|そふぼ|そぼく|そぼろ|そまつ|そまる|そむく|そむりえ|そめる|そもそも|そよかぜ|そらまめ|そろう|そんかい|そんけい|そんざい|そんしつ|そんぞく|そんちょう|ぞんび|ぞんぶん|そんみん|たあい|たいいん|たいうん|たいえき|たいおう|だいがく|たいき|たいぐう|たいけん|たいこ|たいざい|だいじょうぶ|だいすき|たいせつ|たいそう|だいたい|たいちょう|たいてい|だいどころ|たいない|たいねつ|たいのう|たいはん|だいひょう|たいふう|たいへん|たいほ|たいまつばな|たいみんぐ|たいむ|たいめん|たいやき|たいよう|たいら|たいりょく|たいる|たいわん|たうえ|たえる|たおす|たおる|たおれる|たかい|たかね|たきび|たくさん|たこく|たこやき|たさい|たしざん|だじゃれ|たすける|たずさわる|たそがれ|たたかう|たたく|ただしい|たたみ|たちばな|だっかい|だっきゃく|だっこ|だっしゅつ|だったい|たてる|たとえる|たなばた|たにん|たぬき|たのしみ|たはつ|たぶん|たべる|たぼう|たまご|たまる|だむる|ためいき|ためす|ためる|たもつ|たやすい|たよる|たらす|たりきほんがん|たりょう|たりる|たると|たれる|たれんと|たろっと|たわむれる|だんあつ|たんい|たんおん|たんか|たんき|たんけん|たんご|たんさん|たんじょうび|だんせい|たんそく|たんたい|だんち|たんてい|たんとう|だんな|たんにん|だんねつ|たんのう|たんぴん|だんぼう|たんまつ|たんめい|だんれつ|だんろ|だんわ|ちあい|ちあん|ちいき|ちいさい|ちえん|ちかい|ちから|ちきゅう|ちきん|ちけいず|ちけん|ちこく|ちさい|ちしき|ちしりょう|ちせい|ちそう|ちたい|ちたん|ちちおや|ちつじょ|ちてき|ちてん|ちぬき|ちぬり|ちのう|ちひょう|ちへいせん|ちほう|ちまた|ちみつ|ちみどろ|ちめいど|ちゃんこなべ|ちゅうい|ちゆりょく|ちょうし|ちょさくけん|ちらし|ちらみ|ちりがみ|ちりょう|ちるど|ちわわ|ちんたい|ちんもく|ついか|ついたち|つうか|つうじょう|つうはん|つうわ|つかう|つかれる|つくね|つくる|つけね|つける|つごう|つたえる|つづく|つつじ|つつむ|つとめる|つながる|つなみ|つねづね|つのる|つぶす|つまらない|つまる|つみき|つめたい|つもり|つもる|つよい|つるぼ|つるみく|つわもの|つわり|てあし|てあて|てあみ|ていおん|ていか|ていき|ていけい|ていこく|ていさつ|ていし|ていせい|ていたい|ていど|ていねい|ていひょう|ていへん|ていぼう|てうち|ておくれ|てきとう|てくび|でこぼこ|てさぎょう|てさげ|てすり|てそう|てちがい|てちょう|てつがく|てつづき|でっぱ|てつぼう|てつや|でぬかえ|てぬき|てぬぐい|てのひら|てはい|てぶくろ|てふだ|てほどき|てほん|てまえ|てまきずし|てみじか|てみやげ|てらす|てれび|てわけ|てわたし|でんあつ|てんいん|てんかい|てんき|てんぐ|てんけん|てんごく|てんさい|てんし|てんすう|でんち|てんてき|てんとう|てんない|てんぷら|てんぼうだい|てんめつ|てんらんかい|でんりょく|でんわ|どあい|といれ|どうかん|とうきゅう|どうぐ|とうし|とうむぎ|とおい|とおか|とおく|とおす|とおる|とかい|とかす|ときおり|ときどき|とくい|とくしゅう|とくてん|とくに|とくべつ|とけい|とける|とこや|とさか|としょかん|とそう|とたん|とちゅう|とっきゅう|とっくん|とつぜん|とつにゅう|とどける|ととのえる|とない|となえる|となり|とのさま|とばす|どぶがわ|とほう|とまる|とめる|ともだち|ともる|どようび|とらえる|とんかつ|どんぶり|ないかく|ないこう|ないしょ|ないす|ないせん|ないそう|なおす|ながい|なくす|なげる|なこうど|なさけ|なたでここ|なっとう|なつやすみ|ななおし|なにごと|なにもの|なにわ|なのか|なふだ|なまいき|なまえ|なまみ|なみだ|なめらか|なめる|なやむ|ならう|ならび|ならぶ|なれる|なわとび|なわばり|にあう|にいがた|にうけ|におい|にかい|にがて|にきび|にくしみ|にくまん|にげる|にさんかたんそ|にしき|にせもの|にちじょう|にちようび|にっか|にっき|にっけい|にっこう|にっさん|にっしょく|にっすう|にっせき|にってい|になう|にほん|にまめ|にもつ|にやり|にゅういん|にりんしゃ|にわとり|にんい|にんか|にんき|にんげん|にんしき|にんずう|にんそう|にんたい|にんち|にんてい|にんにく|にんぷ|にんまり|にんむ|にんめい|にんよう|ぬいくぎ|ぬかす|ぬぐいとる|ぬぐう|ぬくもり|ぬすむ|ぬまえび|ぬめり|ぬらす|ぬんちゃく|ねあげ|ねいき|ねいる|ねいろ|ねぐせ|ねくたい|ねくら|ねこぜ|ねこむ|ねさげ|ねすごす|ねそべる|ねだん|ねつい|ねっしん|ねつぞう|ねったいぎょ|ねぶそく|ねふだ|ねぼう|ねほりはほり|ねまき|ねまわし|ねみみ|ねむい|ねむたい|ねもと|ねらう|ねわざ|ねんいり|ねんおし|ねんかん|ねんきん|ねんぐ|ねんざ|ねんし|ねんちゃく|ねんど|ねんぴ|ねんぶつ|ねんまつ|ねんりょう|ねんれい|のいず|のおづま|のがす|のきなみ|のこぎり|のこす|のこる|のせる|のぞく|のぞむ|のたまう|のちほど|のっく|のばす|のはら|のべる|のぼる|のみもの|のやま|のらいぬ|のらねこ|のりもの|のりゆき|のれん|のんき|ばあい|はあく|ばあさん|ばいか|ばいく|はいけん|はいご|はいしん|はいすい|はいせん|はいそう|はいち|ばいばい|はいれつ|はえる|はおる|はかい|ばかり|はかる|はくしゅ|はけん|はこぶ|はさみ|はさん|はしご|ばしょ|はしる|はせる|ぱそこん|はそん|はたん|はちみつ|はつおん|はっかく|はづき|はっきり|はっくつ|はっけん|はっこう|はっさん|はっしん|はったつ|はっちゅう|はってん|はっぴょう|はっぽう|はなす|はなび|はにかむ|はぶらし|はみがき|はむかう|はめつ|はやい|はやし|はらう|はろうぃん|はわい|はんい|はんえい|はんおん|はんかく|はんきょう|ばんぐみ|はんこ|はんしゃ|はんすう|はんだん|ぱんち|ぱんつ|はんてい|はんとし|はんのう|はんぱ|はんぶん|はんぺん|はんぼうき|はんめい|はんらん|はんろん|ひいき|ひうん|ひえる|ひかく|ひかり|ひかる|ひかん|ひくい|ひけつ|ひこうき|ひこく|ひさい|ひさしぶり|ひさん|びじゅつかん|ひしょ|ひそか|ひそむ|ひたむき|ひだり|ひたる|ひつぎ|ひっこし|ひっし|ひつじゅひん|ひっす|ひつぜん|ぴったり|ぴっちり|ひつよう|ひてい|ひとごみ|ひなまつり|ひなん|ひねる|ひはん|ひびく|ひひょう|ひほう|ひまわり|ひまん|ひみつ|ひめい|ひめじし|ひやけ|ひやす|ひよう|びょうき|ひらがな|ひらく|ひりつ|ひりょう|ひるま|ひるやすみ|ひれい|ひろい|ひろう|ひろき|ひろゆき|ひんかく|ひんけつ|ひんこん|ひんしゅ|ひんそう|ぴんち|ひんぱん|びんぼう|ふあん|ふいうち|ふうけい|ふうせん|ぷうたろう|ふうとう|ふうふ|ふえる|ふおん|ふかい|ふきん|ふくざつ|ふくぶくろ|ふこう|ふさい|ふしぎ|ふじみ|ふすま|ふせい|ふせぐ|ふそく|ぶたにく|ふたん|ふちょう|ふつう|ふつか|ふっかつ|ふっき|ふっこく|ぶどう|ふとる|ふとん|ふのう|ふはい|ふひょう|ふへん|ふまん|ふみん|ふめつ|ふめん|ふよう|ふりこ|ふりる|ふるい|ふんいき|ぶんがく|ぶんぐ|ふんしつ|ぶんせき|ふんそう|ぶんぽう|へいあん|へいおん|へいがい|へいき|へいげん|へいこう|へいさ|へいしゃ|へいせつ|へいそ|へいたく|へいてん|へいねつ|へいわ|へきが|へこむ|べにいろ|べにしょうが|へらす|へんかん|べんきょう|べんごし|へんさい|へんたい|べんり|ほあん|ほいく|ぼうぎょ|ほうこく|ほうそう|ほうほう|ほうもん|ほうりつ|ほえる|ほおん|ほかん|ほきょう|ぼきん|ほくろ|ほけつ|ほけん|ほこう|ほこる|ほしい|ほしつ|ほしゅ|ほしょう|ほせい|ほそい|ほそく|ほたて|ほたる|ぽちぶくろ|ほっきょく|ほっさ|ほったん|ほとんど|ほめる|ほんい|ほんき|ほんけ|ほんしつ|ほんやく|まいにち|まかい|まかせる|まがる|まける|まこと|まさつ|まじめ|ますく|まぜる|まつり|まとめ|まなぶ|まぬけ|まねく|まほう|まもる|まゆげ|まよう|まろやか|まわす|まわり|まわる|まんが|まんきつ|まんぞく|まんなか|みいら|みうち|みえる|みがく|みかた|みかん|みけん|みこん|みじかい|みすい|みすえる|みせる|みっか|みつかる|みつける|みてい|みとめる|みなと|みなみかさい|みねらる|みのう|みのがす|みほん|みもと|みやげ|みらい|みりょく|みわく|みんか|みんぞく|むいか|むえき|むえん|むかい|むかう|むかえ|むかし|むぎちゃ|むける|むげん|むさぼる|むしあつい|むしば|むじゅん|むしろ|むすう|むすこ|むすぶ|むすめ|むせる|むせん|むちゅう|むなしい|むのう|むやみ|むよう|むらさき|むりょう|むろん|めいあん|めいうん|めいえん|めいかく|めいきょく|めいさい|めいし|めいそう|めいぶつ|めいれい|めいわく|めぐまれる|めざす|めした|めずらしい|めだつ|めまい|めやす|めんきょ|めんせき|めんどう|もうしあげる|もうどうけん|もえる|もくし|もくてき|もくようび|もちろん|もどる|もらう|もんく|もんだい|やおや|やける|やさい|やさしい|やすい|やすたろう|やすみ|やせる|やそう|やたい|やちん|やっと|やっぱり|やぶる|やめる|ややこしい|やよい|やわらかい|ゆうき|ゆうびんきょく|ゆうべ|ゆうめい|ゆけつ|ゆしゅつ|ゆせん|ゆそう|ゆたか|ゆちゃく|ゆでる|ゆにゅう|ゆびわ|ゆらい|ゆれる|ようい|ようか|ようきゅう|ようじ|ようす|ようちえん|よかぜ|よかん|よきん|よくせい|よくぼう|よけい|よごれる|よさん|よしゅう|よそう|よそく|よっか|よてい|よどがわく|よねつ|よやく|よゆう|よろこぶ|よろしい|らいう|らくがき|らくご|らくさつ|らくだ|らしんばん|らせん|らぞく|らたい|らっか|られつ|りえき|りかい|りきさく|りきせつ|りくぐん|りくつ|りけん|りこう|りせい|りそう|りそく|りてん|りねん|りゆう|りゅうがく|りよう|りょうり|りょかん|りょくちゃ|りょこう|りりく|りれき|りろん|りんご|るいけい|るいさい|るいじ|るいせき|るすばん|るりがわら|れいかん|れいぎ|れいせい|れいぞうこ|れいとう|れいぼう|れきし|れきだい|れんあい|れんけい|れんこん|れんさい|れんしゅう|れんぞく|れんらく|ろうか|ろうご|ろうじん|ろうそく|ろくが|ろこつ|ろじうら|ろしゅつ|ろせん|ろてん|ろめん|ろれつ|ろんぎ|ろんぱ|ろんぶん|ろんり|わかす|わかめ|わかやま|わかれる|わしつ|わじまし|わすれもの|わらう|われる'.split('|'); diff --git a/packages/util-crypto/mnemonic/wordlists/ko.d.ts b/packages/util-crypto/mnemonic/wordlists/ko.d.ts new file mode 100644 index 0000000..d451d2b --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/ko.d.ts @@ -0,0 +1,2 @@ +declare const _default: string[]; +export default _default; diff --git a/packages/util-crypto/mnemonic/wordlists/ko.js b/packages/util-crypto/mnemonic/wordlists/ko.js new file mode 100644 index 0000000..94d5167 --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/ko.js @@ -0,0 +1 @@ +export default '가격|가끔|가난|가능|가득|가르침|가뭄|가방|가상|가슴|가운데|가을|가이드|가입|가장|가정|가족|가죽|각오|각자|간격|간부|간섭|간장|간접|간판|갈등|갈비|갈색|갈증|감각|감기|감소|감수성|감자|감정|갑자기|강남|강당|강도|강력히|강변|강북|강사|강수량|강아지|강원도|강의|강제|강조|같이|개구리|개나리|개방|개별|개선|개성|개인|객관적|거실|거액|거울|거짓|거품|걱정|건강|건물|건설|건조|건축|걸음|검사|검토|게시판|게임|겨울|견해|결과|결국|결론|결석|결승|결심|결정|결혼|경계|경고|경기|경력|경복궁|경비|경상도|경영|경우|경쟁|경제|경주|경찰|경치|경향|경험|계곡|계단|계란|계산|계속|계약|계절|계층|계획|고객|고구려|고궁|고급|고등학생|고무신|고민|고양이|고장|고전|고집|고춧가루|고통|고향|곡식|골목|골짜기|골프|공간|공개|공격|공군|공급|공기|공동|공무원|공부|공사|공식|공업|공연|공원|공장|공짜|공책|공통|공포|공항|공휴일|과목|과일|과장|과정|과학|관객|관계|관광|관념|관람|관련|관리|관습|관심|관점|관찰|광경|광고|광장|광주|괴로움|굉장히|교과서|교문|교복|교실|교양|교육|교장|교직|교통|교환|교훈|구경|구름|구멍|구별|구분|구석|구성|구속|구역|구입|구청|구체적|국가|국기|국내|국립|국물|국민|국수|국어|국왕|국적|국제|국회|군대|군사|군인|궁극적|권리|권위|권투|귀국|귀신|규정|규칙|균형|그날|그냥|그늘|그러나|그룹|그릇|그림|그제서야|그토록|극복|극히|근거|근교|근래|근로|근무|근본|근원|근육|근처|글씨|글자|금강산|금고|금년|금메달|금액|금연|금요일|금지|긍정적|기간|기관|기념|기능|기독교|기둥|기록|기름|기법|기본|기분|기쁨|기숙사|기술|기억|기업|기온|기운|기원|기적|기준|기침|기혼|기획|긴급|긴장|길이|김밥|김치|김포공항|깍두기|깜빡|깨달음|깨소금|껍질|꼭대기|꽃잎|나들이|나란히|나머지|나물|나침반|나흘|낙엽|난방|날개|날씨|날짜|남녀|남대문|남매|남산|남자|남편|남학생|낭비|낱말|내년|내용|내일|냄비|냄새|냇물|냉동|냉면|냉방|냉장고|넥타이|넷째|노동|노란색|노력|노인|녹음|녹차|녹화|논리|논문|논쟁|놀이|농구|농담|농민|농부|농업|농장|농촌|높이|눈동자|눈물|눈썹|뉴욕|느낌|늑대|능동적|능력|다방|다양성|다음|다이어트|다행|단계|단골|단독|단맛|단순|단어|단위|단점|단체|단추|단편|단풍|달걀|달러|달력|달리|닭고기|담당|담배|담요|담임|답변|답장|당근|당분간|당연히|당장|대규모|대낮|대단히|대답|대도시|대략|대량|대륙|대문|대부분|대신|대응|대장|대전|대접|대중|대책|대출|대충|대통령|대학|대한민국|대합실|대형|덩어리|데이트|도대체|도덕|도둑|도망|도서관|도심|도움|도입|도자기|도저히|도전|도중|도착|독감|독립|독서|독일|독창적|동화책|뒷모습|뒷산|딸아이|마누라|마늘|마당|마라톤|마련|마무리|마사지|마약|마요네즈|마을|마음|마이크|마중|마지막|마찬가지|마찰|마흔|막걸리|막내|막상|만남|만두|만세|만약|만일|만점|만족|만화|많이|말기|말씀|말투|맘대로|망원경|매년|매달|매력|매번|매스컴|매일|매장|맥주|먹이|먼저|먼지|멀리|메일|며느리|며칠|면담|멸치|명단|명령|명예|명의|명절|명칭|명함|모금|모니터|모델|모든|모범|모습|모양|모임|모조리|모집|모퉁이|목걸이|목록|목사|목소리|목숨|목적|목표|몰래|몸매|몸무게|몸살|몸속|몸짓|몸통|몹시|무관심|무궁화|무더위|무덤|무릎|무슨|무엇|무역|무용|무조건|무지개|무척|문구|문득|문법|문서|문제|문학|문화|물가|물건|물결|물고기|물론|물리학|물음|물질|물체|미국|미디어|미사일|미술|미역|미용실|미움|미인|미팅|미혼|민간|민족|민주|믿음|밀가루|밀리미터|밑바닥|바가지|바구니|바나나|바늘|바닥|바닷가|바람|바이러스|바탕|박물관|박사|박수|반대|반드시|반말|반발|반성|반응|반장|반죽|반지|반찬|받침|발가락|발걸음|발견|발달|발레|발목|발바닥|발생|발음|발자국|발전|발톱|발표|밤하늘|밥그릇|밥맛|밥상|밥솥|방금|방면|방문|방바닥|방법|방송|방식|방안|방울|방지|방학|방해|방향|배경|배꼽|배달|배드민턴|백두산|백색|백성|백인|백제|백화점|버릇|버섯|버튼|번개|번역|번지|번호|벌금|벌레|벌써|범위|범인|범죄|법률|법원|법적|법칙|베이징|벨트|변경|변동|변명|변신|변호사|변화|별도|별명|별일|병실|병아리|병원|보관|보너스|보라색|보람|보름|보상|보안|보자기|보장|보전|보존|보통|보편적|보험|복도|복사|복숭아|복습|볶음|본격적|본래|본부|본사|본성|본인|본질|볼펜|봉사|봉지|봉투|부근|부끄러움|부담|부동산|부문|부분|부산|부상|부엌|부인|부작용|부장|부정|부족|부지런히|부친|부탁|부품|부회장|북부|북한|분노|분량|분리|분명|분석|분야|분위기|분필|분홍색|불고기|불과|불교|불꽃|불만|불법|불빛|불안|불이익|불행|브랜드|비극|비난|비닐|비둘기|비디오|비로소|비만|비명|비밀|비바람|비빔밥|비상|비용|비율|비중|비타민|비판|빌딩|빗물|빗방울|빗줄기|빛깔|빨간색|빨래|빨리|사건|사계절|사나이|사냥|사람|사랑|사립|사모님|사물|사방|사상|사생활|사설|사슴|사실|사업|사용|사월|사장|사전|사진|사촌|사춘기|사탕|사투리|사흘|산길|산부인과|산업|산책|살림|살인|살짝|삼계탕|삼국|삼십|삼월|삼촌|상관|상금|상대|상류|상반기|상상|상식|상업|상인|상자|상점|상처|상추|상태|상표|상품|상황|새벽|색깔|색연필|생각|생명|생물|생방송|생산|생선|생신|생일|생활|서랍|서른|서명|서민|서비스|서양|서울|서적|서점|서쪽|서클|석사|석유|선거|선물|선배|선생|선수|선원|선장|선전|선택|선풍기|설거지|설날|설렁탕|설명|설문|설사|설악산|설치|설탕|섭씨|성공|성당|성명|성별|성인|성장|성적|성질|성함|세금|세미나|세상|세월|세종대왕|세탁|센터|센티미터|셋째|소규모|소극적|소금|소나기|소년|소득|소망|소문|소설|소속|소아과|소용|소원|소음|소중히|소지품|소질|소풍|소형|속담|속도|속옷|손가락|손길|손녀|손님|손등|손목|손뼉|손실|손질|손톱|손해|솔직히|솜씨|송아지|송이|송편|쇠고기|쇼핑|수건|수년|수단|수돗물|수동적|수면|수명|수박|수상|수석|수술|수시로|수업|수염|수영|수입|수준|수집|수출|수컷|수필|수학|수험생|수화기|숙녀|숙소|숙제|순간|순서|순수|순식간|순위|숟가락|술병|술집|숫자|스님|스물|스스로|스승|스웨터|스위치|스케이트|스튜디오|스트레스|스포츠|슬쩍|슬픔|습관|습기|승객|승리|승부|승용차|승진|시각|시간|시골|시금치|시나리오|시댁|시리즈|시멘트|시민|시부모|시선|시설|시스템|시아버지|시어머니|시월|시인|시일|시작|시장|시절|시점|시중|시즌|시집|시청|시합|시험|식구|식기|식당|식량|식료품|식물|식빵|식사|식생활|식초|식탁|식품|신고|신규|신념|신문|신발|신비|신사|신세|신용|신제품|신청|신체|신화|실감|실내|실력|실례|실망|실수|실습|실시|실장|실정|실질적|실천|실체|실컷|실태|실패|실험|실현|심리|심부름|심사|심장|심정|심판|쌍둥이|씨름|씨앗|아가씨|아나운서|아드님|아들|아쉬움|아스팔트|아시아|아울러|아저씨|아줌마|아직|아침|아파트|아프리카|아픔|아홉|아흔|악기|악몽|악수|안개|안경|안과|안내|안녕|안동|안방|안부|안주|알루미늄|알코올|암시|암컷|압력|앞날|앞문|애인|애정|액수|앨범|야간|야단|야옹|약간|약국|약속|약수|약점|약품|약혼녀|양념|양력|양말|양배추|양주|양파|어둠|어려움|어른|어젯밤|어쨌든|어쩌다가|어쩐지|언니|언덕|언론|언어|얼굴|얼른|얼음|얼핏|엄마|업무|업종|업체|엉덩이|엉망|엉터리|엊그제|에너지|에어컨|엔진|여건|여고생|여관|여군|여권|여대생|여덟|여동생|여든|여론|여름|여섯|여성|여왕|여인|여전히|여직원|여학생|여행|역사|역시|역할|연결|연구|연극|연기|연락|연설|연세|연속|연습|연애|연예인|연인|연장|연주|연출|연필|연합|연휴|열기|열매|열쇠|열심히|열정|열차|열흘|염려|엽서|영국|영남|영상|영양|영역|영웅|영원히|영하|영향|영혼|영화|옆구리|옆방|옆집|예감|예금|예방|예산|예상|예선|예술|예습|예식장|예약|예전|예절|예정|예컨대|옛날|오늘|오락|오랫동안|오렌지|오로지|오른발|오븐|오십|오염|오월|오전|오직|오징어|오페라|오피스텔|오히려|옥상|옥수수|온갖|온라인|온몸|온종일|온통|올가을|올림픽|올해|옷차림|와이셔츠|와인|완성|완전|왕비|왕자|왜냐하면|왠지|외갓집|외국|외로움|외삼촌|외출|외침|외할머니|왼발|왼손|왼쪽|요금|요일|요즘|요청|용기|용서|용어|우산|우선|우승|우연히|우정|우체국|우편|운동|운명|운반|운전|운행|울산|울음|움직임|웃어른|웃음|워낙|원고|원래|원서|원숭이|원인|원장|원피스|월급|월드컵|월세|월요일|웨이터|위반|위법|위성|위원|위험|위협|윗사람|유난히|유럽|유명|유물|유산|유적|유치원|유학|유행|유형|육군|육상|육십|육체|은행|음력|음료|음반|음성|음식|음악|음주|의견|의논|의문|의복|의식|의심|의외로|의욕|의원|의학|이것|이곳|이념|이놈|이달|이대로|이동|이렇게|이력서|이론적|이름|이민|이발소|이별|이불|이빨|이상|이성|이슬|이야기|이용|이웃|이월|이윽고|이익|이전|이중|이튿날|이틀|이혼|인간|인격|인공|인구|인근|인기|인도|인류|인물|인생|인쇄|인연|인원|인재|인종|인천|인체|인터넷|인하|인형|일곱|일기|일단|일대|일등|일반|일본|일부|일상|일생|일손|일요일|일월|일정|일종|일주일|일찍|일체|일치|일행|일회용|임금|임무|입대|입력|입맛|입사|입술|입시|입원|입장|입학|자가용|자격|자극|자동|자랑|자부심|자식|자신|자연|자원|자율|자전거|자정|자존심|자판|작가|작년|작성|작업|작용|작은딸|작품|잔디|잔뜩|잔치|잘못|잠깐|잠수함|잠시|잠옷|잠자리|잡지|장관|장군|장기간|장래|장례|장르|장마|장면|장모|장미|장비|장사|장소|장식|장애인|장인|장점|장차|장학금|재능|재빨리|재산|재생|재작년|재정|재채기|재판|재학|재활용|저것|저고리|저곳|저녁|저런|저렇게|저번|저울|저절로|저축|적극|적당히|적성|적용|적응|전개|전공|전기|전달|전라도|전망|전문|전반|전부|전세|전시|전용|전자|전쟁|전주|전철|전체|전통|전혀|전후|절대|절망|절반|절약|절차|점검|점수|점심|점원|점점|점차|접근|접시|접촉|젓가락|정거장|정도|정류장|정리|정말|정면|정문|정반대|정보|정부|정비|정상|정성|정오|정원|정장|정지|정치|정확히|제공|제과점|제대로|제목|제발|제법|제삿날|제안|제일|제작|제주도|제출|제품|제한|조각|조건|조금|조깅|조명|조미료|조상|조선|조용히|조절|조정|조직|존댓말|존재|졸업|졸음|종교|종로|종류|종소리|종업원|종종|종합|좌석|죄인|주관적|주름|주말|주머니|주먹|주문|주민|주방|주변|주식|주인|주일|주장|주전자|주택|준비|줄거리|줄기|줄무늬|중간|중계방송|중국|중년|중단|중독|중반|중부|중세|중소기업|중순|중앙|중요|중학교|즉석|즉시|즐거움|증가|증거|증권|증상|증세|지각|지갑|지경|지극히|지금|지급|지능|지름길|지리산|지방|지붕|지식|지역|지우개|지원|지적|지점|지진|지출|직선|직업|직원|직장|진급|진동|진로|진료|진리|진짜|진찰|진출|진통|진행|질문|질병|질서|짐작|집단|집안|집중|짜증|찌꺼기|차남|차라리|차량|차림|차별|차선|차츰|착각|찬물|찬성|참가|참기름|참새|참석|참여|참외|참조|찻잔|창가|창고|창구|창문|창밖|창작|창조|채널|채점|책가방|책방|책상|책임|챔피언|처벌|처음|천국|천둥|천장|천재|천천히|철도|철저히|철학|첫날|첫째|청년|청바지|청소|청춘|체계|체력|체온|체육|체중|체험|초등학생|초반|초밥|초상화|초순|초여름|초원|초저녁|초점|초청|초콜릿|촛불|총각|총리|총장|촬영|최근|최상|최선|최신|최악|최종|추석|추억|추진|추천|추측|축구|축소|축제|축하|출근|출발|출산|출신|출연|출입|출장|출판|충격|충고|충돌|충분히|충청도|취업|취직|취향|치약|친구|친척|칠십|칠월|칠판|침대|침묵|침실|칫솔|칭찬|카메라|카운터|칼국수|캐릭터|캠퍼스|캠페인|커튼|컨디션|컬러|컴퓨터|코끼리|코미디|콘서트|콜라|콤플렉스|콩나물|쾌감|쿠데타|크림|큰길|큰딸|큰소리|큰아들|큰어머니|큰일|큰절|클래식|클럽|킬로|타입|타자기|탁구|탁자|탄생|태권도|태양|태풍|택시|탤런트|터널|터미널|테니스|테스트|테이블|텔레비전|토론|토마토|토요일|통계|통과|통로|통신|통역|통일|통장|통제|통증|통합|통화|퇴근|퇴원|퇴직금|튀김|트럭|특급|특별|특성|특수|특징|특히|튼튼히|티셔츠|파란색|파일|파출소|판결|판단|판매|판사|팔십|팔월|팝송|패션|팩스|팩시밀리|팬티|퍼센트|페인트|편견|편의|편지|편히|평가|평균|평생|평소|평양|평일|평화|포스터|포인트|포장|포함|표면|표정|표준|표현|품목|품질|풍경|풍속|풍습|프랑스|프린터|플라스틱|피곤|피망|피아노|필름|필수|필요|필자|필통|핑계|하느님|하늘|하드웨어|하룻밤|하반기|하숙집|하순|하여튼|하지만|하천|하품|하필|학과|학교|학급|학기|학년|학력|학번|학부모|학비|학생|학술|학습|학용품|학원|학위|학자|학점|한계|한글|한꺼번에|한낮|한눈|한동안|한때|한라산|한마디|한문|한번|한복|한식|한여름|한쪽|할머니|할아버지|할인|함께|함부로|합격|합리적|항공|항구|항상|항의|해결|해군|해답|해당|해물|해석|해설|해수욕장|해안|핵심|핸드백|햄버거|햇볕|햇살|행동|행복|행사|행운|행위|향기|향상|향수|허락|허용|헬기|현관|현금|현대|현상|현실|현장|현재|현지|혈액|협력|형부|형사|형수|형식|형제|형태|형편|혜택|호기심|호남|호랑이|호박|호텔|호흡|혹시|홀로|홈페이지|홍보|홍수|홍차|화면|화분|화살|화요일|화장|화학|확보|확인|확장|확정|환갑|환경|환영|환율|환자|활기|활동|활발히|활용|활짝|회견|회관|회복|회색|회원|회장|회전|횟수|횡단보도|효율적|후반|후춧가루|훈련|훨씬|휴식|휴일|흉내|흐름|흑백|흑인|흔적|흔히|흥미|흥분|희곡|희망|희생|흰색|힘껏'.split('|'); diff --git a/packages/util-crypto/mnemonic/wordlists/zh-s.d.ts b/packages/util-crypto/mnemonic/wordlists/zh-s.d.ts new file mode 100644 index 0000000..d451d2b --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/zh-s.d.ts @@ -0,0 +1,2 @@ +declare const _default: string[]; +export default _default; diff --git a/packages/util-crypto/mnemonic/wordlists/zh-s.js b/packages/util-crypto/mnemonic/wordlists/zh-s.js new file mode 100644 index 0000000..2428ad9 --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/zh-s.js @@ -0,0 +1 @@ +export default '的|一|是|在|不|了|有|和|人|这|中|大|为|上|个|国|我|以|要|他|时|来|用|们|生|到|作|地|于|出|就|分|对|成|会|可|主|发|年|动|同|工|也|能|下|过|子|说|产|种|面|而|方|后|多|定|行|学|法|所|民|得|经|十|三|之|进|着|等|部|度|家|电|力|里|如|水|化|高|自|二|理|起|小|物|现|实|加|量|都|两|体|制|机|当|使|点|从|业|本|去|把|性|好|应|开|它|合|还|因|由|其|些|然|前|外|天|政|四|日|那|社|义|事|平|形|相|全|表|间|样|与|关|各|重|新|线|内|数|正|心|反|你|明|看|原|又|么|利|比|或|但|质|气|第|向|道|命|此|变|条|只|没|结|解|问|意|建|月|公|无|系|军|很|情|者|最|立|代|想|已|通|并|提|直|题|党|程|展|五|果|料|象|员|革|位|入|常|文|总|次|品|式|活|设|及|管|特|件|长|求|老|头|基|资|边|流|路|级|少|图|山|统|接|知|较|将|组|见|计|别|她|手|角|期|根|论|运|农|指|几|九|区|强|放|决|西|被|干|做|必|战|先|回|则|任|取|据|处|队|南|给|色|光|门|即|保|治|北|造|百|规|热|领|七|海|口|东|导|器|压|志|世|金|增|争|济|阶|油|思|术|极|交|受|联|什|认|六|共|权|收|证|改|清|美|再|采|转|更|单|风|切|打|白|教|速|花|带|安|场|身|车|例|真|务|具|万|每|目|至|达|走|积|示|议|声|报|斗|完|类|八|离|华|名|确|才|科|张|信|马|节|话|米|整|空|元|况|今|集|温|传|土|许|步|群|广|石|记|需|段|研|界|拉|林|律|叫|且|究|观|越|织|装|影|算|低|持|音|众|书|布|复|容|儿|须|际|商|非|验|连|断|深|难|近|矿|千|周|委|素|技|备|半|办|青|省|列|习|响|约|支|般|史|感|劳|便|团|往|酸|历|市|克|何|除|消|构|府|称|太|准|精|值|号|率|族|维|划|选|标|写|存|候|毛|亲|快|效|斯|院|查|江|型|眼|王|按|格|养|易|置|派|层|片|始|却|专|状|育|厂|京|识|适|属|圆|包|火|住|调|满|县|局|照|参|红|细|引|听|该|铁|价|严|首|底|液|官|德|随|病|苏|失|尔|死|讲|配|女|黄|推|显|谈|罪|神|艺|呢|席|含|企|望|密|批|营|项|防|举|球|英|氧|势|告|李|台|落|木|帮|轮|破|亚|师|围|注|远|字|材|排|供|河|态|封|另|施|减|树|溶|怎|止|案|言|士|均|武|固|叶|鱼|波|视|仅|费|紧|爱|左|章|早|朝|害|续|轻|服|试|食|充|兵|源|判|护|司|足|某|练|差|致|板|田|降|黑|犯|负|击|范|继|兴|似|余|坚|曲|输|修|故|城|夫|够|送|笔|船|占|右|财|吃|富|春|职|觉|汉|画|功|巴|跟|虽|杂|飞|检|吸|助|升|阳|互|初|创|抗|考|投|坏|策|古|径|换|未|跑|留|钢|曾|端|责|站|简|述|钱|副|尽|帝|射|草|冲|承|独|令|限|阿|宣|环|双|请|超|微|让|控|州|良|轴|找|否|纪|益|依|优|顶|础|载|倒|房|突|坐|粉|敌|略|客|袁|冷|胜|绝|析|块|剂|测|丝|协|诉|念|陈|仍|罗|盐|友|洋|错|苦|夜|刑|移|频|逐|靠|混|母|短|皮|终|聚|汽|村|云|哪|既|距|卫|停|烈|央|察|烧|迅|境|若|印|洲|刻|括|激|孔|搞|甚|室|待|核|校|散|侵|吧|甲|游|久|菜|味|旧|模|湖|货|损|预|阻|毫|普|稳|乙|妈|植|息|扩|银|语|挥|酒|守|拿|序|纸|医|缺|雨|吗|针|刘|啊|急|唱|误|训|愿|审|附|获|茶|鲜|粮|斤|孩|脱|硫|肥|善|龙|演|父|渐|血|欢|械|掌|歌|沙|刚|攻|谓|盾|讨|晚|粒|乱|燃|矛|乎|杀|药|宁|鲁|贵|钟|煤|读|班|伯|香|介|迫|句|丰|培|握|兰|担|弦|蛋|沉|假|穿|执|答|乐|谁|顺|烟|缩|征|脸|喜|松|脚|困|异|免|背|星|福|买|染|井|概|慢|怕|磁|倍|祖|皇|促|静|补|评|翻|肉|践|尼|衣|宽|扬|棉|希|伤|操|垂|秋|宜|氢|套|督|振|架|亮|末|宪|庆|编|牛|触|映|雷|销|诗|座|居|抓|裂|胞|呼|娘|景|威|绿|晶|厚|盟|衡|鸡|孙|延|危|胶|屋|乡|临|陆|顾|掉|呀|灯|岁|措|束|耐|剧|玉|赵|跳|哥|季|课|凯|胡|额|款|绍|卷|齐|伟|蒸|殖|永|宗|苗|川|炉|岩|弱|零|杨|奏|沿|露|杆|探|滑|镇|饭|浓|航|怀|赶|库|夺|伊|灵|税|途|灭|赛|归|召|鼓|播|盘|裁|险|康|唯|录|菌|纯|借|糖|盖|横|符|私|努|堂|域|枪|润|幅|哈|竟|熟|虫|泽|脑|壤|碳|欧|遍|侧|寨|敢|彻|虑|斜|薄|庭|纳|弹|饲|伸|折|麦|湿|暗|荷|瓦|塞|床|筑|恶|户|访|塔|奇|透|梁|刀|旋|迹|卡|氯|遇|份|毒|泥|退|洗|摆|灰|彩|卖|耗|夏|择|忙|铜|献|硬|予|繁|圈|雪|函|亦|抽|篇|阵|阴|丁|尺|追|堆|雄|迎|泛|爸|楼|避|谋|吨|野|猪|旗|累|偏|典|馆|索|秦|脂|潮|爷|豆|忽|托|惊|塑|遗|愈|朱|替|纤|粗|倾|尚|痛|楚|谢|奋|购|磨|君|池|旁|碎|骨|监|捕|弟|暴|割|贯|殊|释|词|亡|壁|顿|宝|午|尘|闻|揭|炮|残|冬|桥|妇|警|综|招|吴|付|浮|遭|徐|您|摇|谷|赞|箱|隔|订|男|吹|园|纷|唐|败|宋|玻|巨|耕|坦|荣|闭|湾|键|凡|驻|锅|救|恩|剥|凝|碱|齿|截|炼|麻|纺|禁|废|盛|版|缓|净|睛|昌|婚|涉|筒|嘴|插|岸|朗|庄|街|藏|姑|贸|腐|奴|啦|惯|乘|伙|恢|匀|纱|扎|辩|耳|彪|臣|亿|璃|抵|脉|秀|萨|俄|网|舞|店|喷|纵|寸|汗|挂|洪|贺|闪|柬|爆|烯|津|稻|墙|软|勇|像|滚|厘|蒙|芳|肯|坡|柱|荡|腿|仪|旅|尾|轧|冰|贡|登|黎|削|钻|勒|逃|障|氨|郭|峰|币|港|伏|轨|亩|毕|擦|莫|刺|浪|秘|援|株|健|售|股|岛|甘|泡|睡|童|铸|汤|阀|休|汇|舍|牧|绕|炸|哲|磷|绩|朋|淡|尖|启|陷|柴|呈|徒|颜|泪|稍|忘|泵|蓝|拖|洞|授|镜|辛|壮|锋|贫|虚|弯|摩|泰|幼|廷|尊|窗|纲|弄|隶|疑|氏|宫|姐|震|瑞|怪|尤|琴|循|描|膜|违|夹|腰|缘|珠|穷|森|枝|竹|沟|催|绳|忆|邦|剩|幸|浆|栏|拥|牙|贮|礼|滤|钠|纹|罢|拍|咱|喊|袖|埃|勤|罚|焦|潜|伍|墨|欲|缝|姓|刊|饱|仿|奖|铝|鬼|丽|跨|默|挖|链|扫|喝|袋|炭|污|幕|诸|弧|励|梅|奶|洁|灾|舟|鉴|苯|讼|抱|毁|懂|寒|智|埔|寄|届|跃|渡|挑|丹|艰|贝|碰|拔|爹|戴|码|梦|芽|熔|赤|渔|哭|敬|颗|奔|铅|仲|虎|稀|妹|乏|珍|申|桌|遵|允|隆|螺|仓|魏|锐|晓|氮|兼|隐|碍|赫|拨|忠|肃|缸|牵|抢|博|巧|壳|兄|杜|讯|诚|碧|祥|柯|页|巡|矩|悲|灌|龄|伦|票|寻|桂|铺|圣|恐|恰|郑|趣|抬|荒|腾|贴|柔|滴|猛|阔|辆|妻|填|撤|储|签|闹|扰|紫|砂|递|戏|吊|陶|伐|喂|疗|瓶|婆|抚|臂|摸|忍|虾|蜡|邻|胸|巩|挤|偶|弃|槽|劲|乳|邓|吉|仁|烂|砖|租|乌|舰|伴|瓜|浅|丙|暂|燥|橡|柳|迷|暖|牌|秧|胆|详|簧|踏|瓷|谱|呆|宾|糊|洛|辉|愤|竞|隙|怒|粘|乃|绪|肩|籍|敏|涂|熙|皆|侦|悬|掘|享|纠|醒|狂|锁|淀|恨|牲|霸|爬|赏|逆|玩|陵|祝|秒|浙|貌|役|彼|悉|鸭|趋|凤|晨|畜|辈|秩|卵|署|梯|炎|滩|棋|驱|筛|峡|冒|啥|寿|译|浸|泉|帽|迟|硅|疆|贷|漏|稿|冠|嫩|胁|芯|牢|叛|蚀|奥|鸣|岭|羊|凭|串|塘|绘|酵|融|盆|锡|庙|筹|冻|辅|摄|袭|筋|拒|僚|旱|钾|鸟|漆|沈|眉|疏|添|棒|穗|硝|韩|逼|扭|侨|凉|挺|碗|栽|炒|杯|患|馏|劝|豪|辽|勃|鸿|旦|吏|拜|狗|埋|辊|掩|饮|搬|骂|辞|勾|扣|估|蒋|绒|雾|丈|朵|姆|拟|宇|辑|陕|雕|偿|蓄|崇|剪|倡|厅|咬|驶|薯|刷|斥|番|赋|奉|佛|浇|漫|曼|扇|钙|桃|扶|仔|返|俗|亏|腔|鞋|棱|覆|框|悄|叔|撞|骗|勘|旺|沸|孤|吐|孟|渠|屈|疾|妙|惜|仰|狠|胀|谐|抛|霉|桑|岗|嘛|衰|盗|渗|脏|赖|涌|甜|曹|阅|肌|哩|厉|烃|纬|毅|昨|伪|症|煮|叹|钉|搭|茎|笼|酷|偷|弓|锥|恒|杰|坑|鼻|翼|纶|叙|狱|逮|罐|络|棚|抑|膨|蔬|寺|骤|穆|冶|枯|册|尸|凸|绅|坯|牺|焰|轰|欣|晋|瘦|御|锭|锦|丧|旬|锻|垄|搜|扑|邀|亭|酯|迈|舒|脆|酶|闲|忧|酚|顽|羽|涨|卸|仗|陪|辟|惩|杭|姚|肚|捉|飘|漂|昆|欺|吾|郎|烷|汁|呵|饰|萧|雅|邮|迁|燕|撒|姻|赴|宴|烦|债|帐|斑|铃|旨|醇|董|饼|雏|姿|拌|傅|腹|妥|揉|贤|拆|歪|葡|胺|丢|浩|徽|昂|垫|挡|览|贪|慰|缴|汪|慌|冯|诺|姜|谊|凶|劣|诬|耀|昏|躺|盈|骑|乔|溪|丛|卢|抹|闷|咨|刮|驾|缆|悟|摘|铒|掷|颇|幻|柄|惠|惨|佳|仇|腊|窝|涤|剑|瞧|堡|泼|葱|罩|霍|捞|胎|苍|滨|俩|捅|湘|砍|霞|邵|萄|疯|淮|遂|熊|粪|烘|宿|档|戈|驳|嫂|裕|徙|箭|捐|肠|撑|晒|辨|殿|莲|摊|搅|酱|屏|疫|哀|蔡|堵|沫|皱|畅|叠|阁|莱|敲|辖|钩|痕|坝|巷|饿|祸|丘|玄|溜|曰|逻|彭|尝|卿|妨|艇|吞|韦|怨|矮|歇'.split('|'); diff --git a/packages/util-crypto/mnemonic/wordlists/zh-t.d.ts b/packages/util-crypto/mnemonic/wordlists/zh-t.d.ts new file mode 100644 index 0000000..d451d2b --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/zh-t.d.ts @@ -0,0 +1,2 @@ +declare const _default: string[]; +export default _default; diff --git a/packages/util-crypto/mnemonic/wordlists/zh-t.js b/packages/util-crypto/mnemonic/wordlists/zh-t.js new file mode 100644 index 0000000..9ab5398 --- /dev/null +++ b/packages/util-crypto/mnemonic/wordlists/zh-t.js @@ -0,0 +1 @@ +export default '的|一|是|在|不|了|有|和|人|這|中|大|為|上|個|國|我|以|要|他|時|來|用|們|生|到|作|地|於|出|就|分|對|成|會|可|主|發|年|動|同|工|也|能|下|過|子|說|產|種|面|而|方|後|多|定|行|學|法|所|民|得|經|十|三|之|進|著|等|部|度|家|電|力|裡|如|水|化|高|自|二|理|起|小|物|現|實|加|量|都|兩|體|制|機|當|使|點|從|業|本|去|把|性|好|應|開|它|合|還|因|由|其|些|然|前|外|天|政|四|日|那|社|義|事|平|形|相|全|表|間|樣|與|關|各|重|新|線|內|數|正|心|反|你|明|看|原|又|麼|利|比|或|但|質|氣|第|向|道|命|此|變|條|只|沒|結|解|問|意|建|月|公|無|系|軍|很|情|者|最|立|代|想|已|通|並|提|直|題|黨|程|展|五|果|料|象|員|革|位|入|常|文|總|次|品|式|活|設|及|管|特|件|長|求|老|頭|基|資|邊|流|路|級|少|圖|山|統|接|知|較|將|組|見|計|別|她|手|角|期|根|論|運|農|指|幾|九|區|強|放|決|西|被|幹|做|必|戰|先|回|則|任|取|據|處|隊|南|給|色|光|門|即|保|治|北|造|百|規|熱|領|七|海|口|東|導|器|壓|志|世|金|增|爭|濟|階|油|思|術|極|交|受|聯|什|認|六|共|權|收|證|改|清|美|再|採|轉|更|單|風|切|打|白|教|速|花|帶|安|場|身|車|例|真|務|具|萬|每|目|至|達|走|積|示|議|聲|報|鬥|完|類|八|離|華|名|確|才|科|張|信|馬|節|話|米|整|空|元|況|今|集|溫|傳|土|許|步|群|廣|石|記|需|段|研|界|拉|林|律|叫|且|究|觀|越|織|裝|影|算|低|持|音|眾|書|布|复|容|兒|須|際|商|非|驗|連|斷|深|難|近|礦|千|週|委|素|技|備|半|辦|青|省|列|習|響|約|支|般|史|感|勞|便|團|往|酸|歷|市|克|何|除|消|構|府|稱|太|準|精|值|號|率|族|維|劃|選|標|寫|存|候|毛|親|快|效|斯|院|查|江|型|眼|王|按|格|養|易|置|派|層|片|始|卻|專|狀|育|廠|京|識|適|屬|圓|包|火|住|調|滿|縣|局|照|參|紅|細|引|聽|該|鐵|價|嚴|首|底|液|官|德|隨|病|蘇|失|爾|死|講|配|女|黃|推|顯|談|罪|神|藝|呢|席|含|企|望|密|批|營|項|防|舉|球|英|氧|勢|告|李|台|落|木|幫|輪|破|亞|師|圍|注|遠|字|材|排|供|河|態|封|另|施|減|樹|溶|怎|止|案|言|士|均|武|固|葉|魚|波|視|僅|費|緊|愛|左|章|早|朝|害|續|輕|服|試|食|充|兵|源|判|護|司|足|某|練|差|致|板|田|降|黑|犯|負|擊|范|繼|興|似|餘|堅|曲|輸|修|故|城|夫|夠|送|筆|船|佔|右|財|吃|富|春|職|覺|漢|畫|功|巴|跟|雖|雜|飛|檢|吸|助|昇|陽|互|初|創|抗|考|投|壞|策|古|徑|換|未|跑|留|鋼|曾|端|責|站|簡|述|錢|副|盡|帝|射|草|衝|承|獨|令|限|阿|宣|環|雙|請|超|微|讓|控|州|良|軸|找|否|紀|益|依|優|頂|礎|載|倒|房|突|坐|粉|敵|略|客|袁|冷|勝|絕|析|塊|劑|測|絲|協|訴|念|陳|仍|羅|鹽|友|洋|錯|苦|夜|刑|移|頻|逐|靠|混|母|短|皮|終|聚|汽|村|雲|哪|既|距|衛|停|烈|央|察|燒|迅|境|若|印|洲|刻|括|激|孔|搞|甚|室|待|核|校|散|侵|吧|甲|遊|久|菜|味|舊|模|湖|貨|損|預|阻|毫|普|穩|乙|媽|植|息|擴|銀|語|揮|酒|守|拿|序|紙|醫|缺|雨|嗎|針|劉|啊|急|唱|誤|訓|願|審|附|獲|茶|鮮|糧|斤|孩|脫|硫|肥|善|龍|演|父|漸|血|歡|械|掌|歌|沙|剛|攻|謂|盾|討|晚|粒|亂|燃|矛|乎|殺|藥|寧|魯|貴|鐘|煤|讀|班|伯|香|介|迫|句|豐|培|握|蘭|擔|弦|蛋|沉|假|穿|執|答|樂|誰|順|煙|縮|徵|臉|喜|松|腳|困|異|免|背|星|福|買|染|井|概|慢|怕|磁|倍|祖|皇|促|靜|補|評|翻|肉|踐|尼|衣|寬|揚|棉|希|傷|操|垂|秋|宜|氫|套|督|振|架|亮|末|憲|慶|編|牛|觸|映|雷|銷|詩|座|居|抓|裂|胞|呼|娘|景|威|綠|晶|厚|盟|衡|雞|孫|延|危|膠|屋|鄉|臨|陸|顧|掉|呀|燈|歲|措|束|耐|劇|玉|趙|跳|哥|季|課|凱|胡|額|款|紹|卷|齊|偉|蒸|殖|永|宗|苗|川|爐|岩|弱|零|楊|奏|沿|露|桿|探|滑|鎮|飯|濃|航|懷|趕|庫|奪|伊|靈|稅|途|滅|賽|歸|召|鼓|播|盤|裁|險|康|唯|錄|菌|純|借|糖|蓋|橫|符|私|努|堂|域|槍|潤|幅|哈|竟|熟|蟲|澤|腦|壤|碳|歐|遍|側|寨|敢|徹|慮|斜|薄|庭|納|彈|飼|伸|折|麥|濕|暗|荷|瓦|塞|床|築|惡|戶|訪|塔|奇|透|梁|刀|旋|跡|卡|氯|遇|份|毒|泥|退|洗|擺|灰|彩|賣|耗|夏|擇|忙|銅|獻|硬|予|繁|圈|雪|函|亦|抽|篇|陣|陰|丁|尺|追|堆|雄|迎|泛|爸|樓|避|謀|噸|野|豬|旗|累|偏|典|館|索|秦|脂|潮|爺|豆|忽|托|驚|塑|遺|愈|朱|替|纖|粗|傾|尚|痛|楚|謝|奮|購|磨|君|池|旁|碎|骨|監|捕|弟|暴|割|貫|殊|釋|詞|亡|壁|頓|寶|午|塵|聞|揭|炮|殘|冬|橋|婦|警|綜|招|吳|付|浮|遭|徐|您|搖|谷|贊|箱|隔|訂|男|吹|園|紛|唐|敗|宋|玻|巨|耕|坦|榮|閉|灣|鍵|凡|駐|鍋|救|恩|剝|凝|鹼|齒|截|煉|麻|紡|禁|廢|盛|版|緩|淨|睛|昌|婚|涉|筒|嘴|插|岸|朗|莊|街|藏|姑|貿|腐|奴|啦|慣|乘|夥|恢|勻|紗|扎|辯|耳|彪|臣|億|璃|抵|脈|秀|薩|俄|網|舞|店|噴|縱|寸|汗|掛|洪|賀|閃|柬|爆|烯|津|稻|牆|軟|勇|像|滾|厘|蒙|芳|肯|坡|柱|盪|腿|儀|旅|尾|軋|冰|貢|登|黎|削|鑽|勒|逃|障|氨|郭|峰|幣|港|伏|軌|畝|畢|擦|莫|刺|浪|秘|援|株|健|售|股|島|甘|泡|睡|童|鑄|湯|閥|休|匯|舍|牧|繞|炸|哲|磷|績|朋|淡|尖|啟|陷|柴|呈|徒|顏|淚|稍|忘|泵|藍|拖|洞|授|鏡|辛|壯|鋒|貧|虛|彎|摩|泰|幼|廷|尊|窗|綱|弄|隸|疑|氏|宮|姐|震|瑞|怪|尤|琴|循|描|膜|違|夾|腰|緣|珠|窮|森|枝|竹|溝|催|繩|憶|邦|剩|幸|漿|欄|擁|牙|貯|禮|濾|鈉|紋|罷|拍|咱|喊|袖|埃|勤|罰|焦|潛|伍|墨|欲|縫|姓|刊|飽|仿|獎|鋁|鬼|麗|跨|默|挖|鏈|掃|喝|袋|炭|污|幕|諸|弧|勵|梅|奶|潔|災|舟|鑑|苯|訟|抱|毀|懂|寒|智|埔|寄|屆|躍|渡|挑|丹|艱|貝|碰|拔|爹|戴|碼|夢|芽|熔|赤|漁|哭|敬|顆|奔|鉛|仲|虎|稀|妹|乏|珍|申|桌|遵|允|隆|螺|倉|魏|銳|曉|氮|兼|隱|礙|赫|撥|忠|肅|缸|牽|搶|博|巧|殼|兄|杜|訊|誠|碧|祥|柯|頁|巡|矩|悲|灌|齡|倫|票|尋|桂|鋪|聖|恐|恰|鄭|趣|抬|荒|騰|貼|柔|滴|猛|闊|輛|妻|填|撤|儲|簽|鬧|擾|紫|砂|遞|戲|吊|陶|伐|餵|療|瓶|婆|撫|臂|摸|忍|蝦|蠟|鄰|胸|鞏|擠|偶|棄|槽|勁|乳|鄧|吉|仁|爛|磚|租|烏|艦|伴|瓜|淺|丙|暫|燥|橡|柳|迷|暖|牌|秧|膽|詳|簧|踏|瓷|譜|呆|賓|糊|洛|輝|憤|競|隙|怒|粘|乃|緒|肩|籍|敏|塗|熙|皆|偵|懸|掘|享|糾|醒|狂|鎖|淀|恨|牲|霸|爬|賞|逆|玩|陵|祝|秒|浙|貌|役|彼|悉|鴨|趨|鳳|晨|畜|輩|秩|卵|署|梯|炎|灘|棋|驅|篩|峽|冒|啥|壽|譯|浸|泉|帽|遲|矽|疆|貸|漏|稿|冠|嫩|脅|芯|牢|叛|蝕|奧|鳴|嶺|羊|憑|串|塘|繪|酵|融|盆|錫|廟|籌|凍|輔|攝|襲|筋|拒|僚|旱|鉀|鳥|漆|沈|眉|疏|添|棒|穗|硝|韓|逼|扭|僑|涼|挺|碗|栽|炒|杯|患|餾|勸|豪|遼|勃|鴻|旦|吏|拜|狗|埋|輥|掩|飲|搬|罵|辭|勾|扣|估|蔣|絨|霧|丈|朵|姆|擬|宇|輯|陝|雕|償|蓄|崇|剪|倡|廳|咬|駛|薯|刷|斥|番|賦|奉|佛|澆|漫|曼|扇|鈣|桃|扶|仔|返|俗|虧|腔|鞋|棱|覆|框|悄|叔|撞|騙|勘|旺|沸|孤|吐|孟|渠|屈|疾|妙|惜|仰|狠|脹|諧|拋|黴|桑|崗|嘛|衰|盜|滲|臟|賴|湧|甜|曹|閱|肌|哩|厲|烴|緯|毅|昨|偽|症|煮|嘆|釘|搭|莖|籠|酷|偷|弓|錐|恆|傑|坑|鼻|翼|綸|敘|獄|逮|罐|絡|棚|抑|膨|蔬|寺|驟|穆|冶|枯|冊|屍|凸|紳|坯|犧|焰|轟|欣|晉|瘦|禦|錠|錦|喪|旬|鍛|壟|搜|撲|邀|亭|酯|邁|舒|脆|酶|閒|憂|酚|頑|羽|漲|卸|仗|陪|闢|懲|杭|姚|肚|捉|飄|漂|昆|欺|吾|郎|烷|汁|呵|飾|蕭|雅|郵|遷|燕|撒|姻|赴|宴|煩|債|帳|斑|鈴|旨|醇|董|餅|雛|姿|拌|傅|腹|妥|揉|賢|拆|歪|葡|胺|丟|浩|徽|昂|墊|擋|覽|貪|慰|繳|汪|慌|馮|諾|姜|誼|兇|劣|誣|耀|昏|躺|盈|騎|喬|溪|叢|盧|抹|悶|諮|刮|駕|纜|悟|摘|鉺|擲|頗|幻|柄|惠|慘|佳|仇|臘|窩|滌|劍|瞧|堡|潑|蔥|罩|霍|撈|胎|蒼|濱|倆|捅|湘|砍|霞|邵|萄|瘋|淮|遂|熊|糞|烘|宿|檔|戈|駁|嫂|裕|徙|箭|捐|腸|撐|曬|辨|殿|蓮|攤|攪|醬|屏|疫|哀|蔡|堵|沫|皺|暢|疊|閣|萊|敲|轄|鉤|痕|壩|巷|餓|禍|丘|玄|溜|曰|邏|彭|嘗|卿|妨|艇|吞|韋|怨|矮|歇'.split('|'); diff --git a/packages/util-crypto/nacl/decrypt.d.ts b/packages/util-crypto/nacl/decrypt.d.ts new file mode 100644 index 0000000..51e2faf --- /dev/null +++ b/packages/util-crypto/nacl/decrypt.d.ts @@ -0,0 +1,15 @@ +/** + * @name naclDecrypt + * @summary Decrypts a message using the supplied secretKey and nonce + * @description + * Returns an decrypted message, using the `secret` and `nonce`. + * @example + *
+ * + * ```javascript + * import { naclDecrypt } from '@pezkuwi/util-crypto'; + * + * naclDecrypt([...], [...], [...]); // => [...] + * ``` + */ +export declare function naclDecrypt(encrypted: Uint8Array, nonce: Uint8Array, secret: Uint8Array): Uint8Array | null; diff --git a/packages/util-crypto/nacl/decrypt.js b/packages/util-crypto/nacl/decrypt.js new file mode 100644 index 0000000..6ffc419 --- /dev/null +++ b/packages/util-crypto/nacl/decrypt.js @@ -0,0 +1,18 @@ +import { naclSecretboxOpen } from './tweetnacl.js'; +/** + * @name naclDecrypt + * @summary Decrypts a message using the supplied secretKey and nonce + * @description + * Returns an decrypted message, using the `secret` and `nonce`. + * @example + *
+ * + * ```javascript + * import { naclDecrypt } from '@pezkuwi/util-crypto'; + * + * naclDecrypt([...], [...], [...]); // => [...] + * ``` + */ +export function naclDecrypt(encrypted, nonce, secret) { + return naclSecretboxOpen(encrypted, nonce, secret); +} diff --git a/packages/util-crypto/nacl/encrypt.d.ts b/packages/util-crypto/nacl/encrypt.d.ts new file mode 100644 index 0000000..f38f701 --- /dev/null +++ b/packages/util-crypto/nacl/encrypt.d.ts @@ -0,0 +1,20 @@ +interface Encrypted { + encrypted: Uint8Array; + nonce: Uint8Array; +} +/** + * @name naclEncrypt + * @summary Encrypts a message using the supplied secretKey and nonce + * @description + * Returns an encrypted message, using the `secretKey` and `nonce`. If the `nonce` was not supplied, a random value is generated. + * @example + *
+ * + * ```javascript + * import { naclEncrypt } from '@pezkuwi/util-crypto'; + * + * naclEncrypt([...], [...]); // => [...] + * ``` + */ +export declare function naclEncrypt(message: Uint8Array, secret: Uint8Array, nonce?: Uint8Array): Encrypted; +export {}; diff --git a/packages/util-crypto/nacl/encrypt.js b/packages/util-crypto/nacl/encrypt.js new file mode 100644 index 0000000..84ca1e0 --- /dev/null +++ b/packages/util-crypto/nacl/encrypt.js @@ -0,0 +1,22 @@ +import { randomAsU8a } from '../random/asU8a.js'; +import { naclSecretbox } from './tweetnacl.js'; +/** + * @name naclEncrypt + * @summary Encrypts a message using the supplied secretKey and nonce + * @description + * Returns an encrypted message, using the `secretKey` and `nonce`. If the `nonce` was not supplied, a random value is generated. + * @example + *
+ * + * ```javascript + * import { naclEncrypt } from '@pezkuwi/util-crypto'; + * + * naclEncrypt([...], [...]); // => [...] + * ``` + */ +export function naclEncrypt(message, secret, nonce = randomAsU8a(24)) { + return { + encrypted: naclSecretbox(message, nonce, secret), + nonce + }; +} diff --git a/packages/util-crypto/nacl/index.d.ts b/packages/util-crypto/nacl/index.d.ts new file mode 100644 index 0000000..4aaa899 --- /dev/null +++ b/packages/util-crypto/nacl/index.d.ts @@ -0,0 +1,5 @@ +/** + * @summary Implements [NaCl](http://nacl.cr.yp.to/) secret-key authenticated encryption, public-key authenticated encryption + */ +export { naclDecrypt } from './decrypt.js'; +export { naclEncrypt } from './encrypt.js'; diff --git a/packages/util-crypto/nacl/index.js b/packages/util-crypto/nacl/index.js new file mode 100644 index 0000000..4aaa899 --- /dev/null +++ b/packages/util-crypto/nacl/index.js @@ -0,0 +1,5 @@ +/** + * @summary Implements [NaCl](http://nacl.cr.yp.to/) secret-key authenticated encryption, public-key authenticated encryption + */ +export { naclDecrypt } from './decrypt.js'; +export { naclEncrypt } from './encrypt.js'; diff --git a/packages/util-crypto/nacl/tweetnacl.d.ts b/packages/util-crypto/nacl/tweetnacl.d.ts new file mode 100644 index 0000000..91752b3 --- /dev/null +++ b/packages/util-crypto/nacl/tweetnacl.d.ts @@ -0,0 +1,2 @@ +export declare function naclSecretbox(msg: Uint8Array, nonce: Uint8Array, key: Uint8Array): Uint8Array; +export declare function naclSecretboxOpen(box: Uint8Array, nonce: Uint8Array, key: Uint8Array): Uint8Array | null; diff --git a/packages/util-crypto/nacl/tweetnacl.js b/packages/util-crypto/nacl/tweetnacl.js new file mode 100644 index 0000000..1f48844 --- /dev/null +++ b/packages/util-crypto/nacl/tweetnacl.js @@ -0,0 +1,234 @@ +/* eslint-disable brace-style,camelcase,comma-spacing,curly,one-var,padding-line-between-statements,space-infix-ops */ +function L32(x, c) { return (x << c) | (x >>> (32 - c)); } +function ld32(x, i) { + let u = x[i + 3] & 0xff; + u = (u << 8) | (x[i + 2] & 0xff); + u = (u << 8) | (x[i + 1] & 0xff); + return (u << 8) | (x[i + 0] & 0xff); +} +function st32(x, j, u) { + for (let i = 0; i < 4; i++) { + x[j + i] = u & 255; + u >>>= 8; + } +} +function vn(x, xi, y, yi, n) { + let d = 0; + for (let i = 0; i < n; i++) + d |= x[xi + i] ^ y[yi + i]; + return (1 & ((d - 1) >>> 8)) - 1; +} +function core(out, inp, k, c, h) { + const w = new Uint32Array(16), x = new Uint32Array(16), y = new Uint32Array(16), t = new Uint32Array(4); + let i, j, m; + for (i = 0; i < 4; i++) { + x[5 * i] = ld32(c, 4 * i); + x[1 + i] = ld32(k, 4 * i); + x[6 + i] = ld32(inp, 4 * i); + x[11 + i] = ld32(k, 16 + 4 * i); + } + for (i = 0; i < 16; i++) + y[i] = x[i]; + for (i = 0; i < 20; i++) { + for (j = 0; j < 4; j++) { + for (m = 0; m < 4; m++) + t[m] = x[(5 * j + 4 * m) % 16]; + t[1] ^= L32((t[0] + t[3]) | 0, 7); + t[2] ^= L32((t[1] + t[0]) | 0, 9); + t[3] ^= L32((t[2] + t[1]) | 0, 13); + t[0] ^= L32((t[3] + t[2]) | 0, 18); + for (m = 0; m < 4; m++) + w[4 * j + (j + m) % 4] = t[m]; + } + for (m = 0; m < 16; m++) + x[m] = w[m]; + } + if (h) { + for (i = 0; i < 16; i++) + x[i] = (x[i] + y[i]) | 0; + for (i = 0; i < 4; i++) { + x[5 * i] = (x[5 * i] - ld32(c, 4 * i)) | 0; + x[6 + i] = (x[6 + i] - ld32(inp, 4 * i)) | 0; + } + for (i = 0; i < 4; i++) { + st32(out, 4 * i, x[5 * i]); + st32(out, 16 + 4 * i, x[6 + i]); + } + } + else { + for (i = 0; i < 16; i++) + st32(out, 4 * i, (x[i] + y[i]) | 0); + } +} +const sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]); +function crypto_stream_salsa20_xor(c, cpos, m, mpos, b, n, k) { + const z = new Uint8Array(16), x = new Uint8Array(64); + let u, i; + if (!b) + return 0; + for (i = 0; i < 16; i++) + z[i] = 0; + for (i = 0; i < 8; i++) + z[i] = n[i]; + while (b >= 64) { + core(x, z, k, sigma, false); + for (i = 0; i < 64; i++) + c[cpos + i] = (m ? m[mpos + i] : 0) ^ x[i]; + u = 1; + for (i = 8; i < 16; i++) { + u = u + (z[i] & 0xff) | 0; + z[i] = u & 0xff; + u >>>= 8; + } + b -= 64; + cpos += 64; + if (m) + mpos += 64; + } + if (b > 0) { + core(x, z, k, sigma, false); + for (i = 0; i < b; i++) + c[cpos + i] = (m ? m[mpos + i] : 0) ^ x[i]; + } + return 0; +} +function crypto_stream_xor(c, cpos, m, mpos, d, n, k) { + const s = new Uint8Array(32); + core(s, n, k, sigma, true); + return crypto_stream_salsa20_xor(c, cpos, m, mpos, d, n.subarray(16), s); +} +function add1305(h, c) { + let u = 0; + for (let j = 0; j < 17; j++) { + u = (u + ((h[j] + c[j]) | 0)) | 0; + h[j] = u & 255; + u >>>= 8; + } +} +const minusp = new Uint32Array([5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252]); +function crypto_onetimeauth(out, outpos, m, mpos, n, k) { + let i, j, u; + const x = new Uint32Array(17), r = new Uint32Array(17), h = new Uint32Array(17), c = new Uint32Array(17), g = new Uint32Array(17); + for (j = 0; j < 17; j++) + r[j] = h[j] = 0; + for (j = 0; j < 16; j++) + r[j] = k[j]; + r[3] &= 15; + r[4] &= 252; + r[7] &= 15; + r[8] &= 252; + r[11] &= 15; + r[12] &= 252; + r[15] &= 15; + while (n > 0) { + for (j = 0; j < 17; j++) + c[j] = 0; + for (j = 0; (j < 16) && (j < n); ++j) + c[j] = m[mpos + j]; + c[j] = 1; + mpos += j; + n -= j; + add1305(h, c); + for (i = 0; i < 17; i++) { + x[i] = 0; + for (j = 0; j < 17; j++) + x[i] = (x[i] + (h[j] * ((j <= i) ? r[i - j] : ((320 * r[i + 17 - j]) | 0))) | 0) | 0; + } + for (i = 0; i < 17; i++) + h[i] = x[i]; + u = 0; + for (j = 0; j < 16; j++) { + u = (u + h[j]) | 0; + h[j] = u & 255; + u >>>= 8; + } + u = (u + h[16]) | 0; + h[16] = u & 3; + u = (5 * (u >>> 2)) | 0; + for (j = 0; j < 16; j++) { + u = (u + h[j]) | 0; + h[j] = u & 255; + u >>>= 8; + } + u = (u + h[16]) | 0; + h[16] = u; + } + for (j = 0; j < 17; j++) + g[j] = h[j]; + add1305(h, minusp); + const s = (-(h[16] >>> 7) | 0); + for (j = 0; j < 17; j++) + h[j] ^= s & (g[j] ^ h[j]); + for (j = 0; j < 16; j++) + c[j] = k[j + 16]; + c[16] = 0; + add1305(h, c); + for (j = 0; j < 16; j++) + out[outpos + j] = h[j]; + return 0; +} +function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) { + const x = new Uint8Array(16); + crypto_onetimeauth(x, 0, m, mpos, n, k); + return vn(h, hpos, x, 0, 16); +} +function crypto_secretbox(c, m, d, n, k) { + if (d < 32) + return -1; + crypto_stream_xor(c, 0, m, 0, d, n, k); + crypto_onetimeauth(c, 16, c, 32, d - 32, c); + for (let i = 0; i < 16; i++) + c[i] = 0; + return 0; +} +function crypto_secretbox_open(m, c, d, n, k) { + const x = new Uint8Array(32); + if (d < 32) + return -1; + crypto_stream_xor(x, 0, null, 0, 32, n, k); + if (crypto_onetimeauth_verify(c, 16, c, 32, d - 32, x) !== 0) + return -1; + crypto_stream_xor(m, 0, c, 0, d, n, k); + for (let i = 0; i < 32; i++) + m[i] = 0; + return 0; +} +const crypto_secretbox_KEYBYTES = 32; +const crypto_secretbox_NONCEBYTES = 24; +const crypto_secretbox_ZEROBYTES = 32; +const crypto_secretbox_BOXZEROBYTES = 16; +function checkLengths(k, n) { + if (k.length !== crypto_secretbox_KEYBYTES) + throw new Error('bad key size'); + if (n.length !== crypto_secretbox_NONCEBYTES) + throw new Error('bad nonce size'); +} +function checkArrayTypes(...args) { + for (let i = 0, count = args.length; i < count; i++) { + if (!(args[i] instanceof Uint8Array)) + throw new TypeError('unexpected type, use Uint8Array'); + } +} +export function naclSecretbox(msg, nonce, key) { + checkArrayTypes(msg, nonce, key); + checkLengths(key, nonce); + const m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length); + const c = new Uint8Array(m.length); + for (let i = 0; i < msg.length; i++) + m[i + crypto_secretbox_ZEROBYTES] = msg[i]; + crypto_secretbox(c, m, m.length, nonce, key); + return c.subarray(crypto_secretbox_BOXZEROBYTES); +} +export function naclSecretboxOpen(box, nonce, key) { + checkArrayTypes(box, nonce, key); + checkLengths(key, nonce); + const c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length); + const m = new Uint8Array(c.length); + for (let i = 0; i < box.length; i++) + c[i + crypto_secretbox_BOXZEROBYTES] = box[i]; + if (c.length < 32) + return null; + if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) + return null; + return m.subarray(crypto_secretbox_ZEROBYTES); +} diff --git a/packages/util-crypto/networks.d.ts b/packages/util-crypto/networks.d.ts new file mode 100644 index 0000000..1f36543 --- /dev/null +++ b/packages/util-crypto/networks.d.ts @@ -0,0 +1 @@ +export { allNetworks, availableNetworks, selectableNetworks } from '@pezkuwi/networks'; diff --git a/packages/util-crypto/networks.js b/packages/util-crypto/networks.js new file mode 100644 index 0000000..1f36543 --- /dev/null +++ b/packages/util-crypto/networks.js @@ -0,0 +1 @@ +export { allNetworks, availableNetworks, selectableNetworks } from '@pezkuwi/networks'; diff --git a/packages/util-crypto/package.json b/packages/util-crypto/package.json index e332713..0cdb615 100644 --- a/packages/util-crypto/package.json +++ b/packages/util-crypto/package.json @@ -15,31 +15,2043 @@ }, "sideEffects": [ "./bundleInit.js", - "./bundleInit.cjs", + "./cjs/bundleInit.js", "./packageDetect.js", - "./packageDetect.cjs" + "./cjs/packageDetect.js" ], "type": "module", - "version": "14.0.10", + "version": "14.0.11", + "main": "./cjs/index.js", + "module": "./index.js", "browser": { "crypto": false, "stream": false }, - "main": "index.js", + "types": "./index.d.ts", + "exports": { + "./cjs/package.json": "./cjs/package.json", + "./cjs/*": "./cjs/*.js", + ".": { + "module": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "require": { + "types": "./cjs/index.d.ts", + "default": "./cjs/index.js" + }, + "default": { + "types": "./index.d.ts", + "default": "./index.js" + } + }, + "./address": { + "module": { + "types": "./address/index.d.ts", + "default": "./address/index.js" + }, + "require": { + "types": "./cjs/address/index.d.ts", + "default": "./cjs/address/index.js" + }, + "default": { + "types": "./address/index.d.ts", + "default": "./address/index.js" + } + }, + "./address/addressToEvm": { + "module": { + "types": "./address/addressToEvm.d.ts", + "default": "./address/addressToEvm.js" + }, + "require": { + "types": "./cjs/address/addressToEvm.d.ts", + "default": "./cjs/address/addressToEvm.js" + }, + "default": { + "types": "./address/addressToEvm.d.ts", + "default": "./address/addressToEvm.js" + } + }, + "./address/check": { + "module": { + "types": "./address/check.d.ts", + "default": "./address/check.js" + }, + "require": { + "types": "./cjs/address/check.d.ts", + "default": "./cjs/address/check.js" + }, + "default": { + "types": "./address/check.d.ts", + "default": "./address/check.js" + } + }, + "./address/checksum": { + "module": { + "types": "./address/checksum.d.ts", + "default": "./address/checksum.js" + }, + "require": { + "types": "./cjs/address/checksum.d.ts", + "default": "./cjs/address/checksum.js" + }, + "default": { + "types": "./address/checksum.d.ts", + "default": "./address/checksum.js" + } + }, + "./address/decode": { + "module": { + "types": "./address/decode.d.ts", + "default": "./address/decode.js" + }, + "require": { + "types": "./cjs/address/decode.d.ts", + "default": "./cjs/address/decode.js" + }, + "default": { + "types": "./address/decode.d.ts", + "default": "./address/decode.js" + } + }, + "./address/defaults": { + "module": { + "types": "./address/defaults.d.ts", + "default": "./address/defaults.js" + }, + "require": { + "types": "./cjs/address/defaults.d.ts", + "default": "./cjs/address/defaults.js" + }, + "default": { + "types": "./address/defaults.d.ts", + "default": "./address/defaults.js" + } + }, + "./address/derive": { + "module": { + "types": "./address/derive.d.ts", + "default": "./address/derive.js" + }, + "require": { + "types": "./cjs/address/derive.d.ts", + "default": "./cjs/address/derive.js" + }, + "default": { + "types": "./address/derive.d.ts", + "default": "./address/derive.js" + } + }, + "./address/encode": { + "module": { + "types": "./address/encode.d.ts", + "default": "./address/encode.js" + }, + "require": { + "types": "./cjs/address/encode.d.ts", + "default": "./cjs/address/encode.js" + }, + "default": { + "types": "./address/encode.d.ts", + "default": "./address/encode.js" + } + }, + "./address/encodeDerived": { + "module": { + "types": "./address/encodeDerived.d.ts", + "default": "./address/encodeDerived.js" + }, + "require": { + "types": "./cjs/address/encodeDerived.d.ts", + "default": "./cjs/address/encodeDerived.js" + }, + "default": { + "types": "./address/encodeDerived.d.ts", + "default": "./address/encodeDerived.js" + } + }, + "./address/encodeMulti": { + "module": { + "types": "./address/encodeMulti.d.ts", + "default": "./address/encodeMulti.js" + }, + "require": { + "types": "./cjs/address/encodeMulti.d.ts", + "default": "./cjs/address/encodeMulti.js" + }, + "default": { + "types": "./address/encodeMulti.d.ts", + "default": "./address/encodeMulti.js" + } + }, + "./address/eq": { + "module": { + "types": "./address/eq.d.ts", + "default": "./address/eq.js" + }, + "require": { + "types": "./cjs/address/eq.d.ts", + "default": "./cjs/address/eq.js" + }, + "default": { + "types": "./address/eq.d.ts", + "default": "./address/eq.js" + } + }, + "./address/evmToAddress": { + "module": { + "types": "./address/evmToAddress.d.ts", + "default": "./address/evmToAddress.js" + }, + "require": { + "types": "./cjs/address/evmToAddress.d.ts", + "default": "./cjs/address/evmToAddress.js" + }, + "default": { + "types": "./address/evmToAddress.d.ts", + "default": "./address/evmToAddress.js" + } + }, + "./address/is": { + "module": { + "types": "./address/is.d.ts", + "default": "./address/is.js" + }, + "require": { + "types": "./cjs/address/is.d.ts", + "default": "./cjs/address/is.js" + }, + "default": { + "types": "./address/is.d.ts", + "default": "./address/is.js" + } + }, + "./address/keyDerived": { + "module": { + "types": "./address/keyDerived.d.ts", + "default": "./address/keyDerived.js" + }, + "require": { + "types": "./cjs/address/keyDerived.d.ts", + "default": "./cjs/address/keyDerived.js" + }, + "default": { + "types": "./address/keyDerived.d.ts", + "default": "./address/keyDerived.js" + } + }, + "./address/keyMulti": { + "module": { + "types": "./address/keyMulti.d.ts", + "default": "./address/keyMulti.js" + }, + "require": { + "types": "./cjs/address/keyMulti.d.ts", + "default": "./cjs/address/keyMulti.js" + }, + "default": { + "types": "./address/keyMulti.d.ts", + "default": "./address/keyMulti.js" + } + }, + "./address/setSS58Format": { + "module": { + "types": "./address/setSS58Format.d.ts", + "default": "./address/setSS58Format.js" + }, + "require": { + "types": "./cjs/address/setSS58Format.d.ts", + "default": "./cjs/address/setSS58Format.js" + }, + "default": { + "types": "./address/setSS58Format.d.ts", + "default": "./address/setSS58Format.js" + } + }, + "./address/sort": { + "module": { + "types": "./address/sort.d.ts", + "default": "./address/sort.js" + }, + "require": { + "types": "./cjs/address/sort.d.ts", + "default": "./cjs/address/sort.js" + }, + "default": { + "types": "./address/sort.d.ts", + "default": "./address/sort.js" + } + }, + "./address/sshash": { + "module": { + "types": "./address/sshash.d.ts", + "default": "./address/sshash.js" + }, + "require": { + "types": "./cjs/address/sshash.d.ts", + "default": "./cjs/address/sshash.js" + }, + "default": { + "types": "./address/sshash.d.ts", + "default": "./address/sshash.js" + } + }, + "./address/types": { + "module": { + "types": "./address/types.d.ts", + "default": "./address/types.js" + }, + "require": { + "types": "./cjs/address/types.d.ts", + "default": "./cjs/address/types.js" + }, + "default": { + "types": "./address/types.d.ts", + "default": "./address/types.js" + } + }, + "./address/util": { + "module": { + "types": "./address/util.d.ts", + "default": "./address/util.js" + }, + "require": { + "types": "./cjs/address/util.d.ts", + "default": "./cjs/address/util.js" + }, + "default": { + "types": "./address/util.d.ts", + "default": "./address/util.js" + } + }, + "./address/validate": { + "module": { + "types": "./address/validate.d.ts", + "default": "./address/validate.js" + }, + "require": { + "types": "./cjs/address/validate.d.ts", + "default": "./cjs/address/validate.js" + }, + "default": { + "types": "./address/validate.d.ts", + "default": "./address/validate.js" + } + }, + "./base32": { + "module": { + "types": "./base32/index.d.ts", + "default": "./base32/index.js" + }, + "require": { + "types": "./cjs/base32/index.d.ts", + "default": "./cjs/base32/index.js" + }, + "default": { + "types": "./base32/index.d.ts", + "default": "./base32/index.js" + } + }, + "./base32/bs32": { + "module": { + "types": "./base32/bs32.d.ts", + "default": "./base32/bs32.js" + }, + "require": { + "types": "./cjs/base32/bs32.d.ts", + "default": "./cjs/base32/bs32.js" + }, + "default": { + "types": "./base32/bs32.d.ts", + "default": "./base32/bs32.js" + } + }, + "./base32/helpers": { + "module": { + "types": "./base32/helpers.d.ts", + "default": "./base32/helpers.js" + }, + "require": { + "types": "./cjs/base32/helpers.d.ts", + "default": "./cjs/base32/helpers.js" + }, + "default": { + "types": "./base32/helpers.d.ts", + "default": "./base32/helpers.js" + } + }, + "./base58": { + "module": { + "types": "./base58/index.d.ts", + "default": "./base58/index.js" + }, + "require": { + "types": "./cjs/base58/index.d.ts", + "default": "./cjs/base58/index.js" + }, + "default": { + "types": "./base58/index.d.ts", + "default": "./base58/index.js" + } + }, + "./base58/bs58": { + "module": { + "types": "./base58/bs58.d.ts", + "default": "./base58/bs58.js" + }, + "require": { + "types": "./cjs/base58/bs58.d.ts", + "default": "./cjs/base58/bs58.js" + }, + "default": { + "types": "./base58/bs58.d.ts", + "default": "./base58/bs58.js" + } + }, + "./base64": { + "module": { + "types": "./base64/index.d.ts", + "default": "./base64/index.js" + }, + "require": { + "types": "./cjs/base64/index.d.ts", + "default": "./cjs/base64/index.js" + }, + "default": { + "types": "./base64/index.d.ts", + "default": "./base64/index.js" + } + }, + "./base64/bs64": { + "module": { + "types": "./base64/bs64.d.ts", + "default": "./base64/bs64.js" + }, + "require": { + "types": "./cjs/base64/bs64.d.ts", + "default": "./cjs/base64/bs64.js" + }, + "default": { + "types": "./base64/bs64.d.ts", + "default": "./base64/bs64.js" + } + }, + "./base64/pad": { + "module": { + "types": "./base64/pad.d.ts", + "default": "./base64/pad.js" + }, + "require": { + "types": "./cjs/base64/pad.d.ts", + "default": "./cjs/base64/pad.js" + }, + "default": { + "types": "./base64/pad.d.ts", + "default": "./base64/pad.js" + } + }, + "./base64/trim": { + "module": { + "types": "./base64/trim.d.ts", + "default": "./base64/trim.js" + }, + "require": { + "types": "./cjs/base64/trim.d.ts", + "default": "./cjs/base64/trim.js" + }, + "default": { + "types": "./base64/trim.d.ts", + "default": "./base64/trim.js" + } + }, + "./blake2": { + "module": { + "types": "./blake2/index.d.ts", + "default": "./blake2/index.js" + }, + "require": { + "types": "./cjs/blake2/index.d.ts", + "default": "./cjs/blake2/index.js" + }, + "default": { + "types": "./blake2/index.d.ts", + "default": "./blake2/index.js" + } + }, + "./blake2/asU8a": { + "module": { + "types": "./blake2/asU8a.d.ts", + "default": "./blake2/asU8a.js" + }, + "require": { + "types": "./cjs/blake2/asU8a.d.ts", + "default": "./cjs/blake2/asU8a.js" + }, + "default": { + "types": "./blake2/asU8a.d.ts", + "default": "./blake2/asU8a.js" + } + }, + "./bn": { + "module": { + "types": "./bn.d.ts", + "default": "./bn.js" + }, + "require": { + "types": "./cjs/bn.d.ts", + "default": "./cjs/bn.js" + }, + "default": { + "types": "./bn.d.ts", + "default": "./bn.js" + } + }, + "./bundle": { + "module": { + "types": "./bundle.d.ts", + "default": "./bundle.js" + }, + "require": { + "types": "./cjs/bundle.d.ts", + "default": "./cjs/bundle.js" + }, + "default": { + "types": "./bundle.d.ts", + "default": "./bundle.js" + } + }, + "./bundleInit": { + "module": { + "types": "./bundleInit.d.ts", + "default": "./bundleInit.js" + }, + "require": { + "types": "./cjs/bundleInit.d.ts", + "default": "./cjs/bundleInit.js" + }, + "default": { + "types": "./bundleInit.d.ts", + "default": "./bundleInit.js" + } + }, + "./crypto": { + "module": { + "types": "./crypto.d.ts", + "default": "./crypto.js" + }, + "require": { + "types": "./cjs/crypto.d.ts", + "default": "./cjs/crypto.js" + }, + "default": { + "types": "./crypto.d.ts", + "default": "./crypto.js" + } + }, + "./ed25519": { + "module": { + "types": "./ed25519/index.d.ts", + "default": "./ed25519/index.js" + }, + "require": { + "types": "./cjs/ed25519/index.d.ts", + "default": "./cjs/ed25519/index.js" + }, + "default": { + "types": "./ed25519/index.d.ts", + "default": "./ed25519/index.js" + } + }, + "./ed25519/deriveHard": { + "module": { + "types": "./ed25519/deriveHard.d.ts", + "default": "./ed25519/deriveHard.js" + }, + "require": { + "types": "./cjs/ed25519/deriveHard.d.ts", + "default": "./cjs/ed25519/deriveHard.js" + }, + "default": { + "types": "./ed25519/deriveHard.d.ts", + "default": "./ed25519/deriveHard.js" + } + }, + "./ed25519/pair/fromRandom": { + "module": { + "types": "./ed25519/pair/fromRandom.d.ts", + "default": "./ed25519/pair/fromRandom.js" + }, + "require": { + "types": "./cjs/ed25519/pair/fromRandom.d.ts", + "default": "./cjs/ed25519/pair/fromRandom.js" + }, + "default": { + "types": "./ed25519/pair/fromRandom.d.ts", + "default": "./ed25519/pair/fromRandom.js" + } + }, + "./ed25519/pair/fromSecret": { + "module": { + "types": "./ed25519/pair/fromSecret.d.ts", + "default": "./ed25519/pair/fromSecret.js" + }, + "require": { + "types": "./cjs/ed25519/pair/fromSecret.d.ts", + "default": "./cjs/ed25519/pair/fromSecret.js" + }, + "default": { + "types": "./ed25519/pair/fromSecret.d.ts", + "default": "./ed25519/pair/fromSecret.js" + } + }, + "./ed25519/pair/fromSeed": { + "module": { + "types": "./ed25519/pair/fromSeed.d.ts", + "default": "./ed25519/pair/fromSeed.js" + }, + "require": { + "types": "./cjs/ed25519/pair/fromSeed.d.ts", + "default": "./cjs/ed25519/pair/fromSeed.js" + }, + "default": { + "types": "./ed25519/pair/fromSeed.d.ts", + "default": "./ed25519/pair/fromSeed.js" + } + }, + "./ed25519/pair/fromString": { + "module": { + "types": "./ed25519/pair/fromString.d.ts", + "default": "./ed25519/pair/fromString.js" + }, + "require": { + "types": "./cjs/ed25519/pair/fromString.d.ts", + "default": "./cjs/ed25519/pair/fromString.js" + }, + "default": { + "types": "./ed25519/pair/fromString.d.ts", + "default": "./ed25519/pair/fromString.js" + } + }, + "./ed25519/sign": { + "module": { + "types": "./ed25519/sign.d.ts", + "default": "./ed25519/sign.js" + }, + "require": { + "types": "./cjs/ed25519/sign.d.ts", + "default": "./cjs/ed25519/sign.js" + }, + "default": { + "types": "./ed25519/sign.d.ts", + "default": "./ed25519/sign.js" + } + }, + "./ed25519/verify": { + "module": { + "types": "./ed25519/verify.d.ts", + "default": "./ed25519/verify.js" + }, + "require": { + "types": "./cjs/ed25519/verify.d.ts", + "default": "./cjs/ed25519/verify.js" + }, + "default": { + "types": "./ed25519/verify.d.ts", + "default": "./ed25519/verify.js" + } + }, + "./ethereum": { + "module": { + "types": "./ethereum/index.d.ts", + "default": "./ethereum/index.js" + }, + "require": { + "types": "./cjs/ethereum/index.d.ts", + "default": "./cjs/ethereum/index.js" + }, + "default": { + "types": "./ethereum/index.d.ts", + "default": "./ethereum/index.js" + } + }, + "./ethereum/encode": { + "module": { + "types": "./ethereum/encode.d.ts", + "default": "./ethereum/encode.js" + }, + "require": { + "types": "./cjs/ethereum/encode.d.ts", + "default": "./cjs/ethereum/encode.js" + }, + "default": { + "types": "./ethereum/encode.d.ts", + "default": "./ethereum/encode.js" + } + }, + "./ethereum/isAddress": { + "module": { + "types": "./ethereum/isAddress.d.ts", + "default": "./ethereum/isAddress.js" + }, + "require": { + "types": "./cjs/ethereum/isAddress.d.ts", + "default": "./cjs/ethereum/isAddress.js" + }, + "default": { + "types": "./ethereum/isAddress.d.ts", + "default": "./ethereum/isAddress.js" + } + }, + "./ethereum/isChecksum": { + "module": { + "types": "./ethereum/isChecksum.d.ts", + "default": "./ethereum/isChecksum.js" + }, + "require": { + "types": "./cjs/ethereum/isChecksum.d.ts", + "default": "./cjs/ethereum/isChecksum.js" + }, + "default": { + "types": "./ethereum/isChecksum.d.ts", + "default": "./ethereum/isChecksum.js" + } + }, + "./hd": { + "module": { + "types": "./hd/index.d.ts", + "default": "./hd/index.js" + }, + "require": { + "types": "./cjs/hd/index.d.ts", + "default": "./cjs/hd/index.js" + }, + "default": { + "types": "./hd/index.d.ts", + "default": "./hd/index.js" + } + }, + "./hd/ethereum": { + "module": { + "types": "./hd/ethereum/index.d.ts", + "default": "./hd/ethereum/index.js" + }, + "require": { + "types": "./cjs/hd/ethereum/index.d.ts", + "default": "./cjs/hd/ethereum/index.js" + }, + "default": { + "types": "./hd/ethereum/index.d.ts", + "default": "./hd/ethereum/index.js" + } + }, + "./hd/ledger": { + "module": { + "types": "./hd/ledger/index.d.ts", + "default": "./hd/ledger/index.js" + }, + "require": { + "types": "./cjs/hd/ledger/index.d.ts", + "default": "./cjs/hd/ledger/index.js" + }, + "default": { + "types": "./hd/ledger/index.d.ts", + "default": "./hd/ledger/index.js" + } + }, + "./hd/ledger/derivePrivate": { + "module": { + "types": "./hd/ledger/derivePrivate.d.ts", + "default": "./hd/ledger/derivePrivate.js" + }, + "require": { + "types": "./cjs/hd/ledger/derivePrivate.d.ts", + "default": "./cjs/hd/ledger/derivePrivate.js" + }, + "default": { + "types": "./hd/ledger/derivePrivate.d.ts", + "default": "./hd/ledger/derivePrivate.js" + } + }, + "./hd/ledger/master": { + "module": { + "types": "./hd/ledger/master.d.ts", + "default": "./hd/ledger/master.js" + }, + "require": { + "types": "./cjs/hd/ledger/master.d.ts", + "default": "./cjs/hd/ledger/master.js" + }, + "default": { + "types": "./hd/ledger/master.d.ts", + "default": "./hd/ledger/master.js" + } + }, + "./hd/validatePath": { + "module": { + "types": "./hd/validatePath.d.ts", + "default": "./hd/validatePath.js" + }, + "require": { + "types": "./cjs/hd/validatePath.d.ts", + "default": "./cjs/hd/validatePath.js" + }, + "default": { + "types": "./hd/validatePath.d.ts", + "default": "./hd/validatePath.js" + } + }, + "./helpers": { + "module": { + "types": "./helpers.d.ts", + "default": "./helpers.js" + }, + "require": { + "types": "./cjs/helpers.d.ts", + "default": "./cjs/helpers.js" + }, + "default": { + "types": "./helpers.d.ts", + "default": "./helpers.js" + } + }, + "./hmac": { + "module": { + "types": "./hmac/index.d.ts", + "default": "./hmac/index.js" + }, + "require": { + "types": "./cjs/hmac/index.d.ts", + "default": "./cjs/hmac/index.js" + }, + "default": { + "types": "./hmac/index.d.ts", + "default": "./hmac/index.js" + } + }, + "./hmac/shaAsU8a": { + "module": { + "types": "./hmac/shaAsU8a.d.ts", + "default": "./hmac/shaAsU8a.js" + }, + "require": { + "types": "./cjs/hmac/shaAsU8a.d.ts", + "default": "./cjs/hmac/shaAsU8a.js" + }, + "default": { + "types": "./hmac/shaAsU8a.d.ts", + "default": "./hmac/shaAsU8a.js" + } + }, + "./json": { + "module": { + "types": "./json/index.d.ts", + "default": "./json/index.js" + }, + "require": { + "types": "./cjs/json/index.d.ts", + "default": "./cjs/json/index.js" + }, + "default": { + "types": "./json/index.d.ts", + "default": "./json/index.js" + } + }, + "./json/constants": { + "module": { + "types": "./json/constants.d.ts", + "default": "./json/constants.js" + }, + "require": { + "types": "./cjs/json/constants.d.ts", + "default": "./cjs/json/constants.js" + }, + "default": { + "types": "./json/constants.d.ts", + "default": "./json/constants.js" + } + }, + "./json/decrypt": { + "module": { + "types": "./json/decrypt.d.ts", + "default": "./json/decrypt.js" + }, + "require": { + "types": "./cjs/json/decrypt.d.ts", + "default": "./cjs/json/decrypt.js" + }, + "default": { + "types": "./json/decrypt.d.ts", + "default": "./json/decrypt.js" + } + }, + "./json/decryptData": { + "module": { + "types": "./json/decryptData.d.ts", + "default": "./json/decryptData.js" + }, + "require": { + "types": "./cjs/json/decryptData.d.ts", + "default": "./cjs/json/decryptData.js" + }, + "default": { + "types": "./json/decryptData.d.ts", + "default": "./json/decryptData.js" + } + }, + "./json/encrypt": { + "module": { + "types": "./json/encrypt.d.ts", + "default": "./json/encrypt.js" + }, + "require": { + "types": "./cjs/json/encrypt.d.ts", + "default": "./cjs/json/encrypt.js" + }, + "default": { + "types": "./json/encrypt.d.ts", + "default": "./json/encrypt.js" + } + }, + "./json/encryptFormat": { + "module": { + "types": "./json/encryptFormat.d.ts", + "default": "./json/encryptFormat.js" + }, + "require": { + "types": "./cjs/json/encryptFormat.d.ts", + "default": "./cjs/json/encryptFormat.js" + }, + "default": { + "types": "./json/encryptFormat.d.ts", + "default": "./json/encryptFormat.js" + } + }, + "./json/types": { + "module": { + "types": "./json/types.d.ts", + "default": "./json/types.js" + }, + "require": { + "types": "./cjs/json/types.d.ts", + "default": "./cjs/json/types.js" + }, + "default": { + "types": "./json/types.d.ts", + "default": "./json/types.js" + } + }, + "./keccak": { + "module": { + "types": "./keccak/index.d.ts", + "default": "./keccak/index.js" + }, + "require": { + "types": "./cjs/keccak/index.d.ts", + "default": "./cjs/keccak/index.js" + }, + "default": { + "types": "./keccak/index.d.ts", + "default": "./keccak/index.js" + } + }, + "./keccak/asU8a": { + "module": { + "types": "./keccak/asU8a.d.ts", + "default": "./keccak/asU8a.js" + }, + "require": { + "types": "./cjs/keccak/asU8a.d.ts", + "default": "./cjs/keccak/asU8a.js" + }, + "default": { + "types": "./keccak/asU8a.d.ts", + "default": "./keccak/asU8a.js" + } + }, + "./key": { + "module": { + "types": "./key/index.d.ts", + "default": "./key/index.js" + }, + "require": { + "types": "./cjs/key/index.d.ts", + "default": "./cjs/key/index.js" + }, + "default": { + "types": "./key/index.d.ts", + "default": "./key/index.js" + } + }, + "./key/DeriveJunction": { + "module": { + "types": "./key/DeriveJunction.d.ts", + "default": "./key/DeriveJunction.js" + }, + "require": { + "types": "./cjs/key/DeriveJunction.d.ts", + "default": "./cjs/key/DeriveJunction.js" + }, + "default": { + "types": "./key/DeriveJunction.d.ts", + "default": "./key/DeriveJunction.js" + } + }, + "./key/extractPath": { + "module": { + "types": "./key/extractPath.d.ts", + "default": "./key/extractPath.js" + }, + "require": { + "types": "./cjs/key/extractPath.d.ts", + "default": "./cjs/key/extractPath.js" + }, + "default": { + "types": "./key/extractPath.d.ts", + "default": "./key/extractPath.js" + } + }, + "./key/extractSuri": { + "module": { + "types": "./key/extractSuri.d.ts", + "default": "./key/extractSuri.js" + }, + "require": { + "types": "./cjs/key/extractSuri.d.ts", + "default": "./cjs/key/extractSuri.js" + }, + "default": { + "types": "./key/extractSuri.d.ts", + "default": "./key/extractSuri.js" + } + }, + "./key/fromPath": { + "module": { + "types": "./key/fromPath.d.ts", + "default": "./key/fromPath.js" + }, + "require": { + "types": "./cjs/key/fromPath.d.ts", + "default": "./cjs/key/fromPath.js" + }, + "default": { + "types": "./key/fromPath.d.ts", + "default": "./key/fromPath.js" + } + }, + "./key/hdkdDerive": { + "module": { + "types": "./key/hdkdDerive.d.ts", + "default": "./key/hdkdDerive.js" + }, + "require": { + "types": "./cjs/key/hdkdDerive.d.ts", + "default": "./cjs/key/hdkdDerive.js" + }, + "default": { + "types": "./key/hdkdDerive.d.ts", + "default": "./key/hdkdDerive.js" + } + }, + "./key/hdkdEcdsa": { + "module": { + "types": "./key/hdkdEcdsa.d.ts", + "default": "./key/hdkdEcdsa.js" + }, + "require": { + "types": "./cjs/key/hdkdEcdsa.d.ts", + "default": "./cjs/key/hdkdEcdsa.js" + }, + "default": { + "types": "./key/hdkdEcdsa.d.ts", + "default": "./key/hdkdEcdsa.js" + } + }, + "./key/hdkdEd25519": { + "module": { + "types": "./key/hdkdEd25519.d.ts", + "default": "./key/hdkdEd25519.js" + }, + "require": { + "types": "./cjs/key/hdkdEd25519.d.ts", + "default": "./cjs/key/hdkdEd25519.js" + }, + "default": { + "types": "./key/hdkdEd25519.d.ts", + "default": "./key/hdkdEd25519.js" + } + }, + "./key/hdkdSr25519": { + "module": { + "types": "./key/hdkdSr25519.d.ts", + "default": "./key/hdkdSr25519.js" + }, + "require": { + "types": "./cjs/key/hdkdSr25519.d.ts", + "default": "./cjs/key/hdkdSr25519.js" + }, + "default": { + "types": "./key/hdkdSr25519.d.ts", + "default": "./key/hdkdSr25519.js" + } + }, + "./mnemonic": { + "module": { + "types": "./mnemonic/index.d.ts", + "default": "./mnemonic/index.js" + }, + "require": { + "types": "./cjs/mnemonic/index.d.ts", + "default": "./cjs/mnemonic/index.js" + }, + "default": { + "types": "./mnemonic/index.d.ts", + "default": "./mnemonic/index.js" + } + }, + "./mnemonic/bip39": { + "module": { + "types": "./mnemonic/bip39.d.ts", + "default": "./mnemonic/bip39.js" + }, + "require": { + "types": "./cjs/mnemonic/bip39.d.ts", + "default": "./cjs/mnemonic/bip39.js" + }, + "default": { + "types": "./mnemonic/bip39.d.ts", + "default": "./mnemonic/bip39.js" + } + }, + "./mnemonic/generate": { + "module": { + "types": "./mnemonic/generate.d.ts", + "default": "./mnemonic/generate.js" + }, + "require": { + "types": "./cjs/mnemonic/generate.d.ts", + "default": "./cjs/mnemonic/generate.js" + }, + "default": { + "types": "./mnemonic/generate.d.ts", + "default": "./mnemonic/generate.js" + } + }, + "./mnemonic/toEntropy": { + "module": { + "types": "./mnemonic/toEntropy.d.ts", + "default": "./mnemonic/toEntropy.js" + }, + "require": { + "types": "./cjs/mnemonic/toEntropy.d.ts", + "default": "./cjs/mnemonic/toEntropy.js" + }, + "default": { + "types": "./mnemonic/toEntropy.d.ts", + "default": "./mnemonic/toEntropy.js" + } + }, + "./mnemonic/toLegacySeed": { + "module": { + "types": "./mnemonic/toLegacySeed.d.ts", + "default": "./mnemonic/toLegacySeed.js" + }, + "require": { + "types": "./cjs/mnemonic/toLegacySeed.d.ts", + "default": "./cjs/mnemonic/toLegacySeed.js" + }, + "default": { + "types": "./mnemonic/toLegacySeed.d.ts", + "default": "./mnemonic/toLegacySeed.js" + } + }, + "./mnemonic/toMiniSecret": { + "module": { + "types": "./mnemonic/toMiniSecret.d.ts", + "default": "./mnemonic/toMiniSecret.js" + }, + "require": { + "types": "./cjs/mnemonic/toMiniSecret.d.ts", + "default": "./cjs/mnemonic/toMiniSecret.js" + }, + "default": { + "types": "./mnemonic/toMiniSecret.d.ts", + "default": "./mnemonic/toMiniSecret.js" + } + }, + "./mnemonic/validate": { + "module": { + "types": "./mnemonic/validate.d.ts", + "default": "./mnemonic/validate.js" + }, + "require": { + "types": "./cjs/mnemonic/validate.d.ts", + "default": "./cjs/mnemonic/validate.js" + }, + "default": { + "types": "./mnemonic/validate.d.ts", + "default": "./mnemonic/validate.js" + } + }, + "./mnemonic/wordlists": { + "module": { + "types": "./mnemonic/wordlists/index.d.ts", + "default": "./mnemonic/wordlists/index.js" + }, + "require": { + "types": "./cjs/mnemonic/wordlists/index.d.ts", + "default": "./cjs/mnemonic/wordlists/index.js" + }, + "default": { + "types": "./mnemonic/wordlists/index.d.ts", + "default": "./mnemonic/wordlists/index.js" + } + }, + "./mnemonic/wordlists/en": { + "module": { + "types": "./mnemonic/wordlists/en.d.ts", + "default": "./mnemonic/wordlists/en.js" + }, + "require": { + "types": "./cjs/mnemonic/wordlists/en.d.ts", + "default": "./cjs/mnemonic/wordlists/en.js" + }, + "default": { + "types": "./mnemonic/wordlists/en.d.ts", + "default": "./mnemonic/wordlists/en.js" + } + }, + "./mnemonic/wordlists/es": { + "module": { + "types": "./mnemonic/wordlists/es.d.ts", + "default": "./mnemonic/wordlists/es.js" + }, + "require": { + "types": "./cjs/mnemonic/wordlists/es.d.ts", + "default": "./cjs/mnemonic/wordlists/es.js" + }, + "default": { + "types": "./mnemonic/wordlists/es.d.ts", + "default": "./mnemonic/wordlists/es.js" + } + }, + "./mnemonic/wordlists/fr": { + "module": { + "types": "./mnemonic/wordlists/fr.d.ts", + "default": "./mnemonic/wordlists/fr.js" + }, + "require": { + "types": "./cjs/mnemonic/wordlists/fr.d.ts", + "default": "./cjs/mnemonic/wordlists/fr.js" + }, + "default": { + "types": "./mnemonic/wordlists/fr.d.ts", + "default": "./mnemonic/wordlists/fr.js" + } + }, + "./mnemonic/wordlists/it": { + "module": { + "types": "./mnemonic/wordlists/it.d.ts", + "default": "./mnemonic/wordlists/it.js" + }, + "require": { + "types": "./cjs/mnemonic/wordlists/it.d.ts", + "default": "./cjs/mnemonic/wordlists/it.js" + }, + "default": { + "types": "./mnemonic/wordlists/it.d.ts", + "default": "./mnemonic/wordlists/it.js" + } + }, + "./mnemonic/wordlists/jp": { + "module": { + "types": "./mnemonic/wordlists/jp.d.ts", + "default": "./mnemonic/wordlists/jp.js" + }, + "require": { + "types": "./cjs/mnemonic/wordlists/jp.d.ts", + "default": "./cjs/mnemonic/wordlists/jp.js" + }, + "default": { + "types": "./mnemonic/wordlists/jp.d.ts", + "default": "./mnemonic/wordlists/jp.js" + } + }, + "./mnemonic/wordlists/ko": { + "module": { + "types": "./mnemonic/wordlists/ko.d.ts", + "default": "./mnemonic/wordlists/ko.js" + }, + "require": { + "types": "./cjs/mnemonic/wordlists/ko.d.ts", + "default": "./cjs/mnemonic/wordlists/ko.js" + }, + "default": { + "types": "./mnemonic/wordlists/ko.d.ts", + "default": "./mnemonic/wordlists/ko.js" + } + }, + "./mnemonic/wordlists/zh-s": { + "module": { + "types": "./mnemonic/wordlists/zh-s.d.ts", + "default": "./mnemonic/wordlists/zh-s.js" + }, + "require": { + "types": "./cjs/mnemonic/wordlists/zh-s.d.ts", + "default": "./cjs/mnemonic/wordlists/zh-s.js" + }, + "default": { + "types": "./mnemonic/wordlists/zh-s.d.ts", + "default": "./mnemonic/wordlists/zh-s.js" + } + }, + "./mnemonic/wordlists/zh-t": { + "module": { + "types": "./mnemonic/wordlists/zh-t.d.ts", + "default": "./mnemonic/wordlists/zh-t.js" + }, + "require": { + "types": "./cjs/mnemonic/wordlists/zh-t.d.ts", + "default": "./cjs/mnemonic/wordlists/zh-t.js" + }, + "default": { + "types": "./mnemonic/wordlists/zh-t.d.ts", + "default": "./mnemonic/wordlists/zh-t.js" + } + }, + "./nacl": { + "module": { + "types": "./nacl/index.d.ts", + "default": "./nacl/index.js" + }, + "require": { + "types": "./cjs/nacl/index.d.ts", + "default": "./cjs/nacl/index.js" + }, + "default": { + "types": "./nacl/index.d.ts", + "default": "./nacl/index.js" + } + }, + "./nacl/decrypt": { + "module": { + "types": "./nacl/decrypt.d.ts", + "default": "./nacl/decrypt.js" + }, + "require": { + "types": "./cjs/nacl/decrypt.d.ts", + "default": "./cjs/nacl/decrypt.js" + }, + "default": { + "types": "./nacl/decrypt.d.ts", + "default": "./nacl/decrypt.js" + } + }, + "./nacl/encrypt": { + "module": { + "types": "./nacl/encrypt.d.ts", + "default": "./nacl/encrypt.js" + }, + "require": { + "types": "./cjs/nacl/encrypt.d.ts", + "default": "./cjs/nacl/encrypt.js" + }, + "default": { + "types": "./nacl/encrypt.d.ts", + "default": "./nacl/encrypt.js" + } + }, + "./nacl/tweetnacl": { + "module": { + "types": "./nacl/tweetnacl.d.ts", + "default": "./nacl/tweetnacl.js" + }, + "require": { + "types": "./cjs/nacl/tweetnacl.d.ts", + "default": "./cjs/nacl/tweetnacl.js" + }, + "default": { + "types": "./nacl/tweetnacl.d.ts", + "default": "./nacl/tweetnacl.js" + } + }, + "./networks": { + "module": { + "types": "./networks.d.ts", + "default": "./networks.js" + }, + "require": { + "types": "./cjs/networks.d.ts", + "default": "./cjs/networks.js" + }, + "default": { + "types": "./networks.d.ts", + "default": "./networks.js" + } + }, + "./package.json": { + "require": "./cjs/package.json", + "default": "./package.json" + }, + "./packageDetect": { + "module": { + "types": "./packageDetect.d.ts", + "default": "./packageDetect.js" + }, + "require": { + "types": "./cjs/packageDetect.d.ts", + "default": "./cjs/packageDetect.js" + }, + "default": { + "types": "./packageDetect.d.ts", + "default": "./packageDetect.js" + } + }, + "./packageInfo.js": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./packageInfo": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./pbkdf2": { + "module": { + "types": "./pbkdf2/index.d.ts", + "default": "./pbkdf2/index.js" + }, + "require": { + "types": "./cjs/pbkdf2/index.d.ts", + "default": "./cjs/pbkdf2/index.js" + }, + "default": { + "types": "./pbkdf2/index.d.ts", + "default": "./pbkdf2/index.js" + } + }, + "./pbkdf2/encode": { + "module": { + "types": "./pbkdf2/encode.d.ts", + "default": "./pbkdf2/encode.js" + }, + "require": { + "types": "./cjs/pbkdf2/encode.d.ts", + "default": "./cjs/pbkdf2/encode.js" + }, + "default": { + "types": "./pbkdf2/encode.d.ts", + "default": "./pbkdf2/encode.js" + } + }, + "./random": { + "module": { + "types": "./random/index.d.ts", + "default": "./random/index.js" + }, + "require": { + "types": "./cjs/random/index.d.ts", + "default": "./cjs/random/index.js" + }, + "default": { + "types": "./random/index.d.ts", + "default": "./random/index.js" + } + }, + "./random/asNumber": { + "module": { + "types": "./random/asNumber.d.ts", + "default": "./random/asNumber.js" + }, + "require": { + "types": "./cjs/random/asNumber.d.ts", + "default": "./cjs/random/asNumber.js" + }, + "default": { + "types": "./random/asNumber.d.ts", + "default": "./random/asNumber.js" + } + }, + "./random/asU8a": { + "module": { + "types": "./random/asU8a.d.ts", + "default": "./random/asU8a.js" + }, + "require": { + "types": "./cjs/random/asU8a.d.ts", + "default": "./cjs/random/asU8a.js" + }, + "default": { + "types": "./random/asU8a.d.ts", + "default": "./random/asU8a.js" + } + }, + "./scrypt": { + "module": { + "types": "./scrypt/index.d.ts", + "default": "./scrypt/index.js" + }, + "require": { + "types": "./cjs/scrypt/index.d.ts", + "default": "./cjs/scrypt/index.js" + }, + "default": { + "types": "./scrypt/index.d.ts", + "default": "./scrypt/index.js" + } + }, + "./scrypt/defaults": { + "module": { + "types": "./scrypt/defaults.d.ts", + "default": "./scrypt/defaults.js" + }, + "require": { + "types": "./cjs/scrypt/defaults.d.ts", + "default": "./cjs/scrypt/defaults.js" + }, + "default": { + "types": "./scrypt/defaults.d.ts", + "default": "./scrypt/defaults.js" + } + }, + "./scrypt/encode": { + "module": { + "types": "./scrypt/encode.d.ts", + "default": "./scrypt/encode.js" + }, + "require": { + "types": "./cjs/scrypt/encode.d.ts", + "default": "./cjs/scrypt/encode.js" + }, + "default": { + "types": "./scrypt/encode.d.ts", + "default": "./scrypt/encode.js" + } + }, + "./scrypt/fromU8a": { + "module": { + "types": "./scrypt/fromU8a.d.ts", + "default": "./scrypt/fromU8a.js" + }, + "require": { + "types": "./cjs/scrypt/fromU8a.d.ts", + "default": "./cjs/scrypt/fromU8a.js" + }, + "default": { + "types": "./scrypt/fromU8a.d.ts", + "default": "./scrypt/fromU8a.js" + } + }, + "./scrypt/toU8a": { + "module": { + "types": "./scrypt/toU8a.d.ts", + "default": "./scrypt/toU8a.js" + }, + "require": { + "types": "./cjs/scrypt/toU8a.d.ts", + "default": "./cjs/scrypt/toU8a.js" + }, + "default": { + "types": "./scrypt/toU8a.d.ts", + "default": "./scrypt/toU8a.js" + } + }, + "./scrypt/types": { + "module": { + "types": "./scrypt/types.d.ts", + "default": "./scrypt/types.js" + }, + "require": { + "types": "./cjs/scrypt/types.d.ts", + "default": "./cjs/scrypt/types.js" + }, + "default": { + "types": "./scrypt/types.d.ts", + "default": "./scrypt/types.js" + } + }, + "./secp256k1": { + "module": { + "types": "./secp256k1/index.d.ts", + "default": "./secp256k1/index.js" + }, + "require": { + "types": "./cjs/secp256k1/index.d.ts", + "default": "./cjs/secp256k1/index.js" + }, + "default": { + "types": "./secp256k1/index.d.ts", + "default": "./secp256k1/index.js" + } + }, + "./secp256k1/compress": { + "module": { + "types": "./secp256k1/compress.d.ts", + "default": "./secp256k1/compress.js" + }, + "require": { + "types": "./cjs/secp256k1/compress.d.ts", + "default": "./cjs/secp256k1/compress.js" + }, + "default": { + "types": "./secp256k1/compress.d.ts", + "default": "./secp256k1/compress.js" + } + }, + "./secp256k1/deriveHard": { + "module": { + "types": "./secp256k1/deriveHard.d.ts", + "default": "./secp256k1/deriveHard.js" + }, + "require": { + "types": "./cjs/secp256k1/deriveHard.d.ts", + "default": "./cjs/secp256k1/deriveHard.js" + }, + "default": { + "types": "./secp256k1/deriveHard.d.ts", + "default": "./secp256k1/deriveHard.js" + } + }, + "./secp256k1/expand": { + "module": { + "types": "./secp256k1/expand.d.ts", + "default": "./secp256k1/expand.js" + }, + "require": { + "types": "./cjs/secp256k1/expand.d.ts", + "default": "./cjs/secp256k1/expand.js" + }, + "default": { + "types": "./secp256k1/expand.d.ts", + "default": "./secp256k1/expand.js" + } + }, + "./secp256k1/hasher": { + "module": { + "types": "./secp256k1/hasher.d.ts", + "default": "./secp256k1/hasher.js" + }, + "require": { + "types": "./cjs/secp256k1/hasher.d.ts", + "default": "./cjs/secp256k1/hasher.js" + }, + "default": { + "types": "./secp256k1/hasher.d.ts", + "default": "./secp256k1/hasher.js" + } + }, + "./secp256k1/pair/fromSeed": { + "module": { + "types": "./secp256k1/pair/fromSeed.d.ts", + "default": "./secp256k1/pair/fromSeed.js" + }, + "require": { + "types": "./cjs/secp256k1/pair/fromSeed.d.ts", + "default": "./cjs/secp256k1/pair/fromSeed.js" + }, + "default": { + "types": "./secp256k1/pair/fromSeed.d.ts", + "default": "./secp256k1/pair/fromSeed.js" + } + }, + "./secp256k1/recover": { + "module": { + "types": "./secp256k1/recover.d.ts", + "default": "./secp256k1/recover.js" + }, + "require": { + "types": "./cjs/secp256k1/recover.d.ts", + "default": "./cjs/secp256k1/recover.js" + }, + "default": { + "types": "./secp256k1/recover.d.ts", + "default": "./secp256k1/recover.js" + } + }, + "./secp256k1/sign": { + "module": { + "types": "./secp256k1/sign.d.ts", + "default": "./secp256k1/sign.js" + }, + "require": { + "types": "./cjs/secp256k1/sign.d.ts", + "default": "./cjs/secp256k1/sign.js" + }, + "default": { + "types": "./secp256k1/sign.d.ts", + "default": "./secp256k1/sign.js" + } + }, + "./secp256k1/tweakAdd": { + "module": { + "types": "./secp256k1/tweakAdd.d.ts", + "default": "./secp256k1/tweakAdd.js" + }, + "require": { + "types": "./cjs/secp256k1/tweakAdd.d.ts", + "default": "./cjs/secp256k1/tweakAdd.js" + }, + "default": { + "types": "./secp256k1/tweakAdd.d.ts", + "default": "./secp256k1/tweakAdd.js" + } + }, + "./secp256k1/types": { + "module": { + "types": "./secp256k1/types.d.ts", + "default": "./secp256k1/types.js" + }, + "require": { + "types": "./cjs/secp256k1/types.d.ts", + "default": "./cjs/secp256k1/types.js" + }, + "default": { + "types": "./secp256k1/types.d.ts", + "default": "./secp256k1/types.js" + } + }, + "./secp256k1/verify": { + "module": { + "types": "./secp256k1/verify.d.ts", + "default": "./secp256k1/verify.js" + }, + "require": { + "types": "./cjs/secp256k1/verify.d.ts", + "default": "./cjs/secp256k1/verify.js" + }, + "default": { + "types": "./secp256k1/verify.d.ts", + "default": "./secp256k1/verify.js" + } + }, + "./sha": { + "module": { + "types": "./sha/index.d.ts", + "default": "./sha/index.js" + }, + "require": { + "types": "./cjs/sha/index.d.ts", + "default": "./cjs/sha/index.js" + }, + "default": { + "types": "./sha/index.d.ts", + "default": "./sha/index.js" + } + }, + "./sha/asU8a": { + "module": { + "types": "./sha/asU8a.d.ts", + "default": "./sha/asU8a.js" + }, + "require": { + "types": "./cjs/sha/asU8a.d.ts", + "default": "./cjs/sha/asU8a.js" + }, + "default": { + "types": "./sha/asU8a.d.ts", + "default": "./sha/asU8a.js" + } + }, + "./signature": { + "module": { + "types": "./signature/index.d.ts", + "default": "./signature/index.js" + }, + "require": { + "types": "./cjs/signature/index.d.ts", + "default": "./cjs/signature/index.js" + }, + "default": { + "types": "./signature/index.d.ts", + "default": "./signature/index.js" + } + }, + "./signature/verify": { + "module": { + "types": "./signature/verify.d.ts", + "default": "./signature/verify.js" + }, + "require": { + "types": "./cjs/signature/verify.d.ts", + "default": "./cjs/signature/verify.js" + }, + "default": { + "types": "./signature/verify.d.ts", + "default": "./signature/verify.js" + } + }, + "./sr25519": { + "module": { + "types": "./sr25519/index.d.ts", + "default": "./sr25519/index.js" + }, + "require": { + "types": "./cjs/sr25519/index.d.ts", + "default": "./cjs/sr25519/index.js" + }, + "default": { + "types": "./sr25519/index.d.ts", + "default": "./sr25519/index.js" + } + }, + "./sr25519/agreement": { + "module": { + "types": "./sr25519/agreement.d.ts", + "default": "./sr25519/agreement.js" + }, + "require": { + "types": "./cjs/sr25519/agreement.d.ts", + "default": "./cjs/sr25519/agreement.js" + }, + "default": { + "types": "./sr25519/agreement.d.ts", + "default": "./sr25519/agreement.js" + } + }, + "./sr25519/derive": { + "module": { + "types": "./sr25519/derive.d.ts", + "default": "./sr25519/derive.js" + }, + "require": { + "types": "./cjs/sr25519/derive.d.ts", + "default": "./cjs/sr25519/derive.js" + }, + "default": { + "types": "./sr25519/derive.d.ts", + "default": "./sr25519/derive.js" + } + }, + "./sr25519/deriveHard": { + "module": { + "types": "./sr25519/deriveHard.d.ts", + "default": "./sr25519/deriveHard.js" + }, + "require": { + "types": "./cjs/sr25519/deriveHard.d.ts", + "default": "./cjs/sr25519/deriveHard.js" + }, + "default": { + "types": "./sr25519/deriveHard.d.ts", + "default": "./sr25519/deriveHard.js" + } + }, + "./sr25519/derivePublic": { + "module": { + "types": "./sr25519/derivePublic.d.ts", + "default": "./sr25519/derivePublic.js" + }, + "require": { + "types": "./cjs/sr25519/derivePublic.d.ts", + "default": "./cjs/sr25519/derivePublic.js" + }, + "default": { + "types": "./sr25519/derivePublic.d.ts", + "default": "./sr25519/derivePublic.js" + } + }, + "./sr25519/deriveSoft": { + "module": { + "types": "./sr25519/deriveSoft.d.ts", + "default": "./sr25519/deriveSoft.js" + }, + "require": { + "types": "./cjs/sr25519/deriveSoft.d.ts", + "default": "./cjs/sr25519/deriveSoft.js" + }, + "default": { + "types": "./sr25519/deriveSoft.d.ts", + "default": "./sr25519/deriveSoft.js" + } + }, + "./sr25519/pair/fromSeed": { + "module": { + "types": "./sr25519/pair/fromSeed.d.ts", + "default": "./sr25519/pair/fromSeed.js" + }, + "require": { + "types": "./cjs/sr25519/pair/fromSeed.d.ts", + "default": "./cjs/sr25519/pair/fromSeed.js" + }, + "default": { + "types": "./sr25519/pair/fromSeed.d.ts", + "default": "./sr25519/pair/fromSeed.js" + } + }, + "./sr25519/pair/fromU8a": { + "module": { + "types": "./sr25519/pair/fromU8a.d.ts", + "default": "./sr25519/pair/fromU8a.js" + }, + "require": { + "types": "./cjs/sr25519/pair/fromU8a.d.ts", + "default": "./cjs/sr25519/pair/fromU8a.js" + }, + "default": { + "types": "./sr25519/pair/fromU8a.d.ts", + "default": "./sr25519/pair/fromU8a.js" + } + }, + "./sr25519/pair/toU8a": { + "module": { + "types": "./sr25519/pair/toU8a.d.ts", + "default": "./sr25519/pair/toU8a.js" + }, + "require": { + "types": "./cjs/sr25519/pair/toU8a.d.ts", + "default": "./cjs/sr25519/pair/toU8a.js" + }, + "default": { + "types": "./sr25519/pair/toU8a.d.ts", + "default": "./sr25519/pair/toU8a.js" + } + }, + "./sr25519/sign": { + "module": { + "types": "./sr25519/sign.d.ts", + "default": "./sr25519/sign.js" + }, + "require": { + "types": "./cjs/sr25519/sign.d.ts", + "default": "./cjs/sr25519/sign.js" + }, + "default": { + "types": "./sr25519/sign.d.ts", + "default": "./sr25519/sign.js" + } + }, + "./sr25519/verify": { + "module": { + "types": "./sr25519/verify.d.ts", + "default": "./sr25519/verify.js" + }, + "require": { + "types": "./cjs/sr25519/verify.d.ts", + "default": "./cjs/sr25519/verify.js" + }, + "default": { + "types": "./sr25519/verify.d.ts", + "default": "./sr25519/verify.js" + } + }, + "./sr25519/vrfSign": { + "module": { + "types": "./sr25519/vrfSign.d.ts", + "default": "./sr25519/vrfSign.js" + }, + "require": { + "types": "./cjs/sr25519/vrfSign.d.ts", + "default": "./cjs/sr25519/vrfSign.js" + }, + "default": { + "types": "./sr25519/vrfSign.d.ts", + "default": "./sr25519/vrfSign.js" + } + }, + "./sr25519/vrfVerify": { + "module": { + "types": "./sr25519/vrfVerify.d.ts", + "default": "./sr25519/vrfVerify.js" + }, + "require": { + "types": "./cjs/sr25519/vrfVerify.d.ts", + "default": "./cjs/sr25519/vrfVerify.js" + }, + "default": { + "types": "./sr25519/vrfVerify.d.ts", + "default": "./sr25519/vrfVerify.js" + } + }, + "./types": { + "module": { + "types": "./types.d.ts", + "default": "./types.js" + }, + "require": { + "types": "./cjs/types.d.ts", + "default": "./cjs/types.js" + }, + "default": { + "types": "./types.d.ts", + "default": "./types.js" + } + }, + "./xxhash": { + "module": { + "types": "./xxhash/index.d.ts", + "default": "./xxhash/index.js" + }, + "require": { + "types": "./cjs/xxhash/index.d.ts", + "default": "./cjs/xxhash/index.js" + }, + "default": { + "types": "./xxhash/index.d.ts", + "default": "./xxhash/index.js" + } + }, + "./xxhash/asU8a": { + "module": { + "types": "./xxhash/asU8a.d.ts", + "default": "./xxhash/asU8a.js" + }, + "require": { + "types": "./cjs/xxhash/asU8a.d.ts", + "default": "./cjs/xxhash/asU8a.js" + }, + "default": { + "types": "./xxhash/asU8a.d.ts", + "default": "./xxhash/asU8a.js" + } + }, + "./xxhash/xxhash64": { + "module": { + "types": "./xxhash/xxhash64.d.ts", + "default": "./xxhash/xxhash64.js" + }, + "require": { + "types": "./cjs/xxhash/xxhash64.d.ts", + "default": "./cjs/xxhash/xxhash64.js" + }, + "default": { + "types": "./xxhash/xxhash64.d.ts", + "default": "./xxhash/xxhash64.js" + } + } + }, "dependencies": { "@noble/curves": "^1.3.0", "@noble/hashes": "^1.3.3", - "@pezkuwi/networks": "workspace:*", - "@pezkuwi/util": "workspace:*", + "@pezkuwi/networks": "14.0.11", + "@pezkuwi/util": "14.0.11", "@pezkuwi/wasm-crypto": "^7.5.4", "@pezkuwi/wasm-util": "^7.5.4", - "@pezkuwi/x-bigint": "workspace:*", - "@pezkuwi/x-randomvalues": "workspace:*", + "@pezkuwi/x-bigint": "14.0.11", + "@pezkuwi/x-randomvalues": "14.0.11", "@scure/base": "^1.1.7", "@scure/sr25519": "^0.2.0", "tslib": "^2.8.0" }, "peerDependencies": { - "@pezkuwi/util": "workspace:*" + "@pezkuwi/util": "14.0.11" } } diff --git a/packages/util-crypto/packageDetect.d.ts b/packages/util-crypto/packageDetect.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/util-crypto/packageDetect.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/util-crypto/packageDetect.js b/packages/util-crypto/packageDetect.js new file mode 100644 index 0000000..a691605 --- /dev/null +++ b/packages/util-crypto/packageDetect.js @@ -0,0 +1,6 @@ +import { packageInfo as netInfo } from '@pezkuwi/networks/packageInfo'; +import { detectPackage } from '@pezkuwi/util'; +import { packageInfo as utilInfo } from '@pezkuwi/util/packageInfo'; +import { packageInfo as randomInfo } from '@pezkuwi/x-randomvalues'; +import { packageInfo } from './packageInfo.js'; +detectPackage(packageInfo, null, [netInfo, randomInfo, utilInfo]); diff --git a/packages/util-crypto/packageInfo.d.ts b/packages/util-crypto/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/util-crypto/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/util-crypto/packageInfo.js b/packages/util-crypto/packageInfo.js new file mode 100644 index 0000000..fe7acd3 --- /dev/null +++ b/packages/util-crypto/packageInfo.js @@ -0,0 +1 @@ +export const packageInfo = { name: '@pezkuwi/util-crypto', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; diff --git a/packages/util-crypto/pbkdf2/encode.d.ts b/packages/util-crypto/pbkdf2/encode.d.ts new file mode 100644 index 0000000..cc745b0 --- /dev/null +++ b/packages/util-crypto/pbkdf2/encode.d.ts @@ -0,0 +1,7 @@ +interface Result { + password: Uint8Array; + rounds: number; + salt: Uint8Array; +} +export declare function pbkdf2Encode(passphrase?: string | Uint8Array, salt?: Uint8Array, rounds?: number, onlyJs?: boolean): Result; +export {}; diff --git a/packages/util-crypto/pbkdf2/encode.js b/packages/util-crypto/pbkdf2/encode.js new file mode 100644 index 0000000..fe33834 --- /dev/null +++ b/packages/util-crypto/pbkdf2/encode.js @@ -0,0 +1,16 @@ +import { pbkdf2 as pbkdf2Js } from '@noble/hashes/pbkdf2'; +import { sha512 } from '@noble/hashes/sha512'; +import { hasBigInt, u8aToU8a } from '@pezkuwi/util'; +import { isReady, pbkdf2 } from '@pezkuwi/wasm-crypto'; +import { randomAsU8a } from '../random/asU8a.js'; +export function pbkdf2Encode(passphrase, salt = randomAsU8a(), rounds = 2048, onlyJs) { + const u8aPass = u8aToU8a(passphrase); + const u8aSalt = u8aToU8a(salt); + return { + password: !hasBigInt || (!onlyJs && isReady()) + ? pbkdf2(u8aPass, u8aSalt, rounds) + : pbkdf2Js(sha512, u8aPass, u8aSalt, { c: rounds, dkLen: 64 }), + rounds, + salt + }; +} diff --git a/packages/util-crypto/pbkdf2/index.d.ts b/packages/util-crypto/pbkdf2/index.d.ts new file mode 100644 index 0000000..8c1dd5d --- /dev/null +++ b/packages/util-crypto/pbkdf2/index.d.ts @@ -0,0 +1 @@ +export { pbkdf2Encode } from './encode.js'; diff --git a/packages/util-crypto/pbkdf2/index.js b/packages/util-crypto/pbkdf2/index.js new file mode 100644 index 0000000..8c1dd5d --- /dev/null +++ b/packages/util-crypto/pbkdf2/index.js @@ -0,0 +1 @@ +export { pbkdf2Encode } from './encode.js'; diff --git a/packages/util-crypto/random/asNumber.d.ts b/packages/util-crypto/random/asNumber.d.ts new file mode 100644 index 0000000..c1fb451 --- /dev/null +++ b/packages/util-crypto/random/asNumber.d.ts @@ -0,0 +1,15 @@ +/** + * @name randomAsNumber + * @summary Creates a random number from random bytes. + * @description + * Returns a random number generated from the secure bytes. + * @example + *
+ * + * ```javascript + * import { randomAsNumber } from '@pezkuwi/util-crypto'; + * + * randomAsNumber(); // => + * ``` + */ +export declare function randomAsNumber(): number; diff --git a/packages/util-crypto/random/asNumber.js b/packages/util-crypto/random/asNumber.js new file mode 100644 index 0000000..961e7e4 --- /dev/null +++ b/packages/util-crypto/random/asNumber.js @@ -0,0 +1,20 @@ +import { BN, hexToBn } from '@pezkuwi/util'; +import { randomAsHex } from './asU8a.js'; +const BN_53 = new BN(0b11111111111111111111111111111111111111111111111111111); +/** + * @name randomAsNumber + * @summary Creates a random number from random bytes. + * @description + * Returns a random number generated from the secure bytes. + * @example + *
+ * + * ```javascript + * import { randomAsNumber } from '@pezkuwi/util-crypto'; + * + * randomAsNumber(); // => + * ``` + */ +export function randomAsNumber() { + return hexToBn(randomAsHex(8)).and(BN_53).toNumber(); +} diff --git a/packages/util-crypto/random/asU8a.d.ts b/packages/util-crypto/random/asU8a.d.ts new file mode 100644 index 0000000..1d9cf89 --- /dev/null +++ b/packages/util-crypto/random/asU8a.d.ts @@ -0,0 +1,20 @@ +/** + * @name randomAsU8a + * @summary Creates a Uint8Array filled with random bytes. + * @description + * Returns a `Uint8Array` with the specified (optional) length filled with random bytes. + * @example + *
+ * + * ```javascript + * import { randomAsU8a } from '@pezkuwi/util-crypto'; + * + * randomAsU8a(); // => Uint8Array([...]) + * ``` + */ +export declare function randomAsU8a(length?: number): Uint8Array; +/** + * @name randomAsHex + * @description Creates a hex string filled with random bytes. + */ +export declare const randomAsHex: (length?: number | undefined) => import("@pezkuwi/util/types").HexString; diff --git a/packages/util-crypto/random/asU8a.js b/packages/util-crypto/random/asU8a.js new file mode 100644 index 0000000..d2462b3 --- /dev/null +++ b/packages/util-crypto/random/asU8a.js @@ -0,0 +1,24 @@ +import { getRandomValues } from '@pezkuwi/x-randomvalues'; +import { createAsHex } from '../helpers.js'; +/** + * @name randomAsU8a + * @summary Creates a Uint8Array filled with random bytes. + * @description + * Returns a `Uint8Array` with the specified (optional) length filled with random bytes. + * @example + *
+ * + * ```javascript + * import { randomAsU8a } from '@pezkuwi/util-crypto'; + * + * randomAsU8a(); // => Uint8Array([...]) + * ``` + */ +export function randomAsU8a(length = 32) { + return getRandomValues(new Uint8Array(length)); +} +/** + * @name randomAsHex + * @description Creates a hex string filled with random bytes. + */ +export const randomAsHex = /*#__PURE__*/ createAsHex(randomAsU8a); diff --git a/packages/util-crypto/random/index.d.ts b/packages/util-crypto/random/index.d.ts new file mode 100644 index 0000000..cdc2b7d --- /dev/null +++ b/packages/util-crypto/random/index.d.ts @@ -0,0 +1,5 @@ +/** + * @summary Returns a sequence of secure random bytes in a variety of formats + */ +export { randomAsNumber } from './asNumber.js'; +export { randomAsHex, randomAsU8a } from './asU8a.js'; diff --git a/packages/util-crypto/random/index.js b/packages/util-crypto/random/index.js new file mode 100644 index 0000000..cdc2b7d --- /dev/null +++ b/packages/util-crypto/random/index.js @@ -0,0 +1,5 @@ +/** + * @summary Returns a sequence of secure random bytes in a variety of formats + */ +export { randomAsNumber } from './asNumber.js'; +export { randomAsHex, randomAsU8a } from './asU8a.js'; diff --git a/packages/util-crypto/scrypt/defaults.d.ts b/packages/util-crypto/scrypt/defaults.d.ts new file mode 100644 index 0000000..8b9c36d --- /dev/null +++ b/packages/util-crypto/scrypt/defaults.d.ts @@ -0,0 +1,3 @@ +import type { ScryptParams } from './types.js'; +export declare const ALLOWED_PARAMS: ScryptParams[]; +export declare const DEFAULT_PARAMS: ScryptParams; diff --git a/packages/util-crypto/scrypt/defaults.js b/packages/util-crypto/scrypt/defaults.js new file mode 100644 index 0000000..dbf987c --- /dev/null +++ b/packages/util-crypto/scrypt/defaults.js @@ -0,0 +1,13 @@ +export const ALLOWED_PARAMS = [ + { N: 1 << 13, p: 10, r: 8 }, + { N: 1 << 14, p: 5, r: 8 }, + { N: 1 << 15, p: 3, r: 8 }, + { N: 1 << 15, p: 1, r: 8 }, + { N: 1 << 16, p: 2, r: 8 }, + { N: 1 << 17, p: 1, r: 8 } +]; +export const DEFAULT_PARAMS = { + N: 1 << 17, + p: 1, + r: 8 +}; diff --git a/packages/util-crypto/scrypt/encode.d.ts b/packages/util-crypto/scrypt/encode.d.ts new file mode 100644 index 0000000..2fbfb46 --- /dev/null +++ b/packages/util-crypto/scrypt/encode.d.ts @@ -0,0 +1,8 @@ +import type { ScryptParams } from './types.js'; +interface Result { + params: ScryptParams; + password: Uint8Array; + salt: Uint8Array; +} +export declare function scryptEncode(passphrase?: string | Uint8Array, salt?: Uint8Array, params?: ScryptParams, onlyJs?: boolean): Result; +export {}; diff --git a/packages/util-crypto/scrypt/encode.js b/packages/util-crypto/scrypt/encode.js new file mode 100644 index 0000000..254737a --- /dev/null +++ b/packages/util-crypto/scrypt/encode.js @@ -0,0 +1,15 @@ +import { scrypt as scryptJs } from '@noble/hashes/scrypt'; +import { hasBigInt, objectSpread, u8aToU8a } from '@pezkuwi/util'; +import { isReady, scrypt } from '@pezkuwi/wasm-crypto'; +import { randomAsU8a } from '../random/asU8a.js'; +import { DEFAULT_PARAMS } from './defaults.js'; +export function scryptEncode(passphrase, salt = randomAsU8a(), params = DEFAULT_PARAMS, onlyJs) { + const u8a = u8aToU8a(passphrase); + return { + params, + password: !hasBigInt || (!onlyJs && isReady()) + ? scrypt(u8a, salt, Math.log2(params.N), params.r, params.p) + : scryptJs(u8a, salt, objectSpread({ dkLen: 64 }, params)), + salt + }; +} diff --git a/packages/util-crypto/scrypt/fromU8a.d.ts b/packages/util-crypto/scrypt/fromU8a.d.ts new file mode 100644 index 0000000..b0bf75e --- /dev/null +++ b/packages/util-crypto/scrypt/fromU8a.d.ts @@ -0,0 +1,7 @@ +import type { ScryptParams } from './types.js'; +interface Result { + params: ScryptParams; + salt: Uint8Array; +} +export declare function scryptFromU8a(data: Uint8Array): Result; +export {}; diff --git a/packages/util-crypto/scrypt/fromU8a.js b/packages/util-crypto/scrypt/fromU8a.js new file mode 100644 index 0000000..951ab63 --- /dev/null +++ b/packages/util-crypto/scrypt/fromU8a.js @@ -0,0 +1,24 @@ +import { u8aToBn } from '@pezkuwi/util'; +import { BN_LE_OPTS } from '../bn.js'; +import { ALLOWED_PARAMS } from './defaults.js'; +export function scryptFromU8a(data) { + if (!(data instanceof Uint8Array)) { + throw new Error('Expected input to be a Uint8Array'); + } + // Ensure the input is exactly 44 bytes: 32 for salt + 3 * 4 for N, p, r + if (data.length < 32 + 12) { + throw new Error(`Invalid input length: expected 44 bytes, found ${data.length}`); + } + const salt = data.subarray(0, 32); + const N = u8aToBn(data.subarray(32, 36), BN_LE_OPTS).toNumber(); + const p = u8aToBn(data.subarray(36, 40), BN_LE_OPTS).toNumber(); + const r = u8aToBn(data.subarray(40, 44), BN_LE_OPTS).toNumber(); + if (N > (1 << 20) || p > 4 || r > 16) { + throw new Error('Scrypt parameters exceed safe limits'); + } + const isAllowed = ALLOWED_PARAMS.some((preset) => preset.N === N && preset.p === p && preset.r === r); + if (!isAllowed) { + throw new Error('Invalid injected scrypt params found'); + } + return { params: { N, p, r }, salt }; +} diff --git a/packages/util-crypto/scrypt/index.d.ts b/packages/util-crypto/scrypt/index.d.ts new file mode 100644 index 0000000..5cd1784 --- /dev/null +++ b/packages/util-crypto/scrypt/index.d.ts @@ -0,0 +1,3 @@ +export { scryptEncode } from './encode.js'; +export { scryptFromU8a } from './fromU8a.js'; +export { scryptToU8a } from './toU8a.js'; diff --git a/packages/util-crypto/scrypt/index.js b/packages/util-crypto/scrypt/index.js new file mode 100644 index 0000000..5cd1784 --- /dev/null +++ b/packages/util-crypto/scrypt/index.js @@ -0,0 +1,3 @@ +export { scryptEncode } from './encode.js'; +export { scryptFromU8a } from './fromU8a.js'; +export { scryptToU8a } from './toU8a.js'; diff --git a/packages/util-crypto/scrypt/toU8a.d.ts b/packages/util-crypto/scrypt/toU8a.d.ts new file mode 100644 index 0000000..17bd6de --- /dev/null +++ b/packages/util-crypto/scrypt/toU8a.d.ts @@ -0,0 +1,2 @@ +import type { ScryptParams } from './types.js'; +export declare function scryptToU8a(salt: Uint8Array, { N, p, r }: ScryptParams): Uint8Array; diff --git a/packages/util-crypto/scrypt/toU8a.js b/packages/util-crypto/scrypt/toU8a.js new file mode 100644 index 0000000..346c81c --- /dev/null +++ b/packages/util-crypto/scrypt/toU8a.js @@ -0,0 +1,5 @@ +import { bnToU8a, u8aConcat } from '@pezkuwi/util'; +import { BN_LE_32_OPTS } from '../bn.js'; +export function scryptToU8a(salt, { N, p, r }) { + return u8aConcat(salt, bnToU8a(N, BN_LE_32_OPTS), bnToU8a(p, BN_LE_32_OPTS), bnToU8a(r, BN_LE_32_OPTS)); +} diff --git a/packages/util-crypto/scrypt/types.d.ts b/packages/util-crypto/scrypt/types.d.ts new file mode 100644 index 0000000..3d5c89e --- /dev/null +++ b/packages/util-crypto/scrypt/types.d.ts @@ -0,0 +1,6 @@ +/** The params that control scrypt generation */ +export interface ScryptParams { + N: number; + p: number; + r: number; +} diff --git a/packages/util-crypto/scrypt/types.js b/packages/util-crypto/scrypt/types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/util-crypto/scrypt/types.js @@ -0,0 +1 @@ +export {}; diff --git a/packages/util-crypto/secp256k1/compress.d.ts b/packages/util-crypto/secp256k1/compress.d.ts new file mode 100644 index 0000000..8e66a56 --- /dev/null +++ b/packages/util-crypto/secp256k1/compress.d.ts @@ -0,0 +1 @@ +export declare function secp256k1Compress(publicKey: Uint8Array, onlyJs?: boolean): Uint8Array; diff --git a/packages/util-crypto/secp256k1/compress.js b/packages/util-crypto/secp256k1/compress.js new file mode 100644 index 0000000..acfe735 --- /dev/null +++ b/packages/util-crypto/secp256k1/compress.js @@ -0,0 +1,14 @@ +import { secp256k1 } from '@noble/curves/secp256k1'; +import { hasBigInt } from '@pezkuwi/util'; +import { isReady, secp256k1Compress as wasm } from '@pezkuwi/wasm-crypto'; +export function secp256k1Compress(publicKey, onlyJs) { + if (![33, 65].includes(publicKey.length)) { + throw new Error(`Invalid publicKey provided, received ${publicKey.length} bytes input`); + } + if (publicKey.length === 33) { + return publicKey; + } + return !hasBigInt || (!onlyJs && isReady()) + ? wasm(publicKey) + : secp256k1.ProjectivePoint.fromHex(publicKey).toRawBytes(true); +} diff --git a/packages/util-crypto/secp256k1/deriveHard.d.ts b/packages/util-crypto/secp256k1/deriveHard.d.ts new file mode 100644 index 0000000..cd064c0 --- /dev/null +++ b/packages/util-crypto/secp256k1/deriveHard.d.ts @@ -0,0 +1 @@ +export declare function secp256k1DeriveHard(seed: Uint8Array, chainCode: Uint8Array): Uint8Array; diff --git a/packages/util-crypto/secp256k1/deriveHard.js b/packages/util-crypto/secp256k1/deriveHard.js new file mode 100644 index 0000000..062071c --- /dev/null +++ b/packages/util-crypto/secp256k1/deriveHard.js @@ -0,0 +1,10 @@ +import { compactAddLength, isU8a, stringToU8a, u8aConcat } from '@pezkuwi/util'; +import { blake2AsU8a } from '../blake2/asU8a.js'; +const HDKD = compactAddLength(stringToU8a('Secp256k1HDKD')); +export function secp256k1DeriveHard(seed, chainCode) { + if (!isU8a(chainCode) || chainCode.length !== 32) { + throw new Error('Invalid chainCode passed to derive'); + } + // NOTE This is specific to the Substrate HDD derivation, so always use the blake2 hasher + return blake2AsU8a(u8aConcat(HDKD, seed, chainCode), 256); +} diff --git a/packages/util-crypto/secp256k1/expand.d.ts b/packages/util-crypto/secp256k1/expand.d.ts new file mode 100644 index 0000000..193bf02 --- /dev/null +++ b/packages/util-crypto/secp256k1/expand.d.ts @@ -0,0 +1 @@ +export declare function secp256k1Expand(publicKey: Uint8Array, onlyJs?: boolean): Uint8Array; diff --git a/packages/util-crypto/secp256k1/expand.js b/packages/util-crypto/secp256k1/expand.js new file mode 100644 index 0000000..61316cb --- /dev/null +++ b/packages/util-crypto/secp256k1/expand.js @@ -0,0 +1,17 @@ +import { secp256k1 } from '@noble/curves/secp256k1'; +import { bnToU8a, hasBigInt, u8aConcat } from '@pezkuwi/util'; +import { isReady, secp256k1Expand as wasm } from '@pezkuwi/wasm-crypto'; +import { BN_BE_256_OPTS } from '../bn.js'; +export function secp256k1Expand(publicKey, onlyJs) { + if (![33, 65].includes(publicKey.length)) { + throw new Error(`Invalid publicKey provided, received ${publicKey.length} bytes input`); + } + if (publicKey.length === 65) { + return publicKey.subarray(1); + } + if (!hasBigInt || (!onlyJs && isReady())) { + return wasm(publicKey).subarray(1); + } + const { px, py } = secp256k1.ProjectivePoint.fromHex(publicKey); + return u8aConcat(bnToU8a(px, BN_BE_256_OPTS), bnToU8a(py, BN_BE_256_OPTS)); +} diff --git a/packages/util-crypto/secp256k1/hasher.d.ts b/packages/util-crypto/secp256k1/hasher.d.ts new file mode 100644 index 0000000..3acdcd5 --- /dev/null +++ b/packages/util-crypto/secp256k1/hasher.d.ts @@ -0,0 +1,2 @@ +import type { HashType } from './types.js'; +export declare function hasher(hashType: HashType, data: Uint8Array | string, onlyJs?: boolean): Uint8Array; diff --git a/packages/util-crypto/secp256k1/hasher.js b/packages/util-crypto/secp256k1/hasher.js new file mode 100644 index 0000000..45657a4 --- /dev/null +++ b/packages/util-crypto/secp256k1/hasher.js @@ -0,0 +1,7 @@ +import { blake2AsU8a } from '../blake2/index.js'; +import { keccakAsU8a } from '../keccak/index.js'; +export function hasher(hashType, data, onlyJs) { + return hashType === 'keccak' + ? keccakAsU8a(data, undefined, onlyJs) + : blake2AsU8a(data, undefined, undefined, onlyJs); +} diff --git a/packages/util-crypto/secp256k1/index.d.ts b/packages/util-crypto/secp256k1/index.d.ts new file mode 100644 index 0000000..06bdece --- /dev/null +++ b/packages/util-crypto/secp256k1/index.d.ts @@ -0,0 +1,7 @@ +export { secp256k1Compress } from './compress.js'; +export { secp256k1Expand } from './expand.js'; +export { secp256k1PairFromSeed } from './pair/fromSeed.js'; +export { secp256k1Recover } from './recover.js'; +export { secp256k1Sign } from './sign.js'; +export { secp256k1PrivateKeyTweakAdd } from './tweakAdd.js'; +export { secp256k1Verify } from './verify.js'; diff --git a/packages/util-crypto/secp256k1/index.js b/packages/util-crypto/secp256k1/index.js new file mode 100644 index 0000000..06bdece --- /dev/null +++ b/packages/util-crypto/secp256k1/index.js @@ -0,0 +1,7 @@ +export { secp256k1Compress } from './compress.js'; +export { secp256k1Expand } from './expand.js'; +export { secp256k1PairFromSeed } from './pair/fromSeed.js'; +export { secp256k1Recover } from './recover.js'; +export { secp256k1Sign } from './sign.js'; +export { secp256k1PrivateKeyTweakAdd } from './tweakAdd.js'; +export { secp256k1Verify } from './verify.js'; diff --git a/packages/util-crypto/secp256k1/pair/fromSeed.d.ts b/packages/util-crypto/secp256k1/pair/fromSeed.d.ts new file mode 100644 index 0000000..2dd2cc8 --- /dev/null +++ b/packages/util-crypto/secp256k1/pair/fromSeed.d.ts @@ -0,0 +1,6 @@ +import type { Keypair } from '../../types.js'; +/** + * @name secp256k1PairFromSeed + * @description Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed. + */ +export declare function secp256k1PairFromSeed(seed: Uint8Array, onlyJs?: boolean): Keypair; diff --git a/packages/util-crypto/secp256k1/pair/fromSeed.js b/packages/util-crypto/secp256k1/pair/fromSeed.js new file mode 100644 index 0000000..d054b7a --- /dev/null +++ b/packages/util-crypto/secp256k1/pair/fromSeed.js @@ -0,0 +1,31 @@ +import { secp256k1 } from '@noble/curves/secp256k1'; +import { hasBigInt, u8aEmpty } from '@pezkuwi/util'; +import { isReady, secp256k1FromSeed } from '@pezkuwi/wasm-crypto'; +/** + * @name secp256k1PairFromSeed + * @description Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed. + */ +export function secp256k1PairFromSeed(seed, onlyJs) { + if (seed.length !== 32) { + throw new Error('Expected valid 32-byte private key as a seed'); + } + if (!hasBigInt || (!onlyJs && isReady())) { + const full = secp256k1FromSeed(seed); + const publicKey = full.slice(32); + // There is an issue with the secp256k1 when running in an ASM.js environment where + // it seems that the lazy static section yields invalid results on the _first_ run. + // If this happens, fail outright, we cannot allow invalid return values + // https://github.com/polkadot-js/wasm/issues/307 + if (u8aEmpty(publicKey)) { + throw new Error('Invalid publicKey generated from WASM interface'); + } + return { + publicKey, + secretKey: full.slice(0, 32) + }; + } + return { + publicKey: secp256k1.getPublicKey(seed, true), + secretKey: seed + }; +} diff --git a/packages/util-crypto/secp256k1/recover.d.ts b/packages/util-crypto/secp256k1/recover.d.ts new file mode 100644 index 0000000..d82d6a3 --- /dev/null +++ b/packages/util-crypto/secp256k1/recover.d.ts @@ -0,0 +1,6 @@ +import type { HashType } from './types.js'; +/** + * @name secp256k1Recover + * @description Recovers a publicKey from the supplied signature + */ +export declare function secp256k1Recover(msgHash: string | Uint8Array, signature: string | Uint8Array, recovery: number, hashType?: HashType, onlyJs?: boolean): Uint8Array; diff --git a/packages/util-crypto/secp256k1/recover.js b/packages/util-crypto/secp256k1/recover.js new file mode 100644 index 0000000..6a5d566 --- /dev/null +++ b/packages/util-crypto/secp256k1/recover.js @@ -0,0 +1,26 @@ +import { secp256k1 } from '@noble/curves/secp256k1'; +import { hasBigInt, u8aToU8a } from '@pezkuwi/util'; +import { isReady, secp256k1Recover as wasm } from '@pezkuwi/wasm-crypto'; +import { secp256k1Compress } from './compress.js'; +import { secp256k1Expand } from './expand.js'; +/** + * @name secp256k1Recover + * @description Recovers a publicKey from the supplied signature + */ +export function secp256k1Recover(msgHash, signature, recovery, hashType = 'blake2', onlyJs) { + const sig = u8aToU8a(signature).subarray(0, 64); + const msg = u8aToU8a(msgHash); + const publicKey = !hasBigInt || (!onlyJs && isReady()) + ? wasm(msg, sig, recovery) + : secp256k1.Signature + .fromCompact(sig) + .addRecoveryBit(recovery) + .recoverPublicKey(msg) + .toRawBytes(); + if (!publicKey) { + throw new Error('Unable to recover publicKey from signature'); + } + return hashType === 'keccak' + ? secp256k1Expand(publicKey, onlyJs) + : secp256k1Compress(publicKey, onlyJs); +} diff --git a/packages/util-crypto/secp256k1/sign.d.ts b/packages/util-crypto/secp256k1/sign.d.ts new file mode 100644 index 0000000..5a86fc6 --- /dev/null +++ b/packages/util-crypto/secp256k1/sign.d.ts @@ -0,0 +1,7 @@ +import type { Keypair } from '../types.js'; +import type { HashType } from './types.js'; +/** + * @name secp256k1Sign + * @description Returns message signature of `message`, using the supplied pair + */ +export declare function secp256k1Sign(message: Uint8Array | string, { secretKey }: Partial, hashType?: HashType, onlyJs?: boolean): Uint8Array; diff --git a/packages/util-crypto/secp256k1/sign.js b/packages/util-crypto/secp256k1/sign.js new file mode 100644 index 0000000..74cd58c --- /dev/null +++ b/packages/util-crypto/secp256k1/sign.js @@ -0,0 +1,20 @@ +import { secp256k1 } from '@noble/curves/secp256k1'; +import { bnToU8a, hasBigInt, u8aConcat } from '@pezkuwi/util'; +import { isReady, secp256k1Sign as wasm } from '@pezkuwi/wasm-crypto'; +import { BN_BE_256_OPTS } from '../bn.js'; +import { hasher } from './hasher.js'; +/** + * @name secp256k1Sign + * @description Returns message signature of `message`, using the supplied pair + */ +export function secp256k1Sign(message, { secretKey }, hashType = 'blake2', onlyJs) { + if (secretKey?.length !== 32) { + throw new Error('Expected valid secp256k1 secretKey, 32-bytes'); + } + const data = hasher(hashType, message, onlyJs); + if (!hasBigInt || (!onlyJs && isReady())) { + return wasm(data, secretKey); + } + const signature = secp256k1.sign(data, secretKey, { lowS: true }); + return u8aConcat(bnToU8a(signature.r, BN_BE_256_OPTS), bnToU8a(signature.s, BN_BE_256_OPTS), new Uint8Array([signature.recovery || 0])); +} diff --git a/packages/util-crypto/secp256k1/tweakAdd.d.ts b/packages/util-crypto/secp256k1/tweakAdd.d.ts new file mode 100644 index 0000000..ed6591e --- /dev/null +++ b/packages/util-crypto/secp256k1/tweakAdd.d.ts @@ -0,0 +1 @@ +export declare function secp256k1PrivateKeyTweakAdd(seckey: Uint8Array, tweak: Uint8Array, onlyBn?: boolean): Uint8Array; diff --git a/packages/util-crypto/secp256k1/tweakAdd.js b/packages/util-crypto/secp256k1/tweakAdd.js new file mode 100644 index 0000000..9fd9c6a --- /dev/null +++ b/packages/util-crypto/secp256k1/tweakAdd.js @@ -0,0 +1,45 @@ +import { _0n, BN, bnToU8a, hasBigInt, isU8a, nToU8a, u8aToBigInt } from '@pezkuwi/util'; +import { BigInt } from '@pezkuwi/x-bigint'; +import { BN_BE_256_OPTS, BN_BE_OPTS } from '../bn.js'; +const N = 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141'.replace(/ /g, ''); +const N_BI = BigInt(`0x${N}`); +const N_BN = new BN(N, 'hex'); +function addBi(seckey, tweak) { + let res = u8aToBigInt(tweak, BN_BE_OPTS); + if (res >= N_BI) { + throw new Error('Tweak parameter is out of range'); + } + res += u8aToBigInt(seckey, BN_BE_OPTS); + if (res >= N_BI) { + res -= N_BI; + } + if (res === _0n) { + throw new Error('Invalid resulting private key'); + } + return nToU8a(res, BN_BE_256_OPTS); +} +function addBn(seckey, tweak) { + const res = new BN(tweak); + if (res.cmp(N_BN) >= 0) { + throw new Error('Tweak parameter is out of range'); + } + res.iadd(new BN(seckey)); + if (res.cmp(N_BN) >= 0) { + res.isub(N_BN); + } + if (res.isZero()) { + throw new Error('Invalid resulting private key'); + } + return bnToU8a(res, BN_BE_256_OPTS); +} +export function secp256k1PrivateKeyTweakAdd(seckey, tweak, onlyBn) { + if (!isU8a(seckey) || seckey.length !== 32) { + throw new Error('Expected seckey to be an Uint8Array with length 32'); + } + else if (!isU8a(tweak) || tweak.length !== 32) { + throw new Error('Expected tweak to be an Uint8Array with length 32'); + } + return !hasBigInt || onlyBn + ? addBn(seckey, tweak) + : addBi(seckey, tweak); +} diff --git a/packages/util-crypto/secp256k1/types.d.ts b/packages/util-crypto/secp256k1/types.d.ts new file mode 100644 index 0000000..016b877 --- /dev/null +++ b/packages/util-crypto/secp256k1/types.d.ts @@ -0,0 +1 @@ +export type HashType = 'blake2' | 'keccak'; diff --git a/packages/util-crypto/secp256k1/types.js b/packages/util-crypto/secp256k1/types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/util-crypto/secp256k1/types.js @@ -0,0 +1 @@ +export {}; diff --git a/packages/util-crypto/secp256k1/verify.d.ts b/packages/util-crypto/secp256k1/verify.d.ts new file mode 100644 index 0000000..bf6b8d3 --- /dev/null +++ b/packages/util-crypto/secp256k1/verify.d.ts @@ -0,0 +1,6 @@ +import type { HashType } from './types.js'; +/** + * @name secp256k1Verify + * @description Verifies the signature of `message`, using the supplied pair + */ +export declare function secp256k1Verify(msgHash: string | Uint8Array, signature: string | Uint8Array, address: string | Uint8Array, hashType?: HashType, onlyJs?: boolean): boolean; diff --git a/packages/util-crypto/secp256k1/verify.js b/packages/util-crypto/secp256k1/verify.js new file mode 100644 index 0000000..e0e54a9 --- /dev/null +++ b/packages/util-crypto/secp256k1/verify.js @@ -0,0 +1,20 @@ +import { u8aEq, u8aToU8a } from '@pezkuwi/util'; +import { hasher } from './hasher.js'; +import { secp256k1Recover } from './recover.js'; +/** + * @name secp256k1Verify + * @description Verifies the signature of `message`, using the supplied pair + */ +export function secp256k1Verify(msgHash, signature, address, hashType = 'blake2', onlyJs) { + const sig = u8aToU8a(signature); + if (sig.length !== 65) { + throw new Error(`Expected signature with 65 bytes, ${sig.length} found instead`); + } + const publicKey = secp256k1Recover(hasher(hashType, msgHash), sig, sig[64], hashType, onlyJs); + const signerAddr = hasher(hashType, publicKey, onlyJs); + const inputAddr = u8aToU8a(address); + // for Ethereum (keccak) the last 20 bytes is the address + return u8aEq(publicKey, inputAddr) || (hashType === 'keccak' + ? u8aEq(signerAddr.slice(-20), inputAddr.slice(-20)) + : u8aEq(signerAddr, inputAddr)); +} diff --git a/packages/util-crypto/sha/asU8a.d.ts b/packages/util-crypto/sha/asU8a.d.ts new file mode 100644 index 0000000..974b164 --- /dev/null +++ b/packages/util-crypto/sha/asU8a.d.ts @@ -0,0 +1,15 @@ +/** + * @name shaAsU8a + * @summary Creates a sha Uint8Array from the input. + */ +export declare const shaAsU8a: (value: string | Uint8Array, bitLength?: 256 | 512, onlyJs?: boolean) => Uint8Array; +/** + * @name sha256AsU8a + * @summary Creates a sha256 Uint8Array from the input. + */ +export declare const sha256AsU8a: (data: string | Uint8Array, onlyJs?: boolean) => Uint8Array; +/** + * @name sha512AsU8a + * @summary Creates a sha512 Uint8Array from the input. + */ +export declare const sha512AsU8a: (data: string | Uint8Array, onlyJs?: boolean) => Uint8Array; diff --git a/packages/util-crypto/sha/asU8a.js b/packages/util-crypto/sha/asU8a.js new file mode 100644 index 0000000..c9931c9 --- /dev/null +++ b/packages/util-crypto/sha/asU8a.js @@ -0,0 +1,19 @@ +import { sha256 as sha256Js } from '@noble/hashes/sha256'; +import { sha512 as sha512Js } from '@noble/hashes/sha512'; +import { sha256, sha512 } from '@pezkuwi/wasm-crypto'; +import { createBitHasher, createDualHasher } from '../helpers.js'; +/** + * @name shaAsU8a + * @summary Creates a sha Uint8Array from the input. + */ +export const shaAsU8a = /*#__PURE__*/ createDualHasher({ 256: sha256, 512: sha512 }, { 256: sha256Js, 512: sha512Js }); +/** + * @name sha256AsU8a + * @summary Creates a sha256 Uint8Array from the input. + */ +export const sha256AsU8a = /*#__PURE__*/ createBitHasher(256, shaAsU8a); +/** + * @name sha512AsU8a + * @summary Creates a sha512 Uint8Array from the input. + */ +export const sha512AsU8a = /*#__PURE__*/ createBitHasher(512, shaAsU8a); diff --git a/packages/util-crypto/sha/index.d.ts b/packages/util-crypto/sha/index.d.ts new file mode 100644 index 0000000..9bc6226 --- /dev/null +++ b/packages/util-crypto/sha/index.d.ts @@ -0,0 +1,4 @@ +/** + * @summary Implements Sha-256/512 hashing functions for a variety of input and outputs + */ +export { sha256AsU8a, sha512AsU8a, shaAsU8a } from './asU8a.js'; diff --git a/packages/util-crypto/sha/index.js b/packages/util-crypto/sha/index.js new file mode 100644 index 0000000..9bc6226 --- /dev/null +++ b/packages/util-crypto/sha/index.js @@ -0,0 +1,4 @@ +/** + * @summary Implements Sha-256/512 hashing functions for a variety of input and outputs + */ +export { sha256AsU8a, sha512AsU8a, shaAsU8a } from './asU8a.js'; diff --git a/packages/util-crypto/signature/index.d.ts b/packages/util-crypto/signature/index.d.ts new file mode 100644 index 0000000..685361c --- /dev/null +++ b/packages/util-crypto/signature/index.d.ts @@ -0,0 +1,4 @@ +/** + * @summary Utilities for working with signatures + */ +export { signatureVerify } from './verify.js'; diff --git a/packages/util-crypto/signature/index.js b/packages/util-crypto/signature/index.js new file mode 100644 index 0000000..685361c --- /dev/null +++ b/packages/util-crypto/signature/index.js @@ -0,0 +1,4 @@ +/** + * @summary Utilities for working with signatures + */ +export { signatureVerify } from './verify.js'; diff --git a/packages/util-crypto/signature/verify.d.ts b/packages/util-crypto/signature/verify.d.ts new file mode 100644 index 0000000..1bfdaca --- /dev/null +++ b/packages/util-crypto/signature/verify.d.ts @@ -0,0 +1,2 @@ +import type { VerifyResult } from '../types.js'; +export declare function signatureVerify(message: string | Uint8Array, signature: string | Uint8Array, addressOrPublicKey: string | Uint8Array): VerifyResult; diff --git a/packages/util-crypto/signature/verify.js b/packages/util-crypto/signature/verify.js new file mode 100644 index 0000000..2498597 --- /dev/null +++ b/packages/util-crypto/signature/verify.js @@ -0,0 +1,78 @@ +import { u8aIsWrapped, u8aToU8a, u8aUnwrapBytes, u8aWrapBytes } from '@pezkuwi/util'; +import { decodeAddress } from '../address/decode.js'; +import { ed25519Verify } from '../ed25519/verify.js'; +import { secp256k1Verify } from '../secp256k1/verify.js'; +import { sr25519Verify } from '../sr25519/verify.js'; +const secp256k1VerifyHasher = (hashType) => (message, signature, publicKey) => secp256k1Verify(message, signature, publicKey, hashType, true); +const VERIFIERS_ECDSA = [ + ['ecdsa', secp256k1VerifyHasher('blake2')], + ['ethereum', secp256k1VerifyHasher('keccak')] +]; +const VERIFIERS = [ + ['ed25519', ed25519Verify], + ['sr25519', sr25519Verify] +]; +function verifyDetect(result, { message, publicKey, signature }, verifiers = [...VERIFIERS, ...VERIFIERS_ECDSA]) { + result.isValid = verifiers.some(([crypto, verify]) => { + try { + if (verify(message, signature, publicKey)) { + result.crypto = crypto; + return true; + } + } + catch { + // do nothing, result.isValid still set to false + } + return false; + }); + return result; +} +function verifyMultisig(result, { message, publicKey, signature }) { + if (![0, 1, 2].includes(signature[0]) || ![65, 66].includes(signature.length)) { + throw new Error(`Unknown crypto type, expected signature prefix [0..2], found ${signature[0]}`); + } + // If the signature is 66 bytes it must be an ecdsa signature + // containing: prefix [1 byte] + signature [65] bytes. + // Remove the and then verify + if (signature.length === 66) { + result = verifyDetect(result, { message, publicKey, signature: signature.subarray(1) }, VERIFIERS_ECDSA); + } + else { + // The signature contains 65 bytes which is either + // - A ed25519 or sr25519 signature [1 byte prefix + 64 bytes] + // - An ecdsa signature [65 bytes] + result = verifyDetect(result, { message, publicKey, signature: signature.subarray(1) }, VERIFIERS); + if (!result.isValid) { + result = verifyDetect(result, { message, publicKey, signature }, VERIFIERS_ECDSA); + } + // If both failed, explicitly set crypto to 'none' + if (!result.isValid) { + result.crypto = 'none'; + } + } + return result; +} +function getVerifyFn(signature) { + return [0, 1, 2].includes(signature[0]) && [65, 66].includes(signature.length) + ? verifyMultisig + : verifyDetect; +} +export function signatureVerify(message, signature, addressOrPublicKey) { + const signatureU8a = u8aToU8a(signature); + if (![64, 65, 66].includes(signatureU8a.length)) { + throw new Error(`Invalid signature length, expected [64..66] bytes, found ${signatureU8a.length}`); + } + const publicKey = decodeAddress(addressOrPublicKey); + const input = { message: u8aToU8a(message), publicKey, signature: signatureU8a }; + const result = { crypto: 'none', isValid: false, isWrapped: u8aIsWrapped(input.message, true), publicKey }; + const isWrappedBytes = u8aIsWrapped(input.message, false); + const verifyFn = getVerifyFn(signatureU8a); + verifyFn(result, input); + if (result.crypto !== 'none' || (result.isWrapped && !isWrappedBytes)) { + return result; + } + input.message = isWrappedBytes + ? u8aUnwrapBytes(input.message) + : u8aWrapBytes(input.message); + return verifyFn(result, input); +} diff --git a/packages/util-crypto/sr25519/agreement.d.ts b/packages/util-crypto/sr25519/agreement.d.ts new file mode 100644 index 0000000..a316893 --- /dev/null +++ b/packages/util-crypto/sr25519/agreement.d.ts @@ -0,0 +1,5 @@ +/** + * @name sr25519Agreement + * @description Key agreement between other's public key and self secret key + */ +export declare function sr25519Agreement(secretKey: string | Uint8Array, publicKey: string | Uint8Array): Uint8Array; diff --git a/packages/util-crypto/sr25519/agreement.js b/packages/util-crypto/sr25519/agreement.js new file mode 100644 index 0000000..0f51dc6 --- /dev/null +++ b/packages/util-crypto/sr25519/agreement.js @@ -0,0 +1,17 @@ +import { getSharedSecret } from '@scure/sr25519'; +import { u8aToU8a } from '@pezkuwi/util'; +/** + * @name sr25519Agreement + * @description Key agreement between other's public key and self secret key + */ +export function sr25519Agreement(secretKey, publicKey) { + const secretKeyU8a = u8aToU8a(secretKey); + const publicKeyU8a = u8aToU8a(publicKey); + if (publicKeyU8a.length !== 32) { + throw new Error(`Invalid publicKey, received ${publicKeyU8a.length} bytes, expected 32`); + } + else if (secretKeyU8a.length !== 64) { + throw new Error(`Invalid secretKey, received ${secretKeyU8a.length} bytes, expected 64`); + } + return getSharedSecret(secretKeyU8a, publicKeyU8a); +} diff --git a/packages/util-crypto/sr25519/derive.d.ts b/packages/util-crypto/sr25519/derive.d.ts new file mode 100644 index 0000000..a9b3a68 --- /dev/null +++ b/packages/util-crypto/sr25519/derive.d.ts @@ -0,0 +1,2 @@ +import type { Keypair } from '../types.js'; +export declare function createDeriveFn(derive: (pair: Uint8Array, cc: Uint8Array) => Uint8Array): (keypair: Keypair, chainCode: Uint8Array) => Keypair; diff --git a/packages/util-crypto/sr25519/derive.js b/packages/util-crypto/sr25519/derive.js new file mode 100644 index 0000000..dc064cd --- /dev/null +++ b/packages/util-crypto/sr25519/derive.js @@ -0,0 +1,12 @@ +import * as sr25519 from '@scure/sr25519'; +import { isU8a } from '@pezkuwi/util'; +export function createDeriveFn(derive) { + return (keypair, chainCode) => { + if (!isU8a(chainCode) || chainCode.length !== 32) { + throw new Error('Invalid chainCode passed to derive'); + } + const secretKey = derive(keypair.secretKey, chainCode); + const publicKey = sr25519.getPublicKey(secretKey); + return { publicKey, secretKey }; + }; +} diff --git a/packages/util-crypto/sr25519/deriveHard.d.ts b/packages/util-crypto/sr25519/deriveHard.d.ts new file mode 100644 index 0000000..471f9e0 --- /dev/null +++ b/packages/util-crypto/sr25519/deriveHard.d.ts @@ -0,0 +1 @@ +export declare const sr25519DeriveHard: (keypair: import("../types.js").Keypair, chainCode: Uint8Array) => import("../types.js").Keypair; diff --git a/packages/util-crypto/sr25519/deriveHard.js b/packages/util-crypto/sr25519/deriveHard.js new file mode 100644 index 0000000..a2e03e4 --- /dev/null +++ b/packages/util-crypto/sr25519/deriveHard.js @@ -0,0 +1,3 @@ +import * as sr25519 from '@scure/sr25519'; +import { createDeriveFn } from './derive.js'; +export const sr25519DeriveHard = /*#__PURE__*/ createDeriveFn(sr25519.HDKD.secretHard); diff --git a/packages/util-crypto/sr25519/derivePublic.d.ts b/packages/util-crypto/sr25519/derivePublic.d.ts new file mode 100644 index 0000000..dcd1687 --- /dev/null +++ b/packages/util-crypto/sr25519/derivePublic.d.ts @@ -0,0 +1 @@ +export declare function sr25519DerivePublic(publicKey: string | Uint8Array, chainCode: Uint8Array): Uint8Array; diff --git a/packages/util-crypto/sr25519/derivePublic.js b/packages/util-crypto/sr25519/derivePublic.js new file mode 100644 index 0000000..965b603 --- /dev/null +++ b/packages/util-crypto/sr25519/derivePublic.js @@ -0,0 +1,12 @@ +import * as sr25519 from '@scure/sr25519'; +import { isU8a, u8aToU8a } from '@pezkuwi/util'; +export function sr25519DerivePublic(publicKey, chainCode) { + const publicKeyU8a = u8aToU8a(publicKey); + if (!isU8a(chainCode) || chainCode.length !== 32) { + throw new Error('Invalid chainCode passed to derive'); + } + else if (publicKeyU8a.length !== 32) { + throw new Error(`Invalid publicKey, received ${publicKeyU8a.length} bytes, expected 32`); + } + return sr25519.HDKD.publicSoft(publicKeyU8a, chainCode); +} diff --git a/packages/util-crypto/sr25519/deriveSoft.d.ts b/packages/util-crypto/sr25519/deriveSoft.d.ts new file mode 100644 index 0000000..4bd044e --- /dev/null +++ b/packages/util-crypto/sr25519/deriveSoft.d.ts @@ -0,0 +1 @@ +export declare const sr25519DeriveSoft: (keypair: import("../types.js").Keypair, chainCode: Uint8Array) => import("../types.js").Keypair; diff --git a/packages/util-crypto/sr25519/deriveSoft.js b/packages/util-crypto/sr25519/deriveSoft.js new file mode 100644 index 0000000..2be2faf --- /dev/null +++ b/packages/util-crypto/sr25519/deriveSoft.js @@ -0,0 +1,3 @@ +import * as sr25519 from '@scure/sr25519'; +import { createDeriveFn } from './derive.js'; +export const sr25519DeriveSoft = /*#__PURE__*/ createDeriveFn(sr25519.HDKD.secretSoft); diff --git a/packages/util-crypto/sr25519/index.d.ts b/packages/util-crypto/sr25519/index.d.ts new file mode 100644 index 0000000..3fdb022 --- /dev/null +++ b/packages/util-crypto/sr25519/index.d.ts @@ -0,0 +1,9 @@ +export { sr25519Agreement } from './agreement.js'; +export { sr25519DeriveHard } from './deriveHard.js'; +export { sr25519DerivePublic } from './derivePublic.js'; +export { sr25519DeriveSoft } from './deriveSoft.js'; +export { sr25519PairFromSeed } from './pair/fromSeed.js'; +export { sr25519Sign } from './sign.js'; +export { sr25519Verify } from './verify.js'; +export { sr25519VrfSign } from './vrfSign.js'; +export { sr25519VrfVerify } from './vrfVerify.js'; diff --git a/packages/util-crypto/sr25519/index.js b/packages/util-crypto/sr25519/index.js new file mode 100644 index 0000000..3fdb022 --- /dev/null +++ b/packages/util-crypto/sr25519/index.js @@ -0,0 +1,9 @@ +export { sr25519Agreement } from './agreement.js'; +export { sr25519DeriveHard } from './deriveHard.js'; +export { sr25519DerivePublic } from './derivePublic.js'; +export { sr25519DeriveSoft } from './deriveSoft.js'; +export { sr25519PairFromSeed } from './pair/fromSeed.js'; +export { sr25519Sign } from './sign.js'; +export { sr25519Verify } from './verify.js'; +export { sr25519VrfSign } from './vrfSign.js'; +export { sr25519VrfVerify } from './vrfVerify.js'; diff --git a/packages/util-crypto/sr25519/pair/fromSeed.d.ts b/packages/util-crypto/sr25519/pair/fromSeed.d.ts new file mode 100644 index 0000000..cc9e13c --- /dev/null +++ b/packages/util-crypto/sr25519/pair/fromSeed.d.ts @@ -0,0 +1,6 @@ +import type { Keypair } from '../../types.js'; +/** + * @name sr25519PairFromSeed + * @description Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed. + */ +export declare function sr25519PairFromSeed(seed: string | Uint8Array): Keypair; diff --git a/packages/util-crypto/sr25519/pair/fromSeed.js b/packages/util-crypto/sr25519/pair/fromSeed.js new file mode 100644 index 0000000..6ac1f03 --- /dev/null +++ b/packages/util-crypto/sr25519/pair/fromSeed.js @@ -0,0 +1,18 @@ +import * as sr25519 from '@scure/sr25519'; +import { u8aToU8a } from '@pezkuwi/util'; +/** + * @name sr25519PairFromSeed + * @description Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed. + */ +export function sr25519PairFromSeed(seed) { + const seedU8a = u8aToU8a(seed); + if (seedU8a.length !== 32) { + throw new Error(`Expected a seed matching 32 bytes, found ${seedU8a.length}`); + } + const sec = sr25519.secretFromSeed(seedU8a); + const pub = sr25519.getPublicKey(sec); + return { + publicKey: pub, + secretKey: sec + }; +} diff --git a/packages/util-crypto/sr25519/pair/fromU8a.d.ts b/packages/util-crypto/sr25519/pair/fromU8a.d.ts new file mode 100644 index 0000000..472a9cd --- /dev/null +++ b/packages/util-crypto/sr25519/pair/fromU8a.d.ts @@ -0,0 +1,2 @@ +import type { Keypair } from '../../types.js'; +export declare function sr25519PairFromU8a(full: string | Uint8Array): Keypair; diff --git a/packages/util-crypto/sr25519/pair/fromU8a.js b/packages/util-crypto/sr25519/pair/fromU8a.js new file mode 100644 index 0000000..71eab1f --- /dev/null +++ b/packages/util-crypto/sr25519/pair/fromU8a.js @@ -0,0 +1,14 @@ +import { u8aToU8a } from '@pezkuwi/util'; +const SEC_LEN = 64; +const PUB_LEN = 32; +const TOT_LEN = SEC_LEN + PUB_LEN; +export function sr25519PairFromU8a(full) { + const fullU8a = u8aToU8a(full); + if (fullU8a.length !== TOT_LEN) { + throw new Error(`Expected keypair with ${TOT_LEN} bytes, found ${fullU8a.length}`); + } + return { + publicKey: fullU8a.slice(SEC_LEN, TOT_LEN), + secretKey: fullU8a.slice(0, SEC_LEN) + }; +} diff --git a/packages/util-crypto/sr25519/pair/toU8a.d.ts b/packages/util-crypto/sr25519/pair/toU8a.d.ts new file mode 100644 index 0000000..1472b5a --- /dev/null +++ b/packages/util-crypto/sr25519/pair/toU8a.d.ts @@ -0,0 +1,2 @@ +import type { Keypair } from '../../types.js'; +export declare function sr25519KeypairToU8a({ publicKey, secretKey }: Keypair): Uint8Array; diff --git a/packages/util-crypto/sr25519/pair/toU8a.js b/packages/util-crypto/sr25519/pair/toU8a.js new file mode 100644 index 0000000..0a1d5db --- /dev/null +++ b/packages/util-crypto/sr25519/pair/toU8a.js @@ -0,0 +1,4 @@ +import { u8aConcat } from '@pezkuwi/util'; +export function sr25519KeypairToU8a({ publicKey, secretKey }) { + return u8aConcat(secretKey, publicKey).slice(); +} diff --git a/packages/util-crypto/sr25519/sign.d.ts b/packages/util-crypto/sr25519/sign.d.ts new file mode 100644 index 0000000..b63958c --- /dev/null +++ b/packages/util-crypto/sr25519/sign.d.ts @@ -0,0 +1,6 @@ +import type { Keypair } from '../types.js'; +/** + * @name sr25519Sign + * @description Returns message signature of `message`, using the supplied pair + */ +export declare function sr25519Sign(message: string | Uint8Array, { publicKey, secretKey }: Partial): Uint8Array; diff --git a/packages/util-crypto/sr25519/sign.js b/packages/util-crypto/sr25519/sign.js new file mode 100644 index 0000000..9741adb --- /dev/null +++ b/packages/util-crypto/sr25519/sign.js @@ -0,0 +1,15 @@ +import * as sr25519 from '@scure/sr25519'; +import { u8aToU8a } from '@pezkuwi/util'; +/** + * @name sr25519Sign + * @description Returns message signature of `message`, using the supplied pair + */ +export function sr25519Sign(message, { publicKey, secretKey }) { + if (publicKey?.length !== 32) { + throw new Error('Expected a valid publicKey, 32-bytes'); + } + else if (secretKey?.length !== 64) { + throw new Error('Expected a valid secretKey, 64-bytes'); + } + return sr25519.sign(secretKey, u8aToU8a(message)); +} diff --git a/packages/util-crypto/sr25519/verify.d.ts b/packages/util-crypto/sr25519/verify.d.ts new file mode 100644 index 0000000..e6560ed --- /dev/null +++ b/packages/util-crypto/sr25519/verify.d.ts @@ -0,0 +1,5 @@ +/** + * @name sr25519Verify + * @description Verifies the signature of `message`, using the supplied pair + */ +export declare function sr25519Verify(message: string | Uint8Array, signature: string | Uint8Array, publicKey: string | Uint8Array): boolean; diff --git a/packages/util-crypto/sr25519/verify.js b/packages/util-crypto/sr25519/verify.js new file mode 100644 index 0000000..c8d7016 --- /dev/null +++ b/packages/util-crypto/sr25519/verify.js @@ -0,0 +1,17 @@ +import * as sr25519 from '@scure/sr25519'; +import { u8aToU8a } from '@pezkuwi/util'; +/** + * @name sr25519Verify + * @description Verifies the signature of `message`, using the supplied pair + */ +export function sr25519Verify(message, signature, publicKey) { + const publicKeyU8a = u8aToU8a(publicKey); + const signatureU8a = u8aToU8a(signature); + if (publicKeyU8a.length !== 32) { + throw new Error(`Invalid publicKey, received ${publicKeyU8a.length} bytes, expected 32`); + } + else if (signatureU8a.length !== 64) { + throw new Error(`Invalid signature, received ${signatureU8a.length} bytes, expected 64`); + } + return sr25519.verify(u8aToU8a(message), signatureU8a, publicKeyU8a); +} diff --git a/packages/util-crypto/sr25519/vrfSign.d.ts b/packages/util-crypto/sr25519/vrfSign.d.ts new file mode 100644 index 0000000..b3519f0 --- /dev/null +++ b/packages/util-crypto/sr25519/vrfSign.d.ts @@ -0,0 +1,6 @@ +import type { Keypair } from '../types.js'; +/** + * @name sr25519VrfSign + * @description Sign with sr25519 vrf signing (deterministic) + */ +export declare function sr25519VrfSign(message: string | Uint8Array, { secretKey }: Partial, context?: string | Uint8Array, extra?: string | Uint8Array): Uint8Array; diff --git a/packages/util-crypto/sr25519/vrfSign.js b/packages/util-crypto/sr25519/vrfSign.js new file mode 100644 index 0000000..af47213 --- /dev/null +++ b/packages/util-crypto/sr25519/vrfSign.js @@ -0,0 +1,15 @@ +import { randomBytes } from '@noble/hashes/utils'; +import * as sr25519 from '@scure/sr25519'; +import { u8aToU8a } from '@pezkuwi/util'; +const EMPTY_U8A = new Uint8Array(); +/** + * @name sr25519VrfSign + * @description Sign with sr25519 vrf signing (deterministic) + */ +export function sr25519VrfSign(message, { secretKey }, context = EMPTY_U8A, extra = EMPTY_U8A) { + if (secretKey?.length !== 64) { + throw new Error('Invalid secretKey, expected 64-bytes'); + } + return sr25519.vrf.sign(u8aToU8a(message), secretKey, u8aToU8a(context), u8aToU8a(extra), randomBytes); + // return vrfSign(secretKey, u8aToU8a(context), u8aToU8a(message), u8aToU8a(extra)); +} diff --git a/packages/util-crypto/sr25519/vrfVerify.d.ts b/packages/util-crypto/sr25519/vrfVerify.d.ts new file mode 100644 index 0000000..11148c7 --- /dev/null +++ b/packages/util-crypto/sr25519/vrfVerify.d.ts @@ -0,0 +1,5 @@ +/** + * @name sr25519VrfVerify + * @description Verify with sr25519 vrf verification + */ +export declare function sr25519VrfVerify(message: string | Uint8Array, signOutput: string | Uint8Array, publicKey: string | Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): boolean; diff --git a/packages/util-crypto/sr25519/vrfVerify.js b/packages/util-crypto/sr25519/vrfVerify.js new file mode 100644 index 0000000..7125d4e --- /dev/null +++ b/packages/util-crypto/sr25519/vrfVerify.js @@ -0,0 +1,18 @@ +import * as sr25519 from '@scure/sr25519'; +import { u8aToU8a } from '@pezkuwi/util'; +const EMPTY_U8A = new Uint8Array(); +/** + * @name sr25519VrfVerify + * @description Verify with sr25519 vrf verification + */ +export function sr25519VrfVerify(message, signOutput, publicKey, context = EMPTY_U8A, extra = EMPTY_U8A) { + const publicKeyU8a = u8aToU8a(publicKey); + const proofU8a = u8aToU8a(signOutput); + if (publicKeyU8a.length !== 32) { + throw new Error('Invalid publicKey, expected 32-bytes'); + } + else if (proofU8a.length !== 96) { + throw new Error('Invalid vrfSign output, expected 96 bytes'); + } + return sr25519.vrf.verify(u8aToU8a(message), proofU8a, publicKeyU8a, u8aToU8a(context), u8aToU8a(extra)); +} diff --git a/packages/util-crypto/types.d.ts b/packages/util-crypto/types.d.ts new file mode 100644 index 0000000..3d41bc3 --- /dev/null +++ b/packages/util-crypto/types.d.ts @@ -0,0 +1,26 @@ +export * from './address/types.js'; +export * from './json/types.js'; +export interface Keypair { + /** The publicKey for this pair */ + publicKey: Uint8Array; + /** The secretKey for this pair */ + secretKey: Uint8Array; +} +export interface Seedpair { + /** The publicKey for this pair */ + publicKey: Uint8Array; + /** The seed used to construct the pair */ + seed: Uint8Array; +} +/** The supported types of pairs */ +export type KeypairType = 'ed25519' | 'sr25519' | 'ecdsa' | 'ethereum'; +export interface VerifyResult { + /** The detected crypto interface, or 'none' if not detected */ + crypto: 'none' | KeypairType; + /** The validity for this result, false if invalid */ + isValid: boolean; + /** Flag to indicate if the passed data was wrapped in ... */ + isWrapped: boolean; + /** The extracted publicKey */ + publicKey: Uint8Array; +} diff --git a/packages/util-crypto/types.js b/packages/util-crypto/types.js new file mode 100644 index 0000000..fa9a162 --- /dev/null +++ b/packages/util-crypto/types.js @@ -0,0 +1,2 @@ +export * from './address/types.js'; +export * from './json/types.js'; diff --git a/packages/util-crypto/xxhash/asU8a.d.ts b/packages/util-crypto/xxhash/asU8a.d.ts new file mode 100644 index 0000000..084b9ba --- /dev/null +++ b/packages/util-crypto/xxhash/asU8a.d.ts @@ -0,0 +1,20 @@ +/** + * @name xxhashAsU8a + * @summary Creates a xxhash64 u8a from the input. + * @description + * From either a `string`, `Uint8Array` or a `Buffer` input, create the xxhash64 and return the result as a `Uint8Array` with the specified `bitLength`. + * @example + *
+ * + * ```javascript + * import { xxhashAsU8a } from '@pezkuwi/util-crypto'; + * + * xxhashAsU8a('abc'); // => 0x44bc2cf5ad770999 + * ``` + */ +export declare function xxhashAsU8a(data: string | Uint8Array, bitLength?: 64 | 128 | 192 | 256 | 320 | 384 | 448 | 512, onlyJs?: boolean): Uint8Array; +/** + * @name xxhashAsHex + * @description Creates a xxhash64 hex from the input. + */ +export declare const xxhashAsHex: (data: string | Uint8Array, bitLength?: 256 | 512 | 64 | 128 | 384 | 320 | 192 | 448 | undefined, onlyJs?: boolean | undefined) => import("@pezkuwi/util/types").HexString; diff --git a/packages/util-crypto/xxhash/asU8a.js b/packages/util-crypto/xxhash/asU8a.js new file mode 100644 index 0000000..f0c3835 --- /dev/null +++ b/packages/util-crypto/xxhash/asU8a.js @@ -0,0 +1,35 @@ +import { hasBigInt, u8aToU8a } from '@pezkuwi/util'; +import { isReady, twox } from '@pezkuwi/wasm-crypto'; +import { createAsHex } from '../helpers.js'; +import { xxhash64 } from './xxhash64.js'; +/** + * @name xxhashAsU8a + * @summary Creates a xxhash64 u8a from the input. + * @description + * From either a `string`, `Uint8Array` or a `Buffer` input, create the xxhash64 and return the result as a `Uint8Array` with the specified `bitLength`. + * @example + *
+ * + * ```javascript + * import { xxhashAsU8a } from '@pezkuwi/util-crypto'; + * + * xxhashAsU8a('abc'); // => 0x44bc2cf5ad770999 + * ``` + */ +export function xxhashAsU8a(data, bitLength = 64, onlyJs) { + const rounds = Math.ceil(bitLength / 64); + const u8a = u8aToU8a(data); + if (!hasBigInt || (!onlyJs && isReady())) { + return twox(u8a, rounds); + } + const result = new Uint8Array(rounds * 8); + for (let seed = 0; seed < rounds; seed++) { + result.set(xxhash64(u8a, seed).reverse(), seed * 8); + } + return result; +} +/** + * @name xxhashAsHex + * @description Creates a xxhash64 hex from the input. + */ +export const xxhashAsHex = /*#__PURE__*/ createAsHex(xxhashAsU8a); diff --git a/packages/util-crypto/xxhash/index.d.ts b/packages/util-crypto/xxhash/index.d.ts new file mode 100644 index 0000000..d81cae2 --- /dev/null +++ b/packages/util-crypto/xxhash/index.d.ts @@ -0,0 +1,4 @@ +/** + * @summary Create xxhash64 values with specified bitlengths + */ +export { xxhashAsHex, xxhashAsU8a } from './asU8a.js'; diff --git a/packages/util-crypto/xxhash/index.js b/packages/util-crypto/xxhash/index.js new file mode 100644 index 0000000..d81cae2 --- /dev/null +++ b/packages/util-crypto/xxhash/index.js @@ -0,0 +1,4 @@ +/** + * @summary Create xxhash64 values with specified bitlengths + */ +export { xxhashAsHex, xxhashAsU8a } from './asU8a.js'; diff --git a/packages/util-crypto/xxhash/xxhash64.d.ts b/packages/util-crypto/xxhash/xxhash64.d.ts new file mode 100644 index 0000000..7dcfcc2 --- /dev/null +++ b/packages/util-crypto/xxhash/xxhash64.d.ts @@ -0,0 +1 @@ +export declare function xxhash64(input: Uint8Array, initSeed: bigint | number): Uint8Array; diff --git a/packages/util-crypto/xxhash/xxhash64.js b/packages/util-crypto/xxhash/xxhash64.js new file mode 100644 index 0000000..2900e5f --- /dev/null +++ b/packages/util-crypto/xxhash/xxhash64.js @@ -0,0 +1,100 @@ +import { _0n, _1n } from '@pezkuwi/util'; +import { BigInt } from '@pezkuwi/x-bigint'; +const P64_1 = BigInt('11400714785074694791'); +const P64_2 = BigInt('14029467366897019727'); +const P64_3 = BigInt('1609587929392839161'); +const P64_4 = BigInt('9650029242287828579'); +const P64_5 = BigInt('2870177450012600261'); +const U64 = BigInt('0xffffffffffffffff'); +const _7n = BigInt(7); +const _11n = BigInt(11); +const _12n = BigInt(12); +const _16n = BigInt(16); +const _18n = BigInt(18); +const _23n = BigInt(23); +const _27n = BigInt(27); +const _29n = BigInt(29); +const _31n = BigInt(31); +const _32n = BigInt(32); +const _33n = BigInt(33); +const _64n = BigInt(64); +const _256n = BigInt(256); +function rotl(a, b) { + const c = a & U64; + return ((c << b) | (c >> (_64n - b))) & U64; +} +function fromU8a(u8a, p, count) { + const bigints = new Array(count); + let offset = 0; + for (let i = 0; i < count; i++, offset += 2) { + bigints[i] = BigInt(u8a[p + offset] | (u8a[p + 1 + offset] << 8)); + } + let result = _0n; + for (let i = count - 1; i >= 0; i--) { + result = (result << _16n) + bigints[i]; + } + return result; +} +function init(seed, input) { + const state = { + seed, + u8a: new Uint8Array(32), + u8asize: 0, + v1: seed + P64_1 + P64_2, + v2: seed + P64_2, + v3: seed, + v4: seed - P64_1 + }; + if (input.length < 32) { + state.u8a.set(input); + state.u8asize = input.length; + return state; + } + const limit = input.length - 32; + let p = 0; + if (limit >= 0) { + const adjustV = (v) => P64_1 * rotl(v + P64_2 * fromU8a(input, p, 4), _31n); + do { + state.v1 = adjustV(state.v1); + p += 8; + state.v2 = adjustV(state.v2); + p += 8; + state.v3 = adjustV(state.v3); + p += 8; + state.v4 = adjustV(state.v4); + p += 8; + } while (p <= limit); + } + if (p < input.length) { + state.u8a.set(input.subarray(p, input.length)); + state.u8asize = input.length - p; + } + return state; +} +export function xxhash64(input, initSeed) { + const { seed, u8a, u8asize, v1, v2, v3, v4 } = init(BigInt(initSeed), input); + let p = 0; + let h64 = U64 & (BigInt(input.length) + (input.length >= 32 + ? (((((((((rotl(v1, _1n) + rotl(v2, _7n) + rotl(v3, _12n) + rotl(v4, _18n)) ^ (P64_1 * rotl(v1 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v2 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v3 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v4 * P64_2, _31n))) * P64_1 + P64_4) + : (seed + P64_5))); + while (p <= (u8asize - 8)) { + h64 = U64 & (P64_4 + P64_1 * rotl(h64 ^ (P64_1 * rotl(P64_2 * fromU8a(u8a, p, 4), _31n)), _27n)); + p += 8; + } + if ((p + 4) <= u8asize) { + h64 = U64 & (P64_3 + P64_2 * rotl(h64 ^ (P64_1 * fromU8a(u8a, p, 2)), _23n)); + p += 4; + } + while (p < u8asize) { + h64 = U64 & (P64_1 * rotl(h64 ^ (P64_5 * BigInt(u8a[p++])), _11n)); + } + h64 = U64 & (P64_2 * (h64 ^ (h64 >> _33n))); + h64 = U64 & (P64_3 * (h64 ^ (h64 >> _29n))); + h64 = U64 & (h64 ^ (h64 >> _32n)); + const result = new Uint8Array(8); + for (let i = 7; i >= 0; i--) { + result[i] = Number(h64 % _256n); + h64 = h64 / _256n; + } + return result; +} diff --git a/packages/util/array/chunk.d.ts b/packages/util/array/chunk.d.ts new file mode 100644 index 0000000..c085420 --- /dev/null +++ b/packages/util/array/chunk.d.ts @@ -0,0 +1,15 @@ +/** + * @name arrayChunk + * @summary Split T[] into T[][] based on the defind size + * @description + * Returns a set ao arrays based on the chunksize + * @example + *
+ * + * ```javascript + * import { arrayChunk } from '@pezkuwi/util'; + * + * arrayChunk([1, 2, 3, 4, 5]); // [[1, 2], [3, 4], [5]] + * ``` + */ +export declare function arrayChunk(array: T[], chunkSize: number): T[][]; diff --git a/packages/util/array/chunk.js b/packages/util/array/chunk.js new file mode 100644 index 0000000..8826f2d --- /dev/null +++ b/packages/util/array/chunk.js @@ -0,0 +1,27 @@ +/** + * @name arrayChunk + * @summary Split T[] into T[][] based on the defind size + * @description + * Returns a set ao arrays based on the chunksize + * @example + *
+ * + * ```javascript + * import { arrayChunk } from '@pezkuwi/util'; + * + * arrayChunk([1, 2, 3, 4, 5]); // [[1, 2], [3, 4], [5]] + * ``` + */ +export function arrayChunk(array, chunkSize) { + const outputSize = Math.ceil(array.length / chunkSize); + // shortcut for the single-split case + if (outputSize === 1) { + return [array]; + } + const output = Array(outputSize); + for (let i = 0; i < outputSize; i++) { + const offset = i * chunkSize; + output[i] = array.slice(offset, offset + chunkSize); + } + return output; +} diff --git a/packages/util/array/filter.d.ts b/packages/util/array/filter.d.ts new file mode 100644 index 0000000..d8be6ab --- /dev/null +++ b/packages/util/array/filter.d.ts @@ -0,0 +1,16 @@ +/** + * @name arrayFilter + * @summary Filters undefined and (optionally) null values from an array + * @description + * Returns a new array with all `undefined` values removed. Optionally, when `allowNulls = false`, it removes the `null` values as well + * @example + *
+ * + * ```javascript + * import { arrayFilter } from '@pezkuwi/util'; + * + * arrayFilter([0, void 0, true, null, false, '']); // [0, true, null, false, ''] + * arrayFilter([0, void 0, true, null, false, ''], false); // [0, true, false, ''] + * ``` + */ +export declare function arrayFilter(array: readonly (T | null | undefined)[], allowNulls?: boolean): T[]; diff --git a/packages/util/array/filter.js b/packages/util/array/filter.js new file mode 100644 index 0000000..b7a4425 --- /dev/null +++ b/packages/util/array/filter.js @@ -0,0 +1,19 @@ +/** + * @name arrayFilter + * @summary Filters undefined and (optionally) null values from an array + * @description + * Returns a new array with all `undefined` values removed. Optionally, when `allowNulls = false`, it removes the `null` values as well + * @example + *
+ * + * ```javascript + * import { arrayFilter } from '@pezkuwi/util'; + * + * arrayFilter([0, void 0, true, null, false, '']); // [0, true, null, false, ''] + * arrayFilter([0, void 0, true, null, false, ''], false); // [0, true, false, ''] + * ``` + */ +export function arrayFilter(array, allowNulls = true) { + return array.filter((v) => v !== undefined && + (allowNulls || v !== null)); +} diff --git a/packages/util/array/flatten.d.ts b/packages/util/array/flatten.d.ts new file mode 100644 index 0000000..49fa218 --- /dev/null +++ b/packages/util/array/flatten.d.ts @@ -0,0 +1,15 @@ +/** + * @name arrayFlatten + * @summary Merge T[][] into T[] + * @description + * Returns a new array with all arrays merged into one + * @example + *
+ * + * ```javascript + * import { arrayFlatten } from '@pezkuwi/util'; + * + * arrayFlatten([[1, 2], [3, 4], [5]]); // [1, 2, 3, 4, 5] + * ``` + */ +export declare function arrayFlatten(arrays: readonly T[][]): T[]; diff --git a/packages/util/array/flatten.js b/packages/util/array/flatten.js new file mode 100644 index 0000000..4029590 --- /dev/null +++ b/packages/util/array/flatten.js @@ -0,0 +1,39 @@ +/** + * @name arrayFlatten + * @summary Merge T[][] into T[] + * @description + * Returns a new array with all arrays merged into one + * @example + *
+ * + * ```javascript + * import { arrayFlatten } from '@pezkuwi/util'; + * + * arrayFlatten([[1, 2], [3, 4], [5]]); // [1, 2, 3, 4, 5] + * ``` + */ +export function arrayFlatten(arrays) { + const num = arrays.length; + // shortcuts for the empty & single-entry case + if (num === 0) { + return []; + } + else if (num === 1) { + return arrays[0]; + } + // pre-allocate based on the combined size + let size = 0; + for (let i = 0; i < num; i++) { + size += arrays[i].length; + } + const output = new Array(size); + let i = -1; + for (let j = 0; j < num; j++) { + const a = arrays[j]; + // instead of pushing, we just set the entries + for (let e = 0, count = a.length; e < count; e++) { + output[++i] = a[e]; + } + } + return output; +} diff --git a/packages/util/array/index.d.ts b/packages/util/array/index.d.ts new file mode 100644 index 0000000..0f24c19 --- /dev/null +++ b/packages/util/array/index.d.ts @@ -0,0 +1,10 @@ +/** + * @summary Utility methods that operates on arrays + */ +export { arrayChunk } from './chunk.js'; +export { arrayFilter } from './filter.js'; +export { arrayFlatten } from './flatten.js'; +export { arrayRange } from './range.js'; +export { arrayShuffle } from './shuffle.js'; +export { arrayUnzip } from './unzip.js'; +export { arrayZip } from './zip.js'; diff --git a/packages/util/array/index.js b/packages/util/array/index.js new file mode 100644 index 0000000..0f24c19 --- /dev/null +++ b/packages/util/array/index.js @@ -0,0 +1,10 @@ +/** + * @summary Utility methods that operates on arrays + */ +export { arrayChunk } from './chunk.js'; +export { arrayFilter } from './filter.js'; +export { arrayFlatten } from './flatten.js'; +export { arrayRange } from './range.js'; +export { arrayShuffle } from './shuffle.js'; +export { arrayUnzip } from './unzip.js'; +export { arrayZip } from './zip.js'; diff --git a/packages/util/array/range.d.ts b/packages/util/array/range.d.ts new file mode 100644 index 0000000..7918d1d --- /dev/null +++ b/packages/util/array/range.d.ts @@ -0,0 +1,16 @@ +/** + * @name arrayRange + * @summary Returns a range of numbers ith the size and the specified offset + * @description + * Returns a new array of numbers with the specific size. Optionally, when `startAt`, is provided, it generates the range to start at a specific value. + * @example + *
+ * + * ```javascript + * import { arrayRange } from '@pezkuwi/util'; + * + * arrayRange(5); // [0, 1, 2, 3, 4] + * arrayRange(3, 5); // [5, 6, 7] + * ``` + */ +export declare function arrayRange(size: number, startAt?: number): number[]; diff --git a/packages/util/array/range.js b/packages/util/array/range.js new file mode 100644 index 0000000..ecec5bd --- /dev/null +++ b/packages/util/array/range.js @@ -0,0 +1,25 @@ +/** + * @name arrayRange + * @summary Returns a range of numbers ith the size and the specified offset + * @description + * Returns a new array of numbers with the specific size. Optionally, when `startAt`, is provided, it generates the range to start at a specific value. + * @example + *
+ * + * ```javascript + * import { arrayRange } from '@pezkuwi/util'; + * + * arrayRange(5); // [0, 1, 2, 3, 4] + * arrayRange(3, 5); // [5, 6, 7] + * ``` + */ +export function arrayRange(size, startAt = 0) { + if (size <= 0) { + throw new Error('Expected non-zero, positive number as a range size'); + } + const result = new Array(size); + for (let i = 0; i < size; i++) { + result[i] = i + startAt; + } + return result; +} diff --git a/packages/util/array/shuffle.d.ts b/packages/util/array/shuffle.d.ts new file mode 100644 index 0000000..6a6e34d --- /dev/null +++ b/packages/util/array/shuffle.d.ts @@ -0,0 +1,5 @@ +/** + * @name arrayShuffle + * @description Shuffles the input array (unlike sort, this is not done in-place) + */ +export declare function arrayShuffle(input: readonly T[]): T[]; diff --git a/packages/util/array/shuffle.js b/packages/util/array/shuffle.js new file mode 100644 index 0000000..1e17e66 --- /dev/null +++ b/packages/util/array/shuffle.js @@ -0,0 +1,19 @@ +/** + * @name arrayShuffle + * @description Shuffles the input array (unlike sort, this is not done in-place) + */ +export function arrayShuffle(input) { + const result = input.slice(); + let curr = result.length; + // noop for the single entry + if (curr === 1) { + return result; + } + while (curr !== 0) { + // ~~ is more performant than Math.floor + const rand = ~~(Math.random() * curr); + curr--; + [result[curr], result[rand]] = [result[rand], result[curr]]; + } + return result; +} diff --git a/packages/util/array/unzip.d.ts b/packages/util/array/unzip.d.ts new file mode 100644 index 0000000..e98ece0 --- /dev/null +++ b/packages/util/array/unzip.d.ts @@ -0,0 +1,5 @@ +/** + * @name arrayUnzip + * @description Splits a single [K, V][] into [K[], V[]] + */ +export declare function arrayUnzip(entries: readonly [K, V][]): [K[], V[]]; diff --git a/packages/util/array/unzip.js b/packages/util/array/unzip.js new file mode 100644 index 0000000..626585c --- /dev/null +++ b/packages/util/array/unzip.js @@ -0,0 +1,13 @@ +/** + * @name arrayUnzip + * @description Splits a single [K, V][] into [K[], V[]] + */ +export function arrayUnzip(entries) { + const count = entries.length; + const keys = new Array(count); + const values = new Array(count); + for (let i = 0; i < count; i++) { + [keys[i], values[i]] = entries[i]; + } + return [keys, values]; +} diff --git a/packages/util/array/zip.d.ts b/packages/util/array/zip.d.ts new file mode 100644 index 0000000..79769c7 --- /dev/null +++ b/packages/util/array/zip.d.ts @@ -0,0 +1,5 @@ +/** + * @name arrayZip + * @description Combines 2 distinct key/value arrays into a single [K, V] array + */ +export declare function arrayZip(keys: readonly K[], values: readonly V[]): [K, V][]; diff --git a/packages/util/array/zip.js b/packages/util/array/zip.js new file mode 100644 index 0000000..b53008d --- /dev/null +++ b/packages/util/array/zip.js @@ -0,0 +1,12 @@ +/** + * @name arrayZip + * @description Combines 2 distinct key/value arrays into a single [K, V] array + */ +export function arrayZip(keys, values) { + const count = keys.length; + const result = new Array(count); + for (let i = 0; i < count; i++) { + result[i] = [keys[i], values[i]]; + } + return result; +} diff --git a/packages/util/assert.d.ts b/packages/util/assert.d.ts new file mode 100644 index 0000000..bde2a0c --- /dev/null +++ b/packages/util/assert.d.ts @@ -0,0 +1,29 @@ +type MessageFn = () => string; +/** + * @name assert + * @summary Checks for a valid test, if not Error is thrown. + * @description + * Checks that `test` is a truthy value. If value is falsy (`null`, `undefined`, `false`, ...), it throws an Error with the supplied `message`. When `test` passes, `true` is returned. + * @example + *
+ * + * ```javascript + * const { assert } from '@pezkuwi/util'; + * + * assert(true, 'True should be true'); // passes + * assert(false, 'False should not be true'); // Error thrown + * assert(false, () => 'message'); // Error with 'message' + * ``` + */ +export declare function assert(condition: unknown, message: string | MessageFn): asserts condition; +/** + * @name assertReturn + * @description Returns when the value is not undefined/null, otherwise throws assertion error + */ +export declare function assertReturn(value: T | undefined | null, message: string | MessageFn): T; +/** + * @name assertUnreachable + * @description An assertion helper that ensures all codepaths are followed + */ +export declare function assertUnreachable(x: never): never; +export {}; diff --git a/packages/util/assert.js b/packages/util/assert.js new file mode 100644 index 0000000..63de559 --- /dev/null +++ b/packages/util/assert.js @@ -0,0 +1,39 @@ +import { isFunction } from './is/function.js'; +/** + * @name assert + * @summary Checks for a valid test, if not Error is thrown. + * @description + * Checks that `test` is a truthy value. If value is falsy (`null`, `undefined`, `false`, ...), it throws an Error with the supplied `message`. When `test` passes, `true` is returned. + * @example + *
+ * + * ```javascript + * const { assert } from '@pezkuwi/util'; + * + * assert(true, 'True should be true'); // passes + * assert(false, 'False should not be true'); // Error thrown + * assert(false, () => 'message'); // Error with 'message' + * ``` + */ +export function assert(condition, message) { + if (!condition) { + throw new Error(isFunction(message) + ? message() + : message); + } +} +/** + * @name assertReturn + * @description Returns when the value is not undefined/null, otherwise throws assertion error + */ +export function assertReturn(value, message) { + assert(value !== undefined && value !== null, message); + return value; +} +/** + * @name assertUnreachable + * @description An assertion helper that ensures all codepaths are followed + */ +export function assertUnreachable(x) { + throw new Error(`This codepath should be unreachable. Unhandled input: ${x}`); +} diff --git a/packages/util/bi/consts.d.ts b/packages/util/bi/consts.d.ts new file mode 100644 index 0000000..9b0f2fb --- /dev/null +++ b/packages/util/bi/consts.d.ts @@ -0,0 +1,90 @@ +/** + * @name _0n + * @summary BigInt constant for 0. + */ +export declare const _0n: bigint; +/** + * @name _1n + * @summary BigInt constant for 1. + */ +export declare const _1n: bigint; +/** + * @name _2n + * @summary BigInt constant for 2. + */ +export declare const _2n: bigint; +/** + * @name _3n + * @summary BigInt constant for 3. + */ +export declare const _3n: bigint; +/** + * @name _4n + * @summary BigInt constant for 4. + */ +export declare const _4n: bigint; +/** + * @name _5n + * @summary BigInt constant for 5. + */ +export declare const _5n: bigint; +/** + * @name _6n + * @summary BigInt constant for 6. + */ +export declare const _6n: bigint; +/** + * @name _7n + * @summary BigInt constant for 7. + */ +export declare const _7n: bigint; +/** + * @name _8n + * @summary BigInt constant for 8. + */ +export declare const _8n: bigint; +/** + * @name _9n + * @summary BigInt constant for 9. + */ +export declare const _9n: bigint; +/** + * @name _10n + * @summary BigInt constant for 10. + */ +export declare const _10n: bigint; +/** + * @name _100n + * @summary BigInt constant for 100. + */ +export declare const _100n: bigint; +/** + * @name _1000n + * @summary BigInt constant for 1000. + */ +export declare const _1000n: bigint; +/** + * @name _1Mn + * @summary BigInt constant for 1,000,000 (million). + */ +export declare const _1Mn: bigint; +/** +* @name _1Bn +* @summary BigInt constant for 1,000,000,000 (billion). +*/ +export declare const _1Bn: bigint; +/** +* @name _1Qn +* @summary BigInt constant for 1,000,000,000,000,000,000 (quitillion). +*/ +export declare const _1Qn: bigint; +/** +* @name _2pow53n +* @summary BigInt constant for MAX_SAFE_INTEGER +*/ +export declare const _2pow53n: bigint; +/** + * @name _sqrt2pow53n + * @summary BigInt constant for Math.sqrt(MAX_SAFE_INTEGER) + */ +export declare const _sqrt2pow53n: bigint; diff --git a/packages/util/bi/consts.js b/packages/util/bi/consts.js new file mode 100644 index 0000000..5612412 --- /dev/null +++ b/packages/util/bi/consts.js @@ -0,0 +1,91 @@ +import { BigInt } from '@pezkuwi/x-bigint'; +/** + * @name _0n + * @summary BigInt constant for 0. + */ +export const _0n = /*#__PURE__*/ BigInt(0); +/** + * @name _1n + * @summary BigInt constant for 1. + */ +export const _1n = /*#__PURE__*/ BigInt(1); +/** + * @name _2n + * @summary BigInt constant for 2. + */ +export const _2n = /*#__PURE__*/ BigInt(2); +/** + * @name _3n + * @summary BigInt constant for 3. + */ +export const _3n = /*#__PURE__*/ BigInt(3); +/** + * @name _4n + * @summary BigInt constant for 4. + */ +export const _4n = /*#__PURE__*/ BigInt(4); +/** + * @name _5n + * @summary BigInt constant for 5. + */ +export const _5n = /*#__PURE__*/ BigInt(5); +/** + * @name _6n + * @summary BigInt constant for 6. + */ +export const _6n = /*#__PURE__*/ BigInt(6); +/** + * @name _7n + * @summary BigInt constant for 7. + */ +export const _7n = /*#__PURE__*/ BigInt(7); +/** + * @name _8n + * @summary BigInt constant for 8. + */ +export const _8n = /*#__PURE__*/ BigInt(8); +/** + * @name _9n + * @summary BigInt constant for 9. + */ +export const _9n = /*#__PURE__*/ BigInt(9); +/** + * @name _10n + * @summary BigInt constant for 10. + */ +export const _10n = /*#__PURE__*/ BigInt(10); +/** + * @name _100n + * @summary BigInt constant for 100. + */ +export const _100n = /*#__PURE__*/ BigInt(100); +/** + * @name _1000n + * @summary BigInt constant for 1000. + */ +export const _1000n = /*#__PURE__*/ BigInt(1_000); +/** + * @name _1Mn + * @summary BigInt constant for 1,000,000 (million). + */ +export const _1Mn = /*#__PURE__*/ BigInt(1_000_000); +/** +* @name _1Bn +* @summary BigInt constant for 1,000,000,000 (billion). +*/ +export const _1Bn = /*#__PURE__*/ BigInt(1_000_000_000); +/** +* @name _1Qn +* @summary BigInt constant for 1,000,000,000,000,000,000 (quitillion). +*/ +export const _1Qn = _1Bn * _1Bn; +/** +* @name _2pow53n +* @summary BigInt constant for MAX_SAFE_INTEGER +*/ +export const _2pow53n = /*#__PURE__*/ BigInt(Number.MAX_SAFE_INTEGER); +/** + * @name _sqrt2pow53n + * @summary BigInt constant for Math.sqrt(MAX_SAFE_INTEGER) + */ +export const _sqrt2pow53n = /*#__PURE__*/ BigInt(94906265); diff --git a/packages/util/bi/helpers.d.ts b/packages/util/bi/helpers.d.ts new file mode 100644 index 0000000..204df81 --- /dev/null +++ b/packages/util/bi/helpers.d.ts @@ -0,0 +1,2 @@ +/** @internal */ +export declare function createCmp(cmp: (a: T, b: T) => boolean): (...items: T[]) => T; diff --git a/packages/util/bi/helpers.js b/packages/util/bi/helpers.js new file mode 100644 index 0000000..2c11aec --- /dev/null +++ b/packages/util/bi/helpers.js @@ -0,0 +1,16 @@ +/** @internal */ +export function createCmp(cmp) { + return (...items) => { + const count = items.length; + if (count === 0) { + throw new Error('Must provide one or more arguments'); + } + let result = items[0]; + for (let i = 1; i < count; i++) { + if (cmp(items[i], result)) { + result = items[i]; + } + } + return result; + }; +} diff --git a/packages/util/bi/index.d.ts b/packages/util/bi/index.d.ts new file mode 100644 index 0000000..3399c2e --- /dev/null +++ b/packages/util/bi/index.d.ts @@ -0,0 +1,9 @@ +/** + * @summary Utility methods to convert to and from `bigint` objects + */ +export { nMax, nMin } from './min.js'; +export { nSqrt } from './sqrt.js'; +export { nToBigInt } from './toBigInt.js'; +export { nToHex } from './toHex.js'; +export { nToU8a } from './toU8a.js'; +export * from './consts.js'; diff --git a/packages/util/bi/index.js b/packages/util/bi/index.js new file mode 100644 index 0000000..3399c2e --- /dev/null +++ b/packages/util/bi/index.js @@ -0,0 +1,9 @@ +/** + * @summary Utility methods to convert to and from `bigint` objects + */ +export { nMax, nMin } from './min.js'; +export { nSqrt } from './sqrt.js'; +export { nToBigInt } from './toBigInt.js'; +export { nToHex } from './toHex.js'; +export { nToU8a } from './toU8a.js'; +export * from './consts.js'; diff --git a/packages/util/bi/min.d.ts b/packages/util/bi/min.d.ts new file mode 100644 index 0000000..662b41c --- /dev/null +++ b/packages/util/bi/min.d.ts @@ -0,0 +1,10 @@ +/** + * @name nMax + * @summary Finds and returns the highest value in an array of bigint. + */ +export declare const nMax: (...items: bigint[]) => bigint; +/** + * @name nMin + * @summary Finds and returns the lowest value in an array of bigint. + */ +export declare const nMin: (...items: bigint[]) => bigint; diff --git a/packages/util/bi/min.js b/packages/util/bi/min.js new file mode 100644 index 0000000..f97a87d --- /dev/null +++ b/packages/util/bi/min.js @@ -0,0 +1,11 @@ +import { createCmp } from './helpers.js'; +/** + * @name nMax + * @summary Finds and returns the highest value in an array of bigint. + */ +export const nMax = /*#__PURE__*/ createCmp((a, b) => a > b); +/** + * @name nMin + * @summary Finds and returns the lowest value in an array of bigint. + */ +export const nMin = /*#__PURE__*/ createCmp((a, b) => a < b); diff --git a/packages/util/bi/sqrt.d.ts b/packages/util/bi/sqrt.d.ts new file mode 100644 index 0000000..c9b5b2e --- /dev/null +++ b/packages/util/bi/sqrt.d.ts @@ -0,0 +1,7 @@ +import type { BN } from '../bn/index.js'; +import type { ToBigInt, ToBn } from '../types.js'; +/** + * @name nSqrt + * @summary Calculates the integer square root of a bigint + */ +export declare function nSqrt(value: ExtToBn | BN | bigint | string | number | null): bigint; diff --git a/packages/util/bi/sqrt.js b/packages/util/bi/sqrt.js new file mode 100644 index 0000000..4898325 --- /dev/null +++ b/packages/util/bi/sqrt.js @@ -0,0 +1,29 @@ +import { BigInt } from '@pezkuwi/x-bigint'; +import { _0n, _1n, _2pow53n, _sqrt2pow53n } from './consts.js'; +import { nToBigInt } from './toBigInt.js'; +/** + * @name nSqrt + * @summary Calculates the integer square root of a bigint + */ +export function nSqrt(value) { + const n = nToBigInt(value); + if (n < _0n) { + throw new Error('square root of negative numbers is not supported'); + } + // https://stackoverflow.com/questions/53683995/javascript-big-integer-square-root/ + // shortcut <= 2^53 - 1 to use the JS utils + if (n <= _2pow53n) { + // ~~ is more performant that Math.floor + return BigInt(~~Math.sqrt(Number(n))); + } + // Use sqrt(MAX_SAFE_INTEGER) as starting point. since we already know the + // output will be larger than this, we expect this to be a safe start + let x0 = _sqrt2pow53n; + while (true) { + const x1 = ((n / x0) + x0) >> _1n; + if (x0 === x1 || (x0 === (x1 - _1n))) { + return x0; + } + x0 = x1; + } +} diff --git a/packages/util/bi/toBigInt.d.ts b/packages/util/bi/toBigInt.d.ts new file mode 100644 index 0000000..c254d26 --- /dev/null +++ b/packages/util/bi/toBigInt.d.ts @@ -0,0 +1,7 @@ +import type { BN } from '../bn/bn.js'; +import type { ToBigInt, ToBn } from '../types.js'; +/** + * @name nToBigInt + * @summary Creates a bigInt value from a BN, bigint, string (base 10 or hex) or number input. + */ +export declare function nToBigInt(value?: ExtToBn | BN | bigint | string | number | null): bigint; diff --git a/packages/util/bi/toBigInt.js b/packages/util/bi/toBigInt.js new file mode 100644 index 0000000..2ca6584 --- /dev/null +++ b/packages/util/bi/toBigInt.js @@ -0,0 +1,25 @@ +import { BigInt } from '@pezkuwi/x-bigint'; +import { hexToBigInt } from '../hex/toBigInt.js'; +import { isBn } from '../is/bn.js'; +import { isHex } from '../is/hex.js'; +import { isToBigInt } from '../is/toBigInt.js'; +import { isToBn } from '../is/toBn.js'; +/** + * @name nToBigInt + * @summary Creates a bigInt value from a BN, bigint, string (base 10 or hex) or number input. + */ +export function nToBigInt(value) { + return typeof value === 'bigint' + ? value + : !value + ? BigInt(0) + : isHex(value) + ? hexToBigInt(value.toString()) + : isBn(value) + ? BigInt(value.toString()) + : isToBigInt(value) + ? value.toBigInt() + : isToBn(value) + ? BigInt(value.toBn().toString()) + : BigInt(value); +} diff --git a/packages/util/bi/toHex.d.ts b/packages/util/bi/toHex.d.ts new file mode 100644 index 0000000..7ccfc0e --- /dev/null +++ b/packages/util/bi/toHex.d.ts @@ -0,0 +1,7 @@ +import type { BN } from '../bn/bn.js'; +import type { HexString, NumberOptions, ToBigInt, ToBn } from '../types.js'; +/** + * @name nToHex + * @summary Creates a hex value from a bigint object. + */ +export declare function nToHex(value?: ExtToBn | BN | bigint | number | null, { bitLength, isLe, isNegative }?: NumberOptions): HexString; diff --git a/packages/util/bi/toHex.js b/packages/util/bi/toHex.js new file mode 100644 index 0000000..26f5ee8 --- /dev/null +++ b/packages/util/bi/toHex.js @@ -0,0 +1,9 @@ +import { u8aToHex } from '../u8a/index.js'; +import { nToU8a } from './toU8a.js'; +/** + * @name nToHex + * @summary Creates a hex value from a bigint object. + */ +export function nToHex(value, { bitLength = -1, isLe = false, isNegative = false } = {}) { + return u8aToHex(nToU8a(value || 0, { bitLength, isLe, isNegative })); +} diff --git a/packages/util/bi/toU8a.d.ts b/packages/util/bi/toU8a.d.ts new file mode 100644 index 0000000..b75234a --- /dev/null +++ b/packages/util/bi/toU8a.d.ts @@ -0,0 +1,7 @@ +import type { BN } from '../bn/bn.js'; +import type { NumberOptions, ToBigInt, ToBn } from '../types.js'; +/** + * @name nToU8a + * @summary Creates a Uint8Array object from a bigint. + */ +export declare function nToU8a(value?: ExtToBn | BN | bigint | number | null, { bitLength, isLe, isNegative }?: NumberOptions): Uint8Array; diff --git a/packages/util/bi/toU8a.js b/packages/util/bi/toU8a.js new file mode 100644 index 0000000..43821a6 --- /dev/null +++ b/packages/util/bi/toU8a.js @@ -0,0 +1,49 @@ +import { BigInt } from '@pezkuwi/x-bigint'; +import { _0n, _1n } from './consts.js'; +import { nToBigInt } from './toBigInt.js'; +const DIV = BigInt(256); +const NEG_MASK = BigInt(0xff); +function toU8a(value, isLe, isNegative) { + const arr = []; + const withSigned = isNegative && (value < _0n); + if (withSigned) { + value = (value + _1n) * -_1n; + } + while (value !== _0n) { + const mod = value % DIV; + const val = Number(withSigned + ? mod ^ NEG_MASK + : mod); + if (isLe) { + arr.push(val); + } + else { + arr.unshift(val); + } + value = (value - mod) / DIV; + } + return Uint8Array.from(arr); +} +/** + * @name nToU8a + * @summary Creates a Uint8Array object from a bigint. + */ +export function nToU8a(value, { bitLength = -1, isLe = true, isNegative = false } = {}) { + const valueBi = nToBigInt(value); + if (valueBi === _0n) { + return bitLength === -1 + ? new Uint8Array(1) + : new Uint8Array(Math.ceil((bitLength || 0) / 8)); + } + const u8a = toU8a(valueBi, isLe, isNegative); + if (bitLength === -1) { + return u8a; + } + const byteLength = Math.ceil((bitLength || 0) / 8); + const output = new Uint8Array(byteLength); + if (isNegative) { + output.fill(0xff); + } + output.set(u8a, isLe ? 0 : byteLength - u8a.length); + return output; +} diff --git a/packages/util/bn/bn.d.ts b/packages/util/bn/bn.d.ts new file mode 100644 index 0000000..a529f10 --- /dev/null +++ b/packages/util/bn/bn.d.ts @@ -0,0 +1,2 @@ +import BN from 'bn.js'; +export { BN }; diff --git a/packages/util/bn/bn.js b/packages/util/bn/bn.js new file mode 100644 index 0000000..a529f10 --- /dev/null +++ b/packages/util/bn/bn.js @@ -0,0 +1,2 @@ +import BN from 'bn.js'; +export { BN }; diff --git a/packages/util/bn/consts.d.ts b/packages/util/bn/consts.d.ts new file mode 100644 index 0000000..2e9f7e3 --- /dev/null +++ b/packages/util/bn/consts.d.ts @@ -0,0 +1,91 @@ +import { BN } from './bn.js'; +/** + * @name BN_ZERO + * @summary BN constant for 0. + */ +export declare const BN_ZERO: BN; +/** + * @name BN_ONE + * @summary BN constant for 1. + */ +export declare const BN_ONE: BN; +/** + * @name BN_TWO + * @summary BN constant for 2. + */ +export declare const BN_TWO: BN; +/** + * @name BN_THREE + * @summary BN constant for 3. + */ +export declare const BN_THREE: BN; +/** + * @name BN_FOUR + * @summary BN constant for 4. + */ +export declare const BN_FOUR: BN; +/** + * @name BN_FIVE + * @summary BN constant for 5. + */ +export declare const BN_FIVE: BN; +/** + * @name BN_SIX + * @summary BN constant for 6. + */ +export declare const BN_SIX: BN; +/** + * @name BN_SEVEN + * @summary BN constant for 7. + */ +export declare const BN_SEVEN: BN; +/** + * @name BN_EIGHT + * @summary BN constant for 8. + */ +export declare const BN_EIGHT: BN; +/** + * @name BN_NINE + * @summary BN constant for 9. + */ +export declare const BN_NINE: BN; +/** + * @name BN_TEN + * @summary BN constant for 10. + */ +export declare const BN_TEN: BN; +/** + * @name BN_HUNDRED + * @summary BN constant for 100. + */ +export declare const BN_HUNDRED: BN; +/** + * @name BN_THOUSAND + * @summary BN constant for 1,000. + */ +export declare const BN_THOUSAND: BN; +/** + * @name BN_MILLION + * @summary BN constant for 1,000,000. + */ +export declare const BN_MILLION: BN; +/** + * @name BN_BILLION + * @summary BN constant for 1,000,000,000. + */ +export declare const BN_BILLION: BN; +/** + * @name BN_QUINTILL + * @summary BN constant for 1,000,000,000,000,000,000. + */ +export declare const BN_QUINTILL: BN; +/** + * @name BN_MAX_INTEGER + * @summary BN constant for MAX_SAFE_INTEGER + */ +export declare const BN_MAX_INTEGER: BN; +/** + * @name BN_SQRT_MAX_INTEGER + * @summary BN constant for Math.sqrt(MAX_SAFE_INTEGER) + */ +export declare const BN_SQRT_MAX_INTEGER: BN; diff --git a/packages/util/bn/consts.js b/packages/util/bn/consts.js new file mode 100644 index 0000000..cc02416 --- /dev/null +++ b/packages/util/bn/consts.js @@ -0,0 +1,91 @@ +import { BN } from './bn.js'; +/** + * @name BN_ZERO + * @summary BN constant for 0. + */ +export const BN_ZERO = /*#__PURE__*/ new BN(0); +/** + * @name BN_ONE + * @summary BN constant for 1. + */ +export const BN_ONE = /*#__PURE__*/ new BN(1); +/** + * @name BN_TWO + * @summary BN constant for 2. + */ +export const BN_TWO = /*#__PURE__*/ new BN(2); +/** + * @name BN_THREE + * @summary BN constant for 3. + */ +export const BN_THREE = /*#__PURE__*/ new BN(3); +/** + * @name BN_FOUR + * @summary BN constant for 4. + */ +export const BN_FOUR = /*#__PURE__*/ new BN(4); +/** + * @name BN_FIVE + * @summary BN constant for 5. + */ +export const BN_FIVE = /*#__PURE__*/ new BN(5); +/** + * @name BN_SIX + * @summary BN constant for 6. + */ +export const BN_SIX = /*#__PURE__*/ new BN(6); +/** + * @name BN_SEVEN + * @summary BN constant for 7. + */ +export const BN_SEVEN = /*#__PURE__*/ new BN(7); +/** + * @name BN_EIGHT + * @summary BN constant for 8. + */ +export const BN_EIGHT = /*#__PURE__*/ new BN(8); +/** + * @name BN_NINE + * @summary BN constant for 9. + */ +export const BN_NINE = /*#__PURE__*/ new BN(9); +/** + * @name BN_TEN + * @summary BN constant for 10. + */ +export const BN_TEN = /*#__PURE__*/ new BN(10); +/** + * @name BN_HUNDRED + * @summary BN constant for 100. + */ +export const BN_HUNDRED = /*#__PURE__*/ new BN(100); +/** + * @name BN_THOUSAND + * @summary BN constant for 1,000. + */ +export const BN_THOUSAND = /*#__PURE__*/ new BN(1_000); +/** + * @name BN_MILLION + * @summary BN constant for 1,000,000. + */ +export const BN_MILLION = /*#__PURE__*/ new BN(1_000_000); +/** + * @name BN_BILLION + * @summary BN constant for 1,000,000,000. + */ +export const BN_BILLION = /*#__PURE__*/ new BN(1_000_000_000); +/** + * @name BN_QUINTILL + * @summary BN constant for 1,000,000,000,000,000,000. + */ +export const BN_QUINTILL = BN_BILLION.mul(BN_BILLION); +/** + * @name BN_MAX_INTEGER + * @summary BN constant for MAX_SAFE_INTEGER + */ +export const BN_MAX_INTEGER = /*#__PURE__*/ new BN(Number.MAX_SAFE_INTEGER); +/** + * @name BN_SQRT_MAX_INTEGER + * @summary BN constant for Math.sqrt(MAX_SAFE_INTEGER) + */ +export const BN_SQRT_MAX_INTEGER = /*#__PURE__*/ new BN(94906265); diff --git a/packages/util/bn/fromHex.d.ts b/packages/util/bn/fromHex.d.ts new file mode 100644 index 0000000..36d1d71 --- /dev/null +++ b/packages/util/bn/fromHex.d.ts @@ -0,0 +1 @@ +export { hexToBn as bnFromHex } from '../hex/toBn.js'; diff --git a/packages/util/bn/fromHex.js b/packages/util/bn/fromHex.js new file mode 100644 index 0000000..36d1d71 --- /dev/null +++ b/packages/util/bn/fromHex.js @@ -0,0 +1 @@ +export { hexToBn as bnFromHex } from '../hex/toBn.js'; diff --git a/packages/util/bn/index.d.ts b/packages/util/bn/index.d.ts new file mode 100644 index 0000000..27211eb --- /dev/null +++ b/packages/util/bn/index.d.ts @@ -0,0 +1,11 @@ +/** + * @summary Utility methods to convert to and from `BN` objects + */ +export { BN } from './bn.js'; +export { bnFromHex } from './fromHex.js'; +export { bnMax, bnMin } from './min.js'; +export { bnSqrt } from './sqrt.js'; +export { bnToBn } from './toBn.js'; +export { bnToHex } from './toHex.js'; +export { bnToU8a } from './toU8a.js'; +export * from './consts.js'; diff --git a/packages/util/bn/index.js b/packages/util/bn/index.js new file mode 100644 index 0000000..27211eb --- /dev/null +++ b/packages/util/bn/index.js @@ -0,0 +1,11 @@ +/** + * @summary Utility methods to convert to and from `BN` objects + */ +export { BN } from './bn.js'; +export { bnFromHex } from './fromHex.js'; +export { bnMax, bnMin } from './min.js'; +export { bnSqrt } from './sqrt.js'; +export { bnToBn } from './toBn.js'; +export { bnToHex } from './toHex.js'; +export { bnToU8a } from './toU8a.js'; +export * from './consts.js'; diff --git a/packages/util/bn/min.d.ts b/packages/util/bn/min.d.ts new file mode 100644 index 0000000..c0260d4 --- /dev/null +++ b/packages/util/bn/min.d.ts @@ -0,0 +1,29 @@ +import type { BN } from './bn.js'; +/** + * @name bnMax + * @summary Finds and returns the highest value in an array of BNs. + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnMax } from '@pezkuwi/util'; + * + * bnMax([new BN(1), new BN(3), new BN(2)]).toString(); // => '3' + * ``` + */ +export declare const bnMax: (...items: BN[]) => BN; +/** + * @name bnMin + * @summary Finds and returns the smallest value in an array of BNs. + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnMin } from '@pezkuwi/util'; + * + * bnMin([new BN(1), new BN(3), new BN(2)]).toString(); // => '1' + * ``` + */ +export declare const bnMin: (...items: BN[]) => BN; diff --git a/packages/util/bn/min.js b/packages/util/bn/min.js new file mode 100644 index 0000000..7949671 --- /dev/null +++ b/packages/util/bn/min.js @@ -0,0 +1,29 @@ +import { createCmp } from '../bi/helpers.js'; +/** + * @name bnMax + * @summary Finds and returns the highest value in an array of BNs. + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnMax } from '@pezkuwi/util'; + * + * bnMax([new BN(1), new BN(3), new BN(2)]).toString(); // => '3' + * ``` + */ +export const bnMax = /*#__PURE__*/ createCmp((a, b) => a.gt(b)); +/** + * @name bnMin + * @summary Finds and returns the smallest value in an array of BNs. + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnMin } from '@pezkuwi/util'; + * + * bnMin([new BN(1), new BN(3), new BN(2)]).toString(); // => '1' + * ``` + */ +export const bnMin = /*#__PURE__*/ createCmp((a, b) => a.lt(b)); diff --git a/packages/util/bn/sqrt.d.ts b/packages/util/bn/sqrt.d.ts new file mode 100644 index 0000000..484a35a --- /dev/null +++ b/packages/util/bn/sqrt.d.ts @@ -0,0 +1,16 @@ +import type { ToBn } from '../types.js'; +import { BN } from './bn.js'; +/** + * @name bnSqrt + * @summary Calculates the integer square root of a BN + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnSqrt } from '@pezkuwi/util'; + * + * bnSqrt(new BN(16)).toString(); // => '4' + * ``` + */ +export declare function bnSqrt(value: ExtToBn | BN | bigint | string | number | null): BN; diff --git a/packages/util/bn/sqrt.js b/packages/util/bn/sqrt.js new file mode 100644 index 0000000..f91434a --- /dev/null +++ b/packages/util/bn/sqrt.js @@ -0,0 +1,38 @@ +import { BN } from './bn.js'; +import { BN_MAX_INTEGER, BN_ONE, BN_SQRT_MAX_INTEGER } from './consts.js'; +import { bnToBn } from './toBn.js'; +/** + * @name bnSqrt + * @summary Calculates the integer square root of a BN + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnSqrt } from '@pezkuwi/util'; + * + * bnSqrt(new BN(16)).toString(); // => '4' + * ``` + */ +export function bnSqrt(value) { + const n = bnToBn(value); + if (n.isNeg()) { + throw new Error('square root of negative numbers is not supported'); + } + // https://stackoverflow.com/questions/53683995/javascript-big-integer-square-root/ + // shortcut <= 2^53 - 1 to use the JS utils + if (n.lte(BN_MAX_INTEGER)) { + // ~~ More performant version of Math.floor + return new BN(~~Math.sqrt(n.toNumber())); + } + // Use sqrt(MAX_SAFE_INTEGER) as starting point. since we already know the + // output will be larger than this, we expect this to be a safe start + let x0 = BN_SQRT_MAX_INTEGER.clone(); + while (true) { + const x1 = n.div(x0).iadd(x0).ishrn(1); + if (x0.eq(x1) || x0.eq(x1.sub(BN_ONE))) { + return x0; + } + x0 = x1; + } +} diff --git a/packages/util/bn/toBn.d.ts b/packages/util/bn/toBn.d.ts new file mode 100644 index 0000000..47d61ab --- /dev/null +++ b/packages/util/bn/toBn.d.ts @@ -0,0 +1,19 @@ +import type { ToBigInt, ToBn } from '../types.js'; +import { BN } from './bn.js'; +/** + * @name bnToBn + * @summary Creates a BN value from a BN, bigint, string (base 10 or hex) or number input. + * @description + * `null` inputs returns a `0x0` result, BN values returns the value, numbers returns a BN representation. + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnToBn } from '@pezkuwi/util'; + * + * bnToBn(0x1234); // => BN(0x1234) + * bnToBn(new BN(0x1234)); // => BN(0x1234) + * ``` + */ +export declare function bnToBn(value?: ExtToBn | BN | bigint | string | number | null): BN; diff --git a/packages/util/bn/toBn.js b/packages/util/bn/toBn.js new file mode 100644 index 0000000..4260a78 --- /dev/null +++ b/packages/util/bn/toBn.js @@ -0,0 +1,37 @@ +import { hexToBn } from '../hex/toBn.js'; +import { isBigInt } from '../is/bigInt.js'; +import { isHex } from '../is/hex.js'; +import { isToBigInt } from '../is/toBigInt.js'; +import { isToBn } from '../is/toBn.js'; +import { BN } from './bn.js'; +/** + * @name bnToBn + * @summary Creates a BN value from a BN, bigint, string (base 10 or hex) or number input. + * @description + * `null` inputs returns a `0x0` result, BN values returns the value, numbers returns a BN representation. + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnToBn } from '@pezkuwi/util'; + * + * bnToBn(0x1234); // => BN(0x1234) + * bnToBn(new BN(0x1234)); // => BN(0x1234) + * ``` + */ +export function bnToBn(value) { + return value + ? BN.isBN(value) + ? value + : isHex(value) + ? hexToBn(value.toString()) + : isBigInt(value) + ? new BN(value.toString()) + : isToBn(value) + ? value.toBn() + : isToBigInt(value) + ? new BN(value.toBigInt().toString()) + : new BN(value) + : new BN(0); +} diff --git a/packages/util/bn/toHex.d.ts b/packages/util/bn/toHex.d.ts new file mode 100644 index 0000000..6d1ca8d --- /dev/null +++ b/packages/util/bn/toHex.d.ts @@ -0,0 +1,18 @@ +import type { HexString, NumberOptions, ToBn } from '../types.js'; +import type { BN } from './bn.js'; +/** + * @name bnToHex + * @summary Creates a hex value from a BN.js bignumber object. + * @description + * `null` inputs returns a `0x` result, BN values return the actual value as a `0x` prefixed hex value. Anything that is not a BN object throws an error. With `bitLength` set, it fixes the number to the specified length. + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnToHex } from '@pezkuwi/util'; + * + * bnToHex(new BN(0x123456)); // => '0x123456' + * ``` + */ +export declare function bnToHex(value?: ExtToBn | BN | bigint | number | null, { bitLength, isLe, isNegative }?: NumberOptions): HexString; diff --git a/packages/util/bn/toHex.js b/packages/util/bn/toHex.js new file mode 100644 index 0000000..ceb9b09 --- /dev/null +++ b/packages/util/bn/toHex.js @@ -0,0 +1,20 @@ +import { u8aToHex } from '../u8a/index.js'; +import { bnToU8a } from './toU8a.js'; +/** + * @name bnToHex + * @summary Creates a hex value from a BN.js bignumber object. + * @description + * `null` inputs returns a `0x` result, BN values return the actual value as a `0x` prefixed hex value. Anything that is not a BN object throws an error. With `bitLength` set, it fixes the number to the specified length. + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnToHex } from '@pezkuwi/util'; + * + * bnToHex(new BN(0x123456)); // => '0x123456' + * ``` + */ +export function bnToHex(value, { bitLength = -1, isLe = false, isNegative = false } = {}) { + return u8aToHex(bnToU8a(value, { bitLength, isLe, isNegative })); +} diff --git a/packages/util/bn/toU8a.d.ts b/packages/util/bn/toU8a.d.ts new file mode 100644 index 0000000..49abc0a --- /dev/null +++ b/packages/util/bn/toU8a.d.ts @@ -0,0 +1,17 @@ +import type { NumberOptions, ToBn } from '../types.js'; +import type { BN } from './bn.js'; +/** + * @name bnToU8a + * @summary Creates a Uint8Array object from a BN. + * @description + * `null`/`undefined`/`NaN` inputs returns an empty `Uint8Array` result. `BN` input values return the actual bytes value converted to a `Uint8Array`. Optionally convert using little-endian format if `isLE` is set. + * @example + *
+ * + * ```javascript + * import { bnToU8a } from '@pezkuwi/util'; + * + * bnToU8a(new BN(0x1234)); // => [0x12, 0x34] + * ``` + */ +export declare function bnToU8a(value?: ExtToBn | BN | bigint | number | null, { bitLength, isLe, isNegative }?: NumberOptions): Uint8Array; diff --git a/packages/util/bn/toU8a.js b/packages/util/bn/toU8a.js new file mode 100644 index 0000000..14364c0 --- /dev/null +++ b/packages/util/bn/toU8a.js @@ -0,0 +1,33 @@ +import { bnToBn } from './toBn.js'; +const DEFAULT_OPTS = { bitLength: -1, isLe: true, isNegative: false }; +/** + * @name bnToU8a + * @summary Creates a Uint8Array object from a BN. + * @description + * `null`/`undefined`/`NaN` inputs returns an empty `Uint8Array` result. `BN` input values return the actual bytes value converted to a `Uint8Array`. Optionally convert using little-endian format if `isLE` is set. + * @example + *
+ * + * ```javascript + * import { bnToU8a } from '@pezkuwi/util'; + * + * bnToU8a(new BN(0x1234)); // => [0x12, 0x34] + * ``` + */ +export function bnToU8a(value, { bitLength = -1, isLe = true, isNegative = false } = DEFAULT_OPTS) { + const valueBn = bnToBn(value); + const byteLength = bitLength === -1 + ? Math.ceil(valueBn.bitLength() / 8) + : Math.ceil((bitLength || 0) / 8); + if (!value) { + return bitLength === -1 + ? new Uint8Array(1) + : new Uint8Array(byteLength); + } + const output = new Uint8Array(byteLength); + const bn = isNegative + ? valueBn.toTwos(byteLength * 8) + : valueBn; + output.set(bn.toArray(isLe ? 'le' : 'be', byteLength), 0); + return output; +} diff --git a/packages/util/buffer/index.d.ts b/packages/util/buffer/index.d.ts new file mode 100644 index 0000000..9554f62 --- /dev/null +++ b/packages/util/buffer/index.d.ts @@ -0,0 +1,4 @@ +/** + * @summary Utility methods to convert to and from `Buffer` objects + */ +export { bufferToU8a } from './toU8a.js'; diff --git a/packages/util/buffer/index.js b/packages/util/buffer/index.js new file mode 100644 index 0000000..9554f62 --- /dev/null +++ b/packages/util/buffer/index.js @@ -0,0 +1,4 @@ +/** + * @summary Utility methods to convert to and from `Buffer` objects + */ +export { bufferToU8a } from './toU8a.js'; diff --git a/packages/util/buffer/toU8a.d.ts b/packages/util/buffer/toU8a.d.ts new file mode 100644 index 0000000..4ff66da --- /dev/null +++ b/packages/util/buffer/toU8a.d.ts @@ -0,0 +1,15 @@ +/** + * @name bufferToU8a + * @summary Creates a Uint8Array value from a Buffer object. + * @description + * `null` inputs returns an empty result, `Buffer` values return the actual value as a `Uint8Array`. Anything that is not a `Buffer` object throws an error. + * @example + *
+ * + * ```javascript + * import { bufferToU8a } from '@pezkuwi/util'; + * + * bufferToU8a(Buffer.from([1, 2, 3])); + * ``` + */ +export declare function bufferToU8a(buffer?: Uint8Array | number[] | null): Uint8Array; diff --git a/packages/util/buffer/toU8a.js b/packages/util/buffer/toU8a.js new file mode 100644 index 0000000..30ea8d9 --- /dev/null +++ b/packages/util/buffer/toU8a.js @@ -0,0 +1,17 @@ +/** + * @name bufferToU8a + * @summary Creates a Uint8Array value from a Buffer object. + * @description + * `null` inputs returns an empty result, `Buffer` values return the actual value as a `Uint8Array`. Anything that is not a `Buffer` object throws an error. + * @example + *
+ * + * ```javascript + * import { bufferToU8a } from '@pezkuwi/util'; + * + * bufferToU8a(Buffer.from([1, 2, 3])); + * ``` + */ +export function bufferToU8a(buffer) { + return new Uint8Array(buffer || []); +} diff --git a/packages/util/bundle-pezkuwi-util.js b/packages/util/bundle-pezkuwi-util.js new file mode 100644 index 0000000..f2b662b --- /dev/null +++ b/packages/util/bundle-pezkuwi-util.js @@ -0,0 +1,4830 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.pezkuwiUtil = {})); +})(this, (function (exports) { 'use strict'; + + const global = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : window; + + var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null; + const packageInfo$3 = { name: '@pezkuwi/util', path: (({ url: (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-util.js', document.baseURI).href)) }) && (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-util.js', document.baseURI).href))) ? new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-util.js', document.baseURI).href))).pathname.substring(0, new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-util.js', document.baseURI).href))).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; + + function arrayChunk(array, chunkSize) { + const outputSize = Math.ceil(array.length / chunkSize); + if (outputSize === 1) { + return [array]; + } + const output = Array(outputSize); + for (let i = 0; i < outputSize; i++) { + const offset = i * chunkSize; + output[i] = array.slice(offset, offset + chunkSize); + } + return output; + } + + function arrayFilter(array, allowNulls = true) { + return array.filter((v) => v !== undefined && + (allowNulls || v !== null)); + } + + function arrayFlatten(arrays) { + const num = arrays.length; + if (num === 0) { + return []; + } + else if (num === 1) { + return arrays[0]; + } + let size = 0; + for (let i = 0; i < num; i++) { + size += arrays[i].length; + } + const output = new Array(size); + let i = -1; + for (let j = 0; j < num; j++) { + const a = arrays[j]; + for (let e = 0, count = a.length; e < count; e++) { + output[++i] = a[e]; + } + } + return output; + } + + function arrayRange(size, startAt = 0) { + if (size <= 0) { + throw new Error('Expected non-zero, positive number as a range size'); + } + const result = new Array(size); + for (let i = 0; i < size; i++) { + result[i] = i + startAt; + } + return result; + } + + function arrayShuffle(input) { + const result = input.slice(); + let curr = result.length; + if (curr === 1) { + return result; + } + while (curr !== 0) { + const rand = ~~(Math.random() * curr); + curr--; + [result[curr], result[rand]] = [result[rand], result[curr]]; + } + return result; + } + + function arrayUnzip(entries) { + const count = entries.length; + const keys = new Array(count); + const values = new Array(count); + for (let i = 0; i < count; i++) { + [keys[i], values[i]] = entries[i]; + } + return [keys, values]; + } + + function arrayZip(keys, values) { + const count = keys.length; + const result = new Array(count); + for (let i = 0; i < count; i++) { + result[i] = [keys[i], values[i]]; + } + return result; + } + + function isFunction(value) { + return typeof value === 'function'; + } + + function assert(condition, message) { + if (!condition) { + throw new Error(isFunction(message) + ? message() + : message); + } + } + function assertReturn(value, message) { + assert(value !== undefined && value !== null, message); + return value; + } + function assertUnreachable(x) { + throw new Error(`This codepath should be unreachable. Unhandled input: ${x}`); + } + + function createCmp(cmp) { + return (...items) => { + const count = items.length; + if (count === 0) { + throw new Error('Must provide one or more arguments'); + } + let result = items[0]; + for (let i = 1; i < count; i++) { + if (cmp(items[i], result)) { + result = items[i]; + } + } + return result; + }; + } + + const nMax = createCmp((a, b) => a > b); + const nMin = createCmp((a, b) => a < b); + + const packageInfo$2 = { name: '@pezkuwi/x-global', path: (({ url: (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-util.js', document.baseURI).href)) }) && (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-util.js', document.baseURI).href))) ? new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-util.js', document.baseURI).href))).pathname.substring(0, new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bundle-pezkuwi-util.js', document.baseURI).href))).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; + + function evaluateThis(fn) { + return fn('return this'); + } + const xglobal = (typeof globalThis !== 'undefined' + ? globalThis + : typeof global !== 'undefined' + ? global + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : evaluateThis(Function)); + function extractGlobal(name, fallback) { + return typeof xglobal[name] === 'undefined' + ? fallback + : xglobal[name]; + } + function exposeGlobal(name, fallback) { + if (typeof xglobal[name] === 'undefined') { + xglobal[name] = fallback; + } + } + + const build = /*#__PURE__*/Object.freeze({ + __proto__: null, + exposeGlobal: exposeGlobal, + extractGlobal: extractGlobal, + packageInfo: packageInfo$2, + xglobal: xglobal + }); + + function invalidFallback() { + return Number.NaN; + } + const BigInt = extractGlobal('BigInt', invalidFallback); + + const _0n = BigInt(0); + const _1n = BigInt(1); + const _2n = BigInt(2); + const _3n = BigInt(3); + const _4n = BigInt(4); + const _5n = BigInt(5); + const _6n = BigInt(6); + const _7n = BigInt(7); + const _8n = BigInt(8); + const _9n = BigInt(9); + const _10n = BigInt(10); + const _100n = BigInt(100); + const _1000n = BigInt(1_000); + const _1Mn = BigInt(1_000_000); + const _1Bn = BigInt(1_000_000_000); + const _1Qn = _1Bn * _1Bn; + const _2pow53n = BigInt(Number.MAX_SAFE_INTEGER); + const _sqrt2pow53n = BigInt(94906265); + + const U8_MAX = BigInt(256); + const U16_MAX = BigInt(256 * 256); + const U64_MAX = BigInt('0x10000000000000000'); + function u8aToBigInt(value, { isLe = true, isNegative = false } = {}) { + if (!isLe) { + value = value.slice().reverse(); + } + const count = value.length; + if (isNegative && count && (value[count - 1] & 0x80)) { + switch (count) { + case 0: + return BigInt(0); + case 1: + return BigInt(((value[0] ^ 0x0000_00ff) * -1) - 1); + case 2: + return BigInt((((value[0] + (value[1] << 8)) ^ 0x0000_ffff) * -1) - 1); + case 4: + return BigInt((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) * -1) - 1); + } + const dvI = new DataView(value.buffer, value.byteOffset); + if (count === 8) { + return dvI.getBigInt64(0, true); + } + let result = BigInt(0); + const mod = count % 2; + for (let i = count - 2; i >= mod; i -= 2) { + result = (result * U16_MAX) + BigInt(dvI.getUint16(i, true) ^ 0xffff); + } + if (mod) { + result = (result * U8_MAX) + BigInt(value[0] ^ 0xff); + } + return (result * -_1n) - _1n; + } + switch (count) { + case 0: + return BigInt(0); + case 1: + return BigInt(value[0]); + case 2: + return BigInt(value[0] + (value[1] << 8)); + case 4: + return BigInt(value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)); + } + const dvI = new DataView(value.buffer, value.byteOffset); + switch (count) { + case 8: + return dvI.getBigUint64(0, true); + case 16: + return (dvI.getBigUint64(8, true) * U64_MAX) + dvI.getBigUint64(0, true); + default: { + let result = BigInt(0); + const mod = count % 2; + for (let i = count - 2; i >= mod; i -= 2) { + result = (result * U16_MAX) + BigInt(dvI.getUint16(i, true)); + } + if (mod) { + result = (result * U8_MAX) + BigInt(value[0]); + } + return result; + } + } + } + + const CHR = '0123456789abcdef'; + const U8$1 = new Uint8Array(256); + const U16$1 = new Uint8Array(256 * 256); + for (let i = 0, count = CHR.length; i < count; i++) { + U8$1[CHR[i].charCodeAt(0) | 0] = i | 0; + if (i > 9) { + U8$1[CHR[i].toUpperCase().charCodeAt(0) | 0] = i | 0; + } + } + for (let i = 0; i < 256; i++) { + const s = i << 8; + for (let j = 0; j < 256; j++) { + U16$1[s | j] = (U8$1[i] << 4) | U8$1[j]; + } + } + function hexToU8a(value, bitLength = -1) { + if (!value) { + return new Uint8Array(); + } + let s = value.startsWith('0x') + ? 2 + : 0; + const decLength = Math.ceil((value.length - s) / 2); + const endLength = Math.ceil(bitLength === -1 + ? decLength + : bitLength / 8); + const result = new Uint8Array(endLength); + const offset = endLength > decLength + ? endLength - decLength + : 0; + for (let i = offset; i < endLength; i++, s += 2) { + result[i] = U16$1[(value.charCodeAt(s) << 8) | value.charCodeAt(s + 1)]; + } + return result; + } + + function hexToBigInt(value, { isLe = false, isNegative = false } = {}) { + return !value || value === '0x' + ? BigInt(0) + : u8aToBigInt(hexToU8a(value), { isLe, isNegative }); + } + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function getAugmentedNamespace(n) { + if (n.__esModule) return n; + var f = n.default; + if (typeof f == "function") { + var a = function a () { + if (this instanceof a) { + return Reflect.construct(f, arguments, this.constructor); + } + return f.apply(this, arguments); + }; + a.prototype = f.prototype; + } else a = {}; + Object.defineProperty(a, '__esModule', {value: true}); + Object.keys(n).forEach(function (k) { + var d = Object.getOwnPropertyDescriptor(n, k); + Object.defineProperty(a, k, d.get ? d : { + enumerable: true, + get: function () { + return n[k]; + } + }); + }); + return a; + } + + var bn = {exports: {}}; + + const _nodeResolve_empty = {}; + + const _nodeResolve_empty$1 = /*#__PURE__*/Object.freeze({ + __proto__: null, + default: _nodeResolve_empty + }); + + const require$$0$1 = /*@__PURE__*/getAugmentedNamespace(_nodeResolve_empty$1); + + bn.exports; + (function (module) { + (function (module, exports$1) { + function assert (val, msg) { + if (!val) throw new Error(msg || 'Assertion failed'); + } + function inherits (ctor, superCtor) { + ctor.super_ = superCtor; + var TempCtor = function () {}; + TempCtor.prototype = superCtor.prototype; + ctor.prototype = new TempCtor(); + ctor.prototype.constructor = ctor; + } + function BN (number, base, endian) { + if (BN.isBN(number)) { + return number; + } + this.negative = 0; + this.words = null; + this.length = 0; + this.red = null; + if (number !== null) { + if (base === 'le' || base === 'be') { + endian = base; + base = 10; + } + this._init(number || 0, base || 10, endian || 'be'); + } + } + if (typeof module === 'object') { + module.exports = BN; + } else { + exports$1.BN = BN; + } + BN.BN = BN; + BN.wordSize = 26; + var Buffer; + try { + if (typeof window !== 'undefined' && typeof window.Buffer !== 'undefined') { + Buffer = window.Buffer; + } else { + Buffer = require$$0$1.Buffer; + } + } catch (e) { + } + BN.isBN = function isBN (num) { + if (num instanceof BN) { + return true; + } + return num !== null && typeof num === 'object' && + num.constructor.wordSize === BN.wordSize && Array.isArray(num.words); + }; + BN.max = function max (left, right) { + if (left.cmp(right) > 0) return left; + return right; + }; + BN.min = function min (left, right) { + if (left.cmp(right) < 0) return left; + return right; + }; + BN.prototype._init = function init (number, base, endian) { + if (typeof number === 'number') { + return this._initNumber(number, base, endian); + } + if (typeof number === 'object') { + return this._initArray(number, base, endian); + } + if (base === 'hex') { + base = 16; + } + assert(base === (base | 0) && base >= 2 && base <= 36); + number = number.toString().replace(/\s+/g, ''); + var start = 0; + if (number[0] === '-') { + start++; + this.negative = 1; + } + if (start < number.length) { + if (base === 16) { + this._parseHex(number, start, endian); + } else { + this._parseBase(number, base, start); + if (endian === 'le') { + this._initArray(this.toArray(), base, endian); + } + } + } + }; + BN.prototype._initNumber = function _initNumber (number, base, endian) { + if (number < 0) { + this.negative = 1; + number = -number; + } + if (number < 0x4000000) { + this.words = [number & 0x3ffffff]; + this.length = 1; + } else if (number < 0x10000000000000) { + this.words = [ + number & 0x3ffffff, + (number / 0x4000000) & 0x3ffffff + ]; + this.length = 2; + } else { + assert(number < 0x20000000000000); + this.words = [ + number & 0x3ffffff, + (number / 0x4000000) & 0x3ffffff, + 1 + ]; + this.length = 3; + } + if (endian !== 'le') return; + this._initArray(this.toArray(), base, endian); + }; + BN.prototype._initArray = function _initArray (number, base, endian) { + assert(typeof number.length === 'number'); + if (number.length <= 0) { + this.words = [0]; + this.length = 1; + return this; + } + this.length = Math.ceil(number.length / 3); + this.words = new Array(this.length); + for (var i = 0; i < this.length; i++) { + this.words[i] = 0; + } + var j, w; + var off = 0; + if (endian === 'be') { + for (i = number.length - 1, j = 0; i >= 0; i -= 3) { + w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16); + this.words[j] |= (w << off) & 0x3ffffff; + this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; + off += 24; + if (off >= 26) { + off -= 26; + j++; + } + } + } else if (endian === 'le') { + for (i = 0, j = 0; i < number.length; i += 3) { + w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16); + this.words[j] |= (w << off) & 0x3ffffff; + this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; + off += 24; + if (off >= 26) { + off -= 26; + j++; + } + } + } + return this._strip(); + }; + function parseHex4Bits (string, index) { + var c = string.charCodeAt(index); + if (c >= 48 && c <= 57) { + return c - 48; + } else if (c >= 65 && c <= 70) { + return c - 55; + } else if (c >= 97 && c <= 102) { + return c - 87; + } else { + assert(false, 'Invalid character in ' + string); + } + } + function parseHexByte (string, lowerBound, index) { + var r = parseHex4Bits(string, index); + if (index - 1 >= lowerBound) { + r |= parseHex4Bits(string, index - 1) << 4; + } + return r; + } + BN.prototype._parseHex = function _parseHex (number, start, endian) { + this.length = Math.ceil((number.length - start) / 6); + this.words = new Array(this.length); + for (var i = 0; i < this.length; i++) { + this.words[i] = 0; + } + var off = 0; + var j = 0; + var w; + if (endian === 'be') { + for (i = number.length - 1; i >= start; i -= 2) { + w = parseHexByte(number, start, i) << off; + this.words[j] |= w & 0x3ffffff; + if (off >= 18) { + off -= 18; + j += 1; + this.words[j] |= w >>> 26; + } else { + off += 8; + } + } + } else { + var parseLength = number.length - start; + for (i = parseLength % 2 === 0 ? start + 1 : start; i < number.length; i += 2) { + w = parseHexByte(number, start, i) << off; + this.words[j] |= w & 0x3ffffff; + if (off >= 18) { + off -= 18; + j += 1; + this.words[j] |= w >>> 26; + } else { + off += 8; + } + } + } + this._strip(); + }; + function parseBase (str, start, end, mul) { + var r = 0; + var b = 0; + var len = Math.min(str.length, end); + for (var i = start; i < len; i++) { + var c = str.charCodeAt(i) - 48; + r *= mul; + if (c >= 49) { + b = c - 49 + 0xa; + } else if (c >= 17) { + b = c - 17 + 0xa; + } else { + b = c; + } + assert(c >= 0 && b < mul, 'Invalid character'); + r += b; + } + return r; + } + BN.prototype._parseBase = function _parseBase (number, base, start) { + this.words = [0]; + this.length = 1; + for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) { + limbLen++; + } + limbLen--; + limbPow = (limbPow / base) | 0; + var total = number.length - start; + var mod = total % limbLen; + var end = Math.min(total, total - mod) + start; + var word = 0; + for (var i = start; i < end; i += limbLen) { + word = parseBase(number, i, i + limbLen, base); + this.imuln(limbPow); + if (this.words[0] + word < 0x4000000) { + this.words[0] += word; + } else { + this._iaddn(word); + } + } + if (mod !== 0) { + var pow = 1; + word = parseBase(number, i, number.length, base); + for (i = 0; i < mod; i++) { + pow *= base; + } + this.imuln(pow); + if (this.words[0] + word < 0x4000000) { + this.words[0] += word; + } else { + this._iaddn(word); + } + } + this._strip(); + }; + BN.prototype.copy = function copy (dest) { + dest.words = new Array(this.length); + for (var i = 0; i < this.length; i++) { + dest.words[i] = this.words[i]; + } + dest.length = this.length; + dest.negative = this.negative; + dest.red = this.red; + }; + function move (dest, src) { + dest.words = src.words; + dest.length = src.length; + dest.negative = src.negative; + dest.red = src.red; + } + BN.prototype._move = function _move (dest) { + move(dest, this); + }; + BN.prototype.clone = function clone () { + var r = new BN(null); + this.copy(r); + return r; + }; + BN.prototype._expand = function _expand (size) { + while (this.length < size) { + this.words[this.length++] = 0; + } + return this; + }; + BN.prototype._strip = function strip () { + while (this.length > 1 && this.words[this.length - 1] === 0) { + this.length--; + } + return this._normSign(); + }; + BN.prototype._normSign = function _normSign () { + if (this.length === 1 && this.words[0] === 0) { + this.negative = 0; + } + return this; + }; + if (typeof Symbol !== 'undefined' && typeof Symbol.for === 'function') { + try { + BN.prototype[Symbol.for('nodejs.util.inspect.custom')] = inspect; + } catch (e) { + BN.prototype.inspect = inspect; + } + } else { + BN.prototype.inspect = inspect; + } + function inspect () { + return (this.red ? ''; + } + var zeros = [ + '', + '0', + '00', + '000', + '0000', + '00000', + '000000', + '0000000', + '00000000', + '000000000', + '0000000000', + '00000000000', + '000000000000', + '0000000000000', + '00000000000000', + '000000000000000', + '0000000000000000', + '00000000000000000', + '000000000000000000', + '0000000000000000000', + '00000000000000000000', + '000000000000000000000', + '0000000000000000000000', + '00000000000000000000000', + '000000000000000000000000', + '0000000000000000000000000' + ]; + var groupSizes = [ + 0, 0, + 25, 16, 12, 11, 10, 9, 8, + 8, 7, 7, 7, 7, 6, 6, + 6, 6, 6, 6, 6, 5, 5, + 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5 + ]; + var groupBases = [ + 0, 0, + 33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216, + 43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625, + 16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632, + 6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149, + 24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176 + ]; + BN.prototype.toString = function toString (base, padding) { + base = base || 10; + padding = padding | 0 || 1; + var out; + if (base === 16 || base === 'hex') { + out = ''; + var off = 0; + var carry = 0; + for (var i = 0; i < this.length; i++) { + var w = this.words[i]; + var word = (((w << off) | carry) & 0xffffff).toString(16); + carry = (w >>> (24 - off)) & 0xffffff; + off += 2; + if (off >= 26) { + off -= 26; + i--; + } + if (carry !== 0 || i !== this.length - 1) { + out = zeros[6 - word.length] + word + out; + } else { + out = word + out; + } + } + if (carry !== 0) { + out = carry.toString(16) + out; + } + while (out.length % padding !== 0) { + out = '0' + out; + } + if (this.negative !== 0) { + out = '-' + out; + } + return out; + } + if (base === (base | 0) && base >= 2 && base <= 36) { + var groupSize = groupSizes[base]; + var groupBase = groupBases[base]; + out = ''; + var c = this.clone(); + c.negative = 0; + while (!c.isZero()) { + var r = c.modrn(groupBase).toString(base); + c = c.idivn(groupBase); + if (!c.isZero()) { + out = zeros[groupSize - r.length] + r + out; + } else { + out = r + out; + } + } + if (this.isZero()) { + out = '0' + out; + } + while (out.length % padding !== 0) { + out = '0' + out; + } + if (this.negative !== 0) { + out = '-' + out; + } + return out; + } + assert(false, 'Base should be between 2 and 36'); + }; + BN.prototype.toNumber = function toNumber () { + var ret = this.words[0]; + if (this.length === 2) { + ret += this.words[1] * 0x4000000; + } else if (this.length === 3 && this.words[2] === 0x01) { + ret += 0x10000000000000 + (this.words[1] * 0x4000000); + } else if (this.length > 2) { + assert(false, 'Number can only safely store up to 53 bits'); + } + return (this.negative !== 0) ? -ret : ret; + }; + BN.prototype.toJSON = function toJSON () { + return this.toString(16, 2); + }; + if (Buffer) { + BN.prototype.toBuffer = function toBuffer (endian, length) { + return this.toArrayLike(Buffer, endian, length); + }; + } + BN.prototype.toArray = function toArray (endian, length) { + return this.toArrayLike(Array, endian, length); + }; + var allocate = function allocate (ArrayType, size) { + if (ArrayType.allocUnsafe) { + return ArrayType.allocUnsafe(size); + } + return new ArrayType(size); + }; + BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) { + this._strip(); + var byteLength = this.byteLength(); + var reqLength = length || Math.max(1, byteLength); + assert(byteLength <= reqLength, 'byte array longer than desired length'); + assert(reqLength > 0, 'Requested array length <= 0'); + var res = allocate(ArrayType, reqLength); + var postfix = endian === 'le' ? 'LE' : 'BE'; + this['_toArrayLike' + postfix](res, byteLength); + return res; + }; + BN.prototype._toArrayLikeLE = function _toArrayLikeLE (res, byteLength) { + var position = 0; + var carry = 0; + for (var i = 0, shift = 0; i < this.length; i++) { + var word = (this.words[i] << shift) | carry; + res[position++] = word & 0xff; + if (position < res.length) { + res[position++] = (word >> 8) & 0xff; + } + if (position < res.length) { + res[position++] = (word >> 16) & 0xff; + } + if (shift === 6) { + if (position < res.length) { + res[position++] = (word >> 24) & 0xff; + } + carry = 0; + shift = 0; + } else { + carry = word >>> 24; + shift += 2; + } + } + if (position < res.length) { + res[position++] = carry; + while (position < res.length) { + res[position++] = 0; + } + } + }; + BN.prototype._toArrayLikeBE = function _toArrayLikeBE (res, byteLength) { + var position = res.length - 1; + var carry = 0; + for (var i = 0, shift = 0; i < this.length; i++) { + var word = (this.words[i] << shift) | carry; + res[position--] = word & 0xff; + if (position >= 0) { + res[position--] = (word >> 8) & 0xff; + } + if (position >= 0) { + res[position--] = (word >> 16) & 0xff; + } + if (shift === 6) { + if (position >= 0) { + res[position--] = (word >> 24) & 0xff; + } + carry = 0; + shift = 0; + } else { + carry = word >>> 24; + shift += 2; + } + } + if (position >= 0) { + res[position--] = carry; + while (position >= 0) { + res[position--] = 0; + } + } + }; + if (Math.clz32) { + BN.prototype._countBits = function _countBits (w) { + return 32 - Math.clz32(w); + }; + } else { + BN.prototype._countBits = function _countBits (w) { + var t = w; + var r = 0; + if (t >= 0x1000) { + r += 13; + t >>>= 13; + } + if (t >= 0x40) { + r += 7; + t >>>= 7; + } + if (t >= 0x8) { + r += 4; + t >>>= 4; + } + if (t >= 0x02) { + r += 2; + t >>>= 2; + } + return r + t; + }; + } + BN.prototype._zeroBits = function _zeroBits (w) { + if (w === 0) return 26; + var t = w; + var r = 0; + if ((t & 0x1fff) === 0) { + r += 13; + t >>>= 13; + } + if ((t & 0x7f) === 0) { + r += 7; + t >>>= 7; + } + if ((t & 0xf) === 0) { + r += 4; + t >>>= 4; + } + if ((t & 0x3) === 0) { + r += 2; + t >>>= 2; + } + if ((t & 0x1) === 0) { + r++; + } + return r; + }; + BN.prototype.bitLength = function bitLength () { + var w = this.words[this.length - 1]; + var hi = this._countBits(w); + return (this.length - 1) * 26 + hi; + }; + function toBitArray (num) { + var w = new Array(num.bitLength()); + for (var bit = 0; bit < w.length; bit++) { + var off = (bit / 26) | 0; + var wbit = bit % 26; + w[bit] = (num.words[off] >>> wbit) & 0x01; + } + return w; + } + BN.prototype.zeroBits = function zeroBits () { + if (this.isZero()) return 0; + var r = 0; + for (var i = 0; i < this.length; i++) { + var b = this._zeroBits(this.words[i]); + r += b; + if (b !== 26) break; + } + return r; + }; + BN.prototype.byteLength = function byteLength () { + return Math.ceil(this.bitLength() / 8); + }; + BN.prototype.toTwos = function toTwos (width) { + if (this.negative !== 0) { + return this.abs().inotn(width).iaddn(1); + } + return this.clone(); + }; + BN.prototype.fromTwos = function fromTwos (width) { + if (this.testn(width - 1)) { + return this.notn(width).iaddn(1).ineg(); + } + return this.clone(); + }; + BN.prototype.isNeg = function isNeg () { + return this.negative !== 0; + }; + BN.prototype.neg = function neg () { + return this.clone().ineg(); + }; + BN.prototype.ineg = function ineg () { + if (!this.isZero()) { + this.negative ^= 1; + } + return this; + }; + BN.prototype.iuor = function iuor (num) { + while (this.length < num.length) { + this.words[this.length++] = 0; + } + for (var i = 0; i < num.length; i++) { + this.words[i] = this.words[i] | num.words[i]; + } + return this._strip(); + }; + BN.prototype.ior = function ior (num) { + assert((this.negative | num.negative) === 0); + return this.iuor(num); + }; + BN.prototype.or = function or (num) { + if (this.length > num.length) return this.clone().ior(num); + return num.clone().ior(this); + }; + BN.prototype.uor = function uor (num) { + if (this.length > num.length) return this.clone().iuor(num); + return num.clone().iuor(this); + }; + BN.prototype.iuand = function iuand (num) { + var b; + if (this.length > num.length) { + b = num; + } else { + b = this; + } + for (var i = 0; i < b.length; i++) { + this.words[i] = this.words[i] & num.words[i]; + } + this.length = b.length; + return this._strip(); + }; + BN.prototype.iand = function iand (num) { + assert((this.negative | num.negative) === 0); + return this.iuand(num); + }; + BN.prototype.and = function and (num) { + if (this.length > num.length) return this.clone().iand(num); + return num.clone().iand(this); + }; + BN.prototype.uand = function uand (num) { + if (this.length > num.length) return this.clone().iuand(num); + return num.clone().iuand(this); + }; + BN.prototype.iuxor = function iuxor (num) { + var a; + var b; + if (this.length > num.length) { + a = this; + b = num; + } else { + a = num; + b = this; + } + for (var i = 0; i < b.length; i++) { + this.words[i] = a.words[i] ^ b.words[i]; + } + if (this !== a) { + for (; i < a.length; i++) { + this.words[i] = a.words[i]; + } + } + this.length = a.length; + return this._strip(); + }; + BN.prototype.ixor = function ixor (num) { + assert((this.negative | num.negative) === 0); + return this.iuxor(num); + }; + BN.prototype.xor = function xor (num) { + if (this.length > num.length) return this.clone().ixor(num); + return num.clone().ixor(this); + }; + BN.prototype.uxor = function uxor (num) { + if (this.length > num.length) return this.clone().iuxor(num); + return num.clone().iuxor(this); + }; + BN.prototype.inotn = function inotn (width) { + assert(typeof width === 'number' && width >= 0); + var bytesNeeded = Math.ceil(width / 26) | 0; + var bitsLeft = width % 26; + this._expand(bytesNeeded); + if (bitsLeft > 0) { + bytesNeeded--; + } + for (var i = 0; i < bytesNeeded; i++) { + this.words[i] = ~this.words[i] & 0x3ffffff; + } + if (bitsLeft > 0) { + this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft)); + } + return this._strip(); + }; + BN.prototype.notn = function notn (width) { + return this.clone().inotn(width); + }; + BN.prototype.setn = function setn (bit, val) { + assert(typeof bit === 'number' && bit >= 0); + var off = (bit / 26) | 0; + var wbit = bit % 26; + this._expand(off + 1); + if (val) { + this.words[off] = this.words[off] | (1 << wbit); + } else { + this.words[off] = this.words[off] & ~(1 << wbit); + } + return this._strip(); + }; + BN.prototype.iadd = function iadd (num) { + var r; + if (this.negative !== 0 && num.negative === 0) { + this.negative = 0; + r = this.isub(num); + this.negative ^= 1; + return this._normSign(); + } else if (this.negative === 0 && num.negative !== 0) { + num.negative = 0; + r = this.isub(num); + num.negative = 1; + return r._normSign(); + } + var a, b; + if (this.length > num.length) { + a = this; + b = num; + } else { + a = num; + b = this; + } + var carry = 0; + for (var i = 0; i < b.length; i++) { + r = (a.words[i] | 0) + (b.words[i] | 0) + carry; + this.words[i] = r & 0x3ffffff; + carry = r >>> 26; + } + for (; carry !== 0 && i < a.length; i++) { + r = (a.words[i] | 0) + carry; + this.words[i] = r & 0x3ffffff; + carry = r >>> 26; + } + this.length = a.length; + if (carry !== 0) { + this.words[this.length] = carry; + this.length++; + } else if (a !== this) { + for (; i < a.length; i++) { + this.words[i] = a.words[i]; + } + } + return this; + }; + BN.prototype.add = function add (num) { + var res; + if (num.negative !== 0 && this.negative === 0) { + num.negative = 0; + res = this.sub(num); + num.negative ^= 1; + return res; + } else if (num.negative === 0 && this.negative !== 0) { + this.negative = 0; + res = num.sub(this); + this.negative = 1; + return res; + } + if (this.length > num.length) return this.clone().iadd(num); + return num.clone().iadd(this); + }; + BN.prototype.isub = function isub (num) { + if (num.negative !== 0) { + num.negative = 0; + var r = this.iadd(num); + num.negative = 1; + return r._normSign(); + } else if (this.negative !== 0) { + this.negative = 0; + this.iadd(num); + this.negative = 1; + return this._normSign(); + } + var cmp = this.cmp(num); + if (cmp === 0) { + this.negative = 0; + this.length = 1; + this.words[0] = 0; + return this; + } + var a, b; + if (cmp > 0) { + a = this; + b = num; + } else { + a = num; + b = this; + } + var carry = 0; + for (var i = 0; i < b.length; i++) { + r = (a.words[i] | 0) - (b.words[i] | 0) + carry; + carry = r >> 26; + this.words[i] = r & 0x3ffffff; + } + for (; carry !== 0 && i < a.length; i++) { + r = (a.words[i] | 0) + carry; + carry = r >> 26; + this.words[i] = r & 0x3ffffff; + } + if (carry === 0 && i < a.length && a !== this) { + for (; i < a.length; i++) { + this.words[i] = a.words[i]; + } + } + this.length = Math.max(this.length, i); + if (a !== this) { + this.negative = 1; + } + return this._strip(); + }; + BN.prototype.sub = function sub (num) { + return this.clone().isub(num); + }; + function smallMulTo (self, num, out) { + out.negative = num.negative ^ self.negative; + var len = (self.length + num.length) | 0; + out.length = len; + len = (len - 1) | 0; + var a = self.words[0] | 0; + var b = num.words[0] | 0; + var r = a * b; + var lo = r & 0x3ffffff; + var carry = (r / 0x4000000) | 0; + out.words[0] = lo; + for (var k = 1; k < len; k++) { + var ncarry = carry >>> 26; + var rword = carry & 0x3ffffff; + var maxJ = Math.min(k, num.length - 1); + for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) { + var i = (k - j) | 0; + a = self.words[i] | 0; + b = num.words[j] | 0; + r = a * b + rword; + ncarry += (r / 0x4000000) | 0; + rword = r & 0x3ffffff; + } + out.words[k] = rword | 0; + carry = ncarry | 0; + } + if (carry !== 0) { + out.words[k] = carry | 0; + } else { + out.length--; + } + return out._strip(); + } + var comb10MulTo = function comb10MulTo (self, num, out) { + var a = self.words; + var b = num.words; + var o = out.words; + var c = 0; + var lo; + var mid; + var hi; + var a0 = a[0] | 0; + var al0 = a0 & 0x1fff; + var ah0 = a0 >>> 13; + var a1 = a[1] | 0; + var al1 = a1 & 0x1fff; + var ah1 = a1 >>> 13; + var a2 = a[2] | 0; + var al2 = a2 & 0x1fff; + var ah2 = a2 >>> 13; + var a3 = a[3] | 0; + var al3 = a3 & 0x1fff; + var ah3 = a3 >>> 13; + var a4 = a[4] | 0; + var al4 = a4 & 0x1fff; + var ah4 = a4 >>> 13; + var a5 = a[5] | 0; + var al5 = a5 & 0x1fff; + var ah5 = a5 >>> 13; + var a6 = a[6] | 0; + var al6 = a6 & 0x1fff; + var ah6 = a6 >>> 13; + var a7 = a[7] | 0; + var al7 = a7 & 0x1fff; + var ah7 = a7 >>> 13; + var a8 = a[8] | 0; + var al8 = a8 & 0x1fff; + var ah8 = a8 >>> 13; + var a9 = a[9] | 0; + var al9 = a9 & 0x1fff; + var ah9 = a9 >>> 13; + var b0 = b[0] | 0; + var bl0 = b0 & 0x1fff; + var bh0 = b0 >>> 13; + var b1 = b[1] | 0; + var bl1 = b1 & 0x1fff; + var bh1 = b1 >>> 13; + var b2 = b[2] | 0; + var bl2 = b2 & 0x1fff; + var bh2 = b2 >>> 13; + var b3 = b[3] | 0; + var bl3 = b3 & 0x1fff; + var bh3 = b3 >>> 13; + var b4 = b[4] | 0; + var bl4 = b4 & 0x1fff; + var bh4 = b4 >>> 13; + var b5 = b[5] | 0; + var bl5 = b5 & 0x1fff; + var bh5 = b5 >>> 13; + var b6 = b[6] | 0; + var bl6 = b6 & 0x1fff; + var bh6 = b6 >>> 13; + var b7 = b[7] | 0; + var bl7 = b7 & 0x1fff; + var bh7 = b7 >>> 13; + var b8 = b[8] | 0; + var bl8 = b8 & 0x1fff; + var bh8 = b8 >>> 13; + var b9 = b[9] | 0; + var bl9 = b9 & 0x1fff; + var bh9 = b9 >>> 13; + out.negative = self.negative ^ num.negative; + out.length = 19; + lo = Math.imul(al0, bl0); + mid = Math.imul(al0, bh0); + mid = (mid + Math.imul(ah0, bl0)) | 0; + hi = Math.imul(ah0, bh0); + var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0; + w0 &= 0x3ffffff; + lo = Math.imul(al1, bl0); + mid = Math.imul(al1, bh0); + mid = (mid + Math.imul(ah1, bl0)) | 0; + hi = Math.imul(ah1, bh0); + lo = (lo + Math.imul(al0, bl1)) | 0; + mid = (mid + Math.imul(al0, bh1)) | 0; + mid = (mid + Math.imul(ah0, bl1)) | 0; + hi = (hi + Math.imul(ah0, bh1)) | 0; + var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0; + w1 &= 0x3ffffff; + lo = Math.imul(al2, bl0); + mid = Math.imul(al2, bh0); + mid = (mid + Math.imul(ah2, bl0)) | 0; + hi = Math.imul(ah2, bh0); + lo = (lo + Math.imul(al1, bl1)) | 0; + mid = (mid + Math.imul(al1, bh1)) | 0; + mid = (mid + Math.imul(ah1, bl1)) | 0; + hi = (hi + Math.imul(ah1, bh1)) | 0; + lo = (lo + Math.imul(al0, bl2)) | 0; + mid = (mid + Math.imul(al0, bh2)) | 0; + mid = (mid + Math.imul(ah0, bl2)) | 0; + hi = (hi + Math.imul(ah0, bh2)) | 0; + var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0; + w2 &= 0x3ffffff; + lo = Math.imul(al3, bl0); + mid = Math.imul(al3, bh0); + mid = (mid + Math.imul(ah3, bl0)) | 0; + hi = Math.imul(ah3, bh0); + lo = (lo + Math.imul(al2, bl1)) | 0; + mid = (mid + Math.imul(al2, bh1)) | 0; + mid = (mid + Math.imul(ah2, bl1)) | 0; + hi = (hi + Math.imul(ah2, bh1)) | 0; + lo = (lo + Math.imul(al1, bl2)) | 0; + mid = (mid + Math.imul(al1, bh2)) | 0; + mid = (mid + Math.imul(ah1, bl2)) | 0; + hi = (hi + Math.imul(ah1, bh2)) | 0; + lo = (lo + Math.imul(al0, bl3)) | 0; + mid = (mid + Math.imul(al0, bh3)) | 0; + mid = (mid + Math.imul(ah0, bl3)) | 0; + hi = (hi + Math.imul(ah0, bh3)) | 0; + var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0; + w3 &= 0x3ffffff; + lo = Math.imul(al4, bl0); + mid = Math.imul(al4, bh0); + mid = (mid + Math.imul(ah4, bl0)) | 0; + hi = Math.imul(ah4, bh0); + lo = (lo + Math.imul(al3, bl1)) | 0; + mid = (mid + Math.imul(al3, bh1)) | 0; + mid = (mid + Math.imul(ah3, bl1)) | 0; + hi = (hi + Math.imul(ah3, bh1)) | 0; + lo = (lo + Math.imul(al2, bl2)) | 0; + mid = (mid + Math.imul(al2, bh2)) | 0; + mid = (mid + Math.imul(ah2, bl2)) | 0; + hi = (hi + Math.imul(ah2, bh2)) | 0; + lo = (lo + Math.imul(al1, bl3)) | 0; + mid = (mid + Math.imul(al1, bh3)) | 0; + mid = (mid + Math.imul(ah1, bl3)) | 0; + hi = (hi + Math.imul(ah1, bh3)) | 0; + lo = (lo + Math.imul(al0, bl4)) | 0; + mid = (mid + Math.imul(al0, bh4)) | 0; + mid = (mid + Math.imul(ah0, bl4)) | 0; + hi = (hi + Math.imul(ah0, bh4)) | 0; + var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0; + w4 &= 0x3ffffff; + lo = Math.imul(al5, bl0); + mid = Math.imul(al5, bh0); + mid = (mid + Math.imul(ah5, bl0)) | 0; + hi = Math.imul(ah5, bh0); + lo = (lo + Math.imul(al4, bl1)) | 0; + mid = (mid + Math.imul(al4, bh1)) | 0; + mid = (mid + Math.imul(ah4, bl1)) | 0; + hi = (hi + Math.imul(ah4, bh1)) | 0; + lo = (lo + Math.imul(al3, bl2)) | 0; + mid = (mid + Math.imul(al3, bh2)) | 0; + mid = (mid + Math.imul(ah3, bl2)) | 0; + hi = (hi + Math.imul(ah3, bh2)) | 0; + lo = (lo + Math.imul(al2, bl3)) | 0; + mid = (mid + Math.imul(al2, bh3)) | 0; + mid = (mid + Math.imul(ah2, bl3)) | 0; + hi = (hi + Math.imul(ah2, bh3)) | 0; + lo = (lo + Math.imul(al1, bl4)) | 0; + mid = (mid + Math.imul(al1, bh4)) | 0; + mid = (mid + Math.imul(ah1, bl4)) | 0; + hi = (hi + Math.imul(ah1, bh4)) | 0; + lo = (lo + Math.imul(al0, bl5)) | 0; + mid = (mid + Math.imul(al0, bh5)) | 0; + mid = (mid + Math.imul(ah0, bl5)) | 0; + hi = (hi + Math.imul(ah0, bh5)) | 0; + var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0; + w5 &= 0x3ffffff; + lo = Math.imul(al6, bl0); + mid = Math.imul(al6, bh0); + mid = (mid + Math.imul(ah6, bl0)) | 0; + hi = Math.imul(ah6, bh0); + lo = (lo + Math.imul(al5, bl1)) | 0; + mid = (mid + Math.imul(al5, bh1)) | 0; + mid = (mid + Math.imul(ah5, bl1)) | 0; + hi = (hi + Math.imul(ah5, bh1)) | 0; + lo = (lo + Math.imul(al4, bl2)) | 0; + mid = (mid + Math.imul(al4, bh2)) | 0; + mid = (mid + Math.imul(ah4, bl2)) | 0; + hi = (hi + Math.imul(ah4, bh2)) | 0; + lo = (lo + Math.imul(al3, bl3)) | 0; + mid = (mid + Math.imul(al3, bh3)) | 0; + mid = (mid + Math.imul(ah3, bl3)) | 0; + hi = (hi + Math.imul(ah3, bh3)) | 0; + lo = (lo + Math.imul(al2, bl4)) | 0; + mid = (mid + Math.imul(al2, bh4)) | 0; + mid = (mid + Math.imul(ah2, bl4)) | 0; + hi = (hi + Math.imul(ah2, bh4)) | 0; + lo = (lo + Math.imul(al1, bl5)) | 0; + mid = (mid + Math.imul(al1, bh5)) | 0; + mid = (mid + Math.imul(ah1, bl5)) | 0; + hi = (hi + Math.imul(ah1, bh5)) | 0; + lo = (lo + Math.imul(al0, bl6)) | 0; + mid = (mid + Math.imul(al0, bh6)) | 0; + mid = (mid + Math.imul(ah0, bl6)) | 0; + hi = (hi + Math.imul(ah0, bh6)) | 0; + var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0; + w6 &= 0x3ffffff; + lo = Math.imul(al7, bl0); + mid = Math.imul(al7, bh0); + mid = (mid + Math.imul(ah7, bl0)) | 0; + hi = Math.imul(ah7, bh0); + lo = (lo + Math.imul(al6, bl1)) | 0; + mid = (mid + Math.imul(al6, bh1)) | 0; + mid = (mid + Math.imul(ah6, bl1)) | 0; + hi = (hi + Math.imul(ah6, bh1)) | 0; + lo = (lo + Math.imul(al5, bl2)) | 0; + mid = (mid + Math.imul(al5, bh2)) | 0; + mid = (mid + Math.imul(ah5, bl2)) | 0; + hi = (hi + Math.imul(ah5, bh2)) | 0; + lo = (lo + Math.imul(al4, bl3)) | 0; + mid = (mid + Math.imul(al4, bh3)) | 0; + mid = (mid + Math.imul(ah4, bl3)) | 0; + hi = (hi + Math.imul(ah4, bh3)) | 0; + lo = (lo + Math.imul(al3, bl4)) | 0; + mid = (mid + Math.imul(al3, bh4)) | 0; + mid = (mid + Math.imul(ah3, bl4)) | 0; + hi = (hi + Math.imul(ah3, bh4)) | 0; + lo = (lo + Math.imul(al2, bl5)) | 0; + mid = (mid + Math.imul(al2, bh5)) | 0; + mid = (mid + Math.imul(ah2, bl5)) | 0; + hi = (hi + Math.imul(ah2, bh5)) | 0; + lo = (lo + Math.imul(al1, bl6)) | 0; + mid = (mid + Math.imul(al1, bh6)) | 0; + mid = (mid + Math.imul(ah1, bl6)) | 0; + hi = (hi + Math.imul(ah1, bh6)) | 0; + lo = (lo + Math.imul(al0, bl7)) | 0; + mid = (mid + Math.imul(al0, bh7)) | 0; + mid = (mid + Math.imul(ah0, bl7)) | 0; + hi = (hi + Math.imul(ah0, bh7)) | 0; + var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0; + w7 &= 0x3ffffff; + lo = Math.imul(al8, bl0); + mid = Math.imul(al8, bh0); + mid = (mid + Math.imul(ah8, bl0)) | 0; + hi = Math.imul(ah8, bh0); + lo = (lo + Math.imul(al7, bl1)) | 0; + mid = (mid + Math.imul(al7, bh1)) | 0; + mid = (mid + Math.imul(ah7, bl1)) | 0; + hi = (hi + Math.imul(ah7, bh1)) | 0; + lo = (lo + Math.imul(al6, bl2)) | 0; + mid = (mid + Math.imul(al6, bh2)) | 0; + mid = (mid + Math.imul(ah6, bl2)) | 0; + hi = (hi + Math.imul(ah6, bh2)) | 0; + lo = (lo + Math.imul(al5, bl3)) | 0; + mid = (mid + Math.imul(al5, bh3)) | 0; + mid = (mid + Math.imul(ah5, bl3)) | 0; + hi = (hi + Math.imul(ah5, bh3)) | 0; + lo = (lo + Math.imul(al4, bl4)) | 0; + mid = (mid + Math.imul(al4, bh4)) | 0; + mid = (mid + Math.imul(ah4, bl4)) | 0; + hi = (hi + Math.imul(ah4, bh4)) | 0; + lo = (lo + Math.imul(al3, bl5)) | 0; + mid = (mid + Math.imul(al3, bh5)) | 0; + mid = (mid + Math.imul(ah3, bl5)) | 0; + hi = (hi + Math.imul(ah3, bh5)) | 0; + lo = (lo + Math.imul(al2, bl6)) | 0; + mid = (mid + Math.imul(al2, bh6)) | 0; + mid = (mid + Math.imul(ah2, bl6)) | 0; + hi = (hi + Math.imul(ah2, bh6)) | 0; + lo = (lo + Math.imul(al1, bl7)) | 0; + mid = (mid + Math.imul(al1, bh7)) | 0; + mid = (mid + Math.imul(ah1, bl7)) | 0; + hi = (hi + Math.imul(ah1, bh7)) | 0; + lo = (lo + Math.imul(al0, bl8)) | 0; + mid = (mid + Math.imul(al0, bh8)) | 0; + mid = (mid + Math.imul(ah0, bl8)) | 0; + hi = (hi + Math.imul(ah0, bh8)) | 0; + var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0; + w8 &= 0x3ffffff; + lo = Math.imul(al9, bl0); + mid = Math.imul(al9, bh0); + mid = (mid + Math.imul(ah9, bl0)) | 0; + hi = Math.imul(ah9, bh0); + lo = (lo + Math.imul(al8, bl1)) | 0; + mid = (mid + Math.imul(al8, bh1)) | 0; + mid = (mid + Math.imul(ah8, bl1)) | 0; + hi = (hi + Math.imul(ah8, bh1)) | 0; + lo = (lo + Math.imul(al7, bl2)) | 0; + mid = (mid + Math.imul(al7, bh2)) | 0; + mid = (mid + Math.imul(ah7, bl2)) | 0; + hi = (hi + Math.imul(ah7, bh2)) | 0; + lo = (lo + Math.imul(al6, bl3)) | 0; + mid = (mid + Math.imul(al6, bh3)) | 0; + mid = (mid + Math.imul(ah6, bl3)) | 0; + hi = (hi + Math.imul(ah6, bh3)) | 0; + lo = (lo + Math.imul(al5, bl4)) | 0; + mid = (mid + Math.imul(al5, bh4)) | 0; + mid = (mid + Math.imul(ah5, bl4)) | 0; + hi = (hi + Math.imul(ah5, bh4)) | 0; + lo = (lo + Math.imul(al4, bl5)) | 0; + mid = (mid + Math.imul(al4, bh5)) | 0; + mid = (mid + Math.imul(ah4, bl5)) | 0; + hi = (hi + Math.imul(ah4, bh5)) | 0; + lo = (lo + Math.imul(al3, bl6)) | 0; + mid = (mid + Math.imul(al3, bh6)) | 0; + mid = (mid + Math.imul(ah3, bl6)) | 0; + hi = (hi + Math.imul(ah3, bh6)) | 0; + lo = (lo + Math.imul(al2, bl7)) | 0; + mid = (mid + Math.imul(al2, bh7)) | 0; + mid = (mid + Math.imul(ah2, bl7)) | 0; + hi = (hi + Math.imul(ah2, bh7)) | 0; + lo = (lo + Math.imul(al1, bl8)) | 0; + mid = (mid + Math.imul(al1, bh8)) | 0; + mid = (mid + Math.imul(ah1, bl8)) | 0; + hi = (hi + Math.imul(ah1, bh8)) | 0; + lo = (lo + Math.imul(al0, bl9)) | 0; + mid = (mid + Math.imul(al0, bh9)) | 0; + mid = (mid + Math.imul(ah0, bl9)) | 0; + hi = (hi + Math.imul(ah0, bh9)) | 0; + var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0; + w9 &= 0x3ffffff; + lo = Math.imul(al9, bl1); + mid = Math.imul(al9, bh1); + mid = (mid + Math.imul(ah9, bl1)) | 0; + hi = Math.imul(ah9, bh1); + lo = (lo + Math.imul(al8, bl2)) | 0; + mid = (mid + Math.imul(al8, bh2)) | 0; + mid = (mid + Math.imul(ah8, bl2)) | 0; + hi = (hi + Math.imul(ah8, bh2)) | 0; + lo = (lo + Math.imul(al7, bl3)) | 0; + mid = (mid + Math.imul(al7, bh3)) | 0; + mid = (mid + Math.imul(ah7, bl3)) | 0; + hi = (hi + Math.imul(ah7, bh3)) | 0; + lo = (lo + Math.imul(al6, bl4)) | 0; + mid = (mid + Math.imul(al6, bh4)) | 0; + mid = (mid + Math.imul(ah6, bl4)) | 0; + hi = (hi + Math.imul(ah6, bh4)) | 0; + lo = (lo + Math.imul(al5, bl5)) | 0; + mid = (mid + Math.imul(al5, bh5)) | 0; + mid = (mid + Math.imul(ah5, bl5)) | 0; + hi = (hi + Math.imul(ah5, bh5)) | 0; + lo = (lo + Math.imul(al4, bl6)) | 0; + mid = (mid + Math.imul(al4, bh6)) | 0; + mid = (mid + Math.imul(ah4, bl6)) | 0; + hi = (hi + Math.imul(ah4, bh6)) | 0; + lo = (lo + Math.imul(al3, bl7)) | 0; + mid = (mid + Math.imul(al3, bh7)) | 0; + mid = (mid + Math.imul(ah3, bl7)) | 0; + hi = (hi + Math.imul(ah3, bh7)) | 0; + lo = (lo + Math.imul(al2, bl8)) | 0; + mid = (mid + Math.imul(al2, bh8)) | 0; + mid = (mid + Math.imul(ah2, bl8)) | 0; + hi = (hi + Math.imul(ah2, bh8)) | 0; + lo = (lo + Math.imul(al1, bl9)) | 0; + mid = (mid + Math.imul(al1, bh9)) | 0; + mid = (mid + Math.imul(ah1, bl9)) | 0; + hi = (hi + Math.imul(ah1, bh9)) | 0; + var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0; + w10 &= 0x3ffffff; + lo = Math.imul(al9, bl2); + mid = Math.imul(al9, bh2); + mid = (mid + Math.imul(ah9, bl2)) | 0; + hi = Math.imul(ah9, bh2); + lo = (lo + Math.imul(al8, bl3)) | 0; + mid = (mid + Math.imul(al8, bh3)) | 0; + mid = (mid + Math.imul(ah8, bl3)) | 0; + hi = (hi + Math.imul(ah8, bh3)) | 0; + lo = (lo + Math.imul(al7, bl4)) | 0; + mid = (mid + Math.imul(al7, bh4)) | 0; + mid = (mid + Math.imul(ah7, bl4)) | 0; + hi = (hi + Math.imul(ah7, bh4)) | 0; + lo = (lo + Math.imul(al6, bl5)) | 0; + mid = (mid + Math.imul(al6, bh5)) | 0; + mid = (mid + Math.imul(ah6, bl5)) | 0; + hi = (hi + Math.imul(ah6, bh5)) | 0; + lo = (lo + Math.imul(al5, bl6)) | 0; + mid = (mid + Math.imul(al5, bh6)) | 0; + mid = (mid + Math.imul(ah5, bl6)) | 0; + hi = (hi + Math.imul(ah5, bh6)) | 0; + lo = (lo + Math.imul(al4, bl7)) | 0; + mid = (mid + Math.imul(al4, bh7)) | 0; + mid = (mid + Math.imul(ah4, bl7)) | 0; + hi = (hi + Math.imul(ah4, bh7)) | 0; + lo = (lo + Math.imul(al3, bl8)) | 0; + mid = (mid + Math.imul(al3, bh8)) | 0; + mid = (mid + Math.imul(ah3, bl8)) | 0; + hi = (hi + Math.imul(ah3, bh8)) | 0; + lo = (lo + Math.imul(al2, bl9)) | 0; + mid = (mid + Math.imul(al2, bh9)) | 0; + mid = (mid + Math.imul(ah2, bl9)) | 0; + hi = (hi + Math.imul(ah2, bh9)) | 0; + var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0; + w11 &= 0x3ffffff; + lo = Math.imul(al9, bl3); + mid = Math.imul(al9, bh3); + mid = (mid + Math.imul(ah9, bl3)) | 0; + hi = Math.imul(ah9, bh3); + lo = (lo + Math.imul(al8, bl4)) | 0; + mid = (mid + Math.imul(al8, bh4)) | 0; + mid = (mid + Math.imul(ah8, bl4)) | 0; + hi = (hi + Math.imul(ah8, bh4)) | 0; + lo = (lo + Math.imul(al7, bl5)) | 0; + mid = (mid + Math.imul(al7, bh5)) | 0; + mid = (mid + Math.imul(ah7, bl5)) | 0; + hi = (hi + Math.imul(ah7, bh5)) | 0; + lo = (lo + Math.imul(al6, bl6)) | 0; + mid = (mid + Math.imul(al6, bh6)) | 0; + mid = (mid + Math.imul(ah6, bl6)) | 0; + hi = (hi + Math.imul(ah6, bh6)) | 0; + lo = (lo + Math.imul(al5, bl7)) | 0; + mid = (mid + Math.imul(al5, bh7)) | 0; + mid = (mid + Math.imul(ah5, bl7)) | 0; + hi = (hi + Math.imul(ah5, bh7)) | 0; + lo = (lo + Math.imul(al4, bl8)) | 0; + mid = (mid + Math.imul(al4, bh8)) | 0; + mid = (mid + Math.imul(ah4, bl8)) | 0; + hi = (hi + Math.imul(ah4, bh8)) | 0; + lo = (lo + Math.imul(al3, bl9)) | 0; + mid = (mid + Math.imul(al3, bh9)) | 0; + mid = (mid + Math.imul(ah3, bl9)) | 0; + hi = (hi + Math.imul(ah3, bh9)) | 0; + var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0; + w12 &= 0x3ffffff; + lo = Math.imul(al9, bl4); + mid = Math.imul(al9, bh4); + mid = (mid + Math.imul(ah9, bl4)) | 0; + hi = Math.imul(ah9, bh4); + lo = (lo + Math.imul(al8, bl5)) | 0; + mid = (mid + Math.imul(al8, bh5)) | 0; + mid = (mid + Math.imul(ah8, bl5)) | 0; + hi = (hi + Math.imul(ah8, bh5)) | 0; + lo = (lo + Math.imul(al7, bl6)) | 0; + mid = (mid + Math.imul(al7, bh6)) | 0; + mid = (mid + Math.imul(ah7, bl6)) | 0; + hi = (hi + Math.imul(ah7, bh6)) | 0; + lo = (lo + Math.imul(al6, bl7)) | 0; + mid = (mid + Math.imul(al6, bh7)) | 0; + mid = (mid + Math.imul(ah6, bl7)) | 0; + hi = (hi + Math.imul(ah6, bh7)) | 0; + lo = (lo + Math.imul(al5, bl8)) | 0; + mid = (mid + Math.imul(al5, bh8)) | 0; + mid = (mid + Math.imul(ah5, bl8)) | 0; + hi = (hi + Math.imul(ah5, bh8)) | 0; + lo = (lo + Math.imul(al4, bl9)) | 0; + mid = (mid + Math.imul(al4, bh9)) | 0; + mid = (mid + Math.imul(ah4, bl9)) | 0; + hi = (hi + Math.imul(ah4, bh9)) | 0; + var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0; + w13 &= 0x3ffffff; + lo = Math.imul(al9, bl5); + mid = Math.imul(al9, bh5); + mid = (mid + Math.imul(ah9, bl5)) | 0; + hi = Math.imul(ah9, bh5); + lo = (lo + Math.imul(al8, bl6)) | 0; + mid = (mid + Math.imul(al8, bh6)) | 0; + mid = (mid + Math.imul(ah8, bl6)) | 0; + hi = (hi + Math.imul(ah8, bh6)) | 0; + lo = (lo + Math.imul(al7, bl7)) | 0; + mid = (mid + Math.imul(al7, bh7)) | 0; + mid = (mid + Math.imul(ah7, bl7)) | 0; + hi = (hi + Math.imul(ah7, bh7)) | 0; + lo = (lo + Math.imul(al6, bl8)) | 0; + mid = (mid + Math.imul(al6, bh8)) | 0; + mid = (mid + Math.imul(ah6, bl8)) | 0; + hi = (hi + Math.imul(ah6, bh8)) | 0; + lo = (lo + Math.imul(al5, bl9)) | 0; + mid = (mid + Math.imul(al5, bh9)) | 0; + mid = (mid + Math.imul(ah5, bl9)) | 0; + hi = (hi + Math.imul(ah5, bh9)) | 0; + var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0; + w14 &= 0x3ffffff; + lo = Math.imul(al9, bl6); + mid = Math.imul(al9, bh6); + mid = (mid + Math.imul(ah9, bl6)) | 0; + hi = Math.imul(ah9, bh6); + lo = (lo + Math.imul(al8, bl7)) | 0; + mid = (mid + Math.imul(al8, bh7)) | 0; + mid = (mid + Math.imul(ah8, bl7)) | 0; + hi = (hi + Math.imul(ah8, bh7)) | 0; + lo = (lo + Math.imul(al7, bl8)) | 0; + mid = (mid + Math.imul(al7, bh8)) | 0; + mid = (mid + Math.imul(ah7, bl8)) | 0; + hi = (hi + Math.imul(ah7, bh8)) | 0; + lo = (lo + Math.imul(al6, bl9)) | 0; + mid = (mid + Math.imul(al6, bh9)) | 0; + mid = (mid + Math.imul(ah6, bl9)) | 0; + hi = (hi + Math.imul(ah6, bh9)) | 0; + var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0; + w15 &= 0x3ffffff; + lo = Math.imul(al9, bl7); + mid = Math.imul(al9, bh7); + mid = (mid + Math.imul(ah9, bl7)) | 0; + hi = Math.imul(ah9, bh7); + lo = (lo + Math.imul(al8, bl8)) | 0; + mid = (mid + Math.imul(al8, bh8)) | 0; + mid = (mid + Math.imul(ah8, bl8)) | 0; + hi = (hi + Math.imul(ah8, bh8)) | 0; + lo = (lo + Math.imul(al7, bl9)) | 0; + mid = (mid + Math.imul(al7, bh9)) | 0; + mid = (mid + Math.imul(ah7, bl9)) | 0; + hi = (hi + Math.imul(ah7, bh9)) | 0; + var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0; + w16 &= 0x3ffffff; + lo = Math.imul(al9, bl8); + mid = Math.imul(al9, bh8); + mid = (mid + Math.imul(ah9, bl8)) | 0; + hi = Math.imul(ah9, bh8); + lo = (lo + Math.imul(al8, bl9)) | 0; + mid = (mid + Math.imul(al8, bh9)) | 0; + mid = (mid + Math.imul(ah8, bl9)) | 0; + hi = (hi + Math.imul(ah8, bh9)) | 0; + var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0; + w17 &= 0x3ffffff; + lo = Math.imul(al9, bl9); + mid = Math.imul(al9, bh9); + mid = (mid + Math.imul(ah9, bl9)) | 0; + hi = Math.imul(ah9, bh9); + var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0; + w18 &= 0x3ffffff; + o[0] = w0; + o[1] = w1; + o[2] = w2; + o[3] = w3; + o[4] = w4; + o[5] = w5; + o[6] = w6; + o[7] = w7; + o[8] = w8; + o[9] = w9; + o[10] = w10; + o[11] = w11; + o[12] = w12; + o[13] = w13; + o[14] = w14; + o[15] = w15; + o[16] = w16; + o[17] = w17; + o[18] = w18; + if (c !== 0) { + o[19] = c; + out.length++; + } + return out; + }; + if (!Math.imul) { + comb10MulTo = smallMulTo; + } + function bigMulTo (self, num, out) { + out.negative = num.negative ^ self.negative; + out.length = self.length + num.length; + var carry = 0; + var hncarry = 0; + for (var k = 0; k < out.length - 1; k++) { + var ncarry = hncarry; + hncarry = 0; + var rword = carry & 0x3ffffff; + var maxJ = Math.min(k, num.length - 1); + for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) { + var i = k - j; + var a = self.words[i] | 0; + var b = num.words[j] | 0; + var r = a * b; + var lo = r & 0x3ffffff; + ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0; + lo = (lo + rword) | 0; + rword = lo & 0x3ffffff; + ncarry = (ncarry + (lo >>> 26)) | 0; + hncarry += ncarry >>> 26; + ncarry &= 0x3ffffff; + } + out.words[k] = rword; + carry = ncarry; + ncarry = hncarry; + } + if (carry !== 0) { + out.words[k] = carry; + } else { + out.length--; + } + return out._strip(); + } + function jumboMulTo (self, num, out) { + return bigMulTo(self, num, out); + } + BN.prototype.mulTo = function mulTo (num, out) { + var res; + var len = this.length + num.length; + if (this.length === 10 && num.length === 10) { + res = comb10MulTo(this, num, out); + } else if (len < 63) { + res = smallMulTo(this, num, out); + } else if (len < 1024) { + res = bigMulTo(this, num, out); + } else { + res = jumboMulTo(this, num, out); + } + return res; + }; + BN.prototype.mul = function mul (num) { + var out = new BN(null); + out.words = new Array(this.length + num.length); + return this.mulTo(num, out); + }; + BN.prototype.mulf = function mulf (num) { + var out = new BN(null); + out.words = new Array(this.length + num.length); + return jumboMulTo(this, num, out); + }; + BN.prototype.imul = function imul (num) { + return this.clone().mulTo(num, this); + }; + BN.prototype.imuln = function imuln (num) { + var isNegNum = num < 0; + if (isNegNum) num = -num; + assert(typeof num === 'number'); + assert(num < 0x4000000); + var carry = 0; + for (var i = 0; i < this.length; i++) { + var w = (this.words[i] | 0) * num; + var lo = (w & 0x3ffffff) + (carry & 0x3ffffff); + carry >>= 26; + carry += (w / 0x4000000) | 0; + carry += lo >>> 26; + this.words[i] = lo & 0x3ffffff; + } + if (carry !== 0) { + this.words[i] = carry; + this.length++; + } + this.length = num === 0 ? 1 : this.length; + return isNegNum ? this.ineg() : this; + }; + BN.prototype.muln = function muln (num) { + return this.clone().imuln(num); + }; + BN.prototype.sqr = function sqr () { + return this.mul(this); + }; + BN.prototype.isqr = function isqr () { + return this.imul(this.clone()); + }; + BN.prototype.pow = function pow (num) { + var w = toBitArray(num); + if (w.length === 0) return new BN(1); + var res = this; + for (var i = 0; i < w.length; i++, res = res.sqr()) { + if (w[i] !== 0) break; + } + if (++i < w.length) { + for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) { + if (w[i] === 0) continue; + res = res.mul(q); + } + } + return res; + }; + BN.prototype.iushln = function iushln (bits) { + assert(typeof bits === 'number' && bits >= 0); + var r = bits % 26; + var s = (bits - r) / 26; + var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r); + var i; + if (r !== 0) { + var carry = 0; + for (i = 0; i < this.length; i++) { + var newCarry = this.words[i] & carryMask; + var c = ((this.words[i] | 0) - newCarry) << r; + this.words[i] = c | carry; + carry = newCarry >>> (26 - r); + } + if (carry) { + this.words[i] = carry; + this.length++; + } + } + if (s !== 0) { + for (i = this.length - 1; i >= 0; i--) { + this.words[i + s] = this.words[i]; + } + for (i = 0; i < s; i++) { + this.words[i] = 0; + } + this.length += s; + } + return this._strip(); + }; + BN.prototype.ishln = function ishln (bits) { + assert(this.negative === 0); + return this.iushln(bits); + }; + BN.prototype.iushrn = function iushrn (bits, hint, extended) { + assert(typeof bits === 'number' && bits >= 0); + var h; + if (hint) { + h = (hint - (hint % 26)) / 26; + } else { + h = 0; + } + var r = bits % 26; + var s = Math.min((bits - r) / 26, this.length); + var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); + var maskedWords = extended; + h -= s; + h = Math.max(0, h); + if (maskedWords) { + for (var i = 0; i < s; i++) { + maskedWords.words[i] = this.words[i]; + } + maskedWords.length = s; + } + if (s === 0) ; else if (this.length > s) { + this.length -= s; + for (i = 0; i < this.length; i++) { + this.words[i] = this.words[i + s]; + } + } else { + this.words[0] = 0; + this.length = 1; + } + var carry = 0; + for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) { + var word = this.words[i] | 0; + this.words[i] = (carry << (26 - r)) | (word >>> r); + carry = word & mask; + } + if (maskedWords && carry !== 0) { + maskedWords.words[maskedWords.length++] = carry; + } + if (this.length === 0) { + this.words[0] = 0; + this.length = 1; + } + return this._strip(); + }; + BN.prototype.ishrn = function ishrn (bits, hint, extended) { + assert(this.negative === 0); + return this.iushrn(bits, hint, extended); + }; + BN.prototype.shln = function shln (bits) { + return this.clone().ishln(bits); + }; + BN.prototype.ushln = function ushln (bits) { + return this.clone().iushln(bits); + }; + BN.prototype.shrn = function shrn (bits) { + return this.clone().ishrn(bits); + }; + BN.prototype.ushrn = function ushrn (bits) { + return this.clone().iushrn(bits); + }; + BN.prototype.testn = function testn (bit) { + assert(typeof bit === 'number' && bit >= 0); + var r = bit % 26; + var s = (bit - r) / 26; + var q = 1 << r; + if (this.length <= s) return false; + var w = this.words[s]; + return !!(w & q); + }; + BN.prototype.imaskn = function imaskn (bits) { + assert(typeof bits === 'number' && bits >= 0); + var r = bits % 26; + var s = (bits - r) / 26; + assert(this.negative === 0, 'imaskn works only with positive numbers'); + if (this.length <= s) { + return this; + } + if (r !== 0) { + s++; + } + this.length = Math.min(s, this.length); + if (r !== 0) { + var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); + this.words[this.length - 1] &= mask; + } + return this._strip(); + }; + BN.prototype.maskn = function maskn (bits) { + return this.clone().imaskn(bits); + }; + BN.prototype.iaddn = function iaddn (num) { + assert(typeof num === 'number'); + assert(num < 0x4000000); + if (num < 0) return this.isubn(-num); + if (this.negative !== 0) { + if (this.length === 1 && (this.words[0] | 0) <= num) { + this.words[0] = num - (this.words[0] | 0); + this.negative = 0; + return this; + } + this.negative = 0; + this.isubn(num); + this.negative = 1; + return this; + } + return this._iaddn(num); + }; + BN.prototype._iaddn = function _iaddn (num) { + this.words[0] += num; + for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) { + this.words[i] -= 0x4000000; + if (i === this.length - 1) { + this.words[i + 1] = 1; + } else { + this.words[i + 1]++; + } + } + this.length = Math.max(this.length, i + 1); + return this; + }; + BN.prototype.isubn = function isubn (num) { + assert(typeof num === 'number'); + assert(num < 0x4000000); + if (num < 0) return this.iaddn(-num); + if (this.negative !== 0) { + this.negative = 0; + this.iaddn(num); + this.negative = 1; + return this; + } + this.words[0] -= num; + if (this.length === 1 && this.words[0] < 0) { + this.words[0] = -this.words[0]; + this.negative = 1; + } else { + for (var i = 0; i < this.length && this.words[i] < 0; i++) { + this.words[i] += 0x4000000; + this.words[i + 1] -= 1; + } + } + return this._strip(); + }; + BN.prototype.addn = function addn (num) { + return this.clone().iaddn(num); + }; + BN.prototype.subn = function subn (num) { + return this.clone().isubn(num); + }; + BN.prototype.iabs = function iabs () { + this.negative = 0; + return this; + }; + BN.prototype.abs = function abs () { + return this.clone().iabs(); + }; + BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) { + var len = num.length + shift; + var i; + this._expand(len); + var w; + var carry = 0; + for (i = 0; i < num.length; i++) { + w = (this.words[i + shift] | 0) + carry; + var right = (num.words[i] | 0) * mul; + w -= right & 0x3ffffff; + carry = (w >> 26) - ((right / 0x4000000) | 0); + this.words[i + shift] = w & 0x3ffffff; + } + for (; i < this.length - shift; i++) { + w = (this.words[i + shift] | 0) + carry; + carry = w >> 26; + this.words[i + shift] = w & 0x3ffffff; + } + if (carry === 0) return this._strip(); + assert(carry === -1); + carry = 0; + for (i = 0; i < this.length; i++) { + w = -(this.words[i] | 0) + carry; + carry = w >> 26; + this.words[i] = w & 0x3ffffff; + } + this.negative = 1; + return this._strip(); + }; + BN.prototype._wordDiv = function _wordDiv (num, mode) { + var shift = this.length - num.length; + var a = this.clone(); + var b = num; + var bhi = b.words[b.length - 1] | 0; + var bhiBits = this._countBits(bhi); + shift = 26 - bhiBits; + if (shift !== 0) { + b = b.ushln(shift); + a.iushln(shift); + bhi = b.words[b.length - 1] | 0; + } + var m = a.length - b.length; + var q; + if (mode !== 'mod') { + q = new BN(null); + q.length = m + 1; + q.words = new Array(q.length); + for (var i = 0; i < q.length; i++) { + q.words[i] = 0; + } + } + var diff = a.clone()._ishlnsubmul(b, 1, m); + if (diff.negative === 0) { + a = diff; + if (q) { + q.words[m] = 1; + } + } + for (var j = m - 1; j >= 0; j--) { + var qj = (a.words[b.length + j] | 0) * 0x4000000 + + (a.words[b.length + j - 1] | 0); + qj = Math.min((qj / bhi) | 0, 0x3ffffff); + a._ishlnsubmul(b, qj, j); + while (a.negative !== 0) { + qj--; + a.negative = 0; + a._ishlnsubmul(b, 1, j); + if (!a.isZero()) { + a.negative ^= 1; + } + } + if (q) { + q.words[j] = qj; + } + } + if (q) { + q._strip(); + } + a._strip(); + if (mode !== 'div' && shift !== 0) { + a.iushrn(shift); + } + return { + div: q || null, + mod: a + }; + }; + BN.prototype.divmod = function divmod (num, mode, positive) { + assert(!num.isZero()); + if (this.isZero()) { + return { + div: new BN(0), + mod: new BN(0) + }; + } + var div, mod, res; + if (this.negative !== 0 && num.negative === 0) { + res = this.neg().divmod(num, mode); + if (mode !== 'mod') { + div = res.div.neg(); + } + if (mode !== 'div') { + mod = res.mod.neg(); + if (positive && mod.negative !== 0) { + mod.iadd(num); + } + } + return { + div: div, + mod: mod + }; + } + if (this.negative === 0 && num.negative !== 0) { + res = this.divmod(num.neg(), mode); + if (mode !== 'mod') { + div = res.div.neg(); + } + return { + div: div, + mod: res.mod + }; + } + if ((this.negative & num.negative) !== 0) { + res = this.neg().divmod(num.neg(), mode); + if (mode !== 'div') { + mod = res.mod.neg(); + if (positive && mod.negative !== 0) { + mod.isub(num); + } + } + return { + div: res.div, + mod: mod + }; + } + if (num.length > this.length || this.cmp(num) < 0) { + return { + div: new BN(0), + mod: this + }; + } + if (num.length === 1) { + if (mode === 'div') { + return { + div: this.divn(num.words[0]), + mod: null + }; + } + if (mode === 'mod') { + return { + div: null, + mod: new BN(this.modrn(num.words[0])) + }; + } + return { + div: this.divn(num.words[0]), + mod: new BN(this.modrn(num.words[0])) + }; + } + return this._wordDiv(num, mode); + }; + BN.prototype.div = function div (num) { + return this.divmod(num, 'div', false).div; + }; + BN.prototype.mod = function mod (num) { + return this.divmod(num, 'mod', false).mod; + }; + BN.prototype.umod = function umod (num) { + return this.divmod(num, 'mod', true).mod; + }; + BN.prototype.divRound = function divRound (num) { + var dm = this.divmod(num); + if (dm.mod.isZero()) return dm.div; + var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod; + var half = num.ushrn(1); + var r2 = num.andln(1); + var cmp = mod.cmp(half); + if (cmp < 0 || (r2 === 1 && cmp === 0)) return dm.div; + return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1); + }; + BN.prototype.modrn = function modrn (num) { + var isNegNum = num < 0; + if (isNegNum) num = -num; + assert(num <= 0x3ffffff); + var p = (1 << 26) % num; + var acc = 0; + for (var i = this.length - 1; i >= 0; i--) { + acc = (p * acc + (this.words[i] | 0)) % num; + } + return isNegNum ? -acc : acc; + }; + BN.prototype.modn = function modn (num) { + return this.modrn(num); + }; + BN.prototype.idivn = function idivn (num) { + var isNegNum = num < 0; + if (isNegNum) num = -num; + assert(num <= 0x3ffffff); + var carry = 0; + for (var i = this.length - 1; i >= 0; i--) { + var w = (this.words[i] | 0) + carry * 0x4000000; + this.words[i] = (w / num) | 0; + carry = w % num; + } + this._strip(); + return isNegNum ? this.ineg() : this; + }; + BN.prototype.divn = function divn (num) { + return this.clone().idivn(num); + }; + BN.prototype.egcd = function egcd (p) { + assert(p.negative === 0); + assert(!p.isZero()); + var x = this; + var y = p.clone(); + if (x.negative !== 0) { + x = x.umod(p); + } else { + x = x.clone(); + } + var A = new BN(1); + var B = new BN(0); + var C = new BN(0); + var D = new BN(1); + var g = 0; + while (x.isEven() && y.isEven()) { + x.iushrn(1); + y.iushrn(1); + ++g; + } + var yp = y.clone(); + var xp = x.clone(); + while (!x.isZero()) { + for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1); + if (i > 0) { + x.iushrn(i); + while (i-- > 0) { + if (A.isOdd() || B.isOdd()) { + A.iadd(yp); + B.isub(xp); + } + A.iushrn(1); + B.iushrn(1); + } + } + for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1); + if (j > 0) { + y.iushrn(j); + while (j-- > 0) { + if (C.isOdd() || D.isOdd()) { + C.iadd(yp); + D.isub(xp); + } + C.iushrn(1); + D.iushrn(1); + } + } + if (x.cmp(y) >= 0) { + x.isub(y); + A.isub(C); + B.isub(D); + } else { + y.isub(x); + C.isub(A); + D.isub(B); + } + } + return { + a: C, + b: D, + gcd: y.iushln(g) + }; + }; + BN.prototype._invmp = function _invmp (p) { + assert(p.negative === 0); + assert(!p.isZero()); + var a = this; + var b = p.clone(); + if (a.negative !== 0) { + a = a.umod(p); + } else { + a = a.clone(); + } + var x1 = new BN(1); + var x2 = new BN(0); + var delta = b.clone(); + while (a.cmpn(1) > 0 && b.cmpn(1) > 0) { + for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1); + if (i > 0) { + a.iushrn(i); + while (i-- > 0) { + if (x1.isOdd()) { + x1.iadd(delta); + } + x1.iushrn(1); + } + } + for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1); + if (j > 0) { + b.iushrn(j); + while (j-- > 0) { + if (x2.isOdd()) { + x2.iadd(delta); + } + x2.iushrn(1); + } + } + if (a.cmp(b) >= 0) { + a.isub(b); + x1.isub(x2); + } else { + b.isub(a); + x2.isub(x1); + } + } + var res; + if (a.cmpn(1) === 0) { + res = x1; + } else { + res = x2; + } + if (res.cmpn(0) < 0) { + res.iadd(p); + } + return res; + }; + BN.prototype.gcd = function gcd (num) { + if (this.isZero()) return num.abs(); + if (num.isZero()) return this.abs(); + var a = this.clone(); + var b = num.clone(); + a.negative = 0; + b.negative = 0; + for (var shift = 0; a.isEven() && b.isEven(); shift++) { + a.iushrn(1); + b.iushrn(1); + } + do { + while (a.isEven()) { + a.iushrn(1); + } + while (b.isEven()) { + b.iushrn(1); + } + var r = a.cmp(b); + if (r < 0) { + var t = a; + a = b; + b = t; + } else if (r === 0 || b.cmpn(1) === 0) { + break; + } + a.isub(b); + } while (true); + return b.iushln(shift); + }; + BN.prototype.invm = function invm (num) { + return this.egcd(num).a.umod(num); + }; + BN.prototype.isEven = function isEven () { + return (this.words[0] & 1) === 0; + }; + BN.prototype.isOdd = function isOdd () { + return (this.words[0] & 1) === 1; + }; + BN.prototype.andln = function andln (num) { + return this.words[0] & num; + }; + BN.prototype.bincn = function bincn (bit) { + assert(typeof bit === 'number'); + var r = bit % 26; + var s = (bit - r) / 26; + var q = 1 << r; + if (this.length <= s) { + this._expand(s + 1); + this.words[s] |= q; + return this; + } + var carry = q; + for (var i = s; carry !== 0 && i < this.length; i++) { + var w = this.words[i] | 0; + w += carry; + carry = w >>> 26; + w &= 0x3ffffff; + this.words[i] = w; + } + if (carry !== 0) { + this.words[i] = carry; + this.length++; + } + return this; + }; + BN.prototype.isZero = function isZero () { + return this.length === 1 && this.words[0] === 0; + }; + BN.prototype.cmpn = function cmpn (num) { + var negative = num < 0; + if (this.negative !== 0 && !negative) return -1; + if (this.negative === 0 && negative) return 1; + this._strip(); + var res; + if (this.length > 1) { + res = 1; + } else { + if (negative) { + num = -num; + } + assert(num <= 0x3ffffff, 'Number is too big'); + var w = this.words[0] | 0; + res = w === num ? 0 : w < num ? -1 : 1; + } + if (this.negative !== 0) return -res | 0; + return res; + }; + BN.prototype.cmp = function cmp (num) { + if (this.negative !== 0 && num.negative === 0) return -1; + if (this.negative === 0 && num.negative !== 0) return 1; + var res = this.ucmp(num); + if (this.negative !== 0) return -res | 0; + return res; + }; + BN.prototype.ucmp = function ucmp (num) { + if (this.length > num.length) return 1; + if (this.length < num.length) return -1; + var res = 0; + for (var i = this.length - 1; i >= 0; i--) { + var a = this.words[i] | 0; + var b = num.words[i] | 0; + if (a === b) continue; + if (a < b) { + res = -1; + } else if (a > b) { + res = 1; + } + break; + } + return res; + }; + BN.prototype.gtn = function gtn (num) { + return this.cmpn(num) === 1; + }; + BN.prototype.gt = function gt (num) { + return this.cmp(num) === 1; + }; + BN.prototype.gten = function gten (num) { + return this.cmpn(num) >= 0; + }; + BN.prototype.gte = function gte (num) { + return this.cmp(num) >= 0; + }; + BN.prototype.ltn = function ltn (num) { + return this.cmpn(num) === -1; + }; + BN.prototype.lt = function lt (num) { + return this.cmp(num) === -1; + }; + BN.prototype.lten = function lten (num) { + return this.cmpn(num) <= 0; + }; + BN.prototype.lte = function lte (num) { + return this.cmp(num) <= 0; + }; + BN.prototype.eqn = function eqn (num) { + return this.cmpn(num) === 0; + }; + BN.prototype.eq = function eq (num) { + return this.cmp(num) === 0; + }; + BN.red = function red (num) { + return new Red(num); + }; + BN.prototype.toRed = function toRed (ctx) { + assert(!this.red, 'Already a number in reduction context'); + assert(this.negative === 0, 'red works only with positives'); + return ctx.convertTo(this)._forceRed(ctx); + }; + BN.prototype.fromRed = function fromRed () { + assert(this.red, 'fromRed works only with numbers in reduction context'); + return this.red.convertFrom(this); + }; + BN.prototype._forceRed = function _forceRed (ctx) { + this.red = ctx; + return this; + }; + BN.prototype.forceRed = function forceRed (ctx) { + assert(!this.red, 'Already a number in reduction context'); + return this._forceRed(ctx); + }; + BN.prototype.redAdd = function redAdd (num) { + assert(this.red, 'redAdd works only with red numbers'); + return this.red.add(this, num); + }; + BN.prototype.redIAdd = function redIAdd (num) { + assert(this.red, 'redIAdd works only with red numbers'); + return this.red.iadd(this, num); + }; + BN.prototype.redSub = function redSub (num) { + assert(this.red, 'redSub works only with red numbers'); + return this.red.sub(this, num); + }; + BN.prototype.redISub = function redISub (num) { + assert(this.red, 'redISub works only with red numbers'); + return this.red.isub(this, num); + }; + BN.prototype.redShl = function redShl (num) { + assert(this.red, 'redShl works only with red numbers'); + return this.red.shl(this, num); + }; + BN.prototype.redMul = function redMul (num) { + assert(this.red, 'redMul works only with red numbers'); + this.red._verify2(this, num); + return this.red.mul(this, num); + }; + BN.prototype.redIMul = function redIMul (num) { + assert(this.red, 'redMul works only with red numbers'); + this.red._verify2(this, num); + return this.red.imul(this, num); + }; + BN.prototype.redSqr = function redSqr () { + assert(this.red, 'redSqr works only with red numbers'); + this.red._verify1(this); + return this.red.sqr(this); + }; + BN.prototype.redISqr = function redISqr () { + assert(this.red, 'redISqr works only with red numbers'); + this.red._verify1(this); + return this.red.isqr(this); + }; + BN.prototype.redSqrt = function redSqrt () { + assert(this.red, 'redSqrt works only with red numbers'); + this.red._verify1(this); + return this.red.sqrt(this); + }; + BN.prototype.redInvm = function redInvm () { + assert(this.red, 'redInvm works only with red numbers'); + this.red._verify1(this); + return this.red.invm(this); + }; + BN.prototype.redNeg = function redNeg () { + assert(this.red, 'redNeg works only with red numbers'); + this.red._verify1(this); + return this.red.neg(this); + }; + BN.prototype.redPow = function redPow (num) { + assert(this.red && !num.red, 'redPow(normalNum)'); + this.red._verify1(this); + return this.red.pow(this, num); + }; + var primes = { + k256: null, + p224: null, + p192: null, + p25519: null + }; + function MPrime (name, p) { + this.name = name; + this.p = new BN(p, 16); + this.n = this.p.bitLength(); + this.k = new BN(1).iushln(this.n).isub(this.p); + this.tmp = this._tmp(); + } + MPrime.prototype._tmp = function _tmp () { + var tmp = new BN(null); + tmp.words = new Array(Math.ceil(this.n / 13)); + return tmp; + }; + MPrime.prototype.ireduce = function ireduce (num) { + var r = num; + var rlen; + do { + this.split(r, this.tmp); + r = this.imulK(r); + r = r.iadd(this.tmp); + rlen = r.bitLength(); + } while (rlen > this.n); + var cmp = rlen < this.n ? -1 : r.ucmp(this.p); + if (cmp === 0) { + r.words[0] = 0; + r.length = 1; + } else if (cmp > 0) { + r.isub(this.p); + } else { + if (r.strip !== undefined) { + r.strip(); + } else { + r._strip(); + } + } + return r; + }; + MPrime.prototype.split = function split (input, out) { + input.iushrn(this.n, 0, out); + }; + MPrime.prototype.imulK = function imulK (num) { + return num.imul(this.k); + }; + function K256 () { + MPrime.call( + this, + 'k256', + 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f'); + } + inherits(K256, MPrime); + K256.prototype.split = function split (input, output) { + var mask = 0x3fffff; + var outLen = Math.min(input.length, 9); + for (var i = 0; i < outLen; i++) { + output.words[i] = input.words[i]; + } + output.length = outLen; + if (input.length <= 9) { + input.words[0] = 0; + input.length = 1; + return; + } + var prev = input.words[9]; + output.words[output.length++] = prev & mask; + for (i = 10; i < input.length; i++) { + var next = input.words[i] | 0; + input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22); + prev = next; + } + prev >>>= 22; + input.words[i - 10] = prev; + if (prev === 0 && input.length > 10) { + input.length -= 10; + } else { + input.length -= 9; + } + }; + K256.prototype.imulK = function imulK (num) { + num.words[num.length] = 0; + num.words[num.length + 1] = 0; + num.length += 2; + var lo = 0; + for (var i = 0; i < num.length; i++) { + var w = num.words[i] | 0; + lo += w * 0x3d1; + num.words[i] = lo & 0x3ffffff; + lo = w * 0x40 + ((lo / 0x4000000) | 0); + } + if (num.words[num.length - 1] === 0) { + num.length--; + if (num.words[num.length - 1] === 0) { + num.length--; + } + } + return num; + }; + function P224 () { + MPrime.call( + this, + 'p224', + 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001'); + } + inherits(P224, MPrime); + function P192 () { + MPrime.call( + this, + 'p192', + 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff'); + } + inherits(P192, MPrime); + function P25519 () { + MPrime.call( + this, + '25519', + '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed'); + } + inherits(P25519, MPrime); + P25519.prototype.imulK = function imulK (num) { + var carry = 0; + for (var i = 0; i < num.length; i++) { + var hi = (num.words[i] | 0) * 0x13 + carry; + var lo = hi & 0x3ffffff; + hi >>>= 26; + num.words[i] = lo; + carry = hi; + } + if (carry !== 0) { + num.words[num.length++] = carry; + } + return num; + }; + BN._prime = function prime (name) { + if (primes[name]) return primes[name]; + var prime; + if (name === 'k256') { + prime = new K256(); + } else if (name === 'p224') { + prime = new P224(); + } else if (name === 'p192') { + prime = new P192(); + } else if (name === 'p25519') { + prime = new P25519(); + } else { + throw new Error('Unknown prime ' + name); + } + primes[name] = prime; + return prime; + }; + function Red (m) { + if (typeof m === 'string') { + var prime = BN._prime(m); + this.m = prime.p; + this.prime = prime; + } else { + assert(m.gtn(1), 'modulus must be greater than 1'); + this.m = m; + this.prime = null; + } + } + Red.prototype._verify1 = function _verify1 (a) { + assert(a.negative === 0, 'red works only with positives'); + assert(a.red, 'red works only with red numbers'); + }; + Red.prototype._verify2 = function _verify2 (a, b) { + assert((a.negative | b.negative) === 0, 'red works only with positives'); + assert(a.red && a.red === b.red, + 'red works only with red numbers'); + }; + Red.prototype.imod = function imod (a) { + if (this.prime) return this.prime.ireduce(a)._forceRed(this); + move(a, a.umod(this.m)._forceRed(this)); + return a; + }; + Red.prototype.neg = function neg (a) { + if (a.isZero()) { + return a.clone(); + } + return this.m.sub(a)._forceRed(this); + }; + Red.prototype.add = function add (a, b) { + this._verify2(a, b); + var res = a.add(b); + if (res.cmp(this.m) >= 0) { + res.isub(this.m); + } + return res._forceRed(this); + }; + Red.prototype.iadd = function iadd (a, b) { + this._verify2(a, b); + var res = a.iadd(b); + if (res.cmp(this.m) >= 0) { + res.isub(this.m); + } + return res; + }; + Red.prototype.sub = function sub (a, b) { + this._verify2(a, b); + var res = a.sub(b); + if (res.cmpn(0) < 0) { + res.iadd(this.m); + } + return res._forceRed(this); + }; + Red.prototype.isub = function isub (a, b) { + this._verify2(a, b); + var res = a.isub(b); + if (res.cmpn(0) < 0) { + res.iadd(this.m); + } + return res; + }; + Red.prototype.shl = function shl (a, num) { + this._verify1(a); + return this.imod(a.ushln(num)); + }; + Red.prototype.imul = function imul (a, b) { + this._verify2(a, b); + return this.imod(a.imul(b)); + }; + Red.prototype.mul = function mul (a, b) { + this._verify2(a, b); + return this.imod(a.mul(b)); + }; + Red.prototype.isqr = function isqr (a) { + return this.imul(a, a.clone()); + }; + Red.prototype.sqr = function sqr (a) { + return this.mul(a, a); + }; + Red.prototype.sqrt = function sqrt (a) { + if (a.isZero()) return a.clone(); + var mod3 = this.m.andln(3); + assert(mod3 % 2 === 1); + if (mod3 === 3) { + var pow = this.m.add(new BN(1)).iushrn(2); + return this.pow(a, pow); + } + var q = this.m.subn(1); + var s = 0; + while (!q.isZero() && q.andln(1) === 0) { + s++; + q.iushrn(1); + } + assert(!q.isZero()); + var one = new BN(1).toRed(this); + var nOne = one.redNeg(); + var lpow = this.m.subn(1).iushrn(1); + var z = this.m.bitLength(); + z = new BN(2 * z * z).toRed(this); + while (this.pow(z, lpow).cmp(nOne) !== 0) { + z.redIAdd(nOne); + } + var c = this.pow(z, q); + var r = this.pow(a, q.addn(1).iushrn(1)); + var t = this.pow(a, q); + var m = s; + while (t.cmp(one) !== 0) { + var tmp = t; + for (var i = 0; tmp.cmp(one) !== 0; i++) { + tmp = tmp.redSqr(); + } + assert(i < m); + var b = this.pow(c, new BN(1).iushln(m - i - 1)); + r = r.redMul(b); + c = b.redSqr(); + t = t.redMul(c); + m = i; + } + return r; + }; + Red.prototype.invm = function invm (a) { + var inv = a._invmp(this.m); + if (inv.negative !== 0) { + inv.negative = 0; + return this.imod(inv).redNeg(); + } else { + return this.imod(inv); + } + }; + Red.prototype.pow = function pow (a, num) { + if (num.isZero()) return new BN(1).toRed(this); + if (num.cmpn(1) === 0) return a.clone(); + var windowSize = 4; + var wnd = new Array(1 << windowSize); + wnd[0] = new BN(1).toRed(this); + wnd[1] = a; + for (var i = 2; i < wnd.length; i++) { + wnd[i] = this.mul(wnd[i - 1], a); + } + var res = wnd[0]; + var current = 0; + var currentLen = 0; + var start = num.bitLength() % 26; + if (start === 0) { + start = 26; + } + for (i = num.length - 1; i >= 0; i--) { + var word = num.words[i]; + for (var j = start - 1; j >= 0; j--) { + var bit = (word >> j) & 1; + if (res !== wnd[0]) { + res = this.sqr(res); + } + if (bit === 0 && current === 0) { + currentLen = 0; + continue; + } + current <<= 1; + current |= bit; + currentLen++; + if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue; + res = this.mul(res, wnd[current]); + currentLen = 0; + current = 0; + } + start = 26; + } + return res; + }; + Red.prototype.convertTo = function convertTo (num) { + var r = num.umod(this.m); + return r === num ? r.clone() : r; + }; + Red.prototype.convertFrom = function convertFrom (num) { + var res = num.clone(); + res.red = null; + return res; + }; + BN.mont = function mont (num) { + return new Mont(num); + }; + function Mont (m) { + Red.call(this, m); + this.shift = this.m.bitLength(); + if (this.shift % 26 !== 0) { + this.shift += 26 - (this.shift % 26); + } + this.r = new BN(1).iushln(this.shift); + this.r2 = this.imod(this.r.sqr()); + this.rinv = this.r._invmp(this.m); + this.minv = this.rinv.mul(this.r).isubn(1).div(this.m); + this.minv = this.minv.umod(this.r); + this.minv = this.r.sub(this.minv); + } + inherits(Mont, Red); + Mont.prototype.convertTo = function convertTo (num) { + return this.imod(num.ushln(this.shift)); + }; + Mont.prototype.convertFrom = function convertFrom (num) { + var r = this.imod(num.mul(this.rinv)); + r.red = null; + return r; + }; + Mont.prototype.imul = function imul (a, b) { + if (a.isZero() || b.isZero()) { + a.words[0] = 0; + a.length = 1; + return a; + } + var t = a.imul(b); + var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); + var u = t.isub(c).iushrn(this.shift); + var res = u; + if (u.cmp(this.m) >= 0) { + res = u.isub(this.m); + } else if (u.cmpn(0) < 0) { + res = u.iadd(this.m); + } + return res._forceRed(this); + }; + Mont.prototype.mul = function mul (a, b) { + if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this); + var t = a.mul(b); + var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); + var u = t.isub(c).iushrn(this.shift); + var res = u; + if (u.cmp(this.m) >= 0) { + res = u.isub(this.m); + } else if (u.cmpn(0) < 0) { + res = u.iadd(this.m); + } + return res._forceRed(this); + }; + Mont.prototype.invm = function invm (a) { + var res = this.imod(a._invmp(this.m).mul(this.r2)); + return res._forceRed(this); + }; + })(module, commonjsGlobal); + } (bn)); + var bnExports = bn.exports; + const BN = getDefaultExportFromCjs(bnExports); + + function isBn(value) { + return BN.isBN(value); + } + + const REGEX_HEX_PREFIXED = /^0x[\da-fA-F]+$/; + const REGEX_HEX_NOPREFIX = /^[\da-fA-F]+$/; + function isHex(value, bitLength = -1, ignoreLength) { + return (typeof value === 'string' && (value === '0x' || + REGEX_HEX_PREFIXED.test(value))) && (bitLength === -1 + ? (ignoreLength || (value.length % 2 === 0)) + : (value.length === (2 + Math.ceil(bitLength / 4)))); + } + + function isObject(value) { + return !!value && typeof value === 'object'; + } + + function isOn(...fns) { + return (value) => (isObject(value) || isFunction(value)) && + fns.every((f) => isFunction(value[f])); + } + function isOnFunction(...fns) { + return (value) => isFunction(value) && + fns.every((f) => isFunction(value[f])); + } + function isOnObject(...fns) { + return (value) => isObject(value) && + fns.every((f) => isFunction(value[f])); + } + + const isToBigInt = isOn('toBigInt'); + + const isToBn = isOn('toBn'); + + function nToBigInt(value) { + return typeof value === 'bigint' + ? value + : !value + ? BigInt(0) + : isHex(value) + ? hexToBigInt(value.toString()) + : isBn(value) + ? BigInt(value.toString()) + : isToBigInt(value) + ? value.toBigInt() + : isToBn(value) + ? BigInt(value.toBn().toString()) + : BigInt(value); + } + + function nSqrt(value) { + const n = nToBigInt(value); + if (n < _0n) { + throw new Error('square root of negative numbers is not supported'); + } + if (n <= _2pow53n) { + return BigInt(~~Math.sqrt(Number(n))); + } + let x0 = _sqrt2pow53n; + while (true) { + const x1 = ((n / x0) + x0) >> _1n; + if (x0 === x1 || (x0 === (x1 - _1n))) { + return x0; + } + x0 = x1; + } + } + + const hasBigInt = typeof BigInt === 'function' && typeof BigInt.asIntN === 'function'; + const hasCjs = typeof require === 'function' && typeof module !== 'undefined'; + const hasDirname = typeof __dirname !== 'undefined'; + const hasEsm = !hasCjs; + const hasWasm = typeof WebAssembly !== 'undefined'; + const hasBuffer = typeof xglobal.Buffer === 'function' && typeof xglobal.Buffer.isBuffer === 'function'; + const hasProcess = typeof xglobal.process === 'object'; + + function isBuffer(value) { + return hasBuffer && !!value && isFunction(value.readDoubleLE) && xglobal.Buffer.isBuffer(value); + } + + function isU8a(value) { + return (((value && value.constructor) === Uint8Array) || + value instanceof Uint8Array); + } + + var browser$1 = {}; + + const require$$0 = /*@__PURE__*/getAugmentedNamespace(build); + + var fallback$1 = {}; + + Object.defineProperty(fallback$1, "__esModule", { value: true }); + fallback$1.TextEncoder = void 0; + class TextEncoder { + encode(value) { + const count = value.length; + const u8a = new Uint8Array(count); + for (let i = 0; i < count; i++) { + u8a[i] = value.charCodeAt(i); + } + return u8a; + } + } + fallback$1.TextEncoder = TextEncoder; + + var packageInfo$1 = {}; + + Object.defineProperty(packageInfo$1, "__esModule", { value: true }); + packageInfo$1.packageInfo = void 0; + packageInfo$1.packageInfo = { name: '@pezkuwi/x-textencoder', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; + + (function (exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.TextEncoder = exports$1.packageInfo = void 0; + const x_global_1 = require$$0; + const fallback_js_1 = fallback$1; + var packageInfo_js_1 = packageInfo$1; + Object.defineProperty(exports$1, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); + exports$1.TextEncoder = (0, x_global_1.extractGlobal)('TextEncoder', fallback_js_1.TextEncoder); + } (browser$1)); + getDefaultExportFromCjs(browser$1); + + const encoder = new browser$1.TextEncoder(); + function stringToU8a(value) { + return value + ? encoder.encode(value.toString()) + : new Uint8Array(); + } + + function u8aToU8a(value, strict = false) { + if (strict && (value === null || value === undefined)) { + throw new Error('u8aToU8a: Expected non-null, non-undefined value'); + } + return isU8a(value) + ? isBuffer(value) + ? new Uint8Array(value) + : value + : isHex(value) + ? hexToU8a(value) + : Array.isArray(value) + ? new Uint8Array(value) + : stringToU8a(value); + } + + function u8aCmp(a, b) { + const u8aa = u8aToU8a(a); + const u8ab = u8aToU8a(b); + let i = 0; + while (true) { + const overA = i >= u8aa.length; + const overB = i >= u8ab.length; + if (overA && overB) { + return 0; + } + else if (overA) { + return -1; + } + else if (overB) { + return 1; + } + else if (u8aa[i] !== u8ab[i]) { + return u8aa[i] > u8ab[i] + ? 1 + : -1; + } + i++; + } + } + + function u8aConcat(...list) { + const count = list.length; + const u8as = new Array(count); + let length = 0; + for (let i = 0; i < count; i++) { + u8as[i] = u8aToU8a(list[i]); + length += u8as[i].length; + } + return u8aConcatStrict(u8as, length); + } + function u8aConcatStrict(u8as, length = 0) { + const count = u8as.length; + let offset = 0; + if (!length) { + for (let i = 0; i < count; i++) { + length += u8as[i].length; + } + } + const result = new Uint8Array(length); + for (let i = 0; i < count; i++) { + result.set(u8as[i], offset); + offset += u8as[i].length; + } + return result; + } + + function u8aEmpty(value) { + const len = value.length | 0; + for (let i = 0; i < len; i++) { + if (value[i] | 0) { + return false; + } + } + return true; + } + + function u8aEq(a, b) { + const u8aa = u8aToU8a(a); + const u8ab = u8aToU8a(b); + if (u8aa.length === u8ab.length) { + const dvA = new DataView(u8aa.buffer, u8aa.byteOffset); + const dvB = new DataView(u8ab.buffer, u8ab.byteOffset); + const mod = (u8aa.length % 4) | 0; + const length = (u8aa.length - mod) | 0; + for (let i = 0; i < length; i += 4) { + if (dvA.getUint32(i) !== dvB.getUint32(i)) { + return false; + } + } + for (let i = length, count = u8aa.length; i < count; i++) { + if (u8aa[i] !== u8ab[i]) { + return false; + } + } + return true; + } + return false; + } + + function u8aFixLength(value, bitLength = -1, atStart = false) { + const byteLength = Math.ceil(bitLength / 8); + if (bitLength === -1 || value.length === byteLength) { + return value; + } + else if (value.length > byteLength) { + return value.subarray(0, byteLength); + } + const result = new Uint8Array(byteLength); + result.set(value, atStart ? 0 : (byteLength - value.length)); + return result; + } + + function u8aSorted(u8as) { + return u8as.sort(u8aCmp); + } + + function u8aToBn(value, { isLe = true, isNegative = false } = {}) { + if (!isLe) { + value = value.slice().reverse(); + } + const count = value.length; + if (isNegative && count && (value[count - 1] & 0x80)) { + switch (count) { + case 0: + return new BN(0); + case 1: + return new BN(((value[0] ^ 0x0000_00ff) * -1) - 1); + case 2: + return new BN((((value[0] + (value[1] << 8)) ^ 0x0000_ffff) * -1) - 1); + case 3: + return new BN((((value[0] + (value[1] << 8) + (value[2] << 16)) ^ 0x00ff_ffff) * -1) - 1); + case 4: + return new BN((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) * -1) - 1); + case 5: + return new BN(((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) + ((value[4] ^ 0xff) * 0x1_00_00_00_00)) * -1) - 1); + case 6: + return new BN(((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) + (((value[4] + (value[5] << 8)) ^ 0x0000_ffff) * 0x1_00_00_00_00)) * -1) - 1); + default: + return new BN(value, 'le').fromTwos(count * 8); + } + } + switch (count) { + case 0: + return new BN(0); + case 1: + return new BN(value[0]); + case 2: + return new BN(value[0] + (value[1] << 8)); + case 3: + return new BN(value[0] + (value[1] << 8) + (value[2] << 16)); + case 4: + return new BN(value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)); + case 5: + return new BN(value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8)) * 0x1_00_00_00)); + case 6: + return new BN(value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8) + (value[5] << 16)) * 0x1_00_00_00)); + default: + return new BN(value, 'le'); + } + } + + function u8aToBuffer(value) { + return hasBuffer + ? xglobal.Buffer.from(value || []) + : new Uint8Array(value || []); + } + + function u8aToFloat(value, { bitLength = 32, isLe = true } = {}) { + if (bitLength !== 32 && bitLength !== 64) { + throw new Error('Invalid bitLength provided, expected 32 or 64'); + } + else if (value.length < (bitLength / 8)) { + throw new Error(`Invalid input buffer provided, expected at least ${bitLength / 8} bytes, found ${value.length}`); + } + const dv = new DataView(value.buffer, value.byteOffset); + return bitLength === 32 + ? dv.getFloat32(0, isLe) + : dv.getFloat64(0, isLe); + } + + const U8 = new Array(256); + const U16 = new Array(256 * 256); + for (let n = 0; n < 256; n++) { + U8[n] = n.toString(16).padStart(2, '0'); + } + for (let i = 0; i < 256; i++) { + const s = i << 8; + for (let j = 0; j < 256; j++) { + U16[s | j] = U8[i] + U8[j]; + } + } + function hex(value, result) { + const mod = (value.length % 2) | 0; + const length = (value.length - mod) | 0; + for (let i = 0; i < length; i += 2) { + result += U16[(value[i] << 8) | value[i + 1]]; + } + if (mod) { + result += U8[value[length] | 0]; + } + return result; + } + function u8aToHex(value, bitLength = -1, isPrefixed = true) { + const empty = isPrefixed + ? '0x' + : ''; + if (!value?.length) { + return empty; + } + else if (bitLength > 0) { + const length = Math.ceil(bitLength / 8); + if (value.length > length) { + return `${hex(value.subarray(0, length / 2), empty)}…${hex(value.subarray(value.length - length / 2), '')}`; + } + } + return hex(value, empty); + } + + function u8aToNumber(value, { isLe = true, isNegative = false } = {}) { + if (!isLe) { + value = value.slice().reverse(); + } + const count = value.length; + if (isNegative && count && (value[count - 1] & 0x80)) { + switch (count) { + case 0: + return 0; + case 1: + return (((value[0] ^ 0x0000_00ff) * -1) - 1); + case 2: + return ((((value[0] + (value[1] << 8)) ^ 0x0000_ffff) * -1) - 1); + case 3: + return ((((value[0] + (value[1] << 8) + (value[2] << 16)) ^ 0x00ff_ffff) * -1) - 1); + case 4: + return ((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) * -1) - 1); + case 5: + return (((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) + ((value[4] ^ 0xff) * 0x1_00_00_00_00)) * -1) - 1); + case 6: + return (((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) + (((value[4] + (value[5] << 8)) ^ 0x0000_ffff) * 0x1_00_00_00_00)) * -1) - 1); + default: + throw new Error('Value more than 48-bits cannot be reliably converted'); + } + } + switch (count) { + case 0: + return 0; + case 1: + return value[0]; + case 2: + return value[0] + (value[1] << 8); + case 3: + return value[0] + (value[1] << 8) + (value[2] << 16); + case 4: + return value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00); + case 5: + return value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8)) * 0x1_00_00_00); + case 6: + return value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8) + (value[5] << 16)) * 0x1_00_00_00); + default: + throw new Error('Value more than 48-bits cannot be reliably converted'); + } + } + + var browser = {}; + + var fallback = {}; + + Object.defineProperty(fallback, "__esModule", { value: true }); + fallback.TextDecoder = void 0; + class TextDecoder { + __encoding; + constructor(encoding) { + this.__encoding = encoding; + } + decode(value) { + let result = ''; + for (let i = 0, count = value.length; i < count; i++) { + result += String.fromCharCode(value[i]); + } + return result; + } + } + fallback.TextDecoder = TextDecoder; + + var packageInfo = {}; + + Object.defineProperty(packageInfo, "__esModule", { value: true }); + packageInfo.packageInfo = void 0; + packageInfo.packageInfo = { name: '@pezkuwi/x-textdecoder', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; + + (function (exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.TextDecoder = exports$1.packageInfo = void 0; + const x_global_1 = require$$0; + const fallback_js_1 = fallback; + var packageInfo_js_1 = packageInfo; + Object.defineProperty(exports$1, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); + exports$1.TextDecoder = (0, x_global_1.extractGlobal)('TextDecoder', fallback_js_1.TextDecoder); + } (browser)); + getDefaultExportFromCjs(browser); + + const decoder = new browser.TextDecoder('utf-8'); + function u8aToString(value) { + return value + ? decoder.decode(value) + : ''; + } + + const U8A_WRAP_ETHEREUM = u8aToU8a('\x19Ethereum Signed Message:\n'); + const U8A_WRAP_PREFIX = u8aToU8a(''); + const U8A_WRAP_POSTFIX = u8aToU8a(''); + const WRAP_LEN = U8A_WRAP_PREFIX.length + U8A_WRAP_POSTFIX.length; + function u8aIsWrapped(u8a, withEthereum) { + return ((u8a.length >= WRAP_LEN && + u8aEq(u8a.subarray(0, U8A_WRAP_PREFIX.length), U8A_WRAP_PREFIX) && + u8aEq(u8a.slice(-U8A_WRAP_POSTFIX.length), U8A_WRAP_POSTFIX)) || + (withEthereum && + u8a.length >= U8A_WRAP_ETHEREUM.length && + u8aEq(u8a.subarray(0, U8A_WRAP_ETHEREUM.length), U8A_WRAP_ETHEREUM))); + } + function u8aUnwrapBytes(bytes) { + const u8a = u8aToU8a(bytes); + return u8aIsWrapped(u8a, false) + ? u8a.subarray(U8A_WRAP_PREFIX.length, u8a.length - U8A_WRAP_POSTFIX.length) + : u8a; + } + function u8aWrapBytes(bytes) { + const u8a = u8aToU8a(bytes); + return u8aIsWrapped(u8a, true) + ? u8a + : u8aConcatStrict([U8A_WRAP_PREFIX, u8a, U8A_WRAP_POSTFIX]); + } + + const DIV = BigInt(256); + const NEG_MASK = BigInt(0xff); + function toU8a(value, isLe, isNegative) { + const arr = []; + const withSigned = isNegative && (value < _0n); + if (withSigned) { + value = (value + _1n) * -_1n; + } + while (value !== _0n) { + const mod = value % DIV; + const val = Number(withSigned + ? mod ^ NEG_MASK + : mod); + if (isLe) { + arr.push(val); + } + else { + arr.unshift(val); + } + value = (value - mod) / DIV; + } + return Uint8Array.from(arr); + } + function nToU8a(value, { bitLength = -1, isLe = true, isNegative = false } = {}) { + const valueBi = nToBigInt(value); + if (valueBi === _0n) { + return bitLength === -1 + ? new Uint8Array(1) + : new Uint8Array(Math.ceil((bitLength || 0) / 8)); + } + const u8a = toU8a(valueBi, isLe, isNegative); + if (bitLength === -1) { + return u8a; + } + const byteLength = Math.ceil((bitLength || 0) / 8); + const output = new Uint8Array(byteLength); + if (isNegative) { + output.fill(0xff); + } + output.set(u8a, isLe ? 0 : byteLength - u8a.length); + return output; + } + + function nToHex(value, { bitLength = -1, isLe = false, isNegative = false } = {}) { + return u8aToHex(nToU8a(value || 0, { bitLength, isLe, isNegative })); + } + + function hexStripPrefix(value) { + if (!value || value === '0x') { + return ''; + } + else if (REGEX_HEX_PREFIXED.test(value)) { + return value.substring(2); + } + else if (REGEX_HEX_NOPREFIX.test(value)) { + return value; + } + throw new Error(`Expected hex value to convert, found '${value}'`); + } + + function hexToBn(value, { isLe = false, isNegative = false } = {}) { + if (!value || value === '0x') { + return new BN(0); + } + const stripped = hexStripPrefix(value); + const bn = new BN(stripped, 16, isLe ? 'le' : 'be'); + return isNegative + ? bn.fromTwos(stripped.length * 4) + : bn; + } + + const bnMax = createCmp((a, b) => a.gt(b)); + const bnMin = createCmp((a, b) => a.lt(b)); + + const BN_ZERO = new BN(0); + const BN_ONE = new BN(1); + const BN_TWO = new BN(2); + const BN_THREE = new BN(3); + const BN_FOUR = new BN(4); + const BN_FIVE = new BN(5); + const BN_SIX = new BN(6); + const BN_SEVEN = new BN(7); + const BN_EIGHT = new BN(8); + const BN_NINE = new BN(9); + const BN_TEN = new BN(10); + const BN_HUNDRED = new BN(100); + const BN_THOUSAND = new BN(1_000); + const BN_MILLION = new BN(1_000_000); + const BN_BILLION = new BN(1_000_000_000); + const BN_QUINTILL = BN_BILLION.mul(BN_BILLION); + const BN_MAX_INTEGER = new BN(Number.MAX_SAFE_INTEGER); + const BN_SQRT_MAX_INTEGER = new BN(94906265); + + function isBigInt(value) { + return typeof value === 'bigint'; + } + + function bnToBn(value) { + return value + ? BN.isBN(value) + ? value + : isHex(value) + ? hexToBn(value.toString()) + : isBigInt(value) + ? new BN(value.toString()) + : isToBn(value) + ? value.toBn() + : isToBigInt(value) + ? new BN(value.toBigInt().toString()) + : new BN(value) + : new BN(0); + } + + function bnSqrt(value) { + const n = bnToBn(value); + if (n.isNeg()) { + throw new Error('square root of negative numbers is not supported'); + } + if (n.lte(BN_MAX_INTEGER)) { + return new BN(~~Math.sqrt(n.toNumber())); + } + let x0 = BN_SQRT_MAX_INTEGER.clone(); + while (true) { + const x1 = n.div(x0).iadd(x0).ishrn(1); + if (x0.eq(x1) || x0.eq(x1.sub(BN_ONE))) { + return x0; + } + x0 = x1; + } + } + + const DEFAULT_OPTS = { bitLength: -1, isLe: true, isNegative: false }; + function bnToU8a(value, { bitLength = -1, isLe = true, isNegative = false } = DEFAULT_OPTS) { + const valueBn = bnToBn(value); + const byteLength = bitLength === -1 + ? Math.ceil(valueBn.bitLength() / 8) + : Math.ceil((bitLength || 0) / 8); + if (!value) { + return bitLength === -1 + ? new Uint8Array(1) + : new Uint8Array(byteLength); + } + const output = new Uint8Array(byteLength); + const bn = isNegative + ? valueBn.toTwos(byteLength * 8) + : valueBn; + output.set(bn.toArray(isLe ? 'le' : 'be', byteLength), 0); + return output; + } + + function bnToHex(value, { bitLength = -1, isLe = false, isNegative = false } = {}) { + return u8aToHex(bnToU8a(value, { bitLength, isLe, isNegative })); + } + + function bufferToU8a(buffer) { + return new Uint8Array(buffer || []); + } + + const MAX_U8 = BN_TWO.pow(new BN(8 - 2)).isub(BN_ONE); + const MAX_U16 = BN_TWO.pow(new BN(16 - 2)).isub(BN_ONE); + const MAX_U32 = BN_TWO.pow(new BN(32 - 2)).isub(BN_ONE); + const BL_16 = { bitLength: 16 }; + const BL_32 = { bitLength: 32 }; + function compactToU8a(value) { + const bn = bnToBn(value); + if (bn.lte(MAX_U8)) { + return new Uint8Array([bn.toNumber() << 2]); + } + else if (bn.lte(MAX_U16)) { + return bnToU8a(bn.shln(2).iadd(BN_ONE), BL_16); + } + else if (bn.lte(MAX_U32)) { + return bnToU8a(bn.shln(2).iadd(BN_TWO), BL_32); + } + const u8a = bnToU8a(bn); + let length = u8a.length; + while (u8a[length - 1] === 0) { + length--; + } + if (length < 4) { + throw new Error('Invalid length, previous checks match anything less than 2^30'); + } + return u8aConcatStrict([ + new Uint8Array([((length - 4) << 2) + 0b11]), + u8a.subarray(0, length) + ]); + } + + function compactAddLength(input) { + return u8aConcatStrict([ + compactToU8a(input.length), + input + ]); + } + + function compactFromU8a(input) { + const u8a = u8aToU8a(input); + switch (u8a[0] & 0b11) { + case 0b00: + return [1, new BN(u8a[0] >>> 2)]; + case 0b01: + return [2, new BN((u8a[0] + (u8a[1] << 8)) >>> 2)]; + case 0b10: + return [4, new BN((u8a[0] + (u8a[1] << 8) + (u8a[2] << 16) + (u8a[3] * 0x1_00_00_00)) >>> 2)]; + default: { + const offset = (u8a[0] >>> 2) + 5; + switch (offset) { + case 5: + return [5, new BN(u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + (u8a[4] * 0x1_00_00_00))]; + case 6: + return [6, new BN(u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + ((u8a[4] + (u8a[5] << 8)) * 0x1_00_00_00))]; + case 7: + return [7, new BN(u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + ((u8a[4] + (u8a[5] << 8) + (u8a[6] << 16)) * 0x1_00_00_00))]; + default: + return [offset, u8aToBn(u8a.subarray(1, offset))]; + } + } + } + } + function compactFromU8aLim(u8a) { + switch (u8a[0] & 0b11) { + case 0b00: + return [1, u8a[0] >>> 2]; + case 0b01: + return [2, (u8a[0] + (u8a[1] << 8)) >>> 2]; + case 0b10: + return [4, (u8a[0] + (u8a[1] << 8) + (u8a[2] << 16) + (u8a[3] * 0x1_00_00_00)) >>> 2]; + default: { + switch ((u8a[0] >>> 2) + 5) { + case 5: + return [5, u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + (u8a[4] * 0x1_00_00_00)]; + case 6: + return [6, u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + ((u8a[4] + (u8a[5] << 8)) * 0x1_00_00_00)]; + case 7: + return [7, u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + ((u8a[4] + (u8a[5] << 8) + (u8a[6] << 16)) * 0x1_00_00_00)]; + default: + throw new Error('Compact input is > Number.MAX_SAFE_INTEGER'); + } + } + } + } + + function compactStripLength(input) { + const [offset, length] = compactFromU8a(input); + const total = offset + length.toNumber(); + return [ + total, + input.subarray(offset, total) + ]; + } + + const DEDUPE = 'Either remove and explicitly install matching versions or dedupe using your package manager.\nThe following conflicting packages were found:'; + const POLKADOTJS_DISABLE_ESM_CJS_WARNING_FLAG = 'POLKADOTJS_DISABLE_ESM_CJS_WARNING'; + function getEntry(name) { + const _global = xglobal; + if (!_global.__polkadotjs) { + _global.__polkadotjs = {}; + } + if (!_global.__polkadotjs[name]) { + _global.__polkadotjs[name] = []; + } + return _global.__polkadotjs[name]; + } + function formatDisplay(all, fmt) { + let max = 0; + for (let i = 0, count = all.length; i < count; i++) { + max = Math.max(max, all[i].version.length); + } + return all + .map((d) => `\t${fmt(d.version.padEnd(max), d).join('\t')}`) + .join('\n'); + } + function formatInfo(version, { name }) { + return [ + version, + name + ]; + } + function formatVersion(version, { path, type }) { + let extracted; + if (path && path.length >= 5) { + const nmIndex = path.indexOf('node_modules'); + extracted = nmIndex === -1 + ? path + : path.substring(nmIndex); + } + else { + extracted = ''; + } + return [ + `${`${type || ''}`.padStart(3)} ${version}`, + extracted + ]; + } + function getPath(infoPath, pathOrFn) { + if (infoPath) { + return infoPath; + } + else if (isFunction(pathOrFn)) { + try { + return pathOrFn() || ''; + } + catch { + return ''; + } + } + return pathOrFn || ''; + } + function warn(pre, all, fmt) { + console.warn(`${pre}\n${DEDUPE}\n${formatDisplay(all, fmt)}`); + } + function detectPackage({ name, path, type, version }, pathOrFn, deps = []) { + if (!name.startsWith('@pezkuwi')) { + throw new Error(`Invalid package descriptor ${name}`); + } + const entry = getEntry(name); + entry.push({ path: getPath(path, pathOrFn), type, version }); + const entriesSameVersion = entry.every((e) => e.version === version); + const esmCjsWarningDisabled = xglobal.process?.env?.[POLKADOTJS_DISABLE_ESM_CJS_WARNING_FLAG] === '1'; + const multipleEntries = entry.length !== 1; + const disableWarnings = esmCjsWarningDisabled && entriesSameVersion; + if (multipleEntries && !disableWarnings) { + warn(`${name} has multiple versions, ensure that there is only one installed.`, entry, formatVersion); + } + else { + const mismatches = deps.filter((d) => d && d.version !== version); + if (mismatches.length) { + warn(`${name} requires direct dependencies exactly matching version ${version}.`, mismatches, formatInfo); + } + } + } + + const MIN_MS = 60 * 1000; + const HR_MS = MIN_MS * 60; + const DAY_MS = HR_MS * 24; + const ZERO = { days: 0, hours: 0, milliseconds: 0, minutes: 0, seconds: 0 }; + function add(a, b) { + return { + days: (a.days || 0) + b.days, + hours: (a.hours || 0) + b.hours, + milliseconds: (a.milliseconds || 0) + b.milliseconds, + minutes: (a.minutes || 0) + b.minutes, + seconds: (a.seconds || 0) + b.seconds + }; + } + function extractSecs(ms) { + const s = ms / 1000; + if (s < 60) { + const seconds = ~~s; + return add({ seconds }, extractTime(ms - (seconds * 1000))); + } + const m = s / 60; + if (m < 60) { + const minutes = ~~m; + return add({ minutes }, extractTime(ms - (minutes * MIN_MS))); + } + const h = m / 60; + if (h < 24) { + const hours = ~~h; + return add({ hours }, extractTime(ms - (hours * HR_MS))); + } + const days = ~~(h / 24); + return add({ days }, extractTime(ms - (days * DAY_MS))); + } + function extractTime(milliseconds) { + return !milliseconds + ? ZERO + : milliseconds < 1000 + ? add({ milliseconds }, ZERO) + : extractSecs(milliseconds); + } + + function floatToU8a(value = 0.0, { bitLength = 32, isLe = true } = {}) { + if (bitLength !== 32 && bitLength !== 64) { + throw new Error('Invalid bitLength provided, expected 32 or 64'); + } + const result = new Uint8Array(bitLength / 8); + const dv = new DataView(result.buffer, result.byteOffset); + if (bitLength === 32) { + dv.setFloat32(0, Number(value), isLe); + } + else { + dv.setFloat64(0, Number(value), isLe); + } + return result; + } + + function isBoolean(value) { + return typeof value === 'boolean'; + } + + const NUMBER_REGEX = new RegExp('(\\d+?)(?=(\\d{3})+(?!\\d)|$)', 'g'); + function formatDecimal(value, separator = ',') { + const isNegative = value[0].startsWith('-'); + const matched = isNegative + ? value.substring(1).match(NUMBER_REGEX) + : value.match(NUMBER_REGEX); + return matched + ? `${isNegative ? '-' : ''}${matched.join(separator)}` + : value; + } + + function getSeparator(locale) { + return { + decimal: (0.1).toLocaleString(locale, { useGrouping: false }).charAt(1), + thousand: (1000).toLocaleString(locale, { useGrouping: true }).replace(/\d/g, '').charAt(0) + }; + } + + const SI_MID = 8; + const SI = [ + { power: -24, text: 'yocto', value: 'y' }, + { power: -21, text: 'zepto', value: 'z' }, + { power: -18, text: 'atto', value: 'a' }, + { power: -15, text: 'femto', value: 'f' }, + { power: -12, text: 'pico', value: 'p' }, + { power: -9, text: 'nano', value: 'n' }, + { power: -6, text: 'micro', value: 'µ' }, + { power: -3, text: 'milli', value: 'm' }, + { power: 0, text: 'Unit', value: '-' }, + { power: 3, text: 'Kilo', value: 'k' }, + { power: 6, text: 'Mill', value: 'M' }, + { power: 9, text: 'Bill', value: 'B' }, + { power: 12, text: 'Tril', value: 'T' }, + { power: 15, text: 'Peta', value: 'P' }, + { power: 18, text: 'Exa', value: 'E' }, + { power: 21, text: 'Zeta', value: 'Z' }, + { power: 24, text: 'Yotta', value: 'Y' } + ]; + function findSi(type) { + for (let i = 0, count = SI.length; i < count; i++) { + if (SI[i].value === type) { + return SI[i]; + } + } + return SI[SI_MID]; + } + function calcSi(text, decimals, forceUnit) { + if (forceUnit) { + return findSi(forceUnit); + } + const siDefIndex = (SI_MID - 1) + Math.ceil((text.length - decimals) / 3); + return SI[siDefIndex] || SI[siDefIndex < 0 ? 0 : SI.length - 1]; + } + + const DEFAULT_DECIMALS = 0; + const DEFAULT_UNIT = SI[SI_MID].text; + let defaultDecimals = DEFAULT_DECIMALS; + let defaultUnit = DEFAULT_UNIT; + function _formatBalance(input, { decimals = defaultDecimals, forceUnit, locale = 'en', withAll = false, withSi = true, withSiFull = false, withUnit = true, withZero = true } = {}) { + let text = bnToBn(input).toString(); + if (text.length === 0 || text === '0') { + return '0'; + } + let sign = ''; + if (text[0].startsWith('-')) { + sign = '-'; + text = text.substring(1); + } + const si = calcSi(text, decimals, forceUnit); + const mid = text.length - (decimals + si.power); + const pre = mid <= 0 ? '0' : text.substring(0, mid); + let post = text + .padStart(mid < 0 ? decimals : 1, '0') + .substring(mid < 0 ? 0 : mid) + .padEnd(withAll ? Math.max(decimals, 4) : 4, '0') + .substring(0, withAll ? Math.max(4, decimals + si.power) : 4); + if (!withZero) { + let end = post.length - 1; + do { + if (post[end] === '0') { + end--; + } + } while (post[end] === '0'); + post = post.substring(0, end + 1); + } + const unit = isBoolean(withUnit) + ? SI[SI_MID].text + : withUnit; + const units = withSi || withSiFull + ? si.value === '-' + ? withUnit + ? ` ${unit}` + : '' + : ` ${withSiFull ? `${si.text}${withUnit ? ' ' : ''}` : si.value}${withUnit ? unit : ''}` + : ''; + const { decimal, thousand } = getSeparator(locale); + return `${sign}${formatDecimal(pre, thousand)}${post && `${decimal}${post}`}${units}`; + } + const formatBalance = _formatBalance; + formatBalance.calcSi = (text, decimals = defaultDecimals) => calcSi(text, decimals); + formatBalance.findSi = findSi; + formatBalance.getDefaults = () => { + return { + decimals: defaultDecimals, + unit: defaultUnit + }; + }; + formatBalance.getOptions = (decimals = defaultDecimals) => { + return SI.filter(({ power }) => power < 0 + ? (decimals + power) >= 0 + : true); + }; + formatBalance.setDefaults = ({ decimals, unit }) => { + defaultDecimals = (Array.isArray(decimals) + ? decimals[0] + : decimals) ?? defaultDecimals; + defaultUnit = (Array.isArray(unit) + ? unit[0] + : unit) ?? defaultUnit; + SI[SI_MID].text = defaultUnit; + }; + + function zeroPad(value) { + return value.toString().padStart(2, '0'); + } + function formatDate(date) { + const year = date.getFullYear().toString(); + const month = zeroPad((date.getMonth() + 1)); + const day = zeroPad(date.getDate()); + const hour = zeroPad(date.getHours()); + const minute = zeroPad(date.getMinutes()); + const second = zeroPad(date.getSeconds()); + return `${year}-${month}-${day} ${hour}:${minute}:${second}`; + } + + function formatValue(elapsed) { + if (elapsed < 15) { + return `${elapsed.toFixed(1)}s`; + } + else if (elapsed < 60) { + return `${elapsed | 0}s`; + } + else if (elapsed < 3600) { + return `${elapsed / 60 | 0}m`; + } + return `${elapsed / 3600 | 0}h`; + } + function formatElapsed(now, value) { + const tsNow = now?.getTime() || 0; + const tsValue = value instanceof Date + ? value.getTime() + : bnToBn(value).toNumber(); + return (tsNow && tsValue) + ? formatValue(Math.max(Math.abs(tsNow - tsValue), 0) / 1000) + : '0.0s'; + } + + function formatNumber(value, { locale = 'en' } = {}) { + const { thousand } = getSeparator(locale); + return formatDecimal(bnToBn(value).toString(), thousand); + } + + function hexHasPrefix(value) { + return !!value && isHex(value, -1); + } + + function hexAddPrefix(value) { + return value && hexHasPrefix(value) + ? value + : `0x${value && value.length % 2 === 1 ? '0' : ''}${value || ''}`; + } + + function hexFixLength(value, bitLength = -1, withPadding = false) { + const strLength = Math.ceil(bitLength / 4); + const hexLength = strLength + 2; + return hexAddPrefix((bitLength === -1 || value.length === hexLength || (!withPadding && value.length < hexLength)) + ? hexStripPrefix(value) + : (value.length > hexLength) + ? hexStripPrefix(value).slice(-1 * strLength) + : `${'0'.repeat(strLength)}${hexStripPrefix(value)}`.slice(-1 * strLength)); + } + + function hexToNumber(value) { + return value + ? hexToBn(value).toNumber() + : NaN; + } + + function hexToString(_value) { + return u8aToString(hexToU8a(_value)); + } + + function isArray(value) { + return Array.isArray(value); + } + + function isString(value) { + return typeof value === 'string' || value instanceof String; + } + + function isAsciiStr(str) { + for (let i = 0, count = str.length; i < count; i++) { + const b = str.charCodeAt(i); + if (b < 32 || b > 126) { + return false; + } + } + return true; + } + function isAsciiBytes(u8a) { + for (let i = 0, count = u8a.length; i < count; i++) { + const b = u8a[i] | 0; + if (b < 32 || b > 126) { + return false; + } + } + return true; + } + function isAscii(value) { + return isString(value) + ? isHex(value) + ? isAsciiBytes(u8aToU8a(value)) + : isAsciiStr(value) + : value + ? isAsciiBytes(value) + : false; + } + + const isClass = isOnFunction('isPrototypeOf', 'hasOwnProperty'); + + function isChildClass(Parent, Child) { + return isClass(Child) && isClass(Parent) + ? Parent === Child || Parent.isPrototypeOf(Child) + : false; + } + + const checkCodec = isOnObject('toHex', 'toHuman', 'toU8a'); + const checkRegistry = isOnObject('get'); + function isCodec(value) { + return checkCodec(value) && checkRegistry(value.registry); + } + + const isCompact = isOnObject('toBigInt', 'toBn', 'toNumber', 'unwrap'); + + function isError(value) { + return (((value && value.constructor) === Error) || + value instanceof Error); + } + + function isInstanceOf(value, Clazz) { + return (((value && value.constructor) === Clazz) || + value instanceof Clazz); + } + + const v4 = '(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}'; + const v6s = '[a-fA-F\\d]{1,4}'; + const v6 = ` +(?: +(?:${v6s}:){7}(?:${v6s}|:)| // 1:2:3:4:5:6:7:: 1:2:3:4:5:6:7:8 +(?:${v6s}:){6}(?:${v4}|:${v6s}|:)| // 1:2:3:4:5:6:: 1:2:3:4:5:6::8 1:2:3:4:5:6::8 1:2:3:4:5:6::1.2.3.4 +(?:${v6s}:){5}(?::${v4}|(?::${v6s}){1,2}|:)| // 1:2:3:4:5:: 1:2:3:4:5::7:8 1:2:3:4:5::8 1:2:3:4:5::7:1.2.3.4 +(?:${v6s}:){4}(?:(?::${v6s}){0,1}:${v4}|(?::${v6s}){1,3}|:)| // 1:2:3:4:: 1:2:3:4::6:7:8 1:2:3:4::8 1:2:3:4::6:7:1.2.3.4 +(?:${v6s}:){3}(?:(?::${v6s}){0,2}:${v4}|(?::${v6s}){1,4}|:)| // 1:2:3:: 1:2:3::5:6:7:8 1:2:3::8 1:2:3::5:6:7:1.2.3.4 +(?:${v6s}:){2}(?:(?::${v6s}){0,3}:${v4}|(?::${v6s}){1,5}|:)| // 1:2:: 1:2::4:5:6:7:8 1:2::8 1:2::4:5:6:7:1.2.3.4 +(?:${v6s}:){1}(?:(?::${v6s}){0,4}:${v4}|(?::${v6s}){1,6}|:)| // 1:: 1::3:4:5:6:7:8 1::8 1::3:4:5:6:7:1.2.3.4 +(?::(?:(?::${v6s}){0,5}:${v4}|(?::${v6s}){1,7}|:)) // ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::1.2.3.4 +)(?:%[0-9a-zA-Z]{1,})? // %eth0 %1 +`.replace(/\s*\/\/.*$/gm, '').replace(/\n/g, '').trim(); + const v46Exact = new RegExp(`(?:^${v4}$)|(?:^${v6}$)`); + const v4exact = new RegExp(`^${v4}$`); + const v6exact = new RegExp(`^${v6}$`); + function isIp(value, type) { + switch (type) { + case 'v4': return v4exact.test(value); + case 'v6': return v6exact.test(value); + default: return v46Exact.test(value); + } + } + + function replacer(_, v) { + return isBigInt(v) + ? v.toString() + : v; + } + function stringify(value, space) { + return JSON.stringify(value, replacer, space); + } + + function isJsonObject(value) { + const str = typeof value !== 'string' + ? stringify(value) + : value; + try { + const obj = JSON.parse(str); + return typeof obj === 'object' && obj !== null; + } + catch { + return false; + } + } + + function isNull(value) { + return value === null; + } + + function isNumber(value) { + return typeof value === 'number'; + } + + const isObservable = isOn('next'); + + const isPromise = isOnObject('catch', 'then'); + + const ELF_MAGIC = new Uint8Array([0x7f, 0x45, 0x4c, 0x46]); + const PVM_MAGIC = new Uint8Array([0x50, 0x56, 0x4d, 0x00]); + function isRiscV(bytes) { + if (isU8a(bytes)) { + const start = bytes.subarray(0, 4); + return u8aEq(start, PVM_MAGIC) || u8aEq(start, ELF_MAGIC); + } + return false; + } + + const REGEX_DEV = /(Development|Local Testnet)$/; + function isTestChain(chain) { + if (!chain) { + return false; + } + return !!REGEX_DEV.test(chain.toString()); + } + + function isUndefined(value) { + return value === undefined; + } + + function isUtf8(value) { + if (!value) { + return isString(value); + } + const u8a = u8aToU8a(value); + const len = u8a.length; + let i = 0; + while (i < len) { + if (u8a[i] <= 0x7F) { + i += 1; + } + else if (u8a[i] >= 0xC2 && u8a[i] <= 0xDF) { + if (i + 1 < len) { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0xBF) { + return false; + } + } + else { + return false; + } + i += 2; + } + else if (u8a[i] === 0xE0) { + if (i + 2 < len) { + if (u8a[i + 1] < 0xA0 || u8a[i + 1] > 0xBF) { + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + return false; + } + } + else { + return false; + } + i += 3; + } + else if (u8a[i] >= 0xE1 && u8a[i] <= 0xEC) { + if (i + 2 < len) { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0xBF) { + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + return false; + } + } + else { + return false; + } + i += 3; + } + else if (u8a[i] === 0xED) { + if (i + 2 < len) { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0x9F) { + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + return false; + } + } + else { + return false; + } + i += 3; + } + else if (u8a[i] >= 0xEE && u8a[i] <= 0xEF) { + if (i + 2 < len) { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0xBF) { + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + return false; + } + } + else { + return false; + } + i += 3; + } + else if (u8a[i] === 0xF0) { + if (i + 3 < len) { + if (u8a[i + 1] < 0x90 || u8a[i + 1] > 0xBF) { + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + return false; + } + if (u8a[i + 3] < 0x80 || u8a[i + 3] > 0xBF) { + return false; + } + } + else { + return false; + } + i += 4; + } + else if (u8a[i] >= 0xF1 && u8a[i] <= 0xF3) { + if (i + 3 < len) { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0xBF) { + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + return false; + } + if (u8a[i + 3] < 0x80 || u8a[i + 3] > 0xBF) { + return false; + } + } + else { + return false; + } + i += 4; + } + else if (u8a[i] === 0xF4) { + if (i + 3 < len) { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0x8F) { + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + return false; + } + if (u8a[i + 3] < 0x80 || u8a[i + 3] > 0xBF) { + return false; + } + } + else { + return false; + } + i += 4; + } + else { + return false; + } + } + return true; + } + + const WASM_MAGIC = new Uint8Array([0, 97, 115, 109]); + function isWasm(value) { + return isU8a(value) && u8aEq(value.subarray(0, 4), WASM_MAGIC); + } + + function lazyMethod(result, item, creator, getName, index = 0) { + const name = getName + ? getName(item, index) + : item.toString(); + let value; + Object.defineProperty(result, name, { + configurable: true, + enumerable: true, + get: function () { + if (value === undefined) { + value = creator(item, index, this); + try { + Object.defineProperty(this, name, { value }); + } + catch { + } + } + return value; + } + }); + } + function lazyMethods(result, items, creator, getName) { + for (let i = 0, count = items.length; i < count; i++) { + lazyMethod(result, items[i], creator, getName, i); + } + return result; + } + + function identity(value) { + return value; + } + function noop() { + } + + const logTo = { + debug: 'log', + error: 'error', + log: 'log', + warn: 'warn' + }; + function formatOther(value) { + if (value && isObject(value) && value.constructor === Object) { + const result = {}; + for (const [k, v] of Object.entries(value)) { + result[k] = loggerFormat(v); + } + return result; + } + return value; + } + function loggerFormat(value) { + if (Array.isArray(value)) { + return value.map(loggerFormat); + } + else if (isBn(value)) { + return value.toString(); + } + else if (isU8a(value) || isBuffer(value)) { + return u8aToHex(u8aToU8a(value)); + } + return formatOther(value); + } + function formatWithLength(maxLength) { + return (v) => { + if (maxLength <= 0) { + return v; + } + const r = `${v}`; + return r.length < maxLength + ? v + : `${r.substring(0, maxLength)} ...`; + }; + } + function apply(log, type, values, maxSize = -1) { + if (values.length === 1 && isFunction(values[0])) { + const fnResult = values[0](); + return apply(log, type, Array.isArray(fnResult) ? fnResult : [fnResult], maxSize); + } + console[logTo[log]](formatDate(new Date()), type, ...values + .map(loggerFormat) + .map(formatWithLength(maxSize))); + } + function isDebugOn(e, type) { + return !!e && (e === '*' || + type === e || + (e.endsWith('*') && + type.startsWith(e.slice(0, -1)))); + } + function isDebugOff(e, type) { + return !!e && (e.startsWith('-') && + (type === e.slice(1) || + (e.endsWith('*') && + type.startsWith(e.slice(1, -1))))); + } + function getDebugFlag(env, type) { + let flag = false; + for (const e of env) { + if (isDebugOn(e, type)) { + flag = true; + } + else if (isDebugOff(e, type)) { + flag = false; + } + } + return flag; + } + function parseEnv(type) { + const maxSize = parseInt(xglobal.process?.env?.['DEBUG_MAX'] || '-1', 10); + return [ + getDebugFlag((xglobal.process?.env?.['DEBUG'] || '').toLowerCase().split(','), type), + isNaN(maxSize) + ? -1 + : maxSize + ]; + } + function logger(origin) { + const type = `${origin.toUpperCase()}:`.padStart(16); + const [isDebug, maxSize] = parseEnv(origin.toLowerCase()); + return { + debug: isDebug + ? (...values) => apply('debug', type, values, maxSize) + : noop, + error: (...values) => apply('error', type, values), + log: (...values) => apply('log', type, values), + noop, + warn: (...values) => apply('warn', type, values) + }; + } + + function defaultGetId() { + return 'none'; + } + function memoize(fn, { getInstanceId = defaultGetId } = {}) { + const cache = {}; + const memoized = (...args) => { + const stringParams = stringify(args); + const instanceId = getInstanceId(); + if (!cache[instanceId]) { + cache[instanceId] = {}; + } + if (cache[instanceId][stringParams] === undefined) { + cache[instanceId][stringParams] = fn(...args); + } + return cache[instanceId][stringParams]; + }; + memoized.unmemoize = (...args) => { + const stringParams = stringify(args); + const instanceId = getInstanceId(); + if (cache[instanceId]?.[stringParams] !== undefined) { + delete cache[instanceId][stringParams]; + } + }; + return memoized; + } + + function nextTick(onExec, onError) { + setTimeout(() => { + Promise + .resolve() + .then(() => { + onExec(); + }) + .catch((error) => { + if (onError) { + onError(error); + } + else { + console.error(error); + } + }); + }, 0); + } + + function numberToHex(value, bitLength = -1) { + const hex = (!value || Number.isNaN(value) ? 0 : value).toString(16); + return hexFixLength(hex.length % 2 ? `0${hex}` : hex, bitLength, true); + } + + function numberToU8a(value, bitLength = -1) { + return hexToU8a(numberToHex(value, bitLength)); + } + + function objectClear(value) { + const keys = Object.keys(value); + for (let i = 0, count = keys.length; i < count; i++) { + delete value[keys[i]]; + } + return value; + } + + function objectSpread(dest, ...sources) { + const filterProps = new Set(['__proto__', 'constructor', 'prototype']); + for (let i = 0, count = sources.length; i < count; i++) { + const src = sources[i]; + if (src) { + if (typeof src.entries === 'function') { + for (const [key, value] of src.entries()) { + if (!filterProps.has(key)) { + dest[key] = value; + } + } + } + else { + const sanitizedSrc = Object.create(null); + for (const [key, value] of Object.entries(src)) { + if (!filterProps.has(key)) { + sanitizedSrc[key] = value; + } + } + Object.assign(dest, sanitizedSrc); + } + } + } + return dest; + } + + function objectCopy(source) { + return objectSpread({}, source); + } + + function objectEntries(obj) { + return Object.entries(obj); + } + + function objectKeys(value) { + return Object.keys(value); + } + + function objectProperty(that, key, getter, getName, index = 0) { + const name = getName + ? getName(key, index) + : key; + if (!(name in that)) { + Object.defineProperty(that, name, { + enumerable: true, + get: function () { + return getter(key, index, this); + } + }); + } + } + function objectProperties(that, keys, getter, getName) { + for (let i = 0, count = keys.length; i < count; i++) { + objectProperty(that, keys[i], getter, getName, i); + } + } + + function objectValues(obj) { + return Object.values(obj); + } + + function promisify(self, fn, ...params) { + return new Promise((resolve, reject) => { + fn.apply(self, params.concat((error, result) => { + if (error) { + reject(error); + } + else { + resolve(result); + } + })); + }); + } + + const CC_TO_UP = new Array(256); + const CC_TO_LO = new Array(256); + for (let i = 0, count = CC_TO_UP.length; i < count; i++) { + CC_TO_LO[i] = String.fromCharCode(i).toLowerCase(); + CC_TO_UP[i] = String.fromCharCode(i).toUpperCase(); + } + function formatAllCaps(w) { + return w.slice(0, w.length - 1).toLowerCase() + CC_TO_UP[w.charCodeAt(w.length - 1)]; + } + function converter$1(format) { + return (value) => { + const parts = value + .replace(/[-_., ]+/g, ' ') + .trim() + .split(' '); + let result = ''; + for (let i = 0, count = parts.length; i < count; i++) { + const w = parts[i]; + result += format(/^[\dA-Z]+$/.test(w) + ? w.toLowerCase() + : w.replace(/^[\dA-Z]{2,}[^a-z]/, formatAllCaps), i); + } + return result; + }; + } + const stringCamelCase = converter$1((w, i) => + (i ? CC_TO_UP[w.charCodeAt(0)] : CC_TO_LO[w.charCodeAt(0)]) + w.slice(1)); + const stringPascalCase = converter$1((w) => + CC_TO_UP[w.charCodeAt(0)] + w.slice(1)); + + function converter(map) { + return (value) => value + ? map[value.charCodeAt(0)] + value.slice(1) + : ''; + } + const stringLowerFirst = converter(CC_TO_LO); + const stringUpperFirst = converter(CC_TO_UP); + + function stringShorten(value, prefixLength = 6) { + return value.length <= 2 + 2 * prefixLength + ? value.toString() + : `${value.substring(0, prefixLength)}…${value.slice(-prefixLength)}`; + } + + function stringToHex(value) { + return u8aToHex(stringToU8a(value)); + } + + exports.BN = BN; + exports.BN_BILLION = BN_BILLION; + exports.BN_EIGHT = BN_EIGHT; + exports.BN_FIVE = BN_FIVE; + exports.BN_FOUR = BN_FOUR; + exports.BN_HUNDRED = BN_HUNDRED; + exports.BN_MAX_INTEGER = BN_MAX_INTEGER; + exports.BN_MILLION = BN_MILLION; + exports.BN_NINE = BN_NINE; + exports.BN_ONE = BN_ONE; + exports.BN_QUINTILL = BN_QUINTILL; + exports.BN_SEVEN = BN_SEVEN; + exports.BN_SIX = BN_SIX; + exports.BN_SQRT_MAX_INTEGER = BN_SQRT_MAX_INTEGER; + exports.BN_TEN = BN_TEN; + exports.BN_THOUSAND = BN_THOUSAND; + exports.BN_THREE = BN_THREE; + exports.BN_TWO = BN_TWO; + exports.BN_ZERO = BN_ZERO; + exports.POLKADOTJS_DISABLE_ESM_CJS_WARNING_FLAG = POLKADOTJS_DISABLE_ESM_CJS_WARNING_FLAG; + exports.U8A_WRAP_ETHEREUM = U8A_WRAP_ETHEREUM; + exports.U8A_WRAP_POSTFIX = U8A_WRAP_POSTFIX; + exports.U8A_WRAP_PREFIX = U8A_WRAP_PREFIX; + exports._0n = _0n; + exports._1000n = _1000n; + exports._100n = _100n; + exports._10n = _10n; + exports._1Bn = _1Bn; + exports._1Mn = _1Mn; + exports._1Qn = _1Qn; + exports._1n = _1n; + exports._2n = _2n; + exports._2pow53n = _2pow53n; + exports._3n = _3n; + exports._4n = _4n; + exports._5n = _5n; + exports._6n = _6n; + exports._7n = _7n; + exports._8n = _8n; + exports._9n = _9n; + exports._sqrt2pow53n = _sqrt2pow53n; + exports.arrayChunk = arrayChunk; + exports.arrayFilter = arrayFilter; + exports.arrayFlatten = arrayFlatten; + exports.arrayRange = arrayRange; + exports.arrayShuffle = arrayShuffle; + exports.arrayUnzip = arrayUnzip; + exports.arrayZip = arrayZip; + exports.assert = assert; + exports.assertReturn = assertReturn; + exports.assertUnreachable = assertUnreachable; + exports.bnFromHex = hexToBn; + exports.bnMax = bnMax; + exports.bnMin = bnMin; + exports.bnSqrt = bnSqrt; + exports.bnToBn = bnToBn; + exports.bnToHex = bnToHex; + exports.bnToU8a = bnToU8a; + exports.bufferToU8a = bufferToU8a; + exports.calcSi = calcSi; + exports.compactAddLength = compactAddLength; + exports.compactFromU8a = compactFromU8a; + exports.compactFromU8aLim = compactFromU8aLim; + exports.compactStripLength = compactStripLength; + exports.compactToU8a = compactToU8a; + exports.detectPackage = detectPackage; + exports.extractTime = extractTime; + exports.findSi = findSi; + exports.floatToU8a = floatToU8a; + exports.formatBalance = formatBalance; + exports.formatDate = formatDate; + exports.formatDecimal = formatDecimal; + exports.formatElapsed = formatElapsed; + exports.formatNumber = formatNumber; + exports.hasBigInt = hasBigInt; + exports.hasBuffer = hasBuffer; + exports.hasCjs = hasCjs; + exports.hasDirname = hasDirname; + exports.hasEsm = hasEsm; + exports.hasProcess = hasProcess; + exports.hasWasm = hasWasm; + exports.hexAddPrefix = hexAddPrefix; + exports.hexFixLength = hexFixLength; + exports.hexHasPrefix = hexHasPrefix; + exports.hexStripPrefix = hexStripPrefix; + exports.hexToBigInt = hexToBigInt; + exports.hexToBn = hexToBn; + exports.hexToNumber = hexToNumber; + exports.hexToString = hexToString; + exports.hexToU8a = hexToU8a; + exports.identity = identity; + exports.isArray = isArray; + exports.isAscii = isAscii; + exports.isBigInt = isBigInt; + exports.isBn = isBn; + exports.isBoolean = isBoolean; + exports.isBuffer = isBuffer; + exports.isChildClass = isChildClass; + exports.isClass = isClass; + exports.isCodec = isCodec; + exports.isCompact = isCompact; + exports.isError = isError; + exports.isFunction = isFunction; + exports.isHex = isHex; + exports.isInstanceOf = isInstanceOf; + exports.isIp = isIp; + exports.isJsonObject = isJsonObject; + exports.isNull = isNull; + exports.isNumber = isNumber; + exports.isObject = isObject; + exports.isObservable = isObservable; + exports.isPromise = isPromise; + exports.isRiscV = isRiscV; + exports.isString = isString; + exports.isTestChain = isTestChain; + exports.isToBigInt = isToBigInt; + exports.isToBn = isToBn; + exports.isU8a = isU8a; + exports.isUndefined = isUndefined; + exports.isUtf8 = isUtf8; + exports.isWasm = isWasm; + exports.lazyMethod = lazyMethod; + exports.lazyMethods = lazyMethods; + exports.logger = logger; + exports.loggerFormat = loggerFormat; + exports.memoize = memoize; + exports.nMax = nMax; + exports.nMin = nMin; + exports.nSqrt = nSqrt; + exports.nToBigInt = nToBigInt; + exports.nToHex = nToHex; + exports.nToU8a = nToU8a; + exports.nextTick = nextTick; + exports.noop = noop; + exports.numberToHex = numberToHex; + exports.numberToU8a = numberToU8a; + exports.objectClear = objectClear; + exports.objectCopy = objectCopy; + exports.objectEntries = objectEntries; + exports.objectKeys = objectKeys; + exports.objectProperties = objectProperties; + exports.objectProperty = objectProperty; + exports.objectSpread = objectSpread; + exports.objectValues = objectValues; + exports.packageInfo = packageInfo$3; + exports.promisify = promisify; + exports.stringCamelCase = stringCamelCase; + exports.stringLowerFirst = stringLowerFirst; + exports.stringPascalCase = stringPascalCase; + exports.stringShorten = stringShorten; + exports.stringToHex = stringToHex; + exports.stringToU8a = stringToU8a; + exports.stringUpperFirst = stringUpperFirst; + exports.stringify = stringify; + exports.u8aCmp = u8aCmp; + exports.u8aConcat = u8aConcat; + exports.u8aConcatStrict = u8aConcatStrict; + exports.u8aEmpty = u8aEmpty; + exports.u8aEq = u8aEq; + exports.u8aFixLength = u8aFixLength; + exports.u8aIsWrapped = u8aIsWrapped; + exports.u8aSorted = u8aSorted; + exports.u8aToBigInt = u8aToBigInt; + exports.u8aToBn = u8aToBn; + exports.u8aToBuffer = u8aToBuffer; + exports.u8aToFloat = u8aToFloat; + exports.u8aToHex = u8aToHex; + exports.u8aToNumber = u8aToNumber; + exports.u8aToString = u8aToString; + exports.u8aToU8a = u8aToU8a; + exports.u8aUnwrapBytes = u8aUnwrapBytes; + exports.u8aWrapBytes = u8aWrapBytes; + +})); diff --git a/packages/util/bundle.d.ts b/packages/util/bundle.d.ts new file mode 100644 index 0000000..a0ef069 --- /dev/null +++ b/packages/util/bundle.d.ts @@ -0,0 +1,28 @@ +/** + * @summary Utility methods for this package are split into groups + */ +export { packageInfo } from './packageInfo.js'; +export * from './array/index.js'; +export * from './assert.js'; +export * from './bi/index.js'; +export * from './bn/index.js'; +export * from './buffer/index.js'; +export * from './compact/index.js'; +export * from './detectPackage.js'; +export * from './extractTime.js'; +export * from './float/index.js'; +export * from './format/index.js'; +export * from './has.js'; +export * from './hex/index.js'; +export * from './is/index.js'; +export * from './lazy.js'; +export * from './logger.js'; +export * from './memoize.js'; +export * from './nextTick.js'; +export * from './noop.js'; +export * from './number/index.js'; +export * from './object/index.js'; +export * from './promisify.js'; +export * from './string/index.js'; +export * from './stringify.js'; +export * from './u8a/index.js'; diff --git a/packages/util/bundle.js b/packages/util/bundle.js new file mode 100644 index 0000000..a0ef069 --- /dev/null +++ b/packages/util/bundle.js @@ -0,0 +1,28 @@ +/** + * @summary Utility methods for this package are split into groups + */ +export { packageInfo } from './packageInfo.js'; +export * from './array/index.js'; +export * from './assert.js'; +export * from './bi/index.js'; +export * from './bn/index.js'; +export * from './buffer/index.js'; +export * from './compact/index.js'; +export * from './detectPackage.js'; +export * from './extractTime.js'; +export * from './float/index.js'; +export * from './format/index.js'; +export * from './has.js'; +export * from './hex/index.js'; +export * from './is/index.js'; +export * from './lazy.js'; +export * from './logger.js'; +export * from './memoize.js'; +export * from './nextTick.js'; +export * from './noop.js'; +export * from './number/index.js'; +export * from './object/index.js'; +export * from './promisify.js'; +export * from './string/index.js'; +export * from './stringify.js'; +export * from './u8a/index.js'; diff --git a/packages/util/cjs/array/chunk.d.ts b/packages/util/cjs/array/chunk.d.ts new file mode 100644 index 0000000..c085420 --- /dev/null +++ b/packages/util/cjs/array/chunk.d.ts @@ -0,0 +1,15 @@ +/** + * @name arrayChunk + * @summary Split T[] into T[][] based on the defind size + * @description + * Returns a set ao arrays based on the chunksize + * @example + *
+ * + * ```javascript + * import { arrayChunk } from '@pezkuwi/util'; + * + * arrayChunk([1, 2, 3, 4, 5]); // [[1, 2], [3, 4], [5]] + * ``` + */ +export declare function arrayChunk(array: T[], chunkSize: number): T[][]; diff --git a/packages/util/cjs/array/chunk.js b/packages/util/cjs/array/chunk.js new file mode 100644 index 0000000..3066a01 --- /dev/null +++ b/packages/util/cjs/array/chunk.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.arrayChunk = arrayChunk; +/** + * @name arrayChunk + * @summary Split T[] into T[][] based on the defind size + * @description + * Returns a set ao arrays based on the chunksize + * @example + *
+ * + * ```javascript + * import { arrayChunk } from '@pezkuwi/util'; + * + * arrayChunk([1, 2, 3, 4, 5]); // [[1, 2], [3, 4], [5]] + * ``` + */ +function arrayChunk(array, chunkSize) { + const outputSize = Math.ceil(array.length / chunkSize); + // shortcut for the single-split case + if (outputSize === 1) { + return [array]; + } + const output = Array(outputSize); + for (let i = 0; i < outputSize; i++) { + const offset = i * chunkSize; + output[i] = array.slice(offset, offset + chunkSize); + } + return output; +} diff --git a/packages/util/cjs/array/filter.d.ts b/packages/util/cjs/array/filter.d.ts new file mode 100644 index 0000000..d8be6ab --- /dev/null +++ b/packages/util/cjs/array/filter.d.ts @@ -0,0 +1,16 @@ +/** + * @name arrayFilter + * @summary Filters undefined and (optionally) null values from an array + * @description + * Returns a new array with all `undefined` values removed. Optionally, when `allowNulls = false`, it removes the `null` values as well + * @example + *
+ * + * ```javascript + * import { arrayFilter } from '@pezkuwi/util'; + * + * arrayFilter([0, void 0, true, null, false, '']); // [0, true, null, false, ''] + * arrayFilter([0, void 0, true, null, false, ''], false); // [0, true, false, ''] + * ``` + */ +export declare function arrayFilter(array: readonly (T | null | undefined)[], allowNulls?: boolean): T[]; diff --git a/packages/util/cjs/array/filter.js b/packages/util/cjs/array/filter.js new file mode 100644 index 0000000..8f657a1 --- /dev/null +++ b/packages/util/cjs/array/filter.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.arrayFilter = arrayFilter; +/** + * @name arrayFilter + * @summary Filters undefined and (optionally) null values from an array + * @description + * Returns a new array with all `undefined` values removed. Optionally, when `allowNulls = false`, it removes the `null` values as well + * @example + *
+ * + * ```javascript + * import { arrayFilter } from '@pezkuwi/util'; + * + * arrayFilter([0, void 0, true, null, false, '']); // [0, true, null, false, ''] + * arrayFilter([0, void 0, true, null, false, ''], false); // [0, true, false, ''] + * ``` + */ +function arrayFilter(array, allowNulls = true) { + return array.filter((v) => v !== undefined && + (allowNulls || v !== null)); +} diff --git a/packages/util/cjs/array/flatten.d.ts b/packages/util/cjs/array/flatten.d.ts new file mode 100644 index 0000000..49fa218 --- /dev/null +++ b/packages/util/cjs/array/flatten.d.ts @@ -0,0 +1,15 @@ +/** + * @name arrayFlatten + * @summary Merge T[][] into T[] + * @description + * Returns a new array with all arrays merged into one + * @example + *
+ * + * ```javascript + * import { arrayFlatten } from '@pezkuwi/util'; + * + * arrayFlatten([[1, 2], [3, 4], [5]]); // [1, 2, 3, 4, 5] + * ``` + */ +export declare function arrayFlatten(arrays: readonly T[][]): T[]; diff --git a/packages/util/cjs/array/flatten.js b/packages/util/cjs/array/flatten.js new file mode 100644 index 0000000..a398220 --- /dev/null +++ b/packages/util/cjs/array/flatten.js @@ -0,0 +1,42 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.arrayFlatten = arrayFlatten; +/** + * @name arrayFlatten + * @summary Merge T[][] into T[] + * @description + * Returns a new array with all arrays merged into one + * @example + *
+ * + * ```javascript + * import { arrayFlatten } from '@pezkuwi/util'; + * + * arrayFlatten([[1, 2], [3, 4], [5]]); // [1, 2, 3, 4, 5] + * ``` + */ +function arrayFlatten(arrays) { + const num = arrays.length; + // shortcuts for the empty & single-entry case + if (num === 0) { + return []; + } + else if (num === 1) { + return arrays[0]; + } + // pre-allocate based on the combined size + let size = 0; + for (let i = 0; i < num; i++) { + size += arrays[i].length; + } + const output = new Array(size); + let i = -1; + for (let j = 0; j < num; j++) { + const a = arrays[j]; + // instead of pushing, we just set the entries + for (let e = 0, count = a.length; e < count; e++) { + output[++i] = a[e]; + } + } + return output; +} diff --git a/packages/util/cjs/array/index.d.ts b/packages/util/cjs/array/index.d.ts new file mode 100644 index 0000000..0f24c19 --- /dev/null +++ b/packages/util/cjs/array/index.d.ts @@ -0,0 +1,10 @@ +/** + * @summary Utility methods that operates on arrays + */ +export { arrayChunk } from './chunk.js'; +export { arrayFilter } from './filter.js'; +export { arrayFlatten } from './flatten.js'; +export { arrayRange } from './range.js'; +export { arrayShuffle } from './shuffle.js'; +export { arrayUnzip } from './unzip.js'; +export { arrayZip } from './zip.js'; diff --git a/packages/util/cjs/array/index.js b/packages/util/cjs/array/index.js new file mode 100644 index 0000000..caa2975 --- /dev/null +++ b/packages/util/cjs/array/index.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.arrayZip = exports.arrayUnzip = exports.arrayShuffle = exports.arrayRange = exports.arrayFlatten = exports.arrayFilter = exports.arrayChunk = void 0; +/** + * @summary Utility methods that operates on arrays + */ +var chunk_js_1 = require("./chunk.js"); +Object.defineProperty(exports, "arrayChunk", { enumerable: true, get: function () { return chunk_js_1.arrayChunk; } }); +var filter_js_1 = require("./filter.js"); +Object.defineProperty(exports, "arrayFilter", { enumerable: true, get: function () { return filter_js_1.arrayFilter; } }); +var flatten_js_1 = require("./flatten.js"); +Object.defineProperty(exports, "arrayFlatten", { enumerable: true, get: function () { return flatten_js_1.arrayFlatten; } }); +var range_js_1 = require("./range.js"); +Object.defineProperty(exports, "arrayRange", { enumerable: true, get: function () { return range_js_1.arrayRange; } }); +var shuffle_js_1 = require("./shuffle.js"); +Object.defineProperty(exports, "arrayShuffle", { enumerable: true, get: function () { return shuffle_js_1.arrayShuffle; } }); +var unzip_js_1 = require("./unzip.js"); +Object.defineProperty(exports, "arrayUnzip", { enumerable: true, get: function () { return unzip_js_1.arrayUnzip; } }); +var zip_js_1 = require("./zip.js"); +Object.defineProperty(exports, "arrayZip", { enumerable: true, get: function () { return zip_js_1.arrayZip; } }); diff --git a/packages/util/cjs/array/range.d.ts b/packages/util/cjs/array/range.d.ts new file mode 100644 index 0000000..7918d1d --- /dev/null +++ b/packages/util/cjs/array/range.d.ts @@ -0,0 +1,16 @@ +/** + * @name arrayRange + * @summary Returns a range of numbers ith the size and the specified offset + * @description + * Returns a new array of numbers with the specific size. Optionally, when `startAt`, is provided, it generates the range to start at a specific value. + * @example + *
+ * + * ```javascript + * import { arrayRange } from '@pezkuwi/util'; + * + * arrayRange(5); // [0, 1, 2, 3, 4] + * arrayRange(3, 5); // [5, 6, 7] + * ``` + */ +export declare function arrayRange(size: number, startAt?: number): number[]; diff --git a/packages/util/cjs/array/range.js b/packages/util/cjs/array/range.js new file mode 100644 index 0000000..ae7c634 --- /dev/null +++ b/packages/util/cjs/array/range.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.arrayRange = arrayRange; +/** + * @name arrayRange + * @summary Returns a range of numbers ith the size and the specified offset + * @description + * Returns a new array of numbers with the specific size. Optionally, when `startAt`, is provided, it generates the range to start at a specific value. + * @example + *
+ * + * ```javascript + * import { arrayRange } from '@pezkuwi/util'; + * + * arrayRange(5); // [0, 1, 2, 3, 4] + * arrayRange(3, 5); // [5, 6, 7] + * ``` + */ +function arrayRange(size, startAt = 0) { + if (size <= 0) { + throw new Error('Expected non-zero, positive number as a range size'); + } + const result = new Array(size); + for (let i = 0; i < size; i++) { + result[i] = i + startAt; + } + return result; +} diff --git a/packages/util/cjs/array/shuffle.d.ts b/packages/util/cjs/array/shuffle.d.ts new file mode 100644 index 0000000..6a6e34d --- /dev/null +++ b/packages/util/cjs/array/shuffle.d.ts @@ -0,0 +1,5 @@ +/** + * @name arrayShuffle + * @description Shuffles the input array (unlike sort, this is not done in-place) + */ +export declare function arrayShuffle(input: readonly T[]): T[]; diff --git a/packages/util/cjs/array/shuffle.js b/packages/util/cjs/array/shuffle.js new file mode 100644 index 0000000..d408875 --- /dev/null +++ b/packages/util/cjs/array/shuffle.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.arrayShuffle = arrayShuffle; +/** + * @name arrayShuffle + * @description Shuffles the input array (unlike sort, this is not done in-place) + */ +function arrayShuffle(input) { + const result = input.slice(); + let curr = result.length; + // noop for the single entry + if (curr === 1) { + return result; + } + while (curr !== 0) { + // ~~ is more performant than Math.floor + const rand = ~~(Math.random() * curr); + curr--; + [result[curr], result[rand]] = [result[rand], result[curr]]; + } + return result; +} diff --git a/packages/util/cjs/array/unzip.d.ts b/packages/util/cjs/array/unzip.d.ts new file mode 100644 index 0000000..e98ece0 --- /dev/null +++ b/packages/util/cjs/array/unzip.d.ts @@ -0,0 +1,5 @@ +/** + * @name arrayUnzip + * @description Splits a single [K, V][] into [K[], V[]] + */ +export declare function arrayUnzip(entries: readonly [K, V][]): [K[], V[]]; diff --git a/packages/util/cjs/array/unzip.js b/packages/util/cjs/array/unzip.js new file mode 100644 index 0000000..6604ed5 --- /dev/null +++ b/packages/util/cjs/array/unzip.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.arrayUnzip = arrayUnzip; +/** + * @name arrayUnzip + * @description Splits a single [K, V][] into [K[], V[]] + */ +function arrayUnzip(entries) { + const count = entries.length; + const keys = new Array(count); + const values = new Array(count); + for (let i = 0; i < count; i++) { + [keys[i], values[i]] = entries[i]; + } + return [keys, values]; +} diff --git a/packages/util/cjs/array/zip.d.ts b/packages/util/cjs/array/zip.d.ts new file mode 100644 index 0000000..79769c7 --- /dev/null +++ b/packages/util/cjs/array/zip.d.ts @@ -0,0 +1,5 @@ +/** + * @name arrayZip + * @description Combines 2 distinct key/value arrays into a single [K, V] array + */ +export declare function arrayZip(keys: readonly K[], values: readonly V[]): [K, V][]; diff --git a/packages/util/cjs/array/zip.js b/packages/util/cjs/array/zip.js new file mode 100644 index 0000000..c6fb971 --- /dev/null +++ b/packages/util/cjs/array/zip.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.arrayZip = arrayZip; +/** + * @name arrayZip + * @description Combines 2 distinct key/value arrays into a single [K, V] array + */ +function arrayZip(keys, values) { + const count = keys.length; + const result = new Array(count); + for (let i = 0; i < count; i++) { + result[i] = [keys[i], values[i]]; + } + return result; +} diff --git a/packages/util/cjs/assert.d.ts b/packages/util/cjs/assert.d.ts new file mode 100644 index 0000000..bde2a0c --- /dev/null +++ b/packages/util/cjs/assert.d.ts @@ -0,0 +1,29 @@ +type MessageFn = () => string; +/** + * @name assert + * @summary Checks for a valid test, if not Error is thrown. + * @description + * Checks that `test` is a truthy value. If value is falsy (`null`, `undefined`, `false`, ...), it throws an Error with the supplied `message`. When `test` passes, `true` is returned. + * @example + *
+ * + * ```javascript + * const { assert } from '@pezkuwi/util'; + * + * assert(true, 'True should be true'); // passes + * assert(false, 'False should not be true'); // Error thrown + * assert(false, () => 'message'); // Error with 'message' + * ``` + */ +export declare function assert(condition: unknown, message: string | MessageFn): asserts condition; +/** + * @name assertReturn + * @description Returns when the value is not undefined/null, otherwise throws assertion error + */ +export declare function assertReturn(value: T | undefined | null, message: string | MessageFn): T; +/** + * @name assertUnreachable + * @description An assertion helper that ensures all codepaths are followed + */ +export declare function assertUnreachable(x: never): never; +export {}; diff --git a/packages/util/cjs/assert.js b/packages/util/cjs/assert.js new file mode 100644 index 0000000..fea71b2 --- /dev/null +++ b/packages/util/cjs/assert.js @@ -0,0 +1,44 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.assert = assert; +exports.assertReturn = assertReturn; +exports.assertUnreachable = assertUnreachable; +const function_js_1 = require("./is/function.js"); +/** + * @name assert + * @summary Checks for a valid test, if not Error is thrown. + * @description + * Checks that `test` is a truthy value. If value is falsy (`null`, `undefined`, `false`, ...), it throws an Error with the supplied `message`. When `test` passes, `true` is returned. + * @example + *
+ * + * ```javascript + * const { assert } from '@pezkuwi/util'; + * + * assert(true, 'True should be true'); // passes + * assert(false, 'False should not be true'); // Error thrown + * assert(false, () => 'message'); // Error with 'message' + * ``` + */ +function assert(condition, message) { + if (!condition) { + throw new Error((0, function_js_1.isFunction)(message) + ? message() + : message); + } +} +/** + * @name assertReturn + * @description Returns when the value is not undefined/null, otherwise throws assertion error + */ +function assertReturn(value, message) { + assert(value !== undefined && value !== null, message); + return value; +} +/** + * @name assertUnreachable + * @description An assertion helper that ensures all codepaths are followed + */ +function assertUnreachable(x) { + throw new Error(`This codepath should be unreachable. Unhandled input: ${x}`); +} diff --git a/packages/util/cjs/bi/consts.d.ts b/packages/util/cjs/bi/consts.d.ts new file mode 100644 index 0000000..9b0f2fb --- /dev/null +++ b/packages/util/cjs/bi/consts.d.ts @@ -0,0 +1,90 @@ +/** + * @name _0n + * @summary BigInt constant for 0. + */ +export declare const _0n: bigint; +/** + * @name _1n + * @summary BigInt constant for 1. + */ +export declare const _1n: bigint; +/** + * @name _2n + * @summary BigInt constant for 2. + */ +export declare const _2n: bigint; +/** + * @name _3n + * @summary BigInt constant for 3. + */ +export declare const _3n: bigint; +/** + * @name _4n + * @summary BigInt constant for 4. + */ +export declare const _4n: bigint; +/** + * @name _5n + * @summary BigInt constant for 5. + */ +export declare const _5n: bigint; +/** + * @name _6n + * @summary BigInt constant for 6. + */ +export declare const _6n: bigint; +/** + * @name _7n + * @summary BigInt constant for 7. + */ +export declare const _7n: bigint; +/** + * @name _8n + * @summary BigInt constant for 8. + */ +export declare const _8n: bigint; +/** + * @name _9n + * @summary BigInt constant for 9. + */ +export declare const _9n: bigint; +/** + * @name _10n + * @summary BigInt constant for 10. + */ +export declare const _10n: bigint; +/** + * @name _100n + * @summary BigInt constant for 100. + */ +export declare const _100n: bigint; +/** + * @name _1000n + * @summary BigInt constant for 1000. + */ +export declare const _1000n: bigint; +/** + * @name _1Mn + * @summary BigInt constant for 1,000,000 (million). + */ +export declare const _1Mn: bigint; +/** +* @name _1Bn +* @summary BigInt constant for 1,000,000,000 (billion). +*/ +export declare const _1Bn: bigint; +/** +* @name _1Qn +* @summary BigInt constant for 1,000,000,000,000,000,000 (quitillion). +*/ +export declare const _1Qn: bigint; +/** +* @name _2pow53n +* @summary BigInt constant for MAX_SAFE_INTEGER +*/ +export declare const _2pow53n: bigint; +/** + * @name _sqrt2pow53n + * @summary BigInt constant for Math.sqrt(MAX_SAFE_INTEGER) + */ +export declare const _sqrt2pow53n: bigint; diff --git a/packages/util/cjs/bi/consts.js b/packages/util/cjs/bi/consts.js new file mode 100644 index 0000000..ad07c82 --- /dev/null +++ b/packages/util/cjs/bi/consts.js @@ -0,0 +1,94 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports._sqrt2pow53n = exports._2pow53n = exports._1Qn = exports._1Bn = exports._1Mn = exports._1000n = exports._100n = exports._10n = exports._9n = exports._8n = exports._7n = exports._6n = exports._5n = exports._4n = exports._3n = exports._2n = exports._1n = exports._0n = void 0; +const x_bigint_1 = require("@pezkuwi/x-bigint"); +/** + * @name _0n + * @summary BigInt constant for 0. + */ +exports._0n = (0, x_bigint_1.BigInt)(0); +/** + * @name _1n + * @summary BigInt constant for 1. + */ +exports._1n = (0, x_bigint_1.BigInt)(1); +/** + * @name _2n + * @summary BigInt constant for 2. + */ +exports._2n = (0, x_bigint_1.BigInt)(2); +/** + * @name _3n + * @summary BigInt constant for 3. + */ +exports._3n = (0, x_bigint_1.BigInt)(3); +/** + * @name _4n + * @summary BigInt constant for 4. + */ +exports._4n = (0, x_bigint_1.BigInt)(4); +/** + * @name _5n + * @summary BigInt constant for 5. + */ +exports._5n = (0, x_bigint_1.BigInt)(5); +/** + * @name _6n + * @summary BigInt constant for 6. + */ +exports._6n = (0, x_bigint_1.BigInt)(6); +/** + * @name _7n + * @summary BigInt constant for 7. + */ +exports._7n = (0, x_bigint_1.BigInt)(7); +/** + * @name _8n + * @summary BigInt constant for 8. + */ +exports._8n = (0, x_bigint_1.BigInt)(8); +/** + * @name _9n + * @summary BigInt constant for 9. + */ +exports._9n = (0, x_bigint_1.BigInt)(9); +/** + * @name _10n + * @summary BigInt constant for 10. + */ +exports._10n = (0, x_bigint_1.BigInt)(10); +/** + * @name _100n + * @summary BigInt constant for 100. + */ +exports._100n = (0, x_bigint_1.BigInt)(100); +/** + * @name _1000n + * @summary BigInt constant for 1000. + */ +exports._1000n = (0, x_bigint_1.BigInt)(1_000); +/** + * @name _1Mn + * @summary BigInt constant for 1,000,000 (million). + */ +exports._1Mn = (0, x_bigint_1.BigInt)(1_000_000); +/** +* @name _1Bn +* @summary BigInt constant for 1,000,000,000 (billion). +*/ +exports._1Bn = (0, x_bigint_1.BigInt)(1_000_000_000); +/** +* @name _1Qn +* @summary BigInt constant for 1,000,000,000,000,000,000 (quitillion). +*/ +exports._1Qn = exports._1Bn * exports._1Bn; +/** +* @name _2pow53n +* @summary BigInt constant for MAX_SAFE_INTEGER +*/ +exports._2pow53n = (0, x_bigint_1.BigInt)(Number.MAX_SAFE_INTEGER); +/** + * @name _sqrt2pow53n + * @summary BigInt constant for Math.sqrt(MAX_SAFE_INTEGER) + */ +exports._sqrt2pow53n = (0, x_bigint_1.BigInt)(94906265); diff --git a/packages/util/cjs/bi/helpers.d.ts b/packages/util/cjs/bi/helpers.d.ts new file mode 100644 index 0000000..204df81 --- /dev/null +++ b/packages/util/cjs/bi/helpers.d.ts @@ -0,0 +1,2 @@ +/** @internal */ +export declare function createCmp(cmp: (a: T, b: T) => boolean): (...items: T[]) => T; diff --git a/packages/util/cjs/bi/helpers.js b/packages/util/cjs/bi/helpers.js new file mode 100644 index 0000000..61b2c8c --- /dev/null +++ b/packages/util/cjs/bi/helpers.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createCmp = createCmp; +/** @internal */ +function createCmp(cmp) { + return (...items) => { + const count = items.length; + if (count === 0) { + throw new Error('Must provide one or more arguments'); + } + let result = items[0]; + for (let i = 1; i < count; i++) { + if (cmp(items[i], result)) { + result = items[i]; + } + } + return result; + }; +} diff --git a/packages/util/cjs/bi/index.d.ts b/packages/util/cjs/bi/index.d.ts new file mode 100644 index 0000000..3399c2e --- /dev/null +++ b/packages/util/cjs/bi/index.d.ts @@ -0,0 +1,9 @@ +/** + * @summary Utility methods to convert to and from `bigint` objects + */ +export { nMax, nMin } from './min.js'; +export { nSqrt } from './sqrt.js'; +export { nToBigInt } from './toBigInt.js'; +export { nToHex } from './toHex.js'; +export { nToU8a } from './toU8a.js'; +export * from './consts.js'; diff --git a/packages/util/cjs/bi/index.js b/packages/util/cjs/bi/index.js new file mode 100644 index 0000000..1707773 --- /dev/null +++ b/packages/util/cjs/bi/index.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.nToU8a = exports.nToHex = exports.nToBigInt = exports.nSqrt = exports.nMin = exports.nMax = void 0; +const tslib_1 = require("tslib"); +/** + * @summary Utility methods to convert to and from `bigint` objects + */ +var min_js_1 = require("./min.js"); +Object.defineProperty(exports, "nMax", { enumerable: true, get: function () { return min_js_1.nMax; } }); +Object.defineProperty(exports, "nMin", { enumerable: true, get: function () { return min_js_1.nMin; } }); +var sqrt_js_1 = require("./sqrt.js"); +Object.defineProperty(exports, "nSqrt", { enumerable: true, get: function () { return sqrt_js_1.nSqrt; } }); +var toBigInt_js_1 = require("./toBigInt.js"); +Object.defineProperty(exports, "nToBigInt", { enumerable: true, get: function () { return toBigInt_js_1.nToBigInt; } }); +var toHex_js_1 = require("./toHex.js"); +Object.defineProperty(exports, "nToHex", { enumerable: true, get: function () { return toHex_js_1.nToHex; } }); +var toU8a_js_1 = require("./toU8a.js"); +Object.defineProperty(exports, "nToU8a", { enumerable: true, get: function () { return toU8a_js_1.nToU8a; } }); +tslib_1.__exportStar(require("./consts.js"), exports); diff --git a/packages/util/cjs/bi/min.d.ts b/packages/util/cjs/bi/min.d.ts new file mode 100644 index 0000000..662b41c --- /dev/null +++ b/packages/util/cjs/bi/min.d.ts @@ -0,0 +1,10 @@ +/** + * @name nMax + * @summary Finds and returns the highest value in an array of bigint. + */ +export declare const nMax: (...items: bigint[]) => bigint; +/** + * @name nMin + * @summary Finds and returns the lowest value in an array of bigint. + */ +export declare const nMin: (...items: bigint[]) => bigint; diff --git a/packages/util/cjs/bi/min.js b/packages/util/cjs/bi/min.js new file mode 100644 index 0000000..c61befc --- /dev/null +++ b/packages/util/cjs/bi/min.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.nMin = exports.nMax = void 0; +const helpers_js_1 = require("./helpers.js"); +/** + * @name nMax + * @summary Finds and returns the highest value in an array of bigint. + */ +exports.nMax = (0, helpers_js_1.createCmp)((a, b) => a > b); +/** + * @name nMin + * @summary Finds and returns the lowest value in an array of bigint. + */ +exports.nMin = (0, helpers_js_1.createCmp)((a, b) => a < b); diff --git a/packages/util/cjs/bi/sqrt.d.ts b/packages/util/cjs/bi/sqrt.d.ts new file mode 100644 index 0000000..c9b5b2e --- /dev/null +++ b/packages/util/cjs/bi/sqrt.d.ts @@ -0,0 +1,7 @@ +import type { BN } from '../bn/index.js'; +import type { ToBigInt, ToBn } from '../types.js'; +/** + * @name nSqrt + * @summary Calculates the integer square root of a bigint + */ +export declare function nSqrt(value: ExtToBn | BN | bigint | string | number | null): bigint; diff --git a/packages/util/cjs/bi/sqrt.js b/packages/util/cjs/bi/sqrt.js new file mode 100644 index 0000000..8bcffdd --- /dev/null +++ b/packages/util/cjs/bi/sqrt.js @@ -0,0 +1,32 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.nSqrt = nSqrt; +const x_bigint_1 = require("@pezkuwi/x-bigint"); +const consts_js_1 = require("./consts.js"); +const toBigInt_js_1 = require("./toBigInt.js"); +/** + * @name nSqrt + * @summary Calculates the integer square root of a bigint + */ +function nSqrt(value) { + const n = (0, toBigInt_js_1.nToBigInt)(value); + if (n < consts_js_1._0n) { + throw new Error('square root of negative numbers is not supported'); + } + // https://stackoverflow.com/questions/53683995/javascript-big-integer-square-root/ + // shortcut <= 2^53 - 1 to use the JS utils + if (n <= consts_js_1._2pow53n) { + // ~~ is more performant that Math.floor + return (0, x_bigint_1.BigInt)(~~Math.sqrt(Number(n))); + } + // Use sqrt(MAX_SAFE_INTEGER) as starting point. since we already know the + // output will be larger than this, we expect this to be a safe start + let x0 = consts_js_1._sqrt2pow53n; + while (true) { + const x1 = ((n / x0) + x0) >> consts_js_1._1n; + if (x0 === x1 || (x0 === (x1 - consts_js_1._1n))) { + return x0; + } + x0 = x1; + } +} diff --git a/packages/util/cjs/bi/toBigInt.d.ts b/packages/util/cjs/bi/toBigInt.d.ts new file mode 100644 index 0000000..c254d26 --- /dev/null +++ b/packages/util/cjs/bi/toBigInt.d.ts @@ -0,0 +1,7 @@ +import type { BN } from '../bn/bn.js'; +import type { ToBigInt, ToBn } from '../types.js'; +/** + * @name nToBigInt + * @summary Creates a bigInt value from a BN, bigint, string (base 10 or hex) or number input. + */ +export declare function nToBigInt(value?: ExtToBn | BN | bigint | string | number | null): bigint; diff --git a/packages/util/cjs/bi/toBigInt.js b/packages/util/cjs/bi/toBigInt.js new file mode 100644 index 0000000..5a4af92 --- /dev/null +++ b/packages/util/cjs/bi/toBigInt.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.nToBigInt = nToBigInt; +const x_bigint_1 = require("@pezkuwi/x-bigint"); +const toBigInt_js_1 = require("../hex/toBigInt.js"); +const bn_js_1 = require("../is/bn.js"); +const hex_js_1 = require("../is/hex.js"); +const toBigInt_js_2 = require("../is/toBigInt.js"); +const toBn_js_1 = require("../is/toBn.js"); +/** + * @name nToBigInt + * @summary Creates a bigInt value from a BN, bigint, string (base 10 or hex) or number input. + */ +function nToBigInt(value) { + return typeof value === 'bigint' + ? value + : !value + ? (0, x_bigint_1.BigInt)(0) + : (0, hex_js_1.isHex)(value) + ? (0, toBigInt_js_1.hexToBigInt)(value.toString()) + : (0, bn_js_1.isBn)(value) + ? (0, x_bigint_1.BigInt)(value.toString()) + : (0, toBigInt_js_2.isToBigInt)(value) + ? value.toBigInt() + : (0, toBn_js_1.isToBn)(value) + ? (0, x_bigint_1.BigInt)(value.toBn().toString()) + : (0, x_bigint_1.BigInt)(value); +} diff --git a/packages/util/cjs/bi/toHex.d.ts b/packages/util/cjs/bi/toHex.d.ts new file mode 100644 index 0000000..7ccfc0e --- /dev/null +++ b/packages/util/cjs/bi/toHex.d.ts @@ -0,0 +1,7 @@ +import type { BN } from '../bn/bn.js'; +import type { HexString, NumberOptions, ToBigInt, ToBn } from '../types.js'; +/** + * @name nToHex + * @summary Creates a hex value from a bigint object. + */ +export declare function nToHex(value?: ExtToBn | BN | bigint | number | null, { bitLength, isLe, isNegative }?: NumberOptions): HexString; diff --git a/packages/util/cjs/bi/toHex.js b/packages/util/cjs/bi/toHex.js new file mode 100644 index 0000000..a14ee37 --- /dev/null +++ b/packages/util/cjs/bi/toHex.js @@ -0,0 +1,12 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.nToHex = nToHex; +const index_js_1 = require("../u8a/index.js"); +const toU8a_js_1 = require("./toU8a.js"); +/** + * @name nToHex + * @summary Creates a hex value from a bigint object. + */ +function nToHex(value, { bitLength = -1, isLe = false, isNegative = false } = {}) { + return (0, index_js_1.u8aToHex)((0, toU8a_js_1.nToU8a)(value || 0, { bitLength, isLe, isNegative })); +} diff --git a/packages/util/cjs/bi/toU8a.d.ts b/packages/util/cjs/bi/toU8a.d.ts new file mode 100644 index 0000000..b75234a --- /dev/null +++ b/packages/util/cjs/bi/toU8a.d.ts @@ -0,0 +1,7 @@ +import type { BN } from '../bn/bn.js'; +import type { NumberOptions, ToBigInt, ToBn } from '../types.js'; +/** + * @name nToU8a + * @summary Creates a Uint8Array object from a bigint. + */ +export declare function nToU8a(value?: ExtToBn | BN | bigint | number | null, { bitLength, isLe, isNegative }?: NumberOptions): Uint8Array; diff --git a/packages/util/cjs/bi/toU8a.js b/packages/util/cjs/bi/toU8a.js new file mode 100644 index 0000000..835327b --- /dev/null +++ b/packages/util/cjs/bi/toU8a.js @@ -0,0 +1,52 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.nToU8a = nToU8a; +const x_bigint_1 = require("@pezkuwi/x-bigint"); +const consts_js_1 = require("./consts.js"); +const toBigInt_js_1 = require("./toBigInt.js"); +const DIV = (0, x_bigint_1.BigInt)(256); +const NEG_MASK = (0, x_bigint_1.BigInt)(0xff); +function toU8a(value, isLe, isNegative) { + const arr = []; + const withSigned = isNegative && (value < consts_js_1._0n); + if (withSigned) { + value = (value + consts_js_1._1n) * -consts_js_1._1n; + } + while (value !== consts_js_1._0n) { + const mod = value % DIV; + const val = Number(withSigned + ? mod ^ NEG_MASK + : mod); + if (isLe) { + arr.push(val); + } + else { + arr.unshift(val); + } + value = (value - mod) / DIV; + } + return Uint8Array.from(arr); +} +/** + * @name nToU8a + * @summary Creates a Uint8Array object from a bigint. + */ +function nToU8a(value, { bitLength = -1, isLe = true, isNegative = false } = {}) { + const valueBi = (0, toBigInt_js_1.nToBigInt)(value); + if (valueBi === consts_js_1._0n) { + return bitLength === -1 + ? new Uint8Array(1) + : new Uint8Array(Math.ceil((bitLength || 0) / 8)); + } + const u8a = toU8a(valueBi, isLe, isNegative); + if (bitLength === -1) { + return u8a; + } + const byteLength = Math.ceil((bitLength || 0) / 8); + const output = new Uint8Array(byteLength); + if (isNegative) { + output.fill(0xff); + } + output.set(u8a, isLe ? 0 : byteLength - u8a.length); + return output; +} diff --git a/packages/util/cjs/bn/bn.d.ts b/packages/util/cjs/bn/bn.d.ts new file mode 100644 index 0000000..a529f10 --- /dev/null +++ b/packages/util/cjs/bn/bn.d.ts @@ -0,0 +1,2 @@ +import BN from 'bn.js'; +export { BN }; diff --git a/packages/util/cjs/bn/bn.js b/packages/util/cjs/bn/bn.js new file mode 100644 index 0000000..0292bbc --- /dev/null +++ b/packages/util/cjs/bn/bn.js @@ -0,0 +1,6 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BN = void 0; +const tslib_1 = require("tslib"); +const bn_js_1 = tslib_1.__importDefault(require("bn.js")); +exports.BN = bn_js_1.default; diff --git a/packages/util/cjs/bn/consts.d.ts b/packages/util/cjs/bn/consts.d.ts new file mode 100644 index 0000000..2e9f7e3 --- /dev/null +++ b/packages/util/cjs/bn/consts.d.ts @@ -0,0 +1,91 @@ +import { BN } from './bn.js'; +/** + * @name BN_ZERO + * @summary BN constant for 0. + */ +export declare const BN_ZERO: BN; +/** + * @name BN_ONE + * @summary BN constant for 1. + */ +export declare const BN_ONE: BN; +/** + * @name BN_TWO + * @summary BN constant for 2. + */ +export declare const BN_TWO: BN; +/** + * @name BN_THREE + * @summary BN constant for 3. + */ +export declare const BN_THREE: BN; +/** + * @name BN_FOUR + * @summary BN constant for 4. + */ +export declare const BN_FOUR: BN; +/** + * @name BN_FIVE + * @summary BN constant for 5. + */ +export declare const BN_FIVE: BN; +/** + * @name BN_SIX + * @summary BN constant for 6. + */ +export declare const BN_SIX: BN; +/** + * @name BN_SEVEN + * @summary BN constant for 7. + */ +export declare const BN_SEVEN: BN; +/** + * @name BN_EIGHT + * @summary BN constant for 8. + */ +export declare const BN_EIGHT: BN; +/** + * @name BN_NINE + * @summary BN constant for 9. + */ +export declare const BN_NINE: BN; +/** + * @name BN_TEN + * @summary BN constant for 10. + */ +export declare const BN_TEN: BN; +/** + * @name BN_HUNDRED + * @summary BN constant for 100. + */ +export declare const BN_HUNDRED: BN; +/** + * @name BN_THOUSAND + * @summary BN constant for 1,000. + */ +export declare const BN_THOUSAND: BN; +/** + * @name BN_MILLION + * @summary BN constant for 1,000,000. + */ +export declare const BN_MILLION: BN; +/** + * @name BN_BILLION + * @summary BN constant for 1,000,000,000. + */ +export declare const BN_BILLION: BN; +/** + * @name BN_QUINTILL + * @summary BN constant for 1,000,000,000,000,000,000. + */ +export declare const BN_QUINTILL: BN; +/** + * @name BN_MAX_INTEGER + * @summary BN constant for MAX_SAFE_INTEGER + */ +export declare const BN_MAX_INTEGER: BN; +/** + * @name BN_SQRT_MAX_INTEGER + * @summary BN constant for Math.sqrt(MAX_SAFE_INTEGER) + */ +export declare const BN_SQRT_MAX_INTEGER: BN; diff --git a/packages/util/cjs/bn/consts.js b/packages/util/cjs/bn/consts.js new file mode 100644 index 0000000..a797e68 --- /dev/null +++ b/packages/util/cjs/bn/consts.js @@ -0,0 +1,94 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BN_SQRT_MAX_INTEGER = exports.BN_MAX_INTEGER = exports.BN_QUINTILL = exports.BN_BILLION = exports.BN_MILLION = exports.BN_THOUSAND = exports.BN_HUNDRED = exports.BN_TEN = exports.BN_NINE = exports.BN_EIGHT = exports.BN_SEVEN = exports.BN_SIX = exports.BN_FIVE = exports.BN_FOUR = exports.BN_THREE = exports.BN_TWO = exports.BN_ONE = exports.BN_ZERO = void 0; +const bn_js_1 = require("./bn.js"); +/** + * @name BN_ZERO + * @summary BN constant for 0. + */ +exports.BN_ZERO = new bn_js_1.BN(0); +/** + * @name BN_ONE + * @summary BN constant for 1. + */ +exports.BN_ONE = new bn_js_1.BN(1); +/** + * @name BN_TWO + * @summary BN constant for 2. + */ +exports.BN_TWO = new bn_js_1.BN(2); +/** + * @name BN_THREE + * @summary BN constant for 3. + */ +exports.BN_THREE = new bn_js_1.BN(3); +/** + * @name BN_FOUR + * @summary BN constant for 4. + */ +exports.BN_FOUR = new bn_js_1.BN(4); +/** + * @name BN_FIVE + * @summary BN constant for 5. + */ +exports.BN_FIVE = new bn_js_1.BN(5); +/** + * @name BN_SIX + * @summary BN constant for 6. + */ +exports.BN_SIX = new bn_js_1.BN(6); +/** + * @name BN_SEVEN + * @summary BN constant for 7. + */ +exports.BN_SEVEN = new bn_js_1.BN(7); +/** + * @name BN_EIGHT + * @summary BN constant for 8. + */ +exports.BN_EIGHT = new bn_js_1.BN(8); +/** + * @name BN_NINE + * @summary BN constant for 9. + */ +exports.BN_NINE = new bn_js_1.BN(9); +/** + * @name BN_TEN + * @summary BN constant for 10. + */ +exports.BN_TEN = new bn_js_1.BN(10); +/** + * @name BN_HUNDRED + * @summary BN constant for 100. + */ +exports.BN_HUNDRED = new bn_js_1.BN(100); +/** + * @name BN_THOUSAND + * @summary BN constant for 1,000. + */ +exports.BN_THOUSAND = new bn_js_1.BN(1_000); +/** + * @name BN_MILLION + * @summary BN constant for 1,000,000. + */ +exports.BN_MILLION = new bn_js_1.BN(1_000_000); +/** + * @name BN_BILLION + * @summary BN constant for 1,000,000,000. + */ +exports.BN_BILLION = new bn_js_1.BN(1_000_000_000); +/** + * @name BN_QUINTILL + * @summary BN constant for 1,000,000,000,000,000,000. + */ +exports.BN_QUINTILL = exports.BN_BILLION.mul(exports.BN_BILLION); +/** + * @name BN_MAX_INTEGER + * @summary BN constant for MAX_SAFE_INTEGER + */ +exports.BN_MAX_INTEGER = new bn_js_1.BN(Number.MAX_SAFE_INTEGER); +/** + * @name BN_SQRT_MAX_INTEGER + * @summary BN constant for Math.sqrt(MAX_SAFE_INTEGER) + */ +exports.BN_SQRT_MAX_INTEGER = new bn_js_1.BN(94906265); diff --git a/packages/util/cjs/bn/fromHex.d.ts b/packages/util/cjs/bn/fromHex.d.ts new file mode 100644 index 0000000..36d1d71 --- /dev/null +++ b/packages/util/cjs/bn/fromHex.d.ts @@ -0,0 +1 @@ +export { hexToBn as bnFromHex } from '../hex/toBn.js'; diff --git a/packages/util/cjs/bn/fromHex.js b/packages/util/cjs/bn/fromHex.js new file mode 100644 index 0000000..b424e07 --- /dev/null +++ b/packages/util/cjs/bn/fromHex.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.bnFromHex = void 0; +var toBn_js_1 = require("../hex/toBn.js"); +Object.defineProperty(exports, "bnFromHex", { enumerable: true, get: function () { return toBn_js_1.hexToBn; } }); diff --git a/packages/util/cjs/bn/index.d.ts b/packages/util/cjs/bn/index.d.ts new file mode 100644 index 0000000..27211eb --- /dev/null +++ b/packages/util/cjs/bn/index.d.ts @@ -0,0 +1,11 @@ +/** + * @summary Utility methods to convert to and from `BN` objects + */ +export { BN } from './bn.js'; +export { bnFromHex } from './fromHex.js'; +export { bnMax, bnMin } from './min.js'; +export { bnSqrt } from './sqrt.js'; +export { bnToBn } from './toBn.js'; +export { bnToHex } from './toHex.js'; +export { bnToU8a } from './toU8a.js'; +export * from './consts.js'; diff --git a/packages/util/cjs/bn/index.js b/packages/util/cjs/bn/index.js new file mode 100644 index 0000000..231b98e --- /dev/null +++ b/packages/util/cjs/bn/index.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.bnToU8a = exports.bnToHex = exports.bnToBn = exports.bnSqrt = exports.bnMin = exports.bnMax = exports.bnFromHex = exports.BN = void 0; +const tslib_1 = require("tslib"); +/** + * @summary Utility methods to convert to and from `BN` objects + */ +var bn_js_1 = require("./bn.js"); +Object.defineProperty(exports, "BN", { enumerable: true, get: function () { return bn_js_1.BN; } }); +var fromHex_js_1 = require("./fromHex.js"); +Object.defineProperty(exports, "bnFromHex", { enumerable: true, get: function () { return fromHex_js_1.bnFromHex; } }); +var min_js_1 = require("./min.js"); +Object.defineProperty(exports, "bnMax", { enumerable: true, get: function () { return min_js_1.bnMax; } }); +Object.defineProperty(exports, "bnMin", { enumerable: true, get: function () { return min_js_1.bnMin; } }); +var sqrt_js_1 = require("./sqrt.js"); +Object.defineProperty(exports, "bnSqrt", { enumerable: true, get: function () { return sqrt_js_1.bnSqrt; } }); +var toBn_js_1 = require("./toBn.js"); +Object.defineProperty(exports, "bnToBn", { enumerable: true, get: function () { return toBn_js_1.bnToBn; } }); +var toHex_js_1 = require("./toHex.js"); +Object.defineProperty(exports, "bnToHex", { enumerable: true, get: function () { return toHex_js_1.bnToHex; } }); +var toU8a_js_1 = require("./toU8a.js"); +Object.defineProperty(exports, "bnToU8a", { enumerable: true, get: function () { return toU8a_js_1.bnToU8a; } }); +tslib_1.__exportStar(require("./consts.js"), exports); diff --git a/packages/util/cjs/bn/min.d.ts b/packages/util/cjs/bn/min.d.ts new file mode 100644 index 0000000..c0260d4 --- /dev/null +++ b/packages/util/cjs/bn/min.d.ts @@ -0,0 +1,29 @@ +import type { BN } from './bn.js'; +/** + * @name bnMax + * @summary Finds and returns the highest value in an array of BNs. + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnMax } from '@pezkuwi/util'; + * + * bnMax([new BN(1), new BN(3), new BN(2)]).toString(); // => '3' + * ``` + */ +export declare const bnMax: (...items: BN[]) => BN; +/** + * @name bnMin + * @summary Finds and returns the smallest value in an array of BNs. + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnMin } from '@pezkuwi/util'; + * + * bnMin([new BN(1), new BN(3), new BN(2)]).toString(); // => '1' + * ``` + */ +export declare const bnMin: (...items: BN[]) => BN; diff --git a/packages/util/cjs/bn/min.js b/packages/util/cjs/bn/min.js new file mode 100644 index 0000000..879098b --- /dev/null +++ b/packages/util/cjs/bn/min.js @@ -0,0 +1,32 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.bnMin = exports.bnMax = void 0; +const helpers_js_1 = require("../bi/helpers.js"); +/** + * @name bnMax + * @summary Finds and returns the highest value in an array of BNs. + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnMax } from '@pezkuwi/util'; + * + * bnMax([new BN(1), new BN(3), new BN(2)]).toString(); // => '3' + * ``` + */ +exports.bnMax = (0, helpers_js_1.createCmp)((a, b) => a.gt(b)); +/** + * @name bnMin + * @summary Finds and returns the smallest value in an array of BNs. + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnMin } from '@pezkuwi/util'; + * + * bnMin([new BN(1), new BN(3), new BN(2)]).toString(); // => '1' + * ``` + */ +exports.bnMin = (0, helpers_js_1.createCmp)((a, b) => a.lt(b)); diff --git a/packages/util/cjs/bn/sqrt.d.ts b/packages/util/cjs/bn/sqrt.d.ts new file mode 100644 index 0000000..484a35a --- /dev/null +++ b/packages/util/cjs/bn/sqrt.d.ts @@ -0,0 +1,16 @@ +import type { ToBn } from '../types.js'; +import { BN } from './bn.js'; +/** + * @name bnSqrt + * @summary Calculates the integer square root of a BN + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnSqrt } from '@pezkuwi/util'; + * + * bnSqrt(new BN(16)).toString(); // => '4' + * ``` + */ +export declare function bnSqrt(value: ExtToBn | BN | bigint | string | number | null): BN; diff --git a/packages/util/cjs/bn/sqrt.js b/packages/util/cjs/bn/sqrt.js new file mode 100644 index 0000000..ec57792 --- /dev/null +++ b/packages/util/cjs/bn/sqrt.js @@ -0,0 +1,41 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.bnSqrt = bnSqrt; +const bn_js_1 = require("./bn.js"); +const consts_js_1 = require("./consts.js"); +const toBn_js_1 = require("./toBn.js"); +/** + * @name bnSqrt + * @summary Calculates the integer square root of a BN + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnSqrt } from '@pezkuwi/util'; + * + * bnSqrt(new BN(16)).toString(); // => '4' + * ``` + */ +function bnSqrt(value) { + const n = (0, toBn_js_1.bnToBn)(value); + if (n.isNeg()) { + throw new Error('square root of negative numbers is not supported'); + } + // https://stackoverflow.com/questions/53683995/javascript-big-integer-square-root/ + // shortcut <= 2^53 - 1 to use the JS utils + if (n.lte(consts_js_1.BN_MAX_INTEGER)) { + // ~~ More performant version of Math.floor + return new bn_js_1.BN(~~Math.sqrt(n.toNumber())); + } + // Use sqrt(MAX_SAFE_INTEGER) as starting point. since we already know the + // output will be larger than this, we expect this to be a safe start + let x0 = consts_js_1.BN_SQRT_MAX_INTEGER.clone(); + while (true) { + const x1 = n.div(x0).iadd(x0).ishrn(1); + if (x0.eq(x1) || x0.eq(x1.sub(consts_js_1.BN_ONE))) { + return x0; + } + x0 = x1; + } +} diff --git a/packages/util/cjs/bn/toBn.d.ts b/packages/util/cjs/bn/toBn.d.ts new file mode 100644 index 0000000..47d61ab --- /dev/null +++ b/packages/util/cjs/bn/toBn.d.ts @@ -0,0 +1,19 @@ +import type { ToBigInt, ToBn } from '../types.js'; +import { BN } from './bn.js'; +/** + * @name bnToBn + * @summary Creates a BN value from a BN, bigint, string (base 10 or hex) or number input. + * @description + * `null` inputs returns a `0x0` result, BN values returns the value, numbers returns a BN representation. + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnToBn } from '@pezkuwi/util'; + * + * bnToBn(0x1234); // => BN(0x1234) + * bnToBn(new BN(0x1234)); // => BN(0x1234) + * ``` + */ +export declare function bnToBn(value?: ExtToBn | BN | bigint | string | number | null): BN; diff --git a/packages/util/cjs/bn/toBn.js b/packages/util/cjs/bn/toBn.js new file mode 100644 index 0000000..e7da348 --- /dev/null +++ b/packages/util/cjs/bn/toBn.js @@ -0,0 +1,40 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.bnToBn = bnToBn; +const toBn_js_1 = require("../hex/toBn.js"); +const bigInt_js_1 = require("../is/bigInt.js"); +const hex_js_1 = require("../is/hex.js"); +const toBigInt_js_1 = require("../is/toBigInt.js"); +const toBn_js_2 = require("../is/toBn.js"); +const bn_js_1 = require("./bn.js"); +/** + * @name bnToBn + * @summary Creates a BN value from a BN, bigint, string (base 10 or hex) or number input. + * @description + * `null` inputs returns a `0x0` result, BN values returns the value, numbers returns a BN representation. + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnToBn } from '@pezkuwi/util'; + * + * bnToBn(0x1234); // => BN(0x1234) + * bnToBn(new BN(0x1234)); // => BN(0x1234) + * ``` + */ +function bnToBn(value) { + return value + ? bn_js_1.BN.isBN(value) + ? value + : (0, hex_js_1.isHex)(value) + ? (0, toBn_js_1.hexToBn)(value.toString()) + : (0, bigInt_js_1.isBigInt)(value) + ? new bn_js_1.BN(value.toString()) + : (0, toBn_js_2.isToBn)(value) + ? value.toBn() + : (0, toBigInt_js_1.isToBigInt)(value) + ? new bn_js_1.BN(value.toBigInt().toString()) + : new bn_js_1.BN(value) + : new bn_js_1.BN(0); +} diff --git a/packages/util/cjs/bn/toHex.d.ts b/packages/util/cjs/bn/toHex.d.ts new file mode 100644 index 0000000..6d1ca8d --- /dev/null +++ b/packages/util/cjs/bn/toHex.d.ts @@ -0,0 +1,18 @@ +import type { HexString, NumberOptions, ToBn } from '../types.js'; +import type { BN } from './bn.js'; +/** + * @name bnToHex + * @summary Creates a hex value from a BN.js bignumber object. + * @description + * `null` inputs returns a `0x` result, BN values return the actual value as a `0x` prefixed hex value. Anything that is not a BN object throws an error. With `bitLength` set, it fixes the number to the specified length. + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnToHex } from '@pezkuwi/util'; + * + * bnToHex(new BN(0x123456)); // => '0x123456' + * ``` + */ +export declare function bnToHex(value?: ExtToBn | BN | bigint | number | null, { bitLength, isLe, isNegative }?: NumberOptions): HexString; diff --git a/packages/util/cjs/bn/toHex.js b/packages/util/cjs/bn/toHex.js new file mode 100644 index 0000000..b7ea839 --- /dev/null +++ b/packages/util/cjs/bn/toHex.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.bnToHex = bnToHex; +const index_js_1 = require("../u8a/index.js"); +const toU8a_js_1 = require("./toU8a.js"); +/** + * @name bnToHex + * @summary Creates a hex value from a BN.js bignumber object. + * @description + * `null` inputs returns a `0x` result, BN values return the actual value as a `0x` prefixed hex value. Anything that is not a BN object throws an error. With `bitLength` set, it fixes the number to the specified length. + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { bnToHex } from '@pezkuwi/util'; + * + * bnToHex(new BN(0x123456)); // => '0x123456' + * ``` + */ +function bnToHex(value, { bitLength = -1, isLe = false, isNegative = false } = {}) { + return (0, index_js_1.u8aToHex)((0, toU8a_js_1.bnToU8a)(value, { bitLength, isLe, isNegative })); +} diff --git a/packages/util/cjs/bn/toU8a.d.ts b/packages/util/cjs/bn/toU8a.d.ts new file mode 100644 index 0000000..49abc0a --- /dev/null +++ b/packages/util/cjs/bn/toU8a.d.ts @@ -0,0 +1,17 @@ +import type { NumberOptions, ToBn } from '../types.js'; +import type { BN } from './bn.js'; +/** + * @name bnToU8a + * @summary Creates a Uint8Array object from a BN. + * @description + * `null`/`undefined`/`NaN` inputs returns an empty `Uint8Array` result. `BN` input values return the actual bytes value converted to a `Uint8Array`. Optionally convert using little-endian format if `isLE` is set. + * @example + *
+ * + * ```javascript + * import { bnToU8a } from '@pezkuwi/util'; + * + * bnToU8a(new BN(0x1234)); // => [0x12, 0x34] + * ``` + */ +export declare function bnToU8a(value?: ExtToBn | BN | bigint | number | null, { bitLength, isLe, isNegative }?: NumberOptions): Uint8Array; diff --git a/packages/util/cjs/bn/toU8a.js b/packages/util/cjs/bn/toU8a.js new file mode 100644 index 0000000..2553067 --- /dev/null +++ b/packages/util/cjs/bn/toU8a.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.bnToU8a = bnToU8a; +const toBn_js_1 = require("./toBn.js"); +const DEFAULT_OPTS = { bitLength: -1, isLe: true, isNegative: false }; +/** + * @name bnToU8a + * @summary Creates a Uint8Array object from a BN. + * @description + * `null`/`undefined`/`NaN` inputs returns an empty `Uint8Array` result. `BN` input values return the actual bytes value converted to a `Uint8Array`. Optionally convert using little-endian format if `isLE` is set. + * @example + *
+ * + * ```javascript + * import { bnToU8a } from '@pezkuwi/util'; + * + * bnToU8a(new BN(0x1234)); // => [0x12, 0x34] + * ``` + */ +function bnToU8a(value, { bitLength = -1, isLe = true, isNegative = false } = DEFAULT_OPTS) { + const valueBn = (0, toBn_js_1.bnToBn)(value); + const byteLength = bitLength === -1 + ? Math.ceil(valueBn.bitLength() / 8) + : Math.ceil((bitLength || 0) / 8); + if (!value) { + return bitLength === -1 + ? new Uint8Array(1) + : new Uint8Array(byteLength); + } + const output = new Uint8Array(byteLength); + const bn = isNegative + ? valueBn.toTwos(byteLength * 8) + : valueBn; + output.set(bn.toArray(isLe ? 'le' : 'be', byteLength), 0); + return output; +} diff --git a/packages/util/cjs/buffer/index.d.ts b/packages/util/cjs/buffer/index.d.ts new file mode 100644 index 0000000..9554f62 --- /dev/null +++ b/packages/util/cjs/buffer/index.d.ts @@ -0,0 +1,4 @@ +/** + * @summary Utility methods to convert to and from `Buffer` objects + */ +export { bufferToU8a } from './toU8a.js'; diff --git a/packages/util/cjs/buffer/index.js b/packages/util/cjs/buffer/index.js new file mode 100644 index 0000000..9d0cbdf --- /dev/null +++ b/packages/util/cjs/buffer/index.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.bufferToU8a = void 0; +/** + * @summary Utility methods to convert to and from `Buffer` objects + */ +var toU8a_js_1 = require("./toU8a.js"); +Object.defineProperty(exports, "bufferToU8a", { enumerable: true, get: function () { return toU8a_js_1.bufferToU8a; } }); diff --git a/packages/util/cjs/buffer/toU8a.d.ts b/packages/util/cjs/buffer/toU8a.d.ts new file mode 100644 index 0000000..4ff66da --- /dev/null +++ b/packages/util/cjs/buffer/toU8a.d.ts @@ -0,0 +1,15 @@ +/** + * @name bufferToU8a + * @summary Creates a Uint8Array value from a Buffer object. + * @description + * `null` inputs returns an empty result, `Buffer` values return the actual value as a `Uint8Array`. Anything that is not a `Buffer` object throws an error. + * @example + *
+ * + * ```javascript + * import { bufferToU8a } from '@pezkuwi/util'; + * + * bufferToU8a(Buffer.from([1, 2, 3])); + * ``` + */ +export declare function bufferToU8a(buffer?: Uint8Array | number[] | null): Uint8Array; diff --git a/packages/util/cjs/buffer/toU8a.js b/packages/util/cjs/buffer/toU8a.js new file mode 100644 index 0000000..55f63bd --- /dev/null +++ b/packages/util/cjs/buffer/toU8a.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.bufferToU8a = bufferToU8a; +/** + * @name bufferToU8a + * @summary Creates a Uint8Array value from a Buffer object. + * @description + * `null` inputs returns an empty result, `Buffer` values return the actual value as a `Uint8Array`. Anything that is not a `Buffer` object throws an error. + * @example + *
+ * + * ```javascript + * import { bufferToU8a } from '@pezkuwi/util'; + * + * bufferToU8a(Buffer.from([1, 2, 3])); + * ``` + */ +function bufferToU8a(buffer) { + return new Uint8Array(buffer || []); +} diff --git a/packages/util/cjs/bundle.d.ts b/packages/util/cjs/bundle.d.ts new file mode 100644 index 0000000..a0ef069 --- /dev/null +++ b/packages/util/cjs/bundle.d.ts @@ -0,0 +1,28 @@ +/** + * @summary Utility methods for this package are split into groups + */ +export { packageInfo } from './packageInfo.js'; +export * from './array/index.js'; +export * from './assert.js'; +export * from './bi/index.js'; +export * from './bn/index.js'; +export * from './buffer/index.js'; +export * from './compact/index.js'; +export * from './detectPackage.js'; +export * from './extractTime.js'; +export * from './float/index.js'; +export * from './format/index.js'; +export * from './has.js'; +export * from './hex/index.js'; +export * from './is/index.js'; +export * from './lazy.js'; +export * from './logger.js'; +export * from './memoize.js'; +export * from './nextTick.js'; +export * from './noop.js'; +export * from './number/index.js'; +export * from './object/index.js'; +export * from './promisify.js'; +export * from './string/index.js'; +export * from './stringify.js'; +export * from './u8a/index.js'; diff --git a/packages/util/cjs/bundle.js b/packages/util/cjs/bundle.js new file mode 100644 index 0000000..4b339f0 --- /dev/null +++ b/packages/util/cjs/bundle.js @@ -0,0 +1,33 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +const tslib_1 = require("tslib"); +/** + * @summary Utility methods for this package are split into groups + */ +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +tslib_1.__exportStar(require("./array/index.js"), exports); +tslib_1.__exportStar(require("./assert.js"), exports); +tslib_1.__exportStar(require("./bi/index.js"), exports); +tslib_1.__exportStar(require("./bn/index.js"), exports); +tslib_1.__exportStar(require("./buffer/index.js"), exports); +tslib_1.__exportStar(require("./compact/index.js"), exports); +tslib_1.__exportStar(require("./detectPackage.js"), exports); +tslib_1.__exportStar(require("./extractTime.js"), exports); +tslib_1.__exportStar(require("./float/index.js"), exports); +tslib_1.__exportStar(require("./format/index.js"), exports); +tslib_1.__exportStar(require("./has.js"), exports); +tslib_1.__exportStar(require("./hex/index.js"), exports); +tslib_1.__exportStar(require("./is/index.js"), exports); +tslib_1.__exportStar(require("./lazy.js"), exports); +tslib_1.__exportStar(require("./logger.js"), exports); +tslib_1.__exportStar(require("./memoize.js"), exports); +tslib_1.__exportStar(require("./nextTick.js"), exports); +tslib_1.__exportStar(require("./noop.js"), exports); +tslib_1.__exportStar(require("./number/index.js"), exports); +tslib_1.__exportStar(require("./object/index.js"), exports); +tslib_1.__exportStar(require("./promisify.js"), exports); +tslib_1.__exportStar(require("./string/index.js"), exports); +tslib_1.__exportStar(require("./stringify.js"), exports); +tslib_1.__exportStar(require("./u8a/index.js"), exports); diff --git a/packages/util/cjs/compact/addLength.d.ts b/packages/util/cjs/compact/addLength.d.ts new file mode 100644 index 0000000..3a1a5f0 --- /dev/null +++ b/packages/util/cjs/compact/addLength.d.ts @@ -0,0 +1,13 @@ +/** + * @name compactAddLength + * @description Adds a length prefix to the input value + * @example + *
+ * + * ```javascript + * import { compactAddLength } from '@pezkuwi/util'; + * + * console.log(compactAddLength(new Uint8Array([0xde, 0xad, 0xbe, 0xef]))); // Uint8Array([4 << 2, 0xde, 0xad, 0xbe, 0xef]) + * ``` + */ +export declare function compactAddLength(input: Uint8Array): Uint8Array; diff --git a/packages/util/cjs/compact/addLength.js b/packages/util/cjs/compact/addLength.js new file mode 100644 index 0000000..b027e46 --- /dev/null +++ b/packages/util/cjs/compact/addLength.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.compactAddLength = compactAddLength; +const index_js_1 = require("../u8a/index.js"); +const toU8a_js_1 = require("./toU8a.js"); +/** + * @name compactAddLength + * @description Adds a length prefix to the input value + * @example + *
+ * + * ```javascript + * import { compactAddLength } from '@pezkuwi/util'; + * + * console.log(compactAddLength(new Uint8Array([0xde, 0xad, 0xbe, 0xef]))); // Uint8Array([4 << 2, 0xde, 0xad, 0xbe, 0xef]) + * ``` + */ +function compactAddLength(input) { + return (0, index_js_1.u8aConcatStrict)([ + (0, toU8a_js_1.compactToU8a)(input.length), + input + ]); +} diff --git a/packages/util/cjs/compact/defaults.d.ts b/packages/util/cjs/compact/defaults.d.ts new file mode 100644 index 0000000..271842c --- /dev/null +++ b/packages/util/cjs/compact/defaults.d.ts @@ -0,0 +1,3 @@ +import type { BitLength } from './types.js'; +/** @internal */ +export declare const DEFAULT_BITLENGTH: BitLength; diff --git a/packages/util/cjs/compact/defaults.js b/packages/util/cjs/compact/defaults.js new file mode 100644 index 0000000..befcff8 --- /dev/null +++ b/packages/util/cjs/compact/defaults.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DEFAULT_BITLENGTH = void 0; +/** @internal */ +exports.DEFAULT_BITLENGTH = 32; diff --git a/packages/util/cjs/compact/fromU8a.d.ts b/packages/util/cjs/compact/fromU8a.d.ts new file mode 100644 index 0000000..1c26b1b --- /dev/null +++ b/packages/util/cjs/compact/fromU8a.d.ts @@ -0,0 +1,22 @@ +import type { U8aLike } from '../types.js'; +import { BN } from '../bn/index.js'; +/** + * @name compactFromU8a + * @description Retrives the offset and encoded length from a compact-prefixed value + * @example + *
+ * + * ```javascript + * import { compactFromU8a } from '@pezkuwi/util'; + * + * const [offset, length] = compactFromU8a(new Uint8Array([254, 255, 3, 0])); + * + * console.log('value offset=', offset, 'length=', length); // 4, 0xffff + * ``` + */ +export declare function compactFromU8a(input: U8aLike): [number, BN]; +/** + * @name compactFromU8aLim + * @description A limited version of [[compactFromU8a]], accepting only Uint8Array inputs for values <= 48 bits + */ +export declare function compactFromU8aLim(u8a: Uint8Array): [number, number]; diff --git a/packages/util/cjs/compact/fromU8a.js b/packages/util/cjs/compact/fromU8a.js new file mode 100644 index 0000000..5a69b8c --- /dev/null +++ b/packages/util/cjs/compact/fromU8a.js @@ -0,0 +1,92 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.compactFromU8a = compactFromU8a; +exports.compactFromU8aLim = compactFromU8aLim; +const index_js_1 = require("../bn/index.js"); +const index_js_2 = require("../u8a/index.js"); +/** + * @name compactFromU8a + * @description Retrives the offset and encoded length from a compact-prefixed value + * @example + *
+ * + * ```javascript + * import { compactFromU8a } from '@pezkuwi/util'; + * + * const [offset, length] = compactFromU8a(new Uint8Array([254, 255, 3, 0])); + * + * console.log('value offset=', offset, 'length=', length); // 4, 0xffff + * ``` + */ +function compactFromU8a(input) { + const u8a = (0, index_js_2.u8aToU8a)(input); + // The u8a is manually converted here for 1, 2 & 4 lengths, it is 2x faster + // than doing an additional call to u8aToBn (as with variable length) + switch (u8a[0] & 0b11) { + case 0b00: + return [1, new index_js_1.BN(u8a[0] >>> 2)]; + case 0b01: + return [2, new index_js_1.BN((u8a[0] + (u8a[1] << 8)) >>> 2)]; + case 0b10: + // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to + // 32-bit, in the case where the top-most bit is set this yields a negative value + return [4, new index_js_1.BN((u8a[0] + (u8a[1] << 8) + (u8a[2] << 16) + (u8a[3] * 0x1_00_00_00)) >>> 2)]; + // 0b11 + default: { + // add 5 to shifted (4 for base length, 1 for this byte) + const offset = (u8a[0] >>> 2) + 5; + // we unroll the loop + switch (offset) { + // there still could be 4 bytes data, similar to 0b10 above (with offsets) + case 5: + // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to + // 32-bit, in the case where the top-most bit is set this yields a negative value + return [5, new index_js_1.BN(u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + (u8a[4] * 0x1_00_00_00))]; + case 6: + return [6, new index_js_1.BN(u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + ((u8a[4] + (u8a[5] << 8)) * 0x1_00_00_00))]; + // 6 bytes data is the maximum, 48 bits (56 would overflow) + case 7: + return [7, new index_js_1.BN(u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + ((u8a[4] + (u8a[5] << 8) + (u8a[6] << 16)) * 0x1_00_00_00))]; + // for anything else, use the non-unrolled version + default: + return [offset, (0, index_js_2.u8aToBn)(u8a.subarray(1, offset))]; + } + } + } +} +/** + * @name compactFromU8aLim + * @description A limited version of [[compactFromU8a]], accepting only Uint8Array inputs for values <= 48 bits + */ +function compactFromU8aLim(u8a) { + // The u8a is manually converted here for 1, 2 & 4 lengths, it is 2x faster + // than doing an additional call to u8aToBn (as with variable length) + switch (u8a[0] & 0b11) { + case 0b00: + return [1, u8a[0] >>> 2]; + case 0b01: + return [2, (u8a[0] + (u8a[1] << 8)) >>> 2]; + case 0b10: + // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to + // 32-bit, in the case where the top-most bit is set this yields a negative value + return [4, (u8a[0] + (u8a[1] << 8) + (u8a[2] << 16) + (u8a[3] * 0x1_00_00_00)) >>> 2]; + // 0b11 + default: { + // add 5 to shifted (4 for base length, 1 for this byte) + // we unroll the loop + switch ((u8a[0] >>> 2) + 5) { + // there still could be 4 bytes data, similar to 0b10 above (with offsets) + case 5: + return [5, u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + (u8a[4] * 0x1_00_00_00)]; + case 6: + return [6, u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + ((u8a[4] + (u8a[5] << 8)) * 0x1_00_00_00)]; + // 6 bytes data is the maximum, 48 bits (56 would overflow) + case 7: + return [7, u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + ((u8a[4] + (u8a[5] << 8) + (u8a[6] << 16)) * 0x1_00_00_00)]; + // for anything else, we are above the actual MAX_SAFE_INTEGER - bail out + default: + throw new Error('Compact input is > Number.MAX_SAFE_INTEGER'); + } + } + } +} diff --git a/packages/util/cjs/compact/index.d.ts b/packages/util/cjs/compact/index.d.ts new file mode 100644 index 0000000..5114102 --- /dev/null +++ b/packages/util/cjs/compact/index.d.ts @@ -0,0 +1,24 @@ +/** + * @description + * Encoding and decoding of parity-codec compact numbers. The codec is created + * to take up the least amount of space for a specific number. It performs the + * same function as Length, however differs in that it uses a variable number of + * bytes to do the actual encoding. From the Rust implementation for compact + * encoding: + * + * 0b00 00 00 00 / 00 00 00 00 / 00 00 00 00 / 00 00 00 00 + * (0 ... 2**6 - 1) (u8) + * xx xx xx 00 + * (2**6 ... 2**14 - 1) (u8, u16) low LH high + * yL yL yL 01 / yH yH yH yL + * (2**14 ... 2**30 - 1) (u16, u32) low LMMH high + * zL zL zL 10 / zM zM zM zL / zM zM zM zM / zH zH zH zM + * (2**30 ... 2**536 - 1) (u32, u64, u128, U256, U512, U520) straight LE-encoded + * nn nn nn 11 [ / zz zz zz zz ]{4 + n} + * + * Note: we use *LOW BITS* of the LSB in LE encoding to encode the 2 bit key. + */ +export { compactAddLength } from './addLength.js'; +export { compactFromU8a, compactFromU8aLim } from './fromU8a.js'; +export { compactStripLength } from './stripLength.js'; +export { compactToU8a } from './toU8a.js'; diff --git a/packages/util/cjs/compact/index.js b/packages/util/cjs/compact/index.js new file mode 100644 index 0000000..275e688 --- /dev/null +++ b/packages/util/cjs/compact/index.js @@ -0,0 +1,32 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.compactToU8a = exports.compactStripLength = exports.compactFromU8aLim = exports.compactFromU8a = exports.compactAddLength = void 0; +/** + * @description + * Encoding and decoding of parity-codec compact numbers. The codec is created + * to take up the least amount of space for a specific number. It performs the + * same function as Length, however differs in that it uses a variable number of + * bytes to do the actual encoding. From the Rust implementation for compact + * encoding: + * + * 0b00 00 00 00 / 00 00 00 00 / 00 00 00 00 / 00 00 00 00 + * (0 ... 2**6 - 1) (u8) + * xx xx xx 00 + * (2**6 ... 2**14 - 1) (u8, u16) low LH high + * yL yL yL 01 / yH yH yH yL + * (2**14 ... 2**30 - 1) (u16, u32) low LMMH high + * zL zL zL 10 / zM zM zM zL / zM zM zM zM / zH zH zH zM + * (2**30 ... 2**536 - 1) (u32, u64, u128, U256, U512, U520) straight LE-encoded + * nn nn nn 11 [ / zz zz zz zz ]{4 + n} + * + * Note: we use *LOW BITS* of the LSB in LE encoding to encode the 2 bit key. + */ +var addLength_js_1 = require("./addLength.js"); +Object.defineProperty(exports, "compactAddLength", { enumerable: true, get: function () { return addLength_js_1.compactAddLength; } }); +var fromU8a_js_1 = require("./fromU8a.js"); +Object.defineProperty(exports, "compactFromU8a", { enumerable: true, get: function () { return fromU8a_js_1.compactFromU8a; } }); +Object.defineProperty(exports, "compactFromU8aLim", { enumerable: true, get: function () { return fromU8a_js_1.compactFromU8aLim; } }); +var stripLength_js_1 = require("./stripLength.js"); +Object.defineProperty(exports, "compactStripLength", { enumerable: true, get: function () { return stripLength_js_1.compactStripLength; } }); +var toU8a_js_1 = require("./toU8a.js"); +Object.defineProperty(exports, "compactToU8a", { enumerable: true, get: function () { return toU8a_js_1.compactToU8a; } }); diff --git a/packages/util/cjs/compact/stripLength.d.ts b/packages/util/cjs/compact/stripLength.d.ts new file mode 100644 index 0000000..86dedec --- /dev/null +++ b/packages/util/cjs/compact/stripLength.d.ts @@ -0,0 +1,13 @@ +/** + * @name compactStripLength + * @description Removes the length prefix, returning both the total length (including the value + compact encoding) and the decoded value with the correct length + * @example + *
+ * + * ```javascript + * import { compactStripLength } from '@pezkuwi/util'; + * + * console.log(compactStripLength(new Uint8Array([2 << 2, 0xde, 0xad]))); // [2, Uint8Array[0xde, 0xad]] + * ``` + */ +export declare function compactStripLength(input: Uint8Array): [number, Uint8Array]; diff --git a/packages/util/cjs/compact/stripLength.js b/packages/util/cjs/compact/stripLength.js new file mode 100644 index 0000000..ac6e8e2 --- /dev/null +++ b/packages/util/cjs/compact/stripLength.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.compactStripLength = compactStripLength; +const fromU8a_js_1 = require("./fromU8a.js"); +/** + * @name compactStripLength + * @description Removes the length prefix, returning both the total length (including the value + compact encoding) and the decoded value with the correct length + * @example + *
+ * + * ```javascript + * import { compactStripLength } from '@pezkuwi/util'; + * + * console.log(compactStripLength(new Uint8Array([2 << 2, 0xde, 0xad]))); // [2, Uint8Array[0xde, 0xad]] + * ``` + */ +function compactStripLength(input) { + const [offset, length] = (0, fromU8a_js_1.compactFromU8a)(input); + const total = offset + length.toNumber(); + return [ + total, + input.subarray(offset, total) + ]; +} diff --git a/packages/util/cjs/compact/toU8a.d.ts b/packages/util/cjs/compact/toU8a.d.ts new file mode 100644 index 0000000..732cffe --- /dev/null +++ b/packages/util/cjs/compact/toU8a.d.ts @@ -0,0 +1,14 @@ +import { BN } from '../bn/index.js'; +/** + * @name compactToU8a + * @description Encodes a number into a compact representation + * @example + *
+ * + * ```javascript + * import { compactToU8a } from '@pezkuwi/util'; + * + * console.log(compactToU8a(511, 32)); // Uint8Array([0b11111101, 0b00000111]) + * ``` + */ +export declare function compactToU8a(value: BN | bigint | number): Uint8Array; diff --git a/packages/util/cjs/compact/toU8a.js b/packages/util/cjs/compact/toU8a.js new file mode 100644 index 0000000..f3ac587 --- /dev/null +++ b/packages/util/cjs/compact/toU8a.js @@ -0,0 +1,48 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.compactToU8a = compactToU8a; +const index_js_1 = require("../bn/index.js"); +const index_js_2 = require("../u8a/index.js"); +const MAX_U8 = index_js_1.BN_TWO.pow(new index_js_1.BN(8 - 2)).isub(index_js_1.BN_ONE); +const MAX_U16 = index_js_1.BN_TWO.pow(new index_js_1.BN(16 - 2)).isub(index_js_1.BN_ONE); +const MAX_U32 = index_js_1.BN_TWO.pow(new index_js_1.BN(32 - 2)).isub(index_js_1.BN_ONE); +const BL_16 = { bitLength: 16 }; +const BL_32 = { bitLength: 32 }; +/** + * @name compactToU8a + * @description Encodes a number into a compact representation + * @example + *
+ * + * ```javascript + * import { compactToU8a } from '@pezkuwi/util'; + * + * console.log(compactToU8a(511, 32)); // Uint8Array([0b11111101, 0b00000111]) + * ``` + */ +function compactToU8a(value) { + const bn = (0, index_js_1.bnToBn)(value); + if (bn.lte(MAX_U8)) { + return new Uint8Array([bn.toNumber() << 2]); + } + else if (bn.lte(MAX_U16)) { + return (0, index_js_1.bnToU8a)(bn.shln(2).iadd(index_js_1.BN_ONE), BL_16); + } + else if (bn.lte(MAX_U32)) { + return (0, index_js_1.bnToU8a)(bn.shln(2).iadd(index_js_1.BN_TWO), BL_32); + } + const u8a = (0, index_js_1.bnToU8a)(bn); + let length = u8a.length; + // adjust to the minimum number of bytes + while (u8a[length - 1] === 0) { + length--; + } + if (length < 4) { + throw new Error('Invalid length, previous checks match anything less than 2^30'); + } + return (0, index_js_2.u8aConcatStrict)([ + // subtract 4 as minimum (also catered for in decoding) + new Uint8Array([((length - 4) << 2) + 0b11]), + u8a.subarray(0, length) + ]); +} diff --git a/packages/util/cjs/compact/types.d.ts b/packages/util/cjs/compact/types.d.ts new file mode 100644 index 0000000..d4a6650 --- /dev/null +++ b/packages/util/cjs/compact/types.d.ts @@ -0,0 +1 @@ +export type BitLength = 8 | 16 | 32 | 64 | 128 | 256; diff --git a/packages/util/cjs/compact/types.js b/packages/util/cjs/compact/types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/packages/util/cjs/compact/types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/packages/util/cjs/detectPackage.d.ts b/packages/util/cjs/detectPackage.d.ts new file mode 100644 index 0000000..fc66015 --- /dev/null +++ b/packages/util/cjs/detectPackage.d.ts @@ -0,0 +1,17 @@ +interface VersionPath { + path: string; + type: string; + version: string; +} +interface PackageInfo extends VersionPath { + name: string; +} +type FnString = () => string | undefined; +export declare const POLKADOTJS_DISABLE_ESM_CJS_WARNING_FLAG = "POLKADOTJS_DISABLE_ESM_CJS_WARNING"; +/** + * @name detectPackage + * @summary Checks that a specific package is only imported once + * @description A `@pezkuwi/*` version detection utility, checking for one occurrence of a package in addition to checking for dependency versions. + */ +export declare function detectPackage({ name, path, type, version }: PackageInfo, pathOrFn?: FnString | string | false | null, deps?: PackageInfo[]): void; +export {}; diff --git a/packages/util/cjs/detectPackage.js b/packages/util/cjs/detectPackage.js new file mode 100644 index 0000000..1f86192 --- /dev/null +++ b/packages/util/cjs/detectPackage.js @@ -0,0 +1,100 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.POLKADOTJS_DISABLE_ESM_CJS_WARNING_FLAG = void 0; +exports.detectPackage = detectPackage; +const x_global_1 = require("@pezkuwi/x-global"); +const function_js_1 = require("./is/function.js"); +const DEDUPE = 'Either remove and explicitly install matching versions or dedupe using your package manager.\nThe following conflicting packages were found:'; +exports.POLKADOTJS_DISABLE_ESM_CJS_WARNING_FLAG = 'POLKADOTJS_DISABLE_ESM_CJS_WARNING'; +/** @internal */ +function getEntry(name) { + const _global = x_global_1.xglobal; + if (!_global.__polkadotjs) { + _global.__polkadotjs = {}; + } + if (!_global.__polkadotjs[name]) { + _global.__polkadotjs[name] = []; + } + return _global.__polkadotjs[name]; +} +/** @internal */ +function formatDisplay(all, fmt) { + let max = 0; + for (let i = 0, count = all.length; i < count; i++) { + max = Math.max(max, all[i].version.length); + } + return all + .map((d) => `\t${fmt(d.version.padEnd(max), d).join('\t')}`) + .join('\n'); +} +/** @internal */ +function formatInfo(version, { name }) { + return [ + version, + name + ]; +} +/** @internal */ +function formatVersion(version, { path, type }) { + let extracted; + if (path && path.length >= 5) { + const nmIndex = path.indexOf('node_modules'); + extracted = nmIndex === -1 + ? path + : path.substring(nmIndex); + } + else { + extracted = ''; + } + return [ + `${`${type || ''}`.padStart(3)} ${version}`, + extracted + ]; +} +/** @internal */ +function getPath(infoPath, pathOrFn) { + if (infoPath) { + return infoPath; + } + else if ((0, function_js_1.isFunction)(pathOrFn)) { + try { + return pathOrFn() || ''; + } + catch { + return ''; + } + } + return pathOrFn || ''; +} +/** @internal */ +function warn(pre, all, fmt) { + console.warn(`${pre}\n${DEDUPE}\n${formatDisplay(all, fmt)}`); +} +/** + * @name detectPackage + * @summary Checks that a specific package is only imported once + * @description A `@pezkuwi/*` version detection utility, checking for one occurrence of a package in addition to checking for dependency versions. + */ +function detectPackage({ name, path, type, version }, pathOrFn, deps = []) { + if (!name.startsWith('@pezkuwi')) { + throw new Error(`Invalid package descriptor ${name}`); + } + const entry = getEntry(name); + entry.push({ path: getPath(path, pathOrFn), type, version }); + // if we have more than one entry at DIFFERENT version types then warn. If there is + // more than one entry at the same version and ESM/CJS dual warnings are disabled, + // then do not display warnings + const entriesSameVersion = entry.every((e) => e.version === version); + const esmCjsWarningDisabled = x_global_1.xglobal.process?.env?.[exports.POLKADOTJS_DISABLE_ESM_CJS_WARNING_FLAG] === '1'; + const multipleEntries = entry.length !== 1; + const disableWarnings = esmCjsWarningDisabled && entriesSameVersion; + if (multipleEntries && !disableWarnings) { + warn(`${name} has multiple versions, ensure that there is only one installed.`, entry, formatVersion); + } + else { + const mismatches = deps.filter((d) => d && d.version !== version); + if (mismatches.length) { + warn(`${name} requires direct dependencies exactly matching version ${version}.`, mismatches, formatInfo); + } + } +} diff --git a/packages/util/cjs/extractTime.d.ts b/packages/util/cjs/extractTime.d.ts new file mode 100644 index 0000000..62fba8e --- /dev/null +++ b/packages/util/cjs/extractTime.d.ts @@ -0,0 +1,14 @@ +import type { Time } from './types.js'; +/** + * @name extractTime + * @summary Convert a quantity of seconds to Time array representing accumulated {days, minutes, hours, seconds, milliseconds} + * @example + *
+ * + * ```javascript + * import { extractTime } from '@pezkuwi/util'; + * + * const { days, minutes, hours, seconds, milliseconds } = extractTime(6000); // 0, 0, 10, 0, 0 + * ``` + */ +export declare function extractTime(milliseconds?: number): Time; diff --git a/packages/util/cjs/extractTime.js b/packages/util/cjs/extractTime.js new file mode 100644 index 0000000..84f1af9 --- /dev/null +++ b/packages/util/cjs/extractTime.js @@ -0,0 +1,56 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.extractTime = extractTime; +const MIN_MS = 60 * 1000; +const HR_MS = MIN_MS * 60; +const DAY_MS = HR_MS * 24; +const ZERO = { days: 0, hours: 0, milliseconds: 0, minutes: 0, seconds: 0 }; +/** @internal */ +function add(a, b) { + return { + days: (a.days || 0) + b.days, + hours: (a.hours || 0) + b.hours, + milliseconds: (a.milliseconds || 0) + b.milliseconds, + minutes: (a.minutes || 0) + b.minutes, + seconds: (a.seconds || 0) + b.seconds + }; +} +/** @internal */ +function extractSecs(ms) { + const s = ms / 1000; + if (s < 60) { + const seconds = ~~s; + return add({ seconds }, extractTime(ms - (seconds * 1000))); + } + const m = s / 60; + if (m < 60) { + const minutes = ~~m; + return add({ minutes }, extractTime(ms - (minutes * MIN_MS))); + } + const h = m / 60; + if (h < 24) { + const hours = ~~h; + return add({ hours }, extractTime(ms - (hours * HR_MS))); + } + const days = ~~(h / 24); + return add({ days }, extractTime(ms - (days * DAY_MS))); +} +/** + * @name extractTime + * @summary Convert a quantity of seconds to Time array representing accumulated {days, minutes, hours, seconds, milliseconds} + * @example + *
+ * + * ```javascript + * import { extractTime } from '@pezkuwi/util'; + * + * const { days, minutes, hours, seconds, milliseconds } = extractTime(6000); // 0, 0, 10, 0, 0 + * ``` + */ +function extractTime(milliseconds) { + return !milliseconds + ? ZERO + : milliseconds < 1000 + ? add({ milliseconds }, ZERO) + : extractSecs(milliseconds); +} diff --git a/packages/util/cjs/float/index.d.ts b/packages/util/cjs/float/index.d.ts new file mode 100644 index 0000000..0c33ced --- /dev/null +++ b/packages/util/cjs/float/index.d.ts @@ -0,0 +1 @@ +export { floatToU8a } from './toU8a.js'; diff --git a/packages/util/cjs/float/index.js b/packages/util/cjs/float/index.js new file mode 100644 index 0000000..1b2a833 --- /dev/null +++ b/packages/util/cjs/float/index.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.floatToU8a = void 0; +var toU8a_js_1 = require("./toU8a.js"); +Object.defineProperty(exports, "floatToU8a", { enumerable: true, get: function () { return toU8a_js_1.floatToU8a; } }); diff --git a/packages/util/cjs/float/toU8a.d.ts b/packages/util/cjs/float/toU8a.d.ts new file mode 100644 index 0000000..f3d9282 --- /dev/null +++ b/packages/util/cjs/float/toU8a.d.ts @@ -0,0 +1,11 @@ +interface Options { + bitLength?: 32 | 64; + isLe?: boolean; +} +/** + * @name floatToU8a + * @description Converts a float into a U8a representation (While we don't use BE in SCALE + * we still allow for either representation, although, as elsewhere, isLe is default) + */ +export declare function floatToU8a(value?: String | string | number | Number, { bitLength, isLe }?: Options): Uint8Array; +export {}; diff --git a/packages/util/cjs/float/toU8a.js b/packages/util/cjs/float/toU8a.js new file mode 100644 index 0000000..bd709b8 --- /dev/null +++ b/packages/util/cjs/float/toU8a.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.floatToU8a = floatToU8a; +/** + * @name floatToU8a + * @description Converts a float into a U8a representation (While we don't use BE in SCALE + * we still allow for either representation, although, as elsewhere, isLe is default) + */ +function floatToU8a(value = 0.0, { bitLength = 32, isLe = true } = {}) { + if (bitLength !== 32 && bitLength !== 64) { + throw new Error('Invalid bitLength provided, expected 32 or 64'); + } + const result = new Uint8Array(bitLength / 8); + const dv = new DataView(result.buffer, result.byteOffset); + if (bitLength === 32) { + dv.setFloat32(0, Number(value), isLe); + } + else { + dv.setFloat64(0, Number(value), isLe); + } + return result; +} diff --git a/packages/util/cjs/format/formatBalance.d.ts b/packages/util/cjs/format/formatBalance.d.ts new file mode 100644 index 0000000..7eb766c --- /dev/null +++ b/packages/util/cjs/format/formatBalance.d.ts @@ -0,0 +1,54 @@ +import type { BN } from '../bn/bn.js'; +import type { SiDef, ToBn } from '../types.js'; +interface Defaults { + decimals: number; + unit: string; +} +interface SetDefaults { + decimals?: number[] | number; + unit?: string[] | string; +} +interface Options { + /** + * @description The number of decimals + */ + decimals?: number; + /** + * @description Format the number with this specific unit + */ + forceUnit?: string; + /** + * @description Returns value using all available decimals + */ + withAll?: boolean; + /** + * @description Format with SI, i.e. m/M/etc. (default = true) + */ + withSi?: boolean; + /** + * @description Format with full SI, i.e. mili/Mega/etc. + */ + withSiFull?: boolean; + /** + * @description Add the unit (useful in Balance formats) + */ + withUnit?: boolean | string; + /** + * @description Returns all trailing zeros, otherwise removes (default = true) + */ + withZero?: boolean; + /** + * @description The locale to use + */ + locale?: string; +} +interface BalanceFormatter { + (input?: number | string | BN | bigint | ExtToBn, options?: Options): string; + calcSi(text: string, decimals?: number): SiDef; + findSi(type: string): SiDef; + getDefaults(): Defaults; + getOptions(decimals?: number): SiDef[]; + setDefaults(defaults: SetDefaults): void; +} +export declare const formatBalance: BalanceFormatter; +export {}; diff --git a/packages/util/cjs/format/formatBalance.js b/packages/util/cjs/format/formatBalance.js new file mode 100644 index 0000000..2671989 --- /dev/null +++ b/packages/util/cjs/format/formatBalance.js @@ -0,0 +1,88 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.formatBalance = void 0; +const toBn_js_1 = require("../bn/toBn.js"); +const boolean_js_1 = require("../is/boolean.js"); +const formatDecimal_js_1 = require("./formatDecimal.js"); +const getSeparator_js_1 = require("./getSeparator.js"); +const si_js_1 = require("./si.js"); +const DEFAULT_DECIMALS = 0; +const DEFAULT_UNIT = si_js_1.SI[si_js_1.SI_MID].text; +let defaultDecimals = DEFAULT_DECIMALS; +let defaultUnit = DEFAULT_UNIT; +function _formatBalance(input, { decimals = defaultDecimals, forceUnit, locale = 'en', withAll = false, withSi = true, withSiFull = false, withUnit = true, withZero = true } = {}) { + // we only work with string inputs here - convert anything + // into the string-only value + let text = (0, toBn_js_1.bnToBn)(input).toString(); + if (text.length === 0 || text === '0') { + return '0'; + } + // strip the negative sign so we can work with clean groupings, re-add this in the + // end when we return the result (from here on we work with positive numbers) + let sign = ''; + if (text[0].startsWith('-')) { + sign = '-'; + text = text.substring(1); + } + // We start at midpoint (8) minus 1 - this means that values display as + // 123.4567 instead of 0.1234 k (so we always have the most relevant). + const si = (0, si_js_1.calcSi)(text, decimals, forceUnit); + const mid = text.length - (decimals + si.power); + const pre = mid <= 0 ? '0' : text.substring(0, mid); + // get the post from the midpoint onward and then first add max decimals + // before trimming to the correct (calculated) amount of decimals again + let post = text + .padStart(mid < 0 ? decimals : 1, '0') + .substring(mid < 0 ? 0 : mid) + .padEnd(withAll ? Math.max(decimals, 4) : 4, '0') + .substring(0, withAll ? Math.max(4, decimals + si.power) : 4); + // remove all trailing 0's (if required via flag) + if (!withZero) { + let end = post.length - 1; + // This looks inefficient, however it is better to do the checks and + // only make one final slice than it is to do it in multiples + do { + if (post[end] === '0') { + end--; + } + } while (post[end] === '0'); + post = post.substring(0, end + 1); + } + // the display unit + const unit = (0, boolean_js_1.isBoolean)(withUnit) + ? si_js_1.SI[si_js_1.SI_MID].text + : withUnit; + // format the units for display based on the flags + const units = withSi || withSiFull + ? si.value === '-' + ? withUnit + ? ` ${unit}` + : '' + : ` ${withSiFull ? `${si.text}${withUnit ? ' ' : ''}` : si.value}${withUnit ? unit : ''}` + : ''; + const { decimal, thousand } = (0, getSeparator_js_1.getSeparator)(locale); + return `${sign}${(0, formatDecimal_js_1.formatDecimal)(pre, thousand)}${post && `${decimal}${post}`}${units}`; +} +exports.formatBalance = _formatBalance; +exports.formatBalance.calcSi = (text, decimals = defaultDecimals) => (0, si_js_1.calcSi)(text, decimals); +exports.formatBalance.findSi = si_js_1.findSi; +exports.formatBalance.getDefaults = () => { + return { + decimals: defaultDecimals, + unit: defaultUnit + }; +}; +exports.formatBalance.getOptions = (decimals = defaultDecimals) => { + return si_js_1.SI.filter(({ power }) => power < 0 + ? (decimals + power) >= 0 + : true); +}; +exports.formatBalance.setDefaults = ({ decimals, unit }) => { + defaultDecimals = (Array.isArray(decimals) + ? decimals[0] + : decimals) ?? defaultDecimals; + defaultUnit = (Array.isArray(unit) + ? unit[0] + : unit) ?? defaultUnit; + si_js_1.SI[si_js_1.SI_MID].text = defaultUnit; +}; diff --git a/packages/util/cjs/format/formatDate.d.ts b/packages/util/cjs/format/formatDate.d.ts new file mode 100644 index 0000000..c3211a8 --- /dev/null +++ b/packages/util/cjs/format/formatDate.d.ts @@ -0,0 +1,5 @@ +/** + * @name formatDate + * @description Formats a date in CCYY-MM-DD HH:MM:SS format + */ +export declare function formatDate(date: Date): string; diff --git a/packages/util/cjs/format/formatDate.js b/packages/util/cjs/format/formatDate.js new file mode 100644 index 0000000..cacf3cb --- /dev/null +++ b/packages/util/cjs/format/formatDate.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.formatDate = formatDate; +/** @internal */ +function zeroPad(value) { + return value.toString().padStart(2, '0'); +} +/** + * @name formatDate + * @description Formats a date in CCYY-MM-DD HH:MM:SS format + */ +function formatDate(date) { + const year = date.getFullYear().toString(); + const month = zeroPad((date.getMonth() + 1)); + const day = zeroPad(date.getDate()); + const hour = zeroPad(date.getHours()); + const minute = zeroPad(date.getMinutes()); + const second = zeroPad(date.getSeconds()); + return `${year}-${month}-${day} ${hour}:${minute}:${second}`; +} diff --git a/packages/util/cjs/format/formatDecimal.d.ts b/packages/util/cjs/format/formatDecimal.d.ts new file mode 100644 index 0000000..9f73fd1 --- /dev/null +++ b/packages/util/cjs/format/formatDecimal.d.ts @@ -0,0 +1,5 @@ +/** + * @name formatDecimal + * @description Formats a number into string format with thousand separators + */ +export declare function formatDecimal(value: string, separator?: string): string; diff --git a/packages/util/cjs/format/formatDecimal.js b/packages/util/cjs/format/formatDecimal.js new file mode 100644 index 0000000..ef98cae --- /dev/null +++ b/packages/util/cjs/format/formatDecimal.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.formatDecimal = formatDecimal; +const NUMBER_REGEX = new RegExp('(\\d+?)(?=(\\d{3})+(?!\\d)|$)', 'g'); +/** + * @name formatDecimal + * @description Formats a number into string format with thousand separators + */ +function formatDecimal(value, separator = ',') { + // We can do this by adjusting the regx, however for the sake of clarity + // we rather strip and re-add the negative sign in the output + const isNegative = value[0].startsWith('-'); + const matched = isNegative + ? value.substring(1).match(NUMBER_REGEX) + : value.match(NUMBER_REGEX); + return matched + ? `${isNegative ? '-' : ''}${matched.join(separator)}` + : value; +} diff --git a/packages/util/cjs/format/formatElapsed.d.ts b/packages/util/cjs/format/formatElapsed.d.ts new file mode 100644 index 0000000..8302533 --- /dev/null +++ b/packages/util/cjs/format/formatElapsed.d.ts @@ -0,0 +1,7 @@ +import type { BN } from '../bn/bn.js'; +import type { ToBn } from '../types.js'; +/** + * @name formatElapsed + * @description Formats an elapsed value into s, m, h or day segments + */ +export declare function formatElapsed(now?: Date | null, value?: bigint | BN | ExtToBn | Date | number | null): string; diff --git a/packages/util/cjs/format/formatElapsed.js b/packages/util/cjs/format/formatElapsed.js new file mode 100644 index 0000000..b9bd579 --- /dev/null +++ b/packages/util/cjs/format/formatElapsed.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.formatElapsed = formatElapsed; +const toBn_js_1 = require("../bn/toBn.js"); +/** @internal */ +function formatValue(elapsed) { + if (elapsed < 15) { + return `${elapsed.toFixed(1)}s`; + } + else if (elapsed < 60) { + return `${elapsed | 0}s`; + } + else if (elapsed < 3600) { + return `${elapsed / 60 | 0}m`; + } + return `${elapsed / 3600 | 0}h`; +} +/** + * @name formatElapsed + * @description Formats an elapsed value into s, m, h or day segments + */ +function formatElapsed(now, value) { + const tsNow = now?.getTime() || 0; + const tsValue = value instanceof Date + ? value.getTime() + : (0, toBn_js_1.bnToBn)(value).toNumber(); + return (tsNow && tsValue) + ? formatValue(Math.max(Math.abs(tsNow - tsValue), 0) / 1000) + : '0.0s'; +} diff --git a/packages/util/cjs/format/formatNumber.d.ts b/packages/util/cjs/format/formatNumber.d.ts new file mode 100644 index 0000000..83f6338 --- /dev/null +++ b/packages/util/cjs/format/formatNumber.d.ts @@ -0,0 +1,14 @@ +import type { BN } from '../bn/bn.js'; +import type { ToBn } from '../types.js'; +interface Options { + /** + * @description The locale to use + */ + locale?: string; +} +/** + * @name formatNumber + * @description Formats a number into string format with thousand separators + */ +export declare function formatNumber(value?: ExtToBn | BN | bigint | number | null, { locale }?: Options): string; +export {}; diff --git a/packages/util/cjs/format/formatNumber.js b/packages/util/cjs/format/formatNumber.js new file mode 100644 index 0000000..7ab9922 --- /dev/null +++ b/packages/util/cjs/format/formatNumber.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.formatNumber = formatNumber; +const toBn_js_1 = require("../bn/toBn.js"); +const formatDecimal_js_1 = require("./formatDecimal.js"); +const getSeparator_js_1 = require("./getSeparator.js"); +/** + * @name formatNumber + * @description Formats a number into string format with thousand separators + */ +function formatNumber(value, { locale = 'en' } = {}) { + const { thousand } = (0, getSeparator_js_1.getSeparator)(locale); + return (0, formatDecimal_js_1.formatDecimal)((0, toBn_js_1.bnToBn)(value).toString(), thousand); +} diff --git a/packages/util/cjs/format/getSeparator.d.ts b/packages/util/cjs/format/getSeparator.d.ts new file mode 100644 index 0000000..6d7b097 --- /dev/null +++ b/packages/util/cjs/format/getSeparator.d.ts @@ -0,0 +1,9 @@ +/** + * Get the decimal and thousand separator of a locale + * @param locale + * @returns {decimal: string, thousand: string} + */ +export declare function getSeparator(locale?: string): { + thousand: string; + decimal: string; +}; diff --git a/packages/util/cjs/format/getSeparator.js b/packages/util/cjs/format/getSeparator.js new file mode 100644 index 0000000..2a87615 --- /dev/null +++ b/packages/util/cjs/format/getSeparator.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getSeparator = getSeparator; +/** + * Get the decimal and thousand separator of a locale + * @param locale + * @returns {decimal: string, thousand: string} + */ +function getSeparator(locale) { + return { + decimal: (0.1).toLocaleString(locale, { useGrouping: false }).charAt(1), + thousand: (1000).toLocaleString(locale, { useGrouping: true }).replace(/\d/g, '').charAt(0) + }; +} diff --git a/packages/util/cjs/format/index.d.ts b/packages/util/cjs/format/index.d.ts new file mode 100644 index 0000000..6114673 --- /dev/null +++ b/packages/util/cjs/format/index.d.ts @@ -0,0 +1,6 @@ +export { formatBalance } from './formatBalance.js'; +export { formatDate } from './formatDate.js'; +export { formatDecimal } from './formatDecimal.js'; +export { formatElapsed } from './formatElapsed.js'; +export { formatNumber } from './formatNumber.js'; +export { calcSi, findSi } from './si.js'; diff --git a/packages/util/cjs/format/index.js b/packages/util/cjs/format/index.js new file mode 100644 index 0000000..a01f021 --- /dev/null +++ b/packages/util/cjs/format/index.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.findSi = exports.calcSi = exports.formatNumber = exports.formatElapsed = exports.formatDecimal = exports.formatDate = exports.formatBalance = void 0; +var formatBalance_js_1 = require("./formatBalance.js"); +Object.defineProperty(exports, "formatBalance", { enumerable: true, get: function () { return formatBalance_js_1.formatBalance; } }); +var formatDate_js_1 = require("./formatDate.js"); +Object.defineProperty(exports, "formatDate", { enumerable: true, get: function () { return formatDate_js_1.formatDate; } }); +var formatDecimal_js_1 = require("./formatDecimal.js"); +Object.defineProperty(exports, "formatDecimal", { enumerable: true, get: function () { return formatDecimal_js_1.formatDecimal; } }); +var formatElapsed_js_1 = require("./formatElapsed.js"); +Object.defineProperty(exports, "formatElapsed", { enumerable: true, get: function () { return formatElapsed_js_1.formatElapsed; } }); +var formatNumber_js_1 = require("./formatNumber.js"); +Object.defineProperty(exports, "formatNumber", { enumerable: true, get: function () { return formatNumber_js_1.formatNumber; } }); +var si_js_1 = require("./si.js"); +Object.defineProperty(exports, "calcSi", { enumerable: true, get: function () { return si_js_1.calcSi; } }); +Object.defineProperty(exports, "findSi", { enumerable: true, get: function () { return si_js_1.findSi; } }); diff --git a/packages/util/cjs/format/si.d.ts b/packages/util/cjs/format/si.d.ts new file mode 100644 index 0000000..cc4a1cc --- /dev/null +++ b/packages/util/cjs/format/si.d.ts @@ -0,0 +1,9 @@ +import type { SiDef } from '../types.js'; +/** @internal */ +export declare const SI_MID = 8; +/** @internal */ +export declare const SI: SiDef[]; +/** @internal */ +export declare function findSi(type: string): SiDef; +/** @internal */ +export declare function calcSi(text: string, decimals: number, forceUnit?: string): SiDef; diff --git a/packages/util/cjs/format/si.js b/packages/util/cjs/format/si.js new file mode 100644 index 0000000..0425e9b --- /dev/null +++ b/packages/util/cjs/format/si.js @@ -0,0 +1,45 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.SI = exports.SI_MID = void 0; +exports.findSi = findSi; +exports.calcSi = calcSi; +/** @internal */ +exports.SI_MID = 8; +/** @internal */ +exports.SI = [ + { power: -24, text: 'yocto', value: 'y' }, + { power: -21, text: 'zepto', value: 'z' }, + { power: -18, text: 'atto', value: 'a' }, + { power: -15, text: 'femto', value: 'f' }, + { power: -12, text: 'pico', value: 'p' }, + { power: -9, text: 'nano', value: 'n' }, + { power: -6, text: 'micro', value: 'µ' }, + { power: -3, text: 'milli', value: 'm' }, + { power: 0, text: 'Unit', value: '-' }, // position 8 + { power: 3, text: 'Kilo', value: 'k' }, + { power: 6, text: 'Mill', value: 'M' }, // Mega, M + { power: 9, text: 'Bill', value: 'B' }, // Giga, G + { power: 12, text: 'Tril', value: 'T' }, // Tera, T + { power: 15, text: 'Peta', value: 'P' }, + { power: 18, text: 'Exa', value: 'E' }, + { power: 21, text: 'Zeta', value: 'Z' }, + { power: 24, text: 'Yotta', value: 'Y' } +]; +/** @internal */ +function findSi(type) { + // use a loop here, better RN support (which doesn't have [].find) + for (let i = 0, count = exports.SI.length; i < count; i++) { + if (exports.SI[i].value === type) { + return exports.SI[i]; + } + } + return exports.SI[exports.SI_MID]; +} +/** @internal */ +function calcSi(text, decimals, forceUnit) { + if (forceUnit) { + return findSi(forceUnit); + } + const siDefIndex = (exports.SI_MID - 1) + Math.ceil((text.length - decimals) / 3); + return exports.SI[siDefIndex] || exports.SI[siDefIndex < 0 ? 0 : exports.SI.length - 1]; +} diff --git a/packages/util/cjs/has.d.ts b/packages/util/cjs/has.d.ts new file mode 100644 index 0000000..42fac7f --- /dev/null +++ b/packages/util/cjs/has.d.ts @@ -0,0 +1,14 @@ +/** true if the environment has proper BigInt support */ +export declare const hasBigInt: boolean; +/** true if the environment is CJS */ +export declare const hasCjs: boolean; +/** true if the environment has __dirname available */ +export declare const hasDirname: boolean; +/** true if the environment is ESM */ +export declare const hasEsm: boolean; +/** true if the environment has WebAssembly available */ +export declare const hasWasm: boolean; +/** true if the environment has support for Buffer (typically Node.js) */ +export declare const hasBuffer: boolean; +/** true if the environment has process available (typically Node.js) */ +export declare const hasProcess: boolean; diff --git a/packages/util/cjs/has.js b/packages/util/cjs/has.js new file mode 100644 index 0000000..77327af --- /dev/null +++ b/packages/util/cjs/has.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hasProcess = exports.hasBuffer = exports.hasWasm = exports.hasEsm = exports.hasDirname = exports.hasCjs = exports.hasBigInt = void 0; +const x_bigint_1 = require("@pezkuwi/x-bigint"); +const x_global_1 = require("@pezkuwi/x-global"); +/** true if the environment has proper BigInt support */ +exports.hasBigInt = typeof x_bigint_1.BigInt === 'function' && typeof x_bigint_1.BigInt.asIntN === 'function'; +/** true if the environment is CJS */ +exports.hasCjs = typeof require === 'function' && typeof module !== 'undefined'; +/** true if the environment has __dirname available */ +exports.hasDirname = typeof __dirname !== 'undefined'; +/** true if the environment is ESM */ +exports.hasEsm = !exports.hasCjs; +/** true if the environment has WebAssembly available */ +exports.hasWasm = typeof WebAssembly !== 'undefined'; +/** true if the environment has support for Buffer (typically Node.js) */ +exports.hasBuffer = typeof x_global_1.xglobal.Buffer === 'function' && typeof x_global_1.xglobal.Buffer.isBuffer === 'function'; +/** true if the environment has process available (typically Node.js) */ +exports.hasProcess = typeof x_global_1.xglobal.process === 'object'; diff --git a/packages/util/cjs/hex/addPrefix.d.ts b/packages/util/cjs/hex/addPrefix.d.ts new file mode 100644 index 0000000..5701368 --- /dev/null +++ b/packages/util/cjs/hex/addPrefix.d.ts @@ -0,0 +1,16 @@ +import type { HexString } from '../types.js'; +/** + * @name hexAddPrefix + * @summary Adds the `0x` prefix to string values. + * @description + * Returns a `0x` prefixed string from the input value. If the input is already prefixed, it is returned unchanged. + * @example + *
+ * + * ```javascript + * import { hexAddPrefix } from '@pezkuwi/util'; + * + * console.log('With prefix', hexAddPrefix('0a0b12')); // => 0x0a0b12 + * ``` + */ +export declare function hexAddPrefix(value?: string | null): HexString; diff --git a/packages/util/cjs/hex/addPrefix.js b/packages/util/cjs/hex/addPrefix.js new file mode 100644 index 0000000..efa11cf --- /dev/null +++ b/packages/util/cjs/hex/addPrefix.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hexAddPrefix = hexAddPrefix; +const hasPrefix_js_1 = require("./hasPrefix.js"); +/** + * @name hexAddPrefix + * @summary Adds the `0x` prefix to string values. + * @description + * Returns a `0x` prefixed string from the input value. If the input is already prefixed, it is returned unchanged. + * @example + *
+ * + * ```javascript + * import { hexAddPrefix } from '@pezkuwi/util'; + * + * console.log('With prefix', hexAddPrefix('0a0b12')); // => 0x0a0b12 + * ``` + */ +function hexAddPrefix(value) { + return value && (0, hasPrefix_js_1.hexHasPrefix)(value) + ? value + : `0x${value && value.length % 2 === 1 ? '0' : ''}${value || ''}`; +} diff --git a/packages/util/cjs/hex/fixLength.d.ts b/packages/util/cjs/hex/fixLength.d.ts new file mode 100644 index 0000000..f7480a6 --- /dev/null +++ b/packages/util/cjs/hex/fixLength.d.ts @@ -0,0 +1,18 @@ +import type { HexString } from '../types.js'; +/** + * @name hexFixLength + * @summary Shifts a hex string to a specific bitLength + * @description + * Returns a `0x` prefixed string with the specified number of bits contained in the return value. (If bitLength is -1, length checking is not done). Values with more bits are trimmed to the specified length. Input values with less bits are returned as-is by default. When `withPadding` is set, shorter values are padded with `0`. + * @example + *
+ * + * ```javascript + * import { hexFixLength } from '@pezkuwi/util'; + * + * console.log('fixed', hexFixLength('0x12', 16)); // => 0x12 + * console.log('fixed', hexFixLength('0x12', 16, true)); // => 0x0012 + * console.log('fixed', hexFixLength('0x0012', 8)); // => 0x12 + * ``` + */ +export declare function hexFixLength(value: string, bitLength?: number, withPadding?: boolean): HexString; diff --git a/packages/util/cjs/hex/fixLength.js b/packages/util/cjs/hex/fixLength.js new file mode 100644 index 0000000..2a64c37 --- /dev/null +++ b/packages/util/cjs/hex/fixLength.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hexFixLength = hexFixLength; +const addPrefix_js_1 = require("./addPrefix.js"); +const stripPrefix_js_1 = require("./stripPrefix.js"); +/** + * @name hexFixLength + * @summary Shifts a hex string to a specific bitLength + * @description + * Returns a `0x` prefixed string with the specified number of bits contained in the return value. (If bitLength is -1, length checking is not done). Values with more bits are trimmed to the specified length. Input values with less bits are returned as-is by default. When `withPadding` is set, shorter values are padded with `0`. + * @example + *
+ * + * ```javascript + * import { hexFixLength } from '@pezkuwi/util'; + * + * console.log('fixed', hexFixLength('0x12', 16)); // => 0x12 + * console.log('fixed', hexFixLength('0x12', 16, true)); // => 0x0012 + * console.log('fixed', hexFixLength('0x0012', 8)); // => 0x12 + * ``` + */ +function hexFixLength(value, bitLength = -1, withPadding = false) { + const strLength = Math.ceil(bitLength / 4); + const hexLength = strLength + 2; + return (0, addPrefix_js_1.hexAddPrefix)((bitLength === -1 || value.length === hexLength || (!withPadding && value.length < hexLength)) + ? (0, stripPrefix_js_1.hexStripPrefix)(value) + : (value.length > hexLength) + ? (0, stripPrefix_js_1.hexStripPrefix)(value).slice(-1 * strLength) + : `${'0'.repeat(strLength)}${(0, stripPrefix_js_1.hexStripPrefix)(value)}`.slice(-1 * strLength)); +} diff --git a/packages/util/cjs/hex/hasPrefix.d.ts b/packages/util/cjs/hex/hasPrefix.d.ts new file mode 100644 index 0000000..45d0832 --- /dev/null +++ b/packages/util/cjs/hex/hasPrefix.d.ts @@ -0,0 +1,16 @@ +import type { HexString } from '../types.js'; +/** + * @name hexHasPrefix + * @summary Tests for the existence of a `0x` prefix. + * @description + * Checks for a valid hex input value and if the start matched `0x` + * @example + *
+ * + * ```javascript + * import { hexHasPrefix } from '@pezkuwi/util'; + * + * console.log('has prefix', hexHasPrefix('0x1234')); // => true + * ``` + */ +export declare function hexHasPrefix(value?: string | null): value is HexString; diff --git a/packages/util/cjs/hex/hasPrefix.js b/packages/util/cjs/hex/hasPrefix.js new file mode 100644 index 0000000..ef439c8 --- /dev/null +++ b/packages/util/cjs/hex/hasPrefix.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hexHasPrefix = hexHasPrefix; +const hex_js_1 = require("../is/hex.js"); +/** + * @name hexHasPrefix + * @summary Tests for the existence of a `0x` prefix. + * @description + * Checks for a valid hex input value and if the start matched `0x` + * @example + *
+ * + * ```javascript + * import { hexHasPrefix } from '@pezkuwi/util'; + * + * console.log('has prefix', hexHasPrefix('0x1234')); // => true + * ``` + */ +function hexHasPrefix(value) { + return !!value && (0, hex_js_1.isHex)(value, -1); +} diff --git a/packages/util/cjs/hex/index.d.ts b/packages/util/cjs/hex/index.d.ts new file mode 100644 index 0000000..85d3e8f --- /dev/null +++ b/packages/util/cjs/hex/index.d.ts @@ -0,0 +1,12 @@ +/** + * @summary Internal utilities to create and test for hex values + */ +export { hexAddPrefix } from './addPrefix.js'; +export { hexFixLength } from './fixLength.js'; +export { hexHasPrefix } from './hasPrefix.js'; +export { hexStripPrefix } from './stripPrefix.js'; +export { hexToBigInt } from './toBigInt.js'; +export { hexToBn } from './toBn.js'; +export { hexToNumber } from './toNumber.js'; +export { hexToString } from './toString.js'; +export { hexToU8a } from './toU8a.js'; diff --git a/packages/util/cjs/hex/index.js b/packages/util/cjs/hex/index.js new file mode 100644 index 0000000..8f8883e --- /dev/null +++ b/packages/util/cjs/hex/index.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hexToU8a = exports.hexToString = exports.hexToNumber = exports.hexToBn = exports.hexToBigInt = exports.hexStripPrefix = exports.hexHasPrefix = exports.hexFixLength = exports.hexAddPrefix = void 0; +/** + * @summary Internal utilities to create and test for hex values + */ +var addPrefix_js_1 = require("./addPrefix.js"); +Object.defineProperty(exports, "hexAddPrefix", { enumerable: true, get: function () { return addPrefix_js_1.hexAddPrefix; } }); +var fixLength_js_1 = require("./fixLength.js"); +Object.defineProperty(exports, "hexFixLength", { enumerable: true, get: function () { return fixLength_js_1.hexFixLength; } }); +var hasPrefix_js_1 = require("./hasPrefix.js"); +Object.defineProperty(exports, "hexHasPrefix", { enumerable: true, get: function () { return hasPrefix_js_1.hexHasPrefix; } }); +var stripPrefix_js_1 = require("./stripPrefix.js"); +Object.defineProperty(exports, "hexStripPrefix", { enumerable: true, get: function () { return stripPrefix_js_1.hexStripPrefix; } }); +var toBigInt_js_1 = require("./toBigInt.js"); +Object.defineProperty(exports, "hexToBigInt", { enumerable: true, get: function () { return toBigInt_js_1.hexToBigInt; } }); +var toBn_js_1 = require("./toBn.js"); +Object.defineProperty(exports, "hexToBn", { enumerable: true, get: function () { return toBn_js_1.hexToBn; } }); +var toNumber_js_1 = require("./toNumber.js"); +Object.defineProperty(exports, "hexToNumber", { enumerable: true, get: function () { return toNumber_js_1.hexToNumber; } }); +var toString_js_1 = require("./toString.js"); +Object.defineProperty(exports, "hexToString", { enumerable: true, get: function () { return toString_js_1.hexToString; } }); +var toU8a_js_1 = require("./toU8a.js"); +Object.defineProperty(exports, "hexToU8a", { enumerable: true, get: function () { return toU8a_js_1.hexToU8a; } }); diff --git a/packages/util/cjs/hex/stripPrefix.d.ts b/packages/util/cjs/hex/stripPrefix.d.ts new file mode 100644 index 0000000..67d3589 --- /dev/null +++ b/packages/util/cjs/hex/stripPrefix.d.ts @@ -0,0 +1,15 @@ +/** + * @name hexStripPrefix + * @summary Strips any leading `0x` prefix. + * @description + * Tests for the existence of a `0x` prefix, and returns the value without the prefix. Un-prefixed values are returned as-is. + * @example + *
+ * + * ```javascript + * import { hexStripPrefix } from '@pezkuwi/util'; + * + * console.log('stripped', hexStripPrefix('0x1234')); // => 1234 + * ``` + */ +export declare function hexStripPrefix(value?: string | null): string; diff --git a/packages/util/cjs/hex/stripPrefix.js b/packages/util/cjs/hex/stripPrefix.js new file mode 100644 index 0000000..3c4ff2f --- /dev/null +++ b/packages/util/cjs/hex/stripPrefix.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hexStripPrefix = hexStripPrefix; +const hex_js_1 = require("../is/hex.js"); +/** + * @name hexStripPrefix + * @summary Strips any leading `0x` prefix. + * @description + * Tests for the existence of a `0x` prefix, and returns the value without the prefix. Un-prefixed values are returned as-is. + * @example + *
+ * + * ```javascript + * import { hexStripPrefix } from '@pezkuwi/util'; + * + * console.log('stripped', hexStripPrefix('0x1234')); // => 1234 + * ``` + */ +function hexStripPrefix(value) { + if (!value || value === '0x') { + return ''; + } + else if (hex_js_1.REGEX_HEX_PREFIXED.test(value)) { + return value.substring(2); + } + else if (hex_js_1.REGEX_HEX_NOPREFIX.test(value)) { + return value; + } + throw new Error(`Expected hex value to convert, found '${value}'`); +} diff --git a/packages/util/cjs/hex/toBigInt.d.ts b/packages/util/cjs/hex/toBigInt.d.ts new file mode 100644 index 0000000..ecf1f7d --- /dev/null +++ b/packages/util/cjs/hex/toBigInt.d.ts @@ -0,0 +1,6 @@ +import type { ToBnOptions } from '../types.js'; +/** + * @name hexToBigInt + * @summary Creates a BigInt instance object from a hex string. + */ +export declare function hexToBigInt(value?: string | null, { isLe, isNegative }?: ToBnOptions): bigint; diff --git a/packages/util/cjs/hex/toBigInt.js b/packages/util/cjs/hex/toBigInt.js new file mode 100644 index 0000000..1bd9d38 --- /dev/null +++ b/packages/util/cjs/hex/toBigInt.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hexToBigInt = hexToBigInt; +const x_bigint_1 = require("@pezkuwi/x-bigint"); +const toBigInt_js_1 = require("../u8a/toBigInt.js"); +const toU8a_js_1 = require("./toU8a.js"); +/** + * @name hexToBigInt + * @summary Creates a BigInt instance object from a hex string. + */ +function hexToBigInt(value, { isLe = false, isNegative = false } = {}) { + return !value || value === '0x' + ? (0, x_bigint_1.BigInt)(0) + : (0, toBigInt_js_1.u8aToBigInt)((0, toU8a_js_1.hexToU8a)(value), { isLe, isNegative }); +} diff --git a/packages/util/cjs/hex/toBn.d.ts b/packages/util/cjs/hex/toBn.d.ts new file mode 100644 index 0000000..6bc61b9 --- /dev/null +++ b/packages/util/cjs/hex/toBn.d.ts @@ -0,0 +1,21 @@ +import type { ToBnOptions } from '../types.js'; +import { BN } from '../bn/bn.js'; +/** + * @name hexToBn + * @summary Creates a BN.js object from a hex string. + * @description + * `null` inputs returns a `BN(0)` result. Hex input values return the actual value converted to a BN. Anything that is not a hex string (including the `0x` prefix) throws an error. + * @param _value The value to convert + * @param _options Options to pass while converting + * @param _options.isLe Convert using Little Endian + * @param _options.isNegative Convert using two's complement + * @example + *
+ * + * ```javascript + * import { hexToBn } from '@pezkuwi/util'; + * + * hexToBn('0x123480001f'); // => BN(0x123480001f) + * ``` + */ +export declare function hexToBn(value?: string | null, { isLe, isNegative }?: ToBnOptions): BN; diff --git a/packages/util/cjs/hex/toBn.js b/packages/util/cjs/hex/toBn.js new file mode 100644 index 0000000..04f8f51 --- /dev/null +++ b/packages/util/cjs/hex/toBn.js @@ -0,0 +1,35 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hexToBn = hexToBn; +const bn_js_1 = require("../bn/bn.js"); +const stripPrefix_js_1 = require("./stripPrefix.js"); +/** + * @name hexToBn + * @summary Creates a BN.js object from a hex string. + * @description + * `null` inputs returns a `BN(0)` result. Hex input values return the actual value converted to a BN. Anything that is not a hex string (including the `0x` prefix) throws an error. + * @param _value The value to convert + * @param _options Options to pass while converting + * @param _options.isLe Convert using Little Endian + * @param _options.isNegative Convert using two's complement + * @example + *
+ * + * ```javascript + * import { hexToBn } from '@pezkuwi/util'; + * + * hexToBn('0x123480001f'); // => BN(0x123480001f) + * ``` + */ +function hexToBn(value, { isLe = false, isNegative = false } = {}) { + if (!value || value === '0x') { + return new bn_js_1.BN(0); + } + const stripped = (0, stripPrefix_js_1.hexStripPrefix)(value); + const bn = new bn_js_1.BN(stripped, 16, isLe ? 'le' : 'be'); + // fromTwos takes as parameter the number of bits, which is the hex length + // multiplied by 4 (2 bytes being 8 bits) + return isNegative + ? bn.fromTwos(stripped.length * 4) + : bn; +} diff --git a/packages/util/cjs/hex/toNumber.d.ts b/packages/util/cjs/hex/toNumber.d.ts new file mode 100644 index 0000000..ca9beb2 --- /dev/null +++ b/packages/util/cjs/hex/toNumber.d.ts @@ -0,0 +1,15 @@ +/** + * @name hexToNumber + * @summary Creates a Number value from a Buffer object. + * @description + * `null` inputs returns an NaN result, `hex` values return the actual value as a `Number`. + * @example + *
+ * + * ```javascript + * import { hexToNumber } from '@pezkuwi/util'; + * + * hexToNumber('0x1234'); // => 0x1234 + * ``` + */ +export declare function hexToNumber(value?: string | null): number; diff --git a/packages/util/cjs/hex/toNumber.js b/packages/util/cjs/hex/toNumber.js new file mode 100644 index 0000000..ce28f73 --- /dev/null +++ b/packages/util/cjs/hex/toNumber.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hexToNumber = hexToNumber; +const toBn_js_1 = require("./toBn.js"); +/** + * @name hexToNumber + * @summary Creates a Number value from a Buffer object. + * @description + * `null` inputs returns an NaN result, `hex` values return the actual value as a `Number`. + * @example + *
+ * + * ```javascript + * import { hexToNumber } from '@pezkuwi/util'; + * + * hexToNumber('0x1234'); // => 0x1234 + * ``` + */ +function hexToNumber(value) { + return value + ? (0, toBn_js_1.hexToBn)(value).toNumber() + : NaN; +} diff --git a/packages/util/cjs/hex/toString.d.ts b/packages/util/cjs/hex/toString.d.ts new file mode 100644 index 0000000..db6e26f --- /dev/null +++ b/packages/util/cjs/hex/toString.d.ts @@ -0,0 +1,15 @@ +/** + * @name hexToU8a + * @summary Creates a Uint8Array object from a hex string. + * @description + * Hex input values return the actual bytes value converted to a string. Anything that is not a hex string (including the `0x` prefix) throws an error. + * @example + *
+ * + * ```javascript + * import { hexToString } from '@pezkuwi/util'; + * + * hexToU8a('0x68656c6c6f'); // hello + * ``` + */ +export declare function hexToString(_value?: string | null): string; diff --git a/packages/util/cjs/hex/toString.js b/packages/util/cjs/hex/toString.js new file mode 100644 index 0000000..746391c --- /dev/null +++ b/packages/util/cjs/hex/toString.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hexToString = hexToString; +const toString_js_1 = require("../u8a/toString.js"); +const toU8a_js_1 = require("./toU8a.js"); +/** + * @name hexToU8a + * @summary Creates a Uint8Array object from a hex string. + * @description + * Hex input values return the actual bytes value converted to a string. Anything that is not a hex string (including the `0x` prefix) throws an error. + * @example + *
+ * + * ```javascript + * import { hexToString } from '@pezkuwi/util'; + * + * hexToU8a('0x68656c6c6f'); // hello + * ``` + */ +function hexToString(_value) { + return (0, toString_js_1.u8aToString)((0, toU8a_js_1.hexToU8a)(_value)); +} diff --git a/packages/util/cjs/hex/toU8a.d.ts b/packages/util/cjs/hex/toU8a.d.ts new file mode 100644 index 0000000..5a80f41 --- /dev/null +++ b/packages/util/cjs/hex/toU8a.d.ts @@ -0,0 +1,16 @@ +/** + * @name hexToU8a + * @summary Creates a Uint8Array object from a hex string. + * @description + * `null` inputs returns an empty `Uint8Array` result. Hex input values return the actual bytes value converted to a Uint8Array. Anything that is not a hex string (including the `0x` prefix) throws an error. + * @example + *
+ * + * ```javascript + * import { hexToU8a } from '@pezkuwi/util'; + * + * hexToU8a('0x80001f'); // Uint8Array([0x80, 0x00, 0x1f]) + * hexToU8a('0x80001f', 32); // Uint8Array([0x00, 0x80, 0x00, 0x1f]) + * ``` + */ +export declare function hexToU8a(value?: string | null, bitLength?: number): Uint8Array; diff --git a/packages/util/cjs/hex/toU8a.js b/packages/util/cjs/hex/toU8a.js new file mode 100644 index 0000000..0e44b27 --- /dev/null +++ b/packages/util/cjs/hex/toU8a.js @@ -0,0 +1,57 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hexToU8a = hexToU8a; +const CHR = '0123456789abcdef'; +const U8 = new Uint8Array(256); +const U16 = new Uint8Array(256 * 256); +for (let i = 0, count = CHR.length; i < count; i++) { + U8[CHR[i].charCodeAt(0) | 0] = i | 0; + if (i > 9) { + U8[CHR[i].toUpperCase().charCodeAt(0) | 0] = i | 0; + } +} +for (let i = 0; i < 256; i++) { + const s = i << 8; + for (let j = 0; j < 256; j++) { + U16[s | j] = (U8[i] << 4) | U8[j]; + } +} +/** + * @name hexToU8a + * @summary Creates a Uint8Array object from a hex string. + * @description + * `null` inputs returns an empty `Uint8Array` result. Hex input values return the actual bytes value converted to a Uint8Array. Anything that is not a hex string (including the `0x` prefix) throws an error. + * @example + *
+ * + * ```javascript + * import { hexToU8a } from '@pezkuwi/util'; + * + * hexToU8a('0x80001f'); // Uint8Array([0x80, 0x00, 0x1f]) + * hexToU8a('0x80001f', 32); // Uint8Array([0x00, 0x80, 0x00, 0x1f]) + * ``` + */ +function hexToU8a(value, bitLength = -1) { + if (!value) { + return new Uint8Array(); + } + let s = value.startsWith('0x') + ? 2 + : 0; + const decLength = Math.ceil((value.length - s) / 2); + const endLength = Math.ceil(bitLength === -1 + ? decLength + : bitLength / 8); + const result = new Uint8Array(endLength); + const offset = endLength > decLength + ? endLength - decLength + : 0; + for (let i = offset; i < endLength; i++, s += 2) { + // The big factor here is actually the string lookups. If we do + // HEX_TO_U16[value.substring()] we get an 10x slowdown. In the + // same vein using charCodeAt (as opposed to value[s] or value.charAt(s)) is + // also the faster operation by at least 2x with the character map above + result[i] = U16[(value.charCodeAt(s) << 8) | value.charCodeAt(s + 1)]; + } + return result; +} diff --git a/packages/util/cjs/hex/toU8aBuffer.d.ts b/packages/util/cjs/hex/toU8aBuffer.d.ts new file mode 100644 index 0000000..c4288cb --- /dev/null +++ b/packages/util/cjs/hex/toU8aBuffer.d.ts @@ -0,0 +1,16 @@ +/** + * @name hexToU8a + * @summary Creates a Uint8Array object from a hex string. + * @description + * `null` inputs returns an empty `Uint8Array` result. Hex input values return the actual bytes value converted to a Uint8Array. Anything that is not a hex string (including the `0x` prefix) throws an error. + * @example + *
+ * + * ```javascript + * import { hexToU8a } from '@pezkuwi/util'; + * + * hexToU8a('0x80001f'); // Uint8Array([0x80, 0x00, 0x1f]) + * hexToU8a('0x80001f', 32); // Uint8Array([0x00, 0x80, 0x00, 0x1f]) + * ``` + */ +export declare function hexToU8a(_value?: string | null, bitLength?: number): Uint8Array; diff --git a/packages/util/cjs/hex/toU8aBuffer.js b/packages/util/cjs/hex/toU8aBuffer.js new file mode 100644 index 0000000..eb7fc1a --- /dev/null +++ b/packages/util/cjs/hex/toU8aBuffer.js @@ -0,0 +1,43 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hexToU8a = hexToU8a; +/** + * @name hexToU8a + * @summary Creates a Uint8Array object from a hex string. + * @description + * `null` inputs returns an empty `Uint8Array` result. Hex input values return the actual bytes value converted to a Uint8Array. Anything that is not a hex string (including the `0x` prefix) throws an error. + * @example + *
+ * + * ```javascript + * import { hexToU8a } from '@pezkuwi/util'; + * + * hexToU8a('0x80001f'); // Uint8Array([0x80, 0x00, 0x1f]) + * hexToU8a('0x80001f', 32); // Uint8Array([0x00, 0x80, 0x00, 0x1f]) + * ``` + */ +function hexToU8a(_value, bitLength = -1) { + if (!_value) { + return new Uint8Array(); + } + const value = _value.startsWith('0x') + ? _value.substring(2) + : _value; + const buf = Buffer.from(value, 'hex'); + const valLength = value.length / 2; + const resultLength = Math.ceil(bitLength === -1 + ? valLength + : bitLength / 8); + if (resultLength === valLength) { + return Uint8Array.from(buf); + } + const offset = resultLength > valLength + ? resultLength - valLength + : 0; + if (offset) { + const u8a = new Uint8Array(resultLength); + u8a.set(buf, offset); + return u8a; + } + return Uint8Array.from(buf.subarray(0, resultLength)); +} diff --git a/packages/util/cjs/index.d.ts b/packages/util/cjs/index.d.ts new file mode 100644 index 0000000..ca3f403 --- /dev/null +++ b/packages/util/cjs/index.d.ts @@ -0,0 +1,2 @@ +import './packageDetect.js'; +export * from './bundle.js'; diff --git a/packages/util/cjs/index.js b/packages/util/cjs/index.js new file mode 100644 index 0000000..6d0bab1 --- /dev/null +++ b/packages/util/cjs/index.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +require("./packageDetect.js"); +tslib_1.__exportStar(require("./bundle.js"), exports); diff --git a/packages/util/cjs/is/array.d.ts b/packages/util/cjs/is/array.d.ts new file mode 100644 index 0000000..01b861f --- /dev/null +++ b/packages/util/cjs/is/array.d.ts @@ -0,0 +1,5 @@ +/** + * @name isArray + * @summary Tests for a Array instance. + */ +export declare function isArray(value?: unknown): value is T[]; diff --git a/packages/util/cjs/is/array.js b/packages/util/cjs/is/array.js new file mode 100644 index 0000000..17e9ed3 --- /dev/null +++ b/packages/util/cjs/is/array.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isArray = isArray; +/** + * @name isArray + * @summary Tests for a Array instance. + */ +function isArray(value) { + return Array.isArray(value); +} diff --git a/packages/util/cjs/is/ascii.d.ts b/packages/util/cjs/is/ascii.d.ts new file mode 100644 index 0000000..c5c836c --- /dev/null +++ b/packages/util/cjs/is/ascii.d.ts @@ -0,0 +1,8 @@ +import type { U8aLike } from '../types.js'; +/** + * @name isAscii + * @summary Tests if the input is printable ASCII + * @description + * Checks to see if the input string or Uint8Array is printable ASCII, 32-127 + formatters + */ +export declare function isAscii(value?: U8aLike | null): boolean; diff --git a/packages/util/cjs/is/ascii.js b/packages/util/cjs/is/ascii.js new file mode 100644 index 0000000..8cb8c3c --- /dev/null +++ b/packages/util/cjs/is/ascii.js @@ -0,0 +1,43 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isAscii = isAscii; +const toU8a_js_1 = require("../u8a/toU8a.js"); +const hex_js_1 = require("./hex.js"); +const string_js_1 = require("./string.js"); +/** @internal */ +function isAsciiStr(str) { + for (let i = 0, count = str.length; i < count; i++) { + const b = str.charCodeAt(i); + // check is inlined here, it is faster than making a call + if (b < 32 || b > 126) { + return false; + } + } + return true; +} +/** @internal */ +function isAsciiBytes(u8a) { + for (let i = 0, count = u8a.length; i < count; i++) { + const b = u8a[i] | 0; + // check is inlined here, it is faster than making a call + if (b < 32 || b > 126) { + return false; + } + } + return true; +} +/** + * @name isAscii + * @summary Tests if the input is printable ASCII + * @description + * Checks to see if the input string or Uint8Array is printable ASCII, 32-127 + formatters + */ +function isAscii(value) { + return (0, string_js_1.isString)(value) + ? (0, hex_js_1.isHex)(value) + ? isAsciiBytes((0, toU8a_js_1.u8aToU8a)(value)) + : isAsciiStr(value) + : value + ? isAsciiBytes(value) + : false; +} diff --git a/packages/util/cjs/is/bigInt.d.ts b/packages/util/cjs/is/bigInt.d.ts new file mode 100644 index 0000000..d5c3a7d --- /dev/null +++ b/packages/util/cjs/is/bigInt.d.ts @@ -0,0 +1,15 @@ +/** + * @name isBigInt + * @summary Tests for a `BigInt` object instance. + * @description + * Checks to see if the input object is an instance of `BigInt` + * @example + *
+ * + * ```javascript + * import { isBigInt } from '@pezkuwi/util'; + * + * console.log('isBigInt', isBigInt(123_456n)); // => true + * ``` + */ +export declare function isBigInt(value: unknown): value is bigint; diff --git a/packages/util/cjs/is/bigInt.js b/packages/util/cjs/is/bigInt.js new file mode 100644 index 0000000..e0c3651 --- /dev/null +++ b/packages/util/cjs/is/bigInt.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isBigInt = isBigInt; +/** + * @name isBigInt + * @summary Tests for a `BigInt` object instance. + * @description + * Checks to see if the input object is an instance of `BigInt` + * @example + *
+ * + * ```javascript + * import { isBigInt } from '@pezkuwi/util'; + * + * console.log('isBigInt', isBigInt(123_456n)); // => true + * ``` + */ +function isBigInt(value) { + return typeof value === 'bigint'; +} diff --git a/packages/util/cjs/is/bn.d.ts b/packages/util/cjs/is/bn.d.ts new file mode 100644 index 0000000..e036b0b --- /dev/null +++ b/packages/util/cjs/is/bn.d.ts @@ -0,0 +1,17 @@ +import { BN } from '../bn/bn.js'; +/** + * @name isBn + * @summary Tests for a `BN` object instance. + * @description + * Checks to see if the input object is an instance of `BN` (bn.js). + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { isBn } from '@pezkuwi/util'; + * + * console.log('isBn', isBn(new BN(1))); // => true + * ``` + */ +export declare function isBn(value: unknown): value is BN; diff --git a/packages/util/cjs/is/bn.js b/packages/util/cjs/is/bn.js new file mode 100644 index 0000000..eda5329 --- /dev/null +++ b/packages/util/cjs/is/bn.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isBn = isBn; +const bn_js_1 = require("../bn/bn.js"); +/** + * @name isBn + * @summary Tests for a `BN` object instance. + * @description + * Checks to see if the input object is an instance of `BN` (bn.js). + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { isBn } from '@pezkuwi/util'; + * + * console.log('isBn', isBn(new BN(1))); // => true + * ``` + */ +function isBn(value) { + return bn_js_1.BN.isBN(value); +} diff --git a/packages/util/cjs/is/boolean.d.ts b/packages/util/cjs/is/boolean.d.ts new file mode 100644 index 0000000..a19316a --- /dev/null +++ b/packages/util/cjs/is/boolean.d.ts @@ -0,0 +1,15 @@ +/** + * @name isBoolean + * @summary Tests for a boolean value. + * @description + * Checks to see if the input value is a JavaScript boolean. + * @example + *
+ * + * ```javascript + * import { isBoolean } from '@pezkuwi/util'; + * + * isBoolean(false); // => true + * ``` + */ +export declare function isBoolean(value: unknown): value is boolean; diff --git a/packages/util/cjs/is/boolean.js b/packages/util/cjs/is/boolean.js new file mode 100644 index 0000000..46cf273 --- /dev/null +++ b/packages/util/cjs/is/boolean.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isBoolean = isBoolean; +/** + * @name isBoolean + * @summary Tests for a boolean value. + * @description + * Checks to see if the input value is a JavaScript boolean. + * @example + *
+ * + * ```javascript + * import { isBoolean } from '@pezkuwi/util'; + * + * isBoolean(false); // => true + * ``` + */ +function isBoolean(value) { + return typeof value === 'boolean'; +} diff --git a/packages/util/cjs/is/buffer.d.ts b/packages/util/cjs/is/buffer.d.ts new file mode 100644 index 0000000..da85d08 --- /dev/null +++ b/packages/util/cjs/is/buffer.d.ts @@ -0,0 +1,16 @@ +import type { BufferObject } from '../types.js'; +/** + * @name isBuffer + * @summary Tests for a `Buffer` object instance. + * @description + * Checks to see if the input object is an instance of `Buffer`. + * @example + *
+ * + * ```javascript + * import { isBuffer } from '@pezkuwi/util'; + * + * console.log('isBuffer', isBuffer(Buffer.from([]))); // => true + * ``` + */ +export declare function isBuffer(value: unknown): value is T; diff --git a/packages/util/cjs/is/buffer.js b/packages/util/cjs/is/buffer.js new file mode 100644 index 0000000..c5227d3 --- /dev/null +++ b/packages/util/cjs/is/buffer.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isBuffer = isBuffer; +const x_global_1 = require("@pezkuwi/x-global"); +const has_js_1 = require("../has.js"); +const function_js_1 = require("./function.js"); +/** + * @name isBuffer + * @summary Tests for a `Buffer` object instance. + * @description + * Checks to see if the input object is an instance of `Buffer`. + * @example + *
+ * + * ```javascript + * import { isBuffer } from '@pezkuwi/util'; + * + * console.log('isBuffer', isBuffer(Buffer.from([]))); // => true + * ``` + */ +function isBuffer(value) { + // we do check a function first, since it is slightly faster than isBuffer itself + return has_js_1.hasBuffer && !!value && (0, function_js_1.isFunction)(value.readDoubleLE) && x_global_1.xglobal.Buffer.isBuffer(value); +} diff --git a/packages/util/cjs/is/childClass.d.ts b/packages/util/cjs/is/childClass.d.ts new file mode 100644 index 0000000..c7ab4fc --- /dev/null +++ b/packages/util/cjs/is/childClass.d.ts @@ -0,0 +1,17 @@ +import type { Class } from '../types.js'; +/** + * @name isChildClass + * @summary Tests if the child extends the parent Class + * @description + * Checks to see if the child Class extends the parent Class + * @example + *
+ * + * ```javascript + * import { isChildClass } from '@pezkuwi/util'; + * + * console.log('isChildClass', isChildClass(BN, BN); // => true + * console.log('isChildClass', isChildClass(BN, Uint8Array); // => false + * ``` + */ +export declare function isChildClass

(Parent: P, Child?: unknown): Child is P; diff --git a/packages/util/cjs/is/childClass.js b/packages/util/cjs/is/childClass.js new file mode 100644 index 0000000..8abb4f0 --- /dev/null +++ b/packages/util/cjs/is/childClass.js @@ -0,0 +1,26 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isChildClass = isChildClass; +const class_js_1 = require("./class.js"); +/** + * @name isChildClass + * @summary Tests if the child extends the parent Class + * @description + * Checks to see if the child Class extends the parent Class + * @example + *
+ * + * ```javascript + * import { isChildClass } from '@pezkuwi/util'; + * + * console.log('isChildClass', isChildClass(BN, BN); // => true + * console.log('isChildClass', isChildClass(BN, Uint8Array); // => false + * ``` + */ +function isChildClass(Parent, Child) { + // https://stackoverflow.com/questions/30993434/check-if-a-constructor-inherits-another-in-es6/30993664 + return (0, class_js_1.isClass)(Child) && (0, class_js_1.isClass)(Parent) + // eslint-disable-next-line no-prototype-builtins + ? Parent === Child || Parent.isPrototypeOf(Child) + : false; +} diff --git a/packages/util/cjs/is/class.d.ts b/packages/util/cjs/is/class.d.ts new file mode 100644 index 0000000..d319ab8 --- /dev/null +++ b/packages/util/cjs/is/class.d.ts @@ -0,0 +1,6 @@ +import type { Class } from '../types.js'; +/** + * @name isClass + * Tests if the supplied argument is a Class + */ +export declare const isClass: (value?: unknown) => value is T; diff --git a/packages/util/cjs/is/class.js b/packages/util/cjs/is/class.js new file mode 100644 index 0000000..c7aa4b3 --- /dev/null +++ b/packages/util/cjs/is/class.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isClass = void 0; +const helpers_js_1 = require("./helpers.js"); +/** + * @name isClass + * Tests if the supplied argument is a Class + */ +exports.isClass = (0, helpers_js_1.isOnFunction)('isPrototypeOf', 'hasOwnProperty'); diff --git a/packages/util/cjs/is/codec.d.ts b/packages/util/cjs/is/codec.d.ts new file mode 100644 index 0000000..511e559 --- /dev/null +++ b/packages/util/cjs/is/codec.d.ts @@ -0,0 +1,12 @@ +import type { HexString } from '../types.js'; +interface Registry { + get: (...params: never[]) => any; +} +interface Codec { + readonly registry: Registry; + toHex(...params: never[]): HexString; + toHuman(...params: never[]): unknown; + toU8a: (...params: never[]) => Uint8Array; +} +export declare function isCodec(value?: unknown): value is T; +export {}; diff --git a/packages/util/cjs/is/codec.js b/packages/util/cjs/is/codec.js new file mode 100644 index 0000000..5c2a324 --- /dev/null +++ b/packages/util/cjs/is/codec.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isCodec = isCodec; +const helpers_js_1 = require("./helpers.js"); +const checkCodec = /*#__PURE__*/ (0, helpers_js_1.isOnObject)('toHex', 'toHuman', 'toU8a'); +const checkRegistry = /*#__PURE__*/ (0, helpers_js_1.isOnObject)('get'); +function isCodec(value) { + return checkCodec(value) && checkRegistry(value.registry); +} diff --git a/packages/util/cjs/is/compact.d.ts b/packages/util/cjs/is/compact.d.ts new file mode 100644 index 0000000..6117210 --- /dev/null +++ b/packages/util/cjs/is/compact.d.ts @@ -0,0 +1,13 @@ +import type { BN } from '../bn/bn.js'; +interface Compact { + toBigInt(): bigint; + toBn(): BN; + toNumber(): number; + unwrap(): T; +} +/** + * @name isCompact + * @summary Tests for SCALE-Compact-like object instance. + */ +export declare const isCompact: (value?: unknown) => value is Compact; +export {}; diff --git a/packages/util/cjs/is/compact.js b/packages/util/cjs/is/compact.js new file mode 100644 index 0000000..fda42f8 --- /dev/null +++ b/packages/util/cjs/is/compact.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isCompact = void 0; +const helpers_js_1 = require("./helpers.js"); +/** + * @name isCompact + * @summary Tests for SCALE-Compact-like object instance. + */ +exports.isCompact = (0, helpers_js_1.isOnObject)('toBigInt', 'toBn', 'toNumber', 'unwrap'); diff --git a/packages/util/cjs/is/error.d.ts b/packages/util/cjs/is/error.d.ts new file mode 100644 index 0000000..97ba8d2 --- /dev/null +++ b/packages/util/cjs/is/error.d.ts @@ -0,0 +1,15 @@ +/** + * @name isError + * @summary Tests for a `Error` object instance. + * @description + * Checks to see if the input object is an instance of `Error`. + * @example + *
+ * + * ```javascript + * import { isError } from '@pezkuwi/util'; + * + * console.log('isError', isError(new Error('message'))); // => true + * ``` + */ +export declare function isError(value: unknown): value is Error; diff --git a/packages/util/cjs/is/error.js b/packages/util/cjs/is/error.js new file mode 100644 index 0000000..34ed72e --- /dev/null +++ b/packages/util/cjs/is/error.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isError = isError; +/** + * @name isError + * @summary Tests for a `Error` object instance. + * @description + * Checks to see if the input object is an instance of `Error`. + * @example + *
+ * + * ```javascript + * import { isError } from '@pezkuwi/util'; + * + * console.log('isError', isError(new Error('message'))); // => true + * ``` + */ +function isError(value) { + return (((value && value.constructor) === Error) || + value instanceof Error); +} diff --git a/packages/util/cjs/is/function.d.ts b/packages/util/cjs/is/function.d.ts new file mode 100644 index 0000000..7f09bde --- /dev/null +++ b/packages/util/cjs/is/function.d.ts @@ -0,0 +1,17 @@ +type FnType = Function; +/** + * @name isFunction + * @summary Tests for a `function`. + * @description + * Checks to see if the input value is a JavaScript function. + * @example + *
+ * + * ```javascript + * import { isFunction } from '@pezkuwi/util'; + * + * isFunction(() => false); // => true + * ``` + */ +export declare function isFunction(value: unknown): value is FnType; +export {}; diff --git a/packages/util/cjs/is/function.js b/packages/util/cjs/is/function.js new file mode 100644 index 0000000..315a826 --- /dev/null +++ b/packages/util/cjs/is/function.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isFunction = isFunction; +/** + * @name isFunction + * @summary Tests for a `function`. + * @description + * Checks to see if the input value is a JavaScript function. + * @example + *
+ * + * ```javascript + * import { isFunction } from '@pezkuwi/util'; + * + * isFunction(() => false); // => true + * ``` + */ +function isFunction(value) { + return typeof value === 'function'; +} diff --git a/packages/util/cjs/is/helpers.d.ts b/packages/util/cjs/is/helpers.d.ts new file mode 100644 index 0000000..41f5e5a --- /dev/null +++ b/packages/util/cjs/is/helpers.d.ts @@ -0,0 +1,3 @@ +export declare function isOn(...fns: (keyof T)[]): (value?: unknown) => value is T; +export declare function isOnFunction(...fns: (keyof T)[]): (value?: unknown) => value is T; +export declare function isOnObject(...fns: (keyof T)[]): (value?: unknown) => value is T; diff --git a/packages/util/cjs/is/helpers.js b/packages/util/cjs/is/helpers.js new file mode 100644 index 0000000..193bf5a --- /dev/null +++ b/packages/util/cjs/is/helpers.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isOn = isOn; +exports.isOnFunction = isOnFunction; +exports.isOnObject = isOnObject; +const function_js_1 = require("./function.js"); +const object_js_1 = require("./object.js"); +function isOn(...fns) { + return (value) => ((0, object_js_1.isObject)(value) || (0, function_js_1.isFunction)(value)) && + fns.every((f) => (0, function_js_1.isFunction)(value[f])); +} +function isOnFunction(...fns) { + return (value) => (0, function_js_1.isFunction)(value) && + fns.every((f) => (0, function_js_1.isFunction)(value[f])); +} +function isOnObject(...fns) { + return (value) => (0, object_js_1.isObject)(value) && + fns.every((f) => (0, function_js_1.isFunction)(value[f])); +} diff --git a/packages/util/cjs/is/hex.d.ts b/packages/util/cjs/is/hex.d.ts new file mode 100644 index 0000000..2fcabbd --- /dev/null +++ b/packages/util/cjs/is/hex.d.ts @@ -0,0 +1,19 @@ +import type { HexString } from '../types.js'; +export declare const REGEX_HEX_PREFIXED: RegExp; +export declare const REGEX_HEX_NOPREFIX: RegExp; +/** + * @name isHex + * @summary Tests for a hex string. + * @description + * Checks to see if the input value is a `0x` prefixed hex string. Optionally (`bitLength` !== -1) checks to see if the bitLength is correct. + * @example + *
+ * + * ```javascript + * import { isHex } from '@pezkuwi/util'; + * + * isHex('0x1234'); // => true + * isHex('0x1234', 8); // => false + * ``` + */ +export declare function isHex(value: unknown, bitLength?: number, ignoreLength?: boolean): value is HexString; diff --git a/packages/util/cjs/is/hex.js b/packages/util/cjs/is/hex.js new file mode 100644 index 0000000..50353eb --- /dev/null +++ b/packages/util/cjs/is/hex.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.REGEX_HEX_NOPREFIX = exports.REGEX_HEX_PREFIXED = void 0; +exports.isHex = isHex; +exports.REGEX_HEX_PREFIXED = /^0x[\da-fA-F]+$/; +exports.REGEX_HEX_NOPREFIX = /^[\da-fA-F]+$/; +/** + * @name isHex + * @summary Tests for a hex string. + * @description + * Checks to see if the input value is a `0x` prefixed hex string. Optionally (`bitLength` !== -1) checks to see if the bitLength is correct. + * @example + *
+ * + * ```javascript + * import { isHex } from '@pezkuwi/util'; + * + * isHex('0x1234'); // => true + * isHex('0x1234', 8); // => false + * ``` + */ +function isHex(value, bitLength = -1, ignoreLength) { + return (typeof value === 'string' && (value === '0x' || + exports.REGEX_HEX_PREFIXED.test(value))) && (bitLength === -1 + ? (ignoreLength || (value.length % 2 === 0)) + : (value.length === (2 + Math.ceil(bitLength / 4)))); +} diff --git a/packages/util/cjs/is/index.d.ts b/packages/util/cjs/is/index.d.ts new file mode 100644 index 0000000..748c53e --- /dev/null +++ b/packages/util/cjs/is/index.d.ts @@ -0,0 +1,33 @@ +/** + * @summary Type checking utilities + */ +export { isArray } from './array.js'; +export { isAscii } from './ascii.js'; +export { isBigInt } from './bigInt.js'; +export { isBn } from './bn.js'; +export { isBoolean } from './boolean.js'; +export { isBuffer } from './buffer.js'; +export { isChildClass } from './childClass.js'; +export { isClass } from './class.js'; +export { isCodec } from './codec.js'; +export { isCompact } from './compact.js'; +export { isError } from './error.js'; +export { isFunction } from './function.js'; +export { isHex } from './hex.js'; +export { isInstanceOf } from './instanceOf.js'; +export { isIp } from './ip.js'; +export { isJsonObject } from './jsonObject.js'; +export { isNull } from './null.js'; +export { isNumber } from './number.js'; +export { isObject } from './object.js'; +export { isObservable } from './observable.js'; +export { isPromise } from './promise.js'; +export { isRiscV } from './riscv.js'; +export { isString } from './string.js'; +export { isTestChain } from './testChain.js'; +export { isToBigInt } from './toBigInt.js'; +export { isToBn } from './toBn.js'; +export { isU8a } from './u8a.js'; +export { isUndefined } from './undefined.js'; +export { isUtf8 } from './utf8.js'; +export { isWasm } from './wasm.js'; diff --git a/packages/util/cjs/is/index.js b/packages/util/cjs/is/index.js new file mode 100644 index 0000000..d213c08 --- /dev/null +++ b/packages/util/cjs/is/index.js @@ -0,0 +1,66 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isWasm = exports.isUtf8 = exports.isUndefined = exports.isU8a = exports.isToBn = exports.isToBigInt = exports.isTestChain = exports.isString = exports.isRiscV = exports.isPromise = exports.isObservable = exports.isObject = exports.isNumber = exports.isNull = exports.isJsonObject = exports.isIp = exports.isInstanceOf = exports.isHex = exports.isFunction = exports.isError = exports.isCompact = exports.isCodec = exports.isClass = exports.isChildClass = exports.isBuffer = exports.isBoolean = exports.isBn = exports.isBigInt = exports.isAscii = exports.isArray = void 0; +/** + * @summary Type checking utilities + */ +var array_js_1 = require("./array.js"); +Object.defineProperty(exports, "isArray", { enumerable: true, get: function () { return array_js_1.isArray; } }); +var ascii_js_1 = require("./ascii.js"); +Object.defineProperty(exports, "isAscii", { enumerable: true, get: function () { return ascii_js_1.isAscii; } }); +var bigInt_js_1 = require("./bigInt.js"); +Object.defineProperty(exports, "isBigInt", { enumerable: true, get: function () { return bigInt_js_1.isBigInt; } }); +var bn_js_1 = require("./bn.js"); +Object.defineProperty(exports, "isBn", { enumerable: true, get: function () { return bn_js_1.isBn; } }); +var boolean_js_1 = require("./boolean.js"); +Object.defineProperty(exports, "isBoolean", { enumerable: true, get: function () { return boolean_js_1.isBoolean; } }); +var buffer_js_1 = require("./buffer.js"); +Object.defineProperty(exports, "isBuffer", { enumerable: true, get: function () { return buffer_js_1.isBuffer; } }); +var childClass_js_1 = require("./childClass.js"); +Object.defineProperty(exports, "isChildClass", { enumerable: true, get: function () { return childClass_js_1.isChildClass; } }); +var class_js_1 = require("./class.js"); +Object.defineProperty(exports, "isClass", { enumerable: true, get: function () { return class_js_1.isClass; } }); +var codec_js_1 = require("./codec.js"); +Object.defineProperty(exports, "isCodec", { enumerable: true, get: function () { return codec_js_1.isCodec; } }); +var compact_js_1 = require("./compact.js"); +Object.defineProperty(exports, "isCompact", { enumerable: true, get: function () { return compact_js_1.isCompact; } }); +var error_js_1 = require("./error.js"); +Object.defineProperty(exports, "isError", { enumerable: true, get: function () { return error_js_1.isError; } }); +var function_js_1 = require("./function.js"); +Object.defineProperty(exports, "isFunction", { enumerable: true, get: function () { return function_js_1.isFunction; } }); +var hex_js_1 = require("./hex.js"); +Object.defineProperty(exports, "isHex", { enumerable: true, get: function () { return hex_js_1.isHex; } }); +var instanceOf_js_1 = require("./instanceOf.js"); +Object.defineProperty(exports, "isInstanceOf", { enumerable: true, get: function () { return instanceOf_js_1.isInstanceOf; } }); +var ip_js_1 = require("./ip.js"); +Object.defineProperty(exports, "isIp", { enumerable: true, get: function () { return ip_js_1.isIp; } }); +var jsonObject_js_1 = require("./jsonObject.js"); +Object.defineProperty(exports, "isJsonObject", { enumerable: true, get: function () { return jsonObject_js_1.isJsonObject; } }); +var null_js_1 = require("./null.js"); +Object.defineProperty(exports, "isNull", { enumerable: true, get: function () { return null_js_1.isNull; } }); +var number_js_1 = require("./number.js"); +Object.defineProperty(exports, "isNumber", { enumerable: true, get: function () { return number_js_1.isNumber; } }); +var object_js_1 = require("./object.js"); +Object.defineProperty(exports, "isObject", { enumerable: true, get: function () { return object_js_1.isObject; } }); +var observable_js_1 = require("./observable.js"); +Object.defineProperty(exports, "isObservable", { enumerable: true, get: function () { return observable_js_1.isObservable; } }); +var promise_js_1 = require("./promise.js"); +Object.defineProperty(exports, "isPromise", { enumerable: true, get: function () { return promise_js_1.isPromise; } }); +var riscv_js_1 = require("./riscv.js"); +Object.defineProperty(exports, "isRiscV", { enumerable: true, get: function () { return riscv_js_1.isRiscV; } }); +var string_js_1 = require("./string.js"); +Object.defineProperty(exports, "isString", { enumerable: true, get: function () { return string_js_1.isString; } }); +var testChain_js_1 = require("./testChain.js"); +Object.defineProperty(exports, "isTestChain", { enumerable: true, get: function () { return testChain_js_1.isTestChain; } }); +var toBigInt_js_1 = require("./toBigInt.js"); +Object.defineProperty(exports, "isToBigInt", { enumerable: true, get: function () { return toBigInt_js_1.isToBigInt; } }); +var toBn_js_1 = require("./toBn.js"); +Object.defineProperty(exports, "isToBn", { enumerable: true, get: function () { return toBn_js_1.isToBn; } }); +var u8a_js_1 = require("./u8a.js"); +Object.defineProperty(exports, "isU8a", { enumerable: true, get: function () { return u8a_js_1.isU8a; } }); +var undefined_js_1 = require("./undefined.js"); +Object.defineProperty(exports, "isUndefined", { enumerable: true, get: function () { return undefined_js_1.isUndefined; } }); +var utf8_js_1 = require("./utf8.js"); +Object.defineProperty(exports, "isUtf8", { enumerable: true, get: function () { return utf8_js_1.isUtf8; } }); +var wasm_js_1 = require("./wasm.js"); +Object.defineProperty(exports, "isWasm", { enumerable: true, get: function () { return wasm_js_1.isWasm; } }); diff --git a/packages/util/cjs/is/instanceOf.d.ts b/packages/util/cjs/is/instanceOf.d.ts new file mode 100644 index 0000000..1783692 --- /dev/null +++ b/packages/util/cjs/is/instanceOf.d.ts @@ -0,0 +1,15 @@ +/** + * @name isInstanceOf + * @summary Tests for a instance of a class. + * @description + * Checks to see if the input value is an instance of the test class. + * @example + *
+ * + * ```javascript + * import { isInstanceOf } from '@pezkuwi/util'; + * + * console.log('isInstanceOf', isInstanceOf(new Array(0), Array)); // => true + * ``` + */ +export declare function isInstanceOf(value: unknown, Clazz: Function): boolean; diff --git a/packages/util/cjs/is/instanceOf.js b/packages/util/cjs/is/instanceOf.js new file mode 100644 index 0000000..360a0b5 --- /dev/null +++ b/packages/util/cjs/is/instanceOf.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isInstanceOf = isInstanceOf; +/** + * @name isInstanceOf + * @summary Tests for a instance of a class. + * @description + * Checks to see if the input value is an instance of the test class. + * @example + *
+ * + * ```javascript + * import { isInstanceOf } from '@pezkuwi/util'; + * + * console.log('isInstanceOf', isInstanceOf(new Array(0), Array)); // => true + * ``` + */ +function isInstanceOf(value, Clazz) { + return (((value && value.constructor) === Clazz) || + value instanceof Clazz); +} diff --git a/packages/util/cjs/is/ip.d.ts b/packages/util/cjs/is/ip.d.ts new file mode 100644 index 0000000..7a8e94a --- /dev/null +++ b/packages/util/cjs/is/ip.d.ts @@ -0,0 +1,18 @@ +/** + * @name isIp + * @summary Tests if the value is a valid IP address + * @description + * Checks to see if the value is a valid IP address. Optionally check for either v4/v6 + * @example + *
+ * + * ```javascript + * import { isIp } from '@pezkuwi/util'; + * + * isIp('192.168.0.1')); // => true + * isIp('1:2:3:4:5:6:7:8'); // => true + * isIp('192.168.0.1', 'v6')); // => false + * isIp('1:2:3:4:5:6:7:8', 'v4'); // => false + * ``` + */ +export declare function isIp(value: string, type?: 'v4' | 'v6'): boolean; diff --git a/packages/util/cjs/is/ip.js b/packages/util/cjs/is/ip.js new file mode 100644 index 0000000..852e99a --- /dev/null +++ b/packages/util/cjs/is/ip.js @@ -0,0 +1,44 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isIp = isIp; +const v4 = '(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}'; +const v6s = '[a-fA-F\\d]{1,4}'; +const v6 = ` +(?: +(?:${v6s}:){7}(?:${v6s}|:)| // 1:2:3:4:5:6:7:: 1:2:3:4:5:6:7:8 +(?:${v6s}:){6}(?:${v4}|:${v6s}|:)| // 1:2:3:4:5:6:: 1:2:3:4:5:6::8 1:2:3:4:5:6::8 1:2:3:4:5:6::1.2.3.4 +(?:${v6s}:){5}(?::${v4}|(?::${v6s}){1,2}|:)| // 1:2:3:4:5:: 1:2:3:4:5::7:8 1:2:3:4:5::8 1:2:3:4:5::7:1.2.3.4 +(?:${v6s}:){4}(?:(?::${v6s}){0,1}:${v4}|(?::${v6s}){1,3}|:)| // 1:2:3:4:: 1:2:3:4::6:7:8 1:2:3:4::8 1:2:3:4::6:7:1.2.3.4 +(?:${v6s}:){3}(?:(?::${v6s}){0,2}:${v4}|(?::${v6s}){1,4}|:)| // 1:2:3:: 1:2:3::5:6:7:8 1:2:3::8 1:2:3::5:6:7:1.2.3.4 +(?:${v6s}:){2}(?:(?::${v6s}){0,3}:${v4}|(?::${v6s}){1,5}|:)| // 1:2:: 1:2::4:5:6:7:8 1:2::8 1:2::4:5:6:7:1.2.3.4 +(?:${v6s}:){1}(?:(?::${v6s}){0,4}:${v4}|(?::${v6s}){1,6}|:)| // 1:: 1::3:4:5:6:7:8 1::8 1::3:4:5:6:7:1.2.3.4 +(?::(?:(?::${v6s}){0,5}:${v4}|(?::${v6s}){1,7}|:)) // ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::1.2.3.4 +)(?:%[0-9a-zA-Z]{1,})? // %eth0 %1 +`.replace(/\s*\/\/.*$/gm, '').replace(/\n/g, '').trim(); +const v46Exact = new RegExp(`(?:^${v4}$)|(?:^${v6}$)`); +const v4exact = new RegExp(`^${v4}$`); +const v6exact = new RegExp(`^${v6}$`); +/** + * @name isIp + * @summary Tests if the value is a valid IP address + * @description + * Checks to see if the value is a valid IP address. Optionally check for either v4/v6 + * @example + *
+ * + * ```javascript + * import { isIp } from '@pezkuwi/util'; + * + * isIp('192.168.0.1')); // => true + * isIp('1:2:3:4:5:6:7:8'); // => true + * isIp('192.168.0.1', 'v6')); // => false + * isIp('1:2:3:4:5:6:7:8', 'v4'); // => false + * ``` + */ +function isIp(value, type) { + switch (type) { + case 'v4': return v4exact.test(value); + case 'v6': return v6exact.test(value); + default: return v46Exact.test(value); + } +} diff --git a/packages/util/cjs/is/jsonObject.d.ts b/packages/util/cjs/is/jsonObject.d.ts new file mode 100644 index 0000000..79479e3 --- /dev/null +++ b/packages/util/cjs/is/jsonObject.d.ts @@ -0,0 +1,27 @@ +type ObjectIndexed = Record; +/** + * @name isJsonObject + * @summary Tests for a valid JSON `object`. + * @description + * Checks to see if the input value is a valid JSON object. + * It returns false if the input is JSON parsable, but not an Javascript object. + * @example + *
+ * + * ```javascript + * import { isJsonObject } from '@pezkuwi/util'; + * + * isJsonObject({}); // => true + * isJsonObject({ + * "Test": "1234", + * "NestedTest": { + * "Test": "5678" + * } + * }); // => true + * isJsonObject(1234); // JSON parsable, but not an object => false + * isJsonObject(null); // JSON parsable, but not an object => false + * isJsonObject('not an object'); // => false + * ``` + */ +export declare function isJsonObject(value: unknown): value is ObjectIndexed; +export {}; diff --git a/packages/util/cjs/is/jsonObject.js b/packages/util/cjs/is/jsonObject.js new file mode 100644 index 0000000..b790d5f --- /dev/null +++ b/packages/util/cjs/is/jsonObject.js @@ -0,0 +1,40 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isJsonObject = isJsonObject; +const stringify_js_1 = require("../stringify.js"); +/** + * @name isJsonObject + * @summary Tests for a valid JSON `object`. + * @description + * Checks to see if the input value is a valid JSON object. + * It returns false if the input is JSON parsable, but not an Javascript object. + * @example + *
+ * + * ```javascript + * import { isJsonObject } from '@pezkuwi/util'; + * + * isJsonObject({}); // => true + * isJsonObject({ + * "Test": "1234", + * "NestedTest": { + * "Test": "5678" + * } + * }); // => true + * isJsonObject(1234); // JSON parsable, but not an object => false + * isJsonObject(null); // JSON parsable, but not an object => false + * isJsonObject('not an object'); // => false + * ``` + */ +function isJsonObject(value) { + const str = typeof value !== 'string' + ? (0, stringify_js_1.stringify)(value) + : value; + try { + const obj = JSON.parse(str); + return typeof obj === 'object' && obj !== null; + } + catch { + return false; + } +} diff --git a/packages/util/cjs/is/null.d.ts b/packages/util/cjs/is/null.d.ts new file mode 100644 index 0000000..8f20eb5 --- /dev/null +++ b/packages/util/cjs/is/null.d.ts @@ -0,0 +1,15 @@ +/** + * @name isNull + * @summary Tests for a `null` values. + * @description + * Checks to see if the input value is `null`. + * @example + *
+ * + * ```javascript + * import { isNull } from '@pezkuwi/util'; + * + * console.log('isNull', isNull(null)); // => true + * ``` + */ +export declare function isNull(value?: unknown): value is null; diff --git a/packages/util/cjs/is/null.js b/packages/util/cjs/is/null.js new file mode 100644 index 0000000..e4870e3 --- /dev/null +++ b/packages/util/cjs/is/null.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isNull = isNull; +/** + * @name isNull + * @summary Tests for a `null` values. + * @description + * Checks to see if the input value is `null`. + * @example + *
+ * + * ```javascript + * import { isNull } from '@pezkuwi/util'; + * + * console.log('isNull', isNull(null)); // => true + * ``` + */ +function isNull(value) { + return value === null; +} diff --git a/packages/util/cjs/is/number.d.ts b/packages/util/cjs/is/number.d.ts new file mode 100644 index 0000000..3f5934c --- /dev/null +++ b/packages/util/cjs/is/number.d.ts @@ -0,0 +1,15 @@ +/** + * @name isNumber + * @summary Tests for a JavaScript number. + * @description + * Checks to see if the input value is a valid number. + * @example + *
+ * + * ```javascript + * import { isNumber } from '@pezkuwi/util'; + * + * console.log('isNumber', isNumber(1234)); // => true + * ``` + */ +export declare function isNumber(value: unknown): value is number; diff --git a/packages/util/cjs/is/number.js b/packages/util/cjs/is/number.js new file mode 100644 index 0000000..1b154ff --- /dev/null +++ b/packages/util/cjs/is/number.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isNumber = isNumber; +/** + * @name isNumber + * @summary Tests for a JavaScript number. + * @description + * Checks to see if the input value is a valid number. + * @example + *
+ * + * ```javascript + * import { isNumber } from '@pezkuwi/util'; + * + * console.log('isNumber', isNumber(1234)); // => true + * ``` + */ +function isNumber(value) { + return typeof value === 'number'; +} diff --git a/packages/util/cjs/is/object.d.ts b/packages/util/cjs/is/object.d.ts new file mode 100644 index 0000000..610a4d4 --- /dev/null +++ b/packages/util/cjs/is/object.d.ts @@ -0,0 +1,18 @@ +type ObjectIndexed = Record; +/** + * @name isObject + * @summary Tests for an `object`. + * @description + * Checks to see if the input value is a JavaScript object. + * @example + *
+ * + * ```javascript + * import { isObject } from '@pezkuwi/util'; + * + * isObject({}); // => true + * isObject('something'); // => false + * ``` + */ +export declare function isObject(value?: unknown): value is T; +export {}; diff --git a/packages/util/cjs/is/object.js b/packages/util/cjs/is/object.js new file mode 100644 index 0000000..c2dfc19 --- /dev/null +++ b/packages/util/cjs/is/object.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isObject = isObject; +/** + * @name isObject + * @summary Tests for an `object`. + * @description + * Checks to see if the input value is a JavaScript object. + * @example + *
+ * + * ```javascript + * import { isObject } from '@pezkuwi/util'; + * + * isObject({}); // => true + * isObject('something'); // => false + * ``` + */ +function isObject(value) { + return !!value && typeof value === 'object'; +} diff --git a/packages/util/cjs/is/observable.d.ts b/packages/util/cjs/is/observable.d.ts new file mode 100644 index 0000000..cc09c1f --- /dev/null +++ b/packages/util/cjs/is/observable.d.ts @@ -0,0 +1,16 @@ +import type { Observable } from '../types.js'; +/** + * @name isBObservable + * @summary Tests for a `Observable` object instance. + * @description + * Checks to see if the input object is an instance of `BN` (bn.js). + * @example + *
+ * + * ```javascript + * import { isObservable } from '@pezkuwi/util'; + * + * console.log('isObservable', isObservable(...)); + * ``` + */ +export declare const isObservable: (value?: unknown) => value is Observable; diff --git a/packages/util/cjs/is/observable.js b/packages/util/cjs/is/observable.js new file mode 100644 index 0000000..f01406e --- /dev/null +++ b/packages/util/cjs/is/observable.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isObservable = void 0; +const helpers_js_1 = require("./helpers.js"); +/** + * @name isBObservable + * @summary Tests for a `Observable` object instance. + * @description + * Checks to see if the input object is an instance of `BN` (bn.js). + * @example + *
+ * + * ```javascript + * import { isObservable } from '@pezkuwi/util'; + * + * console.log('isObservable', isObservable(...)); + * ``` + */ +exports.isObservable = (0, helpers_js_1.isOn)('next'); diff --git a/packages/util/cjs/is/promise.d.ts b/packages/util/cjs/is/promise.d.ts new file mode 100644 index 0000000..2ee59f9 --- /dev/null +++ b/packages/util/cjs/is/promise.d.ts @@ -0,0 +1 @@ +export declare const isPromise: (value?: unknown) => value is Promise; diff --git a/packages/util/cjs/is/promise.js b/packages/util/cjs/is/promise.js new file mode 100644 index 0000000..80de741 --- /dev/null +++ b/packages/util/cjs/is/promise.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isPromise = void 0; +const helpers_js_1 = require("./helpers.js"); +exports.isPromise = (0, helpers_js_1.isOnObject)('catch', 'then'); diff --git a/packages/util/cjs/is/riscv.d.ts b/packages/util/cjs/is/riscv.d.ts new file mode 100644 index 0000000..2e8e034 --- /dev/null +++ b/packages/util/cjs/is/riscv.d.ts @@ -0,0 +1,7 @@ +/** + * @name isRiscV + * @summary Tests if the input has a RISC-V header + * @description + * Checks to see if the input Uint8Array contains a valid RISC-V header + */ +export declare function isRiscV(bytes: unknown): bytes is Uint8Array; diff --git a/packages/util/cjs/is/riscv.js b/packages/util/cjs/is/riscv.js new file mode 100644 index 0000000..79f9d97 --- /dev/null +++ b/packages/util/cjs/is/riscv.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isRiscV = isRiscV; +const eq_js_1 = require("../u8a/eq.js"); +const u8a_js_1 = require("./u8a.js"); +const ELF_MAGIC = new Uint8Array([0x7f, 0x45, 0x4c, 0x46]); // ELF magic bytes: 0x7f, 'E', 'L', 'F' +const PVM_MAGIC = new Uint8Array([0x50, 0x56, 0x4d, 0x00]); // 'P', 'V', 'M', 0x00 +/** + * @name isRiscV + * @summary Tests if the input has a RISC-V header + * @description + * Checks to see if the input Uint8Array contains a valid RISC-V header + */ +function isRiscV(bytes) { + if ((0, u8a_js_1.isU8a)(bytes)) { + const start = bytes.subarray(0, 4); + return (0, eq_js_1.u8aEq)(start, PVM_MAGIC) || (0, eq_js_1.u8aEq)(start, ELF_MAGIC); + } + return false; +} diff --git a/packages/util/cjs/is/string.d.ts b/packages/util/cjs/is/string.d.ts new file mode 100644 index 0000000..0873b6e --- /dev/null +++ b/packages/util/cjs/is/string.d.ts @@ -0,0 +1,16 @@ +import type { AnyString } from '../types.js'; +/** + * @name isString + * @summary Tests for a string. + * @description + * Checks to see if the input value is a JavaScript string. + * @example + *
+ * + * ```javascript + * import { isString } from '@pezkuwi/util'; + * + * console.log('isString', isString('test')); // => true + * ``` + */ +export declare function isString(value: unknown): value is AnyString; diff --git a/packages/util/cjs/is/string.js b/packages/util/cjs/is/string.js new file mode 100644 index 0000000..426feba --- /dev/null +++ b/packages/util/cjs/is/string.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isString = isString; +/** + * @name isString + * @summary Tests for a string. + * @description + * Checks to see if the input value is a JavaScript string. + * @example + *
+ * + * ```javascript + * import { isString } from '@pezkuwi/util'; + * + * console.log('isString', isString('test')); // => true + * ``` + */ +function isString(value) { + return typeof value === 'string' || value instanceof String; +} diff --git a/packages/util/cjs/is/testChain.d.ts b/packages/util/cjs/is/testChain.d.ts new file mode 100644 index 0000000..253a6f0 --- /dev/null +++ b/packages/util/cjs/is/testChain.d.ts @@ -0,0 +1 @@ +export declare function isTestChain(chain?: string | null): boolean; diff --git a/packages/util/cjs/is/testChain.js b/packages/util/cjs/is/testChain.js new file mode 100644 index 0000000..299d205 --- /dev/null +++ b/packages/util/cjs/is/testChain.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isTestChain = isTestChain; +const REGEX_DEV = /(Development|Local Testnet)$/; +function isTestChain(chain) { + if (!chain) { + return false; + } + return !!REGEX_DEV.test(chain.toString()); +} diff --git a/packages/util/cjs/is/toBigInt.d.ts b/packages/util/cjs/is/toBigInt.d.ts new file mode 100644 index 0000000..e05bb9d --- /dev/null +++ b/packages/util/cjs/is/toBigInt.d.ts @@ -0,0 +1,2 @@ +import type { ToBigInt } from '../types.js'; +export declare const isToBigInt: (value?: unknown) => value is ToBigInt; diff --git a/packages/util/cjs/is/toBigInt.js b/packages/util/cjs/is/toBigInt.js new file mode 100644 index 0000000..5304dfd --- /dev/null +++ b/packages/util/cjs/is/toBigInt.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isToBigInt = void 0; +const helpers_js_1 = require("./helpers.js"); +exports.isToBigInt = (0, helpers_js_1.isOn)('toBigInt'); diff --git a/packages/util/cjs/is/toBn.d.ts b/packages/util/cjs/is/toBn.d.ts new file mode 100644 index 0000000..73d7ec7 --- /dev/null +++ b/packages/util/cjs/is/toBn.d.ts @@ -0,0 +1,2 @@ +import type { ToBn } from '../types.js'; +export declare const isToBn: (value?: unknown) => value is ToBn; diff --git a/packages/util/cjs/is/toBn.js b/packages/util/cjs/is/toBn.js new file mode 100644 index 0000000..b5917bf --- /dev/null +++ b/packages/util/cjs/is/toBn.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isToBn = void 0; +const helpers_js_1 = require("./helpers.js"); +exports.isToBn = (0, helpers_js_1.isOn)('toBn'); diff --git a/packages/util/cjs/is/u8a.d.ts b/packages/util/cjs/is/u8a.d.ts new file mode 100644 index 0000000..52947ec --- /dev/null +++ b/packages/util/cjs/is/u8a.d.ts @@ -0,0 +1,15 @@ +/** + * @name isU8a + * @summary Tests for a `Uint8Array` object instance. + * @description + * Checks to see if the input object is an instance of `Uint8Array`. + * @example + *
+ * + * ```javascript + * import { isUint8Array } from '@pezkuwi/util'; + * + * console.log('isU8a', isU8a([])); // => false + * ``` + */ +export declare function isU8a(value?: unknown): value is Uint8Array; diff --git a/packages/util/cjs/is/u8a.js b/packages/util/cjs/is/u8a.js new file mode 100644 index 0000000..cd7fde1 --- /dev/null +++ b/packages/util/cjs/is/u8a.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isU8a = isU8a; +/** + * @name isU8a + * @summary Tests for a `Uint8Array` object instance. + * @description + * Checks to see if the input object is an instance of `Uint8Array`. + * @example + *
+ * + * ```javascript + * import { isUint8Array } from '@pezkuwi/util'; + * + * console.log('isU8a', isU8a([])); // => false + * ``` + */ +function isU8a(value) { + // here we defer the instanceof check which is actually slightly + // slower than just checking the constrctor (direct instances) + return (((value && value.constructor) === Uint8Array) || + value instanceof Uint8Array); +} diff --git a/packages/util/cjs/is/undefined.d.ts b/packages/util/cjs/is/undefined.d.ts new file mode 100644 index 0000000..2e17969 --- /dev/null +++ b/packages/util/cjs/is/undefined.d.ts @@ -0,0 +1,15 @@ +/** + * @name isUndefined + * @summary Tests for a `undefined` values. + * @description + * Checks to see if the input value is `undefined`. + * @example + *
+ * + * ```javascript + * import { isUndefined } from '@pezkuwi/util'; + * + * console.log('isUndefined', isUndefined(void(0))); // => true + * ``` + */ +export declare function isUndefined(value?: unknown): value is undefined; diff --git a/packages/util/cjs/is/undefined.js b/packages/util/cjs/is/undefined.js new file mode 100644 index 0000000..45f17f0 --- /dev/null +++ b/packages/util/cjs/is/undefined.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isUndefined = isUndefined; +/** + * @name isUndefined + * @summary Tests for a `undefined` values. + * @description + * Checks to see if the input value is `undefined`. + * @example + *
+ * + * ```javascript + * import { isUndefined } from '@pezkuwi/util'; + * + * console.log('isUndefined', isUndefined(void(0))); // => true + * ``` + */ +function isUndefined(value) { + return value === undefined; +} diff --git a/packages/util/cjs/is/utf8.d.ts b/packages/util/cjs/is/utf8.d.ts new file mode 100644 index 0000000..bec769d --- /dev/null +++ b/packages/util/cjs/is/utf8.d.ts @@ -0,0 +1,7 @@ +/** + * @name isUtf8 + * @summary Tests if the input is valid Utf8 + * @description + * Checks to see if the input string or Uint8Array is valid Utf8 + */ +export declare function isUtf8(value?: number[] | Uint8Array | string | null): boolean; diff --git a/packages/util/cjs/is/utf8.js b/packages/util/cjs/is/utf8.js new file mode 100644 index 0000000..a45c4e5 --- /dev/null +++ b/packages/util/cjs/is/utf8.js @@ -0,0 +1,200 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isUtf8 = isUtf8; +const toU8a_js_1 = require("../u8a/toU8a.js"); +const string_js_1 = require("./string.js"); +/** + * @name isUtf8 + * @summary Tests if the input is valid Utf8 + * @description + * Checks to see if the input string or Uint8Array is valid Utf8 + */ +function isUtf8(value) { + if (!value) { + return (0, string_js_1.isString)(value); + } + const u8a = (0, toU8a_js_1.u8aToU8a)(value); + const len = u8a.length; + let i = 0; + while (i < len) { + if (u8a[i] <= 0x7F) /* 00..7F */ { + i += 1; + } + else if (u8a[i] >= 0xC2 && u8a[i] <= 0xDF) /* C2..DF 80..BF */ { + if (i + 1 < len) /* Expect a 2nd byte */ { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0xBF) { + // *message = "After a first byte between C2 and DF, expecting a 2nd byte between 80 and BF"; + // *faulty_bytes = 2; + return false; + } + } + else { + // *message = "After a first byte between C2 and DF, expecting a 2nd byte."; + // *faulty_bytes = 1; + return false; + } + i += 2; + } + else if (u8a[i] === 0xE0) /* E0 A0..BF 80..BF */ { + if (i + 2 < len) /* Expect a 2nd and 3rd byte */ { + if (u8a[i + 1] < 0xA0 || u8a[i + 1] > 0xBF) { + // *message = "After a first byte of E0, expecting a 2nd byte between A0 and BF."; + // *faulty_bytes = 2; + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + // *message = "After a first byte of E0, expecting a 3nd byte between 80 and BF."; + // *faulty_bytes = 3; + return false; + } + } + else { + // *message = "After a first byte of E0, expecting two following bytes."; + // *faulty_bytes = 1; + return false; + } + i += 3; + } + else if (u8a[i] >= 0xE1 && u8a[i] <= 0xEC) /* E1..EC 80..BF 80..BF */ { + if (i + 2 < len) /* Expect a 2nd and 3rd byte */ { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0xBF) { + // *message = "After a first byte between E1 and EC, expecting the 2nd byte between 80 and BF."; + // *faulty_bytes = 2; + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + // *message = "After a first byte between E1 and EC, expecting the 3rd byte between 80 and BF."; + // *faulty_bytes = 3; + return false; + } + } + else { + // *message = "After a first byte between E1 and EC, expecting two following bytes."; + // *faulty_bytes = 1; + return false; + } + i += 3; + } + else if (u8a[i] === 0xED) /* ED 80..9F 80..BF */ { + if (i + 2 < len) /* Expect a 2nd and 3rd byte */ { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0x9F) { + // *message = "After a first byte of ED, expecting 2nd byte between 80 and 9F."; + // *faulty_bytes = 2; + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + // *message = "After a first byte of ED, expecting 3rd byte between 80 and BF."; + // *faulty_bytes = 3; + return false; + } + } + else { + // *message = "After a first byte of ED, expecting two following bytes."; + // *faulty_bytes = 1; + return false; + } + i += 3; + } + else if (u8a[i] >= 0xEE && u8a[i] <= 0xEF) /* EE..EF 80..BF 80..BF */ { + if (i + 2 < len) /* Expect a 2nd and 3rd byte */ { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0xBF) { + // *message = "After a first byte between EE and EF, expecting 2nd byte between 80 and BF."; + // *faulty_bytes = 2; + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + // *message = "After a first byte between EE and EF, expecting 3rd byte between 80 and BF."; + // *faulty_bytes = 3; + return false; + } + } + else { + // *message = "After a first byte between EE and EF, two following bytes."; + // *faulty_bytes = 1; + return false; + } + i += 3; + } + else if (u8a[i] === 0xF0) /* F0 90..BF 80..BF 80..BF */ { + if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ { + if (u8a[i + 1] < 0x90 || u8a[i + 1] > 0xBF) { + // *message = "After a first byte of F0, expecting 2nd byte between 90 and BF."; + // *faulty_bytes = 2; + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + // *message = "After a first byte of F0, expecting 3rd byte between 80 and BF."; + // *faulty_bytes = 3; + return false; + } + if (u8a[i + 3] < 0x80 || u8a[i + 3] > 0xBF) { + // *message = "After a first byte of F0, expecting 4th byte between 80 and BF."; + // *faulty_bytes = 4; + return false; + } + } + else { + // *message = "After a first byte of F0, expecting three following bytes."; + // *faulty_bytes = 1; + return false; + } + i += 4; + } + else if (u8a[i] >= 0xF1 && u8a[i] <= 0xF3) /* F1..F3 80..BF 80..BF 80..BF */ { + if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0xBF) { + // *message = "After a first byte of F1, F2, or F3, expecting a 2nd byte between 80 and BF."; + // *faulty_bytes = 2; + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + // *message = "After a first byte of F1, F2, or F3, expecting a 3rd byte between 80 and BF."; + // *faulty_bytes = 3; + return false; + } + if (u8a[i + 3] < 0x80 || u8a[i + 3] > 0xBF) { + // *message = "After a first byte of F1, F2, or F3, expecting a 4th byte between 80 and BF."; + // *faulty_bytes = 4; + return false; + } + } + else { + // *message = "After a first byte of F1, F2, or F3, expecting three following bytes."; + // *faulty_bytes = 1; + return false; + } + i += 4; + } + else if (u8a[i] === 0xF4) /* F4 80..8F 80..BF 80..BF */ { + if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0x8F) { + // *message = "After a first byte of F4, expecting 2nd byte between 80 and 8F."; + // *faulty_bytes = 2; + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + // *message = "After a first byte of F4, expecting 3rd byte between 80 and BF."; + // *faulty_bytes = 3; + return false; + } + if (u8a[i + 3] < 0x80 || u8a[i + 3] > 0xBF) { + // *message = "After a first byte of F4, expecting 4th byte between 80 and BF."; + // *faulty_bytes = 4; + return false; + } + } + else { + // *message = "After a first byte of F4, expecting three following bytes."; + // *faulty_bytes = 1; + return false; + } + i += 4; + } + else { + // *message = "Expecting bytes in the following ranges: 00..7F C2..F4."; + // *faulty_bytes = 1; + return false; + } + } + return true; +} diff --git a/packages/util/cjs/is/wasm.d.ts b/packages/util/cjs/is/wasm.d.ts new file mode 100644 index 0000000..212605d --- /dev/null +++ b/packages/util/cjs/is/wasm.d.ts @@ -0,0 +1,7 @@ +/** + * @name isWasm + * @summary Tests if the input has a WASM header + * @description + * Checks to see if the input Uint8Array contains a valid WASM header + */ +export declare function isWasm(value?: unknown): value is Uint8Array; diff --git a/packages/util/cjs/is/wasm.js b/packages/util/cjs/is/wasm.js new file mode 100644 index 0000000..bfa3dd0 --- /dev/null +++ b/packages/util/cjs/is/wasm.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isWasm = isWasm; +const eq_js_1 = require("../u8a/eq.js"); +const u8a_js_1 = require("./u8a.js"); +const WASM_MAGIC = new Uint8Array([0, 97, 115, 109]); // \0asm +/** + * @name isWasm + * @summary Tests if the input has a WASM header + * @description + * Checks to see if the input Uint8Array contains a valid WASM header + */ +function isWasm(value) { + return (0, u8a_js_1.isU8a)(value) && (0, eq_js_1.u8aEq)(value.subarray(0, 4), WASM_MAGIC); +} diff --git a/packages/util/cjs/lazy.d.ts b/packages/util/cjs/lazy.d.ts new file mode 100644 index 0000000..9ba5778 --- /dev/null +++ b/packages/util/cjs/lazy.d.ts @@ -0,0 +1,14 @@ +type AnyFn = (...args: unknown[]) => unknown; +/** + * @name lazyMethod + * @description + * Creates a lazy, on-demand getter for the specific value. Upon get the value will be evaluated. + */ +export declare function lazyMethod(result: Record | AnyFn, item: K, creator: (item: K, index: number, self: S) => T, getName?: (item: K, index: number) => string, index?: number): void; +/** + * @name lazyMethods + * @description + * Creates lazy, on-demand getters for the specific values. + */ +export declare function lazyMethods(result: Record, items: readonly K[], creator: (item: K, index: number, self: S) => T, getName?: (item: K, index: number) => string): Record; +export {}; diff --git a/packages/util/cjs/lazy.js b/packages/util/cjs/lazy.js new file mode 100644 index 0000000..daeb8bd --- /dev/null +++ b/packages/util/cjs/lazy.js @@ -0,0 +1,55 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.lazyMethod = lazyMethod; +exports.lazyMethods = lazyMethods; +/** + * @name lazyMethod + * @description + * Creates a lazy, on-demand getter for the specific value. Upon get the value will be evaluated. + */ +function lazyMethod(result, item, creator, getName, index = 0) { + const name = getName + ? getName(item, index) + : item.toString(); + let value; + Object.defineProperty(result, name, { + // This allows for re-configuration with the embedded defineProperty below + // and ensures that on tested browsers and Node, it _will_ be redefined + // and thus short-circuited for future access + configurable: true, + enumerable: true, + // Use a function here, we don't want to capture the outer this, i.e. + // don't use arrow functions in this context since we have a this inside + get: function () { + // This check should _always_ be false and unneeded, since we override + // with a value below ... however we ensure we are quire vigilant against + // all environment failures, so we are rather be safe than sorry + if (value === undefined) { + value = creator(item, index, this); + try { + // re-define the property as a value, next time around this + // getter will only return the computed value + Object.defineProperty(this, name, { value }); + } + catch { + // ignore any errors, since this _should_ not happen due to + // the "configurable" property above. But if it ever does + // from here-on we will be the cached value the next time + // around (with a very slight dip in performance) + } + } + return value; + } + }); +} +/** + * @name lazyMethods + * @description + * Creates lazy, on-demand getters for the specific values. + */ +function lazyMethods(result, items, creator, getName) { + for (let i = 0, count = items.length; i < count; i++) { + lazyMethod(result, items[i], creator, getName, i); + } + return result; +} diff --git a/packages/util/cjs/logger.d.ts b/packages/util/cjs/logger.d.ts new file mode 100644 index 0000000..9372459 --- /dev/null +++ b/packages/util/cjs/logger.d.ts @@ -0,0 +1,17 @@ +import type { Logger } from './types.js'; +export declare function loggerFormat(value: unknown): unknown; +/** + * @name Logger + * @summary Creates a consistent log interface for messages + * @description + * Returns a `Logger` that has `.log`, `.error`, `.warn` and `.debug` (controlled with environment `DEBUG=typeA,typeB`) methods. Logging is done with a consistent prefix (type of logger, date) followed by the actual message using the underlying console. + * @example + *
+ * + * ```javascript + * import { logger } from '@pezkuwi/util'; + * + * const l = logger('test'); + * ``` + */ +export declare function logger(origin: string): Logger; diff --git a/packages/util/cjs/logger.js b/packages/util/cjs/logger.js new file mode 100644 index 0000000..6716373 --- /dev/null +++ b/packages/util/cjs/logger.js @@ -0,0 +1,122 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.loggerFormat = loggerFormat; +exports.logger = logger; +const x_global_1 = require("@pezkuwi/x-global"); +const formatDate_js_1 = require("./format/formatDate.js"); +const bn_js_1 = require("./is/bn.js"); +const buffer_js_1 = require("./is/buffer.js"); +const function_js_1 = require("./is/function.js"); +const object_js_1 = require("./is/object.js"); +const u8a_js_1 = require("./is/u8a.js"); +const toHex_js_1 = require("./u8a/toHex.js"); +const toU8a_js_1 = require("./u8a/toU8a.js"); +const noop_js_1 = require("./noop.js"); +const logTo = { + debug: 'log', + error: 'error', + log: 'log', + warn: 'warn' +}; +function formatOther(value) { + if (value && (0, object_js_1.isObject)(value) && value.constructor === Object) { + const result = {}; + for (const [k, v] of Object.entries(value)) { + result[k] = loggerFormat(v); + } + return result; + } + return value; +} +function loggerFormat(value) { + if (Array.isArray(value)) { + return value.map(loggerFormat); + } + else if ((0, bn_js_1.isBn)(value)) { + return value.toString(); + } + else if ((0, u8a_js_1.isU8a)(value) || (0, buffer_js_1.isBuffer)(value)) { + return (0, toHex_js_1.u8aToHex)((0, toU8a_js_1.u8aToU8a)(value)); + } + return formatOther(value); +} +function formatWithLength(maxLength) { + return (v) => { + if (maxLength <= 0) { + return v; + } + const r = `${v}`; + return r.length < maxLength + ? v + : `${r.substring(0, maxLength)} ...`; + }; +} +function apply(log, type, values, maxSize = -1) { + if (values.length === 1 && (0, function_js_1.isFunction)(values[0])) { + const fnResult = values[0](); + return apply(log, type, Array.isArray(fnResult) ? fnResult : [fnResult], maxSize); + } + console[logTo[log]]((0, formatDate_js_1.formatDate)(new Date()), type, ...values + .map(loggerFormat) + .map(formatWithLength(maxSize))); +} +function isDebugOn(e, type) { + return !!e && (e === '*' || + type === e || + (e.endsWith('*') && + type.startsWith(e.slice(0, -1)))); +} +function isDebugOff(e, type) { + return !!e && (e.startsWith('-') && + (type === e.slice(1) || + (e.endsWith('*') && + type.startsWith(e.slice(1, -1))))); +} +function getDebugFlag(env, type) { + let flag = false; + for (const e of env) { + if (isDebugOn(e, type)) { + flag = true; + } + else if (isDebugOff(e, type)) { + flag = false; + } + } + return flag; +} +function parseEnv(type) { + const maxSize = parseInt(x_global_1.xglobal.process?.env?.['DEBUG_MAX'] || '-1', 10); + return [ + getDebugFlag((x_global_1.xglobal.process?.env?.['DEBUG'] || '').toLowerCase().split(','), type), + isNaN(maxSize) + ? -1 + : maxSize + ]; +} +/** + * @name Logger + * @summary Creates a consistent log interface for messages + * @description + * Returns a `Logger` that has `.log`, `.error`, `.warn` and `.debug` (controlled with environment `DEBUG=typeA,typeB`) methods. Logging is done with a consistent prefix (type of logger, date) followed by the actual message using the underlying console. + * @example + *
+ * + * ```javascript + * import { logger } from '@pezkuwi/util'; + * + * const l = logger('test'); + * ``` + */ +function logger(origin) { + const type = `${origin.toUpperCase()}:`.padStart(16); + const [isDebug, maxSize] = parseEnv(origin.toLowerCase()); + return { + debug: isDebug + ? (...values) => apply('debug', type, values, maxSize) + : noop_js_1.noop, + error: (...values) => apply('error', type, values), + log: (...values) => apply('log', type, values), + noop: noop_js_1.noop, + warn: (...values) => apply('warn', type, values) + }; +} diff --git a/packages/util/cjs/memoize.d.ts b/packages/util/cjs/memoize.d.ts new file mode 100644 index 0000000..465a597 --- /dev/null +++ b/packages/util/cjs/memoize.d.ts @@ -0,0 +1,10 @@ +import type { Memoized } from './types.js'; +interface Options { + getInstanceId?: () => string; +} +/** + * @name memoize + * @description Memomize the function with a specific instanceId + */ +export declare function memoize T>(fn: F, { getInstanceId }?: Options): Memoized; +export {}; diff --git a/packages/util/cjs/memoize.js b/packages/util/cjs/memoize.js new file mode 100644 index 0000000..6127d78 --- /dev/null +++ b/packages/util/cjs/memoize.js @@ -0,0 +1,33 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.memoize = memoize; +const stringify_js_1 = require("./stringify.js"); +function defaultGetId() { + return 'none'; +} +/** + * @name memoize + * @description Memomize the function with a specific instanceId + */ +function memoize(fn, { getInstanceId = defaultGetId } = {}) { + const cache = {}; + const memoized = (...args) => { + const stringParams = (0, stringify_js_1.stringify)(args); + const instanceId = getInstanceId(); + if (!cache[instanceId]) { + cache[instanceId] = {}; + } + if (cache[instanceId][stringParams] === undefined) { + cache[instanceId][stringParams] = fn(...args); + } + return cache[instanceId][stringParams]; + }; + memoized.unmemoize = (...args) => { + const stringParams = (0, stringify_js_1.stringify)(args); + const instanceId = getInstanceId(); + if (cache[instanceId]?.[stringParams] !== undefined) { + delete cache[instanceId][stringParams]; + } + }; + return memoized; +} diff --git a/packages/util/cjs/nextTick.d.ts b/packages/util/cjs/nextTick.d.ts new file mode 100644 index 0000000..99e4378 --- /dev/null +++ b/packages/util/cjs/nextTick.d.ts @@ -0,0 +1,5 @@ +/** + * @name nextTick + * @description Defer the operation to the queue for evaluation on the next tick + */ +export declare function nextTick(onExec: () => unknown, onError?: (error: Error) => unknown): void; diff --git a/packages/util/cjs/nextTick.js b/packages/util/cjs/nextTick.js new file mode 100644 index 0000000..f3d9770 --- /dev/null +++ b/packages/util/cjs/nextTick.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.nextTick = nextTick; +/** + * @name nextTick + * @description Defer the operation to the queue for evaluation on the next tick + */ +function nextTick(onExec, onError) { + // While Promise.resolve().then(...) would defer to the nextTick, this + // actually does not play as nicely in browsers like the setTimeout(...) + // approach. So the safer, though less optimal approach is the one taken here + setTimeout(() => { + Promise + .resolve() + .then(() => { + onExec(); + }) + .catch((error) => { + if (onError) { + onError(error); + } + else { + console.error(error); + } + }); + }, 0); +} diff --git a/packages/util/cjs/noop.d.ts b/packages/util/cjs/noop.d.ts new file mode 100644 index 0000000..90ed136 --- /dev/null +++ b/packages/util/cjs/noop.d.ts @@ -0,0 +1,8 @@ +/** + * A sharable identity function. Returns the input as-is with no transformation applied. + */ +export declare function identity(value: T): T; +/** + * A sharable noop function. As the name suggests, does nothing + */ +export declare function noop(): void; diff --git a/packages/util/cjs/noop.js b/packages/util/cjs/noop.js new file mode 100644 index 0000000..8fdc5e0 --- /dev/null +++ b/packages/util/cjs/noop.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.identity = identity; +exports.noop = noop; +/** + * A sharable identity function. Returns the input as-is with no transformation applied. + */ +function identity(value) { + return value; +} +/** + * A sharable noop function. As the name suggests, does nothing + */ +function noop() { + // noop +} diff --git a/packages/util/cjs/number/index.d.ts b/packages/util/cjs/number/index.d.ts new file mode 100644 index 0000000..f7d0175 --- /dev/null +++ b/packages/util/cjs/number/index.d.ts @@ -0,0 +1,5 @@ +/** + * @summary Utility methods to convert to and from `number` values + */ +export { numberToHex } from './toHex.js'; +export { numberToU8a } from './toU8a.js'; diff --git a/packages/util/cjs/number/index.js b/packages/util/cjs/number/index.js new file mode 100644 index 0000000..abdaaa1 --- /dev/null +++ b/packages/util/cjs/number/index.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.numberToU8a = exports.numberToHex = void 0; +/** + * @summary Utility methods to convert to and from `number` values + */ +var toHex_js_1 = require("./toHex.js"); +Object.defineProperty(exports, "numberToHex", { enumerable: true, get: function () { return toHex_js_1.numberToHex; } }); +var toU8a_js_1 = require("./toU8a.js"); +Object.defineProperty(exports, "numberToU8a", { enumerable: true, get: function () { return toU8a_js_1.numberToU8a; } }); diff --git a/packages/util/cjs/number/toHex.d.ts b/packages/util/cjs/number/toHex.d.ts new file mode 100644 index 0000000..9670041 --- /dev/null +++ b/packages/util/cjs/number/toHex.d.ts @@ -0,0 +1,17 @@ +import type { HexString } from '../types.js'; +/** + * @name numberToHex + * @summary Creates a hex value from a number. + * @description + * `null`/`undefined`/`NaN` inputs returns an empty `0x` result. `number` input values return the actual bytes value converted to a `hex`. With `bitLength` set, it converts the number to the equivalent size. + * @example + *
+ * + * ```javascript + * import { numberToHex } from '@pezkuwi/util'; + * + * numberToHex(0x1234); // => '0x1234' + * numberToHex(0x1234, 32); // => 0x00001234 + * ``` + */ +export declare function numberToHex(value?: number | null, bitLength?: number): HexString; diff --git a/packages/util/cjs/number/toHex.js b/packages/util/cjs/number/toHex.js new file mode 100644 index 0000000..c7eca8d --- /dev/null +++ b/packages/util/cjs/number/toHex.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.numberToHex = numberToHex; +const fixLength_js_1 = require("../hex/fixLength.js"); +/** + * @name numberToHex + * @summary Creates a hex value from a number. + * @description + * `null`/`undefined`/`NaN` inputs returns an empty `0x` result. `number` input values return the actual bytes value converted to a `hex`. With `bitLength` set, it converts the number to the equivalent size. + * @example + *
+ * + * ```javascript + * import { numberToHex } from '@pezkuwi/util'; + * + * numberToHex(0x1234); // => '0x1234' + * numberToHex(0x1234, 32); // => 0x00001234 + * ``` + */ +function numberToHex(value, bitLength = -1) { + const hex = (!value || Number.isNaN(value) ? 0 : value).toString(16); + return (0, fixLength_js_1.hexFixLength)(hex.length % 2 ? `0${hex}` : hex, bitLength, true); +} diff --git a/packages/util/cjs/number/toU8a.d.ts b/packages/util/cjs/number/toU8a.d.ts new file mode 100644 index 0000000..ae9c142 --- /dev/null +++ b/packages/util/cjs/number/toU8a.d.ts @@ -0,0 +1,15 @@ +/** + * @name numberToU8a + * @summary Creates a Uint8Array object from a number. + * @description + * `null`/`undefined`/`NaN` inputs returns an empty `Uint8Array` result. `number` input values return the actual bytes value converted to a `Uint8Array`. With `bitLength`, it converts the value to the equivalent size. + * @example + *
+ * + * ```javascript + * import { numberToU8a } from '@pezkuwi/util'; + * + * numberToU8a(0x1234); // => [0x12, 0x34] + * ``` + */ +export declare function numberToU8a(value?: number | null, bitLength?: number): Uint8Array; diff --git a/packages/util/cjs/number/toU8a.js b/packages/util/cjs/number/toU8a.js new file mode 100644 index 0000000..f7da16a --- /dev/null +++ b/packages/util/cjs/number/toU8a.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.numberToU8a = numberToU8a; +const toU8a_js_1 = require("../hex/toU8a.js"); +const toHex_js_1 = require("./toHex.js"); +/** + * @name numberToU8a + * @summary Creates a Uint8Array object from a number. + * @description + * `null`/`undefined`/`NaN` inputs returns an empty `Uint8Array` result. `number` input values return the actual bytes value converted to a `Uint8Array`. With `bitLength`, it converts the value to the equivalent size. + * @example + *
+ * + * ```javascript + * import { numberToU8a } from '@pezkuwi/util'; + * + * numberToU8a(0x1234); // => [0x12, 0x34] + * ``` + */ +function numberToU8a(value, bitLength = -1) { + return (0, toU8a_js_1.hexToU8a)((0, toHex_js_1.numberToHex)(value, bitLength)); +} diff --git a/packages/util/cjs/object/clear.d.ts b/packages/util/cjs/object/clear.d.ts new file mode 100644 index 0000000..c2da0b8 --- /dev/null +++ b/packages/util/cjs/object/clear.d.ts @@ -0,0 +1,5 @@ +/** + * @name objectClear + * @summary Removes all the keys from the input object + */ +export declare function objectClear(value: Record): Record; diff --git a/packages/util/cjs/object/clear.js b/packages/util/cjs/object/clear.js new file mode 100644 index 0000000..77ad725 --- /dev/null +++ b/packages/util/cjs/object/clear.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.objectClear = objectClear; +/** + * @name objectClear + * @summary Removes all the keys from the input object + */ +function objectClear(value) { + const keys = Object.keys(value); + for (let i = 0, count = keys.length; i < count; i++) { + delete value[keys[i]]; + } + return value; +} diff --git a/packages/util/cjs/object/copy.d.ts b/packages/util/cjs/object/copy.d.ts new file mode 100644 index 0000000..016409a --- /dev/null +++ b/packages/util/cjs/object/copy.d.ts @@ -0,0 +1,5 @@ +/** + * @name objectCopy + * @summary Creates a shallow clone of the input object + */ +export declare function objectCopy(source: T): T; diff --git a/packages/util/cjs/object/copy.js b/packages/util/cjs/object/copy.js new file mode 100644 index 0000000..a0639fa --- /dev/null +++ b/packages/util/cjs/object/copy.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.objectCopy = objectCopy; +const spread_js_1 = require("./spread.js"); +/** + * @name objectCopy + * @summary Creates a shallow clone of the input object + */ +function objectCopy(source) { + return (0, spread_js_1.objectSpread)({}, source); +} diff --git a/packages/util/cjs/object/entries.d.ts b/packages/util/cjs/object/entries.d.ts new file mode 100644 index 0000000..87a3b13 --- /dev/null +++ b/packages/util/cjs/object/entries.d.ts @@ -0,0 +1,9 @@ +type Entries = { + [K in keyof T]: [K, T[K]]; +}[keyof T][]; +/** + * @name objectEntries + * @summary A version of Object.entries that is typed for TS + */ +export declare function objectEntries(obj: T): Entries; +export {}; diff --git a/packages/util/cjs/object/entries.js b/packages/util/cjs/object/entries.js new file mode 100644 index 0000000..1067365 --- /dev/null +++ b/packages/util/cjs/object/entries.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.objectEntries = objectEntries; +/** + * @name objectEntries + * @summary A version of Object.entries that is typed for TS + */ +function objectEntries(obj) { + return Object.entries(obj); +} diff --git a/packages/util/cjs/object/index.d.ts b/packages/util/cjs/object/index.d.ts new file mode 100644 index 0000000..46ea184 --- /dev/null +++ b/packages/util/cjs/object/index.d.ts @@ -0,0 +1,7 @@ +export { objectClear } from './clear.js'; +export { objectCopy } from './copy.js'; +export { objectEntries } from './entries.js'; +export { objectKeys } from './keys.js'; +export { objectProperties, objectProperty } from './property.js'; +export { objectSpread } from './spread.js'; +export { objectValues } from './values.js'; diff --git a/packages/util/cjs/object/index.js b/packages/util/cjs/object/index.js new file mode 100644 index 0000000..7193c69 --- /dev/null +++ b/packages/util/cjs/object/index.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.objectValues = exports.objectSpread = exports.objectProperty = exports.objectProperties = exports.objectKeys = exports.objectEntries = exports.objectCopy = exports.objectClear = void 0; +var clear_js_1 = require("./clear.js"); +Object.defineProperty(exports, "objectClear", { enumerable: true, get: function () { return clear_js_1.objectClear; } }); +var copy_js_1 = require("./copy.js"); +Object.defineProperty(exports, "objectCopy", { enumerable: true, get: function () { return copy_js_1.objectCopy; } }); +var entries_js_1 = require("./entries.js"); +Object.defineProperty(exports, "objectEntries", { enumerable: true, get: function () { return entries_js_1.objectEntries; } }); +var keys_js_1 = require("./keys.js"); +Object.defineProperty(exports, "objectKeys", { enumerable: true, get: function () { return keys_js_1.objectKeys; } }); +var property_js_1 = require("./property.js"); +Object.defineProperty(exports, "objectProperties", { enumerable: true, get: function () { return property_js_1.objectProperties; } }); +Object.defineProperty(exports, "objectProperty", { enumerable: true, get: function () { return property_js_1.objectProperty; } }); +var spread_js_1 = require("./spread.js"); +Object.defineProperty(exports, "objectSpread", { enumerable: true, get: function () { return spread_js_1.objectSpread; } }); +var values_js_1 = require("./values.js"); +Object.defineProperty(exports, "objectValues", { enumerable: true, get: function () { return values_js_1.objectValues; } }); diff --git a/packages/util/cjs/object/keys.d.ts b/packages/util/cjs/object/keys.d.ts new file mode 100644 index 0000000..dc5bd87 --- /dev/null +++ b/packages/util/cjs/object/keys.d.ts @@ -0,0 +1,5 @@ +/** + * @name objectKeys + * @summary A version of Object.keys that is typed for TS + */ +export declare function objectKeys>(value: T): K[]; diff --git a/packages/util/cjs/object/keys.js b/packages/util/cjs/object/keys.js new file mode 100644 index 0000000..6f279f9 --- /dev/null +++ b/packages/util/cjs/object/keys.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.objectKeys = objectKeys; +/** + * @name objectKeys + * @summary A version of Object.keys that is typed for TS + */ +function objectKeys(value) { + return Object.keys(value); +} diff --git a/packages/util/cjs/object/property.d.ts b/packages/util/cjs/object/property.d.ts new file mode 100644 index 0000000..f494c11 --- /dev/null +++ b/packages/util/cjs/object/property.d.ts @@ -0,0 +1,10 @@ +/** + * @name objectProperty + * @summary Assign a get property on the input object + */ +export declare function objectProperty(that: object, key: string, getter: (key: string, index: number, self: S) => unknown, getName?: (key: string, index: number) => string, index?: number): void; +/** + * @name objectProperties + * @summary Assign get properties on the input object + */ +export declare function objectProperties(that: object, keys: string[], getter: (key: string, index: number, self: S) => unknown, getName?: (key: string, index: number) => string): void; diff --git a/packages/util/cjs/object/property.js b/packages/util/cjs/object/property.js new file mode 100644 index 0000000..781896a --- /dev/null +++ b/packages/util/cjs/object/property.js @@ -0,0 +1,38 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.objectProperty = objectProperty; +exports.objectProperties = objectProperties; +/** + * @name objectProperty + * @summary Assign a get property on the input object + */ +function objectProperty(that, key, getter, getName, index = 0) { + const name = getName + ? getName(key, index) + : key; + // There are 3 approaches here - + // - Object.prototype.hasOwnProperty.call(that, key) - this only checks the current class, i.e + // will retuirn false if the property is set in the parent class + // - isUndefined(...) - this may yield a false positive when the property is there, but not set. + // Additionally, on pre-defined getters it may make a call + // - key in that - Does not need to be combined with either of the above and checks the full chain + if (!(name in that)) { + Object.defineProperty(that, name, { + enumerable: true, + // Unlike in lazy, we always call into the upper function, i.e. this method + // does not cache old values (it is expected to be used for dynamic values) + get: function () { + return getter(key, index, this); + } + }); + } +} +/** + * @name objectProperties + * @summary Assign get properties on the input object + */ +function objectProperties(that, keys, getter, getName) { + for (let i = 0, count = keys.length; i < count; i++) { + objectProperty(that, keys[i], getter, getName, i); + } +} diff --git a/packages/util/cjs/object/spread.d.ts b/packages/util/cjs/object/spread.d.ts new file mode 100644 index 0000000..82573d3 --- /dev/null +++ b/packages/util/cjs/object/spread.d.ts @@ -0,0 +1,6 @@ +/** + * @name objectSpread + * @summary Concats all sources into the destination + * @description Spreads object properties while maintaining object integrity + */ +export declare function objectSpread(dest: object, ...sources: (object | undefined | null)[]): T; diff --git a/packages/util/cjs/object/spread.js b/packages/util/cjs/object/spread.js new file mode 100644 index 0000000..7533789 --- /dev/null +++ b/packages/util/cjs/object/spread.js @@ -0,0 +1,34 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.objectSpread = objectSpread; +/** + * @name objectSpread + * @summary Concats all sources into the destination + * @description Spreads object properties while maintaining object integrity + */ +function objectSpread(dest, ...sources) { + const filterProps = new Set(['__proto__', 'constructor', 'prototype']); + for (let i = 0, count = sources.length; i < count; i++) { + const src = sources[i]; + if (src) { + if (typeof src.entries === 'function') { + for (const [key, value] of src.entries()) { + if (!filterProps.has(key)) { + dest[key] = value; + } + } + } + else { + // Create a clean copy of the source object + const sanitizedSrc = Object.create(null); + for (const [key, value] of Object.entries(src)) { + if (!filterProps.has(key)) { + sanitizedSrc[key] = value; + } + } + Object.assign(dest, sanitizedSrc); + } + } + } + return dest; +} diff --git a/packages/util/cjs/object/values.d.ts b/packages/util/cjs/object/values.d.ts new file mode 100644 index 0000000..12acc4f --- /dev/null +++ b/packages/util/cjs/object/values.d.ts @@ -0,0 +1,5 @@ +/** + * @name objectValues + * @summary A version of Object.values that is typed for TS + */ +export declare function objectValues(obj: T): T[keyof T][]; diff --git a/packages/util/cjs/object/values.js b/packages/util/cjs/object/values.js new file mode 100644 index 0000000..6a3f861 --- /dev/null +++ b/packages/util/cjs/object/values.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.objectValues = objectValues; +/** + * @name objectValues + * @summary A version of Object.values that is typed for TS + */ +function objectValues(obj) { + return Object.values(obj); +} diff --git a/packages/util/cjs/package.json b/packages/util/cjs/package.json new file mode 100644 index 0000000..5bbefff --- /dev/null +++ b/packages/util/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/util/cjs/packageDetect.d.ts b/packages/util/cjs/packageDetect.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/util/cjs/packageDetect.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/util/cjs/packageDetect.js b/packages/util/cjs/packageDetect.js new file mode 100644 index 0000000..865dcf0 --- /dev/null +++ b/packages/util/cjs/packageDetect.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const x_textdecoder_1 = require("@pezkuwi/x-textdecoder"); +const x_textencoder_1 = require("@pezkuwi/x-textencoder"); +const detectPackage_js_1 = require("./detectPackage.js"); +const packageInfo_js_1 = require("./packageInfo.js"); +(0, detectPackage_js_1.detectPackage)(packageInfo_js_1.packageInfo, null, [x_textdecoder_1.packageInfo, x_textencoder_1.packageInfo]); diff --git a/packages/util/cjs/packageInfo.d.ts b/packages/util/cjs/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/util/cjs/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/util/cjs/packageInfo.js b/packages/util/cjs/packageInfo.js new file mode 100644 index 0000000..c32c04a --- /dev/null +++ b/packages/util/cjs/packageInfo.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +exports.packageInfo = { name: '@pezkuwi/util', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; diff --git a/packages/util/cjs/promisify.d.ts b/packages/util/cjs/promisify.d.ts new file mode 100644 index 0000000..c1345d3 --- /dev/null +++ b/packages/util/cjs/promisify.d.ts @@ -0,0 +1,16 @@ +/** + * @name promisify + * @summary Wraps an async callback into a `Promise` + * @description + * Wraps the supplied async function `fn` that has a standard JS callback `(error: Error, result: any)` into a `Promise`, passing the supplied parameters. When `error` is set, the Promise is rejected, else the Promise resolves with the `result` value. + * @example + *
+ * + * ```javascript + * const { promisify } from '@pezkuwi/util'; + * + * await promisify(null, ((a, cb) => cb(null, a), true); // resolves with `true` + * await promisify(null, (cb) => cb(new Error('error!'))); // rejects with `error!` + * ``` + */ +export declare function promisify(self: unknown, fn: (...params: any[]) => any, ...params: any[]): Promise; diff --git a/packages/util/cjs/promisify.js b/packages/util/cjs/promisify.js new file mode 100644 index 0000000..0902f56 --- /dev/null +++ b/packages/util/cjs/promisify.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.promisify = promisify; +/** + * @name promisify + * @summary Wraps an async callback into a `Promise` + * @description + * Wraps the supplied async function `fn` that has a standard JS callback `(error: Error, result: any)` into a `Promise`, passing the supplied parameters. When `error` is set, the Promise is rejected, else the Promise resolves with the `result` value. + * @example + *
+ * + * ```javascript + * const { promisify } from '@pezkuwi/util'; + * + * await promisify(null, ((a, cb) => cb(null, a), true); // resolves with `true` + * await promisify(null, (cb) => cb(new Error('error!'))); // rejects with `error!` + * ``` + */ +function promisify(self, fn, ...params) { + return new Promise((resolve, reject) => { + fn.apply(self, params.concat((error, result) => { + if (error) { + reject(error); + } + else { + resolve(result); + } + })); + }); +} diff --git a/packages/util/cjs/string/camelCase.d.ts b/packages/util/cjs/string/camelCase.d.ts new file mode 100644 index 0000000..81aa34a --- /dev/null +++ b/packages/util/cjs/string/camelCase.d.ts @@ -0,0 +1,13 @@ +import type { AnyString } from '../types.js'; +export declare const CC_TO_UP: string[]; +export declare const CC_TO_LO: string[]; +/** + * @name stringCamelCase + * @summary Convert a dash/dot/underscore/space separated Ascii string/String to camelCase + */ +export declare const stringCamelCase: (value: AnyString) => string; +/** + * @name stringPascalCase + * @summary Convert a dash/dot/underscore/space separated Ascii string/String to PascalCase + */ +export declare const stringPascalCase: (value: AnyString) => string; diff --git a/packages/util/cjs/string/camelCase.js b/packages/util/cjs/string/camelCase.js new file mode 100644 index 0000000..08b1974 --- /dev/null +++ b/packages/util/cjs/string/camelCase.js @@ -0,0 +1,62 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.stringPascalCase = exports.stringCamelCase = exports.CC_TO_LO = exports.CC_TO_UP = void 0; +exports.CC_TO_UP = new Array(256); +exports.CC_TO_LO = new Array(256); +for (let i = 0, count = exports.CC_TO_UP.length; i < count; i++) { + exports.CC_TO_LO[i] = String.fromCharCode(i).toLowerCase(); + exports.CC_TO_UP[i] = String.fromCharCode(i).toUpperCase(); +} +/** @internal */ +function formatAllCaps(w) { + return w.slice(0, w.length - 1).toLowerCase() + exports.CC_TO_UP[w.charCodeAt(w.length - 1)]; +} +/** + * @internal + * + * Inspired by https://stackoverflow.com/a/2970667 + * + * This is not as optimal as the original SO answer (we split into per-word), + * however it does pass the tests (which the SO version doesn't) and is still + * a major improvement over the original camelcase npm package - + * + * camelcase: 20.88 μs/op + * this: 1.00 μs/op + * + * Caveat of this: only Ascii, but acceptable for the intended usecase + */ +function converter(format) { + return (value) => { + const parts = value + // replace all separators (including consequtive) with spaces + .replace(/[-_., ]+/g, ' ') + // we don't want leading or trailing spaces + .trim() + // split into words + .split(' '); + let result = ''; + for (let i = 0, count = parts.length; i < count; i++) { + const w = parts[i]; + // apply the formatting + result += format(/^[\dA-Z]+$/.test(w) + // all full uppercase + letters are changed to lowercase + ? w.toLowerCase() + // all consecutive capitals + letters are changed to lowercase + // e.g. UUID64 -> uuid64, while preserving splits, eg. NFTOrder -> nftOrder + : w.replace(/^[\dA-Z]{2,}[^a-z]/, formatAllCaps), i); + } + return result; + }; +} +/** + * @name stringCamelCase + * @summary Convert a dash/dot/underscore/space separated Ascii string/String to camelCase + */ +exports.stringCamelCase = converter((w, i) => +(i ? exports.CC_TO_UP[w.charCodeAt(0)] : exports.CC_TO_LO[w.charCodeAt(0)]) + w.slice(1)); +/** + * @name stringPascalCase + * @summary Convert a dash/dot/underscore/space separated Ascii string/String to PascalCase + */ +exports.stringPascalCase = converter((w) => +exports.CC_TO_UP[w.charCodeAt(0)] + w.slice(1)); diff --git a/packages/util/cjs/string/index.d.ts b/packages/util/cjs/string/index.d.ts new file mode 100644 index 0000000..b7237d5 --- /dev/null +++ b/packages/util/cjs/string/index.d.ts @@ -0,0 +1,8 @@ +/** + * @summary Utility methods to convert to work with `string` values + */ +export { stringCamelCase, stringPascalCase } from './camelCase.js'; +export { stringLowerFirst, stringUpperFirst } from './lowerFirst.js'; +export { stringShorten } from './shorten.js'; +export { stringToHex } from './toHex.js'; +export { stringToU8a } from './toU8a.js'; diff --git a/packages/util/cjs/string/index.js b/packages/util/cjs/string/index.js new file mode 100644 index 0000000..f343ad5 --- /dev/null +++ b/packages/util/cjs/string/index.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.stringToU8a = exports.stringToHex = exports.stringShorten = exports.stringUpperFirst = exports.stringLowerFirst = exports.stringPascalCase = exports.stringCamelCase = void 0; +/** + * @summary Utility methods to convert to work with `string` values + */ +var camelCase_js_1 = require("./camelCase.js"); +Object.defineProperty(exports, "stringCamelCase", { enumerable: true, get: function () { return camelCase_js_1.stringCamelCase; } }); +Object.defineProperty(exports, "stringPascalCase", { enumerable: true, get: function () { return camelCase_js_1.stringPascalCase; } }); +var lowerFirst_js_1 = require("./lowerFirst.js"); +Object.defineProperty(exports, "stringLowerFirst", { enumerable: true, get: function () { return lowerFirst_js_1.stringLowerFirst; } }); +Object.defineProperty(exports, "stringUpperFirst", { enumerable: true, get: function () { return lowerFirst_js_1.stringUpperFirst; } }); +var shorten_js_1 = require("./shorten.js"); +Object.defineProperty(exports, "stringShorten", { enumerable: true, get: function () { return shorten_js_1.stringShorten; } }); +var toHex_js_1 = require("./toHex.js"); +Object.defineProperty(exports, "stringToHex", { enumerable: true, get: function () { return toHex_js_1.stringToHex; } }); +var toU8a_js_1 = require("./toU8a.js"); +Object.defineProperty(exports, "stringToU8a", { enumerable: true, get: function () { return toU8a_js_1.stringToU8a; } }); diff --git a/packages/util/cjs/string/lowerFirst.d.ts b/packages/util/cjs/string/lowerFirst.d.ts new file mode 100644 index 0000000..4c10d35 --- /dev/null +++ b/packages/util/cjs/string/lowerFirst.d.ts @@ -0,0 +1,31 @@ +import type { AnyString } from '../types.js'; +/** + * @name stringLowerFirst + * @summary Lowercase the first letter of a string + * @description + * Lowercase the first letter of a string + * @example + *
+ * + * ```javascript + * import { stringLowerFirst } from '@pezkuwi/util'; + * + * stringLowerFirst('ABC'); // => 'aBC' + * ``` + */ +export declare const stringLowerFirst: (value?: AnyString | null) => string; +/** + * @name stringUpperFirst + * @summary Uppercase the first letter of a string + * @description + * Lowercase the first letter of a string + * @example + *
+ * + * ```javascript + * import { stringUpperFirst } from '@pezkuwi/util'; + * + * stringUpperFirst('abc'); // => 'Abc' + * ``` + */ +export declare const stringUpperFirst: (value?: AnyString | null) => string; diff --git a/packages/util/cjs/string/lowerFirst.js b/packages/util/cjs/string/lowerFirst.js new file mode 100644 index 0000000..2ba6a47 --- /dev/null +++ b/packages/util/cjs/string/lowerFirst.js @@ -0,0 +1,40 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.stringUpperFirst = exports.stringLowerFirst = void 0; +const camelCase_js_1 = require("./camelCase.js"); +/** @internal */ +function converter(map) { + return (value) => value + ? map[value.charCodeAt(0)] + value.slice(1) + : ''; +} +/** + * @name stringLowerFirst + * @summary Lowercase the first letter of a string + * @description + * Lowercase the first letter of a string + * @example + *
+ * + * ```javascript + * import { stringLowerFirst } from '@pezkuwi/util'; + * + * stringLowerFirst('ABC'); // => 'aBC' + * ``` + */ +exports.stringLowerFirst = converter(camelCase_js_1.CC_TO_LO); +/** + * @name stringUpperFirst + * @summary Uppercase the first letter of a string + * @description + * Lowercase the first letter of a string + * @example + *
+ * + * ```javascript + * import { stringUpperFirst } from '@pezkuwi/util'; + * + * stringUpperFirst('abc'); // => 'Abc' + * ``` + */ +exports.stringUpperFirst = converter(camelCase_js_1.CC_TO_UP); diff --git a/packages/util/cjs/string/shorten.d.ts b/packages/util/cjs/string/shorten.d.ts new file mode 100644 index 0000000..ca3cfec --- /dev/null +++ b/packages/util/cjs/string/shorten.d.ts @@ -0,0 +1,16 @@ +import type { AnyString } from '../types.js'; +/** + * @name stringShorten + * @summary Returns a string with maximum length + * @description + * Checks the string against the `prefixLength`, if longer than double this, shortens it by placing `..` in the middle of it + * @example + *
+ * + * ```javascript + * import { stringShorten } from '@pezkuwi/util'; + * + * stringShorten('1234567890', 2); // => 12..90 + * ``` + */ +export declare function stringShorten(value: AnyString, prefixLength?: number): string; diff --git a/packages/util/cjs/string/shorten.js b/packages/util/cjs/string/shorten.js new file mode 100644 index 0000000..17798b1 --- /dev/null +++ b/packages/util/cjs/string/shorten.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.stringShorten = stringShorten; +/** + * @name stringShorten + * @summary Returns a string with maximum length + * @description + * Checks the string against the `prefixLength`, if longer than double this, shortens it by placing `..` in the middle of it + * @example + *
+ * + * ```javascript + * import { stringShorten } from '@pezkuwi/util'; + * + * stringShorten('1234567890', 2); // => 12..90 + * ``` + */ +function stringShorten(value, prefixLength = 6) { + return value.length <= 2 + 2 * prefixLength + ? value.toString() + : `${value.substring(0, prefixLength)}…${value.slice(-prefixLength)}`; +} diff --git a/packages/util/cjs/string/toHex.d.ts b/packages/util/cjs/string/toHex.d.ts new file mode 100644 index 0000000..beea8fb --- /dev/null +++ b/packages/util/cjs/string/toHex.d.ts @@ -0,0 +1,16 @@ +import type { AnyString, HexString } from '../types.js'; +/** + * @name stringToHex + * @summary Creates a hex string from a utf-8 string + * @description + * String input values return the actual encoded hex value. + * @example + *
+ * + * ```javascript + * import { stringToHex } from '@pezkuwi/util'; + * + * stringToU8a('hello'); // 0x68656c6c6f + * ``` + */ +export declare function stringToHex(value?: AnyString): HexString; diff --git a/packages/util/cjs/string/toHex.js b/packages/util/cjs/string/toHex.js new file mode 100644 index 0000000..d380388 --- /dev/null +++ b/packages/util/cjs/string/toHex.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.stringToHex = stringToHex; +const toHex_js_1 = require("../u8a/toHex.js"); +const toU8a_js_1 = require("./toU8a.js"); +/** + * @name stringToHex + * @summary Creates a hex string from a utf-8 string + * @description + * String input values return the actual encoded hex value. + * @example + *
+ * + * ```javascript + * import { stringToHex } from '@pezkuwi/util'; + * + * stringToU8a('hello'); // 0x68656c6c6f + * ``` + */ +function stringToHex(value) { + return (0, toHex_js_1.u8aToHex)((0, toU8a_js_1.stringToU8a)(value)); +} diff --git a/packages/util/cjs/string/toU8a.d.ts b/packages/util/cjs/string/toU8a.d.ts new file mode 100644 index 0000000..7c0a8ce --- /dev/null +++ b/packages/util/cjs/string/toU8a.d.ts @@ -0,0 +1,16 @@ +import type { AnyString } from '../types.js'; +/** + * @name stringToU8a + * @summary Creates a Uint8Array object from a utf-8 string. + * @description + * String input values return the actual encoded `UInt8Array`. `null` or `undefined` values returns an empty encoded array. + * @example + *
+ * + * ```javascript + * import { stringToU8a } from '@pezkuwi/util'; + * + * stringToU8a('hello'); // [0x68, 0x65, 0x6c, 0x6c, 0x6f] + * ``` + */ +export declare function stringToU8a(value?: AnyString | null): Uint8Array; diff --git a/packages/util/cjs/string/toU8a.js b/packages/util/cjs/string/toU8a.js new file mode 100644 index 0000000..bd38153 --- /dev/null +++ b/packages/util/cjs/string/toU8a.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.stringToU8a = stringToU8a; +const x_textencoder_1 = require("@pezkuwi/x-textencoder"); +const encoder = new x_textencoder_1.TextEncoder(); +/** + * @name stringToU8a + * @summary Creates a Uint8Array object from a utf-8 string. + * @description + * String input values return the actual encoded `UInt8Array`. `null` or `undefined` values returns an empty encoded array. + * @example + *
+ * + * ```javascript + * import { stringToU8a } from '@pezkuwi/util'; + * + * stringToU8a('hello'); // [0x68, 0x65, 0x6c, 0x6c, 0x6f] + * ``` + */ +function stringToU8a(value) { + return value + ? encoder.encode(value.toString()) + : new Uint8Array(); +} diff --git a/packages/util/cjs/stringify.d.ts b/packages/util/cjs/stringify.d.ts new file mode 100644 index 0000000..0d1c501 --- /dev/null +++ b/packages/util/cjs/stringify.d.ts @@ -0,0 +1,6 @@ +/** + * @name stringify + * @summary Performs a JSON.stringify, with BigInt handling + * @description A wrapper for JSON.stringify that handles BigInt values transparently, converting them to string. No differences from the native JSON.stringify function otherwise. + */ +export declare function stringify(value: unknown, space?: string | number): string; diff --git a/packages/util/cjs/stringify.js b/packages/util/cjs/stringify.js new file mode 100644 index 0000000..430f0a0 --- /dev/null +++ b/packages/util/cjs/stringify.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.stringify = stringify; +const bigInt_js_1 = require("./is/bigInt.js"); +/** @internal */ +function replacer(_, v) { + return (0, bigInt_js_1.isBigInt)(v) + ? v.toString() + : v; +} +/** + * @name stringify + * @summary Performs a JSON.stringify, with BigInt handling + * @description A wrapper for JSON.stringify that handles BigInt values transparently, converting them to string. No differences from the native JSON.stringify function otherwise. + */ +function stringify(value, space) { + return JSON.stringify(value, replacer, space); +} diff --git a/packages/util/cjs/types.d.ts b/packages/util/cjs/types.d.ts new file mode 100644 index 0000000..b08d4b6 --- /dev/null +++ b/packages/util/cjs/types.d.ts @@ -0,0 +1,62 @@ +import type { BN } from './bn/bn.js'; +/** An interface that defines an actual JS class */ +export interface Class { + prototype: T; + new (...args: A): T; + hasOwnProperty(prop: string): boolean; + isPrototypeOf(other: unknown): boolean; +} +export type Constructor = Class; +export interface ToBigInt { + toBigInt: () => bigint; +} +export interface ToBn { + toBn: () => BN; +} +export interface SiDef { + power: number; + text: string; + value: string; +} +export interface Logger { + debug: (...values: unknown[]) => void; + error: (...values: unknown[]) => void; + log: (...values: unknown[]) => void; + noop: (...values: unknown[]) => void; + warn: (...values: unknown[]) => void; +} +export interface ToBnOptions { + /** Convert in LE format */ + isLe?: boolean; + /** Number is signed, apply two's complement */ + isNegative?: boolean; +} +export interface NumberOptions extends ToBnOptions { + /** Limit to the specified bitLength, despite input length */ + bitLength?: number; +} +export interface Time { + days: number; + hours: number; + minutes: number; + seconds: number; + milliseconds: number; +} +export type Memoized = F & { + unmemoize: (...args: unknown[]) => void; +}; +export type AnyString = string | String; +export type HexDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f'; +export type HexString = `0x${string}`; +export interface BufferObject extends Uint8Array { + equals: (otherBuffer: Uint8Array) => boolean; + readDoubleLE: (offset?: number) => number; +} +export interface BufferClass extends Class { + from: (value: unknown) => T; + isBuffer: (value: unknown) => boolean; +} +export type U8aLike = number[] | Uint8Array | AnyString; +export interface Observable { + next: (...params: unknown[]) => unknown; +} diff --git a/packages/util/cjs/types.js b/packages/util/cjs/types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/packages/util/cjs/types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/packages/util/cjs/u8a/cmp.d.ts b/packages/util/cjs/u8a/cmp.d.ts new file mode 100644 index 0000000..9b5ce92 --- /dev/null +++ b/packages/util/cjs/u8a/cmp.d.ts @@ -0,0 +1,17 @@ +/** + * @name u8aCmp + * @summary Compares two Uint8Arrays for sorting. + * @description + * For `UInt8Array` (or hex string) input values returning -1, 0 or +1 + * @example + *
+ * + * ```javascript + * import { u8aCmp } from '@pezkuwi/util'; + * + * u8aCmp(new Uint8Array([0x67, 0x65]), new Uint8Array([0x68, 0x65])); // -1 + * u8aCmp(new Uint8Array([0x68, 0x65]), new Uint8Array([0x68, 0x65])); // 0 + * u8aCmp(new Uint8Array([0x69, 0x65]), new Uint8Array([0x68, 0x65])); // +1 + * ``` + */ +export declare function u8aCmp(a: string | Uint8Array, b: string | Uint8Array): number; diff --git a/packages/util/cjs/u8a/cmp.js b/packages/util/cjs/u8a/cmp.js new file mode 100644 index 0000000..197644e --- /dev/null +++ b/packages/util/cjs/u8a/cmp.js @@ -0,0 +1,49 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aCmp = u8aCmp; +const toU8a_js_1 = require("./toU8a.js"); +/** + * @name u8aCmp + * @summary Compares two Uint8Arrays for sorting. + * @description + * For `UInt8Array` (or hex string) input values returning -1, 0 or +1 + * @example + *
+ * + * ```javascript + * import { u8aCmp } from '@pezkuwi/util'; + * + * u8aCmp(new Uint8Array([0x67, 0x65]), new Uint8Array([0x68, 0x65])); // -1 + * u8aCmp(new Uint8Array([0x68, 0x65]), new Uint8Array([0x68, 0x65])); // 0 + * u8aCmp(new Uint8Array([0x69, 0x65]), new Uint8Array([0x68, 0x65])); // +1 + * ``` + */ +function u8aCmp(a, b) { + const u8aa = (0, toU8a_js_1.u8aToU8a)(a); + const u8ab = (0, toU8a_js_1.u8aToU8a)(b); + let i = 0; + while (true) { + const overA = i >= u8aa.length; + const overB = i >= u8ab.length; + if (overA && overB) { + // both ends reached + return 0; + } + else if (overA) { + // a has no more data, b has data + return -1; + } + else if (overB) { + // b has no more data, a has data + return 1; + } + else if (u8aa[i] !== u8ab[i]) { + // the number in this index doesn't match + // (we don't use u8aa[i] - u8ab[i] since that doesn't match with localeCompare) + return u8aa[i] > u8ab[i] + ? 1 + : -1; + } + i++; + } +} diff --git a/packages/util/cjs/u8a/concat.d.ts b/packages/util/cjs/u8a/concat.d.ts new file mode 100644 index 0000000..7413e0b --- /dev/null +++ b/packages/util/cjs/u8a/concat.d.ts @@ -0,0 +1,24 @@ +import type { U8aLike } from '../types.js'; +/** + * @name u8aConcat + * @summary Creates a concatenated Uint8Array from the inputs. + * @description + * Concatenates the input arrays into a single `UInt8Array`. + * @example + *
+ * + * ```javascript + * import { { u8aConcat } from '@pezkuwi/util'; + * + * u8aConcat( + * new Uint8Array([1, 2, 3]), + * new Uint8Array([4, 5, 6]) + * ); // [1, 2, 3, 4, 5, 6] + * ``` + */ +export declare function u8aConcat(...list: readonly U8aLike[]): Uint8Array; +/** + * @name u8aConcatStrict + * @description A strict version of [[u8aConcat]], accepting only Uint8Array inputs + */ +export declare function u8aConcatStrict(u8as: readonly Uint8Array[], length?: number): Uint8Array; diff --git a/packages/util/cjs/u8a/concat.js b/packages/util/cjs/u8a/concat.js new file mode 100644 index 0000000..a195a16 --- /dev/null +++ b/packages/util/cjs/u8a/concat.js @@ -0,0 +1,51 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aConcat = u8aConcat; +exports.u8aConcatStrict = u8aConcatStrict; +const toU8a_js_1 = require("./toU8a.js"); +/** + * @name u8aConcat + * @summary Creates a concatenated Uint8Array from the inputs. + * @description + * Concatenates the input arrays into a single `UInt8Array`. + * @example + *
+ * + * ```javascript + * import { { u8aConcat } from '@pezkuwi/util'; + * + * u8aConcat( + * new Uint8Array([1, 2, 3]), + * new Uint8Array([4, 5, 6]) + * ); // [1, 2, 3, 4, 5, 6] + * ``` + */ +function u8aConcat(...list) { + const count = list.length; + const u8as = new Array(count); + let length = 0; + for (let i = 0; i < count; i++) { + u8as[i] = (0, toU8a_js_1.u8aToU8a)(list[i]); + length += u8as[i].length; + } + return u8aConcatStrict(u8as, length); +} +/** + * @name u8aConcatStrict + * @description A strict version of [[u8aConcat]], accepting only Uint8Array inputs + */ +function u8aConcatStrict(u8as, length = 0) { + const count = u8as.length; + let offset = 0; + if (!length) { + for (let i = 0; i < count; i++) { + length += u8as[i].length; + } + } + const result = new Uint8Array(length); + for (let i = 0; i < count; i++) { + result.set(u8as[i], offset); + offset += u8as[i].length; + } + return result; +} diff --git a/packages/util/cjs/u8a/concatBuffer.d.ts b/packages/util/cjs/u8a/concatBuffer.d.ts new file mode 100644 index 0000000..657bf81 --- /dev/null +++ b/packages/util/cjs/u8a/concatBuffer.d.ts @@ -0,0 +1,19 @@ +import type { U8aLike } from '../types.js'; +/** + * @name u8aConcat + * @summary Creates a concatenated Uint8Array from the inputs. + * @description + * Concatenates the input arrays into a single `UInt8Array`. + * @example + *
+ * + * ```javascript + * import { { u8aConcat } from '@pezkuwi/util'; + * + * u8aConcat( + * new Uint8Array([1, 2, 3]), + * new Uint8Array([4, 5, 6]) + * ); // [1, 2, 3, 4, 5, 6] + * ``` + */ +export declare function u8aConcat(...list: readonly U8aLike[]): Uint8Array; diff --git a/packages/util/cjs/u8a/concatBuffer.js b/packages/util/cjs/u8a/concatBuffer.js new file mode 100644 index 0000000..3d1ecc4 --- /dev/null +++ b/packages/util/cjs/u8a/concatBuffer.js @@ -0,0 +1,29 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aConcat = u8aConcat; +const toU8a_js_1 = require("./toU8a.js"); +/** + * @name u8aConcat + * @summary Creates a concatenated Uint8Array from the inputs. + * @description + * Concatenates the input arrays into a single `UInt8Array`. + * @example + *
+ * + * ```javascript + * import { { u8aConcat } from '@pezkuwi/util'; + * + * u8aConcat( + * new Uint8Array([1, 2, 3]), + * new Uint8Array([4, 5, 6]) + * ); // [1, 2, 3, 4, 5, 6] + * ``` + */ +function u8aConcat(...list) { + const count = list.length; + const u8as = new Array(count); + for (let i = 0; i < count; i++) { + u8as[i] = (0, toU8a_js_1.u8aToU8a)(list[i]); + } + return Uint8Array.from(Buffer.concat(u8as)); +} diff --git a/packages/util/cjs/u8a/empty.d.ts b/packages/util/cjs/u8a/empty.d.ts new file mode 100644 index 0000000..535949d --- /dev/null +++ b/packages/util/cjs/u8a/empty.d.ts @@ -0,0 +1,7 @@ +/** + * @name u8aEmpty + * @summary Tests for a `Uint8Array` for emptyness + * @description + * Checks to see if the input `Uint8Array` has zero length or contains all 0 values. + */ +export declare function u8aEmpty(value: Uint8Array): boolean; diff --git a/packages/util/cjs/u8a/empty.js b/packages/util/cjs/u8a/empty.js new file mode 100644 index 0000000..f128123 --- /dev/null +++ b/packages/util/cjs/u8a/empty.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aEmpty = u8aEmpty; +/** + * @name u8aEmpty + * @summary Tests for a `Uint8Array` for emptyness + * @description + * Checks to see if the input `Uint8Array` has zero length or contains all 0 values. + */ +function u8aEmpty(value) { + const len = value.length | 0; + // on smaller sizes, the byte-by-byte compare is faster than allocating + // another object for DataView (on very large arrays the DataView is faster) + for (let i = 0; i < len; i++) { + if (value[i] | 0) { + return false; + } + } + return true; +} diff --git a/packages/util/cjs/u8a/eq.d.ts b/packages/util/cjs/u8a/eq.d.ts new file mode 100644 index 0000000..2ee4ad2 --- /dev/null +++ b/packages/util/cjs/u8a/eq.d.ts @@ -0,0 +1,15 @@ +/** + * @name u8aEq + * @summary Compares two Uint8Arrays for equality. + * @description + * For `UInt8Array` (or hex string) input values true if there is a match. + * @example + *
+ * + * ```javascript + * import { u8aEq } from '@pezkuwi/util'; + * + * u8aEq(new Uint8Array([0x68, 0x65]), new Uint8Array([0x68, 0x65])); // true + * ``` + */ +export declare function u8aEq(a: string | Uint8Array, b: string | Uint8Array): boolean; diff --git a/packages/util/cjs/u8a/eq.js b/packages/util/cjs/u8a/eq.js new file mode 100644 index 0000000..2c61eea --- /dev/null +++ b/packages/util/cjs/u8a/eq.js @@ -0,0 +1,40 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aEq = u8aEq; +const toU8a_js_1 = require("./toU8a.js"); +/** + * @name u8aEq + * @summary Compares two Uint8Arrays for equality. + * @description + * For `UInt8Array` (or hex string) input values true if there is a match. + * @example + *
+ * + * ```javascript + * import { u8aEq } from '@pezkuwi/util'; + * + * u8aEq(new Uint8Array([0x68, 0x65]), new Uint8Array([0x68, 0x65])); // true + * ``` + */ +function u8aEq(a, b) { + const u8aa = (0, toU8a_js_1.u8aToU8a)(a); + const u8ab = (0, toU8a_js_1.u8aToU8a)(b); + if (u8aa.length === u8ab.length) { + const dvA = new DataView(u8aa.buffer, u8aa.byteOffset); + const dvB = new DataView(u8ab.buffer, u8ab.byteOffset); + const mod = (u8aa.length % 4) | 0; + const length = (u8aa.length - mod) | 0; + for (let i = 0; i < length; i += 4) { + if (dvA.getUint32(i) !== dvB.getUint32(i)) { + return false; + } + } + for (let i = length, count = u8aa.length; i < count; i++) { + if (u8aa[i] !== u8ab[i]) { + return false; + } + } + return true; + } + return false; +} diff --git a/packages/util/cjs/u8a/fixLength.d.ts b/packages/util/cjs/u8a/fixLength.d.ts new file mode 100644 index 0000000..e13ebc9 --- /dev/null +++ b/packages/util/cjs/u8a/fixLength.d.ts @@ -0,0 +1,17 @@ +/** + * @name u8aFixLength + * @summary Shifts a Uint8Array to a specific bitLength + * @description + * Returns a uint8Array with the specified number of bits contained in the return value. (If bitLength is -1, length checking is not done). Values with more bits are trimmed to the specified length. + * @example + *
+ * + * ```javascript + * import { u8aFixLength } from '@pezkuwi/util'; + * + * u8aFixLength('0x12') // => 0x12 + * u8aFixLength('0x12', 16) // => 0x0012 + * u8aFixLength('0x1234', 8) // => 0x12 + * ``` + */ +export declare function u8aFixLength(value: Uint8Array, bitLength?: number, atStart?: boolean): Uint8Array; diff --git a/packages/util/cjs/u8a/fixLength.js b/packages/util/cjs/u8a/fixLength.js new file mode 100644 index 0000000..84c362a --- /dev/null +++ b/packages/util/cjs/u8a/fixLength.js @@ -0,0 +1,31 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aFixLength = u8aFixLength; +/** + * @name u8aFixLength + * @summary Shifts a Uint8Array to a specific bitLength + * @description + * Returns a uint8Array with the specified number of bits contained in the return value. (If bitLength is -1, length checking is not done). Values with more bits are trimmed to the specified length. + * @example + *
+ * + * ```javascript + * import { u8aFixLength } from '@pezkuwi/util'; + * + * u8aFixLength('0x12') // => 0x12 + * u8aFixLength('0x12', 16) // => 0x0012 + * u8aFixLength('0x1234', 8) // => 0x12 + * ``` + */ +function u8aFixLength(value, bitLength = -1, atStart = false) { + const byteLength = Math.ceil(bitLength / 8); + if (bitLength === -1 || value.length === byteLength) { + return value; + } + else if (value.length > byteLength) { + return value.subarray(0, byteLength); + } + const result = new Uint8Array(byteLength); + result.set(value, atStart ? 0 : (byteLength - value.length)); + return result; +} diff --git a/packages/util/cjs/u8a/index.d.ts b/packages/util/cjs/u8a/index.d.ts new file mode 100644 index 0000000..b793d8a --- /dev/null +++ b/packages/util/cjs/u8a/index.d.ts @@ -0,0 +1,18 @@ +/** + * @summary Utility methods to convert to and from `Uint8Array` objects + */ +export { u8aCmp } from './cmp.js'; +export { u8aConcat, u8aConcatStrict } from './concat.js'; +export { u8aEmpty } from './empty.js'; +export { u8aEq } from './eq.js'; +export { u8aFixLength } from './fixLength.js'; +export { u8aSorted } from './sorted.js'; +export { u8aToBigInt } from './toBigInt.js'; +export { u8aToBn } from './toBn.js'; +export { u8aToBuffer } from './toBuffer.js'; +export { u8aToFloat } from './toFloat.js'; +export { u8aToHex } from './toHex.js'; +export { u8aToNumber } from './toNumber.js'; +export { u8aToString } from './toString.js'; +export { u8aToU8a } from './toU8a.js'; +export { U8A_WRAP_ETHEREUM, U8A_WRAP_POSTFIX, U8A_WRAP_PREFIX, u8aIsWrapped, u8aUnwrapBytes, u8aWrapBytes } from './wrap.js'; diff --git a/packages/util/cjs/u8a/index.js b/packages/util/cjs/u8a/index.js new file mode 100644 index 0000000..3566513 --- /dev/null +++ b/packages/util/cjs/u8a/index.js @@ -0,0 +1,42 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aWrapBytes = exports.u8aUnwrapBytes = exports.u8aIsWrapped = exports.U8A_WRAP_PREFIX = exports.U8A_WRAP_POSTFIX = exports.U8A_WRAP_ETHEREUM = exports.u8aToU8a = exports.u8aToString = exports.u8aToNumber = exports.u8aToHex = exports.u8aToFloat = exports.u8aToBuffer = exports.u8aToBn = exports.u8aToBigInt = exports.u8aSorted = exports.u8aFixLength = exports.u8aEq = exports.u8aEmpty = exports.u8aConcatStrict = exports.u8aConcat = exports.u8aCmp = void 0; +/** + * @summary Utility methods to convert to and from `Uint8Array` objects + */ +var cmp_js_1 = require("./cmp.js"); +Object.defineProperty(exports, "u8aCmp", { enumerable: true, get: function () { return cmp_js_1.u8aCmp; } }); +var concat_js_1 = require("./concat.js"); +Object.defineProperty(exports, "u8aConcat", { enumerable: true, get: function () { return concat_js_1.u8aConcat; } }); +Object.defineProperty(exports, "u8aConcatStrict", { enumerable: true, get: function () { return concat_js_1.u8aConcatStrict; } }); +var empty_js_1 = require("./empty.js"); +Object.defineProperty(exports, "u8aEmpty", { enumerable: true, get: function () { return empty_js_1.u8aEmpty; } }); +var eq_js_1 = require("./eq.js"); +Object.defineProperty(exports, "u8aEq", { enumerable: true, get: function () { return eq_js_1.u8aEq; } }); +var fixLength_js_1 = require("./fixLength.js"); +Object.defineProperty(exports, "u8aFixLength", { enumerable: true, get: function () { return fixLength_js_1.u8aFixLength; } }); +var sorted_js_1 = require("./sorted.js"); +Object.defineProperty(exports, "u8aSorted", { enumerable: true, get: function () { return sorted_js_1.u8aSorted; } }); +var toBigInt_js_1 = require("./toBigInt.js"); +Object.defineProperty(exports, "u8aToBigInt", { enumerable: true, get: function () { return toBigInt_js_1.u8aToBigInt; } }); +var toBn_js_1 = require("./toBn.js"); +Object.defineProperty(exports, "u8aToBn", { enumerable: true, get: function () { return toBn_js_1.u8aToBn; } }); +var toBuffer_js_1 = require("./toBuffer.js"); +Object.defineProperty(exports, "u8aToBuffer", { enumerable: true, get: function () { return toBuffer_js_1.u8aToBuffer; } }); +var toFloat_js_1 = require("./toFloat.js"); +Object.defineProperty(exports, "u8aToFloat", { enumerable: true, get: function () { return toFloat_js_1.u8aToFloat; } }); +var toHex_js_1 = require("./toHex.js"); +Object.defineProperty(exports, "u8aToHex", { enumerable: true, get: function () { return toHex_js_1.u8aToHex; } }); +var toNumber_js_1 = require("./toNumber.js"); +Object.defineProperty(exports, "u8aToNumber", { enumerable: true, get: function () { return toNumber_js_1.u8aToNumber; } }); +var toString_js_1 = require("./toString.js"); +Object.defineProperty(exports, "u8aToString", { enumerable: true, get: function () { return toString_js_1.u8aToString; } }); +var toU8a_js_1 = require("./toU8a.js"); +Object.defineProperty(exports, "u8aToU8a", { enumerable: true, get: function () { return toU8a_js_1.u8aToU8a; } }); +var wrap_js_1 = require("./wrap.js"); +Object.defineProperty(exports, "U8A_WRAP_ETHEREUM", { enumerable: true, get: function () { return wrap_js_1.U8A_WRAP_ETHEREUM; } }); +Object.defineProperty(exports, "U8A_WRAP_POSTFIX", { enumerable: true, get: function () { return wrap_js_1.U8A_WRAP_POSTFIX; } }); +Object.defineProperty(exports, "U8A_WRAP_PREFIX", { enumerable: true, get: function () { return wrap_js_1.U8A_WRAP_PREFIX; } }); +Object.defineProperty(exports, "u8aIsWrapped", { enumerable: true, get: function () { return wrap_js_1.u8aIsWrapped; } }); +Object.defineProperty(exports, "u8aUnwrapBytes", { enumerable: true, get: function () { return wrap_js_1.u8aUnwrapBytes; } }); +Object.defineProperty(exports, "u8aWrapBytes", { enumerable: true, get: function () { return wrap_js_1.u8aWrapBytes; } }); diff --git a/packages/util/cjs/u8a/sorted.d.ts b/packages/util/cjs/u8a/sorted.d.ts new file mode 100644 index 0000000..aaa612a --- /dev/null +++ b/packages/util/cjs/u8a/sorted.d.ts @@ -0,0 +1,15 @@ +/** + * @name u8aSorted + * @summary Sorts an array of Uint8Arrays + * @description + * For input `UInt8Array[]` return the sorted result + * @example + *
+ * + * ```javascript + * import { u8aSorted} from '@pezkuwi/util'; + * + * u8aSorted([new Uint8Array([0x69]), new Uint8Array([0x68])]); // [0x68, 0x69] + * ``` + */ +export declare function u8aSorted(u8as: Uint8Array[]): Uint8Array[]; diff --git a/packages/util/cjs/u8a/sorted.js b/packages/util/cjs/u8a/sorted.js new file mode 100644 index 0000000..73d9ffb --- /dev/null +++ b/packages/util/cjs/u8a/sorted.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aSorted = u8aSorted; +const cmp_js_1 = require("./cmp.js"); +/** + * @name u8aSorted + * @summary Sorts an array of Uint8Arrays + * @description + * For input `UInt8Array[]` return the sorted result + * @example + *
+ * + * ```javascript + * import { u8aSorted} from '@pezkuwi/util'; + * + * u8aSorted([new Uint8Array([0x69]), new Uint8Array([0x68])]); // [0x68, 0x69] + * ``` + */ +function u8aSorted(u8as) { + return u8as.sort(cmp_js_1.u8aCmp); +} diff --git a/packages/util/cjs/u8a/toBigInt.d.ts b/packages/util/cjs/u8a/toBigInt.d.ts new file mode 100644 index 0000000..c604cd4 --- /dev/null +++ b/packages/util/cjs/u8a/toBigInt.d.ts @@ -0,0 +1,6 @@ +import type { ToBnOptions } from '../types.js'; +/** + * @name u8aToBigInt + * @summary Creates a BigInt from a Uint8Array object. + */ +export declare function u8aToBigInt(value: Uint8Array, { isLe, isNegative }?: ToBnOptions): bigint; diff --git a/packages/util/cjs/u8a/toBigInt.js b/packages/util/cjs/u8a/toBigInt.js new file mode 100644 index 0000000..6223ad2 --- /dev/null +++ b/packages/util/cjs/u8a/toBigInt.js @@ -0,0 +1,73 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aToBigInt = u8aToBigInt; +const x_bigint_1 = require("@pezkuwi/x-bigint"); +const consts_js_1 = require("../bi/consts.js"); +const U8_MAX = (0, x_bigint_1.BigInt)(256); +const U16_MAX = (0, x_bigint_1.BigInt)(256 * 256); +const U64_MAX = (0, x_bigint_1.BigInt)('0x10000000000000000'); +/** + * @name u8aToBigInt + * @summary Creates a BigInt from a Uint8Array object. + */ +function u8aToBigInt(value, { isLe = true, isNegative = false } = {}) { + // slice + reverse is expensive, however SCALE is LE by default so this is the path + // we are most interested in (the BE is added for the sake of being comprehensive) + if (!isLe) { + value = value.slice().reverse(); + } + const count = value.length; + if (isNegative && count && (value[count - 1] & 0x80)) { + switch (count) { + case 0: + return (0, x_bigint_1.BigInt)(0); + case 1: + return (0, x_bigint_1.BigInt)(((value[0] ^ 0x0000_00ff) * -1) - 1); + case 2: + return (0, x_bigint_1.BigInt)((((value[0] + (value[1] << 8)) ^ 0x0000_ffff) * -1) - 1); + case 4: + return (0, x_bigint_1.BigInt)((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) * -1) - 1); + } + const dvI = new DataView(value.buffer, value.byteOffset); + if (count === 8) { + return dvI.getBigInt64(0, true); + } + let result = (0, x_bigint_1.BigInt)(0); + const mod = count % 2; + for (let i = count - 2; i >= mod; i -= 2) { + result = (result * U16_MAX) + (0, x_bigint_1.BigInt)(dvI.getUint16(i, true) ^ 0xffff); + } + if (mod) { + result = (result * U8_MAX) + (0, x_bigint_1.BigInt)(value[0] ^ 0xff); + } + return (result * -consts_js_1._1n) - consts_js_1._1n; + } + switch (count) { + case 0: + return (0, x_bigint_1.BigInt)(0); + case 1: + return (0, x_bigint_1.BigInt)(value[0]); + case 2: + return (0, x_bigint_1.BigInt)(value[0] + (value[1] << 8)); + case 4: + return (0, x_bigint_1.BigInt)(value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)); + } + const dvI = new DataView(value.buffer, value.byteOffset); + switch (count) { + case 8: + return dvI.getBigUint64(0, true); + case 16: + return (dvI.getBigUint64(8, true) * U64_MAX) + dvI.getBigUint64(0, true); + default: { + let result = (0, x_bigint_1.BigInt)(0); + const mod = count % 2; + for (let i = count - 2; i >= mod; i -= 2) { + result = (result * U16_MAX) + (0, x_bigint_1.BigInt)(dvI.getUint16(i, true)); + } + if (mod) { + result = (result * U8_MAX) + (0, x_bigint_1.BigInt)(value[0]); + } + return result; + } + } +} diff --git a/packages/util/cjs/u8a/toBn.d.ts b/packages/util/cjs/u8a/toBn.d.ts new file mode 100644 index 0000000..8f6c482 --- /dev/null +++ b/packages/util/cjs/u8a/toBn.d.ts @@ -0,0 +1,21 @@ +import type { ToBnOptions } from '../types.js'; +import { BN } from '../bn/bn.js'; +/** + * @name u8aToBn + * @summary Creates a BN from a Uint8Array object. + * @description + * `UInt8Array` input values return the actual BN. `null` or `undefined` values returns an `0x0` value. + * @param value The value to convert + * @param options Options to pass while converting + * @param options.isLe Convert using Little Endian (default) + * @param options.isNegative Convert using two's complement + * @example + *
+ * + * ```javascript + * import { u8aToBn } from '@pezkuwi/util'; + * + * u8aToHex(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0xf])); // 0x68656c0f + * ``` + */ +export declare function u8aToBn(value: Uint8Array, { isLe, isNegative }?: ToBnOptions): BN; diff --git a/packages/util/cjs/u8a/toBn.js b/packages/util/cjs/u8a/toBn.js new file mode 100644 index 0000000..c5dad34 --- /dev/null +++ b/packages/util/cjs/u8a/toBn.js @@ -0,0 +1,81 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aToBn = u8aToBn; +const bn_js_1 = require("../bn/bn.js"); +/** + * @name u8aToBn + * @summary Creates a BN from a Uint8Array object. + * @description + * `UInt8Array` input values return the actual BN. `null` or `undefined` values returns an `0x0` value. + * @param value The value to convert + * @param options Options to pass while converting + * @param options.isLe Convert using Little Endian (default) + * @param options.isNegative Convert using two's complement + * @example + *
+ * + * ```javascript + * import { u8aToBn } from '@pezkuwi/util'; + * + * u8aToHex(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0xf])); // 0x68656c0f + * ``` + */ +function u8aToBn(value, { isLe = true, isNegative = false } = {}) { + // slice + reverse is expensive, however SCALE is LE by default so this is the path + // we are most interested in (the BE is added for the sake of being comprehensive) + if (!isLe) { + value = value.slice().reverse(); + } + const count = value.length; + // shortcut for <= u48 values - in this case the manual conversion + // here seems to be more efficient than passing the full array + if (isNegative && count && (value[count - 1] & 0x80)) { + // Most common case i{8, 16, 32} default LE SCALE-encoded + // For <= 32, we also optimize the xor to a single op + switch (count) { + case 0: + return new bn_js_1.BN(0); + case 1: + return new bn_js_1.BN(((value[0] ^ 0x0000_00ff) * -1) - 1); + case 2: + return new bn_js_1.BN((((value[0] + (value[1] << 8)) ^ 0x0000_ffff) * -1) - 1); + case 3: + return new bn_js_1.BN((((value[0] + (value[1] << 8) + (value[2] << 16)) ^ 0x00ff_ffff) * -1) - 1); + case 4: + // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to + // 32-bit, in the case where the top-most bit is set this yields a negative value + return new bn_js_1.BN((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) * -1) - 1); + case 5: + return new bn_js_1.BN(((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) + ((value[4] ^ 0xff) * 0x1_00_00_00_00)) * -1) - 1); + case 6: + return new bn_js_1.BN(((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) + (((value[4] + (value[5] << 8)) ^ 0x0000_ffff) * 0x1_00_00_00_00)) * -1) - 1); + default: + return new bn_js_1.BN(value, 'le').fromTwos(count * 8); + } + } + // Most common case - u{8, 16, 32} default LE SCALE-encoded + // + // There are some slight benefits in unrolling this specific loop, + // however it comes with diminishing returns since here the actual + // `new BN` does seem to take up the bulk of the time + switch (count) { + case 0: + return new bn_js_1.BN(0); + case 1: + return new bn_js_1.BN(value[0]); + case 2: + return new bn_js_1.BN(value[0] + (value[1] << 8)); + case 3: + return new bn_js_1.BN(value[0] + (value[1] << 8) + (value[2] << 16)); + case 4: + // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to + // 32-bit, in the case where the top-most bit is set this yields a negative value + return new bn_js_1.BN(value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)); + case 5: + return new bn_js_1.BN(value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8)) * 0x1_00_00_00)); + case 6: + return new bn_js_1.BN(value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8) + (value[5] << 16)) * 0x1_00_00_00)); + default: + return new bn_js_1.BN(value, 'le'); + } +} diff --git a/packages/util/cjs/u8a/toBuffer.d.ts b/packages/util/cjs/u8a/toBuffer.d.ts new file mode 100644 index 0000000..0cb0ce1 --- /dev/null +++ b/packages/util/cjs/u8a/toBuffer.d.ts @@ -0,0 +1,16 @@ +import type { BufferObject } from '../types.js'; +/** + * @name u8aToBuffer + * @summary Creates a Buffer object from a hex string. + * @description + * `null` inputs returns an empty `Buffer` result. `UInt8Array` input values return the actual bytes value converted to a `Buffer`. Anything that is not a `UInt8Array` throws an error. + * @example + *
+ * + * ```javascript + * import { u8aToBuffer } from '@pezkuwi/util'; + * + * console.log('Buffer', u8aToBuffer(new Uint8Array([1, 2, 3]))); + * ``` + */ +export declare function u8aToBuffer(value?: Uint8Array | null): T; diff --git a/packages/util/cjs/u8a/toBuffer.js b/packages/util/cjs/u8a/toBuffer.js new file mode 100644 index 0000000..a38177f --- /dev/null +++ b/packages/util/cjs/u8a/toBuffer.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aToBuffer = u8aToBuffer; +const x_global_1 = require("@pezkuwi/x-global"); +const has_js_1 = require("../has.js"); +/** + * @name u8aToBuffer + * @summary Creates a Buffer object from a hex string. + * @description + * `null` inputs returns an empty `Buffer` result. `UInt8Array` input values return the actual bytes value converted to a `Buffer`. Anything that is not a `UInt8Array` throws an error. + * @example + *
+ * + * ```javascript + * import { u8aToBuffer } from '@pezkuwi/util'; + * + * console.log('Buffer', u8aToBuffer(new Uint8Array([1, 2, 3]))); + * ``` + */ +function u8aToBuffer(value) { + return has_js_1.hasBuffer + ? x_global_1.xglobal.Buffer.from(value || []) + : new Uint8Array(value || []); +} diff --git a/packages/util/cjs/u8a/toFloat.d.ts b/packages/util/cjs/u8a/toFloat.d.ts new file mode 100644 index 0000000..ee6a428 --- /dev/null +++ b/packages/util/cjs/u8a/toFloat.d.ts @@ -0,0 +1,11 @@ +interface Options { + bitLength?: 32 | 64; + isLe?: boolean; +} +/** + * @name u8aToFloat + * @description Converts a Uint8Array value into the float (either 32 or 64-bit) + * representation. + */ +export declare function u8aToFloat(value: Uint8Array, { bitLength, isLe }?: Options): number; +export {}; diff --git a/packages/util/cjs/u8a/toFloat.js b/packages/util/cjs/u8a/toFloat.js new file mode 100644 index 0000000..39968af --- /dev/null +++ b/packages/util/cjs/u8a/toFloat.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aToFloat = u8aToFloat; +/** + * @name u8aToFloat + * @description Converts a Uint8Array value into the float (either 32 or 64-bit) + * representation. + */ +function u8aToFloat(value, { bitLength = 32, isLe = true } = {}) { + if (bitLength !== 32 && bitLength !== 64) { + throw new Error('Invalid bitLength provided, expected 32 or 64'); + } + else if (value.length < (bitLength / 8)) { + throw new Error(`Invalid input buffer provided, expected at least ${bitLength / 8} bytes, found ${value.length}`); + } + const dv = new DataView(value.buffer, value.byteOffset); + return bitLength === 32 + ? dv.getFloat32(0, isLe) + : dv.getFloat64(0, isLe); +} diff --git a/packages/util/cjs/u8a/toHex.d.ts b/packages/util/cjs/u8a/toHex.d.ts new file mode 100644 index 0000000..7059f13 --- /dev/null +++ b/packages/util/cjs/u8a/toHex.d.ts @@ -0,0 +1,16 @@ +import type { HexString } from '../types.js'; +/** + * @name u8aToHex + * @summary Creates a hex string from a Uint8Array object. + * @description + * `UInt8Array` input values return the actual hex string. `null` or `undefined` values returns an `0x` string. + * @example + *
+ * + * ```javascript + * import { u8aToHex } from '@pezkuwi/util'; + * + * u8aToHex(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0xf])); // 0x68656c0f + * ``` + */ +export declare function u8aToHex(value?: Uint8Array | null, bitLength?: number, isPrefixed?: boolean): HexString; diff --git a/packages/util/cjs/u8a/toHex.js b/packages/util/cjs/u8a/toHex.js new file mode 100644 index 0000000..022cb84 --- /dev/null +++ b/packages/util/cjs/u8a/toHex.js @@ -0,0 +1,56 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aToHex = u8aToHex; +const U8 = new Array(256); +const U16 = new Array(256 * 256); +for (let n = 0; n < 256; n++) { + U8[n] = n.toString(16).padStart(2, '0'); +} +for (let i = 0; i < 256; i++) { + const s = i << 8; + for (let j = 0; j < 256; j++) { + U16[s | j] = U8[i] + U8[j]; + } +} +/** @internal */ +function hex(value, result) { + const mod = (value.length % 2) | 0; + const length = (value.length - mod) | 0; + for (let i = 0; i < length; i += 2) { + result += U16[(value[i] << 8) | value[i + 1]]; + } + if (mod) { + result += U8[value[length] | 0]; + } + return result; +} +/** + * @name u8aToHex + * @summary Creates a hex string from a Uint8Array object. + * @description + * `UInt8Array` input values return the actual hex string. `null` or `undefined` values returns an `0x` string. + * @example + *
+ * + * ```javascript + * import { u8aToHex } from '@pezkuwi/util'; + * + * u8aToHex(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0xf])); // 0x68656c0f + * ``` + */ +function u8aToHex(value, bitLength = -1, isPrefixed = true) { + // this is not 100% correct sinmce we support isPrefixed = false.... + const empty = isPrefixed + ? '0x' + : ''; + if (!value?.length) { + return empty; + } + else if (bitLength > 0) { + const length = Math.ceil(bitLength / 8); + if (value.length > length) { + return `${hex(value.subarray(0, length / 2), empty)}…${hex(value.subarray(value.length - length / 2), '')}`; + } + } + return hex(value, empty); +} diff --git a/packages/util/cjs/u8a/toHexBuffer.d.ts b/packages/util/cjs/u8a/toHexBuffer.d.ts new file mode 100644 index 0000000..7059f13 --- /dev/null +++ b/packages/util/cjs/u8a/toHexBuffer.d.ts @@ -0,0 +1,16 @@ +import type { HexString } from '../types.js'; +/** + * @name u8aToHex + * @summary Creates a hex string from a Uint8Array object. + * @description + * `UInt8Array` input values return the actual hex string. `null` or `undefined` values returns an `0x` string. + * @example + *
+ * + * ```javascript + * import { u8aToHex } from '@pezkuwi/util'; + * + * u8aToHex(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0xf])); // 0x68656c0f + * ``` + */ +export declare function u8aToHex(value?: Uint8Array | null, bitLength?: number, isPrefixed?: boolean): HexString; diff --git a/packages/util/cjs/u8a/toHexBuffer.js b/packages/util/cjs/u8a/toHexBuffer.js new file mode 100644 index 0000000..aa2366e --- /dev/null +++ b/packages/util/cjs/u8a/toHexBuffer.js @@ -0,0 +1,25 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aToHex = u8aToHex; +/** + * @name u8aToHex + * @summary Creates a hex string from a Uint8Array object. + * @description + * `UInt8Array` input values return the actual hex string. `null` or `undefined` values returns an `0x` string. + * @example + *
+ * + * ```javascript + * import { u8aToHex } from '@pezkuwi/util'; + * + * u8aToHex(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0xf])); // 0x68656c0f + * ``` + */ +function u8aToHex(value, bitLength = -1, isPrefixed = true) { + const length = Math.ceil(bitLength / 8); + return `${isPrefixed ? '0x' : ''}${!value?.length + ? '' + : (bitLength > 0 && value.length > length) + ? `${Buffer.from(value.subarray(0, length / 2)).toString('hex')}…${Buffer.from(value.subarray(value.length - length / 2)).toString('hex')}` + : Buffer.from(value).toString('hex')}`; +} diff --git a/packages/util/cjs/u8a/toNumber.d.ts b/packages/util/cjs/u8a/toNumber.d.ts new file mode 100644 index 0000000..0fdd425 --- /dev/null +++ b/packages/util/cjs/u8a/toNumber.d.ts @@ -0,0 +1,6 @@ +import type { ToBnOptions } from '../types.js'; +/** + * @name u8aToNumber + * @summary Creates a number from a Uint8Array object. + */ +export declare function u8aToNumber(value: Uint8Array, { isLe, isNegative }?: ToBnOptions): number; diff --git a/packages/util/cjs/u8a/toNumber.js b/packages/util/cjs/u8a/toNumber.js new file mode 100644 index 0000000..690c13f --- /dev/null +++ b/packages/util/cjs/u8a/toNumber.js @@ -0,0 +1,61 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aToNumber = u8aToNumber; +/** + * @name u8aToNumber + * @summary Creates a number from a Uint8Array object. + */ +function u8aToNumber(value, { isLe = true, isNegative = false } = {}) { + // slice + reverse is expensive, however SCALE is LE by default so this is the path + // we are most interested in (the BE is added for the sake of being comprehensive) + if (!isLe) { + value = value.slice().reverse(); + } + const count = value.length; + // When the value is a i{8, 16, 24, 32, 40, 40} values and the top-most bit + // indicates a signed value, we use a two's complement conversion. If one of these + // flags are not set, we just do a normal unsigned conversion (the same shortcut + // applies in both the u8aTo{BigInt, Bn} conversions as well) + if (isNegative && count && (value[count - 1] & 0x80)) { + switch (count) { + case 0: + return 0; + case 1: + return (((value[0] ^ 0x0000_00ff) * -1) - 1); + case 2: + return ((((value[0] + (value[1] << 8)) ^ 0x0000_ffff) * -1) - 1); + case 3: + return ((((value[0] + (value[1] << 8) + (value[2] << 16)) ^ 0x00ff_ffff) * -1) - 1); + case 4: + // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to + // 32-bit, in the case where the top-most bit is set this yields a negative value + return ((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) * -1) - 1); + case 5: + return (((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) + ((value[4] ^ 0xff) * 0x1_00_00_00_00)) * -1) - 1); + case 6: + return (((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) + (((value[4] + (value[5] << 8)) ^ 0x0000_ffff) * 0x1_00_00_00_00)) * -1) - 1); + default: + throw new Error('Value more than 48-bits cannot be reliably converted'); + } + } + switch (count) { + case 0: + return 0; + case 1: + return value[0]; + case 2: + return value[0] + (value[1] << 8); + case 3: + return value[0] + (value[1] << 8) + (value[2] << 16); + case 4: + // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to + // 32-bit, in the case where the top-most bit is set this yields a negative value + return value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00); + case 5: + return value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8)) * 0x1_00_00_00); + case 6: + return value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8) + (value[5] << 16)) * 0x1_00_00_00); + default: + throw new Error('Value more than 48-bits cannot be reliably converted'); + } +} diff --git a/packages/util/cjs/u8a/toString.d.ts b/packages/util/cjs/u8a/toString.d.ts new file mode 100644 index 0000000..21e6490 --- /dev/null +++ b/packages/util/cjs/u8a/toString.d.ts @@ -0,0 +1,15 @@ +/** + * @name u8aToString + * @summary Creates a utf-8 string from a Uint8Array object. + * @description + * `UInt8Array` input values return the actual decoded utf-8 string. `null` or `undefined` values returns an empty string. + * @example + *
+ * + * ```javascript + * import { u8aToString } from '@pezkuwi/util'; + * + * u8aToString(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0x6f])); // hello + * ``` + */ +export declare function u8aToString(value?: Uint8Array | null): string; diff --git a/packages/util/cjs/u8a/toString.js b/packages/util/cjs/u8a/toString.js new file mode 100644 index 0000000..70960d0 --- /dev/null +++ b/packages/util/cjs/u8a/toString.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aToString = u8aToString; +const x_textdecoder_1 = require("@pezkuwi/x-textdecoder"); +const decoder = new x_textdecoder_1.TextDecoder('utf-8'); +/** + * @name u8aToString + * @summary Creates a utf-8 string from a Uint8Array object. + * @description + * `UInt8Array` input values return the actual decoded utf-8 string. `null` or `undefined` values returns an empty string. + * @example + *
+ * + * ```javascript + * import { u8aToString } from '@pezkuwi/util'; + * + * u8aToString(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0x6f])); // hello + * ``` + */ +function u8aToString(value) { + return value + ? decoder.decode(value) + : ''; +} diff --git a/packages/util/cjs/u8a/toU8a.d.ts b/packages/util/cjs/u8a/toU8a.d.ts new file mode 100644 index 0000000..68e60e7 --- /dev/null +++ b/packages/util/cjs/u8a/toU8a.d.ts @@ -0,0 +1,19 @@ +import type { U8aLike } from '../types.js'; +/** + * @name u8aToU8a + * @summary Creates a Uint8Array value from a Uint8Array, Buffer, string or hex input. + * @description + * `null` or `undefined` inputs returns a `[]` result, Uint8Array values returns the value, hex strings returns a Uint8Array representation. + * If `strict` is true, `null` or `undefined` will throw an error instead of returning an empty array. + * Supports input types: Uint8Array, Buffer, hex string, string, or number array. + * @example + *
+ * + * ```javascript + * import { u8aToU8a } from '@pezkuwi/util'; + * + * u8aToU8a(new Uint8Array([0x12, 0x34]); // => Uint8Array([0x12, 0x34]) + * u8aToU8a(0x1234); // => Uint8Array([0x12, 0x34]) + * ``` + */ +export declare function u8aToU8a(value?: U8aLike | null, strict?: boolean): Uint8Array; diff --git a/packages/util/cjs/u8a/toU8a.js b/packages/util/cjs/u8a/toU8a.js new file mode 100644 index 0000000..ede55b1 --- /dev/null +++ b/packages/util/cjs/u8a/toU8a.js @@ -0,0 +1,42 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u8aToU8a = u8aToU8a; +const toU8a_js_1 = require("../hex/toU8a.js"); +const buffer_js_1 = require("../is/buffer.js"); +const hex_js_1 = require("../is/hex.js"); +const u8a_js_1 = require("../is/u8a.js"); +const toU8a_js_2 = require("../string/toU8a.js"); +/** + * @name u8aToU8a + * @summary Creates a Uint8Array value from a Uint8Array, Buffer, string or hex input. + * @description + * `null` or `undefined` inputs returns a `[]` result, Uint8Array values returns the value, hex strings returns a Uint8Array representation. + * If `strict` is true, `null` or `undefined` will throw an error instead of returning an empty array. + * Supports input types: Uint8Array, Buffer, hex string, string, or number array. + * @example + *
+ * + * ```javascript + * import { u8aToU8a } from '@pezkuwi/util'; + * + * u8aToU8a(new Uint8Array([0x12, 0x34]); // => Uint8Array([0x12, 0x34]) + * u8aToU8a(0x1234); // => Uint8Array([0x12, 0x34]) + * ``` + */ +function u8aToU8a(value, strict = false) { + if (strict && (value === null || value === undefined)) { + throw new Error('u8aToU8a: Expected non-null, non-undefined value'); + } + return (0, u8a_js_1.isU8a)(value) + // NOTE isBuffer needs to go here since it actually extends + // Uint8Array on Node.js environments, so all Buffer are Uint8Array, + // but Uint8Array is not Buffer + ? (0, buffer_js_1.isBuffer)(value) + ? new Uint8Array(value) + : value + : (0, hex_js_1.isHex)(value) + ? (0, toU8a_js_1.hexToU8a)(value) + : Array.isArray(value) + ? new Uint8Array(value) + : (0, toU8a_js_2.stringToU8a)(value); +} diff --git a/packages/util/cjs/u8a/wrap.d.ts b/packages/util/cjs/u8a/wrap.d.ts new file mode 100644 index 0000000..19a8417 --- /dev/null +++ b/packages/util/cjs/u8a/wrap.d.ts @@ -0,0 +1,22 @@ +import type { U8aLike } from '../types.js'; +/** @internal */ +export declare const U8A_WRAP_ETHEREUM: Uint8Array; +/** @internal */ +export declare const U8A_WRAP_PREFIX: Uint8Array; +/** @internal */ +export declare const U8A_WRAP_POSTFIX: Uint8Array; +/** @internal */ +export declare function u8aIsWrapped(u8a: Uint8Array, withEthereum: boolean): boolean; +/** + * @name u8aUnwrapBytes + * @description Removes all ... wrappers from the supplied value + */ +export declare function u8aUnwrapBytes(bytes: U8aLike): Uint8Array; +/** + * @name u8aWrapBytes + * @description + * Adds a ... wrapper to the supplied value, if + * - We don't already have a Bytes wrapper + * - The message is not an Ethereum-style message + */ +export declare function u8aWrapBytes(bytes: U8aLike): Uint8Array; diff --git a/packages/util/cjs/u8a/wrap.js b/packages/util/cjs/u8a/wrap.js new file mode 100644 index 0000000..cb234e3 --- /dev/null +++ b/packages/util/cjs/u8a/wrap.js @@ -0,0 +1,49 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.U8A_WRAP_POSTFIX = exports.U8A_WRAP_PREFIX = exports.U8A_WRAP_ETHEREUM = void 0; +exports.u8aIsWrapped = u8aIsWrapped; +exports.u8aUnwrapBytes = u8aUnwrapBytes; +exports.u8aWrapBytes = u8aWrapBytes; +const concat_js_1 = require("./concat.js"); +const eq_js_1 = require("./eq.js"); +const toU8a_js_1 = require("./toU8a.js"); +/** @internal */ +exports.U8A_WRAP_ETHEREUM = (0, toU8a_js_1.u8aToU8a)('\x19Ethereum Signed Message:\n'); +/** @internal */ +exports.U8A_WRAP_PREFIX = (0, toU8a_js_1.u8aToU8a)(''); +/** @internal */ +exports.U8A_WRAP_POSTFIX = (0, toU8a_js_1.u8aToU8a)(''); +const WRAP_LEN = exports.U8A_WRAP_PREFIX.length + exports.U8A_WRAP_POSTFIX.length; +/** @internal */ +function u8aIsWrapped(u8a, withEthereum) { + return ((u8a.length >= WRAP_LEN && + (0, eq_js_1.u8aEq)(u8a.subarray(0, exports.U8A_WRAP_PREFIX.length), exports.U8A_WRAP_PREFIX) && + (0, eq_js_1.u8aEq)(u8a.slice(-exports.U8A_WRAP_POSTFIX.length), exports.U8A_WRAP_POSTFIX)) || + (withEthereum && + u8a.length >= exports.U8A_WRAP_ETHEREUM.length && + (0, eq_js_1.u8aEq)(u8a.subarray(0, exports.U8A_WRAP_ETHEREUM.length), exports.U8A_WRAP_ETHEREUM))); +} +/** + * @name u8aUnwrapBytes + * @description Removes all ... wrappers from the supplied value + */ +function u8aUnwrapBytes(bytes) { + const u8a = (0, toU8a_js_1.u8aToU8a)(bytes); + // we don't want to unwrap Ethereum-style wraps + return u8aIsWrapped(u8a, false) + ? u8a.subarray(exports.U8A_WRAP_PREFIX.length, u8a.length - exports.U8A_WRAP_POSTFIX.length) + : u8a; +} +/** + * @name u8aWrapBytes + * @description + * Adds a ... wrapper to the supplied value, if + * - We don't already have a Bytes wrapper + * - The message is not an Ethereum-style message + */ +function u8aWrapBytes(bytes) { + const u8a = (0, toU8a_js_1.u8aToU8a)(bytes); + return u8aIsWrapped(u8a, true) + ? u8a + : (0, concat_js_1.u8aConcatStrict)([exports.U8A_WRAP_PREFIX, u8a, exports.U8A_WRAP_POSTFIX]); +} diff --git a/packages/util/compact/addLength.d.ts b/packages/util/compact/addLength.d.ts new file mode 100644 index 0000000..3a1a5f0 --- /dev/null +++ b/packages/util/compact/addLength.d.ts @@ -0,0 +1,13 @@ +/** + * @name compactAddLength + * @description Adds a length prefix to the input value + * @example + *
+ * + * ```javascript + * import { compactAddLength } from '@pezkuwi/util'; + * + * console.log(compactAddLength(new Uint8Array([0xde, 0xad, 0xbe, 0xef]))); // Uint8Array([4 << 2, 0xde, 0xad, 0xbe, 0xef]) + * ``` + */ +export declare function compactAddLength(input: Uint8Array): Uint8Array; diff --git a/packages/util/compact/addLength.js b/packages/util/compact/addLength.js new file mode 100644 index 0000000..f1bdf29 --- /dev/null +++ b/packages/util/compact/addLength.js @@ -0,0 +1,20 @@ +import { u8aConcatStrict } from '../u8a/index.js'; +import { compactToU8a } from './toU8a.js'; +/** + * @name compactAddLength + * @description Adds a length prefix to the input value + * @example + *
+ * + * ```javascript + * import { compactAddLength } from '@pezkuwi/util'; + * + * console.log(compactAddLength(new Uint8Array([0xde, 0xad, 0xbe, 0xef]))); // Uint8Array([4 << 2, 0xde, 0xad, 0xbe, 0xef]) + * ``` + */ +export function compactAddLength(input) { + return u8aConcatStrict([ + compactToU8a(input.length), + input + ]); +} diff --git a/packages/util/compact/defaults.d.ts b/packages/util/compact/defaults.d.ts new file mode 100644 index 0000000..271842c --- /dev/null +++ b/packages/util/compact/defaults.d.ts @@ -0,0 +1,3 @@ +import type { BitLength } from './types.js'; +/** @internal */ +export declare const DEFAULT_BITLENGTH: BitLength; diff --git a/packages/util/compact/defaults.js b/packages/util/compact/defaults.js new file mode 100644 index 0000000..6e1bc33 --- /dev/null +++ b/packages/util/compact/defaults.js @@ -0,0 +1,2 @@ +/** @internal */ +export const DEFAULT_BITLENGTH = 32; diff --git a/packages/util/compact/fromU8a.d.ts b/packages/util/compact/fromU8a.d.ts new file mode 100644 index 0000000..1c26b1b --- /dev/null +++ b/packages/util/compact/fromU8a.d.ts @@ -0,0 +1,22 @@ +import type { U8aLike } from '../types.js'; +import { BN } from '../bn/index.js'; +/** + * @name compactFromU8a + * @description Retrives the offset and encoded length from a compact-prefixed value + * @example + *
+ * + * ```javascript + * import { compactFromU8a } from '@pezkuwi/util'; + * + * const [offset, length] = compactFromU8a(new Uint8Array([254, 255, 3, 0])); + * + * console.log('value offset=', offset, 'length=', length); // 4, 0xffff + * ``` + */ +export declare function compactFromU8a(input: U8aLike): [number, BN]; +/** + * @name compactFromU8aLim + * @description A limited version of [[compactFromU8a]], accepting only Uint8Array inputs for values <= 48 bits + */ +export declare function compactFromU8aLim(u8a: Uint8Array): [number, number]; diff --git a/packages/util/compact/fromU8a.js b/packages/util/compact/fromU8a.js new file mode 100644 index 0000000..492164a --- /dev/null +++ b/packages/util/compact/fromU8a.js @@ -0,0 +1,88 @@ +import { BN } from '../bn/index.js'; +import { u8aToBn, u8aToU8a } from '../u8a/index.js'; +/** + * @name compactFromU8a + * @description Retrives the offset and encoded length from a compact-prefixed value + * @example + *
+ * + * ```javascript + * import { compactFromU8a } from '@pezkuwi/util'; + * + * const [offset, length] = compactFromU8a(new Uint8Array([254, 255, 3, 0])); + * + * console.log('value offset=', offset, 'length=', length); // 4, 0xffff + * ``` + */ +export function compactFromU8a(input) { + const u8a = u8aToU8a(input); + // The u8a is manually converted here for 1, 2 & 4 lengths, it is 2x faster + // than doing an additional call to u8aToBn (as with variable length) + switch (u8a[0] & 0b11) { + case 0b00: + return [1, new BN(u8a[0] >>> 2)]; + case 0b01: + return [2, new BN((u8a[0] + (u8a[1] << 8)) >>> 2)]; + case 0b10: + // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to + // 32-bit, in the case where the top-most bit is set this yields a negative value + return [4, new BN((u8a[0] + (u8a[1] << 8) + (u8a[2] << 16) + (u8a[3] * 0x1_00_00_00)) >>> 2)]; + // 0b11 + default: { + // add 5 to shifted (4 for base length, 1 for this byte) + const offset = (u8a[0] >>> 2) + 5; + // we unroll the loop + switch (offset) { + // there still could be 4 bytes data, similar to 0b10 above (with offsets) + case 5: + // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to + // 32-bit, in the case where the top-most bit is set this yields a negative value + return [5, new BN(u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + (u8a[4] * 0x1_00_00_00))]; + case 6: + return [6, new BN(u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + ((u8a[4] + (u8a[5] << 8)) * 0x1_00_00_00))]; + // 6 bytes data is the maximum, 48 bits (56 would overflow) + case 7: + return [7, new BN(u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + ((u8a[4] + (u8a[5] << 8) + (u8a[6] << 16)) * 0x1_00_00_00))]; + // for anything else, use the non-unrolled version + default: + return [offset, u8aToBn(u8a.subarray(1, offset))]; + } + } + } +} +/** + * @name compactFromU8aLim + * @description A limited version of [[compactFromU8a]], accepting only Uint8Array inputs for values <= 48 bits + */ +export function compactFromU8aLim(u8a) { + // The u8a is manually converted here for 1, 2 & 4 lengths, it is 2x faster + // than doing an additional call to u8aToBn (as with variable length) + switch (u8a[0] & 0b11) { + case 0b00: + return [1, u8a[0] >>> 2]; + case 0b01: + return [2, (u8a[0] + (u8a[1] << 8)) >>> 2]; + case 0b10: + // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to + // 32-bit, in the case where the top-most bit is set this yields a negative value + return [4, (u8a[0] + (u8a[1] << 8) + (u8a[2] << 16) + (u8a[3] * 0x1_00_00_00)) >>> 2]; + // 0b11 + default: { + // add 5 to shifted (4 for base length, 1 for this byte) + // we unroll the loop + switch ((u8a[0] >>> 2) + 5) { + // there still could be 4 bytes data, similar to 0b10 above (with offsets) + case 5: + return [5, u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + (u8a[4] * 0x1_00_00_00)]; + case 6: + return [6, u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + ((u8a[4] + (u8a[5] << 8)) * 0x1_00_00_00)]; + // 6 bytes data is the maximum, 48 bits (56 would overflow) + case 7: + return [7, u8a[1] + (u8a[2] << 8) + (u8a[3] << 16) + ((u8a[4] + (u8a[5] << 8) + (u8a[6] << 16)) * 0x1_00_00_00)]; + // for anything else, we are above the actual MAX_SAFE_INTEGER - bail out + default: + throw new Error('Compact input is > Number.MAX_SAFE_INTEGER'); + } + } + } +} diff --git a/packages/util/compact/index.d.ts b/packages/util/compact/index.d.ts new file mode 100644 index 0000000..5114102 --- /dev/null +++ b/packages/util/compact/index.d.ts @@ -0,0 +1,24 @@ +/** + * @description + * Encoding and decoding of parity-codec compact numbers. The codec is created + * to take up the least amount of space for a specific number. It performs the + * same function as Length, however differs in that it uses a variable number of + * bytes to do the actual encoding. From the Rust implementation for compact + * encoding: + * + * 0b00 00 00 00 / 00 00 00 00 / 00 00 00 00 / 00 00 00 00 + * (0 ... 2**6 - 1) (u8) + * xx xx xx 00 + * (2**6 ... 2**14 - 1) (u8, u16) low LH high + * yL yL yL 01 / yH yH yH yL + * (2**14 ... 2**30 - 1) (u16, u32) low LMMH high + * zL zL zL 10 / zM zM zM zL / zM zM zM zM / zH zH zH zM + * (2**30 ... 2**536 - 1) (u32, u64, u128, U256, U512, U520) straight LE-encoded + * nn nn nn 11 [ / zz zz zz zz ]{4 + n} + * + * Note: we use *LOW BITS* of the LSB in LE encoding to encode the 2 bit key. + */ +export { compactAddLength } from './addLength.js'; +export { compactFromU8a, compactFromU8aLim } from './fromU8a.js'; +export { compactStripLength } from './stripLength.js'; +export { compactToU8a } from './toU8a.js'; diff --git a/packages/util/compact/index.js b/packages/util/compact/index.js new file mode 100644 index 0000000..5114102 --- /dev/null +++ b/packages/util/compact/index.js @@ -0,0 +1,24 @@ +/** + * @description + * Encoding and decoding of parity-codec compact numbers. The codec is created + * to take up the least amount of space for a specific number. It performs the + * same function as Length, however differs in that it uses a variable number of + * bytes to do the actual encoding. From the Rust implementation for compact + * encoding: + * + * 0b00 00 00 00 / 00 00 00 00 / 00 00 00 00 / 00 00 00 00 + * (0 ... 2**6 - 1) (u8) + * xx xx xx 00 + * (2**6 ... 2**14 - 1) (u8, u16) low LH high + * yL yL yL 01 / yH yH yH yL + * (2**14 ... 2**30 - 1) (u16, u32) low LMMH high + * zL zL zL 10 / zM zM zM zL / zM zM zM zM / zH zH zH zM + * (2**30 ... 2**536 - 1) (u32, u64, u128, U256, U512, U520) straight LE-encoded + * nn nn nn 11 [ / zz zz zz zz ]{4 + n} + * + * Note: we use *LOW BITS* of the LSB in LE encoding to encode the 2 bit key. + */ +export { compactAddLength } from './addLength.js'; +export { compactFromU8a, compactFromU8aLim } from './fromU8a.js'; +export { compactStripLength } from './stripLength.js'; +export { compactToU8a } from './toU8a.js'; diff --git a/packages/util/compact/stripLength.d.ts b/packages/util/compact/stripLength.d.ts new file mode 100644 index 0000000..86dedec --- /dev/null +++ b/packages/util/compact/stripLength.d.ts @@ -0,0 +1,13 @@ +/** + * @name compactStripLength + * @description Removes the length prefix, returning both the total length (including the value + compact encoding) and the decoded value with the correct length + * @example + *
+ * + * ```javascript + * import { compactStripLength } from '@pezkuwi/util'; + * + * console.log(compactStripLength(new Uint8Array([2 << 2, 0xde, 0xad]))); // [2, Uint8Array[0xde, 0xad]] + * ``` + */ +export declare function compactStripLength(input: Uint8Array): [number, Uint8Array]; diff --git a/packages/util/compact/stripLength.js b/packages/util/compact/stripLength.js new file mode 100644 index 0000000..d3e0e41 --- /dev/null +++ b/packages/util/compact/stripLength.js @@ -0,0 +1,21 @@ +import { compactFromU8a } from './fromU8a.js'; +/** + * @name compactStripLength + * @description Removes the length prefix, returning both the total length (including the value + compact encoding) and the decoded value with the correct length + * @example + *
+ * + * ```javascript + * import { compactStripLength } from '@pezkuwi/util'; + * + * console.log(compactStripLength(new Uint8Array([2 << 2, 0xde, 0xad]))); // [2, Uint8Array[0xde, 0xad]] + * ``` + */ +export function compactStripLength(input) { + const [offset, length] = compactFromU8a(input); + const total = offset + length.toNumber(); + return [ + total, + input.subarray(offset, total) + ]; +} diff --git a/packages/util/compact/toU8a.d.ts b/packages/util/compact/toU8a.d.ts new file mode 100644 index 0000000..732cffe --- /dev/null +++ b/packages/util/compact/toU8a.d.ts @@ -0,0 +1,14 @@ +import { BN } from '../bn/index.js'; +/** + * @name compactToU8a + * @description Encodes a number into a compact representation + * @example + *
+ * + * ```javascript + * import { compactToU8a } from '@pezkuwi/util'; + * + * console.log(compactToU8a(511, 32)); // Uint8Array([0b11111101, 0b00000111]) + * ``` + */ +export declare function compactToU8a(value: BN | bigint | number): Uint8Array; diff --git a/packages/util/compact/toU8a.js b/packages/util/compact/toU8a.js new file mode 100644 index 0000000..8b12096 --- /dev/null +++ b/packages/util/compact/toU8a.js @@ -0,0 +1,45 @@ +import { BN, BN_ONE, BN_TWO, bnToBn, bnToU8a } from '../bn/index.js'; +import { u8aConcatStrict } from '../u8a/index.js'; +const MAX_U8 = BN_TWO.pow(new BN(8 - 2)).isub(BN_ONE); +const MAX_U16 = BN_TWO.pow(new BN(16 - 2)).isub(BN_ONE); +const MAX_U32 = BN_TWO.pow(new BN(32 - 2)).isub(BN_ONE); +const BL_16 = { bitLength: 16 }; +const BL_32 = { bitLength: 32 }; +/** + * @name compactToU8a + * @description Encodes a number into a compact representation + * @example + *
+ * + * ```javascript + * import { compactToU8a } from '@pezkuwi/util'; + * + * console.log(compactToU8a(511, 32)); // Uint8Array([0b11111101, 0b00000111]) + * ``` + */ +export function compactToU8a(value) { + const bn = bnToBn(value); + if (bn.lte(MAX_U8)) { + return new Uint8Array([bn.toNumber() << 2]); + } + else if (bn.lte(MAX_U16)) { + return bnToU8a(bn.shln(2).iadd(BN_ONE), BL_16); + } + else if (bn.lte(MAX_U32)) { + return bnToU8a(bn.shln(2).iadd(BN_TWO), BL_32); + } + const u8a = bnToU8a(bn); + let length = u8a.length; + // adjust to the minimum number of bytes + while (u8a[length - 1] === 0) { + length--; + } + if (length < 4) { + throw new Error('Invalid length, previous checks match anything less than 2^30'); + } + return u8aConcatStrict([ + // subtract 4 as minimum (also catered for in decoding) + new Uint8Array([((length - 4) << 2) + 0b11]), + u8a.subarray(0, length) + ]); +} diff --git a/packages/util/compact/types.d.ts b/packages/util/compact/types.d.ts new file mode 100644 index 0000000..d4a6650 --- /dev/null +++ b/packages/util/compact/types.d.ts @@ -0,0 +1 @@ +export type BitLength = 8 | 16 | 32 | 64 | 128 | 256; diff --git a/packages/util/compact/types.js b/packages/util/compact/types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/util/compact/types.js @@ -0,0 +1 @@ +export {}; diff --git a/packages/util/detectPackage.d.ts b/packages/util/detectPackage.d.ts new file mode 100644 index 0000000..fc66015 --- /dev/null +++ b/packages/util/detectPackage.d.ts @@ -0,0 +1,17 @@ +interface VersionPath { + path: string; + type: string; + version: string; +} +interface PackageInfo extends VersionPath { + name: string; +} +type FnString = () => string | undefined; +export declare const POLKADOTJS_DISABLE_ESM_CJS_WARNING_FLAG = "POLKADOTJS_DISABLE_ESM_CJS_WARNING"; +/** + * @name detectPackage + * @summary Checks that a specific package is only imported once + * @description A `@pezkuwi/*` version detection utility, checking for one occurrence of a package in addition to checking for dependency versions. + */ +export declare function detectPackage({ name, path, type, version }: PackageInfo, pathOrFn?: FnString | string | false | null, deps?: PackageInfo[]): void; +export {}; diff --git a/packages/util/detectPackage.js b/packages/util/detectPackage.js new file mode 100644 index 0000000..9c1eaf8 --- /dev/null +++ b/packages/util/detectPackage.js @@ -0,0 +1,96 @@ +import { xglobal } from '@pezkuwi/x-global'; +import { isFunction } from './is/function.js'; +const DEDUPE = 'Either remove and explicitly install matching versions or dedupe using your package manager.\nThe following conflicting packages were found:'; +export const POLKADOTJS_DISABLE_ESM_CJS_WARNING_FLAG = 'POLKADOTJS_DISABLE_ESM_CJS_WARNING'; +/** @internal */ +function getEntry(name) { + const _global = xglobal; + if (!_global.__polkadotjs) { + _global.__polkadotjs = {}; + } + if (!_global.__polkadotjs[name]) { + _global.__polkadotjs[name] = []; + } + return _global.__polkadotjs[name]; +} +/** @internal */ +function formatDisplay(all, fmt) { + let max = 0; + for (let i = 0, count = all.length; i < count; i++) { + max = Math.max(max, all[i].version.length); + } + return all + .map((d) => `\t${fmt(d.version.padEnd(max), d).join('\t')}`) + .join('\n'); +} +/** @internal */ +function formatInfo(version, { name }) { + return [ + version, + name + ]; +} +/** @internal */ +function formatVersion(version, { path, type }) { + let extracted; + if (path && path.length >= 5) { + const nmIndex = path.indexOf('node_modules'); + extracted = nmIndex === -1 + ? path + : path.substring(nmIndex); + } + else { + extracted = ''; + } + return [ + `${`${type || ''}`.padStart(3)} ${version}`, + extracted + ]; +} +/** @internal */ +function getPath(infoPath, pathOrFn) { + if (infoPath) { + return infoPath; + } + else if (isFunction(pathOrFn)) { + try { + return pathOrFn() || ''; + } + catch { + return ''; + } + } + return pathOrFn || ''; +} +/** @internal */ +function warn(pre, all, fmt) { + console.warn(`${pre}\n${DEDUPE}\n${formatDisplay(all, fmt)}`); +} +/** + * @name detectPackage + * @summary Checks that a specific package is only imported once + * @description A `@pezkuwi/*` version detection utility, checking for one occurrence of a package in addition to checking for dependency versions. + */ +export function detectPackage({ name, path, type, version }, pathOrFn, deps = []) { + if (!name.startsWith('@pezkuwi')) { + throw new Error(`Invalid package descriptor ${name}`); + } + const entry = getEntry(name); + entry.push({ path: getPath(path, pathOrFn), type, version }); + // if we have more than one entry at DIFFERENT version types then warn. If there is + // more than one entry at the same version and ESM/CJS dual warnings are disabled, + // then do not display warnings + const entriesSameVersion = entry.every((e) => e.version === version); + const esmCjsWarningDisabled = xglobal.process?.env?.[POLKADOTJS_DISABLE_ESM_CJS_WARNING_FLAG] === '1'; + const multipleEntries = entry.length !== 1; + const disableWarnings = esmCjsWarningDisabled && entriesSameVersion; + if (multipleEntries && !disableWarnings) { + warn(`${name} has multiple versions, ensure that there is only one installed.`, entry, formatVersion); + } + else { + const mismatches = deps.filter((d) => d && d.version !== version); + if (mismatches.length) { + warn(`${name} requires direct dependencies exactly matching version ${version}.`, mismatches, formatInfo); + } + } +} diff --git a/packages/util/extractTime.d.ts b/packages/util/extractTime.d.ts new file mode 100644 index 0000000..62fba8e --- /dev/null +++ b/packages/util/extractTime.d.ts @@ -0,0 +1,14 @@ +import type { Time } from './types.js'; +/** + * @name extractTime + * @summary Convert a quantity of seconds to Time array representing accumulated {days, minutes, hours, seconds, milliseconds} + * @example + *
+ * + * ```javascript + * import { extractTime } from '@pezkuwi/util'; + * + * const { days, minutes, hours, seconds, milliseconds } = extractTime(6000); // 0, 0, 10, 0, 0 + * ``` + */ +export declare function extractTime(milliseconds?: number): Time; diff --git a/packages/util/extractTime.js b/packages/util/extractTime.js new file mode 100644 index 0000000..f19184e --- /dev/null +++ b/packages/util/extractTime.js @@ -0,0 +1,53 @@ +const MIN_MS = 60 * 1000; +const HR_MS = MIN_MS * 60; +const DAY_MS = HR_MS * 24; +const ZERO = { days: 0, hours: 0, milliseconds: 0, minutes: 0, seconds: 0 }; +/** @internal */ +function add(a, b) { + return { + days: (a.days || 0) + b.days, + hours: (a.hours || 0) + b.hours, + milliseconds: (a.milliseconds || 0) + b.milliseconds, + minutes: (a.minutes || 0) + b.minutes, + seconds: (a.seconds || 0) + b.seconds + }; +} +/** @internal */ +function extractSecs(ms) { + const s = ms / 1000; + if (s < 60) { + const seconds = ~~s; + return add({ seconds }, extractTime(ms - (seconds * 1000))); + } + const m = s / 60; + if (m < 60) { + const minutes = ~~m; + return add({ minutes }, extractTime(ms - (minutes * MIN_MS))); + } + const h = m / 60; + if (h < 24) { + const hours = ~~h; + return add({ hours }, extractTime(ms - (hours * HR_MS))); + } + const days = ~~(h / 24); + return add({ days }, extractTime(ms - (days * DAY_MS))); +} +/** + * @name extractTime + * @summary Convert a quantity of seconds to Time array representing accumulated {days, minutes, hours, seconds, milliseconds} + * @example + *
+ * + * ```javascript + * import { extractTime } from '@pezkuwi/util'; + * + * const { days, minutes, hours, seconds, milliseconds } = extractTime(6000); // 0, 0, 10, 0, 0 + * ``` + */ +export function extractTime(milliseconds) { + return !milliseconds + ? ZERO + : milliseconds < 1000 + ? add({ milliseconds }, ZERO) + : extractSecs(milliseconds); +} diff --git a/packages/util/float/index.d.ts b/packages/util/float/index.d.ts new file mode 100644 index 0000000..0c33ced --- /dev/null +++ b/packages/util/float/index.d.ts @@ -0,0 +1 @@ +export { floatToU8a } from './toU8a.js'; diff --git a/packages/util/float/index.js b/packages/util/float/index.js new file mode 100644 index 0000000..0c33ced --- /dev/null +++ b/packages/util/float/index.js @@ -0,0 +1 @@ +export { floatToU8a } from './toU8a.js'; diff --git a/packages/util/float/toU8a.d.ts b/packages/util/float/toU8a.d.ts new file mode 100644 index 0000000..f3d9282 --- /dev/null +++ b/packages/util/float/toU8a.d.ts @@ -0,0 +1,11 @@ +interface Options { + bitLength?: 32 | 64; + isLe?: boolean; +} +/** + * @name floatToU8a + * @description Converts a float into a U8a representation (While we don't use BE in SCALE + * we still allow for either representation, although, as elsewhere, isLe is default) + */ +export declare function floatToU8a(value?: String | string | number | Number, { bitLength, isLe }?: Options): Uint8Array; +export {}; diff --git a/packages/util/float/toU8a.js b/packages/util/float/toU8a.js new file mode 100644 index 0000000..2d47488 --- /dev/null +++ b/packages/util/float/toU8a.js @@ -0,0 +1,19 @@ +/** + * @name floatToU8a + * @description Converts a float into a U8a representation (While we don't use BE in SCALE + * we still allow for either representation, although, as elsewhere, isLe is default) + */ +export function floatToU8a(value = 0.0, { bitLength = 32, isLe = true } = {}) { + if (bitLength !== 32 && bitLength !== 64) { + throw new Error('Invalid bitLength provided, expected 32 or 64'); + } + const result = new Uint8Array(bitLength / 8); + const dv = new DataView(result.buffer, result.byteOffset); + if (bitLength === 32) { + dv.setFloat32(0, Number(value), isLe); + } + else { + dv.setFloat64(0, Number(value), isLe); + } + return result; +} diff --git a/packages/util/format/formatBalance.d.ts b/packages/util/format/formatBalance.d.ts new file mode 100644 index 0000000..7eb766c --- /dev/null +++ b/packages/util/format/formatBalance.d.ts @@ -0,0 +1,54 @@ +import type { BN } from '../bn/bn.js'; +import type { SiDef, ToBn } from '../types.js'; +interface Defaults { + decimals: number; + unit: string; +} +interface SetDefaults { + decimals?: number[] | number; + unit?: string[] | string; +} +interface Options { + /** + * @description The number of decimals + */ + decimals?: number; + /** + * @description Format the number with this specific unit + */ + forceUnit?: string; + /** + * @description Returns value using all available decimals + */ + withAll?: boolean; + /** + * @description Format with SI, i.e. m/M/etc. (default = true) + */ + withSi?: boolean; + /** + * @description Format with full SI, i.e. mili/Mega/etc. + */ + withSiFull?: boolean; + /** + * @description Add the unit (useful in Balance formats) + */ + withUnit?: boolean | string; + /** + * @description Returns all trailing zeros, otherwise removes (default = true) + */ + withZero?: boolean; + /** + * @description The locale to use + */ + locale?: string; +} +interface BalanceFormatter { + (input?: number | string | BN | bigint | ExtToBn, options?: Options): string; + calcSi(text: string, decimals?: number): SiDef; + findSi(type: string): SiDef; + getDefaults(): Defaults; + getOptions(decimals?: number): SiDef[]; + setDefaults(defaults: SetDefaults): void; +} +export declare const formatBalance: BalanceFormatter; +export {}; diff --git a/packages/util/format/formatBalance.js b/packages/util/format/formatBalance.js new file mode 100644 index 0000000..14fac96 --- /dev/null +++ b/packages/util/format/formatBalance.js @@ -0,0 +1,85 @@ +import { bnToBn } from '../bn/toBn.js'; +import { isBoolean } from '../is/boolean.js'; +import { formatDecimal } from './formatDecimal.js'; +import { getSeparator } from './getSeparator.js'; +import { calcSi, findSi, SI, SI_MID } from './si.js'; +const DEFAULT_DECIMALS = 0; +const DEFAULT_UNIT = SI[SI_MID].text; +let defaultDecimals = DEFAULT_DECIMALS; +let defaultUnit = DEFAULT_UNIT; +function _formatBalance(input, { decimals = defaultDecimals, forceUnit, locale = 'en', withAll = false, withSi = true, withSiFull = false, withUnit = true, withZero = true } = {}) { + // we only work with string inputs here - convert anything + // into the string-only value + let text = bnToBn(input).toString(); + if (text.length === 0 || text === '0') { + return '0'; + } + // strip the negative sign so we can work with clean groupings, re-add this in the + // end when we return the result (from here on we work with positive numbers) + let sign = ''; + if (text[0].startsWith('-')) { + sign = '-'; + text = text.substring(1); + } + // We start at midpoint (8) minus 1 - this means that values display as + // 123.4567 instead of 0.1234 k (so we always have the most relevant). + const si = calcSi(text, decimals, forceUnit); + const mid = text.length - (decimals + si.power); + const pre = mid <= 0 ? '0' : text.substring(0, mid); + // get the post from the midpoint onward and then first add max decimals + // before trimming to the correct (calculated) amount of decimals again + let post = text + .padStart(mid < 0 ? decimals : 1, '0') + .substring(mid < 0 ? 0 : mid) + .padEnd(withAll ? Math.max(decimals, 4) : 4, '0') + .substring(0, withAll ? Math.max(4, decimals + si.power) : 4); + // remove all trailing 0's (if required via flag) + if (!withZero) { + let end = post.length - 1; + // This looks inefficient, however it is better to do the checks and + // only make one final slice than it is to do it in multiples + do { + if (post[end] === '0') { + end--; + } + } while (post[end] === '0'); + post = post.substring(0, end + 1); + } + // the display unit + const unit = isBoolean(withUnit) + ? SI[SI_MID].text + : withUnit; + // format the units for display based on the flags + const units = withSi || withSiFull + ? si.value === '-' + ? withUnit + ? ` ${unit}` + : '' + : ` ${withSiFull ? `${si.text}${withUnit ? ' ' : ''}` : si.value}${withUnit ? unit : ''}` + : ''; + const { decimal, thousand } = getSeparator(locale); + return `${sign}${formatDecimal(pre, thousand)}${post && `${decimal}${post}`}${units}`; +} +export const formatBalance = _formatBalance; +formatBalance.calcSi = (text, decimals = defaultDecimals) => calcSi(text, decimals); +formatBalance.findSi = findSi; +formatBalance.getDefaults = () => { + return { + decimals: defaultDecimals, + unit: defaultUnit + }; +}; +formatBalance.getOptions = (decimals = defaultDecimals) => { + return SI.filter(({ power }) => power < 0 + ? (decimals + power) >= 0 + : true); +}; +formatBalance.setDefaults = ({ decimals, unit }) => { + defaultDecimals = (Array.isArray(decimals) + ? decimals[0] + : decimals) ?? defaultDecimals; + defaultUnit = (Array.isArray(unit) + ? unit[0] + : unit) ?? defaultUnit; + SI[SI_MID].text = defaultUnit; +}; diff --git a/packages/util/format/formatDate.d.ts b/packages/util/format/formatDate.d.ts new file mode 100644 index 0000000..c3211a8 --- /dev/null +++ b/packages/util/format/formatDate.d.ts @@ -0,0 +1,5 @@ +/** + * @name formatDate + * @description Formats a date in CCYY-MM-DD HH:MM:SS format + */ +export declare function formatDate(date: Date): string; diff --git a/packages/util/format/formatDate.js b/packages/util/format/formatDate.js new file mode 100644 index 0000000..e979c98 --- /dev/null +++ b/packages/util/format/formatDate.js @@ -0,0 +1,17 @@ +/** @internal */ +function zeroPad(value) { + return value.toString().padStart(2, '0'); +} +/** + * @name formatDate + * @description Formats a date in CCYY-MM-DD HH:MM:SS format + */ +export function formatDate(date) { + const year = date.getFullYear().toString(); + const month = zeroPad((date.getMonth() + 1)); + const day = zeroPad(date.getDate()); + const hour = zeroPad(date.getHours()); + const minute = zeroPad(date.getMinutes()); + const second = zeroPad(date.getSeconds()); + return `${year}-${month}-${day} ${hour}:${minute}:${second}`; +} diff --git a/packages/util/format/formatDecimal.d.ts b/packages/util/format/formatDecimal.d.ts new file mode 100644 index 0000000..9f73fd1 --- /dev/null +++ b/packages/util/format/formatDecimal.d.ts @@ -0,0 +1,5 @@ +/** + * @name formatDecimal + * @description Formats a number into string format with thousand separators + */ +export declare function formatDecimal(value: string, separator?: string): string; diff --git a/packages/util/format/formatDecimal.js b/packages/util/format/formatDecimal.js new file mode 100644 index 0000000..9063d34 --- /dev/null +++ b/packages/util/format/formatDecimal.js @@ -0,0 +1,16 @@ +const NUMBER_REGEX = new RegExp('(\\d+?)(?=(\\d{3})+(?!\\d)|$)', 'g'); +/** + * @name formatDecimal + * @description Formats a number into string format with thousand separators + */ +export function formatDecimal(value, separator = ',') { + // We can do this by adjusting the regx, however for the sake of clarity + // we rather strip and re-add the negative sign in the output + const isNegative = value[0].startsWith('-'); + const matched = isNegative + ? value.substring(1).match(NUMBER_REGEX) + : value.match(NUMBER_REGEX); + return matched + ? `${isNegative ? '-' : ''}${matched.join(separator)}` + : value; +} diff --git a/packages/util/format/formatElapsed.d.ts b/packages/util/format/formatElapsed.d.ts new file mode 100644 index 0000000..8302533 --- /dev/null +++ b/packages/util/format/formatElapsed.d.ts @@ -0,0 +1,7 @@ +import type { BN } from '../bn/bn.js'; +import type { ToBn } from '../types.js'; +/** + * @name formatElapsed + * @description Formats an elapsed value into s, m, h or day segments + */ +export declare function formatElapsed(now?: Date | null, value?: bigint | BN | ExtToBn | Date | number | null): string; diff --git a/packages/util/format/formatElapsed.js b/packages/util/format/formatElapsed.js new file mode 100644 index 0000000..e049f06 --- /dev/null +++ b/packages/util/format/formatElapsed.js @@ -0,0 +1,27 @@ +import { bnToBn } from '../bn/toBn.js'; +/** @internal */ +function formatValue(elapsed) { + if (elapsed < 15) { + return `${elapsed.toFixed(1)}s`; + } + else if (elapsed < 60) { + return `${elapsed | 0}s`; + } + else if (elapsed < 3600) { + return `${elapsed / 60 | 0}m`; + } + return `${elapsed / 3600 | 0}h`; +} +/** + * @name formatElapsed + * @description Formats an elapsed value into s, m, h or day segments + */ +export function formatElapsed(now, value) { + const tsNow = now?.getTime() || 0; + const tsValue = value instanceof Date + ? value.getTime() + : bnToBn(value).toNumber(); + return (tsNow && tsValue) + ? formatValue(Math.max(Math.abs(tsNow - tsValue), 0) / 1000) + : '0.0s'; +} diff --git a/packages/util/format/formatNumber.d.ts b/packages/util/format/formatNumber.d.ts new file mode 100644 index 0000000..83f6338 --- /dev/null +++ b/packages/util/format/formatNumber.d.ts @@ -0,0 +1,14 @@ +import type { BN } from '../bn/bn.js'; +import type { ToBn } from '../types.js'; +interface Options { + /** + * @description The locale to use + */ + locale?: string; +} +/** + * @name formatNumber + * @description Formats a number into string format with thousand separators + */ +export declare function formatNumber(value?: ExtToBn | BN | bigint | number | null, { locale }?: Options): string; +export {}; diff --git a/packages/util/format/formatNumber.js b/packages/util/format/formatNumber.js new file mode 100644 index 0000000..b1d98bc --- /dev/null +++ b/packages/util/format/formatNumber.js @@ -0,0 +1,11 @@ +import { bnToBn } from '../bn/toBn.js'; +import { formatDecimal } from './formatDecimal.js'; +import { getSeparator } from './getSeparator.js'; +/** + * @name formatNumber + * @description Formats a number into string format with thousand separators + */ +export function formatNumber(value, { locale = 'en' } = {}) { + const { thousand } = getSeparator(locale); + return formatDecimal(bnToBn(value).toString(), thousand); +} diff --git a/packages/util/format/getSeparator.d.ts b/packages/util/format/getSeparator.d.ts new file mode 100644 index 0000000..6d7b097 --- /dev/null +++ b/packages/util/format/getSeparator.d.ts @@ -0,0 +1,9 @@ +/** + * Get the decimal and thousand separator of a locale + * @param locale + * @returns {decimal: string, thousand: string} + */ +export declare function getSeparator(locale?: string): { + thousand: string; + decimal: string; +}; diff --git a/packages/util/format/getSeparator.js b/packages/util/format/getSeparator.js new file mode 100644 index 0000000..fa26b31 --- /dev/null +++ b/packages/util/format/getSeparator.js @@ -0,0 +1,11 @@ +/** + * Get the decimal and thousand separator of a locale + * @param locale + * @returns {decimal: string, thousand: string} + */ +export function getSeparator(locale) { + return { + decimal: (0.1).toLocaleString(locale, { useGrouping: false }).charAt(1), + thousand: (1000).toLocaleString(locale, { useGrouping: true }).replace(/\d/g, '').charAt(0) + }; +} diff --git a/packages/util/format/index.d.ts b/packages/util/format/index.d.ts new file mode 100644 index 0000000..6114673 --- /dev/null +++ b/packages/util/format/index.d.ts @@ -0,0 +1,6 @@ +export { formatBalance } from './formatBalance.js'; +export { formatDate } from './formatDate.js'; +export { formatDecimal } from './formatDecimal.js'; +export { formatElapsed } from './formatElapsed.js'; +export { formatNumber } from './formatNumber.js'; +export { calcSi, findSi } from './si.js'; diff --git a/packages/util/format/index.js b/packages/util/format/index.js new file mode 100644 index 0000000..6114673 --- /dev/null +++ b/packages/util/format/index.js @@ -0,0 +1,6 @@ +export { formatBalance } from './formatBalance.js'; +export { formatDate } from './formatDate.js'; +export { formatDecimal } from './formatDecimal.js'; +export { formatElapsed } from './formatElapsed.js'; +export { formatNumber } from './formatNumber.js'; +export { calcSi, findSi } from './si.js'; diff --git a/packages/util/format/si.d.ts b/packages/util/format/si.d.ts new file mode 100644 index 0000000..cc4a1cc --- /dev/null +++ b/packages/util/format/si.d.ts @@ -0,0 +1,9 @@ +import type { SiDef } from '../types.js'; +/** @internal */ +export declare const SI_MID = 8; +/** @internal */ +export declare const SI: SiDef[]; +/** @internal */ +export declare function findSi(type: string): SiDef; +/** @internal */ +export declare function calcSi(text: string, decimals: number, forceUnit?: string): SiDef; diff --git a/packages/util/format/si.js b/packages/util/format/si.js new file mode 100644 index 0000000..ed843f3 --- /dev/null +++ b/packages/util/format/si.js @@ -0,0 +1,40 @@ +/** @internal */ +export const SI_MID = 8; +/** @internal */ +export const SI = [ + { power: -24, text: 'yocto', value: 'y' }, + { power: -21, text: 'zepto', value: 'z' }, + { power: -18, text: 'atto', value: 'a' }, + { power: -15, text: 'femto', value: 'f' }, + { power: -12, text: 'pico', value: 'p' }, + { power: -9, text: 'nano', value: 'n' }, + { power: -6, text: 'micro', value: 'µ' }, + { power: -3, text: 'milli', value: 'm' }, + { power: 0, text: 'Unit', value: '-' }, // position 8 + { power: 3, text: 'Kilo', value: 'k' }, + { power: 6, text: 'Mill', value: 'M' }, // Mega, M + { power: 9, text: 'Bill', value: 'B' }, // Giga, G + { power: 12, text: 'Tril', value: 'T' }, // Tera, T + { power: 15, text: 'Peta', value: 'P' }, + { power: 18, text: 'Exa', value: 'E' }, + { power: 21, text: 'Zeta', value: 'Z' }, + { power: 24, text: 'Yotta', value: 'Y' } +]; +/** @internal */ +export function findSi(type) { + // use a loop here, better RN support (which doesn't have [].find) + for (let i = 0, count = SI.length; i < count; i++) { + if (SI[i].value === type) { + return SI[i]; + } + } + return SI[SI_MID]; +} +/** @internal */ +export function calcSi(text, decimals, forceUnit) { + if (forceUnit) { + return findSi(forceUnit); + } + const siDefIndex = (SI_MID - 1) + Math.ceil((text.length - decimals) / 3); + return SI[siDefIndex] || SI[siDefIndex < 0 ? 0 : SI.length - 1]; +} diff --git a/packages/util/has.d.ts b/packages/util/has.d.ts new file mode 100644 index 0000000..42fac7f --- /dev/null +++ b/packages/util/has.d.ts @@ -0,0 +1,14 @@ +/** true if the environment has proper BigInt support */ +export declare const hasBigInt: boolean; +/** true if the environment is CJS */ +export declare const hasCjs: boolean; +/** true if the environment has __dirname available */ +export declare const hasDirname: boolean; +/** true if the environment is ESM */ +export declare const hasEsm: boolean; +/** true if the environment has WebAssembly available */ +export declare const hasWasm: boolean; +/** true if the environment has support for Buffer (typically Node.js) */ +export declare const hasBuffer: boolean; +/** true if the environment has process available (typically Node.js) */ +export declare const hasProcess: boolean; diff --git a/packages/util/has.js b/packages/util/has.js new file mode 100644 index 0000000..8fe907a --- /dev/null +++ b/packages/util/has.js @@ -0,0 +1,16 @@ +import { BigInt } from '@pezkuwi/x-bigint'; +import { xglobal } from '@pezkuwi/x-global'; +/** true if the environment has proper BigInt support */ +export const hasBigInt = typeof BigInt === 'function' && typeof BigInt.asIntN === 'function'; +/** true if the environment is CJS */ +export const hasCjs = typeof require === 'function' && typeof module !== 'undefined'; +/** true if the environment has __dirname available */ +export const hasDirname = typeof __dirname !== 'undefined'; +/** true if the environment is ESM */ +export const hasEsm = !hasCjs; +/** true if the environment has WebAssembly available */ +export const hasWasm = typeof WebAssembly !== 'undefined'; +/** true if the environment has support for Buffer (typically Node.js) */ +export const hasBuffer = typeof xglobal.Buffer === 'function' && typeof xglobal.Buffer.isBuffer === 'function'; +/** true if the environment has process available (typically Node.js) */ +export const hasProcess = typeof xglobal.process === 'object'; diff --git a/packages/util/hex/addPrefix.d.ts b/packages/util/hex/addPrefix.d.ts new file mode 100644 index 0000000..5701368 --- /dev/null +++ b/packages/util/hex/addPrefix.d.ts @@ -0,0 +1,16 @@ +import type { HexString } from '../types.js'; +/** + * @name hexAddPrefix + * @summary Adds the `0x` prefix to string values. + * @description + * Returns a `0x` prefixed string from the input value. If the input is already prefixed, it is returned unchanged. + * @example + *
+ * + * ```javascript + * import { hexAddPrefix } from '@pezkuwi/util'; + * + * console.log('With prefix', hexAddPrefix('0a0b12')); // => 0x0a0b12 + * ``` + */ +export declare function hexAddPrefix(value?: string | null): HexString; diff --git a/packages/util/hex/addPrefix.js b/packages/util/hex/addPrefix.js new file mode 100644 index 0000000..2e5bf82 --- /dev/null +++ b/packages/util/hex/addPrefix.js @@ -0,0 +1,20 @@ +import { hexHasPrefix } from './hasPrefix.js'; +/** + * @name hexAddPrefix + * @summary Adds the `0x` prefix to string values. + * @description + * Returns a `0x` prefixed string from the input value. If the input is already prefixed, it is returned unchanged. + * @example + *
+ * + * ```javascript + * import { hexAddPrefix } from '@pezkuwi/util'; + * + * console.log('With prefix', hexAddPrefix('0a0b12')); // => 0x0a0b12 + * ``` + */ +export function hexAddPrefix(value) { + return value && hexHasPrefix(value) + ? value + : `0x${value && value.length % 2 === 1 ? '0' : ''}${value || ''}`; +} diff --git a/packages/util/hex/fixLength.d.ts b/packages/util/hex/fixLength.d.ts new file mode 100644 index 0000000..f7480a6 --- /dev/null +++ b/packages/util/hex/fixLength.d.ts @@ -0,0 +1,18 @@ +import type { HexString } from '../types.js'; +/** + * @name hexFixLength + * @summary Shifts a hex string to a specific bitLength + * @description + * Returns a `0x` prefixed string with the specified number of bits contained in the return value. (If bitLength is -1, length checking is not done). Values with more bits are trimmed to the specified length. Input values with less bits are returned as-is by default. When `withPadding` is set, shorter values are padded with `0`. + * @example + *
+ * + * ```javascript + * import { hexFixLength } from '@pezkuwi/util'; + * + * console.log('fixed', hexFixLength('0x12', 16)); // => 0x12 + * console.log('fixed', hexFixLength('0x12', 16, true)); // => 0x0012 + * console.log('fixed', hexFixLength('0x0012', 8)); // => 0x12 + * ``` + */ +export declare function hexFixLength(value: string, bitLength?: number, withPadding?: boolean): HexString; diff --git a/packages/util/hex/fixLength.js b/packages/util/hex/fixLength.js new file mode 100644 index 0000000..7b9e415 --- /dev/null +++ b/packages/util/hex/fixLength.js @@ -0,0 +1,27 @@ +import { hexAddPrefix } from './addPrefix.js'; +import { hexStripPrefix } from './stripPrefix.js'; +/** + * @name hexFixLength + * @summary Shifts a hex string to a specific bitLength + * @description + * Returns a `0x` prefixed string with the specified number of bits contained in the return value. (If bitLength is -1, length checking is not done). Values with more bits are trimmed to the specified length. Input values with less bits are returned as-is by default. When `withPadding` is set, shorter values are padded with `0`. + * @example + *
+ * + * ```javascript + * import { hexFixLength } from '@pezkuwi/util'; + * + * console.log('fixed', hexFixLength('0x12', 16)); // => 0x12 + * console.log('fixed', hexFixLength('0x12', 16, true)); // => 0x0012 + * console.log('fixed', hexFixLength('0x0012', 8)); // => 0x12 + * ``` + */ +export function hexFixLength(value, bitLength = -1, withPadding = false) { + const strLength = Math.ceil(bitLength / 4); + const hexLength = strLength + 2; + return hexAddPrefix((bitLength === -1 || value.length === hexLength || (!withPadding && value.length < hexLength)) + ? hexStripPrefix(value) + : (value.length > hexLength) + ? hexStripPrefix(value).slice(-1 * strLength) + : `${'0'.repeat(strLength)}${hexStripPrefix(value)}`.slice(-1 * strLength)); +} diff --git a/packages/util/hex/hasPrefix.d.ts b/packages/util/hex/hasPrefix.d.ts new file mode 100644 index 0000000..45d0832 --- /dev/null +++ b/packages/util/hex/hasPrefix.d.ts @@ -0,0 +1,16 @@ +import type { HexString } from '../types.js'; +/** + * @name hexHasPrefix + * @summary Tests for the existence of a `0x` prefix. + * @description + * Checks for a valid hex input value and if the start matched `0x` + * @example + *
+ * + * ```javascript + * import { hexHasPrefix } from '@pezkuwi/util'; + * + * console.log('has prefix', hexHasPrefix('0x1234')); // => true + * ``` + */ +export declare function hexHasPrefix(value?: string | null): value is HexString; diff --git a/packages/util/hex/hasPrefix.js b/packages/util/hex/hasPrefix.js new file mode 100644 index 0000000..c88951c --- /dev/null +++ b/packages/util/hex/hasPrefix.js @@ -0,0 +1,18 @@ +import { isHex } from '../is/hex.js'; +/** + * @name hexHasPrefix + * @summary Tests for the existence of a `0x` prefix. + * @description + * Checks for a valid hex input value and if the start matched `0x` + * @example + *
+ * + * ```javascript + * import { hexHasPrefix } from '@pezkuwi/util'; + * + * console.log('has prefix', hexHasPrefix('0x1234')); // => true + * ``` + */ +export function hexHasPrefix(value) { + return !!value && isHex(value, -1); +} diff --git a/packages/util/hex/index.d.ts b/packages/util/hex/index.d.ts new file mode 100644 index 0000000..85d3e8f --- /dev/null +++ b/packages/util/hex/index.d.ts @@ -0,0 +1,12 @@ +/** + * @summary Internal utilities to create and test for hex values + */ +export { hexAddPrefix } from './addPrefix.js'; +export { hexFixLength } from './fixLength.js'; +export { hexHasPrefix } from './hasPrefix.js'; +export { hexStripPrefix } from './stripPrefix.js'; +export { hexToBigInt } from './toBigInt.js'; +export { hexToBn } from './toBn.js'; +export { hexToNumber } from './toNumber.js'; +export { hexToString } from './toString.js'; +export { hexToU8a } from './toU8a.js'; diff --git a/packages/util/hex/index.js b/packages/util/hex/index.js new file mode 100644 index 0000000..85d3e8f --- /dev/null +++ b/packages/util/hex/index.js @@ -0,0 +1,12 @@ +/** + * @summary Internal utilities to create and test for hex values + */ +export { hexAddPrefix } from './addPrefix.js'; +export { hexFixLength } from './fixLength.js'; +export { hexHasPrefix } from './hasPrefix.js'; +export { hexStripPrefix } from './stripPrefix.js'; +export { hexToBigInt } from './toBigInt.js'; +export { hexToBn } from './toBn.js'; +export { hexToNumber } from './toNumber.js'; +export { hexToString } from './toString.js'; +export { hexToU8a } from './toU8a.js'; diff --git a/packages/util/hex/stripPrefix.d.ts b/packages/util/hex/stripPrefix.d.ts new file mode 100644 index 0000000..67d3589 --- /dev/null +++ b/packages/util/hex/stripPrefix.d.ts @@ -0,0 +1,15 @@ +/** + * @name hexStripPrefix + * @summary Strips any leading `0x` prefix. + * @description + * Tests for the existence of a `0x` prefix, and returns the value without the prefix. Un-prefixed values are returned as-is. + * @example + *
+ * + * ```javascript + * import { hexStripPrefix } from '@pezkuwi/util'; + * + * console.log('stripped', hexStripPrefix('0x1234')); // => 1234 + * ``` + */ +export declare function hexStripPrefix(value?: string | null): string; diff --git a/packages/util/hex/stripPrefix.js b/packages/util/hex/stripPrefix.js new file mode 100644 index 0000000..e38d17c --- /dev/null +++ b/packages/util/hex/stripPrefix.js @@ -0,0 +1,27 @@ +import { REGEX_HEX_NOPREFIX, REGEX_HEX_PREFIXED } from '../is/hex.js'; +/** + * @name hexStripPrefix + * @summary Strips any leading `0x` prefix. + * @description + * Tests for the existence of a `0x` prefix, and returns the value without the prefix. Un-prefixed values are returned as-is. + * @example + *
+ * + * ```javascript + * import { hexStripPrefix } from '@pezkuwi/util'; + * + * console.log('stripped', hexStripPrefix('0x1234')); // => 1234 + * ``` + */ +export function hexStripPrefix(value) { + if (!value || value === '0x') { + return ''; + } + else if (REGEX_HEX_PREFIXED.test(value)) { + return value.substring(2); + } + else if (REGEX_HEX_NOPREFIX.test(value)) { + return value; + } + throw new Error(`Expected hex value to convert, found '${value}'`); +} diff --git a/packages/util/hex/toBigInt.d.ts b/packages/util/hex/toBigInt.d.ts new file mode 100644 index 0000000..ecf1f7d --- /dev/null +++ b/packages/util/hex/toBigInt.d.ts @@ -0,0 +1,6 @@ +import type { ToBnOptions } from '../types.js'; +/** + * @name hexToBigInt + * @summary Creates a BigInt instance object from a hex string. + */ +export declare function hexToBigInt(value?: string | null, { isLe, isNegative }?: ToBnOptions): bigint; diff --git a/packages/util/hex/toBigInt.js b/packages/util/hex/toBigInt.js new file mode 100644 index 0000000..7bffbc6 --- /dev/null +++ b/packages/util/hex/toBigInt.js @@ -0,0 +1,12 @@ +import { BigInt } from '@pezkuwi/x-bigint'; +import { u8aToBigInt } from '../u8a/toBigInt.js'; +import { hexToU8a } from './toU8a.js'; +/** + * @name hexToBigInt + * @summary Creates a BigInt instance object from a hex string. + */ +export function hexToBigInt(value, { isLe = false, isNegative = false } = {}) { + return !value || value === '0x' + ? BigInt(0) + : u8aToBigInt(hexToU8a(value), { isLe, isNegative }); +} diff --git a/packages/util/hex/toBn.d.ts b/packages/util/hex/toBn.d.ts new file mode 100644 index 0000000..6bc61b9 --- /dev/null +++ b/packages/util/hex/toBn.d.ts @@ -0,0 +1,21 @@ +import type { ToBnOptions } from '../types.js'; +import { BN } from '../bn/bn.js'; +/** + * @name hexToBn + * @summary Creates a BN.js object from a hex string. + * @description + * `null` inputs returns a `BN(0)` result. Hex input values return the actual value converted to a BN. Anything that is not a hex string (including the `0x` prefix) throws an error. + * @param _value The value to convert + * @param _options Options to pass while converting + * @param _options.isLe Convert using Little Endian + * @param _options.isNegative Convert using two's complement + * @example + *
+ * + * ```javascript + * import { hexToBn } from '@pezkuwi/util'; + * + * hexToBn('0x123480001f'); // => BN(0x123480001f) + * ``` + */ +export declare function hexToBn(value?: string | null, { isLe, isNegative }?: ToBnOptions): BN; diff --git a/packages/util/hex/toBn.js b/packages/util/hex/toBn.js new file mode 100644 index 0000000..887bf31 --- /dev/null +++ b/packages/util/hex/toBn.js @@ -0,0 +1,32 @@ +import { BN } from '../bn/bn.js'; +import { hexStripPrefix } from './stripPrefix.js'; +/** + * @name hexToBn + * @summary Creates a BN.js object from a hex string. + * @description + * `null` inputs returns a `BN(0)` result. Hex input values return the actual value converted to a BN. Anything that is not a hex string (including the `0x` prefix) throws an error. + * @param _value The value to convert + * @param _options Options to pass while converting + * @param _options.isLe Convert using Little Endian + * @param _options.isNegative Convert using two's complement + * @example + *
+ * + * ```javascript + * import { hexToBn } from '@pezkuwi/util'; + * + * hexToBn('0x123480001f'); // => BN(0x123480001f) + * ``` + */ +export function hexToBn(value, { isLe = false, isNegative = false } = {}) { + if (!value || value === '0x') { + return new BN(0); + } + const stripped = hexStripPrefix(value); + const bn = new BN(stripped, 16, isLe ? 'le' : 'be'); + // fromTwos takes as parameter the number of bits, which is the hex length + // multiplied by 4 (2 bytes being 8 bits) + return isNegative + ? bn.fromTwos(stripped.length * 4) + : bn; +} diff --git a/packages/util/hex/toNumber.d.ts b/packages/util/hex/toNumber.d.ts new file mode 100644 index 0000000..ca9beb2 --- /dev/null +++ b/packages/util/hex/toNumber.d.ts @@ -0,0 +1,15 @@ +/** + * @name hexToNumber + * @summary Creates a Number value from a Buffer object. + * @description + * `null` inputs returns an NaN result, `hex` values return the actual value as a `Number`. + * @example + *
+ * + * ```javascript + * import { hexToNumber } from '@pezkuwi/util'; + * + * hexToNumber('0x1234'); // => 0x1234 + * ``` + */ +export declare function hexToNumber(value?: string | null): number; diff --git a/packages/util/hex/toNumber.js b/packages/util/hex/toNumber.js new file mode 100644 index 0000000..e999de3 --- /dev/null +++ b/packages/util/hex/toNumber.js @@ -0,0 +1,20 @@ +import { hexToBn } from './toBn.js'; +/** + * @name hexToNumber + * @summary Creates a Number value from a Buffer object. + * @description + * `null` inputs returns an NaN result, `hex` values return the actual value as a `Number`. + * @example + *
+ * + * ```javascript + * import { hexToNumber } from '@pezkuwi/util'; + * + * hexToNumber('0x1234'); // => 0x1234 + * ``` + */ +export function hexToNumber(value) { + return value + ? hexToBn(value).toNumber() + : NaN; +} diff --git a/packages/util/hex/toString.d.ts b/packages/util/hex/toString.d.ts new file mode 100644 index 0000000..db6e26f --- /dev/null +++ b/packages/util/hex/toString.d.ts @@ -0,0 +1,15 @@ +/** + * @name hexToU8a + * @summary Creates a Uint8Array object from a hex string. + * @description + * Hex input values return the actual bytes value converted to a string. Anything that is not a hex string (including the `0x` prefix) throws an error. + * @example + *
+ * + * ```javascript + * import { hexToString } from '@pezkuwi/util'; + * + * hexToU8a('0x68656c6c6f'); // hello + * ``` + */ +export declare function hexToString(_value?: string | null): string; diff --git a/packages/util/hex/toString.js b/packages/util/hex/toString.js new file mode 100644 index 0000000..96c3809 --- /dev/null +++ b/packages/util/hex/toString.js @@ -0,0 +1,19 @@ +import { u8aToString } from '../u8a/toString.js'; +import { hexToU8a } from './toU8a.js'; +/** + * @name hexToU8a + * @summary Creates a Uint8Array object from a hex string. + * @description + * Hex input values return the actual bytes value converted to a string. Anything that is not a hex string (including the `0x` prefix) throws an error. + * @example + *
+ * + * ```javascript + * import { hexToString } from '@pezkuwi/util'; + * + * hexToU8a('0x68656c6c6f'); // hello + * ``` + */ +export function hexToString(_value) { + return u8aToString(hexToU8a(_value)); +} diff --git a/packages/util/hex/toU8a.d.ts b/packages/util/hex/toU8a.d.ts new file mode 100644 index 0000000..5a80f41 --- /dev/null +++ b/packages/util/hex/toU8a.d.ts @@ -0,0 +1,16 @@ +/** + * @name hexToU8a + * @summary Creates a Uint8Array object from a hex string. + * @description + * `null` inputs returns an empty `Uint8Array` result. Hex input values return the actual bytes value converted to a Uint8Array. Anything that is not a hex string (including the `0x` prefix) throws an error. + * @example + *
+ * + * ```javascript + * import { hexToU8a } from '@pezkuwi/util'; + * + * hexToU8a('0x80001f'); // Uint8Array([0x80, 0x00, 0x1f]) + * hexToU8a('0x80001f', 32); // Uint8Array([0x00, 0x80, 0x00, 0x1f]) + * ``` + */ +export declare function hexToU8a(value?: string | null, bitLength?: number): Uint8Array; diff --git a/packages/util/hex/toU8a.js b/packages/util/hex/toU8a.js new file mode 100644 index 0000000..9d9fe9b --- /dev/null +++ b/packages/util/hex/toU8a.js @@ -0,0 +1,54 @@ +const CHR = '0123456789abcdef'; +const U8 = new Uint8Array(256); +const U16 = new Uint8Array(256 * 256); +for (let i = 0, count = CHR.length; i < count; i++) { + U8[CHR[i].charCodeAt(0) | 0] = i | 0; + if (i > 9) { + U8[CHR[i].toUpperCase().charCodeAt(0) | 0] = i | 0; + } +} +for (let i = 0; i < 256; i++) { + const s = i << 8; + for (let j = 0; j < 256; j++) { + U16[s | j] = (U8[i] << 4) | U8[j]; + } +} +/** + * @name hexToU8a + * @summary Creates a Uint8Array object from a hex string. + * @description + * `null` inputs returns an empty `Uint8Array` result. Hex input values return the actual bytes value converted to a Uint8Array. Anything that is not a hex string (including the `0x` prefix) throws an error. + * @example + *
+ * + * ```javascript + * import { hexToU8a } from '@pezkuwi/util'; + * + * hexToU8a('0x80001f'); // Uint8Array([0x80, 0x00, 0x1f]) + * hexToU8a('0x80001f', 32); // Uint8Array([0x00, 0x80, 0x00, 0x1f]) + * ``` + */ +export function hexToU8a(value, bitLength = -1) { + if (!value) { + return new Uint8Array(); + } + let s = value.startsWith('0x') + ? 2 + : 0; + const decLength = Math.ceil((value.length - s) / 2); + const endLength = Math.ceil(bitLength === -1 + ? decLength + : bitLength / 8); + const result = new Uint8Array(endLength); + const offset = endLength > decLength + ? endLength - decLength + : 0; + for (let i = offset; i < endLength; i++, s += 2) { + // The big factor here is actually the string lookups. If we do + // HEX_TO_U16[value.substring()] we get an 10x slowdown. In the + // same vein using charCodeAt (as opposed to value[s] or value.charAt(s)) is + // also the faster operation by at least 2x with the character map above + result[i] = U16[(value.charCodeAt(s) << 8) | value.charCodeAt(s + 1)]; + } + return result; +} diff --git a/packages/util/hex/toU8aBuffer.d.ts b/packages/util/hex/toU8aBuffer.d.ts new file mode 100644 index 0000000..c4288cb --- /dev/null +++ b/packages/util/hex/toU8aBuffer.d.ts @@ -0,0 +1,16 @@ +/** + * @name hexToU8a + * @summary Creates a Uint8Array object from a hex string. + * @description + * `null` inputs returns an empty `Uint8Array` result. Hex input values return the actual bytes value converted to a Uint8Array. Anything that is not a hex string (including the `0x` prefix) throws an error. + * @example + *
+ * + * ```javascript + * import { hexToU8a } from '@pezkuwi/util'; + * + * hexToU8a('0x80001f'); // Uint8Array([0x80, 0x00, 0x1f]) + * hexToU8a('0x80001f', 32); // Uint8Array([0x00, 0x80, 0x00, 0x1f]) + * ``` + */ +export declare function hexToU8a(_value?: string | null, bitLength?: number): Uint8Array; diff --git a/packages/util/hex/toU8aBuffer.js b/packages/util/hex/toU8aBuffer.js new file mode 100644 index 0000000..cdb52fc --- /dev/null +++ b/packages/util/hex/toU8aBuffer.js @@ -0,0 +1,40 @@ +/** + * @name hexToU8a + * @summary Creates a Uint8Array object from a hex string. + * @description + * `null` inputs returns an empty `Uint8Array` result. Hex input values return the actual bytes value converted to a Uint8Array. Anything that is not a hex string (including the `0x` prefix) throws an error. + * @example + *
+ * + * ```javascript + * import { hexToU8a } from '@pezkuwi/util'; + * + * hexToU8a('0x80001f'); // Uint8Array([0x80, 0x00, 0x1f]) + * hexToU8a('0x80001f', 32); // Uint8Array([0x00, 0x80, 0x00, 0x1f]) + * ``` + */ +export function hexToU8a(_value, bitLength = -1) { + if (!_value) { + return new Uint8Array(); + } + const value = _value.startsWith('0x') + ? _value.substring(2) + : _value; + const buf = Buffer.from(value, 'hex'); + const valLength = value.length / 2; + const resultLength = Math.ceil(bitLength === -1 + ? valLength + : bitLength / 8); + if (resultLength === valLength) { + return Uint8Array.from(buf); + } + const offset = resultLength > valLength + ? resultLength - valLength + : 0; + if (offset) { + const u8a = new Uint8Array(resultLength); + u8a.set(buf, offset); + return u8a; + } + return Uint8Array.from(buf.subarray(0, resultLength)); +} diff --git a/packages/util/index.d.ts b/packages/util/index.d.ts new file mode 100644 index 0000000..ca3f403 --- /dev/null +++ b/packages/util/index.d.ts @@ -0,0 +1,2 @@ +import './packageDetect.js'; +export * from './bundle.js'; diff --git a/packages/util/index.js b/packages/util/index.js new file mode 100644 index 0000000..ca3f403 --- /dev/null +++ b/packages/util/index.js @@ -0,0 +1,2 @@ +import './packageDetect.js'; +export * from './bundle.js'; diff --git a/packages/util/is/array.d.ts b/packages/util/is/array.d.ts new file mode 100644 index 0000000..01b861f --- /dev/null +++ b/packages/util/is/array.d.ts @@ -0,0 +1,5 @@ +/** + * @name isArray + * @summary Tests for a Array instance. + */ +export declare function isArray(value?: unknown): value is T[]; diff --git a/packages/util/is/array.js b/packages/util/is/array.js new file mode 100644 index 0000000..cbe5f45 --- /dev/null +++ b/packages/util/is/array.js @@ -0,0 +1,7 @@ +/** + * @name isArray + * @summary Tests for a Array instance. + */ +export function isArray(value) { + return Array.isArray(value); +} diff --git a/packages/util/is/ascii.d.ts b/packages/util/is/ascii.d.ts new file mode 100644 index 0000000..c5c836c --- /dev/null +++ b/packages/util/is/ascii.d.ts @@ -0,0 +1,8 @@ +import type { U8aLike } from '../types.js'; +/** + * @name isAscii + * @summary Tests if the input is printable ASCII + * @description + * Checks to see if the input string or Uint8Array is printable ASCII, 32-127 + formatters + */ +export declare function isAscii(value?: U8aLike | null): boolean; diff --git a/packages/util/is/ascii.js b/packages/util/is/ascii.js new file mode 100644 index 0000000..7e85f4e --- /dev/null +++ b/packages/util/is/ascii.js @@ -0,0 +1,40 @@ +import { u8aToU8a } from '../u8a/toU8a.js'; +import { isHex } from './hex.js'; +import { isString } from './string.js'; +/** @internal */ +function isAsciiStr(str) { + for (let i = 0, count = str.length; i < count; i++) { + const b = str.charCodeAt(i); + // check is inlined here, it is faster than making a call + if (b < 32 || b > 126) { + return false; + } + } + return true; +} +/** @internal */ +function isAsciiBytes(u8a) { + for (let i = 0, count = u8a.length; i < count; i++) { + const b = u8a[i] | 0; + // check is inlined here, it is faster than making a call + if (b < 32 || b > 126) { + return false; + } + } + return true; +} +/** + * @name isAscii + * @summary Tests if the input is printable ASCII + * @description + * Checks to see if the input string or Uint8Array is printable ASCII, 32-127 + formatters + */ +export function isAscii(value) { + return isString(value) + ? isHex(value) + ? isAsciiBytes(u8aToU8a(value)) + : isAsciiStr(value) + : value + ? isAsciiBytes(value) + : false; +} diff --git a/packages/util/is/bigInt.d.ts b/packages/util/is/bigInt.d.ts new file mode 100644 index 0000000..d5c3a7d --- /dev/null +++ b/packages/util/is/bigInt.d.ts @@ -0,0 +1,15 @@ +/** + * @name isBigInt + * @summary Tests for a `BigInt` object instance. + * @description + * Checks to see if the input object is an instance of `BigInt` + * @example + *
+ * + * ```javascript + * import { isBigInt } from '@pezkuwi/util'; + * + * console.log('isBigInt', isBigInt(123_456n)); // => true + * ``` + */ +export declare function isBigInt(value: unknown): value is bigint; diff --git a/packages/util/is/bigInt.js b/packages/util/is/bigInt.js new file mode 100644 index 0000000..c2cb54c --- /dev/null +++ b/packages/util/is/bigInt.js @@ -0,0 +1,17 @@ +/** + * @name isBigInt + * @summary Tests for a `BigInt` object instance. + * @description + * Checks to see if the input object is an instance of `BigInt` + * @example + *
+ * + * ```javascript + * import { isBigInt } from '@pezkuwi/util'; + * + * console.log('isBigInt', isBigInt(123_456n)); // => true + * ``` + */ +export function isBigInt(value) { + return typeof value === 'bigint'; +} diff --git a/packages/util/is/bn.d.ts b/packages/util/is/bn.d.ts new file mode 100644 index 0000000..e036b0b --- /dev/null +++ b/packages/util/is/bn.d.ts @@ -0,0 +1,17 @@ +import { BN } from '../bn/bn.js'; +/** + * @name isBn + * @summary Tests for a `BN` object instance. + * @description + * Checks to see if the input object is an instance of `BN` (bn.js). + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { isBn } from '@pezkuwi/util'; + * + * console.log('isBn', isBn(new BN(1))); // => true + * ``` + */ +export declare function isBn(value: unknown): value is BN; diff --git a/packages/util/is/bn.js b/packages/util/is/bn.js new file mode 100644 index 0000000..b9e38b5 --- /dev/null +++ b/packages/util/is/bn.js @@ -0,0 +1,19 @@ +import { BN } from '../bn/bn.js'; +/** + * @name isBn + * @summary Tests for a `BN` object instance. + * @description + * Checks to see if the input object is an instance of `BN` (bn.js). + * @example + *
+ * + * ```javascript + * import BN from 'bn.js'; + * import { isBn } from '@pezkuwi/util'; + * + * console.log('isBn', isBn(new BN(1))); // => true + * ``` + */ +export function isBn(value) { + return BN.isBN(value); +} diff --git a/packages/util/is/boolean.d.ts b/packages/util/is/boolean.d.ts new file mode 100644 index 0000000..a19316a --- /dev/null +++ b/packages/util/is/boolean.d.ts @@ -0,0 +1,15 @@ +/** + * @name isBoolean + * @summary Tests for a boolean value. + * @description + * Checks to see if the input value is a JavaScript boolean. + * @example + *
+ * + * ```javascript + * import { isBoolean } from '@pezkuwi/util'; + * + * isBoolean(false); // => true + * ``` + */ +export declare function isBoolean(value: unknown): value is boolean; diff --git a/packages/util/is/boolean.js b/packages/util/is/boolean.js new file mode 100644 index 0000000..f91e8fd --- /dev/null +++ b/packages/util/is/boolean.js @@ -0,0 +1,17 @@ +/** + * @name isBoolean + * @summary Tests for a boolean value. + * @description + * Checks to see if the input value is a JavaScript boolean. + * @example + *
+ * + * ```javascript + * import { isBoolean } from '@pezkuwi/util'; + * + * isBoolean(false); // => true + * ``` + */ +export function isBoolean(value) { + return typeof value === 'boolean'; +} diff --git a/packages/util/is/buffer.d.ts b/packages/util/is/buffer.d.ts new file mode 100644 index 0000000..da85d08 --- /dev/null +++ b/packages/util/is/buffer.d.ts @@ -0,0 +1,16 @@ +import type { BufferObject } from '../types.js'; +/** + * @name isBuffer + * @summary Tests for a `Buffer` object instance. + * @description + * Checks to see if the input object is an instance of `Buffer`. + * @example + *
+ * + * ```javascript + * import { isBuffer } from '@pezkuwi/util'; + * + * console.log('isBuffer', isBuffer(Buffer.from([]))); // => true + * ``` + */ +export declare function isBuffer(value: unknown): value is T; diff --git a/packages/util/is/buffer.js b/packages/util/is/buffer.js new file mode 100644 index 0000000..47e7dca --- /dev/null +++ b/packages/util/is/buffer.js @@ -0,0 +1,21 @@ +import { xglobal } from '@pezkuwi/x-global'; +import { hasBuffer } from '../has.js'; +import { isFunction } from './function.js'; +/** + * @name isBuffer + * @summary Tests for a `Buffer` object instance. + * @description + * Checks to see if the input object is an instance of `Buffer`. + * @example + *
+ * + * ```javascript + * import { isBuffer } from '@pezkuwi/util'; + * + * console.log('isBuffer', isBuffer(Buffer.from([]))); // => true + * ``` + */ +export function isBuffer(value) { + // we do check a function first, since it is slightly faster than isBuffer itself + return hasBuffer && !!value && isFunction(value.readDoubleLE) && xglobal.Buffer.isBuffer(value); +} diff --git a/packages/util/is/childClass.d.ts b/packages/util/is/childClass.d.ts new file mode 100644 index 0000000..c7ab4fc --- /dev/null +++ b/packages/util/is/childClass.d.ts @@ -0,0 +1,17 @@ +import type { Class } from '../types.js'; +/** + * @name isChildClass + * @summary Tests if the child extends the parent Class + * @description + * Checks to see if the child Class extends the parent Class + * @example + *
+ * + * ```javascript + * import { isChildClass } from '@pezkuwi/util'; + * + * console.log('isChildClass', isChildClass(BN, BN); // => true + * console.log('isChildClass', isChildClass(BN, Uint8Array); // => false + * ``` + */ +export declare function isChildClass

(Parent: P, Child?: unknown): Child is P; diff --git a/packages/util/is/childClass.js b/packages/util/is/childClass.js new file mode 100644 index 0000000..47dae6b --- /dev/null +++ b/packages/util/is/childClass.js @@ -0,0 +1,23 @@ +import { isClass } from './class.js'; +/** + * @name isChildClass + * @summary Tests if the child extends the parent Class + * @description + * Checks to see if the child Class extends the parent Class + * @example + *
+ * + * ```javascript + * import { isChildClass } from '@pezkuwi/util'; + * + * console.log('isChildClass', isChildClass(BN, BN); // => true + * console.log('isChildClass', isChildClass(BN, Uint8Array); // => false + * ``` + */ +export function isChildClass(Parent, Child) { + // https://stackoverflow.com/questions/30993434/check-if-a-constructor-inherits-another-in-es6/30993664 + return isClass(Child) && isClass(Parent) + // eslint-disable-next-line no-prototype-builtins + ? Parent === Child || Parent.isPrototypeOf(Child) + : false; +} diff --git a/packages/util/is/class.d.ts b/packages/util/is/class.d.ts new file mode 100644 index 0000000..d319ab8 --- /dev/null +++ b/packages/util/is/class.d.ts @@ -0,0 +1,6 @@ +import type { Class } from '../types.js'; +/** + * @name isClass + * Tests if the supplied argument is a Class + */ +export declare const isClass: (value?: unknown) => value is T; diff --git a/packages/util/is/class.js b/packages/util/is/class.js new file mode 100644 index 0000000..68b11da --- /dev/null +++ b/packages/util/is/class.js @@ -0,0 +1,6 @@ +import { isOnFunction } from './helpers.js'; +/** + * @name isClass + * Tests if the supplied argument is a Class + */ +export const isClass = /*#__PURE__*/ isOnFunction('isPrototypeOf', 'hasOwnProperty'); diff --git a/packages/util/is/codec.d.ts b/packages/util/is/codec.d.ts new file mode 100644 index 0000000..511e559 --- /dev/null +++ b/packages/util/is/codec.d.ts @@ -0,0 +1,12 @@ +import type { HexString } from '../types.js'; +interface Registry { + get: (...params: never[]) => any; +} +interface Codec { + readonly registry: Registry; + toHex(...params: never[]): HexString; + toHuman(...params: never[]): unknown; + toU8a: (...params: never[]) => Uint8Array; +} +export declare function isCodec(value?: unknown): value is T; +export {}; diff --git a/packages/util/is/codec.js b/packages/util/is/codec.js new file mode 100644 index 0000000..4e7b81c --- /dev/null +++ b/packages/util/is/codec.js @@ -0,0 +1,6 @@ +import { isOnObject } from './helpers.js'; +const checkCodec = /*#__PURE__*/ isOnObject('toHex', 'toHuman', 'toU8a'); +const checkRegistry = /*#__PURE__*/ isOnObject('get'); +export function isCodec(value) { + return checkCodec(value) && checkRegistry(value.registry); +} diff --git a/packages/util/is/compact.d.ts b/packages/util/is/compact.d.ts new file mode 100644 index 0000000..6117210 --- /dev/null +++ b/packages/util/is/compact.d.ts @@ -0,0 +1,13 @@ +import type { BN } from '../bn/bn.js'; +interface Compact { + toBigInt(): bigint; + toBn(): BN; + toNumber(): number; + unwrap(): T; +} +/** + * @name isCompact + * @summary Tests for SCALE-Compact-like object instance. + */ +export declare const isCompact: (value?: unknown) => value is Compact; +export {}; diff --git a/packages/util/is/compact.js b/packages/util/is/compact.js new file mode 100644 index 0000000..3159bca --- /dev/null +++ b/packages/util/is/compact.js @@ -0,0 +1,6 @@ +import { isOnObject } from './helpers.js'; +/** + * @name isCompact + * @summary Tests for SCALE-Compact-like object instance. + */ +export const isCompact = /*#__PURE__*/ isOnObject('toBigInt', 'toBn', 'toNumber', 'unwrap'); diff --git a/packages/util/is/error.d.ts b/packages/util/is/error.d.ts new file mode 100644 index 0000000..97ba8d2 --- /dev/null +++ b/packages/util/is/error.d.ts @@ -0,0 +1,15 @@ +/** + * @name isError + * @summary Tests for a `Error` object instance. + * @description + * Checks to see if the input object is an instance of `Error`. + * @example + *
+ * + * ```javascript + * import { isError } from '@pezkuwi/util'; + * + * console.log('isError', isError(new Error('message'))); // => true + * ``` + */ +export declare function isError(value: unknown): value is Error; diff --git a/packages/util/is/error.js b/packages/util/is/error.js new file mode 100644 index 0000000..91b589a --- /dev/null +++ b/packages/util/is/error.js @@ -0,0 +1,18 @@ +/** + * @name isError + * @summary Tests for a `Error` object instance. + * @description + * Checks to see if the input object is an instance of `Error`. + * @example + *
+ * + * ```javascript + * import { isError } from '@pezkuwi/util'; + * + * console.log('isError', isError(new Error('message'))); // => true + * ``` + */ +export function isError(value) { + return (((value && value.constructor) === Error) || + value instanceof Error); +} diff --git a/packages/util/is/function.d.ts b/packages/util/is/function.d.ts new file mode 100644 index 0000000..7f09bde --- /dev/null +++ b/packages/util/is/function.d.ts @@ -0,0 +1,17 @@ +type FnType = Function; +/** + * @name isFunction + * @summary Tests for a `function`. + * @description + * Checks to see if the input value is a JavaScript function. + * @example + *
+ * + * ```javascript + * import { isFunction } from '@pezkuwi/util'; + * + * isFunction(() => false); // => true + * ``` + */ +export declare function isFunction(value: unknown): value is FnType; +export {}; diff --git a/packages/util/is/function.js b/packages/util/is/function.js new file mode 100644 index 0000000..7a5f2c0 --- /dev/null +++ b/packages/util/is/function.js @@ -0,0 +1,17 @@ +/** + * @name isFunction + * @summary Tests for a `function`. + * @description + * Checks to see if the input value is a JavaScript function. + * @example + *
+ * + * ```javascript + * import { isFunction } from '@pezkuwi/util'; + * + * isFunction(() => false); // => true + * ``` + */ +export function isFunction(value) { + return typeof value === 'function'; +} diff --git a/packages/util/is/helpers.d.ts b/packages/util/is/helpers.d.ts new file mode 100644 index 0000000..41f5e5a --- /dev/null +++ b/packages/util/is/helpers.d.ts @@ -0,0 +1,3 @@ +export declare function isOn(...fns: (keyof T)[]): (value?: unknown) => value is T; +export declare function isOnFunction(...fns: (keyof T)[]): (value?: unknown) => value is T; +export declare function isOnObject(...fns: (keyof T)[]): (value?: unknown) => value is T; diff --git a/packages/util/is/helpers.js b/packages/util/is/helpers.js new file mode 100644 index 0000000..01837e9 --- /dev/null +++ b/packages/util/is/helpers.js @@ -0,0 +1,14 @@ +import { isFunction } from './function.js'; +import { isObject } from './object.js'; +export function isOn(...fns) { + return (value) => (isObject(value) || isFunction(value)) && + fns.every((f) => isFunction(value[f])); +} +export function isOnFunction(...fns) { + return (value) => isFunction(value) && + fns.every((f) => isFunction(value[f])); +} +export function isOnObject(...fns) { + return (value) => isObject(value) && + fns.every((f) => isFunction(value[f])); +} diff --git a/packages/util/is/hex.d.ts b/packages/util/is/hex.d.ts new file mode 100644 index 0000000..2fcabbd --- /dev/null +++ b/packages/util/is/hex.d.ts @@ -0,0 +1,19 @@ +import type { HexString } from '../types.js'; +export declare const REGEX_HEX_PREFIXED: RegExp; +export declare const REGEX_HEX_NOPREFIX: RegExp; +/** + * @name isHex + * @summary Tests for a hex string. + * @description + * Checks to see if the input value is a `0x` prefixed hex string. Optionally (`bitLength` !== -1) checks to see if the bitLength is correct. + * @example + *
+ * + * ```javascript + * import { isHex } from '@pezkuwi/util'; + * + * isHex('0x1234'); // => true + * isHex('0x1234', 8); // => false + * ``` + */ +export declare function isHex(value: unknown, bitLength?: number, ignoreLength?: boolean): value is HexString; diff --git a/packages/util/is/hex.js b/packages/util/is/hex.js new file mode 100644 index 0000000..e3b1012 --- /dev/null +++ b/packages/util/is/hex.js @@ -0,0 +1,23 @@ +export const REGEX_HEX_PREFIXED = /^0x[\da-fA-F]+$/; +export const REGEX_HEX_NOPREFIX = /^[\da-fA-F]+$/; +/** + * @name isHex + * @summary Tests for a hex string. + * @description + * Checks to see if the input value is a `0x` prefixed hex string. Optionally (`bitLength` !== -1) checks to see if the bitLength is correct. + * @example + *
+ * + * ```javascript + * import { isHex } from '@pezkuwi/util'; + * + * isHex('0x1234'); // => true + * isHex('0x1234', 8); // => false + * ``` + */ +export function isHex(value, bitLength = -1, ignoreLength) { + return (typeof value === 'string' && (value === '0x' || + REGEX_HEX_PREFIXED.test(value))) && (bitLength === -1 + ? (ignoreLength || (value.length % 2 === 0)) + : (value.length === (2 + Math.ceil(bitLength / 4)))); +} diff --git a/packages/util/is/index.d.ts b/packages/util/is/index.d.ts new file mode 100644 index 0000000..748c53e --- /dev/null +++ b/packages/util/is/index.d.ts @@ -0,0 +1,33 @@ +/** + * @summary Type checking utilities + */ +export { isArray } from './array.js'; +export { isAscii } from './ascii.js'; +export { isBigInt } from './bigInt.js'; +export { isBn } from './bn.js'; +export { isBoolean } from './boolean.js'; +export { isBuffer } from './buffer.js'; +export { isChildClass } from './childClass.js'; +export { isClass } from './class.js'; +export { isCodec } from './codec.js'; +export { isCompact } from './compact.js'; +export { isError } from './error.js'; +export { isFunction } from './function.js'; +export { isHex } from './hex.js'; +export { isInstanceOf } from './instanceOf.js'; +export { isIp } from './ip.js'; +export { isJsonObject } from './jsonObject.js'; +export { isNull } from './null.js'; +export { isNumber } from './number.js'; +export { isObject } from './object.js'; +export { isObservable } from './observable.js'; +export { isPromise } from './promise.js'; +export { isRiscV } from './riscv.js'; +export { isString } from './string.js'; +export { isTestChain } from './testChain.js'; +export { isToBigInt } from './toBigInt.js'; +export { isToBn } from './toBn.js'; +export { isU8a } from './u8a.js'; +export { isUndefined } from './undefined.js'; +export { isUtf8 } from './utf8.js'; +export { isWasm } from './wasm.js'; diff --git a/packages/util/is/index.js b/packages/util/is/index.js new file mode 100644 index 0000000..748c53e --- /dev/null +++ b/packages/util/is/index.js @@ -0,0 +1,33 @@ +/** + * @summary Type checking utilities + */ +export { isArray } from './array.js'; +export { isAscii } from './ascii.js'; +export { isBigInt } from './bigInt.js'; +export { isBn } from './bn.js'; +export { isBoolean } from './boolean.js'; +export { isBuffer } from './buffer.js'; +export { isChildClass } from './childClass.js'; +export { isClass } from './class.js'; +export { isCodec } from './codec.js'; +export { isCompact } from './compact.js'; +export { isError } from './error.js'; +export { isFunction } from './function.js'; +export { isHex } from './hex.js'; +export { isInstanceOf } from './instanceOf.js'; +export { isIp } from './ip.js'; +export { isJsonObject } from './jsonObject.js'; +export { isNull } from './null.js'; +export { isNumber } from './number.js'; +export { isObject } from './object.js'; +export { isObservable } from './observable.js'; +export { isPromise } from './promise.js'; +export { isRiscV } from './riscv.js'; +export { isString } from './string.js'; +export { isTestChain } from './testChain.js'; +export { isToBigInt } from './toBigInt.js'; +export { isToBn } from './toBn.js'; +export { isU8a } from './u8a.js'; +export { isUndefined } from './undefined.js'; +export { isUtf8 } from './utf8.js'; +export { isWasm } from './wasm.js'; diff --git a/packages/util/is/instanceOf.d.ts b/packages/util/is/instanceOf.d.ts new file mode 100644 index 0000000..1783692 --- /dev/null +++ b/packages/util/is/instanceOf.d.ts @@ -0,0 +1,15 @@ +/** + * @name isInstanceOf + * @summary Tests for a instance of a class. + * @description + * Checks to see if the input value is an instance of the test class. + * @example + *
+ * + * ```javascript + * import { isInstanceOf } from '@pezkuwi/util'; + * + * console.log('isInstanceOf', isInstanceOf(new Array(0), Array)); // => true + * ``` + */ +export declare function isInstanceOf(value: unknown, Clazz: Function): boolean; diff --git a/packages/util/is/instanceOf.js b/packages/util/is/instanceOf.js new file mode 100644 index 0000000..2e777aa --- /dev/null +++ b/packages/util/is/instanceOf.js @@ -0,0 +1,18 @@ +/** + * @name isInstanceOf + * @summary Tests for a instance of a class. + * @description + * Checks to see if the input value is an instance of the test class. + * @example + *
+ * + * ```javascript + * import { isInstanceOf } from '@pezkuwi/util'; + * + * console.log('isInstanceOf', isInstanceOf(new Array(0), Array)); // => true + * ``` + */ +export function isInstanceOf(value, Clazz) { + return (((value && value.constructor) === Clazz) || + value instanceof Clazz); +} diff --git a/packages/util/is/ip.d.ts b/packages/util/is/ip.d.ts new file mode 100644 index 0000000..7a8e94a --- /dev/null +++ b/packages/util/is/ip.d.ts @@ -0,0 +1,18 @@ +/** + * @name isIp + * @summary Tests if the value is a valid IP address + * @description + * Checks to see if the value is a valid IP address. Optionally check for either v4/v6 + * @example + *
+ * + * ```javascript + * import { isIp } from '@pezkuwi/util'; + * + * isIp('192.168.0.1')); // => true + * isIp('1:2:3:4:5:6:7:8'); // => true + * isIp('192.168.0.1', 'v6')); // => false + * isIp('1:2:3:4:5:6:7:8', 'v4'); // => false + * ``` + */ +export declare function isIp(value: string, type?: 'v4' | 'v6'): boolean; diff --git a/packages/util/is/ip.js b/packages/util/is/ip.js new file mode 100644 index 0000000..0c9f298 --- /dev/null +++ b/packages/util/is/ip.js @@ -0,0 +1,41 @@ +const v4 = '(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}'; +const v6s = '[a-fA-F\\d]{1,4}'; +const v6 = ` +(?: +(?:${v6s}:){7}(?:${v6s}|:)| // 1:2:3:4:5:6:7:: 1:2:3:4:5:6:7:8 +(?:${v6s}:){6}(?:${v4}|:${v6s}|:)| // 1:2:3:4:5:6:: 1:2:3:4:5:6::8 1:2:3:4:5:6::8 1:2:3:4:5:6::1.2.3.4 +(?:${v6s}:){5}(?::${v4}|(?::${v6s}){1,2}|:)| // 1:2:3:4:5:: 1:2:3:4:5::7:8 1:2:3:4:5::8 1:2:3:4:5::7:1.2.3.4 +(?:${v6s}:){4}(?:(?::${v6s}){0,1}:${v4}|(?::${v6s}){1,3}|:)| // 1:2:3:4:: 1:2:3:4::6:7:8 1:2:3:4::8 1:2:3:4::6:7:1.2.3.4 +(?:${v6s}:){3}(?:(?::${v6s}){0,2}:${v4}|(?::${v6s}){1,4}|:)| // 1:2:3:: 1:2:3::5:6:7:8 1:2:3::8 1:2:3::5:6:7:1.2.3.4 +(?:${v6s}:){2}(?:(?::${v6s}){0,3}:${v4}|(?::${v6s}){1,5}|:)| // 1:2:: 1:2::4:5:6:7:8 1:2::8 1:2::4:5:6:7:1.2.3.4 +(?:${v6s}:){1}(?:(?::${v6s}){0,4}:${v4}|(?::${v6s}){1,6}|:)| // 1:: 1::3:4:5:6:7:8 1::8 1::3:4:5:6:7:1.2.3.4 +(?::(?:(?::${v6s}){0,5}:${v4}|(?::${v6s}){1,7}|:)) // ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::1.2.3.4 +)(?:%[0-9a-zA-Z]{1,})? // %eth0 %1 +`.replace(/\s*\/\/.*$/gm, '').replace(/\n/g, '').trim(); +const v46Exact = new RegExp(`(?:^${v4}$)|(?:^${v6}$)`); +const v4exact = new RegExp(`^${v4}$`); +const v6exact = new RegExp(`^${v6}$`); +/** + * @name isIp + * @summary Tests if the value is a valid IP address + * @description + * Checks to see if the value is a valid IP address. Optionally check for either v4/v6 + * @example + *
+ * + * ```javascript + * import { isIp } from '@pezkuwi/util'; + * + * isIp('192.168.0.1')); // => true + * isIp('1:2:3:4:5:6:7:8'); // => true + * isIp('192.168.0.1', 'v6')); // => false + * isIp('1:2:3:4:5:6:7:8', 'v4'); // => false + * ``` + */ +export function isIp(value, type) { + switch (type) { + case 'v4': return v4exact.test(value); + case 'v6': return v6exact.test(value); + default: return v46Exact.test(value); + } +} diff --git a/packages/util/is/jsonObject.d.ts b/packages/util/is/jsonObject.d.ts new file mode 100644 index 0000000..79479e3 --- /dev/null +++ b/packages/util/is/jsonObject.d.ts @@ -0,0 +1,27 @@ +type ObjectIndexed = Record; +/** + * @name isJsonObject + * @summary Tests for a valid JSON `object`. + * @description + * Checks to see if the input value is a valid JSON object. + * It returns false if the input is JSON parsable, but not an Javascript object. + * @example + *
+ * + * ```javascript + * import { isJsonObject } from '@pezkuwi/util'; + * + * isJsonObject({}); // => true + * isJsonObject({ + * "Test": "1234", + * "NestedTest": { + * "Test": "5678" + * } + * }); // => true + * isJsonObject(1234); // JSON parsable, but not an object => false + * isJsonObject(null); // JSON parsable, but not an object => false + * isJsonObject('not an object'); // => false + * ``` + */ +export declare function isJsonObject(value: unknown): value is ObjectIndexed; +export {}; diff --git a/packages/util/is/jsonObject.js b/packages/util/is/jsonObject.js new file mode 100644 index 0000000..4c1e5d2 --- /dev/null +++ b/packages/util/is/jsonObject.js @@ -0,0 +1,37 @@ +import { stringify } from '../stringify.js'; +/** + * @name isJsonObject + * @summary Tests for a valid JSON `object`. + * @description + * Checks to see if the input value is a valid JSON object. + * It returns false if the input is JSON parsable, but not an Javascript object. + * @example + *
+ * + * ```javascript + * import { isJsonObject } from '@pezkuwi/util'; + * + * isJsonObject({}); // => true + * isJsonObject({ + * "Test": "1234", + * "NestedTest": { + * "Test": "5678" + * } + * }); // => true + * isJsonObject(1234); // JSON parsable, but not an object => false + * isJsonObject(null); // JSON parsable, but not an object => false + * isJsonObject('not an object'); // => false + * ``` + */ +export function isJsonObject(value) { + const str = typeof value !== 'string' + ? stringify(value) + : value; + try { + const obj = JSON.parse(str); + return typeof obj === 'object' && obj !== null; + } + catch { + return false; + } +} diff --git a/packages/util/is/null.d.ts b/packages/util/is/null.d.ts new file mode 100644 index 0000000..8f20eb5 --- /dev/null +++ b/packages/util/is/null.d.ts @@ -0,0 +1,15 @@ +/** + * @name isNull + * @summary Tests for a `null` values. + * @description + * Checks to see if the input value is `null`. + * @example + *
+ * + * ```javascript + * import { isNull } from '@pezkuwi/util'; + * + * console.log('isNull', isNull(null)); // => true + * ``` + */ +export declare function isNull(value?: unknown): value is null; diff --git a/packages/util/is/null.js b/packages/util/is/null.js new file mode 100644 index 0000000..085abf1 --- /dev/null +++ b/packages/util/is/null.js @@ -0,0 +1,17 @@ +/** + * @name isNull + * @summary Tests for a `null` values. + * @description + * Checks to see if the input value is `null`. + * @example + *
+ * + * ```javascript + * import { isNull } from '@pezkuwi/util'; + * + * console.log('isNull', isNull(null)); // => true + * ``` + */ +export function isNull(value) { + return value === null; +} diff --git a/packages/util/is/number.d.ts b/packages/util/is/number.d.ts new file mode 100644 index 0000000..3f5934c --- /dev/null +++ b/packages/util/is/number.d.ts @@ -0,0 +1,15 @@ +/** + * @name isNumber + * @summary Tests for a JavaScript number. + * @description + * Checks to see if the input value is a valid number. + * @example + *
+ * + * ```javascript + * import { isNumber } from '@pezkuwi/util'; + * + * console.log('isNumber', isNumber(1234)); // => true + * ``` + */ +export declare function isNumber(value: unknown): value is number; diff --git a/packages/util/is/number.js b/packages/util/is/number.js new file mode 100644 index 0000000..ec2e976 --- /dev/null +++ b/packages/util/is/number.js @@ -0,0 +1,17 @@ +/** + * @name isNumber + * @summary Tests for a JavaScript number. + * @description + * Checks to see if the input value is a valid number. + * @example + *
+ * + * ```javascript + * import { isNumber } from '@pezkuwi/util'; + * + * console.log('isNumber', isNumber(1234)); // => true + * ``` + */ +export function isNumber(value) { + return typeof value === 'number'; +} diff --git a/packages/util/is/object.d.ts b/packages/util/is/object.d.ts new file mode 100644 index 0000000..610a4d4 --- /dev/null +++ b/packages/util/is/object.d.ts @@ -0,0 +1,18 @@ +type ObjectIndexed = Record; +/** + * @name isObject + * @summary Tests for an `object`. + * @description + * Checks to see if the input value is a JavaScript object. + * @example + *
+ * + * ```javascript + * import { isObject } from '@pezkuwi/util'; + * + * isObject({}); // => true + * isObject('something'); // => false + * ``` + */ +export declare function isObject(value?: unknown): value is T; +export {}; diff --git a/packages/util/is/object.js b/packages/util/is/object.js new file mode 100644 index 0000000..fd71d32 --- /dev/null +++ b/packages/util/is/object.js @@ -0,0 +1,18 @@ +/** + * @name isObject + * @summary Tests for an `object`. + * @description + * Checks to see if the input value is a JavaScript object. + * @example + *
+ * + * ```javascript + * import { isObject } from '@pezkuwi/util'; + * + * isObject({}); // => true + * isObject('something'); // => false + * ``` + */ +export function isObject(value) { + return !!value && typeof value === 'object'; +} diff --git a/packages/util/is/observable.d.ts b/packages/util/is/observable.d.ts new file mode 100644 index 0000000..cc09c1f --- /dev/null +++ b/packages/util/is/observable.d.ts @@ -0,0 +1,16 @@ +import type { Observable } from '../types.js'; +/** + * @name isBObservable + * @summary Tests for a `Observable` object instance. + * @description + * Checks to see if the input object is an instance of `BN` (bn.js). + * @example + *
+ * + * ```javascript + * import { isObservable } from '@pezkuwi/util'; + * + * console.log('isObservable', isObservable(...)); + * ``` + */ +export declare const isObservable: (value?: unknown) => value is Observable; diff --git a/packages/util/is/observable.js b/packages/util/is/observable.js new file mode 100644 index 0000000..656eff1 --- /dev/null +++ b/packages/util/is/observable.js @@ -0,0 +1,16 @@ +import { isOn } from './helpers.js'; +/** + * @name isBObservable + * @summary Tests for a `Observable` object instance. + * @description + * Checks to see if the input object is an instance of `BN` (bn.js). + * @example + *
+ * + * ```javascript + * import { isObservable } from '@pezkuwi/util'; + * + * console.log('isObservable', isObservable(...)); + * ``` + */ +export const isObservable = /*#__PURE__*/ isOn('next'); diff --git a/packages/util/is/promise.d.ts b/packages/util/is/promise.d.ts new file mode 100644 index 0000000..2ee59f9 --- /dev/null +++ b/packages/util/is/promise.d.ts @@ -0,0 +1 @@ +export declare const isPromise: (value?: unknown) => value is Promise; diff --git a/packages/util/is/promise.js b/packages/util/is/promise.js new file mode 100644 index 0000000..9f1c340 --- /dev/null +++ b/packages/util/is/promise.js @@ -0,0 +1,2 @@ +import { isOnObject } from './helpers.js'; +export const isPromise = /*#__PURE__*/ isOnObject('catch', 'then'); diff --git a/packages/util/is/riscv.d.ts b/packages/util/is/riscv.d.ts new file mode 100644 index 0000000..2e8e034 --- /dev/null +++ b/packages/util/is/riscv.d.ts @@ -0,0 +1,7 @@ +/** + * @name isRiscV + * @summary Tests if the input has a RISC-V header + * @description + * Checks to see if the input Uint8Array contains a valid RISC-V header + */ +export declare function isRiscV(bytes: unknown): bytes is Uint8Array; diff --git a/packages/util/is/riscv.js b/packages/util/is/riscv.js new file mode 100644 index 0000000..15909f1 --- /dev/null +++ b/packages/util/is/riscv.js @@ -0,0 +1,17 @@ +import { u8aEq } from '../u8a/eq.js'; +import { isU8a } from './u8a.js'; +const ELF_MAGIC = new Uint8Array([0x7f, 0x45, 0x4c, 0x46]); // ELF magic bytes: 0x7f, 'E', 'L', 'F' +const PVM_MAGIC = new Uint8Array([0x50, 0x56, 0x4d, 0x00]); // 'P', 'V', 'M', 0x00 +/** + * @name isRiscV + * @summary Tests if the input has a RISC-V header + * @description + * Checks to see if the input Uint8Array contains a valid RISC-V header + */ +export function isRiscV(bytes) { + if (isU8a(bytes)) { + const start = bytes.subarray(0, 4); + return u8aEq(start, PVM_MAGIC) || u8aEq(start, ELF_MAGIC); + } + return false; +} diff --git a/packages/util/is/string.d.ts b/packages/util/is/string.d.ts new file mode 100644 index 0000000..0873b6e --- /dev/null +++ b/packages/util/is/string.d.ts @@ -0,0 +1,16 @@ +import type { AnyString } from '../types.js'; +/** + * @name isString + * @summary Tests for a string. + * @description + * Checks to see if the input value is a JavaScript string. + * @example + *
+ * + * ```javascript + * import { isString } from '@pezkuwi/util'; + * + * console.log('isString', isString('test')); // => true + * ``` + */ +export declare function isString(value: unknown): value is AnyString; diff --git a/packages/util/is/string.js b/packages/util/is/string.js new file mode 100644 index 0000000..b2fcae5 --- /dev/null +++ b/packages/util/is/string.js @@ -0,0 +1,17 @@ +/** + * @name isString + * @summary Tests for a string. + * @description + * Checks to see if the input value is a JavaScript string. + * @example + *
+ * + * ```javascript + * import { isString } from '@pezkuwi/util'; + * + * console.log('isString', isString('test')); // => true + * ``` + */ +export function isString(value) { + return typeof value === 'string' || value instanceof String; +} diff --git a/packages/util/is/testChain.d.ts b/packages/util/is/testChain.d.ts new file mode 100644 index 0000000..253a6f0 --- /dev/null +++ b/packages/util/is/testChain.d.ts @@ -0,0 +1 @@ +export declare function isTestChain(chain?: string | null): boolean; diff --git a/packages/util/is/testChain.js b/packages/util/is/testChain.js new file mode 100644 index 0000000..f87ed9c --- /dev/null +++ b/packages/util/is/testChain.js @@ -0,0 +1,7 @@ +const REGEX_DEV = /(Development|Local Testnet)$/; +export function isTestChain(chain) { + if (!chain) { + return false; + } + return !!REGEX_DEV.test(chain.toString()); +} diff --git a/packages/util/is/toBigInt.d.ts b/packages/util/is/toBigInt.d.ts new file mode 100644 index 0000000..e05bb9d --- /dev/null +++ b/packages/util/is/toBigInt.d.ts @@ -0,0 +1,2 @@ +import type { ToBigInt } from '../types.js'; +export declare const isToBigInt: (value?: unknown) => value is ToBigInt; diff --git a/packages/util/is/toBigInt.js b/packages/util/is/toBigInt.js new file mode 100644 index 0000000..c96e59f --- /dev/null +++ b/packages/util/is/toBigInt.js @@ -0,0 +1,2 @@ +import { isOn } from './helpers.js'; +export const isToBigInt = /*#__PURE__*/ isOn('toBigInt'); diff --git a/packages/util/is/toBn.d.ts b/packages/util/is/toBn.d.ts new file mode 100644 index 0000000..73d7ec7 --- /dev/null +++ b/packages/util/is/toBn.d.ts @@ -0,0 +1,2 @@ +import type { ToBn } from '../types.js'; +export declare const isToBn: (value?: unknown) => value is ToBn; diff --git a/packages/util/is/toBn.js b/packages/util/is/toBn.js new file mode 100644 index 0000000..d2e9aa7 --- /dev/null +++ b/packages/util/is/toBn.js @@ -0,0 +1,2 @@ +import { isOn } from './helpers.js'; +export const isToBn = /*#__PURE__*/ isOn('toBn'); diff --git a/packages/util/is/u8a.d.ts b/packages/util/is/u8a.d.ts new file mode 100644 index 0000000..52947ec --- /dev/null +++ b/packages/util/is/u8a.d.ts @@ -0,0 +1,15 @@ +/** + * @name isU8a + * @summary Tests for a `Uint8Array` object instance. + * @description + * Checks to see if the input object is an instance of `Uint8Array`. + * @example + *
+ * + * ```javascript + * import { isUint8Array } from '@pezkuwi/util'; + * + * console.log('isU8a', isU8a([])); // => false + * ``` + */ +export declare function isU8a(value?: unknown): value is Uint8Array; diff --git a/packages/util/is/u8a.js b/packages/util/is/u8a.js new file mode 100644 index 0000000..040177d --- /dev/null +++ b/packages/util/is/u8a.js @@ -0,0 +1,20 @@ +/** + * @name isU8a + * @summary Tests for a `Uint8Array` object instance. + * @description + * Checks to see if the input object is an instance of `Uint8Array`. + * @example + *
+ * + * ```javascript + * import { isUint8Array } from '@pezkuwi/util'; + * + * console.log('isU8a', isU8a([])); // => false + * ``` + */ +export function isU8a(value) { + // here we defer the instanceof check which is actually slightly + // slower than just checking the constrctor (direct instances) + return (((value && value.constructor) === Uint8Array) || + value instanceof Uint8Array); +} diff --git a/packages/util/is/undefined.d.ts b/packages/util/is/undefined.d.ts new file mode 100644 index 0000000..2e17969 --- /dev/null +++ b/packages/util/is/undefined.d.ts @@ -0,0 +1,15 @@ +/** + * @name isUndefined + * @summary Tests for a `undefined` values. + * @description + * Checks to see if the input value is `undefined`. + * @example + *
+ * + * ```javascript + * import { isUndefined } from '@pezkuwi/util'; + * + * console.log('isUndefined', isUndefined(void(0))); // => true + * ``` + */ +export declare function isUndefined(value?: unknown): value is undefined; diff --git a/packages/util/is/undefined.js b/packages/util/is/undefined.js new file mode 100644 index 0000000..bc7c7c8 --- /dev/null +++ b/packages/util/is/undefined.js @@ -0,0 +1,17 @@ +/** + * @name isUndefined + * @summary Tests for a `undefined` values. + * @description + * Checks to see if the input value is `undefined`. + * @example + *
+ * + * ```javascript + * import { isUndefined } from '@pezkuwi/util'; + * + * console.log('isUndefined', isUndefined(void(0))); // => true + * ``` + */ +export function isUndefined(value) { + return value === undefined; +} diff --git a/packages/util/is/utf8.d.ts b/packages/util/is/utf8.d.ts new file mode 100644 index 0000000..bec769d --- /dev/null +++ b/packages/util/is/utf8.d.ts @@ -0,0 +1,7 @@ +/** + * @name isUtf8 + * @summary Tests if the input is valid Utf8 + * @description + * Checks to see if the input string or Uint8Array is valid Utf8 + */ +export declare function isUtf8(value?: number[] | Uint8Array | string | null): boolean; diff --git a/packages/util/is/utf8.js b/packages/util/is/utf8.js new file mode 100644 index 0000000..55e426b --- /dev/null +++ b/packages/util/is/utf8.js @@ -0,0 +1,197 @@ +import { u8aToU8a } from '../u8a/toU8a.js'; +import { isString } from './string.js'; +/** + * @name isUtf8 + * @summary Tests if the input is valid Utf8 + * @description + * Checks to see if the input string or Uint8Array is valid Utf8 + */ +export function isUtf8(value) { + if (!value) { + return isString(value); + } + const u8a = u8aToU8a(value); + const len = u8a.length; + let i = 0; + while (i < len) { + if (u8a[i] <= 0x7F) /* 00..7F */ { + i += 1; + } + else if (u8a[i] >= 0xC2 && u8a[i] <= 0xDF) /* C2..DF 80..BF */ { + if (i + 1 < len) /* Expect a 2nd byte */ { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0xBF) { + // *message = "After a first byte between C2 and DF, expecting a 2nd byte between 80 and BF"; + // *faulty_bytes = 2; + return false; + } + } + else { + // *message = "After a first byte between C2 and DF, expecting a 2nd byte."; + // *faulty_bytes = 1; + return false; + } + i += 2; + } + else if (u8a[i] === 0xE0) /* E0 A0..BF 80..BF */ { + if (i + 2 < len) /* Expect a 2nd and 3rd byte */ { + if (u8a[i + 1] < 0xA0 || u8a[i + 1] > 0xBF) { + // *message = "After a first byte of E0, expecting a 2nd byte between A0 and BF."; + // *faulty_bytes = 2; + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + // *message = "After a first byte of E0, expecting a 3nd byte between 80 and BF."; + // *faulty_bytes = 3; + return false; + } + } + else { + // *message = "After a first byte of E0, expecting two following bytes."; + // *faulty_bytes = 1; + return false; + } + i += 3; + } + else if (u8a[i] >= 0xE1 && u8a[i] <= 0xEC) /* E1..EC 80..BF 80..BF */ { + if (i + 2 < len) /* Expect a 2nd and 3rd byte */ { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0xBF) { + // *message = "After a first byte between E1 and EC, expecting the 2nd byte between 80 and BF."; + // *faulty_bytes = 2; + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + // *message = "After a first byte between E1 and EC, expecting the 3rd byte between 80 and BF."; + // *faulty_bytes = 3; + return false; + } + } + else { + // *message = "After a first byte between E1 and EC, expecting two following bytes."; + // *faulty_bytes = 1; + return false; + } + i += 3; + } + else if (u8a[i] === 0xED) /* ED 80..9F 80..BF */ { + if (i + 2 < len) /* Expect a 2nd and 3rd byte */ { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0x9F) { + // *message = "After a first byte of ED, expecting 2nd byte between 80 and 9F."; + // *faulty_bytes = 2; + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + // *message = "After a first byte of ED, expecting 3rd byte between 80 and BF."; + // *faulty_bytes = 3; + return false; + } + } + else { + // *message = "After a first byte of ED, expecting two following bytes."; + // *faulty_bytes = 1; + return false; + } + i += 3; + } + else if (u8a[i] >= 0xEE && u8a[i] <= 0xEF) /* EE..EF 80..BF 80..BF */ { + if (i + 2 < len) /* Expect a 2nd and 3rd byte */ { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0xBF) { + // *message = "After a first byte between EE and EF, expecting 2nd byte between 80 and BF."; + // *faulty_bytes = 2; + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + // *message = "After a first byte between EE and EF, expecting 3rd byte between 80 and BF."; + // *faulty_bytes = 3; + return false; + } + } + else { + // *message = "After a first byte between EE and EF, two following bytes."; + // *faulty_bytes = 1; + return false; + } + i += 3; + } + else if (u8a[i] === 0xF0) /* F0 90..BF 80..BF 80..BF */ { + if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ { + if (u8a[i + 1] < 0x90 || u8a[i + 1] > 0xBF) { + // *message = "After a first byte of F0, expecting 2nd byte between 90 and BF."; + // *faulty_bytes = 2; + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + // *message = "After a first byte of F0, expecting 3rd byte between 80 and BF."; + // *faulty_bytes = 3; + return false; + } + if (u8a[i + 3] < 0x80 || u8a[i + 3] > 0xBF) { + // *message = "After a first byte of F0, expecting 4th byte between 80 and BF."; + // *faulty_bytes = 4; + return false; + } + } + else { + // *message = "After a first byte of F0, expecting three following bytes."; + // *faulty_bytes = 1; + return false; + } + i += 4; + } + else if (u8a[i] >= 0xF1 && u8a[i] <= 0xF3) /* F1..F3 80..BF 80..BF 80..BF */ { + if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0xBF) { + // *message = "After a first byte of F1, F2, or F3, expecting a 2nd byte between 80 and BF."; + // *faulty_bytes = 2; + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + // *message = "After a first byte of F1, F2, or F3, expecting a 3rd byte between 80 and BF."; + // *faulty_bytes = 3; + return false; + } + if (u8a[i + 3] < 0x80 || u8a[i + 3] > 0xBF) { + // *message = "After a first byte of F1, F2, or F3, expecting a 4th byte between 80 and BF."; + // *faulty_bytes = 4; + return false; + } + } + else { + // *message = "After a first byte of F1, F2, or F3, expecting three following bytes."; + // *faulty_bytes = 1; + return false; + } + i += 4; + } + else if (u8a[i] === 0xF4) /* F4 80..8F 80..BF 80..BF */ { + if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ { + if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0x8F) { + // *message = "After a first byte of F4, expecting 2nd byte between 80 and 8F."; + // *faulty_bytes = 2; + return false; + } + if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) { + // *message = "After a first byte of F4, expecting 3rd byte between 80 and BF."; + // *faulty_bytes = 3; + return false; + } + if (u8a[i + 3] < 0x80 || u8a[i + 3] > 0xBF) { + // *message = "After a first byte of F4, expecting 4th byte between 80 and BF."; + // *faulty_bytes = 4; + return false; + } + } + else { + // *message = "After a first byte of F4, expecting three following bytes."; + // *faulty_bytes = 1; + return false; + } + i += 4; + } + else { + // *message = "Expecting bytes in the following ranges: 00..7F C2..F4."; + // *faulty_bytes = 1; + return false; + } + } + return true; +} diff --git a/packages/util/is/wasm.d.ts b/packages/util/is/wasm.d.ts new file mode 100644 index 0000000..212605d --- /dev/null +++ b/packages/util/is/wasm.d.ts @@ -0,0 +1,7 @@ +/** + * @name isWasm + * @summary Tests if the input has a WASM header + * @description + * Checks to see if the input Uint8Array contains a valid WASM header + */ +export declare function isWasm(value?: unknown): value is Uint8Array; diff --git a/packages/util/is/wasm.js b/packages/util/is/wasm.js new file mode 100644 index 0000000..4af2ec9 --- /dev/null +++ b/packages/util/is/wasm.js @@ -0,0 +1,12 @@ +import { u8aEq } from '../u8a/eq.js'; +import { isU8a } from './u8a.js'; +const WASM_MAGIC = new Uint8Array([0, 97, 115, 109]); // \0asm +/** + * @name isWasm + * @summary Tests if the input has a WASM header + * @description + * Checks to see if the input Uint8Array contains a valid WASM header + */ +export function isWasm(value) { + return isU8a(value) && u8aEq(value.subarray(0, 4), WASM_MAGIC); +} diff --git a/packages/util/lazy.d.ts b/packages/util/lazy.d.ts new file mode 100644 index 0000000..9ba5778 --- /dev/null +++ b/packages/util/lazy.d.ts @@ -0,0 +1,14 @@ +type AnyFn = (...args: unknown[]) => unknown; +/** + * @name lazyMethod + * @description + * Creates a lazy, on-demand getter for the specific value. Upon get the value will be evaluated. + */ +export declare function lazyMethod(result: Record | AnyFn, item: K, creator: (item: K, index: number, self: S) => T, getName?: (item: K, index: number) => string, index?: number): void; +/** + * @name lazyMethods + * @description + * Creates lazy, on-demand getters for the specific values. + */ +export declare function lazyMethods(result: Record, items: readonly K[], creator: (item: K, index: number, self: S) => T, getName?: (item: K, index: number) => string): Record; +export {}; diff --git a/packages/util/lazy.js b/packages/util/lazy.js new file mode 100644 index 0000000..1044447 --- /dev/null +++ b/packages/util/lazy.js @@ -0,0 +1,51 @@ +/** + * @name lazyMethod + * @description + * Creates a lazy, on-demand getter for the specific value. Upon get the value will be evaluated. + */ +export function lazyMethod(result, item, creator, getName, index = 0) { + const name = getName + ? getName(item, index) + : item.toString(); + let value; + Object.defineProperty(result, name, { + // This allows for re-configuration with the embedded defineProperty below + // and ensures that on tested browsers and Node, it _will_ be redefined + // and thus short-circuited for future access + configurable: true, + enumerable: true, + // Use a function here, we don't want to capture the outer this, i.e. + // don't use arrow functions in this context since we have a this inside + get: function () { + // This check should _always_ be false and unneeded, since we override + // with a value below ... however we ensure we are quire vigilant against + // all environment failures, so we are rather be safe than sorry + if (value === undefined) { + value = creator(item, index, this); + try { + // re-define the property as a value, next time around this + // getter will only return the computed value + Object.defineProperty(this, name, { value }); + } + catch { + // ignore any errors, since this _should_ not happen due to + // the "configurable" property above. But if it ever does + // from here-on we will be the cached value the next time + // around (with a very slight dip in performance) + } + } + return value; + } + }); +} +/** + * @name lazyMethods + * @description + * Creates lazy, on-demand getters for the specific values. + */ +export function lazyMethods(result, items, creator, getName) { + for (let i = 0, count = items.length; i < count; i++) { + lazyMethod(result, items[i], creator, getName, i); + } + return result; +} diff --git a/packages/util/logger.d.ts b/packages/util/logger.d.ts new file mode 100644 index 0000000..9372459 --- /dev/null +++ b/packages/util/logger.d.ts @@ -0,0 +1,17 @@ +import type { Logger } from './types.js'; +export declare function loggerFormat(value: unknown): unknown; +/** + * @name Logger + * @summary Creates a consistent log interface for messages + * @description + * Returns a `Logger` that has `.log`, `.error`, `.warn` and `.debug` (controlled with environment `DEBUG=typeA,typeB`) methods. Logging is done with a consistent prefix (type of logger, date) followed by the actual message using the underlying console. + * @example + *
+ * + * ```javascript + * import { logger } from '@pezkuwi/util'; + * + * const l = logger('test'); + * ``` + */ +export declare function logger(origin: string): Logger; diff --git a/packages/util/logger.js b/packages/util/logger.js new file mode 100644 index 0000000..d54483a --- /dev/null +++ b/packages/util/logger.js @@ -0,0 +1,118 @@ +import { xglobal } from '@pezkuwi/x-global'; +import { formatDate } from './format/formatDate.js'; +import { isBn } from './is/bn.js'; +import { isBuffer } from './is/buffer.js'; +import { isFunction } from './is/function.js'; +import { isObject } from './is/object.js'; +import { isU8a } from './is/u8a.js'; +import { u8aToHex } from './u8a/toHex.js'; +import { u8aToU8a } from './u8a/toU8a.js'; +import { noop } from './noop.js'; +const logTo = { + debug: 'log', + error: 'error', + log: 'log', + warn: 'warn' +}; +function formatOther(value) { + if (value && isObject(value) && value.constructor === Object) { + const result = {}; + for (const [k, v] of Object.entries(value)) { + result[k] = loggerFormat(v); + } + return result; + } + return value; +} +export function loggerFormat(value) { + if (Array.isArray(value)) { + return value.map(loggerFormat); + } + else if (isBn(value)) { + return value.toString(); + } + else if (isU8a(value) || isBuffer(value)) { + return u8aToHex(u8aToU8a(value)); + } + return formatOther(value); +} +function formatWithLength(maxLength) { + return (v) => { + if (maxLength <= 0) { + return v; + } + const r = `${v}`; + return r.length < maxLength + ? v + : `${r.substring(0, maxLength)} ...`; + }; +} +function apply(log, type, values, maxSize = -1) { + if (values.length === 1 && isFunction(values[0])) { + const fnResult = values[0](); + return apply(log, type, Array.isArray(fnResult) ? fnResult : [fnResult], maxSize); + } + console[logTo[log]](formatDate(new Date()), type, ...values + .map(loggerFormat) + .map(formatWithLength(maxSize))); +} +function isDebugOn(e, type) { + return !!e && (e === '*' || + type === e || + (e.endsWith('*') && + type.startsWith(e.slice(0, -1)))); +} +function isDebugOff(e, type) { + return !!e && (e.startsWith('-') && + (type === e.slice(1) || + (e.endsWith('*') && + type.startsWith(e.slice(1, -1))))); +} +function getDebugFlag(env, type) { + let flag = false; + for (const e of env) { + if (isDebugOn(e, type)) { + flag = true; + } + else if (isDebugOff(e, type)) { + flag = false; + } + } + return flag; +} +function parseEnv(type) { + const maxSize = parseInt(xglobal.process?.env?.['DEBUG_MAX'] || '-1', 10); + return [ + getDebugFlag((xglobal.process?.env?.['DEBUG'] || '').toLowerCase().split(','), type), + isNaN(maxSize) + ? -1 + : maxSize + ]; +} +/** + * @name Logger + * @summary Creates a consistent log interface for messages + * @description + * Returns a `Logger` that has `.log`, `.error`, `.warn` and `.debug` (controlled with environment `DEBUG=typeA,typeB`) methods. Logging is done with a consistent prefix (type of logger, date) followed by the actual message using the underlying console. + * @example + *
+ * + * ```javascript + * import { logger } from '@pezkuwi/util'; + * + * const l = logger('test'); + * ``` + */ +export function logger(origin) { + const type = `${origin.toUpperCase()}:`.padStart(16); + const [isDebug, maxSize] = parseEnv(origin.toLowerCase()); + return { + debug: isDebug + ? (...values) => apply('debug', type, values, maxSize) + : noop, + error: (...values) => apply('error', type, values), + log: (...values) => apply('log', type, values), + noop, + warn: (...values) => apply('warn', type, values) + }; +} diff --git a/packages/util/memoize.d.ts b/packages/util/memoize.d.ts new file mode 100644 index 0000000..465a597 --- /dev/null +++ b/packages/util/memoize.d.ts @@ -0,0 +1,10 @@ +import type { Memoized } from './types.js'; +interface Options { + getInstanceId?: () => string; +} +/** + * @name memoize + * @description Memomize the function with a specific instanceId + */ +export declare function memoize T>(fn: F, { getInstanceId }?: Options): Memoized; +export {}; diff --git a/packages/util/memoize.js b/packages/util/memoize.js new file mode 100644 index 0000000..5d4b1af --- /dev/null +++ b/packages/util/memoize.js @@ -0,0 +1,30 @@ +import { stringify } from './stringify.js'; +function defaultGetId() { + return 'none'; +} +/** + * @name memoize + * @description Memomize the function with a specific instanceId + */ +export function memoize(fn, { getInstanceId = defaultGetId } = {}) { + const cache = {}; + const memoized = (...args) => { + const stringParams = stringify(args); + const instanceId = getInstanceId(); + if (!cache[instanceId]) { + cache[instanceId] = {}; + } + if (cache[instanceId][stringParams] === undefined) { + cache[instanceId][stringParams] = fn(...args); + } + return cache[instanceId][stringParams]; + }; + memoized.unmemoize = (...args) => { + const stringParams = stringify(args); + const instanceId = getInstanceId(); + if (cache[instanceId]?.[stringParams] !== undefined) { + delete cache[instanceId][stringParams]; + } + }; + return memoized; +} diff --git a/packages/util/nextTick.d.ts b/packages/util/nextTick.d.ts new file mode 100644 index 0000000..99e4378 --- /dev/null +++ b/packages/util/nextTick.d.ts @@ -0,0 +1,5 @@ +/** + * @name nextTick + * @description Defer the operation to the queue for evaluation on the next tick + */ +export declare function nextTick(onExec: () => unknown, onError?: (error: Error) => unknown): void; diff --git a/packages/util/nextTick.js b/packages/util/nextTick.js new file mode 100644 index 0000000..c9ca9b6 --- /dev/null +++ b/packages/util/nextTick.js @@ -0,0 +1,24 @@ +/** + * @name nextTick + * @description Defer the operation to the queue for evaluation on the next tick + */ +export function nextTick(onExec, onError) { + // While Promise.resolve().then(...) would defer to the nextTick, this + // actually does not play as nicely in browsers like the setTimeout(...) + // approach. So the safer, though less optimal approach is the one taken here + setTimeout(() => { + Promise + .resolve() + .then(() => { + onExec(); + }) + .catch((error) => { + if (onError) { + onError(error); + } + else { + console.error(error); + } + }); + }, 0); +} diff --git a/packages/util/noop.d.ts b/packages/util/noop.d.ts new file mode 100644 index 0000000..90ed136 --- /dev/null +++ b/packages/util/noop.d.ts @@ -0,0 +1,8 @@ +/** + * A sharable identity function. Returns the input as-is with no transformation applied. + */ +export declare function identity(value: T): T; +/** + * A sharable noop function. As the name suggests, does nothing + */ +export declare function noop(): void; diff --git a/packages/util/noop.js b/packages/util/noop.js new file mode 100644 index 0000000..8d50afd --- /dev/null +++ b/packages/util/noop.js @@ -0,0 +1,12 @@ +/** + * A sharable identity function. Returns the input as-is with no transformation applied. + */ +export function identity(value) { + return value; +} +/** + * A sharable noop function. As the name suggests, does nothing + */ +export function noop() { + // noop +} diff --git a/packages/util/number/index.d.ts b/packages/util/number/index.d.ts new file mode 100644 index 0000000..f7d0175 --- /dev/null +++ b/packages/util/number/index.d.ts @@ -0,0 +1,5 @@ +/** + * @summary Utility methods to convert to and from `number` values + */ +export { numberToHex } from './toHex.js'; +export { numberToU8a } from './toU8a.js'; diff --git a/packages/util/number/index.js b/packages/util/number/index.js new file mode 100644 index 0000000..f7d0175 --- /dev/null +++ b/packages/util/number/index.js @@ -0,0 +1,5 @@ +/** + * @summary Utility methods to convert to and from `number` values + */ +export { numberToHex } from './toHex.js'; +export { numberToU8a } from './toU8a.js'; diff --git a/packages/util/number/toHex.d.ts b/packages/util/number/toHex.d.ts new file mode 100644 index 0000000..9670041 --- /dev/null +++ b/packages/util/number/toHex.d.ts @@ -0,0 +1,17 @@ +import type { HexString } from '../types.js'; +/** + * @name numberToHex + * @summary Creates a hex value from a number. + * @description + * `null`/`undefined`/`NaN` inputs returns an empty `0x` result. `number` input values return the actual bytes value converted to a `hex`. With `bitLength` set, it converts the number to the equivalent size. + * @example + *
+ * + * ```javascript + * import { numberToHex } from '@pezkuwi/util'; + * + * numberToHex(0x1234); // => '0x1234' + * numberToHex(0x1234, 32); // => 0x00001234 + * ``` + */ +export declare function numberToHex(value?: number | null, bitLength?: number): HexString; diff --git a/packages/util/number/toHex.js b/packages/util/number/toHex.js new file mode 100644 index 0000000..09c3d19 --- /dev/null +++ b/packages/util/number/toHex.js @@ -0,0 +1,20 @@ +import { hexFixLength } from '../hex/fixLength.js'; +/** + * @name numberToHex + * @summary Creates a hex value from a number. + * @description + * `null`/`undefined`/`NaN` inputs returns an empty `0x` result. `number` input values return the actual bytes value converted to a `hex`. With `bitLength` set, it converts the number to the equivalent size. + * @example + *
+ * + * ```javascript + * import { numberToHex } from '@pezkuwi/util'; + * + * numberToHex(0x1234); // => '0x1234' + * numberToHex(0x1234, 32); // => 0x00001234 + * ``` + */ +export function numberToHex(value, bitLength = -1) { + const hex = (!value || Number.isNaN(value) ? 0 : value).toString(16); + return hexFixLength(hex.length % 2 ? `0${hex}` : hex, bitLength, true); +} diff --git a/packages/util/number/toU8a.d.ts b/packages/util/number/toU8a.d.ts new file mode 100644 index 0000000..ae9c142 --- /dev/null +++ b/packages/util/number/toU8a.d.ts @@ -0,0 +1,15 @@ +/** + * @name numberToU8a + * @summary Creates a Uint8Array object from a number. + * @description + * `null`/`undefined`/`NaN` inputs returns an empty `Uint8Array` result. `number` input values return the actual bytes value converted to a `Uint8Array`. With `bitLength`, it converts the value to the equivalent size. + * @example + *
+ * + * ```javascript + * import { numberToU8a } from '@pezkuwi/util'; + * + * numberToU8a(0x1234); // => [0x12, 0x34] + * ``` + */ +export declare function numberToU8a(value?: number | null, bitLength?: number): Uint8Array; diff --git a/packages/util/number/toU8a.js b/packages/util/number/toU8a.js new file mode 100644 index 0000000..6a66432 --- /dev/null +++ b/packages/util/number/toU8a.js @@ -0,0 +1,19 @@ +import { hexToU8a } from '../hex/toU8a.js'; +import { numberToHex } from './toHex.js'; +/** + * @name numberToU8a + * @summary Creates a Uint8Array object from a number. + * @description + * `null`/`undefined`/`NaN` inputs returns an empty `Uint8Array` result. `number` input values return the actual bytes value converted to a `Uint8Array`. With `bitLength`, it converts the value to the equivalent size. + * @example + *
+ * + * ```javascript + * import { numberToU8a } from '@pezkuwi/util'; + * + * numberToU8a(0x1234); // => [0x12, 0x34] + * ``` + */ +export function numberToU8a(value, bitLength = -1) { + return hexToU8a(numberToHex(value, bitLength)); +} diff --git a/packages/util/object/clear.d.ts b/packages/util/object/clear.d.ts new file mode 100644 index 0000000..c2da0b8 --- /dev/null +++ b/packages/util/object/clear.d.ts @@ -0,0 +1,5 @@ +/** + * @name objectClear + * @summary Removes all the keys from the input object + */ +export declare function objectClear(value: Record): Record; diff --git a/packages/util/object/clear.js b/packages/util/object/clear.js new file mode 100644 index 0000000..d86a023 --- /dev/null +++ b/packages/util/object/clear.js @@ -0,0 +1,11 @@ +/** + * @name objectClear + * @summary Removes all the keys from the input object + */ +export function objectClear(value) { + const keys = Object.keys(value); + for (let i = 0, count = keys.length; i < count; i++) { + delete value[keys[i]]; + } + return value; +} diff --git a/packages/util/object/copy.d.ts b/packages/util/object/copy.d.ts new file mode 100644 index 0000000..016409a --- /dev/null +++ b/packages/util/object/copy.d.ts @@ -0,0 +1,5 @@ +/** + * @name objectCopy + * @summary Creates a shallow clone of the input object + */ +export declare function objectCopy(source: T): T; diff --git a/packages/util/object/copy.js b/packages/util/object/copy.js new file mode 100644 index 0000000..cdc1980 --- /dev/null +++ b/packages/util/object/copy.js @@ -0,0 +1,8 @@ +import { objectSpread } from './spread.js'; +/** + * @name objectCopy + * @summary Creates a shallow clone of the input object + */ +export function objectCopy(source) { + return objectSpread({}, source); +} diff --git a/packages/util/object/entries.d.ts b/packages/util/object/entries.d.ts new file mode 100644 index 0000000..87a3b13 --- /dev/null +++ b/packages/util/object/entries.d.ts @@ -0,0 +1,9 @@ +type Entries = { + [K in keyof T]: [K, T[K]]; +}[keyof T][]; +/** + * @name objectEntries + * @summary A version of Object.entries that is typed for TS + */ +export declare function objectEntries(obj: T): Entries; +export {}; diff --git a/packages/util/object/entries.js b/packages/util/object/entries.js new file mode 100644 index 0000000..0ed296a --- /dev/null +++ b/packages/util/object/entries.js @@ -0,0 +1,7 @@ +/** + * @name objectEntries + * @summary A version of Object.entries that is typed for TS + */ +export function objectEntries(obj) { + return Object.entries(obj); +} diff --git a/packages/util/object/index.d.ts b/packages/util/object/index.d.ts new file mode 100644 index 0000000..46ea184 --- /dev/null +++ b/packages/util/object/index.d.ts @@ -0,0 +1,7 @@ +export { objectClear } from './clear.js'; +export { objectCopy } from './copy.js'; +export { objectEntries } from './entries.js'; +export { objectKeys } from './keys.js'; +export { objectProperties, objectProperty } from './property.js'; +export { objectSpread } from './spread.js'; +export { objectValues } from './values.js'; diff --git a/packages/util/object/index.js b/packages/util/object/index.js new file mode 100644 index 0000000..46ea184 --- /dev/null +++ b/packages/util/object/index.js @@ -0,0 +1,7 @@ +export { objectClear } from './clear.js'; +export { objectCopy } from './copy.js'; +export { objectEntries } from './entries.js'; +export { objectKeys } from './keys.js'; +export { objectProperties, objectProperty } from './property.js'; +export { objectSpread } from './spread.js'; +export { objectValues } from './values.js'; diff --git a/packages/util/object/keys.d.ts b/packages/util/object/keys.d.ts new file mode 100644 index 0000000..dc5bd87 --- /dev/null +++ b/packages/util/object/keys.d.ts @@ -0,0 +1,5 @@ +/** + * @name objectKeys + * @summary A version of Object.keys that is typed for TS + */ +export declare function objectKeys>(value: T): K[]; diff --git a/packages/util/object/keys.js b/packages/util/object/keys.js new file mode 100644 index 0000000..8b5d166 --- /dev/null +++ b/packages/util/object/keys.js @@ -0,0 +1,7 @@ +/** + * @name objectKeys + * @summary A version of Object.keys that is typed for TS + */ +export function objectKeys(value) { + return Object.keys(value); +} diff --git a/packages/util/object/property.d.ts b/packages/util/object/property.d.ts new file mode 100644 index 0000000..f494c11 --- /dev/null +++ b/packages/util/object/property.d.ts @@ -0,0 +1,10 @@ +/** + * @name objectProperty + * @summary Assign a get property on the input object + */ +export declare function objectProperty(that: object, key: string, getter: (key: string, index: number, self: S) => unknown, getName?: (key: string, index: number) => string, index?: number): void; +/** + * @name objectProperties + * @summary Assign get properties on the input object + */ +export declare function objectProperties(that: object, keys: string[], getter: (key: string, index: number, self: S) => unknown, getName?: (key: string, index: number) => string): void; diff --git a/packages/util/object/property.js b/packages/util/object/property.js new file mode 100644 index 0000000..63b9779 --- /dev/null +++ b/packages/util/object/property.js @@ -0,0 +1,34 @@ +/** + * @name objectProperty + * @summary Assign a get property on the input object + */ +export function objectProperty(that, key, getter, getName, index = 0) { + const name = getName + ? getName(key, index) + : key; + // There are 3 approaches here - + // - Object.prototype.hasOwnProperty.call(that, key) - this only checks the current class, i.e + // will retuirn false if the property is set in the parent class + // - isUndefined(...) - this may yield a false positive when the property is there, but not set. + // Additionally, on pre-defined getters it may make a call + // - key in that - Does not need to be combined with either of the above and checks the full chain + if (!(name in that)) { + Object.defineProperty(that, name, { + enumerable: true, + // Unlike in lazy, we always call into the upper function, i.e. this method + // does not cache old values (it is expected to be used for dynamic values) + get: function () { + return getter(key, index, this); + } + }); + } +} +/** + * @name objectProperties + * @summary Assign get properties on the input object + */ +export function objectProperties(that, keys, getter, getName) { + for (let i = 0, count = keys.length; i < count; i++) { + objectProperty(that, keys[i], getter, getName, i); + } +} diff --git a/packages/util/object/spread.d.ts b/packages/util/object/spread.d.ts new file mode 100644 index 0000000..82573d3 --- /dev/null +++ b/packages/util/object/spread.d.ts @@ -0,0 +1,6 @@ +/** + * @name objectSpread + * @summary Concats all sources into the destination + * @description Spreads object properties while maintaining object integrity + */ +export declare function objectSpread(dest: object, ...sources: (object | undefined | null)[]): T; diff --git a/packages/util/object/spread.js b/packages/util/object/spread.js new file mode 100644 index 0000000..f98f9cc --- /dev/null +++ b/packages/util/object/spread.js @@ -0,0 +1,31 @@ +/** + * @name objectSpread + * @summary Concats all sources into the destination + * @description Spreads object properties while maintaining object integrity + */ +export function objectSpread(dest, ...sources) { + const filterProps = new Set(['__proto__', 'constructor', 'prototype']); + for (let i = 0, count = sources.length; i < count; i++) { + const src = sources[i]; + if (src) { + if (typeof src.entries === 'function') { + for (const [key, value] of src.entries()) { + if (!filterProps.has(key)) { + dest[key] = value; + } + } + } + else { + // Create a clean copy of the source object + const sanitizedSrc = Object.create(null); + for (const [key, value] of Object.entries(src)) { + if (!filterProps.has(key)) { + sanitizedSrc[key] = value; + } + } + Object.assign(dest, sanitizedSrc); + } + } + } + return dest; +} diff --git a/packages/util/object/values.d.ts b/packages/util/object/values.d.ts new file mode 100644 index 0000000..12acc4f --- /dev/null +++ b/packages/util/object/values.d.ts @@ -0,0 +1,5 @@ +/** + * @name objectValues + * @summary A version of Object.values that is typed for TS + */ +export declare function objectValues(obj: T): T[keyof T][]; diff --git a/packages/util/object/values.js b/packages/util/object/values.js new file mode 100644 index 0000000..ed09dec --- /dev/null +++ b/packages/util/object/values.js @@ -0,0 +1,7 @@ +/** + * @name objectValues + * @summary A version of Object.values that is typed for TS + */ +export function objectValues(obj) { + return Object.values(obj); +} diff --git a/packages/util/package.json b/packages/util/package.json index f47ac81..5cb476d 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -15,40 +15,1984 @@ }, "sideEffects": [ "./packageDetect.js", - "./packageDetect.cjs" + "./cjs/packageDetect.js" ], "type": "module", - "version": "14.0.10", - "main": "index.js", + "version": "14.0.11", + "main": "./cjs/index.js", + "module": "./index.js", + "types": "./index.d.ts", "exports": { + "./cjs/package.json": "./cjs/package.json", + "./cjs/*": "./cjs/*.js", ".": { "types": "./index.d.ts", + "module": { + "types": "./index.d.ts", + "default": "./index.js" + }, "import": "./index.js", - "require": "./cjs/index.js" + "require": { + "types": "./cjs/index.d.ts", + "default": "./cjs/index.js" + }, + "default": { + "types": "./index.d.ts", + "default": "./index.js" + } + }, + "./array": { + "module": { + "types": "./array/index.d.ts", + "default": "./array/index.js" + }, + "require": { + "types": "./cjs/array/index.d.ts", + "default": "./cjs/array/index.js" + }, + "default": { + "types": "./array/index.d.ts", + "default": "./array/index.js" + } + }, + "./array/chunk": { + "module": { + "types": "./array/chunk.d.ts", + "default": "./array/chunk.js" + }, + "require": { + "types": "./cjs/array/chunk.d.ts", + "default": "./cjs/array/chunk.js" + }, + "default": { + "types": "./array/chunk.d.ts", + "default": "./array/chunk.js" + } + }, + "./array/filter": { + "module": { + "types": "./array/filter.d.ts", + "default": "./array/filter.js" + }, + "require": { + "types": "./cjs/array/filter.d.ts", + "default": "./cjs/array/filter.js" + }, + "default": { + "types": "./array/filter.d.ts", + "default": "./array/filter.js" + } + }, + "./array/flatten": { + "module": { + "types": "./array/flatten.d.ts", + "default": "./array/flatten.js" + }, + "require": { + "types": "./cjs/array/flatten.d.ts", + "default": "./cjs/array/flatten.js" + }, + "default": { + "types": "./array/flatten.d.ts", + "default": "./array/flatten.js" + } + }, + "./array/range": { + "module": { + "types": "./array/range.d.ts", + "default": "./array/range.js" + }, + "require": { + "types": "./cjs/array/range.d.ts", + "default": "./cjs/array/range.js" + }, + "default": { + "types": "./array/range.d.ts", + "default": "./array/range.js" + } + }, + "./array/shuffle": { + "module": { + "types": "./array/shuffle.d.ts", + "default": "./array/shuffle.js" + }, + "require": { + "types": "./cjs/array/shuffle.d.ts", + "default": "./cjs/array/shuffle.js" + }, + "default": { + "types": "./array/shuffle.d.ts", + "default": "./array/shuffle.js" + } + }, + "./array/unzip": { + "module": { + "types": "./array/unzip.d.ts", + "default": "./array/unzip.js" + }, + "require": { + "types": "./cjs/array/unzip.d.ts", + "default": "./cjs/array/unzip.js" + }, + "default": { + "types": "./array/unzip.d.ts", + "default": "./array/unzip.js" + } + }, + "./array/zip": { + "module": { + "types": "./array/zip.d.ts", + "default": "./array/zip.js" + }, + "require": { + "types": "./cjs/array/zip.d.ts", + "default": "./cjs/array/zip.js" + }, + "default": { + "types": "./array/zip.d.ts", + "default": "./array/zip.js" + } + }, + "./assert": { + "module": { + "types": "./assert.d.ts", + "default": "./assert.js" + }, + "require": { + "types": "./cjs/assert.d.ts", + "default": "./cjs/assert.js" + }, + "default": { + "types": "./assert.d.ts", + "default": "./assert.js" + } + }, + "./bi": { + "module": { + "types": "./bi/index.d.ts", + "default": "./bi/index.js" + }, + "require": { + "types": "./cjs/bi/index.d.ts", + "default": "./cjs/bi/index.js" + }, + "default": { + "types": "./bi/index.d.ts", + "default": "./bi/index.js" + } + }, + "./bi/consts": { + "module": { + "types": "./bi/consts.d.ts", + "default": "./bi/consts.js" + }, + "require": { + "types": "./cjs/bi/consts.d.ts", + "default": "./cjs/bi/consts.js" + }, + "default": { + "types": "./bi/consts.d.ts", + "default": "./bi/consts.js" + } + }, + "./bi/helpers": { + "module": { + "types": "./bi/helpers.d.ts", + "default": "./bi/helpers.js" + }, + "require": { + "types": "./cjs/bi/helpers.d.ts", + "default": "./cjs/bi/helpers.js" + }, + "default": { + "types": "./bi/helpers.d.ts", + "default": "./bi/helpers.js" + } + }, + "./bi/min": { + "module": { + "types": "./bi/min.d.ts", + "default": "./bi/min.js" + }, + "require": { + "types": "./cjs/bi/min.d.ts", + "default": "./cjs/bi/min.js" + }, + "default": { + "types": "./bi/min.d.ts", + "default": "./bi/min.js" + } + }, + "./bi/sqrt": { + "module": { + "types": "./bi/sqrt.d.ts", + "default": "./bi/sqrt.js" + }, + "require": { + "types": "./cjs/bi/sqrt.d.ts", + "default": "./cjs/bi/sqrt.js" + }, + "default": { + "types": "./bi/sqrt.d.ts", + "default": "./bi/sqrt.js" + } + }, + "./bi/toBigInt": { + "module": { + "types": "./bi/toBigInt.d.ts", + "default": "./bi/toBigInt.js" + }, + "require": { + "types": "./cjs/bi/toBigInt.d.ts", + "default": "./cjs/bi/toBigInt.js" + }, + "default": { + "types": "./bi/toBigInt.d.ts", + "default": "./bi/toBigInt.js" + } + }, + "./bi/toHex": { + "module": { + "types": "./bi/toHex.d.ts", + "default": "./bi/toHex.js" + }, + "require": { + "types": "./cjs/bi/toHex.d.ts", + "default": "./cjs/bi/toHex.js" + }, + "default": { + "types": "./bi/toHex.d.ts", + "default": "./bi/toHex.js" + } + }, + "./bi/toU8a": { + "module": { + "types": "./bi/toU8a.d.ts", + "default": "./bi/toU8a.js" + }, + "require": { + "types": "./cjs/bi/toU8a.d.ts", + "default": "./cjs/bi/toU8a.js" + }, + "default": { + "types": "./bi/toU8a.d.ts", + "default": "./bi/toU8a.js" + } + }, + "./bn": { + "module": { + "types": "./bn/index.d.ts", + "default": "./bn/index.js" + }, + "require": { + "types": "./cjs/bn/index.d.ts", + "default": "./cjs/bn/index.js" + }, + "default": { + "types": "./bn/index.d.ts", + "default": "./bn/index.js" + } + }, + "./bn/bn": { + "module": { + "types": "./bn/bn.d.ts", + "default": "./bn/bn.js" + }, + "require": { + "types": "./cjs/bn/bn.d.ts", + "default": "./cjs/bn/bn.js" + }, + "default": { + "types": "./bn/bn.d.ts", + "default": "./bn/bn.js" + } + }, + "./bn/consts": { + "module": { + "types": "./bn/consts.d.ts", + "default": "./bn/consts.js" + }, + "require": { + "types": "./cjs/bn/consts.d.ts", + "default": "./cjs/bn/consts.js" + }, + "default": { + "types": "./bn/consts.d.ts", + "default": "./bn/consts.js" + } + }, + "./bn/fromHex": { + "module": { + "types": "./bn/fromHex.d.ts", + "default": "./bn/fromHex.js" + }, + "require": { + "types": "./cjs/bn/fromHex.d.ts", + "default": "./cjs/bn/fromHex.js" + }, + "default": { + "types": "./bn/fromHex.d.ts", + "default": "./bn/fromHex.js" + } + }, + "./bn/min": { + "module": { + "types": "./bn/min.d.ts", + "default": "./bn/min.js" + }, + "require": { + "types": "./cjs/bn/min.d.ts", + "default": "./cjs/bn/min.js" + }, + "default": { + "types": "./bn/min.d.ts", + "default": "./bn/min.js" + } + }, + "./bn/sqrt": { + "module": { + "types": "./bn/sqrt.d.ts", + "default": "./bn/sqrt.js" + }, + "require": { + "types": "./cjs/bn/sqrt.d.ts", + "default": "./cjs/bn/sqrt.js" + }, + "default": { + "types": "./bn/sqrt.d.ts", + "default": "./bn/sqrt.js" + } + }, + "./bn/toBn": { + "module": { + "types": "./bn/toBn.d.ts", + "default": "./bn/toBn.js" + }, + "require": { + "types": "./cjs/bn/toBn.d.ts", + "default": "./cjs/bn/toBn.js" + }, + "default": { + "types": "./bn/toBn.d.ts", + "default": "./bn/toBn.js" + } + }, + "./bn/toHex": { + "module": { + "types": "./bn/toHex.d.ts", + "default": "./bn/toHex.js" + }, + "require": { + "types": "./cjs/bn/toHex.d.ts", + "default": "./cjs/bn/toHex.js" + }, + "default": { + "types": "./bn/toHex.d.ts", + "default": "./bn/toHex.js" + } + }, + "./bn/toU8a": { + "module": { + "types": "./bn/toU8a.d.ts", + "default": "./bn/toU8a.js" + }, + "require": { + "types": "./cjs/bn/toU8a.d.ts", + "default": "./cjs/bn/toU8a.js" + }, + "default": { + "types": "./bn/toU8a.d.ts", + "default": "./bn/toU8a.js" + } + }, + "./buffer": { + "module": { + "types": "./buffer/index.d.ts", + "default": "./buffer/index.js" + }, + "require": { + "types": "./cjs/buffer/index.d.ts", + "default": "./cjs/buffer/index.js" + }, + "default": { + "types": "./buffer/index.d.ts", + "default": "./buffer/index.js" + } + }, + "./buffer/toU8a": { + "module": { + "types": "./buffer/toU8a.d.ts", + "default": "./buffer/toU8a.js" + }, + "require": { + "types": "./cjs/buffer/toU8a.d.ts", + "default": "./cjs/buffer/toU8a.js" + }, + "default": { + "types": "./buffer/toU8a.d.ts", + "default": "./buffer/toU8a.js" + } + }, + "./bundle": { + "module": { + "types": "./bundle.d.ts", + "default": "./bundle.js" + }, + "require": { + "types": "./cjs/bundle.d.ts", + "default": "./cjs/bundle.js" + }, + "default": { + "types": "./bundle.d.ts", + "default": "./bundle.js" + } + }, + "./compact": { + "module": { + "types": "./compact/index.d.ts", + "default": "./compact/index.js" + }, + "require": { + "types": "./cjs/compact/index.d.ts", + "default": "./cjs/compact/index.js" + }, + "default": { + "types": "./compact/index.d.ts", + "default": "./compact/index.js" + } + }, + "./compact/addLength": { + "module": { + "types": "./compact/addLength.d.ts", + "default": "./compact/addLength.js" + }, + "require": { + "types": "./cjs/compact/addLength.d.ts", + "default": "./cjs/compact/addLength.js" + }, + "default": { + "types": "./compact/addLength.d.ts", + "default": "./compact/addLength.js" + } + }, + "./compact/defaults": { + "module": { + "types": "./compact/defaults.d.ts", + "default": "./compact/defaults.js" + }, + "require": { + "types": "./cjs/compact/defaults.d.ts", + "default": "./cjs/compact/defaults.js" + }, + "default": { + "types": "./compact/defaults.d.ts", + "default": "./compact/defaults.js" + } + }, + "./compact/fromU8a": { + "module": { + "types": "./compact/fromU8a.d.ts", + "default": "./compact/fromU8a.js" + }, + "require": { + "types": "./cjs/compact/fromU8a.d.ts", + "default": "./cjs/compact/fromU8a.js" + }, + "default": { + "types": "./compact/fromU8a.d.ts", + "default": "./compact/fromU8a.js" + } + }, + "./compact/stripLength": { + "module": { + "types": "./compact/stripLength.d.ts", + "default": "./compact/stripLength.js" + }, + "require": { + "types": "./cjs/compact/stripLength.d.ts", + "default": "./cjs/compact/stripLength.js" + }, + "default": { + "types": "./compact/stripLength.d.ts", + "default": "./compact/stripLength.js" + } + }, + "./compact/toU8a": { + "module": { + "types": "./compact/toU8a.d.ts", + "default": "./compact/toU8a.js" + }, + "require": { + "types": "./cjs/compact/toU8a.d.ts", + "default": "./cjs/compact/toU8a.js" + }, + "default": { + "types": "./compact/toU8a.d.ts", + "default": "./compact/toU8a.js" + } + }, + "./compact/types": { + "module": { + "types": "./compact/types.d.ts", + "default": "./compact/types.js" + }, + "require": { + "types": "./cjs/compact/types.d.ts", + "default": "./cjs/compact/types.js" + }, + "default": { + "types": "./compact/types.d.ts", + "default": "./compact/types.js" + } + }, + "./detectPackage": { + "module": { + "types": "./detectPackage.d.ts", + "default": "./detectPackage.js" + }, + "require": { + "types": "./cjs/detectPackage.d.ts", + "default": "./cjs/detectPackage.js" + }, + "default": { + "types": "./detectPackage.d.ts", + "default": "./detectPackage.js" + } + }, + "./extractTime": { + "module": { + "types": "./extractTime.d.ts", + "default": "./extractTime.js" + }, + "require": { + "types": "./cjs/extractTime.d.ts", + "default": "./cjs/extractTime.js" + }, + "default": { + "types": "./extractTime.d.ts", + "default": "./extractTime.js" + } + }, + "./float": { + "module": { + "types": "./float/index.d.ts", + "default": "./float/index.js" + }, + "require": { + "types": "./cjs/float/index.d.ts", + "default": "./cjs/float/index.js" + }, + "default": { + "types": "./float/index.d.ts", + "default": "./float/index.js" + } + }, + "./float/toU8a": { + "module": { + "types": "./float/toU8a.d.ts", + "default": "./float/toU8a.js" + }, + "require": { + "types": "./cjs/float/toU8a.d.ts", + "default": "./cjs/float/toU8a.js" + }, + "default": { + "types": "./float/toU8a.d.ts", + "default": "./float/toU8a.js" + } + }, + "./format": { + "module": { + "types": "./format/index.d.ts", + "default": "./format/index.js" + }, + "require": { + "types": "./cjs/format/index.d.ts", + "default": "./cjs/format/index.js" + }, + "default": { + "types": "./format/index.d.ts", + "default": "./format/index.js" + } + }, + "./format/formatBalance": { + "module": { + "types": "./format/formatBalance.d.ts", + "default": "./format/formatBalance.js" + }, + "require": { + "types": "./cjs/format/formatBalance.d.ts", + "default": "./cjs/format/formatBalance.js" + }, + "default": { + "types": "./format/formatBalance.d.ts", + "default": "./format/formatBalance.js" + } + }, + "./format/formatDate": { + "module": { + "types": "./format/formatDate.d.ts", + "default": "./format/formatDate.js" + }, + "require": { + "types": "./cjs/format/formatDate.d.ts", + "default": "./cjs/format/formatDate.js" + }, + "default": { + "types": "./format/formatDate.d.ts", + "default": "./format/formatDate.js" + } + }, + "./format/formatDecimal": { + "module": { + "types": "./format/formatDecimal.d.ts", + "default": "./format/formatDecimal.js" + }, + "require": { + "types": "./cjs/format/formatDecimal.d.ts", + "default": "./cjs/format/formatDecimal.js" + }, + "default": { + "types": "./format/formatDecimal.d.ts", + "default": "./format/formatDecimal.js" + } + }, + "./format/formatElapsed": { + "module": { + "types": "./format/formatElapsed.d.ts", + "default": "./format/formatElapsed.js" + }, + "require": { + "types": "./cjs/format/formatElapsed.d.ts", + "default": "./cjs/format/formatElapsed.js" + }, + "default": { + "types": "./format/formatElapsed.d.ts", + "default": "./format/formatElapsed.js" + } + }, + "./format/formatNumber": { + "module": { + "types": "./format/formatNumber.d.ts", + "default": "./format/formatNumber.js" + }, + "require": { + "types": "./cjs/format/formatNumber.d.ts", + "default": "./cjs/format/formatNumber.js" + }, + "default": { + "types": "./format/formatNumber.d.ts", + "default": "./format/formatNumber.js" + } + }, + "./format/getSeparator": { + "module": { + "types": "./format/getSeparator.d.ts", + "default": "./format/getSeparator.js" + }, + "require": { + "types": "./cjs/format/getSeparator.d.ts", + "default": "./cjs/format/getSeparator.js" + }, + "default": { + "types": "./format/getSeparator.d.ts", + "default": "./format/getSeparator.js" + } + }, + "./format/si": { + "module": { + "types": "./format/si.d.ts", + "default": "./format/si.js" + }, + "require": { + "types": "./cjs/format/si.d.ts", + "default": "./cjs/format/si.js" + }, + "default": { + "types": "./format/si.d.ts", + "default": "./format/si.js" + } + }, + "./has": { + "module": { + "types": "./has.d.ts", + "default": "./has.js" + }, + "require": { + "types": "./cjs/has.d.ts", + "default": "./cjs/has.js" + }, + "default": { + "types": "./has.d.ts", + "default": "./has.js" + } + }, + "./hex": { + "module": { + "types": "./hex/index.d.ts", + "default": "./hex/index.js" + }, + "require": { + "types": "./cjs/hex/index.d.ts", + "default": "./cjs/hex/index.js" + }, + "default": { + "types": "./hex/index.d.ts", + "default": "./hex/index.js" + } + }, + "./hex/addPrefix": { + "module": { + "types": "./hex/addPrefix.d.ts", + "default": "./hex/addPrefix.js" + }, + "require": { + "types": "./cjs/hex/addPrefix.d.ts", + "default": "./cjs/hex/addPrefix.js" + }, + "default": { + "types": "./hex/addPrefix.d.ts", + "default": "./hex/addPrefix.js" + } + }, + "./hex/fixLength": { + "module": { + "types": "./hex/fixLength.d.ts", + "default": "./hex/fixLength.js" + }, + "require": { + "types": "./cjs/hex/fixLength.d.ts", + "default": "./cjs/hex/fixLength.js" + }, + "default": { + "types": "./hex/fixLength.d.ts", + "default": "./hex/fixLength.js" + } + }, + "./hex/hasPrefix": { + "module": { + "types": "./hex/hasPrefix.d.ts", + "default": "./hex/hasPrefix.js" + }, + "require": { + "types": "./cjs/hex/hasPrefix.d.ts", + "default": "./cjs/hex/hasPrefix.js" + }, + "default": { + "types": "./hex/hasPrefix.d.ts", + "default": "./hex/hasPrefix.js" + } + }, + "./hex/stripPrefix": { + "module": { + "types": "./hex/stripPrefix.d.ts", + "default": "./hex/stripPrefix.js" + }, + "require": { + "types": "./cjs/hex/stripPrefix.d.ts", + "default": "./cjs/hex/stripPrefix.js" + }, + "default": { + "types": "./hex/stripPrefix.d.ts", + "default": "./hex/stripPrefix.js" + } + }, + "./hex/toBigInt": { + "module": { + "types": "./hex/toBigInt.d.ts", + "default": "./hex/toBigInt.js" + }, + "require": { + "types": "./cjs/hex/toBigInt.d.ts", + "default": "./cjs/hex/toBigInt.js" + }, + "default": { + "types": "./hex/toBigInt.d.ts", + "default": "./hex/toBigInt.js" + } + }, + "./hex/toBn": { + "module": { + "types": "./hex/toBn.d.ts", + "default": "./hex/toBn.js" + }, + "require": { + "types": "./cjs/hex/toBn.d.ts", + "default": "./cjs/hex/toBn.js" + }, + "default": { + "types": "./hex/toBn.d.ts", + "default": "./hex/toBn.js" + } + }, + "./hex/toNumber": { + "module": { + "types": "./hex/toNumber.d.ts", + "default": "./hex/toNumber.js" + }, + "require": { + "types": "./cjs/hex/toNumber.d.ts", + "default": "./cjs/hex/toNumber.js" + }, + "default": { + "types": "./hex/toNumber.d.ts", + "default": "./hex/toNumber.js" + } + }, + "./hex/toString": { + "module": { + "types": "./hex/toString.d.ts", + "default": "./hex/toString.js" + }, + "require": { + "types": "./cjs/hex/toString.d.ts", + "default": "./cjs/hex/toString.js" + }, + "default": { + "types": "./hex/toString.d.ts", + "default": "./hex/toString.js" + } }, "./hex/toU8a": { + "module": { + "types": "./hex/toU8a.d.ts", + "default": "./hex/toU8a.js" + }, "node": { "require": "./cjs/hex/toU8aBuffer.js", "default": "./hex/toU8aBuffer.js" + }, + "require": { + "types": "./cjs/hex/toU8a.d.ts", + "default": "./cjs/hex/toU8a.js" + }, + "default": { + "types": "./hex/toU8a.d.ts", + "default": "./hex/toU8a.js" + } + }, + "./hex/toU8aBuffer": { + "module": { + "types": "./hex/toU8aBuffer.d.ts", + "default": "./hex/toU8aBuffer.js" + }, + "require": { + "types": "./cjs/hex/toU8aBuffer.d.ts", + "default": "./cjs/hex/toU8aBuffer.js" + }, + "default": { + "types": "./hex/toU8aBuffer.d.ts", + "default": "./hex/toU8aBuffer.js" + } + }, + "./is": { + "module": { + "types": "./is/index.d.ts", + "default": "./is/index.js" + }, + "require": { + "types": "./cjs/is/index.d.ts", + "default": "./cjs/is/index.js" + }, + "default": { + "types": "./is/index.d.ts", + "default": "./is/index.js" + } + }, + "./is/array": { + "module": { + "types": "./is/array.d.ts", + "default": "./is/array.js" + }, + "require": { + "types": "./cjs/is/array.d.ts", + "default": "./cjs/is/array.js" + }, + "default": { + "types": "./is/array.d.ts", + "default": "./is/array.js" + } + }, + "./is/ascii": { + "module": { + "types": "./is/ascii.d.ts", + "default": "./is/ascii.js" + }, + "require": { + "types": "./cjs/is/ascii.d.ts", + "default": "./cjs/is/ascii.js" + }, + "default": { + "types": "./is/ascii.d.ts", + "default": "./is/ascii.js" + } + }, + "./is/bigInt": { + "module": { + "types": "./is/bigInt.d.ts", + "default": "./is/bigInt.js" + }, + "require": { + "types": "./cjs/is/bigInt.d.ts", + "default": "./cjs/is/bigInt.js" + }, + "default": { + "types": "./is/bigInt.d.ts", + "default": "./is/bigInt.js" + } + }, + "./is/bn": { + "module": { + "types": "./is/bn.d.ts", + "default": "./is/bn.js" + }, + "require": { + "types": "./cjs/is/bn.d.ts", + "default": "./cjs/is/bn.js" + }, + "default": { + "types": "./is/bn.d.ts", + "default": "./is/bn.js" + } + }, + "./is/boolean": { + "module": { + "types": "./is/boolean.d.ts", + "default": "./is/boolean.js" + }, + "require": { + "types": "./cjs/is/boolean.d.ts", + "default": "./cjs/is/boolean.js" + }, + "default": { + "types": "./is/boolean.d.ts", + "default": "./is/boolean.js" + } + }, + "./is/buffer": { + "module": { + "types": "./is/buffer.d.ts", + "default": "./is/buffer.js" + }, + "require": { + "types": "./cjs/is/buffer.d.ts", + "default": "./cjs/is/buffer.js" + }, + "default": { + "types": "./is/buffer.d.ts", + "default": "./is/buffer.js" + } + }, + "./is/childClass": { + "module": { + "types": "./is/childClass.d.ts", + "default": "./is/childClass.js" + }, + "require": { + "types": "./cjs/is/childClass.d.ts", + "default": "./cjs/is/childClass.js" + }, + "default": { + "types": "./is/childClass.d.ts", + "default": "./is/childClass.js" + } + }, + "./is/class": { + "module": { + "types": "./is/class.d.ts", + "default": "./is/class.js" + }, + "require": { + "types": "./cjs/is/class.d.ts", + "default": "./cjs/is/class.js" + }, + "default": { + "types": "./is/class.d.ts", + "default": "./is/class.js" + } + }, + "./is/codec": { + "module": { + "types": "./is/codec.d.ts", + "default": "./is/codec.js" + }, + "require": { + "types": "./cjs/is/codec.d.ts", + "default": "./cjs/is/codec.js" + }, + "default": { + "types": "./is/codec.d.ts", + "default": "./is/codec.js" + } + }, + "./is/compact": { + "module": { + "types": "./is/compact.d.ts", + "default": "./is/compact.js" + }, + "require": { + "types": "./cjs/is/compact.d.ts", + "default": "./cjs/is/compact.js" + }, + "default": { + "types": "./is/compact.d.ts", + "default": "./is/compact.js" + } + }, + "./is/error": { + "module": { + "types": "./is/error.d.ts", + "default": "./is/error.js" + }, + "require": { + "types": "./cjs/is/error.d.ts", + "default": "./cjs/is/error.js" + }, + "default": { + "types": "./is/error.d.ts", + "default": "./is/error.js" + } + }, + "./is/function": { + "module": { + "types": "./is/function.d.ts", + "default": "./is/function.js" + }, + "require": { + "types": "./cjs/is/function.d.ts", + "default": "./cjs/is/function.js" + }, + "default": { + "types": "./is/function.d.ts", + "default": "./is/function.js" + } + }, + "./is/helpers": { + "module": { + "types": "./is/helpers.d.ts", + "default": "./is/helpers.js" + }, + "require": { + "types": "./cjs/is/helpers.d.ts", + "default": "./cjs/is/helpers.js" + }, + "default": { + "types": "./is/helpers.d.ts", + "default": "./is/helpers.js" + } + }, + "./is/hex": { + "module": { + "types": "./is/hex.d.ts", + "default": "./is/hex.js" + }, + "require": { + "types": "./cjs/is/hex.d.ts", + "default": "./cjs/is/hex.js" + }, + "default": { + "types": "./is/hex.d.ts", + "default": "./is/hex.js" + } + }, + "./is/instanceOf": { + "module": { + "types": "./is/instanceOf.d.ts", + "default": "./is/instanceOf.js" + }, + "require": { + "types": "./cjs/is/instanceOf.d.ts", + "default": "./cjs/is/instanceOf.js" + }, + "default": { + "types": "./is/instanceOf.d.ts", + "default": "./is/instanceOf.js" + } + }, + "./is/ip": { + "module": { + "types": "./is/ip.d.ts", + "default": "./is/ip.js" + }, + "require": { + "types": "./cjs/is/ip.d.ts", + "default": "./cjs/is/ip.js" + }, + "default": { + "types": "./is/ip.d.ts", + "default": "./is/ip.js" + } + }, + "./is/jsonObject": { + "module": { + "types": "./is/jsonObject.d.ts", + "default": "./is/jsonObject.js" + }, + "require": { + "types": "./cjs/is/jsonObject.d.ts", + "default": "./cjs/is/jsonObject.js" + }, + "default": { + "types": "./is/jsonObject.d.ts", + "default": "./is/jsonObject.js" + } + }, + "./is/null": { + "module": { + "types": "./is/null.d.ts", + "default": "./is/null.js" + }, + "require": { + "types": "./cjs/is/null.d.ts", + "default": "./cjs/is/null.js" + }, + "default": { + "types": "./is/null.d.ts", + "default": "./is/null.js" + } + }, + "./is/number": { + "module": { + "types": "./is/number.d.ts", + "default": "./is/number.js" + }, + "require": { + "types": "./cjs/is/number.d.ts", + "default": "./cjs/is/number.js" + }, + "default": { + "types": "./is/number.d.ts", + "default": "./is/number.js" + } + }, + "./is/object": { + "module": { + "types": "./is/object.d.ts", + "default": "./is/object.js" + }, + "require": { + "types": "./cjs/is/object.d.ts", + "default": "./cjs/is/object.js" + }, + "default": { + "types": "./is/object.d.ts", + "default": "./is/object.js" + } + }, + "./is/observable": { + "module": { + "types": "./is/observable.d.ts", + "default": "./is/observable.js" + }, + "require": { + "types": "./cjs/is/observable.d.ts", + "default": "./cjs/is/observable.js" + }, + "default": { + "types": "./is/observable.d.ts", + "default": "./is/observable.js" + } + }, + "./is/promise": { + "module": { + "types": "./is/promise.d.ts", + "default": "./is/promise.js" + }, + "require": { + "types": "./cjs/is/promise.d.ts", + "default": "./cjs/is/promise.js" + }, + "default": { + "types": "./is/promise.d.ts", + "default": "./is/promise.js" + } + }, + "./is/riscv": { + "module": { + "types": "./is/riscv.d.ts", + "default": "./is/riscv.js" + }, + "require": { + "types": "./cjs/is/riscv.d.ts", + "default": "./cjs/is/riscv.js" + }, + "default": { + "types": "./is/riscv.d.ts", + "default": "./is/riscv.js" + } + }, + "./is/string": { + "module": { + "types": "./is/string.d.ts", + "default": "./is/string.js" + }, + "require": { + "types": "./cjs/is/string.d.ts", + "default": "./cjs/is/string.js" + }, + "default": { + "types": "./is/string.d.ts", + "default": "./is/string.js" + } + }, + "./is/testChain": { + "module": { + "types": "./is/testChain.d.ts", + "default": "./is/testChain.js" + }, + "require": { + "types": "./cjs/is/testChain.d.ts", + "default": "./cjs/is/testChain.js" + }, + "default": { + "types": "./is/testChain.d.ts", + "default": "./is/testChain.js" + } + }, + "./is/toBigInt": { + "module": { + "types": "./is/toBigInt.d.ts", + "default": "./is/toBigInt.js" + }, + "require": { + "types": "./cjs/is/toBigInt.d.ts", + "default": "./cjs/is/toBigInt.js" + }, + "default": { + "types": "./is/toBigInt.d.ts", + "default": "./is/toBigInt.js" + } + }, + "./is/toBn": { + "module": { + "types": "./is/toBn.d.ts", + "default": "./is/toBn.js" + }, + "require": { + "types": "./cjs/is/toBn.d.ts", + "default": "./cjs/is/toBn.js" + }, + "default": { + "types": "./is/toBn.d.ts", + "default": "./is/toBn.js" + } + }, + "./is/u8a": { + "module": { + "types": "./is/u8a.d.ts", + "default": "./is/u8a.js" + }, + "require": { + "types": "./cjs/is/u8a.d.ts", + "default": "./cjs/is/u8a.js" + }, + "default": { + "types": "./is/u8a.d.ts", + "default": "./is/u8a.js" + } + }, + "./is/undefined": { + "module": { + "types": "./is/undefined.d.ts", + "default": "./is/undefined.js" + }, + "require": { + "types": "./cjs/is/undefined.d.ts", + "default": "./cjs/is/undefined.js" + }, + "default": { + "types": "./is/undefined.d.ts", + "default": "./is/undefined.js" + } + }, + "./is/utf8": { + "module": { + "types": "./is/utf8.d.ts", + "default": "./is/utf8.js" + }, + "require": { + "types": "./cjs/is/utf8.d.ts", + "default": "./cjs/is/utf8.js" + }, + "default": { + "types": "./is/utf8.d.ts", + "default": "./is/utf8.js" + } + }, + "./is/wasm": { + "module": { + "types": "./is/wasm.d.ts", + "default": "./is/wasm.js" + }, + "require": { + "types": "./cjs/is/wasm.d.ts", + "default": "./cjs/is/wasm.js" + }, + "default": { + "types": "./is/wasm.d.ts", + "default": "./is/wasm.js" + } + }, + "./lazy": { + "module": { + "types": "./lazy.d.ts", + "default": "./lazy.js" + }, + "require": { + "types": "./cjs/lazy.d.ts", + "default": "./cjs/lazy.js" + }, + "default": { + "types": "./lazy.d.ts", + "default": "./lazy.js" + } + }, + "./logger": { + "module": { + "types": "./logger.d.ts", + "default": "./logger.js" + }, + "require": { + "types": "./cjs/logger.d.ts", + "default": "./cjs/logger.js" + }, + "default": { + "types": "./logger.d.ts", + "default": "./logger.js" + } + }, + "./memoize": { + "module": { + "types": "./memoize.d.ts", + "default": "./memoize.js" + }, + "require": { + "types": "./cjs/memoize.d.ts", + "default": "./cjs/memoize.js" + }, + "default": { + "types": "./memoize.d.ts", + "default": "./memoize.js" + } + }, + "./nextTick": { + "module": { + "types": "./nextTick.d.ts", + "default": "./nextTick.js" + }, + "require": { + "types": "./cjs/nextTick.d.ts", + "default": "./cjs/nextTick.js" + }, + "default": { + "types": "./nextTick.d.ts", + "default": "./nextTick.js" + } + }, + "./noop": { + "module": { + "types": "./noop.d.ts", + "default": "./noop.js" + }, + "require": { + "types": "./cjs/noop.d.ts", + "default": "./cjs/noop.js" + }, + "default": { + "types": "./noop.d.ts", + "default": "./noop.js" + } + }, + "./number": { + "module": { + "types": "./number/index.d.ts", + "default": "./number/index.js" + }, + "require": { + "types": "./cjs/number/index.d.ts", + "default": "./cjs/number/index.js" + }, + "default": { + "types": "./number/index.d.ts", + "default": "./number/index.js" + } + }, + "./number/toHex": { + "module": { + "types": "./number/toHex.d.ts", + "default": "./number/toHex.js" + }, + "require": { + "types": "./cjs/number/toHex.d.ts", + "default": "./cjs/number/toHex.js" + }, + "default": { + "types": "./number/toHex.d.ts", + "default": "./number/toHex.js" + } + }, + "./number/toU8a": { + "module": { + "types": "./number/toU8a.d.ts", + "default": "./number/toU8a.js" + }, + "require": { + "types": "./cjs/number/toU8a.d.ts", + "default": "./cjs/number/toU8a.js" + }, + "default": { + "types": "./number/toU8a.d.ts", + "default": "./number/toU8a.js" + } + }, + "./object": { + "module": { + "types": "./object/index.d.ts", + "default": "./object/index.js" + }, + "require": { + "types": "./cjs/object/index.d.ts", + "default": "./cjs/object/index.js" + }, + "default": { + "types": "./object/index.d.ts", + "default": "./object/index.js" + } + }, + "./object/clear": { + "module": { + "types": "./object/clear.d.ts", + "default": "./object/clear.js" + }, + "require": { + "types": "./cjs/object/clear.d.ts", + "default": "./cjs/object/clear.js" + }, + "default": { + "types": "./object/clear.d.ts", + "default": "./object/clear.js" + } + }, + "./object/copy": { + "module": { + "types": "./object/copy.d.ts", + "default": "./object/copy.js" + }, + "require": { + "types": "./cjs/object/copy.d.ts", + "default": "./cjs/object/copy.js" + }, + "default": { + "types": "./object/copy.d.ts", + "default": "./object/copy.js" + } + }, + "./object/entries": { + "module": { + "types": "./object/entries.d.ts", + "default": "./object/entries.js" + }, + "require": { + "types": "./cjs/object/entries.d.ts", + "default": "./cjs/object/entries.js" + }, + "default": { + "types": "./object/entries.d.ts", + "default": "./object/entries.js" + } + }, + "./object/keys": { + "module": { + "types": "./object/keys.d.ts", + "default": "./object/keys.js" + }, + "require": { + "types": "./cjs/object/keys.d.ts", + "default": "./cjs/object/keys.js" + }, + "default": { + "types": "./object/keys.d.ts", + "default": "./object/keys.js" + } + }, + "./object/property": { + "module": { + "types": "./object/property.d.ts", + "default": "./object/property.js" + }, + "require": { + "types": "./cjs/object/property.d.ts", + "default": "./cjs/object/property.js" + }, + "default": { + "types": "./object/property.d.ts", + "default": "./object/property.js" + } + }, + "./object/spread": { + "module": { + "types": "./object/spread.d.ts", + "default": "./object/spread.js" + }, + "require": { + "types": "./cjs/object/spread.d.ts", + "default": "./cjs/object/spread.js" + }, + "default": { + "types": "./object/spread.d.ts", + "default": "./object/spread.js" + } + }, + "./object/values": { + "module": { + "types": "./object/values.d.ts", + "default": "./object/values.js" + }, + "require": { + "types": "./cjs/object/values.d.ts", + "default": "./cjs/object/values.js" + }, + "default": { + "types": "./object/values.d.ts", + "default": "./object/values.js" + } + }, + "./package.json": { + "require": "./cjs/package.json", + "default": "./package.json" + }, + "./packageDetect": { + "module": { + "types": "./packageDetect.d.ts", + "default": "./packageDetect.js" + }, + "require": { + "types": "./cjs/packageDetect.d.ts", + "default": "./cjs/packageDetect.js" + }, + "default": { + "types": "./packageDetect.d.ts", + "default": "./packageDetect.js" + } + }, + "./packageInfo.js": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./packageInfo": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./promisify": { + "module": { + "types": "./promisify.d.ts", + "default": "./promisify.js" + }, + "require": { + "types": "./cjs/promisify.d.ts", + "default": "./cjs/promisify.js" + }, + "default": { + "types": "./promisify.d.ts", + "default": "./promisify.js" + } + }, + "./string": { + "module": { + "types": "./string/index.d.ts", + "default": "./string/index.js" + }, + "require": { + "types": "./cjs/string/index.d.ts", + "default": "./cjs/string/index.js" + }, + "default": { + "types": "./string/index.d.ts", + "default": "./string/index.js" + } + }, + "./string/camelCase": { + "module": { + "types": "./string/camelCase.d.ts", + "default": "./string/camelCase.js" + }, + "require": { + "types": "./cjs/string/camelCase.d.ts", + "default": "./cjs/string/camelCase.js" + }, + "default": { + "types": "./string/camelCase.d.ts", + "default": "./string/camelCase.js" + } + }, + "./string/lowerFirst": { + "module": { + "types": "./string/lowerFirst.d.ts", + "default": "./string/lowerFirst.js" + }, + "require": { + "types": "./cjs/string/lowerFirst.d.ts", + "default": "./cjs/string/lowerFirst.js" + }, + "default": { + "types": "./string/lowerFirst.d.ts", + "default": "./string/lowerFirst.js" + } + }, + "./string/shorten": { + "module": { + "types": "./string/shorten.d.ts", + "default": "./string/shorten.js" + }, + "require": { + "types": "./cjs/string/shorten.d.ts", + "default": "./cjs/string/shorten.js" + }, + "default": { + "types": "./string/shorten.d.ts", + "default": "./string/shorten.js" + } + }, + "./string/toHex": { + "module": { + "types": "./string/toHex.d.ts", + "default": "./string/toHex.js" + }, + "require": { + "types": "./cjs/string/toHex.d.ts", + "default": "./cjs/string/toHex.js" + }, + "default": { + "types": "./string/toHex.d.ts", + "default": "./string/toHex.js" + } + }, + "./string/toU8a": { + "module": { + "types": "./string/toU8a.d.ts", + "default": "./string/toU8a.js" + }, + "require": { + "types": "./cjs/string/toU8a.d.ts", + "default": "./cjs/string/toU8a.js" + }, + "default": { + "types": "./string/toU8a.d.ts", + "default": "./string/toU8a.js" + } + }, + "./stringify": { + "module": { + "types": "./stringify.d.ts", + "default": "./stringify.js" + }, + "require": { + "types": "./cjs/stringify.d.ts", + "default": "./cjs/stringify.js" + }, + "default": { + "types": "./stringify.d.ts", + "default": "./stringify.js" + } + }, + "./types": { + "module": { + "types": "./types.d.ts", + "default": "./types.js" + }, + "require": { + "types": "./cjs/types.d.ts", + "default": "./cjs/types.js" + }, + "default": { + "types": "./types.d.ts", + "default": "./types.js" + } + }, + "./u8a": { + "module": { + "types": "./u8a/index.d.ts", + "default": "./u8a/index.js" + }, + "require": { + "types": "./cjs/u8a/index.d.ts", + "default": "./cjs/u8a/index.js" + }, + "default": { + "types": "./u8a/index.d.ts", + "default": "./u8a/index.js" + } + }, + "./u8a/cmp": { + "module": { + "types": "./u8a/cmp.d.ts", + "default": "./u8a/cmp.js" + }, + "require": { + "types": "./cjs/u8a/cmp.d.ts", + "default": "./cjs/u8a/cmp.js" + }, + "default": { + "types": "./u8a/cmp.d.ts", + "default": "./u8a/cmp.js" + } + }, + "./u8a/concat": { + "module": { + "types": "./u8a/concat.d.ts", + "default": "./u8a/concat.js" + }, + "require": { + "types": "./cjs/u8a/concat.d.ts", + "default": "./cjs/u8a/concat.js" + }, + "default": { + "types": "./u8a/concat.d.ts", + "default": "./u8a/concat.js" + } + }, + "./u8a/concatBuffer": { + "module": { + "types": "./u8a/concatBuffer.d.ts", + "default": "./u8a/concatBuffer.js" + }, + "require": { + "types": "./cjs/u8a/concatBuffer.d.ts", + "default": "./cjs/u8a/concatBuffer.js" + }, + "default": { + "types": "./u8a/concatBuffer.d.ts", + "default": "./u8a/concatBuffer.js" + } + }, + "./u8a/empty": { + "module": { + "types": "./u8a/empty.d.ts", + "default": "./u8a/empty.js" + }, + "require": { + "types": "./cjs/u8a/empty.d.ts", + "default": "./cjs/u8a/empty.js" + }, + "default": { + "types": "./u8a/empty.d.ts", + "default": "./u8a/empty.js" + } + }, + "./u8a/eq": { + "module": { + "types": "./u8a/eq.d.ts", + "default": "./u8a/eq.js" + }, + "require": { + "types": "./cjs/u8a/eq.d.ts", + "default": "./cjs/u8a/eq.js" + }, + "default": { + "types": "./u8a/eq.d.ts", + "default": "./u8a/eq.js" + } + }, + "./u8a/fixLength": { + "module": { + "types": "./u8a/fixLength.d.ts", + "default": "./u8a/fixLength.js" + }, + "require": { + "types": "./cjs/u8a/fixLength.d.ts", + "default": "./cjs/u8a/fixLength.js" + }, + "default": { + "types": "./u8a/fixLength.d.ts", + "default": "./u8a/fixLength.js" + } + }, + "./u8a/sorted": { + "module": { + "types": "./u8a/sorted.d.ts", + "default": "./u8a/sorted.js" + }, + "require": { + "types": "./cjs/u8a/sorted.d.ts", + "default": "./cjs/u8a/sorted.js" + }, + "default": { + "types": "./u8a/sorted.d.ts", + "default": "./u8a/sorted.js" + } + }, + "./u8a/toBigInt": { + "module": { + "types": "./u8a/toBigInt.d.ts", + "default": "./u8a/toBigInt.js" + }, + "require": { + "types": "./cjs/u8a/toBigInt.d.ts", + "default": "./cjs/u8a/toBigInt.js" + }, + "default": { + "types": "./u8a/toBigInt.d.ts", + "default": "./u8a/toBigInt.js" + } + }, + "./u8a/toBn": { + "module": { + "types": "./u8a/toBn.d.ts", + "default": "./u8a/toBn.js" + }, + "require": { + "types": "./cjs/u8a/toBn.d.ts", + "default": "./cjs/u8a/toBn.js" + }, + "default": { + "types": "./u8a/toBn.d.ts", + "default": "./u8a/toBn.js" + } + }, + "./u8a/toBuffer": { + "module": { + "types": "./u8a/toBuffer.d.ts", + "default": "./u8a/toBuffer.js" + }, + "require": { + "types": "./cjs/u8a/toBuffer.d.ts", + "default": "./cjs/u8a/toBuffer.js" + }, + "default": { + "types": "./u8a/toBuffer.d.ts", + "default": "./u8a/toBuffer.js" + } + }, + "./u8a/toFloat": { + "module": { + "types": "./u8a/toFloat.d.ts", + "default": "./u8a/toFloat.js" + }, + "require": { + "types": "./cjs/u8a/toFloat.d.ts", + "default": "./cjs/u8a/toFloat.js" + }, + "default": { + "types": "./u8a/toFloat.d.ts", + "default": "./u8a/toFloat.js" } }, "./u8a/toHex": { + "module": { + "types": "./u8a/toHex.d.ts", + "default": "./u8a/toHex.js" + }, "node": { "require": "./cjs/u8a/toHexBuffer.js", "default": "./u8a/toHexBuffer.js" + }, + "require": { + "types": "./cjs/u8a/toHex.d.ts", + "default": "./cjs/u8a/toHex.js" + }, + "default": { + "types": "./u8a/toHex.d.ts", + "default": "./u8a/toHex.js" + } + }, + "./u8a/toHexBuffer": { + "module": { + "types": "./u8a/toHexBuffer.d.ts", + "default": "./u8a/toHexBuffer.js" + }, + "require": { + "types": "./cjs/u8a/toHexBuffer.d.ts", + "default": "./cjs/u8a/toHexBuffer.js" + }, + "default": { + "types": "./u8a/toHexBuffer.d.ts", + "default": "./u8a/toHexBuffer.js" + } + }, + "./u8a/toNumber": { + "module": { + "types": "./u8a/toNumber.d.ts", + "default": "./u8a/toNumber.js" + }, + "require": { + "types": "./cjs/u8a/toNumber.d.ts", + "default": "./cjs/u8a/toNumber.js" + }, + "default": { + "types": "./u8a/toNumber.d.ts", + "default": "./u8a/toNumber.js" + } + }, + "./u8a/toString": { + "module": { + "types": "./u8a/toString.d.ts", + "default": "./u8a/toString.js" + }, + "require": { + "types": "./cjs/u8a/toString.d.ts", + "default": "./cjs/u8a/toString.js" + }, + "default": { + "types": "./u8a/toString.d.ts", + "default": "./u8a/toString.js" + } + }, + "./u8a/toU8a": { + "module": { + "types": "./u8a/toU8a.d.ts", + "default": "./u8a/toU8a.js" + }, + "require": { + "types": "./cjs/u8a/toU8a.d.ts", + "default": "./cjs/u8a/toU8a.js" + }, + "default": { + "types": "./u8a/toU8a.d.ts", + "default": "./u8a/toU8a.js" + } + }, + "./u8a/wrap": { + "module": { + "types": "./u8a/wrap.d.ts", + "default": "./u8a/wrap.js" + }, + "require": { + "types": "./cjs/u8a/wrap.d.ts", + "default": "./cjs/u8a/wrap.js" + }, + "default": { + "types": "./u8a/wrap.d.ts", + "default": "./u8a/wrap.js" } } }, "dependencies": { - "@pezkuwi/x-bigint": "workspace:*", - "@pezkuwi/x-global": "workspace:*", - "@pezkuwi/x-textdecoder": "workspace:*", - "@pezkuwi/x-textencoder": "workspace:*", + "@pezkuwi/x-bigint": "14.0.11", + "@pezkuwi/x-global": "14.0.11", + "@pezkuwi/x-textdecoder": "14.0.11", + "@pezkuwi/x-textencoder": "14.0.11", "@types/bn.js": "^5.1.6", "bn.js": "^5.2.1", "tslib": "^2.8.0" - }, - "devDependencies": { - "@pezkuwi/x-randomvalues": "workspace:*" } } diff --git a/packages/util/packageDetect.d.ts b/packages/util/packageDetect.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/util/packageDetect.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/util/packageDetect.js b/packages/util/packageDetect.js new file mode 100644 index 0000000..bf633e1 --- /dev/null +++ b/packages/util/packageDetect.js @@ -0,0 +1,5 @@ +import { packageInfo as decoderInfo } from '@pezkuwi/x-textdecoder'; +import { packageInfo as encoderInfo } from '@pezkuwi/x-textencoder'; +import { detectPackage } from './detectPackage.js'; +import { packageInfo } from './packageInfo.js'; +detectPackage(packageInfo, null, [decoderInfo, encoderInfo]); diff --git a/packages/util/packageInfo.d.ts b/packages/util/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/util/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/util/packageInfo.js b/packages/util/packageInfo.js new file mode 100644 index 0000000..ac04478 --- /dev/null +++ b/packages/util/packageInfo.js @@ -0,0 +1 @@ +export const packageInfo = { name: '@pezkuwi/util', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; diff --git a/packages/util/promisify.d.ts b/packages/util/promisify.d.ts new file mode 100644 index 0000000..c1345d3 --- /dev/null +++ b/packages/util/promisify.d.ts @@ -0,0 +1,16 @@ +/** + * @name promisify + * @summary Wraps an async callback into a `Promise` + * @description + * Wraps the supplied async function `fn` that has a standard JS callback `(error: Error, result: any)` into a `Promise`, passing the supplied parameters. When `error` is set, the Promise is rejected, else the Promise resolves with the `result` value. + * @example + *
+ * + * ```javascript + * const { promisify } from '@pezkuwi/util'; + * + * await promisify(null, ((a, cb) => cb(null, a), true); // resolves with `true` + * await promisify(null, (cb) => cb(new Error('error!'))); // rejects with `error!` + * ``` + */ +export declare function promisify(self: unknown, fn: (...params: any[]) => any, ...params: any[]): Promise; diff --git a/packages/util/promisify.js b/packages/util/promisify.js new file mode 100644 index 0000000..8806708 --- /dev/null +++ b/packages/util/promisify.js @@ -0,0 +1,27 @@ +/** + * @name promisify + * @summary Wraps an async callback into a `Promise` + * @description + * Wraps the supplied async function `fn` that has a standard JS callback `(error: Error, result: any)` into a `Promise`, passing the supplied parameters. When `error` is set, the Promise is rejected, else the Promise resolves with the `result` value. + * @example + *
+ * + * ```javascript + * const { promisify } from '@pezkuwi/util'; + * + * await promisify(null, ((a, cb) => cb(null, a), true); // resolves with `true` + * await promisify(null, (cb) => cb(new Error('error!'))); // rejects with `error!` + * ``` + */ +export function promisify(self, fn, ...params) { + return new Promise((resolve, reject) => { + fn.apply(self, params.concat((error, result) => { + if (error) { + reject(error); + } + else { + resolve(result); + } + })); + }); +} diff --git a/packages/util/string/camelCase.d.ts b/packages/util/string/camelCase.d.ts new file mode 100644 index 0000000..81aa34a --- /dev/null +++ b/packages/util/string/camelCase.d.ts @@ -0,0 +1,13 @@ +import type { AnyString } from '../types.js'; +export declare const CC_TO_UP: string[]; +export declare const CC_TO_LO: string[]; +/** + * @name stringCamelCase + * @summary Convert a dash/dot/underscore/space separated Ascii string/String to camelCase + */ +export declare const stringCamelCase: (value: AnyString) => string; +/** + * @name stringPascalCase + * @summary Convert a dash/dot/underscore/space separated Ascii string/String to PascalCase + */ +export declare const stringPascalCase: (value: AnyString) => string; diff --git a/packages/util/string/camelCase.js b/packages/util/string/camelCase.js new file mode 100644 index 0000000..658bba1 --- /dev/null +++ b/packages/util/string/camelCase.js @@ -0,0 +1,59 @@ +export const CC_TO_UP = new Array(256); +export const CC_TO_LO = new Array(256); +for (let i = 0, count = CC_TO_UP.length; i < count; i++) { + CC_TO_LO[i] = String.fromCharCode(i).toLowerCase(); + CC_TO_UP[i] = String.fromCharCode(i).toUpperCase(); +} +/** @internal */ +function formatAllCaps(w) { + return w.slice(0, w.length - 1).toLowerCase() + CC_TO_UP[w.charCodeAt(w.length - 1)]; +} +/** + * @internal + * + * Inspired by https://stackoverflow.com/a/2970667 + * + * This is not as optimal as the original SO answer (we split into per-word), + * however it does pass the tests (which the SO version doesn't) and is still + * a major improvement over the original camelcase npm package - + * + * camelcase: 20.88 μs/op + * this: 1.00 μs/op + * + * Caveat of this: only Ascii, but acceptable for the intended usecase + */ +function converter(format) { + return (value) => { + const parts = value + // replace all separators (including consequtive) with spaces + .replace(/[-_., ]+/g, ' ') + // we don't want leading or trailing spaces + .trim() + // split into words + .split(' '); + let result = ''; + for (let i = 0, count = parts.length; i < count; i++) { + const w = parts[i]; + // apply the formatting + result += format(/^[\dA-Z]+$/.test(w) + // all full uppercase + letters are changed to lowercase + ? w.toLowerCase() + // all consecutive capitals + letters are changed to lowercase + // e.g. UUID64 -> uuid64, while preserving splits, eg. NFTOrder -> nftOrder + : w.replace(/^[\dA-Z]{2,}[^a-z]/, formatAllCaps), i); + } + return result; + }; +} +/** + * @name stringCamelCase + * @summary Convert a dash/dot/underscore/space separated Ascii string/String to camelCase + */ +export const stringCamelCase = /*#__PURE__*/ converter((w, i) => +(i ? CC_TO_UP[w.charCodeAt(0)] : CC_TO_LO[w.charCodeAt(0)]) + w.slice(1)); +/** + * @name stringPascalCase + * @summary Convert a dash/dot/underscore/space separated Ascii string/String to PascalCase + */ +export const stringPascalCase = /*#__PURE__*/ converter((w) => +CC_TO_UP[w.charCodeAt(0)] + w.slice(1)); diff --git a/packages/util/string/index.d.ts b/packages/util/string/index.d.ts new file mode 100644 index 0000000..b7237d5 --- /dev/null +++ b/packages/util/string/index.d.ts @@ -0,0 +1,8 @@ +/** + * @summary Utility methods to convert to work with `string` values + */ +export { stringCamelCase, stringPascalCase } from './camelCase.js'; +export { stringLowerFirst, stringUpperFirst } from './lowerFirst.js'; +export { stringShorten } from './shorten.js'; +export { stringToHex } from './toHex.js'; +export { stringToU8a } from './toU8a.js'; diff --git a/packages/util/string/index.js b/packages/util/string/index.js new file mode 100644 index 0000000..b7237d5 --- /dev/null +++ b/packages/util/string/index.js @@ -0,0 +1,8 @@ +/** + * @summary Utility methods to convert to work with `string` values + */ +export { stringCamelCase, stringPascalCase } from './camelCase.js'; +export { stringLowerFirst, stringUpperFirst } from './lowerFirst.js'; +export { stringShorten } from './shorten.js'; +export { stringToHex } from './toHex.js'; +export { stringToU8a } from './toU8a.js'; diff --git a/packages/util/string/lowerFirst.d.ts b/packages/util/string/lowerFirst.d.ts new file mode 100644 index 0000000..4c10d35 --- /dev/null +++ b/packages/util/string/lowerFirst.d.ts @@ -0,0 +1,31 @@ +import type { AnyString } from '../types.js'; +/** + * @name stringLowerFirst + * @summary Lowercase the first letter of a string + * @description + * Lowercase the first letter of a string + * @example + *
+ * + * ```javascript + * import { stringLowerFirst } from '@pezkuwi/util'; + * + * stringLowerFirst('ABC'); // => 'aBC' + * ``` + */ +export declare const stringLowerFirst: (value?: AnyString | null) => string; +/** + * @name stringUpperFirst + * @summary Uppercase the first letter of a string + * @description + * Lowercase the first letter of a string + * @example + *
+ * + * ```javascript + * import { stringUpperFirst } from '@pezkuwi/util'; + * + * stringUpperFirst('abc'); // => 'Abc' + * ``` + */ +export declare const stringUpperFirst: (value?: AnyString | null) => string; diff --git a/packages/util/string/lowerFirst.js b/packages/util/string/lowerFirst.js new file mode 100644 index 0000000..87b6941 --- /dev/null +++ b/packages/util/string/lowerFirst.js @@ -0,0 +1,37 @@ +import { CC_TO_LO, CC_TO_UP } from './camelCase.js'; +/** @internal */ +function converter(map) { + return (value) => value + ? map[value.charCodeAt(0)] + value.slice(1) + : ''; +} +/** + * @name stringLowerFirst + * @summary Lowercase the first letter of a string + * @description + * Lowercase the first letter of a string + * @example + *
+ * + * ```javascript + * import { stringLowerFirst } from '@pezkuwi/util'; + * + * stringLowerFirst('ABC'); // => 'aBC' + * ``` + */ +export const stringLowerFirst = /*#__PURE__*/ converter(CC_TO_LO); +/** + * @name stringUpperFirst + * @summary Uppercase the first letter of a string + * @description + * Lowercase the first letter of a string + * @example + *
+ * + * ```javascript + * import { stringUpperFirst } from '@pezkuwi/util'; + * + * stringUpperFirst('abc'); // => 'Abc' + * ``` + */ +export const stringUpperFirst = /*#__PURE__*/ converter(CC_TO_UP); diff --git a/packages/util/string/shorten.d.ts b/packages/util/string/shorten.d.ts new file mode 100644 index 0000000..ca3cfec --- /dev/null +++ b/packages/util/string/shorten.d.ts @@ -0,0 +1,16 @@ +import type { AnyString } from '../types.js'; +/** + * @name stringShorten + * @summary Returns a string with maximum length + * @description + * Checks the string against the `prefixLength`, if longer than double this, shortens it by placing `..` in the middle of it + * @example + *
+ * + * ```javascript + * import { stringShorten } from '@pezkuwi/util'; + * + * stringShorten('1234567890', 2); // => 12..90 + * ``` + */ +export declare function stringShorten(value: AnyString, prefixLength?: number): string; diff --git a/packages/util/string/shorten.js b/packages/util/string/shorten.js new file mode 100644 index 0000000..072ef4e --- /dev/null +++ b/packages/util/string/shorten.js @@ -0,0 +1,19 @@ +/** + * @name stringShorten + * @summary Returns a string with maximum length + * @description + * Checks the string against the `prefixLength`, if longer than double this, shortens it by placing `..` in the middle of it + * @example + *
+ * + * ```javascript + * import { stringShorten } from '@pezkuwi/util'; + * + * stringShorten('1234567890', 2); // => 12..90 + * ``` + */ +export function stringShorten(value, prefixLength = 6) { + return value.length <= 2 + 2 * prefixLength + ? value.toString() + : `${value.substring(0, prefixLength)}…${value.slice(-prefixLength)}`; +} diff --git a/packages/util/string/toHex.d.ts b/packages/util/string/toHex.d.ts new file mode 100644 index 0000000..beea8fb --- /dev/null +++ b/packages/util/string/toHex.d.ts @@ -0,0 +1,16 @@ +import type { AnyString, HexString } from '../types.js'; +/** + * @name stringToHex + * @summary Creates a hex string from a utf-8 string + * @description + * String input values return the actual encoded hex value. + * @example + *
+ * + * ```javascript + * import { stringToHex } from '@pezkuwi/util'; + * + * stringToU8a('hello'); // 0x68656c6c6f + * ``` + */ +export declare function stringToHex(value?: AnyString): HexString; diff --git a/packages/util/string/toHex.js b/packages/util/string/toHex.js new file mode 100644 index 0000000..3ab5248 --- /dev/null +++ b/packages/util/string/toHex.js @@ -0,0 +1,19 @@ +import { u8aToHex } from '../u8a/toHex.js'; +import { stringToU8a } from './toU8a.js'; +/** + * @name stringToHex + * @summary Creates a hex string from a utf-8 string + * @description + * String input values return the actual encoded hex value. + * @example + *
+ * + * ```javascript + * import { stringToHex } from '@pezkuwi/util'; + * + * stringToU8a('hello'); // 0x68656c6c6f + * ``` + */ +export function stringToHex(value) { + return u8aToHex(stringToU8a(value)); +} diff --git a/packages/util/string/toU8a.d.ts b/packages/util/string/toU8a.d.ts new file mode 100644 index 0000000..7c0a8ce --- /dev/null +++ b/packages/util/string/toU8a.d.ts @@ -0,0 +1,16 @@ +import type { AnyString } from '../types.js'; +/** + * @name stringToU8a + * @summary Creates a Uint8Array object from a utf-8 string. + * @description + * String input values return the actual encoded `UInt8Array`. `null` or `undefined` values returns an empty encoded array. + * @example + *
+ * + * ```javascript + * import { stringToU8a } from '@pezkuwi/util'; + * + * stringToU8a('hello'); // [0x68, 0x65, 0x6c, 0x6c, 0x6f] + * ``` + */ +export declare function stringToU8a(value?: AnyString | null): Uint8Array; diff --git a/packages/util/string/toU8a.js b/packages/util/string/toU8a.js new file mode 100644 index 0000000..996e7f3 --- /dev/null +++ b/packages/util/string/toU8a.js @@ -0,0 +1,21 @@ +import { TextEncoder } from '@pezkuwi/x-textencoder'; +const encoder = new TextEncoder(); +/** + * @name stringToU8a + * @summary Creates a Uint8Array object from a utf-8 string. + * @description + * String input values return the actual encoded `UInt8Array`. `null` or `undefined` values returns an empty encoded array. + * @example + *
+ * + * ```javascript + * import { stringToU8a } from '@pezkuwi/util'; + * + * stringToU8a('hello'); // [0x68, 0x65, 0x6c, 0x6c, 0x6f] + * ``` + */ +export function stringToU8a(value) { + return value + ? encoder.encode(value.toString()) + : new Uint8Array(); +} diff --git a/packages/util/stringify.d.ts b/packages/util/stringify.d.ts new file mode 100644 index 0000000..0d1c501 --- /dev/null +++ b/packages/util/stringify.d.ts @@ -0,0 +1,6 @@ +/** + * @name stringify + * @summary Performs a JSON.stringify, with BigInt handling + * @description A wrapper for JSON.stringify that handles BigInt values transparently, converting them to string. No differences from the native JSON.stringify function otherwise. + */ +export declare function stringify(value: unknown, space?: string | number): string; diff --git a/packages/util/stringify.js b/packages/util/stringify.js new file mode 100644 index 0000000..402d0c1 --- /dev/null +++ b/packages/util/stringify.js @@ -0,0 +1,15 @@ +import { isBigInt } from './is/bigInt.js'; +/** @internal */ +function replacer(_, v) { + return isBigInt(v) + ? v.toString() + : v; +} +/** + * @name stringify + * @summary Performs a JSON.stringify, with BigInt handling + * @description A wrapper for JSON.stringify that handles BigInt values transparently, converting them to string. No differences from the native JSON.stringify function otherwise. + */ +export function stringify(value, space) { + return JSON.stringify(value, replacer, space); +} diff --git a/packages/util/types.d.ts b/packages/util/types.d.ts new file mode 100644 index 0000000..b08d4b6 --- /dev/null +++ b/packages/util/types.d.ts @@ -0,0 +1,62 @@ +import type { BN } from './bn/bn.js'; +/** An interface that defines an actual JS class */ +export interface Class { + prototype: T; + new (...args: A): T; + hasOwnProperty(prop: string): boolean; + isPrototypeOf(other: unknown): boolean; +} +export type Constructor = Class; +export interface ToBigInt { + toBigInt: () => bigint; +} +export interface ToBn { + toBn: () => BN; +} +export interface SiDef { + power: number; + text: string; + value: string; +} +export interface Logger { + debug: (...values: unknown[]) => void; + error: (...values: unknown[]) => void; + log: (...values: unknown[]) => void; + noop: (...values: unknown[]) => void; + warn: (...values: unknown[]) => void; +} +export interface ToBnOptions { + /** Convert in LE format */ + isLe?: boolean; + /** Number is signed, apply two's complement */ + isNegative?: boolean; +} +export interface NumberOptions extends ToBnOptions { + /** Limit to the specified bitLength, despite input length */ + bitLength?: number; +} +export interface Time { + days: number; + hours: number; + minutes: number; + seconds: number; + milliseconds: number; +} +export type Memoized = F & { + unmemoize: (...args: unknown[]) => void; +}; +export type AnyString = string | String; +export type HexDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f'; +export type HexString = `0x${string}`; +export interface BufferObject extends Uint8Array { + equals: (otherBuffer: Uint8Array) => boolean; + readDoubleLE: (offset?: number) => number; +} +export interface BufferClass extends Class { + from: (value: unknown) => T; + isBuffer: (value: unknown) => boolean; +} +export type U8aLike = number[] | Uint8Array | AnyString; +export interface Observable { + next: (...params: unknown[]) => unknown; +} diff --git a/packages/util/types.js b/packages/util/types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/util/types.js @@ -0,0 +1 @@ +export {}; diff --git a/packages/util/u8a/cmp.d.ts b/packages/util/u8a/cmp.d.ts new file mode 100644 index 0000000..9b5ce92 --- /dev/null +++ b/packages/util/u8a/cmp.d.ts @@ -0,0 +1,17 @@ +/** + * @name u8aCmp + * @summary Compares two Uint8Arrays for sorting. + * @description + * For `UInt8Array` (or hex string) input values returning -1, 0 or +1 + * @example + *
+ * + * ```javascript + * import { u8aCmp } from '@pezkuwi/util'; + * + * u8aCmp(new Uint8Array([0x67, 0x65]), new Uint8Array([0x68, 0x65])); // -1 + * u8aCmp(new Uint8Array([0x68, 0x65]), new Uint8Array([0x68, 0x65])); // 0 + * u8aCmp(new Uint8Array([0x69, 0x65]), new Uint8Array([0x68, 0x65])); // +1 + * ``` + */ +export declare function u8aCmp(a: string | Uint8Array, b: string | Uint8Array): number; diff --git a/packages/util/u8a/cmp.js b/packages/util/u8a/cmp.js new file mode 100644 index 0000000..87e5555 --- /dev/null +++ b/packages/util/u8a/cmp.js @@ -0,0 +1,46 @@ +import { u8aToU8a } from './toU8a.js'; +/** + * @name u8aCmp + * @summary Compares two Uint8Arrays for sorting. + * @description + * For `UInt8Array` (or hex string) input values returning -1, 0 or +1 + * @example + *
+ * + * ```javascript + * import { u8aCmp } from '@pezkuwi/util'; + * + * u8aCmp(new Uint8Array([0x67, 0x65]), new Uint8Array([0x68, 0x65])); // -1 + * u8aCmp(new Uint8Array([0x68, 0x65]), new Uint8Array([0x68, 0x65])); // 0 + * u8aCmp(new Uint8Array([0x69, 0x65]), new Uint8Array([0x68, 0x65])); // +1 + * ``` + */ +export function u8aCmp(a, b) { + const u8aa = u8aToU8a(a); + const u8ab = u8aToU8a(b); + let i = 0; + while (true) { + const overA = i >= u8aa.length; + const overB = i >= u8ab.length; + if (overA && overB) { + // both ends reached + return 0; + } + else if (overA) { + // a has no more data, b has data + return -1; + } + else if (overB) { + // b has no more data, a has data + return 1; + } + else if (u8aa[i] !== u8ab[i]) { + // the number in this index doesn't match + // (we don't use u8aa[i] - u8ab[i] since that doesn't match with localeCompare) + return u8aa[i] > u8ab[i] + ? 1 + : -1; + } + i++; + } +} diff --git a/packages/util/u8a/concat.d.ts b/packages/util/u8a/concat.d.ts new file mode 100644 index 0000000..7413e0b --- /dev/null +++ b/packages/util/u8a/concat.d.ts @@ -0,0 +1,24 @@ +import type { U8aLike } from '../types.js'; +/** + * @name u8aConcat + * @summary Creates a concatenated Uint8Array from the inputs. + * @description + * Concatenates the input arrays into a single `UInt8Array`. + * @example + *
+ * + * ```javascript + * import { { u8aConcat } from '@pezkuwi/util'; + * + * u8aConcat( + * new Uint8Array([1, 2, 3]), + * new Uint8Array([4, 5, 6]) + * ); // [1, 2, 3, 4, 5, 6] + * ``` + */ +export declare function u8aConcat(...list: readonly U8aLike[]): Uint8Array; +/** + * @name u8aConcatStrict + * @description A strict version of [[u8aConcat]], accepting only Uint8Array inputs + */ +export declare function u8aConcatStrict(u8as: readonly Uint8Array[], length?: number): Uint8Array; diff --git a/packages/util/u8a/concat.js b/packages/util/u8a/concat.js new file mode 100644 index 0000000..8059703 --- /dev/null +++ b/packages/util/u8a/concat.js @@ -0,0 +1,47 @@ +import { u8aToU8a } from './toU8a.js'; +/** + * @name u8aConcat + * @summary Creates a concatenated Uint8Array from the inputs. + * @description + * Concatenates the input arrays into a single `UInt8Array`. + * @example + *
+ * + * ```javascript + * import { { u8aConcat } from '@pezkuwi/util'; + * + * u8aConcat( + * new Uint8Array([1, 2, 3]), + * new Uint8Array([4, 5, 6]) + * ); // [1, 2, 3, 4, 5, 6] + * ``` + */ +export function u8aConcat(...list) { + const count = list.length; + const u8as = new Array(count); + let length = 0; + for (let i = 0; i < count; i++) { + u8as[i] = u8aToU8a(list[i]); + length += u8as[i].length; + } + return u8aConcatStrict(u8as, length); +} +/** + * @name u8aConcatStrict + * @description A strict version of [[u8aConcat]], accepting only Uint8Array inputs + */ +export function u8aConcatStrict(u8as, length = 0) { + const count = u8as.length; + let offset = 0; + if (!length) { + for (let i = 0; i < count; i++) { + length += u8as[i].length; + } + } + const result = new Uint8Array(length); + for (let i = 0; i < count; i++) { + result.set(u8as[i], offset); + offset += u8as[i].length; + } + return result; +} diff --git a/packages/util/u8a/concatBuffer.d.ts b/packages/util/u8a/concatBuffer.d.ts new file mode 100644 index 0000000..657bf81 --- /dev/null +++ b/packages/util/u8a/concatBuffer.d.ts @@ -0,0 +1,19 @@ +import type { U8aLike } from '../types.js'; +/** + * @name u8aConcat + * @summary Creates a concatenated Uint8Array from the inputs. + * @description + * Concatenates the input arrays into a single `UInt8Array`. + * @example + *
+ * + * ```javascript + * import { { u8aConcat } from '@pezkuwi/util'; + * + * u8aConcat( + * new Uint8Array([1, 2, 3]), + * new Uint8Array([4, 5, 6]) + * ); // [1, 2, 3, 4, 5, 6] + * ``` + */ +export declare function u8aConcat(...list: readonly U8aLike[]): Uint8Array; diff --git a/packages/util/u8a/concatBuffer.js b/packages/util/u8a/concatBuffer.js new file mode 100644 index 0000000..5a127e8 --- /dev/null +++ b/packages/util/u8a/concatBuffer.js @@ -0,0 +1,26 @@ +import { u8aToU8a } from './toU8a.js'; +/** + * @name u8aConcat + * @summary Creates a concatenated Uint8Array from the inputs. + * @description + * Concatenates the input arrays into a single `UInt8Array`. + * @example + *
+ * + * ```javascript + * import { { u8aConcat } from '@pezkuwi/util'; + * + * u8aConcat( + * new Uint8Array([1, 2, 3]), + * new Uint8Array([4, 5, 6]) + * ); // [1, 2, 3, 4, 5, 6] + * ``` + */ +export function u8aConcat(...list) { + const count = list.length; + const u8as = new Array(count); + for (let i = 0; i < count; i++) { + u8as[i] = u8aToU8a(list[i]); + } + return Uint8Array.from(Buffer.concat(u8as)); +} diff --git a/packages/util/u8a/empty.d.ts b/packages/util/u8a/empty.d.ts new file mode 100644 index 0000000..535949d --- /dev/null +++ b/packages/util/u8a/empty.d.ts @@ -0,0 +1,7 @@ +/** + * @name u8aEmpty + * @summary Tests for a `Uint8Array` for emptyness + * @description + * Checks to see if the input `Uint8Array` has zero length or contains all 0 values. + */ +export declare function u8aEmpty(value: Uint8Array): boolean; diff --git a/packages/util/u8a/empty.js b/packages/util/u8a/empty.js new file mode 100644 index 0000000..1d3abab --- /dev/null +++ b/packages/util/u8a/empty.js @@ -0,0 +1,17 @@ +/** + * @name u8aEmpty + * @summary Tests for a `Uint8Array` for emptyness + * @description + * Checks to see if the input `Uint8Array` has zero length or contains all 0 values. + */ +export function u8aEmpty(value) { + const len = value.length | 0; + // on smaller sizes, the byte-by-byte compare is faster than allocating + // another object for DataView (on very large arrays the DataView is faster) + for (let i = 0; i < len; i++) { + if (value[i] | 0) { + return false; + } + } + return true; +} diff --git a/packages/util/u8a/eq.d.ts b/packages/util/u8a/eq.d.ts new file mode 100644 index 0000000..2ee4ad2 --- /dev/null +++ b/packages/util/u8a/eq.d.ts @@ -0,0 +1,15 @@ +/** + * @name u8aEq + * @summary Compares two Uint8Arrays for equality. + * @description + * For `UInt8Array` (or hex string) input values true if there is a match. + * @example + *
+ * + * ```javascript + * import { u8aEq } from '@pezkuwi/util'; + * + * u8aEq(new Uint8Array([0x68, 0x65]), new Uint8Array([0x68, 0x65])); // true + * ``` + */ +export declare function u8aEq(a: string | Uint8Array, b: string | Uint8Array): boolean; diff --git a/packages/util/u8a/eq.js b/packages/util/u8a/eq.js new file mode 100644 index 0000000..850d89f --- /dev/null +++ b/packages/util/u8a/eq.js @@ -0,0 +1,37 @@ +import { u8aToU8a } from './toU8a.js'; +/** + * @name u8aEq + * @summary Compares two Uint8Arrays for equality. + * @description + * For `UInt8Array` (or hex string) input values true if there is a match. + * @example + *
+ * + * ```javascript + * import { u8aEq } from '@pezkuwi/util'; + * + * u8aEq(new Uint8Array([0x68, 0x65]), new Uint8Array([0x68, 0x65])); // true + * ``` + */ +export function u8aEq(a, b) { + const u8aa = u8aToU8a(a); + const u8ab = u8aToU8a(b); + if (u8aa.length === u8ab.length) { + const dvA = new DataView(u8aa.buffer, u8aa.byteOffset); + const dvB = new DataView(u8ab.buffer, u8ab.byteOffset); + const mod = (u8aa.length % 4) | 0; + const length = (u8aa.length - mod) | 0; + for (let i = 0; i < length; i += 4) { + if (dvA.getUint32(i) !== dvB.getUint32(i)) { + return false; + } + } + for (let i = length, count = u8aa.length; i < count; i++) { + if (u8aa[i] !== u8ab[i]) { + return false; + } + } + return true; + } + return false; +} diff --git a/packages/util/u8a/fixLength.d.ts b/packages/util/u8a/fixLength.d.ts new file mode 100644 index 0000000..e13ebc9 --- /dev/null +++ b/packages/util/u8a/fixLength.d.ts @@ -0,0 +1,17 @@ +/** + * @name u8aFixLength + * @summary Shifts a Uint8Array to a specific bitLength + * @description + * Returns a uint8Array with the specified number of bits contained in the return value. (If bitLength is -1, length checking is not done). Values with more bits are trimmed to the specified length. + * @example + *
+ * + * ```javascript + * import { u8aFixLength } from '@pezkuwi/util'; + * + * u8aFixLength('0x12') // => 0x12 + * u8aFixLength('0x12', 16) // => 0x0012 + * u8aFixLength('0x1234', 8) // => 0x12 + * ``` + */ +export declare function u8aFixLength(value: Uint8Array, bitLength?: number, atStart?: boolean): Uint8Array; diff --git a/packages/util/u8a/fixLength.js b/packages/util/u8a/fixLength.js new file mode 100644 index 0000000..9997583 --- /dev/null +++ b/packages/util/u8a/fixLength.js @@ -0,0 +1,28 @@ +/** + * @name u8aFixLength + * @summary Shifts a Uint8Array to a specific bitLength + * @description + * Returns a uint8Array with the specified number of bits contained in the return value. (If bitLength is -1, length checking is not done). Values with more bits are trimmed to the specified length. + * @example + *
+ * + * ```javascript + * import { u8aFixLength } from '@pezkuwi/util'; + * + * u8aFixLength('0x12') // => 0x12 + * u8aFixLength('0x12', 16) // => 0x0012 + * u8aFixLength('0x1234', 8) // => 0x12 + * ``` + */ +export function u8aFixLength(value, bitLength = -1, atStart = false) { + const byteLength = Math.ceil(bitLength / 8); + if (bitLength === -1 || value.length === byteLength) { + return value; + } + else if (value.length > byteLength) { + return value.subarray(0, byteLength); + } + const result = new Uint8Array(byteLength); + result.set(value, atStart ? 0 : (byteLength - value.length)); + return result; +} diff --git a/packages/util/u8a/index.d.ts b/packages/util/u8a/index.d.ts new file mode 100644 index 0000000..b793d8a --- /dev/null +++ b/packages/util/u8a/index.d.ts @@ -0,0 +1,18 @@ +/** + * @summary Utility methods to convert to and from `Uint8Array` objects + */ +export { u8aCmp } from './cmp.js'; +export { u8aConcat, u8aConcatStrict } from './concat.js'; +export { u8aEmpty } from './empty.js'; +export { u8aEq } from './eq.js'; +export { u8aFixLength } from './fixLength.js'; +export { u8aSorted } from './sorted.js'; +export { u8aToBigInt } from './toBigInt.js'; +export { u8aToBn } from './toBn.js'; +export { u8aToBuffer } from './toBuffer.js'; +export { u8aToFloat } from './toFloat.js'; +export { u8aToHex } from './toHex.js'; +export { u8aToNumber } from './toNumber.js'; +export { u8aToString } from './toString.js'; +export { u8aToU8a } from './toU8a.js'; +export { U8A_WRAP_ETHEREUM, U8A_WRAP_POSTFIX, U8A_WRAP_PREFIX, u8aIsWrapped, u8aUnwrapBytes, u8aWrapBytes } from './wrap.js'; diff --git a/packages/util/u8a/index.js b/packages/util/u8a/index.js new file mode 100644 index 0000000..b793d8a --- /dev/null +++ b/packages/util/u8a/index.js @@ -0,0 +1,18 @@ +/** + * @summary Utility methods to convert to and from `Uint8Array` objects + */ +export { u8aCmp } from './cmp.js'; +export { u8aConcat, u8aConcatStrict } from './concat.js'; +export { u8aEmpty } from './empty.js'; +export { u8aEq } from './eq.js'; +export { u8aFixLength } from './fixLength.js'; +export { u8aSorted } from './sorted.js'; +export { u8aToBigInt } from './toBigInt.js'; +export { u8aToBn } from './toBn.js'; +export { u8aToBuffer } from './toBuffer.js'; +export { u8aToFloat } from './toFloat.js'; +export { u8aToHex } from './toHex.js'; +export { u8aToNumber } from './toNumber.js'; +export { u8aToString } from './toString.js'; +export { u8aToU8a } from './toU8a.js'; +export { U8A_WRAP_ETHEREUM, U8A_WRAP_POSTFIX, U8A_WRAP_PREFIX, u8aIsWrapped, u8aUnwrapBytes, u8aWrapBytes } from './wrap.js'; diff --git a/packages/util/u8a/sorted.d.ts b/packages/util/u8a/sorted.d.ts new file mode 100644 index 0000000..aaa612a --- /dev/null +++ b/packages/util/u8a/sorted.d.ts @@ -0,0 +1,15 @@ +/** + * @name u8aSorted + * @summary Sorts an array of Uint8Arrays + * @description + * For input `UInt8Array[]` return the sorted result + * @example + *
+ * + * ```javascript + * import { u8aSorted} from '@pezkuwi/util'; + * + * u8aSorted([new Uint8Array([0x69]), new Uint8Array([0x68])]); // [0x68, 0x69] + * ``` + */ +export declare function u8aSorted(u8as: Uint8Array[]): Uint8Array[]; diff --git a/packages/util/u8a/sorted.js b/packages/util/u8a/sorted.js new file mode 100644 index 0000000..d5fedf2 --- /dev/null +++ b/packages/util/u8a/sorted.js @@ -0,0 +1,18 @@ +import { u8aCmp } from './cmp.js'; +/** + * @name u8aSorted + * @summary Sorts an array of Uint8Arrays + * @description + * For input `UInt8Array[]` return the sorted result + * @example + *
+ * + * ```javascript + * import { u8aSorted} from '@pezkuwi/util'; + * + * u8aSorted([new Uint8Array([0x69]), new Uint8Array([0x68])]); // [0x68, 0x69] + * ``` + */ +export function u8aSorted(u8as) { + return u8as.sort(u8aCmp); +} diff --git a/packages/util/u8a/toBigInt.d.ts b/packages/util/u8a/toBigInt.d.ts new file mode 100644 index 0000000..c604cd4 --- /dev/null +++ b/packages/util/u8a/toBigInt.d.ts @@ -0,0 +1,6 @@ +import type { ToBnOptions } from '../types.js'; +/** + * @name u8aToBigInt + * @summary Creates a BigInt from a Uint8Array object. + */ +export declare function u8aToBigInt(value: Uint8Array, { isLe, isNegative }?: ToBnOptions): bigint; diff --git a/packages/util/u8a/toBigInt.js b/packages/util/u8a/toBigInt.js new file mode 100644 index 0000000..dbbe3a5 --- /dev/null +++ b/packages/util/u8a/toBigInt.js @@ -0,0 +1,70 @@ +import { BigInt } from '@pezkuwi/x-bigint'; +import { _1n } from '../bi/consts.js'; +const U8_MAX = BigInt(256); +const U16_MAX = BigInt(256 * 256); +const U64_MAX = BigInt('0x10000000000000000'); +/** + * @name u8aToBigInt + * @summary Creates a BigInt from a Uint8Array object. + */ +export function u8aToBigInt(value, { isLe = true, isNegative = false } = {}) { + // slice + reverse is expensive, however SCALE is LE by default so this is the path + // we are most interested in (the BE is added for the sake of being comprehensive) + if (!isLe) { + value = value.slice().reverse(); + } + const count = value.length; + if (isNegative && count && (value[count - 1] & 0x80)) { + switch (count) { + case 0: + return BigInt(0); + case 1: + return BigInt(((value[0] ^ 0x0000_00ff) * -1) - 1); + case 2: + return BigInt((((value[0] + (value[1] << 8)) ^ 0x0000_ffff) * -1) - 1); + case 4: + return BigInt((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) * -1) - 1); + } + const dvI = new DataView(value.buffer, value.byteOffset); + if (count === 8) { + return dvI.getBigInt64(0, true); + } + let result = BigInt(0); + const mod = count % 2; + for (let i = count - 2; i >= mod; i -= 2) { + result = (result * U16_MAX) + BigInt(dvI.getUint16(i, true) ^ 0xffff); + } + if (mod) { + result = (result * U8_MAX) + BigInt(value[0] ^ 0xff); + } + return (result * -_1n) - _1n; + } + switch (count) { + case 0: + return BigInt(0); + case 1: + return BigInt(value[0]); + case 2: + return BigInt(value[0] + (value[1] << 8)); + case 4: + return BigInt(value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)); + } + const dvI = new DataView(value.buffer, value.byteOffset); + switch (count) { + case 8: + return dvI.getBigUint64(0, true); + case 16: + return (dvI.getBigUint64(8, true) * U64_MAX) + dvI.getBigUint64(0, true); + default: { + let result = BigInt(0); + const mod = count % 2; + for (let i = count - 2; i >= mod; i -= 2) { + result = (result * U16_MAX) + BigInt(dvI.getUint16(i, true)); + } + if (mod) { + result = (result * U8_MAX) + BigInt(value[0]); + } + return result; + } + } +} diff --git a/packages/util/u8a/toBn.d.ts b/packages/util/u8a/toBn.d.ts new file mode 100644 index 0000000..8f6c482 --- /dev/null +++ b/packages/util/u8a/toBn.d.ts @@ -0,0 +1,21 @@ +import type { ToBnOptions } from '../types.js'; +import { BN } from '../bn/bn.js'; +/** + * @name u8aToBn + * @summary Creates a BN from a Uint8Array object. + * @description + * `UInt8Array` input values return the actual BN. `null` or `undefined` values returns an `0x0` value. + * @param value The value to convert + * @param options Options to pass while converting + * @param options.isLe Convert using Little Endian (default) + * @param options.isNegative Convert using two's complement + * @example + *
+ * + * ```javascript + * import { u8aToBn } from '@pezkuwi/util'; + * + * u8aToHex(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0xf])); // 0x68656c0f + * ``` + */ +export declare function u8aToBn(value: Uint8Array, { isLe, isNegative }?: ToBnOptions): BN; diff --git a/packages/util/u8a/toBn.js b/packages/util/u8a/toBn.js new file mode 100644 index 0000000..65923e5 --- /dev/null +++ b/packages/util/u8a/toBn.js @@ -0,0 +1,78 @@ +import { BN } from '../bn/bn.js'; +/** + * @name u8aToBn + * @summary Creates a BN from a Uint8Array object. + * @description + * `UInt8Array` input values return the actual BN. `null` or `undefined` values returns an `0x0` value. + * @param value The value to convert + * @param options Options to pass while converting + * @param options.isLe Convert using Little Endian (default) + * @param options.isNegative Convert using two's complement + * @example + *
+ * + * ```javascript + * import { u8aToBn } from '@pezkuwi/util'; + * + * u8aToHex(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0xf])); // 0x68656c0f + * ``` + */ +export function u8aToBn(value, { isLe = true, isNegative = false } = {}) { + // slice + reverse is expensive, however SCALE is LE by default so this is the path + // we are most interested in (the BE is added for the sake of being comprehensive) + if (!isLe) { + value = value.slice().reverse(); + } + const count = value.length; + // shortcut for <= u48 values - in this case the manual conversion + // here seems to be more efficient than passing the full array + if (isNegative && count && (value[count - 1] & 0x80)) { + // Most common case i{8, 16, 32} default LE SCALE-encoded + // For <= 32, we also optimize the xor to a single op + switch (count) { + case 0: + return new BN(0); + case 1: + return new BN(((value[0] ^ 0x0000_00ff) * -1) - 1); + case 2: + return new BN((((value[0] + (value[1] << 8)) ^ 0x0000_ffff) * -1) - 1); + case 3: + return new BN((((value[0] + (value[1] << 8) + (value[2] << 16)) ^ 0x00ff_ffff) * -1) - 1); + case 4: + // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to + // 32-bit, in the case where the top-most bit is set this yields a negative value + return new BN((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) * -1) - 1); + case 5: + return new BN(((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) + ((value[4] ^ 0xff) * 0x1_00_00_00_00)) * -1) - 1); + case 6: + return new BN(((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) + (((value[4] + (value[5] << 8)) ^ 0x0000_ffff) * 0x1_00_00_00_00)) * -1) - 1); + default: + return new BN(value, 'le').fromTwos(count * 8); + } + } + // Most common case - u{8, 16, 32} default LE SCALE-encoded + // + // There are some slight benefits in unrolling this specific loop, + // however it comes with diminishing returns since here the actual + // `new BN` does seem to take up the bulk of the time + switch (count) { + case 0: + return new BN(0); + case 1: + return new BN(value[0]); + case 2: + return new BN(value[0] + (value[1] << 8)); + case 3: + return new BN(value[0] + (value[1] << 8) + (value[2] << 16)); + case 4: + // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to + // 32-bit, in the case where the top-most bit is set this yields a negative value + return new BN(value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)); + case 5: + return new BN(value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8)) * 0x1_00_00_00)); + case 6: + return new BN(value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8) + (value[5] << 16)) * 0x1_00_00_00)); + default: + return new BN(value, 'le'); + } +} diff --git a/packages/util/u8a/toBuffer.d.ts b/packages/util/u8a/toBuffer.d.ts new file mode 100644 index 0000000..0cb0ce1 --- /dev/null +++ b/packages/util/u8a/toBuffer.d.ts @@ -0,0 +1,16 @@ +import type { BufferObject } from '../types.js'; +/** + * @name u8aToBuffer + * @summary Creates a Buffer object from a hex string. + * @description + * `null` inputs returns an empty `Buffer` result. `UInt8Array` input values return the actual bytes value converted to a `Buffer`. Anything that is not a `UInt8Array` throws an error. + * @example + *
+ * + * ```javascript + * import { u8aToBuffer } from '@pezkuwi/util'; + * + * console.log('Buffer', u8aToBuffer(new Uint8Array([1, 2, 3]))); + * ``` + */ +export declare function u8aToBuffer(value?: Uint8Array | null): T; diff --git a/packages/util/u8a/toBuffer.js b/packages/util/u8a/toBuffer.js new file mode 100644 index 0000000..279131e --- /dev/null +++ b/packages/util/u8a/toBuffer.js @@ -0,0 +1,21 @@ +import { xglobal } from '@pezkuwi/x-global'; +import { hasBuffer } from '../has.js'; +/** + * @name u8aToBuffer + * @summary Creates a Buffer object from a hex string. + * @description + * `null` inputs returns an empty `Buffer` result. `UInt8Array` input values return the actual bytes value converted to a `Buffer`. Anything that is not a `UInt8Array` throws an error. + * @example + *
+ * + * ```javascript + * import { u8aToBuffer } from '@pezkuwi/util'; + * + * console.log('Buffer', u8aToBuffer(new Uint8Array([1, 2, 3]))); + * ``` + */ +export function u8aToBuffer(value) { + return hasBuffer + ? xglobal.Buffer.from(value || []) + : new Uint8Array(value || []); +} diff --git a/packages/util/u8a/toFloat.d.ts b/packages/util/u8a/toFloat.d.ts new file mode 100644 index 0000000..ee6a428 --- /dev/null +++ b/packages/util/u8a/toFloat.d.ts @@ -0,0 +1,11 @@ +interface Options { + bitLength?: 32 | 64; + isLe?: boolean; +} +/** + * @name u8aToFloat + * @description Converts a Uint8Array value into the float (either 32 or 64-bit) + * representation. + */ +export declare function u8aToFloat(value: Uint8Array, { bitLength, isLe }?: Options): number; +export {}; diff --git a/packages/util/u8a/toFloat.js b/packages/util/u8a/toFloat.js new file mode 100644 index 0000000..f51f572 --- /dev/null +++ b/packages/util/u8a/toFloat.js @@ -0,0 +1,17 @@ +/** + * @name u8aToFloat + * @description Converts a Uint8Array value into the float (either 32 or 64-bit) + * representation. + */ +export function u8aToFloat(value, { bitLength = 32, isLe = true } = {}) { + if (bitLength !== 32 && bitLength !== 64) { + throw new Error('Invalid bitLength provided, expected 32 or 64'); + } + else if (value.length < (bitLength / 8)) { + throw new Error(`Invalid input buffer provided, expected at least ${bitLength / 8} bytes, found ${value.length}`); + } + const dv = new DataView(value.buffer, value.byteOffset); + return bitLength === 32 + ? dv.getFloat32(0, isLe) + : dv.getFloat64(0, isLe); +} diff --git a/packages/util/u8a/toHex.d.ts b/packages/util/u8a/toHex.d.ts new file mode 100644 index 0000000..7059f13 --- /dev/null +++ b/packages/util/u8a/toHex.d.ts @@ -0,0 +1,16 @@ +import type { HexString } from '../types.js'; +/** + * @name u8aToHex + * @summary Creates a hex string from a Uint8Array object. + * @description + * `UInt8Array` input values return the actual hex string. `null` or `undefined` values returns an `0x` string. + * @example + *
+ * + * ```javascript + * import { u8aToHex } from '@pezkuwi/util'; + * + * u8aToHex(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0xf])); // 0x68656c0f + * ``` + */ +export declare function u8aToHex(value?: Uint8Array | null, bitLength?: number, isPrefixed?: boolean): HexString; diff --git a/packages/util/u8a/toHex.js b/packages/util/u8a/toHex.js new file mode 100644 index 0000000..924d593 --- /dev/null +++ b/packages/util/u8a/toHex.js @@ -0,0 +1,53 @@ +const U8 = new Array(256); +const U16 = new Array(256 * 256); +for (let n = 0; n < 256; n++) { + U8[n] = n.toString(16).padStart(2, '0'); +} +for (let i = 0; i < 256; i++) { + const s = i << 8; + for (let j = 0; j < 256; j++) { + U16[s | j] = U8[i] + U8[j]; + } +} +/** @internal */ +function hex(value, result) { + const mod = (value.length % 2) | 0; + const length = (value.length - mod) | 0; + for (let i = 0; i < length; i += 2) { + result += U16[(value[i] << 8) | value[i + 1]]; + } + if (mod) { + result += U8[value[length] | 0]; + } + return result; +} +/** + * @name u8aToHex + * @summary Creates a hex string from a Uint8Array object. + * @description + * `UInt8Array` input values return the actual hex string. `null` or `undefined` values returns an `0x` string. + * @example + *
+ * + * ```javascript + * import { u8aToHex } from '@pezkuwi/util'; + * + * u8aToHex(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0xf])); // 0x68656c0f + * ``` + */ +export function u8aToHex(value, bitLength = -1, isPrefixed = true) { + // this is not 100% correct sinmce we support isPrefixed = false.... + const empty = isPrefixed + ? '0x' + : ''; + if (!value?.length) { + return empty; + } + else if (bitLength > 0) { + const length = Math.ceil(bitLength / 8); + if (value.length > length) { + return `${hex(value.subarray(0, length / 2), empty)}…${hex(value.subarray(value.length - length / 2), '')}`; + } + } + return hex(value, empty); +} diff --git a/packages/util/u8a/toHexBuffer.d.ts b/packages/util/u8a/toHexBuffer.d.ts new file mode 100644 index 0000000..7059f13 --- /dev/null +++ b/packages/util/u8a/toHexBuffer.d.ts @@ -0,0 +1,16 @@ +import type { HexString } from '../types.js'; +/** + * @name u8aToHex + * @summary Creates a hex string from a Uint8Array object. + * @description + * `UInt8Array` input values return the actual hex string. `null` or `undefined` values returns an `0x` string. + * @example + *
+ * + * ```javascript + * import { u8aToHex } from '@pezkuwi/util'; + * + * u8aToHex(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0xf])); // 0x68656c0f + * ``` + */ +export declare function u8aToHex(value?: Uint8Array | null, bitLength?: number, isPrefixed?: boolean): HexString; diff --git a/packages/util/u8a/toHexBuffer.js b/packages/util/u8a/toHexBuffer.js new file mode 100644 index 0000000..ea95e6f --- /dev/null +++ b/packages/util/u8a/toHexBuffer.js @@ -0,0 +1,22 @@ +/** + * @name u8aToHex + * @summary Creates a hex string from a Uint8Array object. + * @description + * `UInt8Array` input values return the actual hex string. `null` or `undefined` values returns an `0x` string. + * @example + *
+ * + * ```javascript + * import { u8aToHex } from '@pezkuwi/util'; + * + * u8aToHex(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0xf])); // 0x68656c0f + * ``` + */ +export function u8aToHex(value, bitLength = -1, isPrefixed = true) { + const length = Math.ceil(bitLength / 8); + return `${isPrefixed ? '0x' : ''}${!value?.length + ? '' + : (bitLength > 0 && value.length > length) + ? `${Buffer.from(value.subarray(0, length / 2)).toString('hex')}…${Buffer.from(value.subarray(value.length - length / 2)).toString('hex')}` + : Buffer.from(value).toString('hex')}`; +} diff --git a/packages/util/u8a/toNumber.d.ts b/packages/util/u8a/toNumber.d.ts new file mode 100644 index 0000000..0fdd425 --- /dev/null +++ b/packages/util/u8a/toNumber.d.ts @@ -0,0 +1,6 @@ +import type { ToBnOptions } from '../types.js'; +/** + * @name u8aToNumber + * @summary Creates a number from a Uint8Array object. + */ +export declare function u8aToNumber(value: Uint8Array, { isLe, isNegative }?: ToBnOptions): number; diff --git a/packages/util/u8a/toNumber.js b/packages/util/u8a/toNumber.js new file mode 100644 index 0000000..fdf39b6 --- /dev/null +++ b/packages/util/u8a/toNumber.js @@ -0,0 +1,58 @@ +/** + * @name u8aToNumber + * @summary Creates a number from a Uint8Array object. + */ +export function u8aToNumber(value, { isLe = true, isNegative = false } = {}) { + // slice + reverse is expensive, however SCALE is LE by default so this is the path + // we are most interested in (the BE is added for the sake of being comprehensive) + if (!isLe) { + value = value.slice().reverse(); + } + const count = value.length; + // When the value is a i{8, 16, 24, 32, 40, 40} values and the top-most bit + // indicates a signed value, we use a two's complement conversion. If one of these + // flags are not set, we just do a normal unsigned conversion (the same shortcut + // applies in both the u8aTo{BigInt, Bn} conversions as well) + if (isNegative && count && (value[count - 1] & 0x80)) { + switch (count) { + case 0: + return 0; + case 1: + return (((value[0] ^ 0x0000_00ff) * -1) - 1); + case 2: + return ((((value[0] + (value[1] << 8)) ^ 0x0000_ffff) * -1) - 1); + case 3: + return ((((value[0] + (value[1] << 8) + (value[2] << 16)) ^ 0x00ff_ffff) * -1) - 1); + case 4: + // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to + // 32-bit, in the case where the top-most bit is set this yields a negative value + return ((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) * -1) - 1); + case 5: + return (((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) + ((value[4] ^ 0xff) * 0x1_00_00_00_00)) * -1) - 1); + case 6: + return (((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) + (((value[4] + (value[5] << 8)) ^ 0x0000_ffff) * 0x1_00_00_00_00)) * -1) - 1); + default: + throw new Error('Value more than 48-bits cannot be reliably converted'); + } + } + switch (count) { + case 0: + return 0; + case 1: + return value[0]; + case 2: + return value[0] + (value[1] << 8); + case 3: + return value[0] + (value[1] << 8) + (value[2] << 16); + case 4: + // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to + // 32-bit, in the case where the top-most bit is set this yields a negative value + return value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00); + case 5: + return value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8)) * 0x1_00_00_00); + case 6: + return value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8) + (value[5] << 16)) * 0x1_00_00_00); + default: + throw new Error('Value more than 48-bits cannot be reliably converted'); + } +} diff --git a/packages/util/u8a/toString.d.ts b/packages/util/u8a/toString.d.ts new file mode 100644 index 0000000..21e6490 --- /dev/null +++ b/packages/util/u8a/toString.d.ts @@ -0,0 +1,15 @@ +/** + * @name u8aToString + * @summary Creates a utf-8 string from a Uint8Array object. + * @description + * `UInt8Array` input values return the actual decoded utf-8 string. `null` or `undefined` values returns an empty string. + * @example + *
+ * + * ```javascript + * import { u8aToString } from '@pezkuwi/util'; + * + * u8aToString(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0x6f])); // hello + * ``` + */ +export declare function u8aToString(value?: Uint8Array | null): string; diff --git a/packages/util/u8a/toString.js b/packages/util/u8a/toString.js new file mode 100644 index 0000000..5901da4 --- /dev/null +++ b/packages/util/u8a/toString.js @@ -0,0 +1,21 @@ +import { TextDecoder } from '@pezkuwi/x-textdecoder'; +const decoder = new TextDecoder('utf-8'); +/** + * @name u8aToString + * @summary Creates a utf-8 string from a Uint8Array object. + * @description + * `UInt8Array` input values return the actual decoded utf-8 string. `null` or `undefined` values returns an empty string. + * @example + *
+ * + * ```javascript + * import { u8aToString } from '@pezkuwi/util'; + * + * u8aToString(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0x6f])); // hello + * ``` + */ +export function u8aToString(value) { + return value + ? decoder.decode(value) + : ''; +} diff --git a/packages/util/u8a/toU8a.d.ts b/packages/util/u8a/toU8a.d.ts new file mode 100644 index 0000000..68e60e7 --- /dev/null +++ b/packages/util/u8a/toU8a.d.ts @@ -0,0 +1,19 @@ +import type { U8aLike } from '../types.js'; +/** + * @name u8aToU8a + * @summary Creates a Uint8Array value from a Uint8Array, Buffer, string or hex input. + * @description + * `null` or `undefined` inputs returns a `[]` result, Uint8Array values returns the value, hex strings returns a Uint8Array representation. + * If `strict` is true, `null` or `undefined` will throw an error instead of returning an empty array. + * Supports input types: Uint8Array, Buffer, hex string, string, or number array. + * @example + *
+ * + * ```javascript + * import { u8aToU8a } from '@pezkuwi/util'; + * + * u8aToU8a(new Uint8Array([0x12, 0x34]); // => Uint8Array([0x12, 0x34]) + * u8aToU8a(0x1234); // => Uint8Array([0x12, 0x34]) + * ``` + */ +export declare function u8aToU8a(value?: U8aLike | null, strict?: boolean): Uint8Array; diff --git a/packages/util/u8a/toU8a.js b/packages/util/u8a/toU8a.js new file mode 100644 index 0000000..ca05def --- /dev/null +++ b/packages/util/u8a/toU8a.js @@ -0,0 +1,39 @@ +import { hexToU8a } from '../hex/toU8a.js'; +import { isBuffer } from '../is/buffer.js'; +import { isHex } from '../is/hex.js'; +import { isU8a } from '../is/u8a.js'; +import { stringToU8a } from '../string/toU8a.js'; +/** + * @name u8aToU8a + * @summary Creates a Uint8Array value from a Uint8Array, Buffer, string or hex input. + * @description + * `null` or `undefined` inputs returns a `[]` result, Uint8Array values returns the value, hex strings returns a Uint8Array representation. + * If `strict` is true, `null` or `undefined` will throw an error instead of returning an empty array. + * Supports input types: Uint8Array, Buffer, hex string, string, or number array. + * @example + *
+ * + * ```javascript + * import { u8aToU8a } from '@pezkuwi/util'; + * + * u8aToU8a(new Uint8Array([0x12, 0x34]); // => Uint8Array([0x12, 0x34]) + * u8aToU8a(0x1234); // => Uint8Array([0x12, 0x34]) + * ``` + */ +export function u8aToU8a(value, strict = false) { + if (strict && (value === null || value === undefined)) { + throw new Error('u8aToU8a: Expected non-null, non-undefined value'); + } + return isU8a(value) + // NOTE isBuffer needs to go here since it actually extends + // Uint8Array on Node.js environments, so all Buffer are Uint8Array, + // but Uint8Array is not Buffer + ? isBuffer(value) + ? new Uint8Array(value) + : value + : isHex(value) + ? hexToU8a(value) + : Array.isArray(value) + ? new Uint8Array(value) + : stringToU8a(value); +} diff --git a/packages/util/u8a/wrap.d.ts b/packages/util/u8a/wrap.d.ts new file mode 100644 index 0000000..19a8417 --- /dev/null +++ b/packages/util/u8a/wrap.d.ts @@ -0,0 +1,22 @@ +import type { U8aLike } from '../types.js'; +/** @internal */ +export declare const U8A_WRAP_ETHEREUM: Uint8Array; +/** @internal */ +export declare const U8A_WRAP_PREFIX: Uint8Array; +/** @internal */ +export declare const U8A_WRAP_POSTFIX: Uint8Array; +/** @internal */ +export declare function u8aIsWrapped(u8a: Uint8Array, withEthereum: boolean): boolean; +/** + * @name u8aUnwrapBytes + * @description Removes all ... wrappers from the supplied value + */ +export declare function u8aUnwrapBytes(bytes: U8aLike): Uint8Array; +/** + * @name u8aWrapBytes + * @description + * Adds a ... wrapper to the supplied value, if + * - We don't already have a Bytes wrapper + * - The message is not an Ethereum-style message + */ +export declare function u8aWrapBytes(bytes: U8aLike): Uint8Array; diff --git a/packages/util/u8a/wrap.js b/packages/util/u8a/wrap.js new file mode 100644 index 0000000..d434345 --- /dev/null +++ b/packages/util/u8a/wrap.js @@ -0,0 +1,43 @@ +import { u8aConcatStrict } from './concat.js'; +import { u8aEq } from './eq.js'; +import { u8aToU8a } from './toU8a.js'; +/** @internal */ +export const U8A_WRAP_ETHEREUM = /*#__PURE__*/ u8aToU8a('\x19Ethereum Signed Message:\n'); +/** @internal */ +export const U8A_WRAP_PREFIX = /*#__PURE__*/ u8aToU8a(''); +/** @internal */ +export const U8A_WRAP_POSTFIX = /*#__PURE__*/ u8aToU8a(''); +const WRAP_LEN = U8A_WRAP_PREFIX.length + U8A_WRAP_POSTFIX.length; +/** @internal */ +export function u8aIsWrapped(u8a, withEthereum) { + return ((u8a.length >= WRAP_LEN && + u8aEq(u8a.subarray(0, U8A_WRAP_PREFIX.length), U8A_WRAP_PREFIX) && + u8aEq(u8a.slice(-U8A_WRAP_POSTFIX.length), U8A_WRAP_POSTFIX)) || + (withEthereum && + u8a.length >= U8A_WRAP_ETHEREUM.length && + u8aEq(u8a.subarray(0, U8A_WRAP_ETHEREUM.length), U8A_WRAP_ETHEREUM))); +} +/** + * @name u8aUnwrapBytes + * @description Removes all ... wrappers from the supplied value + */ +export function u8aUnwrapBytes(bytes) { + const u8a = u8aToU8a(bytes); + // we don't want to unwrap Ethereum-style wraps + return u8aIsWrapped(u8a, false) + ? u8a.subarray(U8A_WRAP_PREFIX.length, u8a.length - U8A_WRAP_POSTFIX.length) + : u8a; +} +/** + * @name u8aWrapBytes + * @description + * Adds a ... wrapper to the supplied value, if + * - We don't already have a Bytes wrapper + * - The message is not an Ethereum-style message + */ +export function u8aWrapBytes(bytes) { + const u8a = u8aToU8a(bytes); + return u8aIsWrapped(u8a, true) + ? u8a + : u8aConcatStrict([U8A_WRAP_PREFIX, u8a, U8A_WRAP_POSTFIX]); +} diff --git a/packages/x-bigint/cjs/index.d.ts b/packages/x-bigint/cjs/index.d.ts new file mode 100644 index 0000000..4ed4797 --- /dev/null +++ b/packages/x-bigint/cjs/index.d.ts @@ -0,0 +1,2 @@ +export { packageInfo } from './packageInfo.js'; +export declare const BigInt: BigIntConstructor; diff --git a/packages/x-bigint/cjs/index.js b/packages/x-bigint/cjs/index.js new file mode 100644 index 0000000..73cc8a5 --- /dev/null +++ b/packages/x-bigint/cjs/index.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BigInt = exports.packageInfo = void 0; +const x_global_1 = require("@pezkuwi/x-global"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +/** + * @internal + * + * There are _still_ some older environments (specifically RN < 0.70), that does + * not have proper BigInt support - a non-working fallback is provided for those. + * + * We detect availability of BigInt upon usage, so this is purely to allow functional + * compilation & bundling. Since we have operators such as *+-/ top-level, a number-ish + * result is used here. + */ +function invalidFallback() { + return Number.NaN; +} +exports.BigInt = (0, x_global_1.extractGlobal)('BigInt', invalidFallback); diff --git a/packages/x-bigint/cjs/package.json b/packages/x-bigint/cjs/package.json new file mode 100644 index 0000000..5bbefff --- /dev/null +++ b/packages/x-bigint/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/x-bigint/cjs/packageInfo.d.ts b/packages/x-bigint/cjs/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/x-bigint/cjs/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/x-bigint/cjs/packageInfo.js b/packages/x-bigint/cjs/packageInfo.js new file mode 100644 index 0000000..a868dec --- /dev/null +++ b/packages/x-bigint/cjs/packageInfo.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +exports.packageInfo = { name: '@pezkuwi/x-bigint', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; diff --git a/packages/x-bigint/cjs/shim.d.ts b/packages/x-bigint/cjs/shim.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/x-bigint/cjs/shim.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/x-bigint/cjs/shim.js b/packages/x-bigint/cjs/shim.js new file mode 100644 index 0000000..55ab9b6 --- /dev/null +++ b/packages/x-bigint/cjs/shim.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const x_bigint_1 = require("@pezkuwi/x-bigint"); +const x_global_1 = require("@pezkuwi/x-global"); +(0, x_global_1.exposeGlobal)('BigInt', x_bigint_1.BigInt); diff --git a/packages/x-bigint/index.d.ts b/packages/x-bigint/index.d.ts new file mode 100644 index 0000000..4ed4797 --- /dev/null +++ b/packages/x-bigint/index.d.ts @@ -0,0 +1,2 @@ +export { packageInfo } from './packageInfo.js'; +export declare const BigInt: BigIntConstructor; diff --git a/packages/x-bigint/index.js b/packages/x-bigint/index.js new file mode 100644 index 0000000..0930f5e --- /dev/null +++ b/packages/x-bigint/index.js @@ -0,0 +1,16 @@ +import { extractGlobal } from '@pezkuwi/x-global'; +export { packageInfo } from './packageInfo.js'; +/** + * @internal + * + * There are _still_ some older environments (specifically RN < 0.70), that does + * not have proper BigInt support - a non-working fallback is provided for those. + * + * We detect availability of BigInt upon usage, so this is purely to allow functional + * compilation & bundling. Since we have operators such as *+-/ top-level, a number-ish + * result is used here. + */ +function invalidFallback() { + return Number.NaN; +} +export const BigInt = /*#__PURE__*/ extractGlobal('BigInt', invalidFallback); diff --git a/packages/x-bigint/package.json b/packages/x-bigint/package.json index c1776f4..68e194b 100644 --- a/packages/x-bigint/package.json +++ b/packages/x-bigint/package.json @@ -15,12 +15,93 @@ }, "sideEffects": [ "./shim.js", - "./shim.cjs" + "./cjs/shim.js" ], "type": "module", - "version": "14.0.10", + "version": "14.0.11", + "main": "./cjs/index.js", + "module": "./index.js", + "types": "./index.d.ts", + "exports": { + "./cjs/package.json": "./cjs/package.json", + "./cjs/*": "./cjs/*.js", + ".": { + "module": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "require": { + "types": "./cjs/index.d.ts", + "default": "./cjs/index.js" + }, + "default": { + "types": "./index.d.ts", + "default": "./index.js" + } + }, + "./package.json": { + "require": "./cjs/package.json", + "default": "./package.json" + }, + "./packageInfo.js": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./packageInfo": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./shim.js": { + "module": { + "types": "./shim.d.ts", + "default": "./shim.js" + }, + "require": { + "types": "./cjs/shim.d.ts", + "default": "./cjs/shim.js" + }, + "default": { + "types": "./shim.d.ts", + "default": "./shim.js" + } + }, + "./shim": { + "module": { + "types": "./shim.d.ts", + "default": "./shim.js" + }, + "require": { + "types": "./cjs/shim.d.ts", + "default": "./cjs/shim.js" + }, + "default": { + "types": "./shim.d.ts", + "default": "./shim.js" + } + } + }, "dependencies": { - "@pezkuwi/x-global": "workspace:*", + "@pezkuwi/x-global": "14.0.11", "tslib": "^2.8.0" } } diff --git a/packages/x-bigint/packageInfo.d.ts b/packages/x-bigint/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/x-bigint/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/x-bigint/packageInfo.js b/packages/x-bigint/packageInfo.js new file mode 100644 index 0000000..3a0f42b --- /dev/null +++ b/packages/x-bigint/packageInfo.js @@ -0,0 +1 @@ +export const packageInfo = { name: '@pezkuwi/x-bigint', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; diff --git a/packages/x-bigint/shim.d.ts b/packages/x-bigint/shim.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/x-bigint/shim.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/x-bigint/shim.js b/packages/x-bigint/shim.js new file mode 100644 index 0000000..ae6e9f3 --- /dev/null +++ b/packages/x-bigint/shim.js @@ -0,0 +1,3 @@ +import { BigInt } from '@pezkuwi/x-bigint'; +import { exposeGlobal } from '@pezkuwi/x-global'; +exposeGlobal('BigInt', BigInt); diff --git a/packages/x-bundle/buffer.d.ts b/packages/x-bundle/buffer.d.ts new file mode 100644 index 0000000..95a1022 --- /dev/null +++ b/packages/x-bundle/buffer.d.ts @@ -0,0 +1,3 @@ +import { Buffer } from 'buffer-es6'; +export default Buffer; +export { Buffer }; diff --git a/packages/x-bundle/buffer.js b/packages/x-bundle/buffer.js new file mode 100644 index 0000000..95a1022 --- /dev/null +++ b/packages/x-bundle/buffer.js @@ -0,0 +1,3 @@ +import { Buffer } from 'buffer-es6'; +export default Buffer; +export { Buffer }; diff --git a/packages/x-bundle/cjs/bn.d.ts b/packages/x-bundle/cjs/bn.d.ts new file mode 100644 index 0000000..f80d732 --- /dev/null +++ b/packages/x-bundle/cjs/bn.d.ts @@ -0,0 +1,2 @@ +export = BN; +import { BN } from "@pezkuwi/util/bn/index"; diff --git a/packages/x-bundle/cjs/bn.js b/packages/x-bundle/cjs/bn.js new file mode 100644 index 0000000..1d4e7a7 --- /dev/null +++ b/packages/x-bundle/cjs/bn.js @@ -0,0 +1,7 @@ +// Copyright 2017-2025 @pezkuwi/x-bundle authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +// @ts-expect-error In dev mode we don't have export maps... +const { BN } = require('@pezkuwi/util'); + +module.exports = BN; diff --git a/packages/x-bundle/cjs/buffer.d.ts b/packages/x-bundle/cjs/buffer.d.ts new file mode 100644 index 0000000..95a1022 --- /dev/null +++ b/packages/x-bundle/cjs/buffer.d.ts @@ -0,0 +1,3 @@ +import { Buffer } from 'buffer-es6'; +export default Buffer; +export { Buffer }; diff --git a/packages/x-bundle/cjs/buffer.js b/packages/x-bundle/cjs/buffer.js new file mode 100644 index 0000000..e479112 --- /dev/null +++ b/packages/x-bundle/cjs/buffer.js @@ -0,0 +1,6 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Buffer = void 0; +const buffer_es6_1 = require("buffer-es6"); +Object.defineProperty(exports, "Buffer", { enumerable: true, get: function () { return buffer_es6_1.Buffer; } }); +exports.default = buffer_es6_1.Buffer; diff --git a/packages/x-bundle/cjs/crypto.d.ts b/packages/x-bundle/cjs/crypto.d.ts new file mode 100644 index 0000000..d87c485 --- /dev/null +++ b/packages/x-bundle/cjs/crypto.d.ts @@ -0,0 +1,2 @@ +declare const _default: {}; +export default _default; diff --git a/packages/x-bundle/cjs/crypto.js b/packages/x-bundle/cjs/crypto.js new file mode 100644 index 0000000..2367d85 --- /dev/null +++ b/packages/x-bundle/cjs/crypto.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = {}; diff --git a/packages/x-bundle/cjs/dummy.d.ts b/packages/x-bundle/cjs/dummy.d.ts new file mode 100644 index 0000000..98df5e1 --- /dev/null +++ b/packages/x-bundle/cjs/dummy.d.ts @@ -0,0 +1,2 @@ +import { BN } from '@pezkuwi/util'; +export { BN }; diff --git a/packages/x-bundle/cjs/dummy.js b/packages/x-bundle/cjs/dummy.js new file mode 100644 index 0000000..3ec2f6e --- /dev/null +++ b/packages/x-bundle/cjs/dummy.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BN = void 0; +const util_1 = require("@pezkuwi/util"); +Object.defineProperty(exports, "BN", { enumerable: true, get: function () { return util_1.BN; } }); diff --git a/packages/x-bundle/cjs/empty.d.ts b/packages/x-bundle/cjs/empty.d.ts new file mode 100644 index 0000000..d87c485 --- /dev/null +++ b/packages/x-bundle/cjs/empty.d.ts @@ -0,0 +1,2 @@ +declare const _default: {}; +export default _default; diff --git a/packages/x-bundle/cjs/empty.js b/packages/x-bundle/cjs/empty.js new file mode 100644 index 0000000..2367d85 --- /dev/null +++ b/packages/x-bundle/cjs/empty.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = {}; diff --git a/packages/x-bundle/cjs/index.d.ts b/packages/x-bundle/cjs/index.d.ts new file mode 100644 index 0000000..7904c07 --- /dev/null +++ b/packages/x-bundle/cjs/index.d.ts @@ -0,0 +1 @@ +export { packageInfo } from './packageInfo.js'; diff --git a/packages/x-bundle/cjs/index.js b/packages/x-bundle/cjs/index.js new file mode 100644 index 0000000..b2c3d89 --- /dev/null +++ b/packages/x-bundle/cjs/index.js @@ -0,0 +1,6 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +console.error('@pezkuwi/x-bundle is not meant to be used directly'); diff --git a/packages/x-bundle/cjs/inherits.d.ts b/packages/x-bundle/cjs/inherits.d.ts new file mode 100644 index 0000000..a1477bc --- /dev/null +++ b/packages/x-bundle/cjs/inherits.d.ts @@ -0,0 +1,7 @@ +interface Class { + prototype: object; + super_: Class; + [key: string]: unknown; +} +export default function inherits(child: Class, parent: Class): void; +export {}; diff --git a/packages/x-bundle/cjs/inherits.js b/packages/x-bundle/cjs/inherits.js new file mode 100644 index 0000000..ccab6d5 --- /dev/null +++ b/packages/x-bundle/cjs/inherits.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = inherits; +function inherits(child, parent) { + if (parent) { + child.super_ = parent; + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + child.prototype = Object.create(parent.prototype, { + constructor: { + configurable: true, + enumerable: false, + value: child, + writable: true + } + }); + } +} diff --git a/packages/x-bundle/cjs/package.json b/packages/x-bundle/cjs/package.json new file mode 100644 index 0000000..5bbefff --- /dev/null +++ b/packages/x-bundle/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/x-bundle/cjs/packageInfo.d.ts b/packages/x-bundle/cjs/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/x-bundle/cjs/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/x-bundle/cjs/packageInfo.js b/packages/x-bundle/cjs/packageInfo.js new file mode 100644 index 0000000..1b49691 --- /dev/null +++ b/packages/x-bundle/cjs/packageInfo.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +exports.packageInfo = { name: '@pezkuwi/x-bundle', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; diff --git a/packages/x-bundle/crypto.d.ts b/packages/x-bundle/crypto.d.ts new file mode 100644 index 0000000..d87c485 --- /dev/null +++ b/packages/x-bundle/crypto.d.ts @@ -0,0 +1,2 @@ +declare const _default: {}; +export default _default; diff --git a/packages/x-bundle/crypto.js b/packages/x-bundle/crypto.js new file mode 100644 index 0000000..ff8b4c5 --- /dev/null +++ b/packages/x-bundle/crypto.js @@ -0,0 +1 @@ +export default {}; diff --git a/packages/x-bundle/dummy.d.ts b/packages/x-bundle/dummy.d.ts new file mode 100644 index 0000000..98df5e1 --- /dev/null +++ b/packages/x-bundle/dummy.d.ts @@ -0,0 +1,2 @@ +import { BN } from '@pezkuwi/util'; +export { BN }; diff --git a/packages/x-bundle/dummy.js b/packages/x-bundle/dummy.js new file mode 100644 index 0000000..98df5e1 --- /dev/null +++ b/packages/x-bundle/dummy.js @@ -0,0 +1,2 @@ +import { BN } from '@pezkuwi/util'; +export { BN }; diff --git a/packages/x-bundle/empty.d.ts b/packages/x-bundle/empty.d.ts new file mode 100644 index 0000000..d87c485 --- /dev/null +++ b/packages/x-bundle/empty.d.ts @@ -0,0 +1,2 @@ +declare const _default: {}; +export default _default; diff --git a/packages/x-bundle/empty.js b/packages/x-bundle/empty.js new file mode 100644 index 0000000..ff8b4c5 --- /dev/null +++ b/packages/x-bundle/empty.js @@ -0,0 +1 @@ +export default {}; diff --git a/packages/x-bundle/index.d.ts b/packages/x-bundle/index.d.ts new file mode 100644 index 0000000..7904c07 --- /dev/null +++ b/packages/x-bundle/index.d.ts @@ -0,0 +1 @@ +export { packageInfo } from './packageInfo.js'; diff --git a/packages/x-bundle/index.js b/packages/x-bundle/index.js new file mode 100644 index 0000000..7aa0031 --- /dev/null +++ b/packages/x-bundle/index.js @@ -0,0 +1,2 @@ +export { packageInfo } from './packageInfo.js'; +console.error('@pezkuwi/x-bundle is not meant to be used directly'); diff --git a/packages/x-bundle/inherits.d.ts b/packages/x-bundle/inherits.d.ts new file mode 100644 index 0000000..a1477bc --- /dev/null +++ b/packages/x-bundle/inherits.d.ts @@ -0,0 +1,7 @@ +interface Class { + prototype: object; + super_: Class; + [key: string]: unknown; +} +export default function inherits(child: Class, parent: Class): void; +export {}; diff --git a/packages/x-bundle/inherits.js b/packages/x-bundle/inherits.js new file mode 100644 index 0000000..2ef6408 --- /dev/null +++ b/packages/x-bundle/inherits.js @@ -0,0 +1,14 @@ +export default function inherits(child, parent) { + if (parent) { + child.super_ = parent; + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + child.prototype = Object.create(parent.prototype, { + constructor: { + configurable: true, + enumerable: false, + value: child, + writable: true + } + }); + } +} diff --git a/packages/x-bundle/package.json b/packages/x-bundle/package.json index d007fa0..4b8bac0 100644 --- a/packages/x-bundle/package.json +++ b/packages/x-bundle/package.json @@ -15,10 +15,132 @@ }, "sideEffects": false, "type": "module", - "version": "14.0.10", - "main": "index.js", + "version": "14.0.11", + "main": "./cjs/index.js", + "module": "./index.js", + "types": "./index.d.ts", + "exports": { + "./cjs/package.json": "./cjs/package.json", + "./cjs/*": "./cjs/*.js", + ".": { + "module": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "require": { + "types": "./cjs/index.d.ts", + "default": "./cjs/index.js" + }, + "default": { + "types": "./index.d.ts", + "default": "./index.js" + } + }, + "./buffer": { + "module": { + "types": "./buffer.d.ts", + "default": "./buffer.js" + }, + "require": { + "types": "./cjs/buffer.d.ts", + "default": "./cjs/buffer.js" + }, + "default": { + "types": "./buffer.d.ts", + "default": "./buffer.js" + } + }, + "./crypto": { + "module": { + "types": "./crypto.d.ts", + "default": "./crypto.js" + }, + "require": { + "types": "./cjs/crypto.d.ts", + "default": "./cjs/crypto.js" + }, + "default": { + "types": "./crypto.d.ts", + "default": "./crypto.js" + } + }, + "./dummy": { + "module": { + "types": "./dummy.d.ts", + "default": "./dummy.js" + }, + "require": { + "types": "./cjs/dummy.d.ts", + "default": "./cjs/dummy.js" + }, + "default": { + "types": "./dummy.d.ts", + "default": "./dummy.js" + } + }, + "./empty": { + "module": { + "types": "./empty.d.ts", + "default": "./empty.js" + }, + "require": { + "types": "./cjs/empty.d.ts", + "default": "./cjs/empty.js" + }, + "default": { + "types": "./empty.d.ts", + "default": "./empty.js" + } + }, + "./inherits": { + "module": { + "types": "./inherits.d.ts", + "default": "./inherits.js" + }, + "require": { + "types": "./cjs/inherits.d.ts", + "default": "./cjs/inherits.js" + }, + "default": { + "types": "./inherits.d.ts", + "default": "./inherits.js" + } + }, + "./package.json": { + "require": "./cjs/package.json", + "default": "./package.json" + }, + "./packageInfo.js": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./packageInfo": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + } + }, "dependencies": { - "@pezkuwi/util": "workspace:*", + "@pezkuwi/util": "14.0.11", "buffer-es6": "^4.9.3", "tslib": "^2.8.0" } diff --git a/packages/x-bundle/packageInfo.d.ts b/packages/x-bundle/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/x-bundle/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/x-bundle/packageInfo.js b/packages/x-bundle/packageInfo.js new file mode 100644 index 0000000..2e90cfc --- /dev/null +++ b/packages/x-bundle/packageInfo.js @@ -0,0 +1 @@ +export const packageInfo = { name: '@pezkuwi/x-bundle', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; diff --git a/packages/x-fetch/browser.d.ts b/packages/x-fetch/browser.d.ts new file mode 100644 index 0000000..390d662 --- /dev/null +++ b/packages/x-fetch/browser.d.ts @@ -0,0 +1,2 @@ +export { packageInfo } from './packageInfo.js'; +export declare const fetch: typeof globalThis.fetch; diff --git a/packages/x-fetch/browser.js b/packages/x-fetch/browser.js new file mode 100644 index 0000000..f924655 --- /dev/null +++ b/packages/x-fetch/browser.js @@ -0,0 +1,3 @@ +import { xglobal } from '@pezkuwi/x-global'; +export { packageInfo } from './packageInfo.js'; +export const fetch = xglobal.fetch; diff --git a/packages/x-fetch/cjs/browser.d.ts b/packages/x-fetch/cjs/browser.d.ts new file mode 100644 index 0000000..390d662 --- /dev/null +++ b/packages/x-fetch/cjs/browser.d.ts @@ -0,0 +1,2 @@ +export { packageInfo } from './packageInfo.js'; +export declare const fetch: typeof globalThis.fetch; diff --git a/packages/x-fetch/cjs/browser.js b/packages/x-fetch/cjs/browser.js new file mode 100644 index 0000000..e3c9704 --- /dev/null +++ b/packages/x-fetch/cjs/browser.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.fetch = exports.packageInfo = void 0; +const x_global_1 = require("@pezkuwi/x-global"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +exports.fetch = x_global_1.xglobal.fetch; diff --git a/packages/x-fetch/cjs/node.d.ts b/packages/x-fetch/cjs/node.d.ts new file mode 100644 index 0000000..390d662 --- /dev/null +++ b/packages/x-fetch/cjs/node.d.ts @@ -0,0 +1,2 @@ +export { packageInfo } from './packageInfo.js'; +export declare const fetch: typeof globalThis.fetch; diff --git a/packages/x-fetch/cjs/node.js b/packages/x-fetch/cjs/node.js new file mode 100644 index 0000000..949647e --- /dev/null +++ b/packages/x-fetch/cjs/node.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.fetch = exports.packageInfo = void 0; +const x_global_1 = require("@pezkuwi/x-global"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +const importFetch = import('node-fetch').catch(() => null); +let modFn = null; +async function nodeFetch(...args) { + if (!modFn) { + const mod = await importFetch; + if (!mod?.default) { + throw new Error('Unable to import node-fetch in this environment'); + } + modFn = mod.default; + } + return modFn(...args); +} +exports.fetch = (0, x_global_1.extractGlobal)('fetch', nodeFetch); diff --git a/packages/x-fetch/cjs/package.json b/packages/x-fetch/cjs/package.json new file mode 100644 index 0000000..5bbefff --- /dev/null +++ b/packages/x-fetch/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/x-fetch/cjs/packageInfo.d.ts b/packages/x-fetch/cjs/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/x-fetch/cjs/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/x-fetch/cjs/packageInfo.js b/packages/x-fetch/cjs/packageInfo.js new file mode 100644 index 0000000..05e028e --- /dev/null +++ b/packages/x-fetch/cjs/packageInfo.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +exports.packageInfo = { name: '@pezkuwi/x-fetch', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; diff --git a/packages/x-fetch/cjs/react-native.d.ts b/packages/x-fetch/cjs/react-native.d.ts new file mode 100644 index 0000000..c2429fa --- /dev/null +++ b/packages/x-fetch/cjs/react-native.d.ts @@ -0,0 +1 @@ +export * from './browser.js'; diff --git a/packages/x-fetch/cjs/react-native.js b/packages/x-fetch/cjs/react-native.js new file mode 100644 index 0000000..c0c4bdf --- /dev/null +++ b/packages/x-fetch/cjs/react-native.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +tslib_1.__exportStar(require("./browser.js"), exports); diff --git a/packages/x-fetch/cjs/shim.d.ts b/packages/x-fetch/cjs/shim.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/x-fetch/cjs/shim.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/x-fetch/cjs/shim.js b/packages/x-fetch/cjs/shim.js new file mode 100644 index 0000000..b76fd1c --- /dev/null +++ b/packages/x-fetch/cjs/shim.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const x_fetch_1 = require("@pezkuwi/x-fetch"); +const x_global_1 = require("@pezkuwi/x-global"); +(0, x_global_1.exposeGlobal)('fetch', x_fetch_1.fetch); diff --git a/packages/x-fetch/node.d.ts b/packages/x-fetch/node.d.ts new file mode 100644 index 0000000..390d662 --- /dev/null +++ b/packages/x-fetch/node.d.ts @@ -0,0 +1,2 @@ +export { packageInfo } from './packageInfo.js'; +export declare const fetch: typeof globalThis.fetch; diff --git a/packages/x-fetch/node.js b/packages/x-fetch/node.js new file mode 100644 index 0000000..0307dd1 --- /dev/null +++ b/packages/x-fetch/node.js @@ -0,0 +1,15 @@ +import { extractGlobal } from '@pezkuwi/x-global'; +export { packageInfo } from './packageInfo.js'; +const importFetch = import('node-fetch').catch(() => null); +let modFn = null; +async function nodeFetch(...args) { + if (!modFn) { + const mod = await importFetch; + if (!mod?.default) { + throw new Error('Unable to import node-fetch in this environment'); + } + modFn = mod.default; + } + return modFn(...args); +} +export const fetch = /*#__PURE__*/ extractGlobal('fetch', nodeFetch); diff --git a/packages/x-fetch/package.json b/packages/x-fetch/package.json index c25f97b..63b28c6 100644 --- a/packages/x-fetch/package.json +++ b/packages/x-fetch/package.json @@ -15,12 +15,165 @@ }, "sideEffects": false, "type": "module", - "version": "14.0.10", - "browser": "browser.js", - "main": "node.js", - "react-native": "react-native.js", + "version": "14.0.11", + "main": "./cjs/node.js", + "module": "./node.js", + "browser": "./cjs/browser.js", + "react-native": "./cjs/react-native.js", + "types": "./node.d.ts", + "exports": { + "./cjs/package.json": "./cjs/package.json", + "./cjs/*": "./cjs/*.js", + ".": { + "types": "./node.d.ts", + "react-native": { + "module": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + }, + "require": { + "types": "./cjs/react-native.d.ts", + "default": "./cjs/react-native.js" + }, + "default": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + } + }, + "browser": { + "module": { + "types": "./browser.d.ts", + "default": "./browser.js" + }, + "require": { + "types": "./cjs/browser.d.ts", + "default": "./cjs/browser.js" + }, + "default": { + "types": "./browser.d.ts", + "default": "./browser.js" + } + }, + "node": { + "module": { + "types": "./node.d.ts", + "default": "./node.js" + }, + "require": { + "types": "./cjs/node.d.ts", + "default": "./cjs/node.js" + }, + "default": { + "types": "./node.d.ts", + "default": "./node.js" + } + } + }, + "./browser": { + "module": { + "types": "./browser.d.ts", + "default": "./browser.js" + }, + "require": { + "types": "./cjs/browser.d.ts", + "default": "./cjs/browser.js" + }, + "default": { + "types": "./browser.d.ts", + "default": "./browser.js" + } + }, + "./node": { + "module": { + "types": "./node.d.ts", + "default": "./node.js" + }, + "require": { + "types": "./cjs/node.d.ts", + "default": "./cjs/node.js" + }, + "default": { + "types": "./node.d.ts", + "default": "./node.js" + } + }, + "./package.json": { + "require": "./cjs/package.json", + "default": "./package.json" + }, + "./packageInfo.js": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./packageInfo": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./react-native": { + "module": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + }, + "require": { + "types": "./cjs/react-native.d.ts", + "default": "./cjs/react-native.js" + }, + "default": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + } + }, + "./shim.js": { + "module": { + "types": "./shim.d.ts", + "default": "./shim.js" + }, + "require": { + "types": "./cjs/shim.d.ts", + "default": "./cjs/shim.js" + }, + "default": { + "types": "./shim.d.ts", + "default": "./shim.js" + } + }, + "./shim": { + "module": { + "types": "./shim.d.ts", + "default": "./shim.js" + }, + "require": { + "types": "./cjs/shim.d.ts", + "default": "./cjs/shim.js" + }, + "default": { + "types": "./shim.d.ts", + "default": "./shim.js" + } + } + }, "dependencies": { - "@pezkuwi/x-global": "workspace:*", + "@pezkuwi/x-global": "14.0.11", "node-fetch": "^3.3.2", "tslib": "^2.8.0" } diff --git a/packages/x-fetch/packageInfo.d.ts b/packages/x-fetch/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/x-fetch/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/x-fetch/packageInfo.js b/packages/x-fetch/packageInfo.js new file mode 100644 index 0000000..2f5998f --- /dev/null +++ b/packages/x-fetch/packageInfo.js @@ -0,0 +1 @@ +export const packageInfo = { name: '@pezkuwi/x-fetch', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; diff --git a/packages/x-fetch/react-native.d.ts b/packages/x-fetch/react-native.d.ts new file mode 100644 index 0000000..c2429fa --- /dev/null +++ b/packages/x-fetch/react-native.d.ts @@ -0,0 +1 @@ +export * from './browser.js'; diff --git a/packages/x-fetch/react-native.js b/packages/x-fetch/react-native.js new file mode 100644 index 0000000..c2429fa --- /dev/null +++ b/packages/x-fetch/react-native.js @@ -0,0 +1 @@ +export * from './browser.js'; diff --git a/packages/x-fetch/shim.d.ts b/packages/x-fetch/shim.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/x-fetch/shim.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/x-fetch/shim.js b/packages/x-fetch/shim.js new file mode 100644 index 0000000..a857fee --- /dev/null +++ b/packages/x-fetch/shim.js @@ -0,0 +1,3 @@ +import { fetch } from '@pezkuwi/x-fetch'; +import { exposeGlobal } from '@pezkuwi/x-global'; +exposeGlobal('fetch', fetch); diff --git a/packages/x-global/cjs/index.d.ts b/packages/x-global/cjs/index.d.ts new file mode 100644 index 0000000..97d9f0a --- /dev/null +++ b/packages/x-global/cjs/index.d.ts @@ -0,0 +1,21 @@ +export { packageInfo } from './packageInfo.js'; +type GlobalThis = typeof globalThis & { + process?: { + env?: Record; + }; + [key: string]: unknown; +}; +type GlobalNames = keyof typeof globalThis; +type GlobalType = typeof globalThis[N]; +/** + * A cross-environment implementation for globalThis + */ +export declare const xglobal: GlobalThis; +/** + * Extracts a known global from the environment, applying a fallback if not found + */ +export declare function extractGlobal>(name: N, fallback: unknown): T; +/** + * Expose a value as a known global, if not already defined + */ +export declare function exposeGlobal>(name: N, fallback: unknown): void; diff --git a/packages/x-global/cjs/index.js b/packages/x-global/cjs/index.js new file mode 100644 index 0000000..f360d1d --- /dev/null +++ b/packages/x-global/cjs/index.js @@ -0,0 +1,43 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.xglobal = exports.packageInfo = void 0; +exports.extractGlobal = extractGlobal; +exports.exposeGlobal = exposeGlobal; +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +/** @internal Last-resort "this", if it gets here it probably would fail anyway */ +function evaluateThis(fn) { + return fn('return this'); +} +/** + * A cross-environment implementation for globalThis + */ +exports.xglobal = (typeof globalThis !== 'undefined' + ? globalThis + : typeof global !== 'undefined' + ? global + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : evaluateThis(Function)); +/** + * Extracts a known global from the environment, applying a fallback if not found + */ +function extractGlobal(name, fallback) { + // Not quite sure why this is here - snuck in with TS 4.7.2 with no real idea + // (as of now) as to why this looks like an "any" when we do cast it to a T + // + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return typeof exports.xglobal[name] === 'undefined' + ? fallback + : exports.xglobal[name]; +} +/** + * Expose a value as a known global, if not already defined + */ +function exposeGlobal(name, fallback) { + if (typeof exports.xglobal[name] === 'undefined') { + exports.xglobal[name] = fallback; + } +} diff --git a/packages/x-global/cjs/package.json b/packages/x-global/cjs/package.json new file mode 100644 index 0000000..5bbefff --- /dev/null +++ b/packages/x-global/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/x-global/cjs/packageInfo.d.ts b/packages/x-global/cjs/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/x-global/cjs/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/x-global/cjs/packageInfo.js b/packages/x-global/cjs/packageInfo.js new file mode 100644 index 0000000..a3e552a --- /dev/null +++ b/packages/x-global/cjs/packageInfo.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +exports.packageInfo = { name: '@pezkuwi/x-global', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; diff --git a/packages/x-global/index.d.ts b/packages/x-global/index.d.ts new file mode 100644 index 0000000..97d9f0a --- /dev/null +++ b/packages/x-global/index.d.ts @@ -0,0 +1,21 @@ +export { packageInfo } from './packageInfo.js'; +type GlobalThis = typeof globalThis & { + process?: { + env?: Record; + }; + [key: string]: unknown; +}; +type GlobalNames = keyof typeof globalThis; +type GlobalType = typeof globalThis[N]; +/** + * A cross-environment implementation for globalThis + */ +export declare const xglobal: GlobalThis; +/** + * Extracts a known global from the environment, applying a fallback if not found + */ +export declare function extractGlobal>(name: N, fallback: unknown): T; +/** + * Expose a value as a known global, if not already defined + */ +export declare function exposeGlobal>(name: N, fallback: unknown): void; diff --git a/packages/x-global/index.js b/packages/x-global/index.js new file mode 100644 index 0000000..9eecc5d --- /dev/null +++ b/packages/x-global/index.js @@ -0,0 +1,37 @@ +export { packageInfo } from './packageInfo.js'; +/** @internal Last-resort "this", if it gets here it probably would fail anyway */ +function evaluateThis(fn) { + return fn('return this'); +} +/** + * A cross-environment implementation for globalThis + */ +export const xglobal = /*#__PURE__*/ (typeof globalThis !== 'undefined' + ? globalThis + : typeof global !== 'undefined' + ? global + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : evaluateThis(Function)); +/** + * Extracts a known global from the environment, applying a fallback if not found + */ +export function extractGlobal(name, fallback) { + // Not quite sure why this is here - snuck in with TS 4.7.2 with no real idea + // (as of now) as to why this looks like an "any" when we do cast it to a T + // + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return typeof xglobal[name] === 'undefined' + ? fallback + : xglobal[name]; +} +/** + * Expose a value as a known global, if not already defined + */ +export function exposeGlobal(name, fallback) { + if (typeof xglobal[name] === 'undefined') { + xglobal[name] = fallback; + } +} diff --git a/packages/x-global/package.json b/packages/x-global/package.json index 9f1a858..f75af37 100644 --- a/packages/x-global/package.json +++ b/packages/x-global/package.json @@ -15,8 +15,60 @@ }, "sideEffects": false, "type": "module", - "version": "14.0.10", - "main": "index.js", + "version": "14.0.11", + "main": "./cjs/index.js", + "module": "./index.js", + "types": "./index.d.ts", + "exports": { + "./cjs/package.json": "./cjs/package.json", + "./cjs/*": "./cjs/*.js", + ".": { + "module": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "require": { + "types": "./cjs/index.d.ts", + "default": "./cjs/index.js" + }, + "default": { + "types": "./index.d.ts", + "default": "./index.js" + } + }, + "./package.json": { + "require": "./cjs/package.json", + "default": "./package.json" + }, + "./packageInfo.js": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./packageInfo": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + } + }, "dependencies": { "tslib": "^2.8.0" } diff --git a/packages/x-global/packageInfo.d.ts b/packages/x-global/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/x-global/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/x-global/packageInfo.js b/packages/x-global/packageInfo.js new file mode 100644 index 0000000..f4bd34a --- /dev/null +++ b/packages/x-global/packageInfo.js @@ -0,0 +1 @@ +export const packageInfo = { name: '@pezkuwi/x-global', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; diff --git a/packages/x-randomvalues/browser.d.ts b/packages/x-randomvalues/browser.d.ts new file mode 100644 index 0000000..8e963ca --- /dev/null +++ b/packages/x-randomvalues/browser.d.ts @@ -0,0 +1,3 @@ +export { packageInfo } from './packageInfo.js'; +export declare const crypto: Crypto; +export declare function getRandomValues(arr: T): T; diff --git a/packages/x-randomvalues/browser.js b/packages/x-randomvalues/browser.js new file mode 100644 index 0000000..3fcdc40 --- /dev/null +++ b/packages/x-randomvalues/browser.js @@ -0,0 +1,6 @@ +import { xglobal } from '@pezkuwi/x-global'; +export { packageInfo } from './packageInfo.js'; +export const crypto = xglobal.crypto; +export function getRandomValues(arr) { + return crypto.getRandomValues(arr); +} diff --git a/packages/x-randomvalues/cjs/browser.d.ts b/packages/x-randomvalues/cjs/browser.d.ts new file mode 100644 index 0000000..8e963ca --- /dev/null +++ b/packages/x-randomvalues/cjs/browser.d.ts @@ -0,0 +1,3 @@ +export { packageInfo } from './packageInfo.js'; +export declare const crypto: Crypto; +export declare function getRandomValues(arr: T): T; diff --git a/packages/x-randomvalues/cjs/browser.js b/packages/x-randomvalues/cjs/browser.js new file mode 100644 index 0000000..2388f4b --- /dev/null +++ b/packages/x-randomvalues/cjs/browser.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.crypto = exports.packageInfo = void 0; +exports.getRandomValues = getRandomValues; +const x_global_1 = require("@pezkuwi/x-global"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +exports.crypto = x_global_1.xglobal.crypto; +function getRandomValues(arr) { + return exports.crypto.getRandomValues(arr); +} diff --git a/packages/x-randomvalues/cjs/fallback.d.ts b/packages/x-randomvalues/cjs/fallback.d.ts new file mode 100644 index 0000000..4bc46c2 --- /dev/null +++ b/packages/x-randomvalues/cjs/fallback.d.ts @@ -0,0 +1 @@ +export declare function insecureRandomValues(arr: T): T; diff --git a/packages/x-randomvalues/cjs/fallback.js b/packages/x-randomvalues/cjs/fallback.js new file mode 100644 index 0000000..2f60935 --- /dev/null +++ b/packages/x-randomvalues/cjs/fallback.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.insecureRandomValues = insecureRandomValues; +let warned = false; +function insecureRandomValues(arr) { + if (!warned) { + console.warn('Using an insecure random number generator, this should only happen when running in a debugger without support for crypto'); + warned = true; + } + let r = 0; + for (let i = 0, count = arr.length; i < count; i++) { + if ((i & 0b11) === 0) { + r = Math.random() * 0x100000000; + } + arr[i] = (r >>> ((i & 0b11) << 3)) & 0xff; + } + return arr; +} diff --git a/packages/x-randomvalues/cjs/node.d.ts b/packages/x-randomvalues/cjs/node.d.ts new file mode 100644 index 0000000..b1f5787 --- /dev/null +++ b/packages/x-randomvalues/cjs/node.d.ts @@ -0,0 +1,3 @@ +export { packageInfo } from './packageInfo.js'; +export declare const crypto: Crypto; +export declare function getRandomValues(output: T): T; diff --git a/packages/x-randomvalues/cjs/node.js b/packages/x-randomvalues/cjs/node.js new file mode 100644 index 0000000..b047984 --- /dev/null +++ b/packages/x-randomvalues/cjs/node.js @@ -0,0 +1,13 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.crypto = exports.packageInfo = void 0; +exports.getRandomValues = getRandomValues; +const tslib_1 = require("tslib"); +const node_crypto_1 = tslib_1.__importDefault(require("node:crypto")); +const x_global_1 = require("@pezkuwi/x-global"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +exports.crypto = (0, x_global_1.extractGlobal)('crypto', node_crypto_1.default.webcrypto); +function getRandomValues(output) { + return exports.crypto.getRandomValues(output); +} diff --git a/packages/x-randomvalues/cjs/package.json b/packages/x-randomvalues/cjs/package.json new file mode 100644 index 0000000..5bbefff --- /dev/null +++ b/packages/x-randomvalues/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/x-randomvalues/cjs/packageInfo.d.ts b/packages/x-randomvalues/cjs/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/x-randomvalues/cjs/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/x-randomvalues/cjs/packageInfo.js b/packages/x-randomvalues/cjs/packageInfo.js new file mode 100644 index 0000000..8b5c035 --- /dev/null +++ b/packages/x-randomvalues/cjs/packageInfo.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +exports.packageInfo = { name: '@pezkuwi/x-randomvalues', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; diff --git a/packages/x-randomvalues/cjs/react-native.d.ts b/packages/x-randomvalues/cjs/react-native.d.ts new file mode 100644 index 0000000..04870de --- /dev/null +++ b/packages/x-randomvalues/cjs/react-native.d.ts @@ -0,0 +1,12 @@ +export { packageInfo } from './packageInfo.js'; +/** + * @internal + * + * A getRandomValues util that detects and uses the available RN + * random utiliy generation functions. + **/ +declare function getRandomValuesRn(output: Uint8Array): Uint8Array; +export declare const getRandomValues: typeof getRandomValuesRn; +export declare const crypto: Crypto | { + getRandomValues: typeof getRandomValuesRn; +}; diff --git a/packages/x-randomvalues/cjs/react-native.js b/packages/x-randomvalues/cjs/react-native.js new file mode 100644 index 0000000..8542807 --- /dev/null +++ b/packages/x-randomvalues/cjs/react-native.js @@ -0,0 +1,35 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.crypto = exports.getRandomValues = exports.packageInfo = void 0; +const react_native_1 = require("react-native"); +const base64_1 = require("@pezkuwi/wasm-util/base64"); +const x_global_1 = require("@pezkuwi/x-global"); +const browser_js_1 = require("./browser.js"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +/** + * @internal + * + * A getRandomValues util that detects and uses the available RN + * random utiliy generation functions. + **/ +function getRandomValuesRn(output) { + if (!react_native_1.NativeModules['ExpoRandom'] && !react_native_1.NativeModules.RNGetRandomValues) { + throw new Error('No secure random number generator available. This environment does not support crypto.getRandomValues and no React Native secure RNG module is available.'); + } + return (0, base64_1.base64Decode)(react_native_1.NativeModules.RNGetRandomValues + ? react_native_1.NativeModules.RNGetRandomValues.getRandomBase64(output.length) + : react_native_1.NativeModules.ExpoRandom.getRandomBase64String(output.length), output); +} +const hasNativeRNModules = !!react_native_1.NativeModules['ExpoRandom'] || !!react_native_1.NativeModules.RNGetRandomValues; +const hasNativeCrypto = typeof x_global_1.xglobal.crypto === 'object' && typeof x_global_1.xglobal.crypto.getRandomValues === 'function'; +exports.getRandomValues = (hasNativeRNModules + ? getRandomValuesRn + : hasNativeCrypto + ? browser_js_1.getRandomValues + : () => { + throw new Error('No secure random number generator available. This environment does not support crypto.getRandomValues.'); + }); +exports.crypto = (exports.getRandomValues === browser_js_1.getRandomValues + ? browser_js_1.crypto + : { getRandomValues: exports.getRandomValues }); diff --git a/packages/x-randomvalues/cjs/shim.d.ts b/packages/x-randomvalues/cjs/shim.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/x-randomvalues/cjs/shim.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/x-randomvalues/cjs/shim.js b/packages/x-randomvalues/cjs/shim.js new file mode 100644 index 0000000..fcd8778 --- /dev/null +++ b/packages/x-randomvalues/cjs/shim.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const x_global_1 = require("@pezkuwi/x-global"); +const x_randomvalues_1 = require("@pezkuwi/x-randomvalues"); +(0, x_global_1.exposeGlobal)('crypto', x_randomvalues_1.crypto); diff --git a/packages/x-randomvalues/fallback.d.ts b/packages/x-randomvalues/fallback.d.ts new file mode 100644 index 0000000..4bc46c2 --- /dev/null +++ b/packages/x-randomvalues/fallback.d.ts @@ -0,0 +1 @@ +export declare function insecureRandomValues(arr: T): T; diff --git a/packages/x-randomvalues/fallback.js b/packages/x-randomvalues/fallback.js new file mode 100644 index 0000000..dd48368 --- /dev/null +++ b/packages/x-randomvalues/fallback.js @@ -0,0 +1,15 @@ +let warned = false; +export function insecureRandomValues(arr) { + if (!warned) { + console.warn('Using an insecure random number generator, this should only happen when running in a debugger without support for crypto'); + warned = true; + } + let r = 0; + for (let i = 0, count = arr.length; i < count; i++) { + if ((i & 0b11) === 0) { + r = Math.random() * 0x100000000; + } + arr[i] = (r >>> ((i & 0b11) << 3)) & 0xff; + } + return arr; +} diff --git a/packages/x-randomvalues/node.d.ts b/packages/x-randomvalues/node.d.ts new file mode 100644 index 0000000..b1f5787 --- /dev/null +++ b/packages/x-randomvalues/node.d.ts @@ -0,0 +1,3 @@ +export { packageInfo } from './packageInfo.js'; +export declare const crypto: Crypto; +export declare function getRandomValues(output: T): T; diff --git a/packages/x-randomvalues/node.js b/packages/x-randomvalues/node.js new file mode 100644 index 0000000..da84e34 --- /dev/null +++ b/packages/x-randomvalues/node.js @@ -0,0 +1,7 @@ +import nodeCrypto from 'node:crypto'; +import { extractGlobal } from '@pezkuwi/x-global'; +export { packageInfo } from './packageInfo.js'; +export const crypto = /*#__PURE__*/ extractGlobal('crypto', nodeCrypto.webcrypto); +export function getRandomValues(output) { + return crypto.getRandomValues(output); +} diff --git a/packages/x-randomvalues/package.json b/packages/x-randomvalues/package.json index 3bec1f4..1489512 100644 --- a/packages/x-randomvalues/package.json +++ b/packages/x-randomvalues/package.json @@ -15,21 +15,183 @@ }, "sideEffects": false, "type": "module", - "version": "14.0.10", - "browser": "browser.js", - "main": "node.js", - "react-native": "react-native.js", + "version": "14.0.11", + "main": "./cjs/node.js", + "module": "./node.js", + "browser": "./cjs/browser.js", + "react-native": "./cjs/react-native.js", + "types": "./node.d.ts", + "exports": { + "./cjs/package.json": "./cjs/package.json", + "./cjs/*": "./cjs/*.js", + ".": { + "types": "./node.d.ts", + "react-native": { + "module": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + }, + "require": { + "types": "./cjs/react-native.d.ts", + "default": "./cjs/react-native.js" + }, + "default": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + } + }, + "browser": { + "module": { + "types": "./browser.d.ts", + "default": "./browser.js" + }, + "require": { + "types": "./cjs/browser.d.ts", + "default": "./cjs/browser.js" + }, + "default": { + "types": "./browser.d.ts", + "default": "./browser.js" + } + }, + "node": { + "module": { + "types": "./node.d.ts", + "default": "./node.js" + }, + "require": { + "types": "./cjs/node.d.ts", + "default": "./cjs/node.js" + }, + "default": { + "types": "./node.d.ts", + "default": "./node.js" + } + } + }, + "./browser": { + "module": { + "types": "./browser.d.ts", + "default": "./browser.js" + }, + "require": { + "types": "./cjs/browser.d.ts", + "default": "./cjs/browser.js" + }, + "default": { + "types": "./browser.d.ts", + "default": "./browser.js" + } + }, + "./fallback": { + "module": { + "types": "./fallback.d.ts", + "default": "./fallback.js" + }, + "require": { + "types": "./cjs/fallback.d.ts", + "default": "./cjs/fallback.js" + }, + "default": { + "types": "./fallback.d.ts", + "default": "./fallback.js" + } + }, + "./node": { + "module": { + "types": "./node.d.ts", + "default": "./node.js" + }, + "require": { + "types": "./cjs/node.d.ts", + "default": "./cjs/node.js" + }, + "default": { + "types": "./node.d.ts", + "default": "./node.js" + } + }, + "./package.json": { + "require": "./cjs/package.json", + "default": "./package.json" + }, + "./packageInfo.js": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./packageInfo": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./react-native": { + "module": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + }, + "require": { + "types": "./cjs/react-native.d.ts", + "default": "./cjs/react-native.js" + }, + "default": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + } + }, + "./shim.js": { + "module": { + "types": "./shim.d.ts", + "default": "./shim.js" + }, + "require": { + "types": "./cjs/shim.d.ts", + "default": "./cjs/shim.js" + }, + "default": { + "types": "./shim.d.ts", + "default": "./shim.js" + } + }, + "./shim": { + "module": { + "types": "./shim.d.ts", + "default": "./shim.js" + }, + "require": { + "types": "./cjs/shim.d.ts", + "default": "./cjs/shim.js" + }, + "default": { + "types": "./shim.d.ts", + "default": "./shim.js" + } + } + }, "dependencies": { - "@pezkuwi/x-global": "workspace:*", + "@pezkuwi/x-global": "14.0.11", "tslib": "^2.8.0" }, - "devDependencies": { - "@pezkuwi/util": "workspace:*", - "@pezkuwi/wasm-util": "^7.5.3", - "@types/react-native": "^0.73.0" - }, "peerDependencies": { - "@pezkuwi/util": "workspace:*", + "@pezkuwi/util": "14.0.11", "@pezkuwi/wasm-util": "*" } } diff --git a/packages/x-randomvalues/packageInfo.d.ts b/packages/x-randomvalues/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/x-randomvalues/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/x-randomvalues/packageInfo.js b/packages/x-randomvalues/packageInfo.js new file mode 100644 index 0000000..edc87ba --- /dev/null +++ b/packages/x-randomvalues/packageInfo.js @@ -0,0 +1 @@ +export const packageInfo = { name: '@pezkuwi/x-randomvalues', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; diff --git a/packages/x-randomvalues/react-native.d.ts b/packages/x-randomvalues/react-native.d.ts new file mode 100644 index 0000000..04870de --- /dev/null +++ b/packages/x-randomvalues/react-native.d.ts @@ -0,0 +1,12 @@ +export { packageInfo } from './packageInfo.js'; +/** + * @internal + * + * A getRandomValues util that detects and uses the available RN + * random utiliy generation functions. + **/ +declare function getRandomValuesRn(output: Uint8Array): Uint8Array; +export declare const getRandomValues: typeof getRandomValuesRn; +export declare const crypto: Crypto | { + getRandomValues: typeof getRandomValuesRn; +}; diff --git a/packages/x-randomvalues/react-native.js b/packages/x-randomvalues/react-native.js new file mode 100644 index 0000000..cbd1b87 --- /dev/null +++ b/packages/x-randomvalues/react-native.js @@ -0,0 +1,31 @@ +import { NativeModules } from 'react-native'; +import { base64Decode } from '@pezkuwi/wasm-util/base64'; +import { xglobal } from '@pezkuwi/x-global'; +import { crypto as cryptoBrowser, getRandomValues as getRandomValuesBrowser } from './browser.js'; +export { packageInfo } from './packageInfo.js'; +/** + * @internal + * + * A getRandomValues util that detects and uses the available RN + * random utiliy generation functions. + **/ +function getRandomValuesRn(output) { + if (!NativeModules['ExpoRandom'] && !NativeModules.RNGetRandomValues) { + throw new Error('No secure random number generator available. This environment does not support crypto.getRandomValues and no React Native secure RNG module is available.'); + } + return base64Decode(NativeModules.RNGetRandomValues + ? NativeModules.RNGetRandomValues.getRandomBase64(output.length) + : NativeModules.ExpoRandom.getRandomBase64String(output.length), output); +} +const hasNativeRNModules = !!NativeModules['ExpoRandom'] || !!NativeModules.RNGetRandomValues; +const hasNativeCrypto = typeof xglobal.crypto === 'object' && typeof xglobal.crypto.getRandomValues === 'function'; +export const getRandomValues = (hasNativeRNModules + ? getRandomValuesRn + : hasNativeCrypto + ? getRandomValuesBrowser + : () => { + throw new Error('No secure random number generator available. This environment does not support crypto.getRandomValues.'); + }); +export const crypto = (getRandomValues === getRandomValuesBrowser + ? cryptoBrowser + : { getRandomValues }); diff --git a/packages/x-randomvalues/shim.d.ts b/packages/x-randomvalues/shim.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/x-randomvalues/shim.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/x-randomvalues/shim.js b/packages/x-randomvalues/shim.js new file mode 100644 index 0000000..207f640 --- /dev/null +++ b/packages/x-randomvalues/shim.js @@ -0,0 +1,3 @@ +import { exposeGlobal } from '@pezkuwi/x-global'; +import { crypto } from '@pezkuwi/x-randomvalues'; +exposeGlobal('crypto', crypto); diff --git a/packages/x-textdecoder/browser.d.ts b/packages/x-textdecoder/browser.d.ts new file mode 100644 index 0000000..ca06109 --- /dev/null +++ b/packages/x-textdecoder/browser.d.ts @@ -0,0 +1,5 @@ +export { packageInfo } from './packageInfo.js'; +export declare const TextDecoder: { + new (label?: string, options?: TextDecoderOptions): TextDecoder; + prototype: TextDecoder; +}; diff --git a/packages/x-textdecoder/browser.js b/packages/x-textdecoder/browser.js new file mode 100644 index 0000000..08b60e3 --- /dev/null +++ b/packages/x-textdecoder/browser.js @@ -0,0 +1,4 @@ +import { extractGlobal } from '@pezkuwi/x-global'; +import { TextDecoder as Fallback } from './fallback.js'; +export { packageInfo } from './packageInfo.js'; +export const TextDecoder = /*#__PURE__*/ extractGlobal('TextDecoder', Fallback); diff --git a/packages/x-textdecoder/cjs/browser.d.ts b/packages/x-textdecoder/cjs/browser.d.ts new file mode 100644 index 0000000..ca06109 --- /dev/null +++ b/packages/x-textdecoder/cjs/browser.d.ts @@ -0,0 +1,5 @@ +export { packageInfo } from './packageInfo.js'; +export declare const TextDecoder: { + new (label?: string, options?: TextDecoderOptions): TextDecoder; + prototype: TextDecoder; +}; diff --git a/packages/x-textdecoder/cjs/browser.js b/packages/x-textdecoder/cjs/browser.js new file mode 100644 index 0000000..79982b1 --- /dev/null +++ b/packages/x-textdecoder/cjs/browser.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TextDecoder = exports.packageInfo = void 0; +const x_global_1 = require("@pezkuwi/x-global"); +const fallback_js_1 = require("./fallback.js"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +exports.TextDecoder = (0, x_global_1.extractGlobal)('TextDecoder', fallback_js_1.TextDecoder); diff --git a/packages/x-textdecoder/cjs/fallback.d.ts b/packages/x-textdecoder/cjs/fallback.d.ts new file mode 100644 index 0000000..71caef5 --- /dev/null +++ b/packages/x-textdecoder/cjs/fallback.d.ts @@ -0,0 +1,5 @@ +export declare class TextDecoder { + __encoding?: string; + constructor(encoding?: 'utf-8' | 'utf8'); + decode(value: Uint8Array): string; +} diff --git a/packages/x-textdecoder/cjs/fallback.js b/packages/x-textdecoder/cjs/fallback.js new file mode 100644 index 0000000..3bba69f --- /dev/null +++ b/packages/x-textdecoder/cjs/fallback.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TextDecoder = void 0; +class TextDecoder { + __encoding; + constructor(encoding) { + this.__encoding = encoding; + } + decode(value) { + let result = ''; + for (let i = 0, count = value.length; i < count; i++) { + result += String.fromCharCode(value[i]); + } + return result; + } +} +exports.TextDecoder = TextDecoder; diff --git a/packages/x-textdecoder/cjs/node.d.ts b/packages/x-textdecoder/cjs/node.d.ts new file mode 100644 index 0000000..ca06109 --- /dev/null +++ b/packages/x-textdecoder/cjs/node.d.ts @@ -0,0 +1,5 @@ +export { packageInfo } from './packageInfo.js'; +export declare const TextDecoder: { + new (label?: string, options?: TextDecoderOptions): TextDecoder; + prototype: TextDecoder; +}; diff --git a/packages/x-textdecoder/cjs/node.js b/packages/x-textdecoder/cjs/node.js new file mode 100644 index 0000000..8efa711 --- /dev/null +++ b/packages/x-textdecoder/cjs/node.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TextDecoder = exports.packageInfo = void 0; +const tslib_1 = require("tslib"); +const node_util_1 = tslib_1.__importDefault(require("node:util")); +const x_global_1 = require("@pezkuwi/x-global"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +exports.TextDecoder = (0, x_global_1.extractGlobal)('TextDecoder', node_util_1.default.TextDecoder); diff --git a/packages/x-textdecoder/cjs/package.json b/packages/x-textdecoder/cjs/package.json new file mode 100644 index 0000000..5bbefff --- /dev/null +++ b/packages/x-textdecoder/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/x-textdecoder/cjs/packageInfo.d.ts b/packages/x-textdecoder/cjs/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/x-textdecoder/cjs/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/x-textdecoder/cjs/packageInfo.js b/packages/x-textdecoder/cjs/packageInfo.js new file mode 100644 index 0000000..24ebaec --- /dev/null +++ b/packages/x-textdecoder/cjs/packageInfo.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +exports.packageInfo = { name: '@pezkuwi/x-textdecoder', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; diff --git a/packages/x-textdecoder/cjs/react-native.d.ts b/packages/x-textdecoder/cjs/react-native.d.ts new file mode 100644 index 0000000..c2429fa --- /dev/null +++ b/packages/x-textdecoder/cjs/react-native.d.ts @@ -0,0 +1 @@ +export * from './browser.js'; diff --git a/packages/x-textdecoder/cjs/react-native.js b/packages/x-textdecoder/cjs/react-native.js new file mode 100644 index 0000000..c0c4bdf --- /dev/null +++ b/packages/x-textdecoder/cjs/react-native.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +tslib_1.__exportStar(require("./browser.js"), exports); diff --git a/packages/x-textdecoder/cjs/shim.d.ts b/packages/x-textdecoder/cjs/shim.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/x-textdecoder/cjs/shim.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/x-textdecoder/cjs/shim.js b/packages/x-textdecoder/cjs/shim.js new file mode 100644 index 0000000..83591c5 --- /dev/null +++ b/packages/x-textdecoder/cjs/shim.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const x_global_1 = require("@pezkuwi/x-global"); +const x_textdecoder_1 = require("@pezkuwi/x-textdecoder"); +(0, x_global_1.exposeGlobal)('TextDecoder', x_textdecoder_1.TextDecoder); diff --git a/packages/x-textdecoder/cjs/typeCheck.d.ts b/packages/x-textdecoder/cjs/typeCheck.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/x-textdecoder/cjs/typeCheck.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/x-textdecoder/cjs/typeCheck.js b/packages/x-textdecoder/cjs/typeCheck.js new file mode 100644 index 0000000..2c2bb26 --- /dev/null +++ b/packages/x-textdecoder/cjs/typeCheck.js @@ -0,0 +1,6 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const browser_js_1 = require("./browser.js"); +const node_js_1 = require("./node.js"); +console.log(new browser_js_1.TextDecoder('utf-8').decode(new Uint8Array([1, 2, 3]))); +console.log(new node_js_1.TextDecoder('utf-8').decode(new Uint8Array([1, 2, 3]))); diff --git a/packages/x-textdecoder/fallback.d.ts b/packages/x-textdecoder/fallback.d.ts new file mode 100644 index 0000000..71caef5 --- /dev/null +++ b/packages/x-textdecoder/fallback.d.ts @@ -0,0 +1,5 @@ +export declare class TextDecoder { + __encoding?: string; + constructor(encoding?: 'utf-8' | 'utf8'); + decode(value: Uint8Array): string; +} diff --git a/packages/x-textdecoder/fallback.js b/packages/x-textdecoder/fallback.js new file mode 100644 index 0000000..5404199 --- /dev/null +++ b/packages/x-textdecoder/fallback.js @@ -0,0 +1,13 @@ +export class TextDecoder { + __encoding; + constructor(encoding) { + this.__encoding = encoding; + } + decode(value) { + let result = ''; + for (let i = 0, count = value.length; i < count; i++) { + result += String.fromCharCode(value[i]); + } + return result; + } +} diff --git a/packages/x-textdecoder/node.d.ts b/packages/x-textdecoder/node.d.ts new file mode 100644 index 0000000..ca06109 --- /dev/null +++ b/packages/x-textdecoder/node.d.ts @@ -0,0 +1,5 @@ +export { packageInfo } from './packageInfo.js'; +export declare const TextDecoder: { + new (label?: string, options?: TextDecoderOptions): TextDecoder; + prototype: TextDecoder; +}; diff --git a/packages/x-textdecoder/node.js b/packages/x-textdecoder/node.js new file mode 100644 index 0000000..6872d8e --- /dev/null +++ b/packages/x-textdecoder/node.js @@ -0,0 +1,4 @@ +import util from 'node:util'; +import { extractGlobal } from '@pezkuwi/x-global'; +export { packageInfo } from './packageInfo.js'; +export const TextDecoder = /*#__PURE__*/ extractGlobal('TextDecoder', util.TextDecoder); diff --git a/packages/x-textdecoder/package.json b/packages/x-textdecoder/package.json index bdbf1a5..8056abb 100644 --- a/packages/x-textdecoder/package.json +++ b/packages/x-textdecoder/package.json @@ -15,12 +15,193 @@ }, "sideEffects": false, "type": "module", - "version": "14.0.10", - "browser": "browser.js", - "main": "node.js", - "react-native": "react-native.js", + "version": "14.0.11", + "main": "./cjs/node.js", + "module": "./node.js", + "browser": "./cjs/browser.js", + "react-native": "./cjs/react-native.js", + "types": "./node.d.ts", + "exports": { + "./cjs/package.json": "./cjs/package.json", + "./cjs/*": "./cjs/*.js", + ".": { + "types": "./node.d.ts", + "react-native": { + "module": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + }, + "require": { + "types": "./cjs/react-native.d.ts", + "default": "./cjs/react-native.js" + }, + "default": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + } + }, + "browser": { + "module": { + "types": "./browser.d.ts", + "default": "./browser.js" + }, + "require": { + "types": "./cjs/browser.d.ts", + "default": "./cjs/browser.js" + }, + "default": { + "types": "./browser.d.ts", + "default": "./browser.js" + } + }, + "node": { + "module": { + "types": "./node.d.ts", + "default": "./node.js" + }, + "require": { + "types": "./cjs/node.d.ts", + "default": "./cjs/node.js" + }, + "default": { + "types": "./node.d.ts", + "default": "./node.js" + } + } + }, + "./browser": { + "module": { + "types": "./browser.d.ts", + "default": "./browser.js" + }, + "require": { + "types": "./cjs/browser.d.ts", + "default": "./cjs/browser.js" + }, + "default": { + "types": "./browser.d.ts", + "default": "./browser.js" + } + }, + "./fallback": { + "module": { + "types": "./fallback.d.ts", + "default": "./fallback.js" + }, + "require": { + "types": "./cjs/fallback.d.ts", + "default": "./cjs/fallback.js" + }, + "default": { + "types": "./fallback.d.ts", + "default": "./fallback.js" + } + }, + "./node": { + "module": { + "types": "./node.d.ts", + "default": "./node.js" + }, + "require": { + "types": "./cjs/node.d.ts", + "default": "./cjs/node.js" + }, + "default": { + "types": "./node.d.ts", + "default": "./node.js" + } + }, + "./package.json": { + "require": "./cjs/package.json", + "default": "./package.json" + }, + "./packageInfo.js": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./packageInfo": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./react-native": { + "module": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + }, + "require": { + "types": "./cjs/react-native.d.ts", + "default": "./cjs/react-native.js" + }, + "default": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + } + }, + "./shim.js": { + "module": { + "types": "./shim.d.ts", + "default": "./shim.js" + }, + "require": { + "types": "./cjs/shim.d.ts", + "default": "./cjs/shim.js" + }, + "default": { + "types": "./shim.d.ts", + "default": "./shim.js" + } + }, + "./shim": { + "module": { + "types": "./shim.d.ts", + "default": "./shim.js" + }, + "require": { + "types": "./cjs/shim.d.ts", + "default": "./cjs/shim.js" + }, + "default": { + "types": "./shim.d.ts", + "default": "./shim.js" + } + }, + "./typeCheck": { + "module": { + "types": "./typeCheck.d.ts", + "default": "./typeCheck.js" + }, + "require": { + "types": "./cjs/typeCheck.d.ts", + "default": "./cjs/typeCheck.js" + }, + "default": { + "types": "./typeCheck.d.ts", + "default": "./typeCheck.js" + } + } + }, "dependencies": { - "@pezkuwi/x-global": "workspace:*", + "@pezkuwi/x-global": "14.0.11", "tslib": "^2.8.0" } } diff --git a/packages/x-textdecoder/packageInfo.d.ts b/packages/x-textdecoder/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/x-textdecoder/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/x-textdecoder/packageInfo.js b/packages/x-textdecoder/packageInfo.js new file mode 100644 index 0000000..04b7c5e --- /dev/null +++ b/packages/x-textdecoder/packageInfo.js @@ -0,0 +1 @@ +export const packageInfo = { name: '@pezkuwi/x-textdecoder', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; diff --git a/packages/x-textdecoder/react-native.d.ts b/packages/x-textdecoder/react-native.d.ts new file mode 100644 index 0000000..c2429fa --- /dev/null +++ b/packages/x-textdecoder/react-native.d.ts @@ -0,0 +1 @@ +export * from './browser.js'; diff --git a/packages/x-textdecoder/react-native.js b/packages/x-textdecoder/react-native.js new file mode 100644 index 0000000..c2429fa --- /dev/null +++ b/packages/x-textdecoder/react-native.js @@ -0,0 +1 @@ +export * from './browser.js'; diff --git a/packages/x-textdecoder/shim.d.ts b/packages/x-textdecoder/shim.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/x-textdecoder/shim.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/x-textdecoder/shim.js b/packages/x-textdecoder/shim.js new file mode 100644 index 0000000..78e3f57 --- /dev/null +++ b/packages/x-textdecoder/shim.js @@ -0,0 +1,3 @@ +import { exposeGlobal } from '@pezkuwi/x-global'; +import { TextDecoder } from '@pezkuwi/x-textdecoder'; +exposeGlobal('TextDecoder', TextDecoder); diff --git a/packages/x-textdecoder/typeCheck.d.ts b/packages/x-textdecoder/typeCheck.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/x-textdecoder/typeCheck.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/x-textdecoder/typeCheck.js b/packages/x-textdecoder/typeCheck.js new file mode 100644 index 0000000..6ff5135 --- /dev/null +++ b/packages/x-textdecoder/typeCheck.js @@ -0,0 +1,4 @@ +import { TextDecoder as BrowserTD } from './browser.js'; +import { TextDecoder as NodeTD } from './node.js'; +console.log(new BrowserTD('utf-8').decode(new Uint8Array([1, 2, 3]))); +console.log(new NodeTD('utf-8').decode(new Uint8Array([1, 2, 3]))); diff --git a/packages/x-textencoder/browser.d.ts b/packages/x-textencoder/browser.d.ts new file mode 100644 index 0000000..b458eaf --- /dev/null +++ b/packages/x-textencoder/browser.d.ts @@ -0,0 +1,5 @@ +export { packageInfo } from './packageInfo.js'; +export declare const TextEncoder: { + new (): TextEncoder; + prototype: TextEncoder; +}; diff --git a/packages/x-textencoder/browser.js b/packages/x-textencoder/browser.js new file mode 100644 index 0000000..f165f62 --- /dev/null +++ b/packages/x-textencoder/browser.js @@ -0,0 +1,4 @@ +import { extractGlobal } from '@pezkuwi/x-global'; +import { TextEncoder as Fallback } from './fallback.js'; +export { packageInfo } from './packageInfo.js'; +export const TextEncoder = /*#__PURE__*/ extractGlobal('TextEncoder', Fallback); diff --git a/packages/x-textencoder/cjs/browser.d.ts b/packages/x-textencoder/cjs/browser.d.ts new file mode 100644 index 0000000..b458eaf --- /dev/null +++ b/packages/x-textencoder/cjs/browser.d.ts @@ -0,0 +1,5 @@ +export { packageInfo } from './packageInfo.js'; +export declare const TextEncoder: { + new (): TextEncoder; + prototype: TextEncoder; +}; diff --git a/packages/x-textencoder/cjs/browser.js b/packages/x-textencoder/cjs/browser.js new file mode 100644 index 0000000..b1f4921 --- /dev/null +++ b/packages/x-textencoder/cjs/browser.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TextEncoder = exports.packageInfo = void 0; +const x_global_1 = require("@pezkuwi/x-global"); +const fallback_js_1 = require("./fallback.js"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +exports.TextEncoder = (0, x_global_1.extractGlobal)('TextEncoder', fallback_js_1.TextEncoder); diff --git a/packages/x-textencoder/cjs/fallback.d.ts b/packages/x-textencoder/cjs/fallback.d.ts new file mode 100644 index 0000000..dee5407 --- /dev/null +++ b/packages/x-textencoder/cjs/fallback.d.ts @@ -0,0 +1,3 @@ +export declare class TextEncoder { + encode(value: string): Uint8Array; +} diff --git a/packages/x-textencoder/cjs/fallback.js b/packages/x-textencoder/cjs/fallback.js new file mode 100644 index 0000000..adce8f2 --- /dev/null +++ b/packages/x-textencoder/cjs/fallback.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TextEncoder = void 0; +class TextEncoder { + encode(value) { + const count = value.length; + const u8a = new Uint8Array(count); + for (let i = 0; i < count; i++) { + u8a[i] = value.charCodeAt(i); + } + return u8a; + } +} +exports.TextEncoder = TextEncoder; diff --git a/packages/x-textencoder/cjs/node.d.ts b/packages/x-textencoder/cjs/node.d.ts new file mode 100644 index 0000000..b458eaf --- /dev/null +++ b/packages/x-textencoder/cjs/node.d.ts @@ -0,0 +1,5 @@ +export { packageInfo } from './packageInfo.js'; +export declare const TextEncoder: { + new (): TextEncoder; + prototype: TextEncoder; +}; diff --git a/packages/x-textencoder/cjs/node.js b/packages/x-textencoder/cjs/node.js new file mode 100644 index 0000000..64e117b --- /dev/null +++ b/packages/x-textencoder/cjs/node.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TextEncoder = exports.packageInfo = void 0; +const tslib_1 = require("tslib"); +const node_util_1 = tslib_1.__importDefault(require("node:util")); +const x_global_1 = require("@pezkuwi/x-global"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +class Fallback { + #encoder; + constructor() { + this.#encoder = new node_util_1.default.TextEncoder(); + } + // For a Jest 26.0.1 environment, Buffer !== Uint8Array + encode(value) { + return Uint8Array.from(this.#encoder.encode(value)); + } +} +exports.TextEncoder = (0, x_global_1.extractGlobal)('TextEncoder', Fallback); diff --git a/packages/x-textencoder/cjs/package.json b/packages/x-textencoder/cjs/package.json new file mode 100644 index 0000000..5bbefff --- /dev/null +++ b/packages/x-textencoder/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/x-textencoder/cjs/packageInfo.d.ts b/packages/x-textencoder/cjs/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/x-textencoder/cjs/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/x-textencoder/cjs/packageInfo.js b/packages/x-textencoder/cjs/packageInfo.js new file mode 100644 index 0000000..62b30f3 --- /dev/null +++ b/packages/x-textencoder/cjs/packageInfo.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +exports.packageInfo = { name: '@pezkuwi/x-textencoder', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; diff --git a/packages/x-textencoder/cjs/react-native.d.ts b/packages/x-textencoder/cjs/react-native.d.ts new file mode 100644 index 0000000..c2429fa --- /dev/null +++ b/packages/x-textencoder/cjs/react-native.d.ts @@ -0,0 +1 @@ +export * from './browser.js'; diff --git a/packages/x-textencoder/cjs/react-native.js b/packages/x-textencoder/cjs/react-native.js new file mode 100644 index 0000000..c0c4bdf --- /dev/null +++ b/packages/x-textencoder/cjs/react-native.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +tslib_1.__exportStar(require("./browser.js"), exports); diff --git a/packages/x-textencoder/cjs/shim.d.ts b/packages/x-textencoder/cjs/shim.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/x-textencoder/cjs/shim.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/x-textencoder/cjs/shim.js b/packages/x-textencoder/cjs/shim.js new file mode 100644 index 0000000..543d719 --- /dev/null +++ b/packages/x-textencoder/cjs/shim.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const x_global_1 = require("@pezkuwi/x-global"); +const x_textencoder_1 = require("@pezkuwi/x-textencoder"); +(0, x_global_1.exposeGlobal)('TextEncoder', x_textencoder_1.TextEncoder); diff --git a/packages/x-textencoder/cjs/typeCheck.d.ts b/packages/x-textencoder/cjs/typeCheck.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/x-textencoder/cjs/typeCheck.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/x-textencoder/cjs/typeCheck.js b/packages/x-textencoder/cjs/typeCheck.js new file mode 100644 index 0000000..70b3605 --- /dev/null +++ b/packages/x-textencoder/cjs/typeCheck.js @@ -0,0 +1,6 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const browser_js_1 = require("./browser.js"); +const node_js_1 = require("./node.js"); +console.log(new browser_js_1.TextEncoder().encode('abc')); +console.log(new node_js_1.TextEncoder().encode('abc')); diff --git a/packages/x-textencoder/fallback.d.ts b/packages/x-textencoder/fallback.d.ts new file mode 100644 index 0000000..dee5407 --- /dev/null +++ b/packages/x-textencoder/fallback.d.ts @@ -0,0 +1,3 @@ +export declare class TextEncoder { + encode(value: string): Uint8Array; +} diff --git a/packages/x-textencoder/fallback.js b/packages/x-textencoder/fallback.js new file mode 100644 index 0000000..45e7b65 --- /dev/null +++ b/packages/x-textencoder/fallback.js @@ -0,0 +1,10 @@ +export class TextEncoder { + encode(value) { + const count = value.length; + const u8a = new Uint8Array(count); + for (let i = 0; i < count; i++) { + u8a[i] = value.charCodeAt(i); + } + return u8a; + } +} diff --git a/packages/x-textencoder/node.d.ts b/packages/x-textencoder/node.d.ts new file mode 100644 index 0000000..b458eaf --- /dev/null +++ b/packages/x-textencoder/node.d.ts @@ -0,0 +1,5 @@ +export { packageInfo } from './packageInfo.js'; +export declare const TextEncoder: { + new (): TextEncoder; + prototype: TextEncoder; +}; diff --git a/packages/x-textencoder/node.js b/packages/x-textencoder/node.js new file mode 100644 index 0000000..b3e912a --- /dev/null +++ b/packages/x-textencoder/node.js @@ -0,0 +1,14 @@ +import util from 'node:util'; +import { extractGlobal } from '@pezkuwi/x-global'; +export { packageInfo } from './packageInfo.js'; +class Fallback { + #encoder; + constructor() { + this.#encoder = new util.TextEncoder(); + } + // For a Jest 26.0.1 environment, Buffer !== Uint8Array + encode(value) { + return Uint8Array.from(this.#encoder.encode(value)); + } +} +export const TextEncoder = /*#__PURE__*/ extractGlobal('TextEncoder', Fallback); diff --git a/packages/x-textencoder/package.json b/packages/x-textencoder/package.json index 2592c5d..cbc7346 100644 --- a/packages/x-textencoder/package.json +++ b/packages/x-textencoder/package.json @@ -15,12 +15,193 @@ }, "sideEffects": false, "type": "module", - "version": "14.0.10", - "browser": "browser.js", - "main": "node.js", - "react-native": "react-native.js", + "version": "14.0.11", + "main": "./cjs/node.js", + "module": "./node.js", + "browser": "./cjs/browser.js", + "react-native": "./cjs/react-native.js", + "types": "./node.d.ts", + "exports": { + "./cjs/package.json": "./cjs/package.json", + "./cjs/*": "./cjs/*.js", + ".": { + "types": "./node.d.ts", + "react-native": { + "module": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + }, + "require": { + "types": "./cjs/react-native.d.ts", + "default": "./cjs/react-native.js" + }, + "default": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + } + }, + "browser": { + "module": { + "types": "./browser.d.ts", + "default": "./browser.js" + }, + "require": { + "types": "./cjs/browser.d.ts", + "default": "./cjs/browser.js" + }, + "default": { + "types": "./browser.d.ts", + "default": "./browser.js" + } + }, + "node": { + "module": { + "types": "./node.d.ts", + "default": "./node.js" + }, + "require": { + "types": "./cjs/node.d.ts", + "default": "./cjs/node.js" + }, + "default": { + "types": "./node.d.ts", + "default": "./node.js" + } + } + }, + "./browser": { + "module": { + "types": "./browser.d.ts", + "default": "./browser.js" + }, + "require": { + "types": "./cjs/browser.d.ts", + "default": "./cjs/browser.js" + }, + "default": { + "types": "./browser.d.ts", + "default": "./browser.js" + } + }, + "./fallback": { + "module": { + "types": "./fallback.d.ts", + "default": "./fallback.js" + }, + "require": { + "types": "./cjs/fallback.d.ts", + "default": "./cjs/fallback.js" + }, + "default": { + "types": "./fallback.d.ts", + "default": "./fallback.js" + } + }, + "./node": { + "module": { + "types": "./node.d.ts", + "default": "./node.js" + }, + "require": { + "types": "./cjs/node.d.ts", + "default": "./cjs/node.js" + }, + "default": { + "types": "./node.d.ts", + "default": "./node.js" + } + }, + "./package.json": { + "require": "./cjs/package.json", + "default": "./package.json" + }, + "./packageInfo.js": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./packageInfo": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./react-native": { + "module": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + }, + "require": { + "types": "./cjs/react-native.d.ts", + "default": "./cjs/react-native.js" + }, + "default": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + } + }, + "./shim.js": { + "module": { + "types": "./shim.d.ts", + "default": "./shim.js" + }, + "require": { + "types": "./cjs/shim.d.ts", + "default": "./cjs/shim.js" + }, + "default": { + "types": "./shim.d.ts", + "default": "./shim.js" + } + }, + "./shim": { + "module": { + "types": "./shim.d.ts", + "default": "./shim.js" + }, + "require": { + "types": "./cjs/shim.d.ts", + "default": "./cjs/shim.js" + }, + "default": { + "types": "./shim.d.ts", + "default": "./shim.js" + } + }, + "./typeCheck": { + "module": { + "types": "./typeCheck.d.ts", + "default": "./typeCheck.js" + }, + "require": { + "types": "./cjs/typeCheck.d.ts", + "default": "./cjs/typeCheck.js" + }, + "default": { + "types": "./typeCheck.d.ts", + "default": "./typeCheck.js" + } + } + }, "dependencies": { - "@pezkuwi/x-global": "workspace:*", + "@pezkuwi/x-global": "14.0.11", "tslib": "^2.8.0" } } diff --git a/packages/x-textencoder/packageInfo.d.ts b/packages/x-textencoder/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/x-textencoder/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/x-textencoder/packageInfo.js b/packages/x-textencoder/packageInfo.js new file mode 100644 index 0000000..02a48a6 --- /dev/null +++ b/packages/x-textencoder/packageInfo.js @@ -0,0 +1 @@ +export const packageInfo = { name: '@pezkuwi/x-textencoder', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; diff --git a/packages/x-textencoder/react-native.d.ts b/packages/x-textencoder/react-native.d.ts new file mode 100644 index 0000000..c2429fa --- /dev/null +++ b/packages/x-textencoder/react-native.d.ts @@ -0,0 +1 @@ +export * from './browser.js'; diff --git a/packages/x-textencoder/react-native.js b/packages/x-textencoder/react-native.js new file mode 100644 index 0000000..c2429fa --- /dev/null +++ b/packages/x-textencoder/react-native.js @@ -0,0 +1 @@ +export * from './browser.js'; diff --git a/packages/x-textencoder/shim.d.ts b/packages/x-textencoder/shim.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/x-textencoder/shim.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/x-textencoder/shim.js b/packages/x-textencoder/shim.js new file mode 100644 index 0000000..8d727d6 --- /dev/null +++ b/packages/x-textencoder/shim.js @@ -0,0 +1,3 @@ +import { exposeGlobal } from '@pezkuwi/x-global'; +import { TextEncoder } from '@pezkuwi/x-textencoder'; +exposeGlobal('TextEncoder', TextEncoder); diff --git a/packages/x-textencoder/typeCheck.d.ts b/packages/x-textencoder/typeCheck.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/x-textencoder/typeCheck.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/x-textencoder/typeCheck.js b/packages/x-textencoder/typeCheck.js new file mode 100644 index 0000000..c9feaea --- /dev/null +++ b/packages/x-textencoder/typeCheck.js @@ -0,0 +1,4 @@ +import { TextEncoder as BrowserTE } from './browser.js'; +import { TextEncoder as NodeTE } from './node.js'; +console.log(new BrowserTE().encode('abc')); +console.log(new NodeTE().encode('abc')); diff --git a/packages/x-ws/browser.d.ts b/packages/x-ws/browser.d.ts new file mode 100644 index 0000000..18779bf --- /dev/null +++ b/packages/x-ws/browser.d.ts @@ -0,0 +1,9 @@ +export { packageInfo } from './packageInfo.js'; +export declare const WebSocket: { + new (url: string | URL, protocols?: string | string[]): WebSocket; + prototype: WebSocket; + readonly CONNECTING: 0; + readonly OPEN: 1; + readonly CLOSING: 2; + readonly CLOSED: 3; +}; diff --git a/packages/x-ws/browser.js b/packages/x-ws/browser.js new file mode 100644 index 0000000..d0baf57 --- /dev/null +++ b/packages/x-ws/browser.js @@ -0,0 +1,3 @@ +import { xglobal } from '@pezkuwi/x-global'; +export { packageInfo } from './packageInfo.js'; +export const WebSocket = xglobal.WebSocket; diff --git a/packages/x-ws/cjs/browser.d.ts b/packages/x-ws/cjs/browser.d.ts new file mode 100644 index 0000000..18779bf --- /dev/null +++ b/packages/x-ws/cjs/browser.d.ts @@ -0,0 +1,9 @@ +export { packageInfo } from './packageInfo.js'; +export declare const WebSocket: { + new (url: string | URL, protocols?: string | string[]): WebSocket; + prototype: WebSocket; + readonly CONNECTING: 0; + readonly OPEN: 1; + readonly CLOSING: 2; + readonly CLOSED: 3; +}; diff --git a/packages/x-ws/cjs/browser.js b/packages/x-ws/cjs/browser.js new file mode 100644 index 0000000..4c07705 --- /dev/null +++ b/packages/x-ws/cjs/browser.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.WebSocket = exports.packageInfo = void 0; +const x_global_1 = require("@pezkuwi/x-global"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +exports.WebSocket = x_global_1.xglobal.WebSocket; diff --git a/packages/x-ws/cjs/node.d.ts b/packages/x-ws/cjs/node.d.ts new file mode 100644 index 0000000..18779bf --- /dev/null +++ b/packages/x-ws/cjs/node.d.ts @@ -0,0 +1,9 @@ +export { packageInfo } from './packageInfo.js'; +export declare const WebSocket: { + new (url: string | URL, protocols?: string | string[]): WebSocket; + prototype: WebSocket; + readonly CONNECTING: 0; + readonly OPEN: 1; + readonly CLOSING: 2; + readonly CLOSED: 3; +}; diff --git a/packages/x-ws/cjs/node.js b/packages/x-ws/cjs/node.js new file mode 100644 index 0000000..b4b5f19 --- /dev/null +++ b/packages/x-ws/cjs/node.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.WebSocket = exports.packageInfo = void 0; +const tslib_1 = require("tslib"); +const ws_1 = tslib_1.__importDefault(require("ws")); +const x_global_1 = require("@pezkuwi/x-global"); +var packageInfo_js_1 = require("./packageInfo.js"); +Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } }); +exports.WebSocket = (0, x_global_1.extractGlobal)('WebSocket', ws_1.default); diff --git a/packages/x-ws/cjs/package.json b/packages/x-ws/cjs/package.json new file mode 100644 index 0000000..5bbefff --- /dev/null +++ b/packages/x-ws/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/x-ws/cjs/packageInfo.d.ts b/packages/x-ws/cjs/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/x-ws/cjs/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/x-ws/cjs/packageInfo.js b/packages/x-ws/cjs/packageInfo.js new file mode 100644 index 0000000..ac60ddb --- /dev/null +++ b/packages/x-ws/cjs/packageInfo.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.packageInfo = void 0; +exports.packageInfo = { name: '@pezkuwi/x-ws', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '14.0.10' }; diff --git a/packages/x-ws/cjs/react-native.d.ts b/packages/x-ws/cjs/react-native.d.ts new file mode 100644 index 0000000..c2429fa --- /dev/null +++ b/packages/x-ws/cjs/react-native.d.ts @@ -0,0 +1 @@ +export * from './browser.js'; diff --git a/packages/x-ws/cjs/react-native.js b/packages/x-ws/cjs/react-native.js new file mode 100644 index 0000000..c0c4bdf --- /dev/null +++ b/packages/x-ws/cjs/react-native.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +tslib_1.__exportStar(require("./browser.js"), exports); diff --git a/packages/x-ws/cjs/shim.d.ts b/packages/x-ws/cjs/shim.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/x-ws/cjs/shim.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/x-ws/cjs/shim.js b/packages/x-ws/cjs/shim.js new file mode 100644 index 0000000..9f4c16d --- /dev/null +++ b/packages/x-ws/cjs/shim.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const x_global_1 = require("@pezkuwi/x-global"); +const x_ws_1 = require("@pezkuwi/x-ws"); +(0, x_global_1.exposeGlobal)('WebSocket', x_ws_1.WebSocket); diff --git a/packages/x-ws/node.d.ts b/packages/x-ws/node.d.ts new file mode 100644 index 0000000..18779bf --- /dev/null +++ b/packages/x-ws/node.d.ts @@ -0,0 +1,9 @@ +export { packageInfo } from './packageInfo.js'; +export declare const WebSocket: { + new (url: string | URL, protocols?: string | string[]): WebSocket; + prototype: WebSocket; + readonly CONNECTING: 0; + readonly OPEN: 1; + readonly CLOSING: 2; + readonly CLOSED: 3; +}; diff --git a/packages/x-ws/node.js b/packages/x-ws/node.js new file mode 100644 index 0000000..c1c15c3 --- /dev/null +++ b/packages/x-ws/node.js @@ -0,0 +1,4 @@ +import ws from 'ws'; +import { extractGlobal } from '@pezkuwi/x-global'; +export { packageInfo } from './packageInfo.js'; +export const WebSocket = /*#__PURE__*/ extractGlobal('WebSocket', ws); diff --git a/packages/x-ws/package.json b/packages/x-ws/package.json index 80a6b48..3cbc8a9 100644 --- a/packages/x-ws/package.json +++ b/packages/x-ws/package.json @@ -15,16 +15,166 @@ }, "sideEffects": false, "type": "module", - "version": "14.0.10", - "browser": "browser.js", - "main": "node.js", - "react-native": "react-native.js", + "version": "14.0.11", + "main": "./cjs/node.js", + "module": "./node.js", + "browser": "./cjs/browser.js", + "react-native": "./cjs/react-native.js", + "types": "./node.d.ts", + "exports": { + "./cjs/package.json": "./cjs/package.json", + "./cjs/*": "./cjs/*.js", + ".": { + "types": "./node.d.ts", + "react-native": { + "module": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + }, + "require": { + "types": "./cjs/react-native.d.ts", + "default": "./cjs/react-native.js" + }, + "default": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + } + }, + "browser": { + "module": { + "types": "./browser.d.ts", + "default": "./browser.js" + }, + "require": { + "types": "./cjs/browser.d.ts", + "default": "./cjs/browser.js" + }, + "default": { + "types": "./browser.d.ts", + "default": "./browser.js" + } + }, + "node": { + "module": { + "types": "./node.d.ts", + "default": "./node.js" + }, + "require": { + "types": "./cjs/node.d.ts", + "default": "./cjs/node.js" + }, + "default": { + "types": "./node.d.ts", + "default": "./node.js" + } + } + }, + "./browser": { + "module": { + "types": "./browser.d.ts", + "default": "./browser.js" + }, + "require": { + "types": "./cjs/browser.d.ts", + "default": "./cjs/browser.js" + }, + "default": { + "types": "./browser.d.ts", + "default": "./browser.js" + } + }, + "./node": { + "module": { + "types": "./node.d.ts", + "default": "./node.js" + }, + "require": { + "types": "./cjs/node.d.ts", + "default": "./cjs/node.js" + }, + "default": { + "types": "./node.d.ts", + "default": "./node.js" + } + }, + "./package.json": { + "require": "./cjs/package.json", + "default": "./package.json" + }, + "./packageInfo.js": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./packageInfo": { + "module": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + }, + "require": { + "types": "./cjs/packageInfo.d.ts", + "default": "./cjs/packageInfo.js" + }, + "default": { + "types": "./packageInfo.d.ts", + "default": "./packageInfo.js" + } + }, + "./react-native": { + "module": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + }, + "require": { + "types": "./cjs/react-native.d.ts", + "default": "./cjs/react-native.js" + }, + "default": { + "types": "./react-native.d.ts", + "default": "./react-native.js" + } + }, + "./shim.js": { + "module": { + "types": "./shim.d.ts", + "default": "./shim.js" + }, + "require": { + "types": "./cjs/shim.d.ts", + "default": "./cjs/shim.js" + }, + "default": { + "types": "./shim.d.ts", + "default": "./shim.js" + } + }, + "./shim": { + "module": { + "types": "./shim.d.ts", + "default": "./shim.js" + }, + "require": { + "types": "./cjs/shim.d.ts", + "default": "./cjs/shim.js" + }, + "default": { + "types": "./shim.d.ts", + "default": "./shim.js" + } + } + }, "dependencies": { - "@pezkuwi/x-global": "workspace:*", + "@pezkuwi/x-global": "14.0.11", "tslib": "^2.8.0", "ws": "^8.18.0" - }, - "devDependencies": { - "@types/ws": "^8.5.12" } } diff --git a/packages/x-ws/packageInfo.d.ts b/packages/x-ws/packageInfo.d.ts new file mode 100644 index 0000000..eecb501 --- /dev/null +++ b/packages/x-ws/packageInfo.d.ts @@ -0,0 +1,6 @@ +export declare const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; diff --git a/packages/x-ws/packageInfo.js b/packages/x-ws/packageInfo.js new file mode 100644 index 0000000..a248d7f --- /dev/null +++ b/packages/x-ws/packageInfo.js @@ -0,0 +1 @@ +export const packageInfo = { name: '@pezkuwi/x-ws', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '14.0.10' }; diff --git a/packages/x-ws/react-native.d.ts b/packages/x-ws/react-native.d.ts new file mode 100644 index 0000000..c2429fa --- /dev/null +++ b/packages/x-ws/react-native.d.ts @@ -0,0 +1 @@ +export * from './browser.js'; diff --git a/packages/x-ws/react-native.js b/packages/x-ws/react-native.js new file mode 100644 index 0000000..c2429fa --- /dev/null +++ b/packages/x-ws/react-native.js @@ -0,0 +1 @@ +export * from './browser.js'; diff --git a/packages/x-ws/shim.d.ts b/packages/x-ws/shim.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/packages/x-ws/shim.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/x-ws/shim.js b/packages/x-ws/shim.js new file mode 100644 index 0000000..4caa209 --- /dev/null +++ b/packages/x-ws/shim.js @@ -0,0 +1,3 @@ +import { exposeGlobal } from '@pezkuwi/x-global'; +import { WebSocket } from '@pezkuwi/x-ws'; +exposeGlobal('WebSocket', WebSocket);