tenjin-cli 0.1.0-alpha.1 → 0.1.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +33 -0
- package/README.md +167 -16
- package/dist/{_esm-ZH2J4QEH.js → _esm-C5CRWCYU.js} +2 -2
- package/dist/_esm-FEASBWRP.js +881 -0
- package/dist/buy-EE6SEXP6.js +1598 -0
- package/dist/buy-EE6SEXP6.js.map +1 -0
- package/dist/candidate-ERMSYYQZ.js +127 -0
- package/dist/candidate-ERMSYYQZ.js.map +1 -0
- package/dist/{ccip-UCLT5VOW.js → ccip-NQXCEK2U.js} +6 -5
- package/dist/ccip-XR5NE5QK.js +19 -0
- package/dist/chunk-2I4QTOLB.js +11 -0
- package/dist/chunk-2I4QTOLB.js.map +1 -0
- package/dist/chunk-3OV7E5G5.js +18 -0
- package/dist/chunk-3OV7E5G5.js.map +1 -0
- package/dist/chunk-4ONXEEQL.js +152 -0
- package/dist/chunk-4ONXEEQL.js.map +1 -0
- package/dist/chunk-5CLSD5YN.js +209 -0
- package/dist/chunk-5CLSD5YN.js.map +1 -0
- package/dist/chunk-662MSGZB.js +286 -0
- package/dist/chunk-662MSGZB.js.map +1 -0
- package/dist/chunk-7KUW4MJD.js +59 -0
- package/dist/chunk-7KUW4MJD.js.map +1 -0
- package/dist/{doctor-3QBYN46N.js → chunk-AWPAWHNX.js} +88 -93
- package/dist/chunk-AWPAWHNX.js.map +1 -0
- package/dist/chunk-CYOF7ROH.js +70 -0
- package/dist/chunk-CYOF7ROH.js.map +1 -0
- package/dist/chunk-DXTQ3CSI.js +171 -0
- package/dist/chunk-DXTQ3CSI.js.map +1 -0
- package/dist/{chunk-EZROUI5U.js → chunk-ESPNTPQ2.js} +80 -8
- package/dist/chunk-ESPNTPQ2.js.map +1 -0
- package/dist/chunk-FJPLRISB.js +79 -0
- package/dist/chunk-FJPLRISB.js.map +1 -0
- package/dist/chunk-GO75V3NZ.js +160 -0
- package/dist/chunk-GO75V3NZ.js.map +1 -0
- package/dist/chunk-HIVZG55D.js +204 -0
- package/dist/chunk-HIVZG55D.js.map +1 -0
- package/dist/chunk-HSDCI7OV.js +7806 -0
- package/dist/chunk-HSDCI7OV.js.map +1 -0
- package/dist/chunk-JPHG2JW3.js +96 -0
- package/dist/chunk-JPHG2JW3.js.map +1 -0
- package/dist/{chunk-ZPZFPVDN.js → chunk-MUBUQVC3.js} +1 -1
- package/dist/chunk-MUBUQVC3.js.map +1 -0
- package/dist/{chunk-T4LKNY7T.js → chunk-NCE5NSN6.js} +166 -11
- package/dist/chunk-NCE5NSN6.js.map +1 -0
- package/dist/{chunk-YG2DO46P.js → chunk-OYMYCW7J.js} +18 -3
- package/dist/{chunk-YG2DO46P.js.map → chunk-OYMYCW7J.js.map} +1 -1
- package/dist/{chunk-Q53IYV2G.js → chunk-QVX5MWJZ.js} +20 -17
- package/dist/{chunk-Q53IYV2G.js.map → chunk-QVX5MWJZ.js.map} +1 -1
- package/dist/{chunk-CUWUHTIL.js → chunk-RBJPAZFI.js} +16 -202
- package/dist/chunk-RBJPAZFI.js.map +1 -0
- package/dist/chunk-RRN3YTK7.js +6199 -0
- package/dist/chunk-RRN3YTK7.js.map +1 -0
- package/dist/chunk-RY4XKNV3.js +140 -0
- package/dist/chunk-RY4XKNV3.js.map +1 -0
- package/dist/chunk-S3IGX57D.js +14682 -0
- package/dist/chunk-S3IGX57D.js.map +1 -0
- package/dist/chunk-TLCMMYLY.js +126 -0
- package/dist/chunk-TLCMMYLY.js.map +1 -0
- package/dist/{chunk-IPOWB3G3.js → chunk-UGX7YPX2.js} +3314 -306
- package/dist/chunk-UGX7YPX2.js.map +1 -0
- package/dist/chunk-UO22YNY4.js +69 -0
- package/dist/chunk-UO22YNY4.js.map +1 -0
- package/dist/{config-CEFTL5ZL.js → chunk-XHC6FCGZ.js} +115 -18
- package/dist/chunk-XHC6FCGZ.js.map +1 -0
- package/dist/chunk-XJIW7USF.js +217 -0
- package/dist/chunk-XJIW7USF.js.map +1 -0
- package/dist/{chunk-BRJHUQSY.js → chunk-YALGASEU.js} +1548 -1452
- package/dist/chunk-YALGASEU.js.map +1 -0
- package/dist/{chunk-DXPYFVKG.js → chunk-YN5SHIXQ.js} +6 -6
- package/dist/chunk-YN5SHIXQ.js.map +1 -0
- package/dist/chunk-Z52RA3NC.js +137 -0
- package/dist/chunk-Z52RA3NC.js.map +1 -0
- package/dist/{chunk-EXBMF5X7.js → chunk-Z6MFJV5Z.js} +151 -19
- package/dist/chunk-Z6MFJV5Z.js.map +1 -0
- package/dist/chunk-ZABPQJ3M.js +83 -0
- package/dist/chunk-ZABPQJ3M.js.map +1 -0
- package/dist/{chunk-LPRVHM7P.js → chunk-ZMHYXMO6.js} +1655 -114
- package/dist/chunk-ZMHYXMO6.js.map +1 -0
- package/dist/{chunk-3IMLRUZE.js → chunk-ZXTAQYNA.js} +6 -2
- package/dist/{cli-WA65NP4Y.js → cli-SBXI5AMS.js} +177 -177
- package/dist/cli-SBXI5AMS.js.map +1 -0
- package/dist/config-VELDKLHY.js +21 -0
- package/dist/doctor-T3KWNNP2.js +20 -0
- package/dist/doctor-T3KWNNP2.js.map +1 -0
- package/dist/ethersCompat-Df4a6QIZ-3YZIAXDK.js +18 -0
- package/dist/ethersCompat-Df4a6QIZ-3YZIAXDK.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/inspect-LMKOXE4Y.js +96 -0
- package/dist/inspect-LMKOXE4Y.js.map +1 -0
- package/dist/install-LEX3ENQ6.js +387 -0
- package/dist/install-LEX3ENQ6.js.map +1 -0
- package/dist/lookup-ZPN2Q67N.js +129 -0
- package/dist/lookup-ZPN2Q67N.js.map +1 -0
- package/dist/{mine.wasm-GQECMSGN.js → mine.wasm-6PIT3DK6.js} +2 -2
- package/dist/outcome-N7TAK6WR.js +66 -0
- package/dist/outcome-N7TAK6WR.js.map +1 -0
- package/dist/publish-BKBQQAW4.js +1478 -0
- package/dist/publish-BKBQQAW4.js.map +1 -0
- package/dist/{secp256k1-BEZS642W.js → secp256k1-N3ZHU7LB.js} +5 -4
- package/dist/secp256k1-N3ZHU7LB.js.map +1 -0
- package/dist/usdc-JIAJW4SV.js +22 -0
- package/dist/usdc-JIAJW4SV.js.map +1 -0
- package/dist/viemAdapter-By13KInL-ZZE6UV4Y.js +14 -0
- package/dist/viemAdapter-By13KInL-ZZE6UV4Y.js.map +1 -0
- package/dist/{wallet-XD576HF3.js → wallet-CWEMYVIH.js} +28 -22
- package/dist/{wallet-XD576HF3.js.map → wallet-CWEMYVIH.js.map} +1 -1
- package/dist/wallet-PA54CRBL.js +30 -0
- package/dist/wallet-PA54CRBL.js.map +1 -0
- package/package.json +19 -16
- package/skills/tenjin/SKILL.md +199 -0
- package/skills/tenjin-publish/SKILL.md +111 -0
- package/skills/tenjin-search/SKILL.md +133 -0
- package/dist/chunk-BRJHUQSY.js.map +0 -1
- package/dist/chunk-CUWUHTIL.js.map +0 -1
- package/dist/chunk-DXPYFVKG.js.map +0 -1
- package/dist/chunk-EXBMF5X7.js.map +0 -1
- package/dist/chunk-EZROUI5U.js.map +0 -1
- package/dist/chunk-IPOWB3G3.js.map +0 -1
- package/dist/chunk-LPRVHM7P.js.map +0 -1
- package/dist/chunk-T4LKNY7T.js.map +0 -1
- package/dist/chunk-ZPZFPVDN.js.map +0 -1
- package/dist/cli-WA65NP4Y.js.map +0 -1
- package/dist/config-CEFTL5ZL.js.map +0 -1
- package/dist/doctor-3QBYN46N.js.map +0 -1
- package/dist/usdc-44R6XZF2.js +0 -18
- package/dist/wallet-ELBTBMXO.js +0 -20
- /package/dist/{_esm-ZH2J4QEH.js.map → _esm-C5CRWCYU.js.map} +0 -0
- /package/dist/{ccip-UCLT5VOW.js.map → _esm-FEASBWRP.js.map} +0 -0
- /package/dist/{chunk-3IMLRUZE.js.map → ccip-NQXCEK2U.js.map} +0 -0
- /package/dist/{secp256k1-BEZS642W.js.map → ccip-XR5NE5QK.js.map} +0 -0
- /package/dist/{usdc-44R6XZF2.js.map → chunk-ZXTAQYNA.js.map} +0 -0
- /package/dist/{wallet-ELBTBMXO.js.map → config-VELDKLHY.js.map} +0 -0
- /package/dist/{mine.wasm-GQECMSGN.js.map → mine.wasm-6PIT3DK6.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/src/cryptoNode.ts","../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/src/utils.ts","../node_modules/.pnpm/@noble+curves@1.9.1/node_modules/@noble/curves/src/abstract/utils.ts","../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/src/_u64.ts"],"sourcesContent":["/**\n * Internal webcrypto alias.\n * We prefer WebCrypto aka globalThis.crypto, which exists in node.js 16+.\n * Falls back to Node.js built-in crypto for Node.js <=v14.\n * See utils.ts for details.\n * @module\n */\n// @ts-ignore\nimport * as nc from 'node:crypto';\nexport const crypto: any =\n nc && typeof nc === 'object' && 'webcrypto' in nc\n ? (nc.webcrypto as any)\n : nc && typeof nc === 'object' && 'randomBytes' in nc\n ? nc\n : undefined;\n","/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n\n// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.\n// node.js versions earlier than v19 don't declare it in global scope.\n// For node.js, package.json#exports field mapping rewrites import\n// from `crypto` to `cryptoNode`, which imports native module.\n// Makes the utils un-importable in browsers without a bundler.\n// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.\nimport { crypto } from '@noble/hashes/crypto';\n\n/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */\nexport function isBytes(a: unknown): a is Uint8Array {\n return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');\n}\n\n/** Asserts something is positive integer. */\nexport function anumber(n: number): void {\n if (!Number.isSafeInteger(n) || n < 0) throw new Error('positive integer expected, got ' + n);\n}\n\n/** Asserts something is Uint8Array. */\nexport function abytes(b: Uint8Array | undefined, ...lengths: number[]): void {\n if (!isBytes(b)) throw new Error('Uint8Array expected');\n if (lengths.length > 0 && !lengths.includes(b.length))\n throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);\n}\n\n/** Asserts something is hash */\nexport function ahash(h: IHash): void {\n if (typeof h !== 'function' || typeof h.create !== 'function')\n throw new Error('Hash should be wrapped by utils.createHasher');\n anumber(h.outputLen);\n anumber(h.blockLen);\n}\n\n/** Asserts a hash instance has not been destroyed / finished */\nexport function aexists(instance: any, checkFinished = true): void {\n if (instance.destroyed) throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');\n}\n\n/** Asserts output is properly-sized byte array */\nexport function aoutput(out: any, instance: any): void {\n abytes(out);\n const min = instance.outputLen;\n if (out.length < min) {\n throw new Error('digestInto() expects output buffer of length at least ' + min);\n }\n}\n\n/** Generic type encompassing 8/16/32-byte arrays - but not 64-byte. */\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\n/** Cast u8 / u16 / u32 to u8. */\nexport function u8(arr: TypedArray): Uint8Array {\n return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/** Cast u8 / u16 / u32 to u32. */\nexport function u32(arr: TypedArray): Uint32Array {\n return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n}\n\n/** Zeroize a byte array. Warning: JS provides no guarantees. */\nexport function clean(...arrays: TypedArray[]): void {\n for (let i = 0; i < arrays.length; i++) {\n arrays[i].fill(0);\n }\n}\n\n/** Create DataView of an array for easy byte-level manipulation. */\nexport function createView(arr: TypedArray): DataView {\n return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/** The rotate right (circular right shift) operation for uint32 */\nexport function rotr(word: number, shift: number): number {\n return (word << (32 - shift)) | (word >>> shift);\n}\n\n/** The rotate left (circular left shift) operation for uint32 */\nexport function rotl(word: number, shift: number): number {\n return (word << shift) | ((word >>> (32 - shift)) >>> 0);\n}\n\n/** Is current platform little-endian? Most are. Big-Endian platform: IBM */\nexport const isLE: boolean = /* @__PURE__ */ (() =>\n new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n\n/** The byte swap operation for uint32 */\nexport function byteSwap(word: number): number {\n return (\n ((word << 24) & 0xff000000) |\n ((word << 8) & 0xff0000) |\n ((word >>> 8) & 0xff00) |\n ((word >>> 24) & 0xff)\n );\n}\n/** Conditionally byte swap if on a big-endian platform */\nexport const swap8IfBE: (n: number) => number = isLE\n ? (n: number) => n\n : (n: number) => byteSwap(n);\n\n/** @deprecated */\nexport const byteSwapIfBE: typeof swap8IfBE = swap8IfBE;\n/** In place byte swap for Uint32Array */\nexport function byteSwap32(arr: Uint32Array): Uint32Array {\n for (let i = 0; i < arr.length; i++) {\n arr[i] = byteSwap(arr[i]);\n }\n return arr;\n}\n\nexport const swap32IfBE: (u: Uint32Array) => Uint32Array = isLE\n ? (u: Uint32Array) => u\n : byteSwap32;\n\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\nconst hasHexBuiltin: boolean = /* @__PURE__ */ (() =>\n // @ts-ignore\n typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n\n/**\n * Convert byte array to hex string. Uses built-in function, when available.\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n abytes(bytes);\n // @ts-ignore\n if (hasHexBuiltin) return bytes.toHex();\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n\n/**\n * Convert hex string to byte array. Uses built-in function, when available.\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex: string): Uint8Array {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n // @ts-ignore\n if (hasHexBuiltin) return Uint8Array.fromHex(hex);\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2) throw new Error('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new Error('hex string expected, got non-hex character \"' + char + '\" at index ' + hi);\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array;\n}\n\n/**\n * There is no setImmediate in browser and setTimeout is slow.\n * Call of async fn will return Promise, which will be fullfiled only on\n * next scheduler queue processing step and this is exactly what we need.\n */\nexport const nextTick = async (): Promise<void> => {};\n\n/** Returns control to thread each 'tick' ms to avoid blocking. */\nexport async function asyncLoop(\n iters: number,\n tick: number,\n cb: (i: number) => void\n): Promise<void> {\n let ts = Date.now();\n for (let i = 0; i < iters; i++) {\n cb(i);\n // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n const diff = Date.now() - ts;\n if (diff >= 0 && diff < tick) continue;\n await nextTick();\n ts += diff;\n }\n}\n\n// Global symbols, but ts doesn't see them: https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\ndeclare const TextDecoder: any;\n\n/**\n * Converts string to bytes using UTF8 encoding.\n * @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])\n */\nexport function utf8ToBytes(str: string): Uint8Array {\n if (typeof str !== 'string') throw new Error('string expected');\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\n/**\n * Converts bytes to string using UTF8 encoding.\n * @example bytesToUtf8(Uint8Array.from([97, 98, 99])) // 'abc'\n */\nexport function bytesToUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\n/** Accepted input of hash functions. Strings are converted to byte arrays. */\nexport type Input = string | Uint8Array;\n/**\n * Normalizes (non-hex) string or Uint8Array to Uint8Array.\n * Warning: when Uint8Array is passed, it would NOT get copied.\n * Keep in mind for future mutable operations.\n */\nexport function toBytes(data: Input): Uint8Array {\n if (typeof data === 'string') data = utf8ToBytes(data);\n abytes(data);\n return data;\n}\n\n/** KDFs can accept string or Uint8Array for user convenience. */\nexport type KDFInput = string | Uint8Array;\n/**\n * Helper for KDFs: consumes uint8array or string.\n * When string is passed, does utf8 decoding, using TextDecoder.\n */\nexport function kdfInputToBytes(data: KDFInput): Uint8Array {\n if (typeof data === 'string') data = utf8ToBytes(data);\n abytes(data);\n return data;\n}\n\n/** Copies several Uint8Arrays into one. */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res;\n}\n\ntype EmptyObj = {};\nexport function checkOpts<T1 extends EmptyObj, T2 extends EmptyObj>(\n defaults: T1,\n opts?: T2\n): T1 & T2 {\n if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')\n throw new Error('options should be object or undefined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\n/** Hash interface. */\nexport type IHash = {\n (data: Uint8Array): Uint8Array;\n blockLen: number;\n outputLen: number;\n create: any;\n};\n\n/** For runtime check if class implements interface */\nexport abstract class Hash<T extends Hash<T>> {\n abstract blockLen: number; // Bytes per block\n abstract outputLen: number; // Bytes in output\n abstract update(buf: Input): this;\n // Writes digest into buf\n abstract digestInto(buf: Uint8Array): void;\n abstract digest(): Uint8Array;\n /**\n * Resets internal state. Makes Hash instance unusable.\n * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed\n * by user, they will need to manually call `destroy()` when zeroing is necessary.\n */\n abstract destroy(): void;\n /**\n * Clones hash instance. Unsafe: doesn't check whether `to` is valid. Can be used as `clone()`\n * when no options are passed.\n * Reasons to use `_cloneInto` instead of clone: 1) performance 2) reuse instance => all internal\n * buffers are overwritten => causes buffer overwrite which is used for digest in some cases.\n * There are no guarantees for clean-up because it's impossible in JS.\n */\n abstract _cloneInto(to?: T): T;\n // Safe version that clones internal state\n abstract clone(): T;\n}\n\n/**\n * XOF: streaming API to read digest in chunks.\n * Same as 'squeeze' in keccak/k12 and 'seek' in blake3, but more generic name.\n * When hash used in XOF mode it is up to user to call '.destroy' afterwards, since we cannot\n * destroy state, next call can require more bytes.\n */\nexport type HashXOF<T extends Hash<T>> = Hash<T> & {\n xof(bytes: number): Uint8Array; // Read 'bytes' bytes from digest stream\n xofInto(buf: Uint8Array): Uint8Array; // read buf.length bytes from digest stream into buf\n};\n\n/** Hash function */\nexport type CHash = ReturnType<typeof createHasher>;\n/** Hash function with output */\nexport type CHashO = ReturnType<typeof createOptHasher>;\n/** XOF with output */\nexport type CHashXO = ReturnType<typeof createXOFer>;\n\n/** Wraps hash function, creating an interface on top of it */\nexport function createHasher<T extends Hash<T>>(\n hashCons: () => Hash<T>\n): {\n (msg: Input): Uint8Array;\n outputLen: number;\n blockLen: number;\n create(): Hash<T>;\n} {\n const hashC = (msg: Input): Uint8Array => hashCons().update(toBytes(msg)).digest();\n const tmp = hashCons();\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = () => hashCons();\n return hashC;\n}\n\nexport function createOptHasher<H extends Hash<H>, T extends Object>(\n hashCons: (opts?: T) => Hash<H>\n): {\n (msg: Input, opts?: T): Uint8Array;\n outputLen: number;\n blockLen: number;\n create(opts?: T): Hash<H>;\n} {\n const hashC = (msg: Input, opts?: T): Uint8Array => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({} as T);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts?: T) => hashCons(opts);\n return hashC;\n}\n\nexport function createXOFer<H extends HashXOF<H>, T extends Object>(\n hashCons: (opts?: T) => HashXOF<H>\n): {\n (msg: Input, opts?: T): Uint8Array;\n outputLen: number;\n blockLen: number;\n create(opts?: T): HashXOF<H>;\n} {\n const hashC = (msg: Input, opts?: T): Uint8Array => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({} as T);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts?: T) => hashCons(opts);\n return hashC;\n}\nexport const wrapConstructor: typeof createHasher = createHasher;\nexport const wrapConstructorWithOpts: typeof createOptHasher = createOptHasher;\nexport const wrapXOFConstructorWithOpts: typeof createXOFer = createXOFer;\n\n/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */\nexport function randomBytes(bytesLength = 32): Uint8Array {\n if (crypto && typeof crypto.getRandomValues === 'function') {\n return crypto.getRandomValues(new Uint8Array(bytesLength));\n }\n // Legacy Node.js compatibility\n if (crypto && typeof crypto.randomBytes === 'function') {\n return Uint8Array.from(crypto.randomBytes(bytesLength));\n }\n throw new Error('crypto.getRandomValues must be defined');\n}\n","/**\n * Hex, bytes and number utilities.\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n\n// 100 lines of code in the file are duplicated from noble-hashes (utils).\n// This is OK: `abstract` directory does not use noble-hashes.\n// User may opt-in into using different hashing library. This way, noble-hashes\n// won't be included into their bundle.\nconst _0n = /* @__PURE__ */ BigInt(0);\nconst _1n = /* @__PURE__ */ BigInt(1);\nexport type Hex = Uint8Array | string; // hex strings are accepted for simplicity\nexport type PrivKey = Hex | bigint; // bigints are accepted to ease learning curve\nexport type CHash = {\n (message: Uint8Array | string): Uint8Array;\n blockLen: number;\n outputLen: number;\n create(opts?: { dkLen?: number }): any; // For shake\n};\nexport type FHash = (message: Uint8Array | string) => Uint8Array;\n\nexport function isBytes(a: unknown): a is Uint8Array {\n return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');\n}\n\nexport function abytes(item: unknown): void {\n if (!isBytes(item)) throw new Error('Uint8Array expected');\n}\n\nexport function abool(title: string, value: boolean): void {\n if (typeof value !== 'boolean') throw new Error(title + ' boolean expected, got ' + value);\n}\n\n// Used in weierstrass, der\nexport function numberToHexUnpadded(num: number | bigint): string {\n const hex = num.toString(16);\n return hex.length & 1 ? '0' + hex : hex;\n}\n\nexport function hexToNumber(hex: string): bigint {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n return hex === '' ? _0n : BigInt('0x' + hex); // Big Endian\n}\n\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\nconst hasHexBuiltin: boolean =\n // @ts-ignore\n typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function';\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n\n/**\n * Convert byte array to hex string. Uses built-in function, when available.\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n abytes(bytes);\n // @ts-ignore\n if (hasHexBuiltin) return bytes.toHex();\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n\n/**\n * Convert hex string to byte array. Uses built-in function, when available.\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex: string): Uint8Array {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n // @ts-ignore\n if (hasHexBuiltin) return Uint8Array.fromHex(hex);\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2) throw new Error('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new Error('hex string expected, got non-hex character \"' + char + '\" at index ' + hi);\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array;\n}\n\n// BE: Big Endian, LE: Little Endian\nexport function bytesToNumberBE(bytes: Uint8Array): bigint {\n return hexToNumber(bytesToHex(bytes));\n}\nexport function bytesToNumberLE(bytes: Uint8Array): bigint {\n abytes(bytes);\n return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));\n}\n\nexport function numberToBytesBE(n: number | bigint, len: number): Uint8Array {\n return hexToBytes(n.toString(16).padStart(len * 2, '0'));\n}\nexport function numberToBytesLE(n: number | bigint, len: number): Uint8Array {\n return numberToBytesBE(n, len).reverse();\n}\n// Unpadded, rarely used\nexport function numberToVarBytesBE(n: number | bigint): Uint8Array {\n return hexToBytes(numberToHexUnpadded(n));\n}\n\n/**\n * Takes hex string or Uint8Array, converts to Uint8Array.\n * Validates output length.\n * Will throw error for other types.\n * @param title descriptive title for an error e.g. 'private key'\n * @param hex hex string or Uint8Array\n * @param expectedLength optional, will compare to result array's length\n * @returns\n */\nexport function ensureBytes(title: string, hex: Hex, expectedLength?: number): Uint8Array {\n let res: Uint8Array;\n if (typeof hex === 'string') {\n try {\n res = hexToBytes(hex);\n } catch (e) {\n throw new Error(title + ' must be hex string or Uint8Array, cause: ' + e);\n }\n } else if (isBytes(hex)) {\n // Uint8Array.from() instead of hash.slice() because node.js Buffer\n // is instance of Uint8Array, and its slice() creates **mutable** copy\n res = Uint8Array.from(hex);\n } else {\n throw new Error(title + ' must be hex string or Uint8Array');\n }\n const len = res.length;\n if (typeof expectedLength === 'number' && len !== expectedLength)\n throw new Error(title + ' of length ' + expectedLength + ' expected, got ' + len);\n return res;\n}\n\n/**\n * Copies several Uint8Arrays into one.\n */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res;\n}\n\n// Compares 2 u8a-s in kinda constant time\nexport function equalBytes(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];\n return diff === 0;\n}\n\n// Global symbols in both browsers and Node.js since v11\n// See https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\n\n/**\n * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])\n */\nexport function utf8ToBytes(str: string): Uint8Array {\n if (typeof str !== 'string') throw new Error('string expected');\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\n// Is positive bigint\nconst isPosBig = (n: bigint) => typeof n === 'bigint' && _0n <= n;\n\nexport function inRange(n: bigint, min: bigint, max: bigint): boolean {\n return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;\n}\n\n/**\n * Asserts min <= n < max. NOTE: It's < max and not <= max.\n * @example\n * aInRange('x', x, 1n, 256n); // would assume x is in (1n..255n)\n */\nexport function aInRange(title: string, n: bigint, min: bigint, max: bigint): void {\n // Why min <= n < max and not a (min < n < max) OR b (min <= n <= max)?\n // consider P=256n, min=0n, max=P\n // - a for min=0 would require -1: `inRange('x', x, -1n, P)`\n // - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`\n // - our way is the cleanest: `inRange('x', x, 0n, P)\n if (!inRange(n, min, max))\n throw new Error('expected valid ' + title + ': ' + min + ' <= n < ' + max + ', got ' + n);\n}\n\n// Bit operations\n\n/**\n * Calculates amount of bits in a bigint.\n * Same as `n.toString(2).length`\n * TODO: merge with nLength in modular\n */\nexport function bitLen(n: bigint): number {\n let len;\n for (len = 0; n > _0n; n >>= _1n, len += 1);\n return len;\n}\n\n/**\n * Gets single bit at position.\n * NOTE: first bit position is 0 (same as arrays)\n * Same as `!!+Array.from(n.toString(2)).reverse()[pos]`\n */\nexport function bitGet(n: bigint, pos: number): bigint {\n return (n >> BigInt(pos)) & _1n;\n}\n\n/**\n * Sets single bit at position.\n */\nexport function bitSet(n: bigint, pos: number, value: boolean): bigint {\n return n | ((value ? _1n : _0n) << BigInt(pos));\n}\n\n/**\n * Calculate mask for N bits. Not using ** operator with bigints because of old engines.\n * Same as BigInt(`0b${Array(i).fill('1').join('')}`)\n */\nexport const bitMask = (n: number): bigint => (_1n << BigInt(n)) - _1n;\n\n// DRBG\n\nconst u8n = (len: number) => new Uint8Array(len); // creates Uint8Array\nconst u8fr = (arr: ArrayLike<number>) => Uint8Array.from(arr); // another shortcut\ntype Pred<T> = (v: Uint8Array) => T | undefined;\n/**\n * Minimal HMAC-DRBG from NIST 800-90 for RFC6979 sigs.\n * @returns function that will call DRBG until 2nd arg returns something meaningful\n * @example\n * const drbg = createHmacDRBG<Key>(32, 32, hmac);\n * drbg(seed, bytesToKey); // bytesToKey must return Key or undefined\n */\nexport function createHmacDrbg<T>(\n hashLen: number,\n qByteLen: number,\n hmacFn: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array\n): (seed: Uint8Array, predicate: Pred<T>) => T {\n if (typeof hashLen !== 'number' || hashLen < 2) throw new Error('hashLen must be a number');\n if (typeof qByteLen !== 'number' || qByteLen < 2) throw new Error('qByteLen must be a number');\n if (typeof hmacFn !== 'function') throw new Error('hmacFn must be a function');\n // Step B, Step C: set hashLen to 8*ceil(hlen/8)\n let v = u8n(hashLen); // Minimal non-full-spec HMAC-DRBG from NIST 800-90 for RFC6979 sigs.\n let k = u8n(hashLen); // Steps B and C of RFC6979 3.2: set hashLen, in our case always same\n let i = 0; // Iterations counter, will throw when over 1000\n const reset = () => {\n v.fill(1);\n k.fill(0);\n i = 0;\n };\n const h = (...b: Uint8Array[]) => hmacFn(k, v, ...b); // hmac(k)(v, ...values)\n const reseed = (seed = u8n(0)) => {\n // HMAC-DRBG reseed() function. Steps D-G\n k = h(u8fr([0x00]), seed); // k = hmac(k || v || 0x00 || seed)\n v = h(); // v = hmac(k || v)\n if (seed.length === 0) return;\n k = h(u8fr([0x01]), seed); // k = hmac(k || v || 0x01 || seed)\n v = h(); // v = hmac(k || v)\n };\n const gen = () => {\n // HMAC-DRBG generate() function\n if (i++ >= 1000) throw new Error('drbg: tried 1000 values');\n let len = 0;\n const out: Uint8Array[] = [];\n while (len < qByteLen) {\n v = h();\n const sl = v.slice();\n out.push(sl);\n len += v.length;\n }\n return concatBytes(...out);\n };\n const genUntil = (seed: Uint8Array, pred: Pred<T>): T => {\n reset();\n reseed(seed); // Steps D-G\n let res: T | undefined = undefined; // Step H: grind until k is in [1..n-1]\n while (!(res = pred(gen()))) reseed();\n reset();\n return res;\n };\n return genUntil;\n}\n\n// Validating curves and fields\n\nconst validatorFns = {\n bigint: (val: any): boolean => typeof val === 'bigint',\n function: (val: any): boolean => typeof val === 'function',\n boolean: (val: any): boolean => typeof val === 'boolean',\n string: (val: any): boolean => typeof val === 'string',\n stringOrUint8Array: (val: any): boolean => typeof val === 'string' || isBytes(val),\n isSafeInteger: (val: any): boolean => Number.isSafeInteger(val),\n array: (val: any): boolean => Array.isArray(val),\n field: (val: any, object: any): any => (object as any).Fp.isValid(val),\n hash: (val: any): boolean => typeof val === 'function' && Number.isSafeInteger(val.outputLen),\n} as const;\ntype Validator = keyof typeof validatorFns;\ntype ValMap<T extends Record<string, any>> = { [K in keyof T]?: Validator };\n// type Record<K extends string | number | symbol, T> = { [P in K]: T; }\n\nexport function validateObject<T extends Record<string, any>>(\n object: T,\n validators: ValMap<T>,\n optValidators: ValMap<T> = {}\n): T {\n const checkField = (fieldName: keyof T, type: Validator, isOptional: boolean) => {\n const checkVal = validatorFns[type];\n if (typeof checkVal !== 'function') throw new Error('invalid validator function');\n\n const val = object[fieldName as keyof typeof object];\n if (isOptional && val === undefined) return;\n if (!checkVal(val, object)) {\n throw new Error(\n 'param ' + String(fieldName) + ' is invalid. Expected ' + type + ', got ' + val\n );\n }\n };\n for (const [fieldName, type] of Object.entries(validators)) checkField(fieldName, type!, false);\n for (const [fieldName, type] of Object.entries(optValidators)) checkField(fieldName, type!, true);\n return object;\n}\n// validate type tests\n// const o: { a: number; b: number; c: number } = { a: 1, b: 5, c: 6 };\n// const z0 = validateObject(o, { a: 'isSafeInteger' }, { c: 'bigint' }); // Ok!\n// // Should fail type-check\n// const z1 = validateObject(o, { a: 'tmp' }, { c: 'zz' });\n// const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });\n// const z3 = validateObject(o, { test: 'boolean', z: 'bug' });\n// const z4 = validateObject(o, { a: 'boolean', z: 'bug' });\n\n/**\n * throws not implemented error\n */\nexport const notImplemented = (): never => {\n throw new Error('not implemented');\n};\n\n/**\n * Memoizes (caches) computation result.\n * Uses WeakMap: the value is going auto-cleaned by GC after last reference is removed.\n */\nexport function memoized<T extends object, R, O extends any[]>(\n fn: (arg: T, ...args: O) => R\n): (arg: T, ...args: O) => R {\n const map = new WeakMap<T, R>();\n return (arg: T, ...args: O): R => {\n const val = map.get(arg);\n if (val !== undefined) return val;\n const computed = fn(arg, ...args);\n map.set(arg, computed);\n return computed;\n };\n}\n","/**\n * Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.\n * @todo re-check https://issues.chromium.org/issues/42212588\n * @module\n */\nconst U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);\nconst _32n = /* @__PURE__ */ BigInt(32);\n\nfunction fromBig(\n n: bigint,\n le = false\n): {\n h: number;\n l: number;\n} {\n if (le) return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };\n return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };\n}\n\nfunction split(lst: bigint[], le = false): Uint32Array[] {\n const len = lst.length;\n let Ah = new Uint32Array(len);\n let Al = new Uint32Array(len);\n for (let i = 0; i < len; i++) {\n const { h, l } = fromBig(lst[i], le);\n [Ah[i], Al[i]] = [h, l];\n }\n return [Ah, Al];\n}\n\nconst toBig = (h: number, l: number): bigint => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0);\n// for Shift in [0, 32)\nconst shrSH = (h: number, _l: number, s: number): number => h >>> s;\nconst shrSL = (h: number, l: number, s: number): number => (h << (32 - s)) | (l >>> s);\n// Right rotate for Shift in [1, 32)\nconst rotrSH = (h: number, l: number, s: number): number => (h >>> s) | (l << (32 - s));\nconst rotrSL = (h: number, l: number, s: number): number => (h << (32 - s)) | (l >>> s);\n// Right rotate for Shift in (32, 64), NOTE: 32 is special case.\nconst rotrBH = (h: number, l: number, s: number): number => (h << (64 - s)) | (l >>> (s - 32));\nconst rotrBL = (h: number, l: number, s: number): number => (h >>> (s - 32)) | (l << (64 - s));\n// Right rotate for shift===32 (just swaps l&h)\nconst rotr32H = (_h: number, l: number): number => l;\nconst rotr32L = (h: number, _l: number): number => h;\n// Left rotate for Shift in [1, 32)\nconst rotlSH = (h: number, l: number, s: number): number => (h << s) | (l >>> (32 - s));\nconst rotlSL = (h: number, l: number, s: number): number => (l << s) | (h >>> (32 - s));\n// Left rotate for Shift in (32, 64), NOTE: 32 is special case.\nconst rotlBH = (h: number, l: number, s: number): number => (l << (s - 32)) | (h >>> (64 - s));\nconst rotlBL = (h: number, l: number, s: number): number => (h << (s - 32)) | (l >>> (64 - s));\n\n// JS uses 32-bit signed integers for bitwise operations which means we cannot\n// simple take carry out of low bit sum by shift, we need to use division.\nfunction add(\n Ah: number,\n Al: number,\n Bh: number,\n Bl: number\n): {\n h: number;\n l: number;\n} {\n const l = (Al >>> 0) + (Bl >>> 0);\n return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };\n}\n// Addition with more than 2 elements\nconst add3L = (Al: number, Bl: number, Cl: number): number => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);\nconst add3H = (low: number, Ah: number, Bh: number, Ch: number): number =>\n (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;\nconst add4L = (Al: number, Bl: number, Cl: number, Dl: number): number =>\n (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);\nconst add4H = (low: number, Ah: number, Bh: number, Ch: number, Dh: number): number =>\n (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;\nconst add5L = (Al: number, Bl: number, Cl: number, Dl: number, El: number): number =>\n (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);\nconst add5H = (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number): number =>\n (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;\n\n// prettier-ignore\nexport {\n add, add3H, add3L, add4H, add4L, add5H, add5L, fromBig, rotlBH, rotlBL, rotlSH, rotlSL, rotr32H, rotr32L, rotrBH, rotrBL, rotrSH, rotrSL, shrSH, shrSL, split, toBig\n};\n// prettier-ignore\nconst u64: { fromBig: typeof fromBig; split: typeof split; toBig: (h: number, l: number) => bigint; shrSH: (h: number, _l: number, s: number) => number; shrSL: (h: number, l: number, s: number) => number; rotrSH: (h: number, l: number, s: number) => number; rotrSL: (h: number, l: number, s: number) => number; rotrBH: (h: number, l: number, s: number) => number; rotrBL: (h: number, l: number, s: number) => number; rotr32H: (_h: number, l: number) => number; rotr32L: (h: number, _l: number) => number; rotlSH: (h: number, l: number, s: number) => number; rotlSL: (h: number, l: number, s: number) => number; rotlBH: (h: number, l: number, s: number) => number; rotlBL: (h: number, l: number, s: number) => number; add: typeof add; add3L: (Al: number, Bl: number, Cl: number) => number; add3H: (low: number, Ah: number, Bh: number, Ch: number) => number; add4L: (Al: number, Bl: number, Cl: number, Dl: number) => number; add4H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number) => number; add5H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number) => number; add5L: (Al: number, Bl: number, Cl: number, Dl: number, El: number) => number; } = {\n fromBig, split, toBig,\n shrSH, shrSL,\n rotrSH, rotrSL, rotrBH, rotrBL,\n rotr32H, rotr32L,\n rotlSH, rotlSL, rotlBH, rotlBL,\n add, add3L, add3H, add4L, add4H, add5H, add5L,\n};\nexport default u64;\n"],"mappings":"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","names":["isBytes","abytes","isBytes","concatBytes","abytes","utf8ToBytes","concatBytes","isBytes"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/wallet/store.ts"],"sourcesContent":["import { readFile, stat } from 'node:fs/promises';\nimport { z } from 'zod';\nimport * as Keystore from 'ox/Keystore';\nimport { CliError } from '../errors';\nimport { writeFileAtomicExclusive } from '../atomic-json';\nimport { walletPath } from '../paths';\n\n/** A 0x-prefixed 32-byte hex private key (case-insensitive). */\nexport const PRIVATE_KEY_RE = /^0x[0-9a-f]{64}$/i;\nconst ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;\n\n/**\n * The at-rest shape of a Keystore v3 document (Web3 Secret Storage). Validated\n * structurally on read so an obviously-corrupt keystore fails as\n * WALLET_INVALID_KEY before we ever ask for a passphrase; the real integrity\n * check is the keystore's own MAC, verified by ox at decrypt time. `kdfparams`\n * stays an open object because scrypt and pbkdf2 carry different fields and only\n * ox needs to interpret them.\n */\nconst KeystoreV3Schema = z.object({\n crypto: z.object({\n cipher: z.literal('aes-128-ctr'),\n ciphertext: z.string(),\n cipherparams: z.object({ iv: z.string() }),\n kdf: z.enum(['scrypt', 'pbkdf2']),\n kdfparams: z.record(z.string(), z.unknown()),\n mac: z.string(),\n }),\n id: z.string(),\n version: z.literal(3),\n});\n\n/**\n * The persisted wallet record (schema v2). The private key is NEVER stored in\n * cleartext: `keystore` is a Keystore v3 document (scrypt + AES-128-CTR) and the\n * key is recovered only by decrypting it with the wallet passphrase. `address`\n * stays top-level in cleartext ON PURPOSE so `show`/`balance`/`doctor` keep\n * working without a passphrase; only signing decrypts. The `provider`\n * discriminator keeps the schema from implying every future wallet embeds a\n * keystore. Validated on read (a corrupt file is WALLET_INVALID_KEY, never a\n * silent partial parse).\n */\nexport const WalletRecordSchema = z.object({\n schemaVersion: z.literal(2),\n provider: z.literal('local'),\n address: z.string().regex(ADDRESS_RE, 'expected a 0x-prefixed 20-byte address'),\n keystore: KeystoreV3Schema,\n createdAt: z.string(),\n});\nexport type WalletRecord = Omit<z.infer<typeof WalletRecordSchema>, 'keystore'> & {\n keystore: Keystore.Keystore;\n};\n\nexport async function walletFileExists(dir: string): Promise<boolean> {\n return (await walletFileMode(dir)) !== null;\n}\n\n/** File permission bits (`mode & 0o777`), or null when the wallet file is absent. */\nexport async function walletFileMode(dir: string): Promise<number | null> {\n try {\n return (await stat(walletPath(dir))).mode & 0o777;\n } catch (err) {\n if (isNotFound(err)) return null;\n throw err;\n }\n}\n\n/** Read + validate the wallet record; null when absent, WALLET_INVALID_KEY when corrupt. */\nexport async function readWalletRecord(dir: string): Promise<WalletRecord | null> {\n const path = walletPath(dir);\n let raw: string;\n try {\n raw = await readFile(path, 'utf8');\n } catch (err) {\n if (isNotFound(err)) return null;\n throw new CliError('WALLET_INVALID_KEY', `Could not read the wallet file at ${path}.`, {\n fix: `Check file permissions on ${path}.`,\n cause: err,\n });\n }\n let json: unknown;\n try {\n json = JSON.parse(raw);\n } catch (err) {\n throw new CliError('WALLET_INVALID_KEY', `The wallet file at ${path} is not valid JSON.`, {\n fix: `Move ${path} aside, then run \\`tenjin wallet create\\`.`,\n cause: err,\n });\n }\n // A pre-encryption record (schema v1 stored the raw key). There is no in-place\n // migration: the old key must be swept and a fresh encrypted wallet created.\n if (isPreEncryptionRecord(json)) {\n throw new CliError(\n 'WALLET_INVALID_KEY',\n `The wallet file at ${path} predates encrypted storage.`,\n {\n fix: `Move ${path} aside and run \\`tenjin wallet create\\`; sweep any funds from the old address first.`,\n },\n );\n }\n const parsed = WalletRecordSchema.safeParse(json);\n if (!parsed.success) {\n throw new CliError(\n 'WALLET_INVALID_KEY',\n `The wallet file at ${path} is not a valid wallet record.`,\n {\n fix: `Move ${path} aside, then run \\`tenjin wallet create\\`.`,\n details: parsed.error.issues,\n },\n );\n }\n return parsed.data as WalletRecord;\n}\n\n/**\n * Persist a validated record at 0600 in a 0700 dir, NO-CLOBBER. The exclusive\n * write — not an earlier existence check — is the authority: two concurrent\n * `create` runs can both pass a pre-check, but only one can win the atomic\n * commit; the loser surfaces as WALLET_EXISTS instead of silently overwriting\n * (and losing) a non-recoverable key.\n */\nexport async function writeWalletRecord(dir: string, record: WalletRecord): Promise<void> {\n const validated = WalletRecordSchema.parse(record);\n const path = walletPath(dir);\n try {\n await writeFileAtomicExclusive(path, `${JSON.stringify(validated, null, 2)}\\n`, {\n mode: 0o600,\n dirMode: 0o700,\n });\n } catch (err) {\n if (hasCode(err, 'EEXIST')) {\n throw new CliError('WALLET_EXISTS', `A wallet already exists at ${path}.`, {\n fix: `Keys are non-recoverable; move it aside first (e.g. \\`mv ${path} ${path}.bak\\`) to create a new one.`,\n cause: err,\n });\n }\n throw err;\n }\n}\n\n/** A cleartext-key record from before encrypted storage: schema v1 or a bare `privateKey`. */\nfunction isPreEncryptionRecord(json: unknown): boolean {\n if (typeof json !== 'object' || json === null) return false;\n const rec = json as Record<string, unknown>;\n return rec.schemaVersion === 1 || 'privateKey' in rec;\n}\n\nfunction isNotFound(err: unknown): boolean {\n return hasCode(err, 'ENOENT');\n}\n\nfunction hasCode(err: unknown, code: string): boolean {\n return (\n typeof err === 'object' &&\n err !== null &&\n 'code' in err &&\n (err as { code?: unknown }).code === code\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/src/pbkdf2.ts","../node_modules/.pnpm/viem@2.55.2_typescript@6.0.3_zod@4.4.3/node_modules/viem/accounts/generatePrivateKey.ts","../node_modules/.pnpm/viem@2.55.2_typescript@6.0.3_zod@4.4.3/node_modules/viem/accounts/toAccount.ts","../node_modules/.pnpm/viem@2.55.2_typescript@6.0.3_zod@4.4.3/node_modules/viem/accounts/utils/sign.ts","../node_modules/.pnpm/viem@2.55.2_typescript@6.0.3_zod@4.4.3/node_modules/viem/accounts/utils/signAuthorization.ts","../node_modules/.pnpm/viem@2.55.2_typescript@6.0.3_zod@4.4.3/node_modules/viem/accounts/utils/signMessage.ts","../node_modules/.pnpm/viem@2.55.2_typescript@6.0.3_zod@4.4.3/node_modules/viem/accounts/utils/signTransaction.ts","../node_modules/.pnpm/viem@2.55.2_typescript@6.0.3_zod@4.4.3/node_modules/viem/accounts/utils/signTypedData.ts","../node_modules/.pnpm/viem@2.55.2_typescript@6.0.3_zod@4.4.3/node_modules/viem/accounts/privateKeyToAccount.ts","../node_modules/.pnpm/@noble+ciphers@1.3.0/node_modules/@noble/ciphers/src/utils.ts","../node_modules/.pnpm/@noble+ciphers@1.3.0/node_modules/@noble/ciphers/src/aes.ts","../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/src/scrypt.ts","../node_modules/.pnpm/ox@0.14.30_typescript@6.0.3_zod@4.4.3/node_modules/ox/core/Keystore.ts","../src/lib/wallet/passphrase.ts","../src/lib/wallet/local.ts","../src/lib/wallet/index.ts"],"sourcesContent":["/**\n * PBKDF (RFC 2898). Can be used to create a key from password and salt.\n * @module\n */\nimport { hmac } from './hmac.ts';\n// prettier-ignore\nimport {\n ahash, anumber,\n asyncLoop, checkOpts, clean, createView, Hash, kdfInputToBytes,\n type CHash,\n type KDFInput\n} from './utils.ts';\n\nexport type Pbkdf2Opt = {\n c: number; // Iterations\n dkLen?: number; // Desired key length in bytes (Intended output length in octets of the derived key\n asyncTick?: number; // Maximum time in ms for which async function can block execution\n};\n// Common prologue and epilogue for sync/async functions\nfunction pbkdf2Init(hash: CHash, _password: KDFInput, _salt: KDFInput, _opts: Pbkdf2Opt) {\n ahash(hash);\n const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts);\n const { c, dkLen, asyncTick } = opts;\n anumber(c);\n anumber(dkLen);\n anumber(asyncTick);\n if (c < 1) throw new Error('iterations (c) should be >= 1');\n const password = kdfInputToBytes(_password);\n const salt = kdfInputToBytes(_salt);\n // DK = PBKDF2(PRF, Password, Salt, c, dkLen);\n const DK = new Uint8Array(dkLen);\n // U1 = PRF(Password, Salt + INT_32_BE(i))\n const PRF = hmac.create(hash, password);\n const PRFSalt = PRF._cloneInto().update(salt);\n return { c, dkLen, asyncTick, DK, PRF, PRFSalt };\n}\n\nfunction pbkdf2Output<T extends Hash<T>>(\n PRF: Hash<T>,\n PRFSalt: Hash<T>,\n DK: Uint8Array,\n prfW: Hash<T>,\n u: Uint8Array\n) {\n PRF.destroy();\n PRFSalt.destroy();\n if (prfW) prfW.destroy();\n clean(u);\n return DK;\n}\n\n/**\n * PBKDF2-HMAC: RFC 2898 key derivation function\n * @param hash - hash function that would be used e.g. sha256\n * @param password - password from which a derived key is generated\n * @param salt - cryptographic salt\n * @param opts - {c, dkLen} where c is work factor and dkLen is output message size\n * @example\n * const key = pbkdf2(sha256, 'password', 'salt', { dkLen: 32, c: Math.pow(2, 18) });\n */\nexport function pbkdf2(\n hash: CHash,\n password: KDFInput,\n salt: KDFInput,\n opts: Pbkdf2Opt\n): Uint8Array {\n const { c, dkLen, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);\n let prfW: any; // Working copy\n const arr = new Uint8Array(4);\n const view = createView(arr);\n const u = new Uint8Array(PRF.outputLen);\n // DK = T1 + T2 + ⋯ + Tdklen/hlen\n for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {\n // Ti = F(Password, Salt, c, i)\n const Ti = DK.subarray(pos, pos + PRF.outputLen);\n view.setInt32(0, ti, false);\n // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc\n // U1 = PRF(Password, Salt + INT_32_BE(i))\n (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);\n Ti.set(u.subarray(0, Ti.length));\n for (let ui = 1; ui < c; ui++) {\n // Uc = PRF(Password, Uc−1)\n PRF._cloneInto(prfW).update(u).digestInto(u);\n for (let i = 0; i < Ti.length; i++) Ti[i] ^= u[i];\n }\n }\n return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);\n}\n\n/**\n * PBKDF2-HMAC: RFC 2898 key derivation function. Async version.\n * @example\n * await pbkdf2Async(sha256, 'password', 'salt', { dkLen: 32, c: 500_000 });\n */\nexport async function pbkdf2Async(\n hash: CHash,\n password: KDFInput,\n salt: KDFInput,\n opts: Pbkdf2Opt\n): Promise<Uint8Array> {\n const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);\n let prfW: any; // Working copy\n const arr = new Uint8Array(4);\n const view = createView(arr);\n const u = new Uint8Array(PRF.outputLen);\n // DK = T1 + T2 + ⋯ + Tdklen/hlen\n for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {\n // Ti = F(Password, Salt, c, i)\n const Ti = DK.subarray(pos, pos + PRF.outputLen);\n view.setInt32(0, ti, false);\n // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc\n // U1 = PRF(Password, Salt + INT_32_BE(i))\n (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);\n Ti.set(u.subarray(0, Ti.length));\n await asyncLoop(c - 1, asyncTick, () => {\n // Uc = PRF(Password, Uc−1)\n PRF._cloneInto(prfW).update(u).digestInto(u);\n for (let i = 0; i < Ti.length; i++) Ti[i] ^= u[i];\n });\n }\n return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);\n}\n","import { secp256k1 } from '@noble/curves/secp256k1'\n\nimport type { ErrorType } from '../errors/utils.js'\nimport type { Hex } from '../types/misc.js'\nimport { type ToHexErrorType, toHex } from '../utils/encoding/toHex.js'\n\nexport type GeneratePrivateKeyErrorType = ToHexErrorType | ErrorType\n\n/**\n * @description Generates a random private key.\n *\n * @returns A randomly generated private key.\n */\nexport function generatePrivateKey(): Hex {\n return toHex(secp256k1.utils.randomPrivateKey())\n}\n","// TODO(v3): Rename to `toLocalAccount` + add `source` property to define source (privateKey, mnemonic, hdKey, etc).\n\nimport type { Address } from 'abitype'\n\nimport {\n InvalidAddressError,\n type InvalidAddressErrorType,\n} from '../errors/address.js'\nimport type { ErrorType } from '../errors/utils.js'\nimport {\n type IsAddressErrorType,\n isAddress,\n} from '../utils/address/isAddress.js'\nimport type {\n AccountSource,\n CustomSource,\n JsonRpcAccount,\n LocalAccount,\n} from './types.js'\n\ntype GetAccountReturnType<accountSource extends AccountSource> =\n | (accountSource extends Address ? JsonRpcAccount : never)\n | (accountSource extends CustomSource ? LocalAccount : never)\n\nexport type ToAccountErrorType =\n | InvalidAddressErrorType\n | IsAddressErrorType\n | ErrorType\n\n/**\n * @description Creates an Account from a custom signing implementation.\n *\n * @returns A Local Account.\n */\nexport function toAccount<accountSource extends AccountSource>(\n source: accountSource,\n): GetAccountReturnType<accountSource> {\n if (typeof source === 'string') {\n if (!isAddress(source, { strict: false }))\n throw new InvalidAddressError({ address: source })\n return {\n address: source,\n type: 'json-rpc',\n } as GetAccountReturnType<accountSource>\n }\n\n if (!isAddress(source.address, { strict: false }))\n throw new InvalidAddressError({ address: source.address })\n return {\n address: source.address,\n nonceManager: source.nonceManager,\n sign: source.sign,\n signAuthorization: source.signAuthorization,\n signMessage: source.signMessage,\n signTransaction: source.signTransaction,\n signTypedData: source.signTypedData,\n source: 'custom',\n type: 'local',\n } as GetAccountReturnType<accountSource>\n}\n","// TODO(v3): Convert to sync.\n\nimport { secp256k1 } from '@noble/curves/secp256k1'\n\nimport type { ErrorType } from '../../errors/utils.js'\nimport type { ByteArray, Hex, Signature } from '../../types/misc.js'\nimport { type IsHexErrorType, isHex } from '../../utils/data/isHex.js'\nimport {\n type HexToBytesErrorType,\n hexToBytes,\n} from '../../utils/encoding/toBytes.js'\nimport {\n type NumberToHexErrorType,\n numberToHex,\n} from '../../utils/encoding/toHex.js'\nimport { serializeSignature } from '../../utils/signature/serializeSignature.js'\n\ntype To = 'object' | 'bytes' | 'hex'\n\nexport type SignParameters<to extends To = 'object'> = {\n hash: Hex\n privateKey: Hex\n to?: to | To | undefined\n}\n\nexport type SignReturnType<to extends To = 'object'> =\n | (to extends 'object' ? Signature : never)\n | (to extends 'bytes' ? ByteArray : never)\n | (to extends 'hex' ? Hex : never)\n\nexport type SignErrorType =\n | HexToBytesErrorType\n | IsHexErrorType\n | NumberToHexErrorType\n | ErrorType\n\nlet extraEntropy: Hex | boolean = false\n\n/**\n * Sets extra entropy for signing functions.\n */\nexport function setSignEntropy(entropy: true | Hex) {\n if (!entropy) throw new Error('must be a `true` or a hex value.')\n extraEntropy = entropy\n}\n\n/**\n * @description Signs a hash with a given private key.\n *\n * @param hash The hash to sign.\n * @param privateKey The private key to sign with.\n *\n * @returns The signature.\n */\nexport async function sign<to extends To = 'object'>({\n hash,\n privateKey,\n to = 'object',\n}: SignParameters<to>): Promise<SignReturnType<to>> {\n const { r, s, recovery } = secp256k1.sign(\n hash.slice(2),\n privateKey.slice(2),\n {\n lowS: true,\n extraEntropy: isHex(extraEntropy, { strict: false })\n ? hexToBytes(extraEntropy)\n : extraEntropy,\n },\n )\n const signature = {\n r: numberToHex(r, { size: 32 }),\n s: numberToHex(s, { size: 32 }),\n v: recovery ? 28n : 27n,\n yParity: recovery,\n }\n return (() => {\n if (to === 'bytes' || to === 'hex')\n return serializeSignature({ ...signature, to })\n return signature\n })() as SignReturnType<to>\n}\n","import type { ErrorType } from '../../errors/utils.js'\nimport type {\n AuthorizationRequest,\n SignedAuthorization,\n} from '../../types/authorization.js'\nimport type { Hex, Signature } from '../../types/misc.js'\nimport type { Prettify } from '../../types/utils.js'\nimport {\n type HashAuthorizationErrorType,\n hashAuthorization,\n} from '../../utils/authorization/hashAuthorization.js'\nimport {\n type SignErrorType,\n type SignParameters,\n type SignReturnType,\n sign,\n} from './sign.js'\n\ntype To = 'object' | 'bytes' | 'hex'\n\nexport type SignAuthorizationParameters<to extends To = 'object'> =\n AuthorizationRequest & {\n /** The private key to sign with. */\n privateKey: Hex\n to?: SignParameters<to>['to'] | undefined\n }\n\nexport type SignAuthorizationReturnType<to extends To = 'object'> = Prettify<\n to extends 'object' ? SignedAuthorization : SignReturnType<to>\n>\n\nexport type SignAuthorizationErrorType =\n | SignErrorType\n | HashAuthorizationErrorType\n | ErrorType\n\n/**\n * Signs an Authorization hash in [EIP-7702 format](https://eips.ethereum.org/EIPS/eip-7702): `keccak256('0x05' || rlp([chain_id, address, nonce]))`.\n */\nexport async function signAuthorization<to extends To = 'object'>(\n parameters: SignAuthorizationParameters<to>,\n): Promise<SignAuthorizationReturnType<to>> {\n const { chainId, nonce, privateKey, to = 'object' } = parameters\n const address = parameters.contractAddress ?? parameters.address\n const signature = await sign({\n hash: hashAuthorization({ address, chainId, nonce }),\n privateKey,\n to,\n })\n if (to === 'object')\n return {\n address,\n chainId,\n nonce,\n ...(signature as Signature),\n } as any\n return signature as any\n}\n","import type { ErrorType } from '../../errors/utils.js'\nimport type { Hex, SignableMessage } from '../../types/misc.js'\nimport {\n type HashMessageErrorType,\n hashMessage,\n} from '../../utils/signature/hashMessage.js'\n\nimport { type SignErrorType, sign } from './sign.js'\n\nexport type SignMessageParameters = {\n /** The message to sign. */\n message: SignableMessage\n /** The private key to sign with. */\n privateKey: Hex\n}\n\nexport type SignMessageReturnType = Hex\n\nexport type SignMessageErrorType =\n | SignErrorType\n | HashMessageErrorType\n | ErrorType\n\n/**\n * @description Calculates an Ethereum-specific signature in [EIP-191 format](https://eips.ethereum.org/EIPS/eip-191):\n * `keccak256(\"\\x19Ethereum Signed Message:\\n\" + len(message) + message))`.\n *\n * @returns The signature.\n */\nexport async function signMessage({\n message,\n privateKey,\n}: SignMessageParameters): Promise<SignMessageReturnType> {\n return await sign({ hash: hashMessage(message), privateKey, to: 'hex' })\n}\n","import type { ErrorType } from '../../errors/utils.js'\nimport type { Hex } from '../../types/misc.js'\nimport type {\n TransactionSerializable,\n TransactionSerialized,\n} from '../../types/transaction.js'\nimport {\n type Keccak256ErrorType,\n keccak256,\n} from '../../utils/hash/keccak256.js'\nimport type { GetTransactionType } from '../../utils/transaction/getTransactionType.js'\nimport {\n type SerializeTransactionFn,\n serializeTransaction,\n} from '../../utils/transaction/serializeTransaction.js'\n\nimport { type SignErrorType, sign } from './sign.js'\n\nexport type SignTransactionParameters<\n serializer extends\n SerializeTransactionFn<TransactionSerializable> = SerializeTransactionFn<TransactionSerializable>,\n transaction extends Parameters<serializer>[0] = Parameters<serializer>[0],\n> = {\n privateKey: Hex\n transaction: transaction\n serializer?: serializer | undefined\n}\n\nexport type SignTransactionReturnType<\n serializer extends\n SerializeTransactionFn<TransactionSerializable> = SerializeTransactionFn<TransactionSerializable>,\n transaction extends Parameters<serializer>[0] = Parameters<serializer>[0],\n> = TransactionSerialized<GetTransactionType<transaction>>\n\nexport type SignTransactionErrorType =\n | Keccak256ErrorType\n | SignErrorType\n | ErrorType\n\nexport async function signTransaction<\n serializer extends\n SerializeTransactionFn<TransactionSerializable> = SerializeTransactionFn<TransactionSerializable>,\n transaction extends Parameters<serializer>[0] = Parameters<serializer>[0],\n>(\n parameters: SignTransactionParameters<serializer, transaction>,\n): Promise<SignTransactionReturnType<serializer, transaction>> {\n const {\n privateKey,\n transaction,\n serializer = serializeTransaction,\n } = parameters\n\n const signableTransaction = (() => {\n // For EIP-4844 Transactions, we want to sign the transaction payload body (tx_payload_body) without the sidecars (ie. without the network wrapper).\n // See: https://github.com/ethereum/EIPs/blob/e00f4daa66bd56e2dbd5f1d36d09fd613811a48b/EIPS/eip-4844.md#networking\n if (transaction.type === 'eip4844')\n return {\n ...transaction,\n sidecars: false,\n }\n return transaction\n })()\n\n const signature = await sign({\n hash: keccak256(await serializer(signableTransaction)),\n privateKey,\n })\n return (await serializer(\n transaction,\n signature,\n )) as SignTransactionReturnType<serializer, transaction>\n}\n","import type { TypedData } from 'abitype'\nimport type { ErrorType } from '../../errors/utils.js'\nimport type { Hex } from '../../types/misc.js'\nimport type { TypedDataDefinition } from '../../types/typedData.js'\nimport {\n type HashTypedDataErrorType,\n hashTypedData,\n} from '../../utils/signature/hashTypedData.js'\nimport { type SignErrorType, sign } from './sign.js'\n\nexport type SignTypedDataParameters<\n typedData extends TypedData | Record<string, unknown> = TypedData,\n primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData,\n> = TypedDataDefinition<typedData, primaryType> & {\n /** The private key to sign with. */\n privateKey: Hex\n}\n\nexport type SignTypedDataReturnType = Hex\n\nexport type SignTypedDataErrorType =\n | HashTypedDataErrorType\n | SignErrorType\n | ErrorType\n\n/**\n * @description Signs typed data and calculates an Ethereum-specific signature in [https://eips.ethereum.org/EIPS/eip-712](https://eips.ethereum.org/EIPS/eip-712):\n * `sign(keccak256(\"\\x19\\x01\" ‖ domainSeparator ‖ hashStruct(message)))`.\n *\n * @returns The signature.\n */\nexport async function signTypedData<\n const typedData extends TypedData | Record<string, unknown>,\n primaryType extends keyof typedData | 'EIP712Domain',\n>(\n parameters: SignTypedDataParameters<typedData, primaryType>,\n): Promise<SignTypedDataReturnType> {\n const { privateKey, ...typedData } =\n parameters as unknown as SignTypedDataParameters\n return await sign({\n hash: hashTypedData(typedData),\n privateKey,\n to: 'hex',\n })\n}\n","import { secp256k1 } from '@noble/curves/secp256k1'\nimport type { ErrorType } from '../errors/utils.js'\nimport type { Hex } from '../types/misc.js'\nimport { type ToHexErrorType, toHex } from '../utils/encoding/toHex.js'\nimport type { NonceManager } from '../utils/nonceManager.js'\nimport { type ToAccountErrorType, toAccount } from './toAccount.js'\nimport type { PrivateKeyAccount } from './types.js'\nimport {\n type PublicKeyToAddressErrorType,\n publicKeyToAddress,\n} from './utils/publicKeyToAddress.js'\nimport { type SignErrorType, sign } from './utils/sign.js'\nimport { signAuthorization } from './utils/signAuthorization.js'\nimport { type SignMessageErrorType, signMessage } from './utils/signMessage.js'\nimport {\n type SignTransactionErrorType,\n signTransaction,\n} from './utils/signTransaction.js'\nimport {\n type SignTypedDataErrorType,\n signTypedData,\n} from './utils/signTypedData.js'\n\nexport type PrivateKeyToAccountOptions = {\n nonceManager?: NonceManager | undefined\n}\n\nexport type PrivateKeyToAccountErrorType =\n | ToAccountErrorType\n | ToHexErrorType\n | PublicKeyToAddressErrorType\n | SignErrorType\n | SignMessageErrorType\n | SignTransactionErrorType\n | SignTypedDataErrorType\n | ErrorType\n\n/**\n * @description Creates an Account from a private key.\n *\n * @returns A Private Key Account.\n */\nexport function privateKeyToAccount(\n privateKey: Hex,\n options: PrivateKeyToAccountOptions = {},\n): PrivateKeyAccount {\n const { nonceManager } = options\n const publicKey = toHex(secp256k1.getPublicKey(privateKey.slice(2), false))\n const address = publicKeyToAddress(publicKey)\n\n const account = toAccount({\n address,\n nonceManager,\n async sign({ hash }) {\n return sign({ hash, privateKey, to: 'hex' })\n },\n async signAuthorization(authorization) {\n return signAuthorization({ ...authorization, privateKey })\n },\n async signMessage({ message }) {\n return signMessage({ message, privateKey })\n },\n async signTransaction(transaction, { serializer } = {}) {\n return signTransaction({ privateKey, transaction, serializer })\n },\n async signTypedData(typedData) {\n return signTypedData({ ...typedData, privateKey } as any)\n },\n })\n\n return {\n ...account,\n publicKey,\n source: 'privateKey',\n } as PrivateKeyAccount\n}\n","/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */\n\n/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */\nexport function isBytes(a: unknown): a is Uint8Array {\n return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');\n}\n\n/** Asserts something is boolean. */\nexport function abool(b: boolean): void {\n if (typeof b !== 'boolean') throw new Error(`boolean expected, not ${b}`);\n}\n\n/** Asserts something is positive integer. */\nexport function anumber(n: number): void {\n if (!Number.isSafeInteger(n) || n < 0) throw new Error('positive integer expected, got ' + n);\n}\n\n/** Asserts something is Uint8Array. */\nexport function abytes(b: Uint8Array | undefined, ...lengths: number[]): void {\n if (!isBytes(b)) throw new Error('Uint8Array expected');\n if (lengths.length > 0 && !lengths.includes(b.length))\n throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);\n}\n\n/**\n * Asserts something is hash\n * TODO: remove\n * @deprecated\n */\nexport function ahash(h: IHash): void {\n if (typeof h !== 'function' || typeof h.create !== 'function')\n throw new Error('Hash should be wrapped by utils.createHasher');\n anumber(h.outputLen);\n anumber(h.blockLen);\n}\n\n/** Asserts a hash instance has not been destroyed / finished */\nexport function aexists(instance: any, checkFinished = true): void {\n if (instance.destroyed) throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');\n}\n\n/** Asserts output is properly-sized byte array */\nexport function aoutput(out: any, instance: any): void {\n abytes(out);\n const min = instance.outputLen;\n if (out.length < min) {\n throw new Error('digestInto() expects output buffer of length at least ' + min);\n }\n}\n\nexport type IHash = {\n (data: string | Uint8Array): Uint8Array;\n blockLen: number;\n outputLen: number;\n create: any;\n};\n\n/** Generic type encompassing 8/16/32-byte arrays - but not 64-byte. */\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\n/** Cast u8 / u16 / u32 to u8. */\nexport function u8(arr: TypedArray): Uint8Array {\n return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/** Cast u8 / u16 / u32 to u32. */\nexport function u32(arr: TypedArray): Uint32Array {\n return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n}\n\n/** Zeroize a byte array. Warning: JS provides no guarantees. */\nexport function clean(...arrays: TypedArray[]): void {\n for (let i = 0; i < arrays.length; i++) {\n arrays[i].fill(0);\n }\n}\n\n/** Create DataView of an array for easy byte-level manipulation. */\nexport function createView(arr: TypedArray): DataView {\n return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/** Is current platform little-endian? Most are. Big-Endian platform: IBM */\nexport const isLE: boolean = /* @__PURE__ */ (() =>\n new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\nconst hasHexBuiltin: boolean = /* @__PURE__ */ (() =>\n // @ts-ignore\n typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n\n/**\n * Convert byte array to hex string. Uses built-in function, when available.\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n abytes(bytes);\n // @ts-ignore\n if (hasHexBuiltin) return bytes.toHex();\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n\n/**\n * Convert hex string to byte array. Uses built-in function, when available.\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex: string): Uint8Array {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n // @ts-ignore\n if (hasHexBuiltin) return Uint8Array.fromHex(hex);\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2) throw new Error('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new Error('hex string expected, got non-hex character \"' + char + '\" at index ' + hi);\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array;\n}\n\n// Used in micro\nexport function hexToNumber(hex: string): bigint {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n return BigInt(hex === '' ? '0' : '0x' + hex); // Big Endian\n}\n\n// Used in ff1\n// BE: Big Endian, LE: Little Endian\nexport function bytesToNumberBE(bytes: Uint8Array): bigint {\n return hexToNumber(bytesToHex(bytes));\n}\n\n// Used in micro, ff1\nexport function numberToBytesBE(n: number | bigint, len: number): Uint8Array {\n return hexToBytes(n.toString(16).padStart(len * 2, '0'));\n}\n\n// TODO: remove\n// There is no setImmediate in browser and setTimeout is slow.\n// call of async fn will return Promise, which will be fullfiled only on\n// next scheduler queue processing step and this is exactly what we need.\nexport const nextTick = async (): Promise<void> => {};\n\n// Global symbols, but ts doesn't see them: https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\ndeclare const TextDecoder: any;\n\n/**\n * Converts string to bytes using UTF8 encoding.\n * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])\n */\nexport function utf8ToBytes(str: string): Uint8Array {\n if (typeof str !== 'string') throw new Error('string expected');\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\n/**\n * Converts bytes to string using UTF8 encoding.\n * @example bytesToUtf8(new Uint8Array([97, 98, 99])) // 'abc'\n */\nexport function bytesToUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\n// TODO: remove\nexport type Input = Uint8Array | string;\n/**\n * Normalizes (non-hex) string or Uint8Array to Uint8Array.\n * Warning: when Uint8Array is passed, it would NOT get copied.\n * Keep in mind for future mutable operations.\n */\nexport function toBytes(data: string | Uint8Array): Uint8Array {\n if (typeof data === 'string') data = utf8ToBytes(data);\n else if (isBytes(data)) data = copyBytes(data);\n else throw new Error('Uint8Array expected, got ' + typeof data);\n return data;\n}\n\n/**\n * Checks if two U8A use same underlying buffer and overlaps.\n * This is invalid and can corrupt data.\n */\nexport function overlapBytes(a: Uint8Array, b: Uint8Array): boolean {\n return (\n a.buffer === b.buffer && // best we can do, may fail with an obscure Proxy\n a.byteOffset < b.byteOffset + b.byteLength && // a starts before b end\n b.byteOffset < a.byteOffset + a.byteLength // b starts before a end\n );\n}\n\n/**\n * If input and output overlap and input starts before output, we will overwrite end of input before\n * we start processing it, so this is not supported for most ciphers (except chacha/salse, which designed with this)\n */\nexport function complexOverlapBytes(input: Uint8Array, output: Uint8Array): void {\n // This is very cursed. It works somehow, but I'm completely unsure,\n // reasoning about overlapping aligned windows is very hard.\n if (overlapBytes(input, output) && input.byteOffset < output.byteOffset)\n throw new Error('complex overlap of input and output is not supported');\n}\n\n/**\n * Copies several Uint8Arrays into one.\n */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res;\n}\n\n// Used in ARX only\ntype EmptyObj = {};\nexport function checkOpts<T1 extends EmptyObj, T2 extends EmptyObj>(\n defaults: T1,\n opts: T2\n): T1 & T2 {\n if (opts == null || typeof opts !== 'object') throw new Error('options must be defined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\n/** Compares 2 uint8array-s in kinda constant time. */\nexport function equalBytes(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];\n return diff === 0;\n}\n\n// TODO: remove\n/** For runtime check if class implements interface. */\nexport abstract class Hash<T extends Hash<T>> {\n abstract blockLen: number; // Bytes per block\n abstract outputLen: number; // Bytes in output\n abstract update(buf: string | Uint8Array): this;\n // Writes digest into buf\n abstract digestInto(buf: Uint8Array): void;\n abstract digest(): Uint8Array;\n /**\n * Resets internal state. Makes Hash instance unusable.\n * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed\n * by user, they will need to manually call `destroy()` when zeroing is necessary.\n */\n abstract destroy(): void;\n}\n\n// This will allow to re-use with composable things like packed & base encoders\n// Also, we probably can make tags composable\n\n/** Sync cipher: takes byte array and returns byte array. */\nexport type Cipher = {\n encrypt(plaintext: Uint8Array): Uint8Array;\n decrypt(ciphertext: Uint8Array): Uint8Array;\n};\n\n/** Async cipher e.g. from built-in WebCrypto. */\nexport type AsyncCipher = {\n encrypt(plaintext: Uint8Array): Promise<Uint8Array>;\n decrypt(ciphertext: Uint8Array): Promise<Uint8Array>;\n};\n\n/** Cipher with `output` argument which can optimize by doing 1 less allocation. */\nexport type CipherWithOutput = Cipher & {\n encrypt(plaintext: Uint8Array, output?: Uint8Array): Uint8Array;\n decrypt(ciphertext: Uint8Array, output?: Uint8Array): Uint8Array;\n};\n\n/**\n * Params are outside of return type, so it is accessible before calling constructor.\n * If function support multiple nonceLength's, we return the best one.\n */\nexport type CipherParams = {\n blockSize: number;\n nonceLength?: number;\n tagLength?: number;\n varSizeNonce?: boolean;\n};\n/** ARX cipher, like salsa or chacha. */\nexport type ARXCipher = ((\n key: Uint8Array,\n nonce: Uint8Array,\n AAD?: Uint8Array\n) => CipherWithOutput) & {\n blockSize: number;\n nonceLength: number;\n tagLength: number;\n};\nexport type CipherCons<T extends any[]> = (key: Uint8Array, ...args: T) => Cipher;\n/**\n * Wraps a cipher: validates args, ensures encrypt() can only be called once.\n * @__NO_SIDE_EFFECTS__\n */\nexport const wrapCipher = <C extends CipherCons<any>, P extends CipherParams>(\n params: P,\n constructor: C\n): C & P => {\n function wrappedCipher(key: Uint8Array, ...args: any[]): CipherWithOutput {\n // Validate key\n abytes(key);\n\n // Big-Endian hardware is rare. Just in case someone still decides to run ciphers:\n if (!isLE) throw new Error('Non little-endian hardware is not yet supported');\n\n // Validate nonce if nonceLength is present\n if (params.nonceLength !== undefined) {\n const nonce = args[0];\n if (!nonce) throw new Error('nonce / iv required');\n if (params.varSizeNonce) abytes(nonce);\n else abytes(nonce, params.nonceLength);\n }\n\n // Validate AAD if tagLength present\n const tagl = params.tagLength;\n if (tagl && args[1] !== undefined) {\n abytes(args[1]);\n }\n\n const cipher = constructor(key, ...args);\n const checkOutput = (fnLength: number, output?: Uint8Array) => {\n if (output !== undefined) {\n if (fnLength !== 2) throw new Error('cipher output not supported');\n abytes(output);\n }\n };\n // Create wrapped cipher with validation and single-use encryption\n let called = false;\n const wrCipher = {\n encrypt(data: Uint8Array, output?: Uint8Array) {\n if (called) throw new Error('cannot encrypt() twice with same key + nonce');\n called = true;\n abytes(data);\n checkOutput(cipher.encrypt.length, output);\n return (cipher as CipherWithOutput).encrypt(data, output);\n },\n decrypt(data: Uint8Array, output?: Uint8Array) {\n abytes(data);\n if (tagl && data.length < tagl)\n throw new Error('invalid ciphertext length: smaller than tagLength=' + tagl);\n checkOutput(cipher.decrypt.length, output);\n return (cipher as CipherWithOutput).decrypt(data, output);\n },\n };\n\n return wrCipher;\n }\n\n Object.assign(wrappedCipher, params);\n return wrappedCipher as C & P;\n};\n\n/** Represents salsa / chacha stream. */\nexport type XorStream = (\n key: Uint8Array,\n nonce: Uint8Array,\n data: Uint8Array,\n output?: Uint8Array,\n counter?: number\n) => Uint8Array;\n\n/**\n * By default, returns u8a of length.\n * When out is available, it checks it for validity and uses it.\n */\nexport function getOutput(\n expectedLength: number,\n out?: Uint8Array,\n onlyAligned = true\n): Uint8Array {\n if (out === undefined) return new Uint8Array(expectedLength);\n if (out.length !== expectedLength)\n throw new Error('invalid output length, expected ' + expectedLength + ', got: ' + out.length);\n if (onlyAligned && !isAligned32(out)) throw new Error('invalid output, must be aligned');\n return out;\n}\n\n/** Polyfill for Safari 14. */\nexport function setBigUint64(\n view: DataView,\n byteOffset: number,\n value: bigint,\n isLE: boolean\n): void {\n if (typeof view.setBigUint64 === 'function') return view.setBigUint64(byteOffset, value, isLE);\n const _32n = BigInt(32);\n const _u32_max = BigInt(0xffffffff);\n const wh = Number((value >> _32n) & _u32_max);\n const wl = Number(value & _u32_max);\n const h = isLE ? 4 : 0;\n const l = isLE ? 0 : 4;\n view.setUint32(byteOffset + h, wh, isLE);\n view.setUint32(byteOffset + l, wl, isLE);\n}\n\nexport function u64Lengths(dataLength: number, aadLength: number, isLE: boolean): Uint8Array {\n abool(isLE);\n const num = new Uint8Array(16);\n const view = createView(num);\n setBigUint64(view, 0, BigInt(aadLength), isLE);\n setBigUint64(view, 8, BigInt(dataLength), isLE);\n return num;\n}\n\n// Is byte array aligned to 4 byte offset (u32)?\nexport function isAligned32(bytes: Uint8Array): boolean {\n return bytes.byteOffset % 4 === 0;\n}\n\n// copy bytes to new u8a (aligned). Because Buffer.slice is broken.\nexport function copyBytes(bytes: Uint8Array): Uint8Array {\n return Uint8Array.from(bytes);\n}\n","/**\n * [AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)\n * a.k.a. Advanced Encryption Standard\n * is a variant of Rijndael block cipher, standardized by NIST in 2001.\n * We provide the fastest available pure JS implementation.\n *\n * Data is split into 128-bit blocks. Encrypted in 10/12/14 rounds (128/192/256 bits). In every round:\n * 1. **S-box**, table substitution\n * 2. **Shift rows**, cyclic shift left of all rows of data array\n * 3. **Mix columns**, multiplying every column by fixed polynomial\n * 4. **Add round key**, round_key xor i-th column of array\n *\n * Check out [FIPS-197](https://csrc.nist.gov/files/pubs/fips/197/final/docs/fips-197.pdf)\n * and [original proposal](https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf)\n * @module\n */\nimport { ghash, polyval } from './_polyval.ts';\n// prettier-ignore\nimport {\n abytes, clean, complexOverlapBytes, concatBytes,\n copyBytes, createView, equalBytes, getOutput, isAligned32, overlapBytes,\n setBigUint64, u32, u64Lengths, u8, wrapCipher,\n type Cipher, type CipherWithOutput,\n} from './utils.ts';\n\nconst BLOCK_SIZE = 16;\nconst BLOCK_SIZE32 = 4;\nconst EMPTY_BLOCK = /* @__PURE__ */ new Uint8Array(BLOCK_SIZE);\nconst POLY = 0x11b; // 1 + x + x**3 + x**4 + x**8\n\n// TODO: remove multiplication, binary ops only\nfunction mul2(n: number) {\n return (n << 1) ^ (POLY & -(n >> 7));\n}\n\nfunction mul(a: number, b: number) {\n let res = 0;\n for (; b > 0; b >>= 1) {\n // Montgomery ladder\n res ^= a & -(b & 1); // if (b&1) res ^=a (but const-time).\n a = mul2(a); // a = 2*a\n }\n return res;\n}\n\n// AES S-box is generated using finite field inversion,\n// an affine transform, and xor of a constant 0x63.\nconst sbox = /* @__PURE__ */ (() => {\n const t = new Uint8Array(256);\n for (let i = 0, x = 1; i < 256; i++, x ^= mul2(x)) t[i] = x;\n const box = new Uint8Array(256);\n box[0] = 0x63; // first elm\n for (let i = 0; i < 255; i++) {\n let x = t[255 - i];\n x |= x << 8;\n box[t[i]] = (x ^ (x >> 4) ^ (x >> 5) ^ (x >> 6) ^ (x >> 7) ^ 0x63) & 0xff;\n }\n clean(t);\n return box;\n})();\n\n// Inverted S-box\nconst invSbox = /* @__PURE__ */ sbox.map((_, j) => sbox.indexOf(j));\n\n// Rotate u32 by 8\nconst rotr32_8 = (n: number) => (n << 24) | (n >>> 8);\nconst rotl32_8 = (n: number) => (n << 8) | (n >>> 24);\n// The byte swap operation for uint32 (LE<->BE)\nconst byteSwap = (word: number) =>\n ((word << 24) & 0xff000000) |\n ((word << 8) & 0xff0000) |\n ((word >>> 8) & 0xff00) |\n ((word >>> 24) & 0xff);\n\n// T-table is optimization suggested in 5.2 of original proposal (missed from FIPS-197). Changes:\n// - LE instead of BE\n// - bigger tables: T0 and T1 are merged into T01 table and T2 & T3 into T23;\n// so index is u16, instead of u8. This speeds up things, unexpectedly\nfunction genTtable(sbox: Uint8Array, fn: (n: number) => number) {\n if (sbox.length !== 256) throw new Error('Wrong sbox length');\n const T0 = new Uint32Array(256).map((_, j) => fn(sbox[j]));\n const T1 = T0.map(rotl32_8);\n const T2 = T1.map(rotl32_8);\n const T3 = T2.map(rotl32_8);\n const T01 = new Uint32Array(256 * 256);\n const T23 = new Uint32Array(256 * 256);\n const sbox2 = new Uint16Array(256 * 256);\n for (let i = 0; i < 256; i++) {\n for (let j = 0; j < 256; j++) {\n const idx = i * 256 + j;\n T01[idx] = T0[i] ^ T1[j];\n T23[idx] = T2[i] ^ T3[j];\n sbox2[idx] = (sbox[i] << 8) | sbox[j];\n }\n }\n return { sbox, sbox2, T0, T1, T2, T3, T01, T23 };\n}\n\nconst tableEncoding = /* @__PURE__ */ genTtable(\n sbox,\n (s: number) => (mul(s, 3) << 24) | (s << 16) | (s << 8) | mul(s, 2)\n);\nconst tableDecoding = /* @__PURE__ */ genTtable(\n invSbox,\n (s) => (mul(s, 11) << 24) | (mul(s, 13) << 16) | (mul(s, 9) << 8) | mul(s, 14)\n);\n\nconst xPowers = /* @__PURE__ */ (() => {\n const p = new Uint8Array(16);\n for (let i = 0, x = 1; i < 16; i++, x = mul2(x)) p[i] = x;\n return p;\n})();\n\n/** Key expansion used in CTR. */\nfunction expandKeyLE(key: Uint8Array): Uint32Array {\n abytes(key);\n const len = key.length;\n if (![16, 24, 32].includes(len))\n throw new Error('aes: invalid key size, should be 16, 24 or 32, got ' + len);\n const { sbox2 } = tableEncoding;\n const toClean = [];\n if (!isAligned32(key)) toClean.push((key = copyBytes(key)));\n const k32 = u32(key);\n const Nk = k32.length;\n const subByte = (n: number) => applySbox(sbox2, n, n, n, n);\n const xk = new Uint32Array(len + 28); // expanded key\n xk.set(k32);\n // 4.3.1 Key expansion\n for (let i = Nk; i < xk.length; i++) {\n let t = xk[i - 1];\n if (i % Nk === 0) t = subByte(rotr32_8(t)) ^ xPowers[i / Nk - 1];\n else if (Nk > 6 && i % Nk === 4) t = subByte(t);\n xk[i] = xk[i - Nk] ^ t;\n }\n clean(...toClean);\n return xk;\n}\n\nfunction expandKeyDecLE(key: Uint8Array): Uint32Array {\n const encKey = expandKeyLE(key);\n const xk = encKey.slice();\n const Nk = encKey.length;\n const { sbox2 } = tableEncoding;\n const { T0, T1, T2, T3 } = tableDecoding;\n // Inverse key by chunks of 4 (rounds)\n for (let i = 0; i < Nk; i += 4) {\n for (let j = 0; j < 4; j++) xk[i + j] = encKey[Nk - i - 4 + j];\n }\n clean(encKey);\n // apply InvMixColumn except first & last round\n for (let i = 4; i < Nk - 4; i++) {\n const x = xk[i];\n const w = applySbox(sbox2, x, x, x, x);\n xk[i] = T0[w & 0xff] ^ T1[(w >>> 8) & 0xff] ^ T2[(w >>> 16) & 0xff] ^ T3[w >>> 24];\n }\n return xk;\n}\n\n// Apply tables\nfunction apply0123(\n T01: Uint32Array,\n T23: Uint32Array,\n s0: number,\n s1: number,\n s2: number,\n s3: number\n) {\n return (\n T01[((s0 << 8) & 0xff00) | ((s1 >>> 8) & 0xff)] ^\n T23[((s2 >>> 8) & 0xff00) | ((s3 >>> 24) & 0xff)]\n );\n}\n\nfunction applySbox(sbox2: Uint16Array, s0: number, s1: number, s2: number, s3: number) {\n return (\n sbox2[(s0 & 0xff) | (s1 & 0xff00)] |\n (sbox2[((s2 >>> 16) & 0xff) | ((s3 >>> 16) & 0xff00)] << 16)\n );\n}\n\nfunction encrypt(\n xk: Uint32Array,\n s0: number,\n s1: number,\n s2: number,\n s3: number\n): { s0: number; s1: number; s2: number; s3: number } {\n const { sbox2, T01, T23 } = tableEncoding;\n let k = 0;\n (s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++]);\n const rounds = xk.length / 4 - 2;\n for (let i = 0; i < rounds; i++) {\n const t0 = xk[k++] ^ apply0123(T01, T23, s0, s1, s2, s3);\n const t1 = xk[k++] ^ apply0123(T01, T23, s1, s2, s3, s0);\n const t2 = xk[k++] ^ apply0123(T01, T23, s2, s3, s0, s1);\n const t3 = xk[k++] ^ apply0123(T01, T23, s3, s0, s1, s2);\n (s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3);\n }\n // last round (without mixcolumns, so using SBOX2 table)\n const t0 = xk[k++] ^ applySbox(sbox2, s0, s1, s2, s3);\n const t1 = xk[k++] ^ applySbox(sbox2, s1, s2, s3, s0);\n const t2 = xk[k++] ^ applySbox(sbox2, s2, s3, s0, s1);\n const t3 = xk[k++] ^ applySbox(sbox2, s3, s0, s1, s2);\n return { s0: t0, s1: t1, s2: t2, s3: t3 };\n}\n\n// Can't be merged with encrypt: arg positions for apply0123 / applySbox are different\nfunction decrypt(\n xk: Uint32Array,\n s0: number,\n s1: number,\n s2: number,\n s3: number\n): {\n s0: number;\n s1: number;\n s2: number;\n s3: number;\n} {\n const { sbox2, T01, T23 } = tableDecoding;\n let k = 0;\n (s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++]);\n const rounds = xk.length / 4 - 2;\n for (let i = 0; i < rounds; i++) {\n const t0 = xk[k++] ^ apply0123(T01, T23, s0, s3, s2, s1);\n const t1 = xk[k++] ^ apply0123(T01, T23, s1, s0, s3, s2);\n const t2 = xk[k++] ^ apply0123(T01, T23, s2, s1, s0, s3);\n const t3 = xk[k++] ^ apply0123(T01, T23, s3, s2, s1, s0);\n (s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3);\n }\n // Last round\n const t0: number = xk[k++] ^ applySbox(sbox2, s0, s3, s2, s1);\n const t1: number = xk[k++] ^ applySbox(sbox2, s1, s0, s3, s2);\n const t2: number = xk[k++] ^ applySbox(sbox2, s2, s1, s0, s3);\n const t3: number = xk[k++] ^ applySbox(sbox2, s3, s2, s1, s0);\n return { s0: t0, s1: t1, s2: t2, s3: t3 };\n}\n\n// TODO: investigate merging with ctr32\nfunction ctrCounter(\n xk: Uint32Array,\n nonce: Uint8Array,\n src: Uint8Array,\n dst?: Uint8Array\n): Uint8Array {\n abytes(nonce, BLOCK_SIZE);\n abytes(src);\n const srcLen = src.length;\n dst = getOutput(srcLen, dst);\n complexOverlapBytes(src, dst);\n const ctr = nonce;\n const c32 = u32(ctr);\n // Fill block (empty, ctr=0)\n let { s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]);\n const src32 = u32(src);\n const dst32 = u32(dst);\n // process blocks\n for (let i = 0; i + 4 <= src32.length; i += 4) {\n dst32[i + 0] = src32[i + 0] ^ s0;\n dst32[i + 1] = src32[i + 1] ^ s1;\n dst32[i + 2] = src32[i + 2] ^ s2;\n dst32[i + 3] = src32[i + 3] ^ s3;\n // Full 128 bit counter with wrap around\n let carry = 1;\n for (let i = ctr.length - 1; i >= 0; i--) {\n carry = (carry + (ctr[i] & 0xff)) | 0;\n ctr[i] = carry & 0xff;\n carry >>>= 8;\n }\n ({ s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]));\n }\n // leftovers (less than block)\n // It's possible to handle > u32 fast, but is it worth it?\n const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);\n if (start < srcLen) {\n const b32 = new Uint32Array([s0, s1, s2, s3]);\n const buf = u8(b32);\n for (let i = start, pos = 0; i < srcLen; i++, pos++) dst[i] = src[i] ^ buf[pos];\n clean(b32);\n }\n return dst;\n}\n\n// AES CTR with overflowing 32 bit counter\n// It's possible to do 32le significantly simpler (and probably faster) by using u32.\n// But, we need both, and perf bottleneck is in ghash anyway.\nfunction ctr32(\n xk: Uint32Array,\n isLE: boolean,\n nonce: Uint8Array,\n src: Uint8Array,\n dst?: Uint8Array\n): Uint8Array {\n abytes(nonce, BLOCK_SIZE);\n abytes(src);\n dst = getOutput(src.length, dst);\n const ctr = nonce; // write new value to nonce, so it can be re-used\n const c32 = u32(ctr);\n const view = createView(ctr);\n const src32 = u32(src);\n const dst32 = u32(dst);\n const ctrPos = isLE ? 0 : 12;\n const srcLen = src.length;\n // Fill block (empty, ctr=0)\n let ctrNum = view.getUint32(ctrPos, isLE); // read current counter value\n let { s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]);\n // process blocks\n for (let i = 0; i + 4 <= src32.length; i += 4) {\n dst32[i + 0] = src32[i + 0] ^ s0;\n dst32[i + 1] = src32[i + 1] ^ s1;\n dst32[i + 2] = src32[i + 2] ^ s2;\n dst32[i + 3] = src32[i + 3] ^ s3;\n ctrNum = (ctrNum + 1) >>> 0; // u32 wrap\n view.setUint32(ctrPos, ctrNum, isLE);\n ({ s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]));\n }\n // leftovers (less than a block)\n const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);\n if (start < srcLen) {\n const b32 = new Uint32Array([s0, s1, s2, s3]);\n const buf = u8(b32);\n for (let i = start, pos = 0; i < srcLen; i++, pos++) dst[i] = src[i] ^ buf[pos];\n clean(b32);\n }\n return dst;\n}\n\n/**\n * CTR: counter mode. Creates stream cipher.\n * Requires good IV. Parallelizable. OK, but no MAC.\n */\nexport const ctr: ((key: Uint8Array, nonce: Uint8Array) => CipherWithOutput) & {\n blockSize: number;\n nonceLength: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, nonceLength: 16 },\n function aesctr(key: Uint8Array, nonce: Uint8Array): CipherWithOutput {\n function processCtr(buf: Uint8Array, dst?: Uint8Array) {\n abytes(buf);\n if (dst !== undefined) {\n abytes(dst);\n if (!isAligned32(dst)) throw new Error('unaligned destination');\n }\n const xk = expandKeyLE(key);\n const n = copyBytes(nonce); // align + avoid changing\n const toClean = [xk, n];\n if (!isAligned32(buf)) toClean.push((buf = copyBytes(buf)));\n const out = ctrCounter(xk, n, buf, dst);\n clean(...toClean);\n return out;\n }\n return {\n encrypt: (plaintext: Uint8Array, dst?: Uint8Array) => processCtr(plaintext, dst),\n decrypt: (ciphertext: Uint8Array, dst?: Uint8Array) => processCtr(ciphertext, dst),\n };\n }\n);\n\nfunction validateBlockDecrypt(data: Uint8Array) {\n abytes(data);\n if (data.length % BLOCK_SIZE !== 0) {\n throw new Error(\n 'aes-(cbc/ecb).decrypt ciphertext should consist of blocks with size ' + BLOCK_SIZE\n );\n }\n}\n\nfunction validateBlockEncrypt(plaintext: Uint8Array, pcks5: boolean, dst?: Uint8Array) {\n abytes(plaintext);\n let outLen = plaintext.length;\n const remaining = outLen % BLOCK_SIZE;\n if (!pcks5 && remaining !== 0)\n throw new Error('aec/(cbc-ecb): unpadded plaintext with disabled padding');\n if (!isAligned32(plaintext)) plaintext = copyBytes(plaintext);\n const b = u32(plaintext);\n if (pcks5) {\n let left = BLOCK_SIZE - remaining;\n if (!left) left = BLOCK_SIZE; // if no bytes left, create empty padding block\n outLen = outLen + left;\n }\n dst = getOutput(outLen, dst);\n complexOverlapBytes(plaintext, dst);\n const o = u32(dst);\n return { b, o, out: dst };\n}\n\nfunction validatePCKS(data: Uint8Array, pcks5: boolean) {\n if (!pcks5) return data;\n const len = data.length;\n if (!len) throw new Error('aes/pcks5: empty ciphertext not allowed');\n const lastByte = data[len - 1];\n if (lastByte <= 0 || lastByte > 16) throw new Error('aes/pcks5: wrong padding');\n const out = data.subarray(0, -lastByte);\n for (let i = 0; i < lastByte; i++)\n if (data[len - i - 1] !== lastByte) throw new Error('aes/pcks5: wrong padding');\n return out;\n}\n\nfunction padPCKS(left: Uint8Array) {\n const tmp = new Uint8Array(16);\n const tmp32 = u32(tmp);\n tmp.set(left);\n const paddingByte = BLOCK_SIZE - left.length;\n for (let i = BLOCK_SIZE - paddingByte; i < BLOCK_SIZE; i++) tmp[i] = paddingByte;\n return tmp32;\n}\n\n/** Options for ECB and CBC. */\nexport type BlockOpts = { disablePadding?: boolean };\n\n/**\n * ECB: Electronic CodeBook. Simple deterministic replacement.\n * Dangerous: always map x to y. See [AES Penguin](https://words.filippo.io/the-ecb-penguin/).\n */\nexport const ecb: ((key: Uint8Array, opts?: BlockOpts) => CipherWithOutput) & {\n blockSize: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16 },\n function aesecb(key: Uint8Array, opts: BlockOpts = {}): CipherWithOutput {\n const pcks5 = !opts.disablePadding;\n return {\n encrypt(plaintext: Uint8Array, dst?: Uint8Array) {\n const { b, o, out: _out } = validateBlockEncrypt(plaintext, pcks5, dst);\n const xk = expandKeyLE(key);\n let i = 0;\n for (; i + 4 <= b.length; ) {\n const { s0, s1, s2, s3 } = encrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]);\n (o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);\n }\n if (pcks5) {\n const tmp32 = padPCKS(plaintext.subarray(i * 4));\n const { s0, s1, s2, s3 } = encrypt(xk, tmp32[0], tmp32[1], tmp32[2], tmp32[3]);\n (o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);\n }\n clean(xk);\n return _out;\n },\n decrypt(ciphertext: Uint8Array, dst?: Uint8Array) {\n validateBlockDecrypt(ciphertext);\n const xk = expandKeyDecLE(key);\n dst = getOutput(ciphertext.length, dst);\n const toClean: (Uint8Array | Uint32Array)[] = [xk];\n if (!isAligned32(ciphertext)) toClean.push((ciphertext = copyBytes(ciphertext)));\n complexOverlapBytes(ciphertext, dst);\n const b = u32(ciphertext);\n const o = u32(dst);\n for (let i = 0; i + 4 <= b.length; ) {\n const { s0, s1, s2, s3 } = decrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]);\n (o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);\n }\n clean(...toClean);\n return validatePCKS(dst, pcks5);\n },\n };\n }\n);\n\n/**\n * CBC: Cipher-Block-Chaining. Key is previous round’s block.\n * Fragile: needs proper padding. Unauthenticated: needs MAC.\n */\nexport const cbc: ((key: Uint8Array, iv: Uint8Array, opts?: BlockOpts) => CipherWithOutput) & {\n blockSize: number;\n nonceLength: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, nonceLength: 16 },\n function aescbc(key: Uint8Array, iv: Uint8Array, opts: BlockOpts = {}): CipherWithOutput {\n const pcks5 = !opts.disablePadding;\n return {\n encrypt(plaintext: Uint8Array, dst?: Uint8Array) {\n const xk = expandKeyLE(key);\n const { b, o, out: _out } = validateBlockEncrypt(plaintext, pcks5, dst);\n let _iv = iv;\n const toClean: (Uint8Array | Uint32Array)[] = [xk];\n if (!isAligned32(_iv)) toClean.push((_iv = copyBytes(_iv)));\n const n32 = u32(_iv);\n // prettier-ignore\n let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];\n let i = 0;\n for (; i + 4 <= b.length; ) {\n (s0 ^= b[i + 0]), (s1 ^= b[i + 1]), (s2 ^= b[i + 2]), (s3 ^= b[i + 3]);\n ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));\n (o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);\n }\n if (pcks5) {\n const tmp32 = padPCKS(plaintext.subarray(i * 4));\n (s0 ^= tmp32[0]), (s1 ^= tmp32[1]), (s2 ^= tmp32[2]), (s3 ^= tmp32[3]);\n ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));\n (o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);\n }\n clean(...toClean);\n return _out;\n },\n decrypt(ciphertext: Uint8Array, dst?: Uint8Array) {\n validateBlockDecrypt(ciphertext);\n const xk = expandKeyDecLE(key);\n let _iv = iv;\n const toClean: (Uint8Array | Uint32Array)[] = [xk];\n if (!isAligned32(_iv)) toClean.push((_iv = copyBytes(_iv)));\n const n32 = u32(_iv);\n dst = getOutput(ciphertext.length, dst);\n if (!isAligned32(ciphertext)) toClean.push((ciphertext = copyBytes(ciphertext)));\n complexOverlapBytes(ciphertext, dst);\n const b = u32(ciphertext);\n const o = u32(dst);\n // prettier-ignore\n let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];\n for (let i = 0; i + 4 <= b.length; ) {\n // prettier-ignore\n const ps0 = s0, ps1 = s1, ps2 = s2, ps3 = s3;\n (s0 = b[i + 0]), (s1 = b[i + 1]), (s2 = b[i + 2]), (s3 = b[i + 3]);\n const { s0: o0, s1: o1, s2: o2, s3: o3 } = decrypt(xk, s0, s1, s2, s3);\n (o[i++] = o0 ^ ps0), (o[i++] = o1 ^ ps1), (o[i++] = o2 ^ ps2), (o[i++] = o3 ^ ps3);\n }\n clean(...toClean);\n return validatePCKS(dst, pcks5);\n },\n };\n }\n);\n\n/**\n * CFB: Cipher Feedback Mode. The input for the block cipher is the previous cipher output.\n * Unauthenticated: needs MAC.\n */\nexport const cfb: ((key: Uint8Array, iv: Uint8Array) => CipherWithOutput) & {\n blockSize: number;\n nonceLength: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, nonceLength: 16 },\n function aescfb(key: Uint8Array, iv: Uint8Array): CipherWithOutput {\n function processCfb(src: Uint8Array, isEncrypt: boolean, dst?: Uint8Array) {\n abytes(src);\n const srcLen = src.length;\n dst = getOutput(srcLen, dst);\n if (overlapBytes(src, dst)) throw new Error('overlapping src and dst not supported.');\n const xk = expandKeyLE(key);\n let _iv = iv;\n const toClean: (Uint8Array | Uint32Array)[] = [xk];\n if (!isAligned32(_iv)) toClean.push((_iv = copyBytes(_iv)));\n if (!isAligned32(src)) toClean.push((src = copyBytes(src)));\n const src32 = u32(src);\n const dst32 = u32(dst);\n const next32 = isEncrypt ? dst32 : src32;\n const n32 = u32(_iv);\n // prettier-ignore\n let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];\n for (let i = 0; i + 4 <= src32.length; ) {\n const { s0: e0, s1: e1, s2: e2, s3: e3 } = encrypt(xk, s0, s1, s2, s3);\n dst32[i + 0] = src32[i + 0] ^ e0;\n dst32[i + 1] = src32[i + 1] ^ e1;\n dst32[i + 2] = src32[i + 2] ^ e2;\n dst32[i + 3] = src32[i + 3] ^ e3;\n (s0 = next32[i++]), (s1 = next32[i++]), (s2 = next32[i++]), (s3 = next32[i++]);\n }\n // leftovers (less than block)\n const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);\n if (start < srcLen) {\n ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));\n const buf = u8(new Uint32Array([s0, s1, s2, s3]));\n for (let i = start, pos = 0; i < srcLen; i++, pos++) dst[i] = src[i] ^ buf[pos];\n clean(buf);\n }\n clean(...toClean);\n return dst;\n }\n return {\n encrypt: (plaintext: Uint8Array, dst?: Uint8Array) => processCfb(plaintext, true, dst),\n decrypt: (ciphertext: Uint8Array, dst?: Uint8Array) => processCfb(ciphertext, false, dst),\n };\n }\n);\n\n// TODO: merge with chacha, however gcm has bitLen while chacha has byteLen\nfunction computeTag(\n fn: typeof ghash,\n isLE: boolean,\n key: Uint8Array,\n data: Uint8Array,\n AAD?: Uint8Array\n) {\n const aadLength = AAD ? AAD.length : 0;\n const h = fn.create(key, data.length + aadLength);\n if (AAD) h.update(AAD);\n const num = u64Lengths(8 * data.length, 8 * aadLength, isLE);\n h.update(data);\n h.update(num);\n const res = h.digest();\n clean(num);\n return res;\n}\n\n/**\n * GCM: Galois/Counter Mode.\n * Modern, parallel version of CTR, with MAC.\n * Be careful: MACs can be forged.\n * Unsafe to use random nonces under the same key, due to collision chance.\n * As for nonce size, prefer 12-byte, instead of 8-byte.\n */\nexport const gcm: ((key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array) => Cipher) & {\n blockSize: number;\n nonceLength: number;\n tagLength: number;\n varSizeNonce: true;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, nonceLength: 12, tagLength: 16, varSizeNonce: true },\n function aesgcm(key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array): Cipher {\n // NIST 800-38d doesn't enforce minimum nonce length.\n // We enforce 8 bytes for compat with openssl.\n // 12 bytes are recommended. More than 12 bytes would be converted into 12.\n if (nonce.length < 8) throw new Error('aes/gcm: invalid nonce length');\n const tagLength = 16;\n function _computeTag(authKey: Uint8Array, tagMask: Uint8Array, data: Uint8Array) {\n const tag = computeTag(ghash, false, authKey, data, AAD);\n for (let i = 0; i < tagMask.length; i++) tag[i] ^= tagMask[i];\n return tag;\n }\n function deriveKeys() {\n const xk = expandKeyLE(key);\n const authKey = EMPTY_BLOCK.slice();\n const counter = EMPTY_BLOCK.slice();\n ctr32(xk, false, counter, counter, authKey);\n // NIST 800-38d, page 15: different behavior for 96-bit and non-96-bit nonces\n if (nonce.length === 12) {\n counter.set(nonce);\n } else {\n const nonceLen = EMPTY_BLOCK.slice();\n const view = createView(nonceLen);\n setBigUint64(view, 8, BigInt(nonce.length * 8), false);\n // ghash(nonce || u64be(0) || u64be(nonceLen*8))\n const g = ghash.create(authKey).update(nonce).update(nonceLen);\n g.digestInto(counter); // digestInto doesn't trigger '.destroy'\n g.destroy();\n }\n const tagMask = ctr32(xk, false, counter, EMPTY_BLOCK);\n return { xk, authKey, counter, tagMask };\n }\n return {\n encrypt(plaintext: Uint8Array) {\n const { xk, authKey, counter, tagMask } = deriveKeys();\n const out = new Uint8Array(plaintext.length + tagLength);\n const toClean: (Uint8Array | Uint32Array)[] = [xk, authKey, counter, tagMask];\n if (!isAligned32(plaintext)) toClean.push((plaintext = copyBytes(plaintext)));\n ctr32(xk, false, counter, plaintext, out.subarray(0, plaintext.length));\n const tag = _computeTag(authKey, tagMask, out.subarray(0, out.length - tagLength));\n toClean.push(tag);\n out.set(tag, plaintext.length);\n clean(...toClean);\n return out;\n },\n decrypt(ciphertext: Uint8Array) {\n const { xk, authKey, counter, tagMask } = deriveKeys();\n const toClean: (Uint8Array | Uint32Array)[] = [xk, authKey, tagMask, counter];\n if (!isAligned32(ciphertext)) toClean.push((ciphertext = copyBytes(ciphertext)));\n const data = ciphertext.subarray(0, -tagLength);\n const passedTag = ciphertext.subarray(-tagLength);\n const tag = _computeTag(authKey, tagMask, data);\n toClean.push(tag);\n if (!equalBytes(tag, passedTag)) throw new Error('aes/gcm: invalid ghash tag');\n const out = ctr32(xk, false, counter, data);\n clean(...toClean);\n return out;\n },\n };\n }\n);\n\nconst limit = (name: string, min: number, max: number) => (value: number) => {\n if (!Number.isSafeInteger(value) || min > value || value > max) {\n const minmax = '[' + min + '..' + max + ']';\n throw new Error('' + name + ': expected value in range ' + minmax + ', got ' + value);\n }\n};\n\n/**\n * AES-GCM-SIV: classic AES-GCM with nonce-misuse resistance.\n * Guarantees that, when a nonce is repeated, the only security loss is that identical\n * plaintexts will produce identical ciphertexts.\n * RFC 8452, https://datatracker.ietf.org/doc/html/rfc8452\n */\nexport const gcmsiv: ((key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array) => Cipher) & {\n blockSize: number;\n nonceLength: number;\n tagLength: number;\n varSizeNonce: true;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, nonceLength: 12, tagLength: 16, varSizeNonce: true },\n function aessiv(key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array): Cipher {\n const tagLength = 16;\n // From RFC 8452: Section 6\n const AAD_LIMIT = limit('AAD', 0, 2 ** 36);\n const PLAIN_LIMIT = limit('plaintext', 0, 2 ** 36);\n const NONCE_LIMIT = limit('nonce', 12, 12);\n const CIPHER_LIMIT = limit('ciphertext', 16, 2 ** 36 + 16);\n abytes(key, 16, 24, 32);\n NONCE_LIMIT(nonce.length);\n if (AAD !== undefined) AAD_LIMIT(AAD.length);\n function deriveKeys() {\n const xk = expandKeyLE(key);\n const encKey = new Uint8Array(key.length);\n const authKey = new Uint8Array(16);\n const toClean: (Uint8Array | Uint32Array)[] = [xk, encKey];\n let _nonce = nonce;\n if (!isAligned32(_nonce)) toClean.push((_nonce = copyBytes(_nonce)));\n const n32 = u32(_nonce);\n // prettier-ignore\n let s0 = 0, s1 = n32[0], s2 = n32[1], s3 = n32[2];\n let counter = 0;\n for (const derivedKey of [authKey, encKey].map(u32)) {\n const d32 = u32(derivedKey);\n for (let i = 0; i < d32.length; i += 2) {\n // aes(u32le(0) || nonce)[:8] || aes(u32le(1) || nonce)[:8] ...\n const { s0: o0, s1: o1 } = encrypt(xk, s0, s1, s2, s3);\n d32[i + 0] = o0;\n d32[i + 1] = o1;\n s0 = ++counter; // increment counter inside state\n }\n }\n const res = { authKey, encKey: expandKeyLE(encKey) };\n // Cleanup\n clean(...toClean);\n return res;\n }\n function _computeTag(encKey: Uint32Array, authKey: Uint8Array, data: Uint8Array) {\n const tag = computeTag(polyval, true, authKey, data, AAD);\n // Compute the expected tag by XORing S_s and the nonce, clearing the\n // most significant bit of the last byte and encrypting with the\n // message-encryption key.\n for (let i = 0; i < 12; i++) tag[i] ^= nonce[i];\n tag[15] &= 0x7f; // Clear the highest bit\n // encrypt tag as block\n const t32 = u32(tag);\n // prettier-ignore\n let s0 = t32[0], s1 = t32[1], s2 = t32[2], s3 = t32[3];\n ({ s0, s1, s2, s3 } = encrypt(encKey, s0, s1, s2, s3));\n (t32[0] = s0), (t32[1] = s1), (t32[2] = s2), (t32[3] = s3);\n return tag;\n }\n // actual decrypt/encrypt of message.\n function processSiv(encKey: Uint32Array, tag: Uint8Array, input: Uint8Array) {\n let block = copyBytes(tag);\n block[15] |= 0x80; // Force highest bit\n const res = ctr32(encKey, true, block, input);\n // Cleanup\n clean(block);\n return res;\n }\n return {\n encrypt(plaintext: Uint8Array) {\n PLAIN_LIMIT(plaintext.length);\n const { encKey, authKey } = deriveKeys();\n const tag = _computeTag(encKey, authKey, plaintext);\n const toClean: (Uint8Array | Uint32Array)[] = [encKey, authKey, tag];\n if (!isAligned32(plaintext)) toClean.push((plaintext = copyBytes(plaintext)));\n const out = new Uint8Array(plaintext.length + tagLength);\n out.set(tag, plaintext.length);\n out.set(processSiv(encKey, tag, plaintext));\n // Cleanup\n clean(...toClean);\n return out;\n },\n decrypt(ciphertext: Uint8Array) {\n CIPHER_LIMIT(ciphertext.length);\n const tag = ciphertext.subarray(-tagLength);\n const { encKey, authKey } = deriveKeys();\n const toClean: (Uint8Array | Uint32Array)[] = [encKey, authKey];\n if (!isAligned32(ciphertext)) toClean.push((ciphertext = copyBytes(ciphertext)));\n const plaintext = processSiv(encKey, tag, ciphertext.subarray(0, -tagLength));\n const expectedTag = _computeTag(encKey, authKey, plaintext);\n toClean.push(expectedTag);\n if (!equalBytes(tag, expectedTag)) {\n clean(...toClean);\n throw new Error('invalid polyval tag');\n }\n // Cleanup\n clean(...toClean);\n return plaintext;\n },\n };\n }\n);\n\n/**\n * AES-GCM-SIV, not AES-SIV.\n * This is legace name, use `gcmsiv` export instead.\n * @deprecated\n */\nexport const siv: typeof gcmsiv = gcmsiv;\n\nfunction isBytes32(a: unknown): a is Uint32Array {\n return (\n a instanceof Uint32Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint32Array')\n );\n}\n\nfunction encryptBlock(xk: Uint32Array, block: Uint8Array): Uint8Array {\n abytes(block, 16);\n if (!isBytes32(xk)) throw new Error('_encryptBlock accepts result of expandKeyLE');\n const b32 = u32(block);\n let { s0, s1, s2, s3 } = encrypt(xk, b32[0], b32[1], b32[2], b32[3]);\n (b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3);\n return block;\n}\n\nfunction decryptBlock(xk: Uint32Array, block: Uint8Array): Uint8Array {\n abytes(block, 16);\n if (!isBytes32(xk)) throw new Error('_decryptBlock accepts result of expandKeyLE');\n const b32 = u32(block);\n let { s0, s1, s2, s3 } = decrypt(xk, b32[0], b32[1], b32[2], b32[3]);\n (b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3);\n return block;\n}\n\n/**\n * AES-W (base for AESKW/AESKWP).\n * Specs: [SP800-38F](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf),\n * [RFC 3394](https://datatracker.ietf.org/doc/rfc3394/),\n * [RFC 5649](https://datatracker.ietf.org/doc/rfc5649/).\n */\nconst AESW = {\n /*\n High-level pseudocode:\n ```\n A: u64 = IV\n out = []\n for (let i=0, ctr = 0; i<6; i++) {\n for (const chunk of chunks(plaintext, 8)) {\n A ^= swapEndianess(ctr++)\n [A, res] = chunks(encrypt(A || chunk), 8);\n out ||= res\n }\n }\n out = A || out\n ```\n Decrypt is the same, but reversed.\n */\n encrypt(kek: Uint8Array, out: Uint8Array) {\n // Size is limited to 4GB, otherwise ctr will overflow and we'll need to switch to bigints.\n // If you need it larger, open an issue.\n if (out.length >= 2 ** 32) throw new Error('plaintext should be less than 4gb');\n const xk = expandKeyLE(kek);\n if (out.length === 16) encryptBlock(xk, out);\n else {\n const o32 = u32(out);\n // prettier-ignore\n let a0 = o32[0], a1 = o32[1]; // A\n for (let j = 0, ctr = 1; j < 6; j++) {\n for (let pos = 2; pos < o32.length; pos += 2, ctr++) {\n const { s0, s1, s2, s3 } = encrypt(xk, a0, a1, o32[pos], o32[pos + 1]);\n // A = MSB(64, B) ^ t where t = (n*j)+i\n (a0 = s0), (a1 = s1 ^ byteSwap(ctr)), (o32[pos] = s2), (o32[pos + 1] = s3);\n }\n }\n (o32[0] = a0), (o32[1] = a1); // out = A || out\n }\n xk.fill(0);\n },\n decrypt(kek: Uint8Array, out: Uint8Array) {\n if (out.length - 8 >= 2 ** 32) throw new Error('ciphertext should be less than 4gb');\n const xk = expandKeyDecLE(kek);\n const chunks = out.length / 8 - 1; // first chunk is IV\n if (chunks === 1) decryptBlock(xk, out);\n else {\n const o32 = u32(out);\n // prettier-ignore\n let a0 = o32[0], a1 = o32[1]; // A\n for (let j = 0, ctr = chunks * 6; j < 6; j++) {\n for (let pos = chunks * 2; pos >= 1; pos -= 2, ctr--) {\n a1 ^= byteSwap(ctr);\n const { s0, s1, s2, s3 } = decrypt(xk, a0, a1, o32[pos], o32[pos + 1]);\n (a0 = s0), (a1 = s1), (o32[pos] = s2), (o32[pos + 1] = s3);\n }\n }\n (o32[0] = a0), (o32[1] = a1);\n }\n xk.fill(0);\n },\n};\n\nconst AESKW_IV = /* @__PURE__ */ new Uint8Array(8).fill(0xa6); // A6A6A6A6A6A6A6A6\n\n/**\n * AES-KW (key-wrap). Injects static IV into plaintext, adds counter, encrypts 6 times.\n * Reduces block size from 16 to 8 bytes.\n * For padded version, use aeskwp.\n * [RFC 3394](https://datatracker.ietf.org/doc/rfc3394/),\n * [NIST.SP.800-38F](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf).\n */\nexport const aeskw: ((kek: Uint8Array) => Cipher) & {\n blockSize: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 8 },\n (kek: Uint8Array): Cipher => ({\n encrypt(plaintext: Uint8Array) {\n if (!plaintext.length || plaintext.length % 8 !== 0)\n throw new Error('invalid plaintext length');\n if (plaintext.length === 8)\n throw new Error('8-byte keys not allowed in AESKW, use AESKWP instead');\n const out = concatBytes(AESKW_IV, plaintext);\n AESW.encrypt(kek, out);\n return out;\n },\n decrypt(ciphertext: Uint8Array) {\n // ciphertext must be at least 24 bytes and a multiple of 8 bytes\n // 24 because should have at least two block (1 iv + 2).\n // Replace with 16 to enable '8-byte keys'\n if (ciphertext.length % 8 !== 0 || ciphertext.length < 3 * 8)\n throw new Error('invalid ciphertext length');\n const out = copyBytes(ciphertext);\n AESW.decrypt(kek, out);\n if (!equalBytes(out.subarray(0, 8), AESKW_IV)) throw new Error('integrity check failed');\n out.subarray(0, 8).fill(0); // ciphertext.subarray(0, 8) === IV, but we clean it anyway\n return out.subarray(8);\n },\n })\n);\n\n/*\nWe don't support 8-byte keys. The rabbit hole:\n\n- Wycheproof says: \"NIST SP 800-38F does not define the wrapping of 8 byte keys.\n RFC 3394 Section 2 on the other hand specifies that 8 byte keys are wrapped\n by directly encrypting one block with AES.\"\n - https://github.com/C2SP/wycheproof/blob/master/doc/key_wrap.md\n - \"RFC 3394 specifies in Section 2, that the input for the key wrap\n algorithm must be at least two blocks and otherwise the constant\n field and key are simply encrypted with ECB as a single block\"\n- What RFC 3394 actually says (in Section 2):\n - \"Before being wrapped, the key data is parsed into n blocks of 64 bits.\n The only restriction the key wrap algorithm places on n is that n be\n at least two\"\n - \"For key data with length less than or equal to 64 bits, the constant\n field used in this specification and the key data form a single\n 128-bit codebook input making this key wrap unnecessary.\"\n- Which means \"assert(n >= 2)\" and \"use something else for 8 byte keys\"\n- NIST SP800-38F actually prohibits 8-byte in \"5.3.1 Mandatory Limits\".\n It states that plaintext for KW should be \"2 to 2^54 -1 semiblocks\".\n- So, where does \"directly encrypt single block with AES\" come from?\n - Not RFC 3394. Pseudocode of key wrap in 2.2 explicitly uses\n loop of 6 for any code path\n - There is a weird W3C spec:\n https://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#kw-aes128\n - This spec is outdated, as admitted by Wycheproof authors\n - There is RFC 5649 for padded key wrap, which is padding construction on\n top of AESKW. In '4.1.2' it says: \"If the padded plaintext contains exactly\n eight octets, then prepend the AIV as defined in Section 3 above to P[1] and\n encrypt the resulting 128-bit block using AES in ECB mode [Modes] with key\n K (the KEK). In this case, the output is two 64-bit blocks C[0] and C[1]:\"\n - Browser subtle crypto is actually crashes on wrapping keys less than 16 bytes:\n `Error: error:1C8000E6:Provider routines::invalid input length] { opensslErrorStack: [ 'error:030000BD:digital envelope routines::update error' ]`\n\nIn the end, seems like a bug in Wycheproof.\nThe 8-byte check can be easily disabled inside of AES_W.\n*/\n\nconst AESKWP_IV = 0xa65959a6; // single u32le value\n\n/**\n * AES-KW, but with padding and allows random keys.\n * Second u32 of IV is used as counter for length.\n * [RFC 5649](https://www.rfc-editor.org/rfc/rfc5649)\n */\nexport const aeskwp: ((kek: Uint8Array) => Cipher) & {\n blockSize: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 8 },\n (kek: Uint8Array): Cipher => ({\n encrypt(plaintext: Uint8Array) {\n if (!plaintext.length) throw new Error('invalid plaintext length');\n const padded = Math.ceil(plaintext.length / 8) * 8;\n const out = new Uint8Array(8 + padded);\n out.set(plaintext, 8);\n const out32 = u32(out);\n out32[0] = AESKWP_IV;\n out32[1] = byteSwap(plaintext.length);\n AESW.encrypt(kek, out);\n return out;\n },\n decrypt(ciphertext: Uint8Array) {\n // 16 because should have at least one block\n if (ciphertext.length < 16) throw new Error('invalid ciphertext length');\n const out = copyBytes(ciphertext);\n const o32 = u32(out);\n AESW.decrypt(kek, out);\n const len = byteSwap(o32[1]) >>> 0;\n const padded = Math.ceil(len / 8) * 8;\n if (o32[0] !== AESKWP_IV || out.length - 8 !== padded)\n throw new Error('integrity check failed');\n for (let i = len; i < padded; i++)\n if (out[8 + i] !== 0) throw new Error('integrity check failed');\n out.subarray(0, 8).fill(0); // ciphertext.subarray(0, 8) === IV, but we clean it anyway\n return out.subarray(8, 8 + len);\n },\n })\n);\n\n/** Unsafe low-level internal methods. May change at any time. */\nexport const unsafe: {\n expandKeyLE: typeof expandKeyLE;\n expandKeyDecLE: typeof expandKeyDecLE;\n encrypt: typeof encrypt;\n decrypt: typeof decrypt;\n encryptBlock: typeof encryptBlock;\n decryptBlock: typeof decryptBlock;\n ctrCounter: typeof ctrCounter;\n ctr32: typeof ctr32;\n} = {\n expandKeyLE,\n expandKeyDecLE,\n encrypt,\n decrypt,\n encryptBlock,\n decryptBlock,\n ctrCounter,\n ctr32,\n};\n","/**\n * RFC 7914 Scrypt KDF. Can be used to create a key from password and salt.\n * @module\n */\nimport { pbkdf2 } from './pbkdf2.ts';\nimport { sha256 } from './sha2.ts';\n// prettier-ignore\nimport {\n anumber, asyncLoop,\n checkOpts, clean,\n type KDFInput, rotl,\n swap32IfBE,\n u32\n} from './utils.ts';\n\n// The main Scrypt loop: uses Salsa extensively.\n// Six versions of the function were tried, this is the fastest one.\n// prettier-ignore\nfunction XorAndSalsa(\n prev: Uint32Array,\n pi: number,\n input: Uint32Array,\n ii: number,\n out: Uint32Array,\n oi: number\n) {\n // Based on https://cr.yp.to/salsa20.html\n // Xor blocks\n let y00 = prev[pi++] ^ input[ii++], y01 = prev[pi++] ^ input[ii++];\n let y02 = prev[pi++] ^ input[ii++], y03 = prev[pi++] ^ input[ii++];\n let y04 = prev[pi++] ^ input[ii++], y05 = prev[pi++] ^ input[ii++];\n let y06 = prev[pi++] ^ input[ii++], y07 = prev[pi++] ^ input[ii++];\n let y08 = prev[pi++] ^ input[ii++], y09 = prev[pi++] ^ input[ii++];\n let y10 = prev[pi++] ^ input[ii++], y11 = prev[pi++] ^ input[ii++];\n let y12 = prev[pi++] ^ input[ii++], y13 = prev[pi++] ^ input[ii++];\n let y14 = prev[pi++] ^ input[ii++], y15 = prev[pi++] ^ input[ii++];\n // Save state to temporary variables (salsa)\n let x00 = y00, x01 = y01, x02 = y02, x03 = y03,\n x04 = y04, x05 = y05, x06 = y06, x07 = y07,\n x08 = y08, x09 = y09, x10 = y10, x11 = y11,\n x12 = y12, x13 = y13, x14 = y14, x15 = y15;\n // Main loop (salsa)\n for (let i = 0; i < 8; i += 2) {\n x04 ^= rotl(x00 + x12 | 0, 7); x08 ^= rotl(x04 + x00 | 0, 9);\n x12 ^= rotl(x08 + x04 | 0, 13); x00 ^= rotl(x12 + x08 | 0, 18);\n x09 ^= rotl(x05 + x01 | 0, 7); x13 ^= rotl(x09 + x05 | 0, 9);\n x01 ^= rotl(x13 + x09 | 0, 13); x05 ^= rotl(x01 + x13 | 0, 18);\n x14 ^= rotl(x10 + x06 | 0, 7); x02 ^= rotl(x14 + x10 | 0, 9);\n x06 ^= rotl(x02 + x14 | 0, 13); x10 ^= rotl(x06 + x02 | 0, 18);\n x03 ^= rotl(x15 + x11 | 0, 7); x07 ^= rotl(x03 + x15 | 0, 9);\n x11 ^= rotl(x07 + x03 | 0, 13); x15 ^= rotl(x11 + x07 | 0, 18);\n x01 ^= rotl(x00 + x03 | 0, 7); x02 ^= rotl(x01 + x00 | 0, 9);\n x03 ^= rotl(x02 + x01 | 0, 13); x00 ^= rotl(x03 + x02 | 0, 18);\n x06 ^= rotl(x05 + x04 | 0, 7); x07 ^= rotl(x06 + x05 | 0, 9);\n x04 ^= rotl(x07 + x06 | 0, 13); x05 ^= rotl(x04 + x07 | 0, 18);\n x11 ^= rotl(x10 + x09 | 0, 7); x08 ^= rotl(x11 + x10 | 0, 9);\n x09 ^= rotl(x08 + x11 | 0, 13); x10 ^= rotl(x09 + x08 | 0, 18);\n x12 ^= rotl(x15 + x14 | 0, 7); x13 ^= rotl(x12 + x15 | 0, 9);\n x14 ^= rotl(x13 + x12 | 0, 13); x15 ^= rotl(x14 + x13 | 0, 18);\n }\n // Write output (salsa)\n out[oi++] = (y00 + x00) | 0; out[oi++] = (y01 + x01) | 0;\n out[oi++] = (y02 + x02) | 0; out[oi++] = (y03 + x03) | 0;\n out[oi++] = (y04 + x04) | 0; out[oi++] = (y05 + x05) | 0;\n out[oi++] = (y06 + x06) | 0; out[oi++] = (y07 + x07) | 0;\n out[oi++] = (y08 + x08) | 0; out[oi++] = (y09 + x09) | 0;\n out[oi++] = (y10 + x10) | 0; out[oi++] = (y11 + x11) | 0;\n out[oi++] = (y12 + x12) | 0; out[oi++] = (y13 + x13) | 0;\n out[oi++] = (y14 + x14) | 0; out[oi++] = (y15 + x15) | 0;\n}\n\nfunction BlockMix(input: Uint32Array, ii: number, out: Uint32Array, oi: number, r: number) {\n // The block B is r 128-byte chunks (which is equivalent of 2r 64-byte chunks)\n let head = oi + 0;\n let tail = oi + 16 * r;\n for (let i = 0; i < 16; i++) out[tail + i] = input[ii + (2 * r - 1) * 16 + i]; // X ← B[2r−1]\n for (let i = 0; i < r; i++, head += 16, ii += 16) {\n // We write odd & even Yi at same time. Even: 0bXXXXX0 Odd: 0bXXXXX1\n XorAndSalsa(out, tail, input, ii, out, head); // head[i] = Salsa(blockIn[2*i] ^ tail[i-1])\n if (i > 0) tail += 16; // First iteration overwrites tmp value in tail\n XorAndSalsa(out, head, input, (ii += 16), out, tail); // tail[i] = Salsa(blockIn[2*i+1] ^ head[i])\n }\n}\n\nexport type ScryptOpts = {\n N: number; // cost factor\n r: number; // block size\n p: number; // parallelization\n dkLen?: number; // key length\n asyncTick?: number; // block execution max time\n maxmem?: number;\n onProgress?: (progress: number) => void;\n};\n\n// Common prologue and epilogue for sync/async functions\nfunction scryptInit(password: KDFInput, salt: KDFInput, _opts?: ScryptOpts) {\n // Maxmem - 1GB+1KB by default\n const opts = checkOpts(\n {\n dkLen: 32,\n asyncTick: 10,\n maxmem: 1024 ** 3 + 1024,\n },\n _opts\n );\n const { N, r, p, dkLen, asyncTick, maxmem, onProgress } = opts;\n anumber(N);\n anumber(r);\n anumber(p);\n anumber(dkLen);\n anumber(asyncTick);\n anumber(maxmem);\n if (onProgress !== undefined && typeof onProgress !== 'function')\n throw new Error('progressCb should be function');\n const blockSize = 128 * r;\n const blockSize32 = blockSize / 4;\n\n // Max N is 2^32 (Integrify is 32-bit). Real limit is 2^22: JS engines Uint8Array limit is 4GB in 2024.\n // Spec check `N >= 2^(blockSize / 8)` is not done for compat with popular libs,\n // which used incorrect r: 1, p: 8. Also, the check seems to be a spec error:\n // https://www.rfc-editor.org/errata_search.php?rfc=7914\n const pow32 = Math.pow(2, 32);\n if (N <= 1 || (N & (N - 1)) !== 0 || N > pow32) {\n throw new Error('Scrypt: N must be larger than 1, a power of 2, and less than 2^32');\n }\n if (p < 0 || p > ((pow32 - 1) * 32) / blockSize) {\n throw new Error(\n 'Scrypt: p must be a positive integer less than or equal to ((2^32 - 1) * 32) / (128 * r)'\n );\n }\n if (dkLen < 0 || dkLen > (pow32 - 1) * 32) {\n throw new Error(\n 'Scrypt: dkLen should be positive integer less than or equal to (2^32 - 1) * 32'\n );\n }\n const memUsed = blockSize * (N + p);\n if (memUsed > maxmem) {\n throw new Error(\n 'Scrypt: memused is bigger than maxMem. Expected 128 * r * (N + p) > maxmem of ' + maxmem\n );\n }\n // [B0...Bp−1] ← PBKDF2HMAC-SHA256(Passphrase, Salt, 1, blockSize*ParallelizationFactor)\n // Since it has only one iteration there is no reason to use async variant\n const B = pbkdf2(sha256, password, salt, { c: 1, dkLen: blockSize * p });\n const B32 = u32(B);\n // Re-used between parallel iterations. Array(iterations) of B\n const V = u32(new Uint8Array(blockSize * N));\n const tmp = u32(new Uint8Array(blockSize));\n let blockMixCb = () => {};\n if (onProgress) {\n const totalBlockMix = 2 * N * p;\n // Invoke callback if progress changes from 10.01 to 10.02\n // Allows to draw smooth progress bar on up to 8K screen\n const callbackPer = Math.max(Math.floor(totalBlockMix / 10000), 1);\n let blockMixCnt = 0;\n blockMixCb = () => {\n blockMixCnt++;\n if (onProgress && (!(blockMixCnt % callbackPer) || blockMixCnt === totalBlockMix))\n onProgress(blockMixCnt / totalBlockMix);\n };\n }\n return { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick };\n}\n\nfunction scryptOutput(\n password: KDFInput,\n dkLen: number,\n B: Uint8Array,\n V: Uint32Array,\n tmp: Uint32Array\n) {\n const res = pbkdf2(sha256, password, B, { c: 1, dkLen });\n clean(B, V, tmp);\n return res;\n}\n\n/**\n * Scrypt KDF from RFC 7914.\n * @param password - pass\n * @param salt - salt\n * @param opts - parameters\n * - `N` is cpu/mem work factor (power of 2 e.g. 2**18)\n * - `r` is block size (8 is common), fine-tunes sequential memory read size and performance\n * - `p` is parallelization factor (1 is common)\n * - `dkLen` is output key length in bytes e.g. 32.\n * - `asyncTick` - (default: 10) max time in ms for which async function can block execution\n * - `maxmem` - (default: `1024 ** 3 + 1024` aka 1GB+1KB). A limit that the app could use for scrypt\n * - `onProgress` - callback function that would be executed for progress report\n * @returns Derived key\n * @example\n * scrypt('password', 'salt', { N: 2**18, r: 8, p: 1, dkLen: 32 });\n */\nexport function scrypt(password: KDFInput, salt: KDFInput, opts: ScryptOpts): Uint8Array {\n const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb } = scryptInit(\n password,\n salt,\n opts\n );\n swap32IfBE(B32);\n for (let pi = 0; pi < p; pi++) {\n const Pi = blockSize32 * pi;\n for (let i = 0; i < blockSize32; i++) V[i] = B32[Pi + i]; // V[0] = B[i]\n for (let i = 0, pos = 0; i < N - 1; i++) {\n BlockMix(V, pos, V, (pos += blockSize32), r); // V[i] = BlockMix(V[i-1]);\n blockMixCb();\n }\n BlockMix(V, (N - 1) * blockSize32, B32, Pi, r); // Process last element\n blockMixCb();\n for (let i = 0; i < N; i++) {\n // First u32 of the last 64-byte block (u32 is LE)\n const j = B32[Pi + blockSize32 - 16] % N; // j = Integrify(X) % iterations\n for (let k = 0; k < blockSize32; k++) tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k]; // tmp = B ^ V[j]\n BlockMix(tmp, 0, B32, Pi, r); // B = BlockMix(B ^ V[j])\n blockMixCb();\n }\n }\n swap32IfBE(B32);\n return scryptOutput(password, dkLen, B, V, tmp);\n}\n\n/**\n * Scrypt KDF from RFC 7914. Async version.\n * @example\n * await scryptAsync('password', 'salt', { N: 2**18, r: 8, p: 1, dkLen: 32 });\n */\nexport async function scryptAsync(\n password: KDFInput,\n salt: KDFInput,\n opts: ScryptOpts\n): Promise<Uint8Array> {\n const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick } = scryptInit(\n password,\n salt,\n opts\n );\n swap32IfBE(B32);\n for (let pi = 0; pi < p; pi++) {\n const Pi = blockSize32 * pi;\n for (let i = 0; i < blockSize32; i++) V[i] = B32[Pi + i]; // V[0] = B[i]\n let pos = 0;\n await asyncLoop(N - 1, asyncTick, () => {\n BlockMix(V, pos, V, (pos += blockSize32), r); // V[i] = BlockMix(V[i-1]);\n blockMixCb();\n });\n BlockMix(V, (N - 1) * blockSize32, B32, Pi, r); // Process last element\n blockMixCb();\n await asyncLoop(N, asyncTick, () => {\n // First u32 of the last 64-byte block (u32 is LE)\n const j = B32[Pi + blockSize32 - 16] % N; // j = Integrify(X) % iterations\n for (let k = 0; k < blockSize32; k++) tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k]; // tmp = B ^ V[j]\n BlockMix(tmp, 0, B32, Pi, r); // B = BlockMix(B ^ V[j])\n blockMixCb();\n });\n }\n swap32IfBE(B32);\n return scryptOutput(password, dkLen, B, V, tmp);\n}\n","import { ctr } from '@noble/ciphers/aes'\nimport {\n pbkdf2 as pbkdf2_noble,\n pbkdf2Async as pbkdf2Async_noble,\n} from '@noble/hashes/pbkdf2'\nimport {\n scrypt as scrypt_noble,\n scryptAsync as scryptAsync_noble,\n} from '@noble/hashes/scrypt'\nimport { sha256 } from '@noble/hashes/sha2'\nimport * as Bytes from './Bytes.js'\nimport type * as Errors from './Errors.js'\nimport * as Hash from './Hash.js'\nimport type * as Hex from './Hex.js'\nimport type { OneOf } from './internal/types.js'\n\n/** Base Derivation Options. */\ntype BaseDeriveOpts<\n kdf extends string = string,\n kdfparams extends Record<string, unknown> = Record<string, unknown>,\n> = {\n iv: Bytes.Bytes\n kdfparams: kdfparams\n kdf: kdf\n}\n\n/** Keystore. */\nexport type Keystore = {\n crypto: {\n cipher: 'aes-128-ctr'\n ciphertext: string\n cipherparams: {\n iv: string\n }\n mac: string\n } & Pick<DeriveOpts, 'kdf' | 'kdfparams'>\n id: string\n version: 3\n}\n\n/** Key. */\nexport type Key = (() => Hex.Hex) | Hex.Hex\n\n/** Derivation Options. */\nexport type DeriveOpts = Pbkdf2DeriveOpts | ScryptDeriveOpts\n\n/** PBKDF2 Derivation Options. */\nexport type Pbkdf2DeriveOpts = BaseDeriveOpts<\n 'pbkdf2',\n {\n c: number\n dklen: number\n prf: 'hmac-sha256'\n salt: string\n }\n>\n\n/** Scrypt Derivation Options. */\nexport type ScryptDeriveOpts = BaseDeriveOpts<\n 'scrypt',\n {\n dklen: number\n n: number\n p: number\n r: number\n salt: string\n }\n>\n\n/**\n * Decrypts a [JSON keystore](https://ethereum.org/en/developers/docs/data-structures-and-encoding/web3-secret-storage/)\n * into a private key.\n *\n * Supports the following key derivation functions (KDFs):\n * - {@link ox#Keystore.(pbkdf2:function)}\n * - {@link ox#Keystore.(scrypt:function)}\n *\n * @example\n * ```ts twoslash\n * // @noErrors\n * import { Keystore, Secp256k1 } from 'ox'\n *\n * // JSON keystore.\n * const keystore = { crypto: { ... }, id: '...', version: 3 }\n *\n * // Derive the key using your password.\n * const key = Keystore.toKey(keystore, { password: 'hunter2' })\n *\n * // Decrypt the private key.\n * const privateKey = Keystore.decrypt(keystore, key)\n * // @log: \"0x...\"\n * ```\n *\n * @param keystore - JSON keystore.\n * @param key - Key to use for decryption.\n * @param options - Decryption options.\n * @returns Decrypted private key.\n */\nexport function decrypt<as extends 'Hex' | 'Bytes' = 'Hex'>(\n keystore: Keystore,\n key: Key,\n options: decrypt.Options<as> = {},\n): decrypt.ReturnType<as> {\n const { as = 'Hex' } = options\n const key_ = Bytes.from(typeof key === 'function' ? key() : key)\n\n const encKey = Bytes.slice(key_, 0, 16)\n const macKey = Bytes.slice(key_, 16, 32)\n\n const ciphertext = Bytes.from(`0x${keystore.crypto.ciphertext}`)\n const mac = Hash.keccak256(Bytes.concat(macKey, ciphertext))\n\n if (!Bytes.isEqual(mac, Bytes.from(`0x${keystore.crypto.mac}`)))\n throw new Error('corrupt keystore')\n\n const data = ctr(\n encKey,\n Bytes.from(`0x${keystore.crypto.cipherparams.iv}`),\n ).decrypt(ciphertext)\n\n if (as === 'Hex') return Bytes.toHex(data) as never\n return data as never\n}\n\nexport declare namespace decrypt {\n type Options<as extends 'Hex' | 'Bytes' = 'Hex' | 'Bytes'> = {\n /** Output format. @default 'Hex' */\n as?: as | 'Hex' | 'Bytes' | undefined\n }\n\n type ReturnType<as extends 'Hex' | 'Bytes' = 'Hex' | 'Bytes'> =\n | (as extends 'Hex' ? Hex.Hex : never)\n | (as extends 'Bytes' ? Bytes.Bytes : never)\n}\n\n/**\n * Encrypts a private key as a [JSON keystore](https://ethereum.org/en/developers/docs/data-structures-and-encoding/web3-secret-storage/)\n * using a derived key.\n *\n * Supports the following key derivation functions (KDFs):\n * - {@link ox#Keystore.(pbkdf2:function)}\n * - {@link ox#Keystore.(scrypt:function)}\n *\n * @example\n * ```ts twoslash\n * import { Keystore, Secp256k1 } from 'ox'\n *\n * // Generate a random private key.\n * const privateKey = Secp256k1.randomPrivateKey()\n *\n * // Derive key from password.\n * const [key, opts] = Keystore.pbkdf2({ password: 'testpassword' })\n *\n * // Encrypt the private key.\n * const encrypted = Keystore.encrypt(privateKey, key, opts)\n * // @log: {\n * // @log: \"crypto\": {\n * // @log: \"cipher\": \"aes-128-ctr\",\n * // @log: \"ciphertext\": \"...\",\n * // @log: \"cipherparams\": {\n * // @log: \"iv\": \"...\",\n * // @log: },\n * // @log: \"kdf\": \"pbkdf2\",\n * // @log: \"kdfparams\": {\n * // @log: \"salt\": \"...\",\n * // @log: \"dklen\": 32,\n * // @log: \"prf\": \"hmac-sha256\",\n * // @log: \"c\": 262144,\n * // @log: },\n * // @log: \"mac\": \"...\",\n * // @log: },\n * // @log: \"id\": \"...\",\n * // @log: \"version\": 3,\n * // @log: }\n * ```\n *\n * @param privateKey - Private key to encrypt.\n * @param key - Key to use for encryption.\n * @param options - Encryption options.\n * @returns Encrypted keystore.\n */\nexport function encrypt(\n privateKey: Bytes.Bytes | Hex.Hex,\n key: Key,\n options: encrypt.Options,\n): Keystore {\n const { id = crypto.randomUUID(), kdf, kdfparams, iv } = options\n\n const key_ = Bytes.from(typeof key === 'function' ? key() : key)\n const value_ = Bytes.from(privateKey)\n\n const encKey = Bytes.slice(key_, 0, 16)\n const macKey = Bytes.slice(key_, 16, 32)\n\n const ciphertext = ctr(encKey, iv).encrypt(value_)\n const mac = Hash.keccak256(Bytes.concat(macKey, ciphertext))\n\n return {\n crypto: {\n cipher: 'aes-128-ctr',\n ciphertext: Bytes.toHex(ciphertext).slice(2),\n cipherparams: { iv: Bytes.toHex(iv).slice(2) },\n kdf,\n kdfparams,\n mac: Bytes.toHex(mac).slice(2),\n } as Keystore['crypto'],\n id,\n version: 3,\n }\n}\n\nexport declare namespace encrypt {\n type Options = DeriveOpts & {\n /** UUID. */\n id?: string | undefined\n }\n}\n\n/**\n * Derives a key from a password using [PBKDF2](https://en.wikipedia.org/wiki/PBKDF2).\n *\n * @example\n * ```ts twoslash\n * import { Keystore } from 'ox'\n *\n * const [key, opts] = Keystore.pbkdf2({ password: 'testpassword' })\n * ```\n *\n * @param options - PBKDF2 options.\n * @returns PBKDF2 key.\n */\nexport function pbkdf2(options: pbkdf2.Options) {\n const { iv, iterations = 262_144, password } = options\n\n const salt = options.salt ? Bytes.from(options.salt) : Bytes.random(32)\n const key = Bytes.toHex(\n pbkdf2_noble(sha256, password, salt, { c: iterations, dkLen: 32 }),\n )\n\n return defineKey(() => key, {\n iv,\n kdfparams: {\n c: iterations,\n dklen: 32,\n prf: 'hmac-sha256',\n salt: Bytes.toHex(salt).slice(2),\n },\n kdf: 'pbkdf2',\n }) satisfies [Key, Pbkdf2DeriveOpts]\n}\n\nexport declare namespace pbkdf2 {\n type Options = {\n /** The counter to use for the AES-CTR encryption. */\n iv?: Bytes.Bytes | Hex.Hex | undefined\n /** The number of iterations to use. @default 262_144 */\n iterations?: number | undefined\n /** Password to derive key from. */\n password: string\n /** Salt to use for key derivation. @default `Bytes.random(32)` */\n salt?: Bytes.Bytes | Hex.Hex | undefined\n }\n}\n\n/**\n * Derives a key from a password using [PBKDF2](https://en.wikipedia.org/wiki/PBKDF2).\n *\n * @example\n * ```ts twoslash\n * import { Keystore } from 'ox'\n *\n * const [key, opts] = await Keystore.pbkdf2Async({ password: 'testpassword' })\n * ```\n *\n * @param options - PBKDF2 options.\n * @returns PBKDF2 key.\n */\nexport async function pbkdf2Async(options: pbkdf2.Options) {\n const { iv, iterations = 262_144, password } = options\n\n const salt = options.salt ? Bytes.from(options.salt) : Bytes.random(32)\n const key = Bytes.toHex(\n await pbkdf2Async_noble(sha256, password, salt, {\n c: iterations,\n dkLen: 32,\n }),\n )\n\n return defineKey(() => key, {\n iv,\n kdfparams: {\n c: iterations,\n dklen: 32,\n prf: 'hmac-sha256',\n salt: Bytes.toHex(salt).slice(2),\n },\n kdf: 'pbkdf2',\n }) satisfies [Key, Pbkdf2DeriveOpts]\n}\n\nexport declare namespace pbkdf2Async {\n type Options = pbkdf2.Options\n}\n\n/**\n * Derives a key from a password using [scrypt](https://en.wikipedia.org/wiki/Scrypt).\n *\n * @example\n * ```ts twoslash\n * import { Keystore } from 'ox'\n *\n * const [key, opts] = Keystore.scrypt({ password: 'testpassword' })\n * ```\n *\n * @param options - Scrypt options.\n * @returns Scrypt key.\n */\nexport function scrypt(options: scrypt.Options) {\n const { iv, n = 262_144, password, p = 8, r = 1 } = options\n\n const salt = options.salt ? Bytes.from(options.salt) : Bytes.random(32)\n const key = Bytes.toHex(\n scrypt_noble(password, salt, { N: n, dkLen: 32, r, p }),\n )\n\n return defineKey(() => key, {\n iv,\n kdfparams: {\n dklen: 32,\n n,\n p,\n r,\n salt: Bytes.toHex(salt).slice(2),\n },\n kdf: 'scrypt',\n }) satisfies [Key, ScryptDeriveOpts]\n}\n\nexport declare namespace scrypt {\n type Options = {\n /** The counter to use for the AES-CTR encryption. */\n iv?: Bytes.Bytes | Hex.Hex | undefined\n /** Cost factor. @default 262_144 */\n n?: number | undefined\n /** Parallelization factor. @default 8 */\n p?: number | undefined\n /** Block size. @default 1 */\n r?: number | undefined\n /** Password to derive key from. */\n password: string\n /** Salt to use for key derivation. @default `Bytes.random(32)` */\n salt?: Bytes.Bytes | Hex.Hex | undefined\n }\n}\n\n/**\n * Derives a key from a password using [scrypt](https://en.wikipedia.org/wiki/Scrypt).\n *\n * @example\n * ```ts twoslash\n * import { Keystore } from 'ox'\n *\n * const [key, opts] = await Keystore.scryptAsync({ password: 'testpassword' })\n * ```\n *\n * @param options - Scrypt options.\n * @returns Scrypt key.\n */\nexport async function scryptAsync(options: scrypt.Options) {\n const { iv, n = 262_144, password } = options\n\n const p = 8\n const r = 1\n\n const salt = options.salt ? Bytes.from(options.salt) : Bytes.random(32)\n const key = Bytes.toHex(\n await scryptAsync_noble(password, salt, { N: n, dkLen: 32, r, p }),\n )\n\n return defineKey(() => key, {\n iv,\n kdfparams: {\n dklen: 32,\n n,\n p,\n r,\n salt: Bytes.toHex(salt).slice(2),\n },\n kdf: 'scrypt',\n }) satisfies [Key, ScryptDeriveOpts]\n}\n\nexport declare namespace scryptAsync {\n type Options = scrypt.Options\n}\n\n/**\n * Extracts a Key from a JSON Keystore to use for decryption.\n *\n * @example\n * ```ts twoslash\n * // @noErrors\n * import { Keystore } from 'ox'\n *\n * // JSON keystore.\n * const keystore = { crypto: { ... }, id: '...', version: 3 }\n *\n * const key = Keystore.toKey(keystore, { password: 'hunter2' }) // [!code focus]\n *\n * const decrypted = Keystore.decrypt(keystore, key)\n * ```\n *\n * @param keystore - JSON Keystore\n * @param options - Options\n * @returns Key\n */\nexport function toKey(keystore: Keystore, options: toKey.Options): Key {\n const { crypto } = keystore\n const { password } = options\n const { cipherparams, kdf, kdfparams } = crypto\n const { iv } = cipherparams\n const { c, n, p, r, salt } = kdfparams as OneOf<\n Pbkdf2DeriveOpts['kdfparams'] | ScryptDeriveOpts['kdfparams']\n >\n\n const [key] = (() => {\n switch (kdf) {\n case 'scrypt':\n return scrypt({\n iv: Bytes.from(`0x${iv}`),\n n,\n p,\n r,\n salt: Bytes.from(`0x${salt}`),\n password,\n })\n case 'pbkdf2':\n return pbkdf2({\n iv: Bytes.from(`0x${iv}`),\n iterations: c,\n password,\n salt: Bytes.from(`0x${salt}`),\n })\n default:\n throw new Error('unsupported kdf')\n }\n })()\n\n return key\n}\n\nexport declare namespace toKey {\n type Options = {\n /** Password to derive key from. */\n password: string\n }\n}\n\n/**\n * Extracts a Key asynchronously from a JSON Keystore to use for decryption.\n *\n * @example\n * ```ts twoslash\n * // @noErrors\n * import { Keystore } from 'ox'\n *\n * // JSON keystore.\n * const keystore = { crypto: { ... }, id: '...', version: 3 }\n *\n * const key = await Keystore.toKeyAsync(keystore, { password: 'hunter2' }) // [!code focus]\n *\n * const decrypted = Keystore.decrypt(keystore, key)\n * ```\n *\n * @param keystore - JSON Keystore\n * @param options - Options\n * @returns Key\n */\nexport async function toKeyAsync(\n keystore: Keystore,\n options: toKeyAsync.Options,\n): Promise<Key> {\n const { crypto } = keystore\n const { password } = options\n const { cipherparams, kdf, kdfparams } = crypto\n const { iv } = cipherparams\n const { c, n, p, r, salt } = kdfparams as OneOf<\n Pbkdf2DeriveOpts['kdfparams'] | ScryptDeriveOpts['kdfparams']\n >\n\n const [key] = await (async () => {\n switch (kdf) {\n case 'scrypt':\n return await scryptAsync({\n iv: Bytes.from(`0x${iv}`),\n n,\n p,\n r,\n salt: Bytes.from(`0x${salt}`),\n password,\n })\n case 'pbkdf2':\n return await pbkdf2({\n iv: Bytes.from(`0x${iv}`),\n iterations: c,\n password,\n salt: Bytes.from(`0x${salt}`),\n })\n default:\n throw new Error('unsupported kdf')\n }\n })()\n\n return key\n}\n\nexport declare namespace toKeyAsync {\n type Options = {\n /** Password to derive key from. */\n password: string\n }\n}\n\n///////////////////////////////////////////////////////////////////////////\n\n/** @internal */\n// biome-ignore lint/correctness/noUnusedVariables: _\nfunction defineKey<\n const key extends Key,\n const options extends defineKey.Options,\n>(key: key, options: options): [key, options & { iv: Bytes.Bytes }] {\n const iv = options.iv ? Bytes.from(options.iv) : Bytes.random(16)\n return [key, { ...options, iv }] as never\n}\n\n/** @internal */\ndeclare namespace defineKey {\n type Options<\n kdf extends string = string,\n kdfparams extends Record<string, unknown> = Record<string, unknown>,\n > = Omit<BaseDeriveOpts<kdf, kdfparams>, 'iv'> & {\n iv?: Bytes.Bytes | Hex.Hex | undefined\n }\n\n type ErrorType = Errors.GlobalErrorType\n}\n","import { execFile } from 'node:child_process';\nimport { randomBytes } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport { CliError } from '../errors';\nimport { writeFileAtomic } from '../atomic-json';\nimport { passphraseBlobPath } from '../paths';\n\n/**\n * Wallet passphrase resolution. The private key lives on disk as an encrypted\n * Keystore v3 document; the passphrase that unlocks it is resolved here, in a\n * fixed order, so signing works headlessly (env), transparently through the OS\n * store (macOS keychain, Windows DPAPI, desktop-Linux keyring), or interactively\n * (TTY). Every side-effecting seam — the store CLIs and the hidden-input prompt —\n * is injectable so tests never touch a real keychain or terminal.\n *\n * The passphrase never appears in any argv (which the OS process table can show):\n * reads come back on stdout, and writes pipe the secret over the child's stdin.\n * A store that cannot serve degrades to null/false so resolution falls through to\n * the next source rather than hard-failing, and no plaintext is ever written to\n * disk (the Windows blob is DPAPI-encrypted, not the passphrase itself).\n */\n\nconst KEYCHAIN_SERVICE = 'tenjin-cli';\nconst KEYCHAIN_ACCOUNT = 'wallet';\n\n/** base64url alphabet — exactly what `randomBytes(32).toString('base64url')` yields. */\nconst BASE64URL_RE = /^[A-Za-z0-9_-]+$/;\n\nexport type PassphraseSource = 'env' | 'keychain' | 'dpapi' | 'secret-service' | 'prompt';\n\nexport interface ResolvedPassphrase {\n passphrase: string;\n source: PassphraseSource;\n}\n\n/**\n * Runs a command with an argv array (execFile semantics — never shell-interpolated).\n * When `stdin` is provided it is written to the child's stdin and the stream is\n * closed; this is how the passphrase reaches `security -i`, PowerShell, and\n * `secret-tool` WITHOUT ever appearing in an argv the process table can expose.\n */\nexport type ExecFn = (\n file: string,\n args: string[],\n stdin?: string,\n) => Promise<{ stdout: string; stderr: string }>;\n\n/** Reads one line of hidden input, writing `label` to stderr (never stdout). */\nexport type PromptFn = (label: string) => Promise<string>;\n\nexport interface PassphraseDeps {\n env: NodeJS.ProcessEnv;\n /** Data dir that holds the Windows DPAPI blob; defaults to the resolved data dir. */\n dir?: string;\n /** Defaults to `process.platform`; selects the OS store (or none). */\n platform?: NodeJS.Platform;\n /** Whether an interactive prompt is possible; defaults to `process.stdin.isTTY`. */\n isTTY?: boolean;\n /** The store-CLI exec seam; defaults to a real execFile with stdin support. */\n exec?: ExecFn;\n /** The hidden-input prompt seam; defaults to a raw-mode TTY reader. */\n prompt?: PromptFn;\n}\n\n/**\n * A per-platform durable passphrase store. `read` returns the stored passphrase or\n * null (miss / unavailable); `store` persists one and reports whether it stuck.\n * Neither throws: a store that cannot serve degrades to null/false so resolution\n * falls through to the next source.\n */\ninterface PassphraseStore {\n /** The source label reported when this store serves the passphrase. */\n source: Exclude<PassphraseSource, 'env' | 'prompt'>;\n read(): Promise<string | null>;\n store(passphrase: string): Promise<boolean>;\n}\n\nconst defaultExec: ExecFn = (file, args, stdin) =>\n new Promise((resolve, reject) => {\n const child = execFile(file, args, { encoding: 'utf8' }, (err, stdout, stderr) => {\n if (err) reject(err);\n else resolve({ stdout, stderr });\n });\n if (stdin !== undefined) {\n // A child that exits before draining stdin closes the pipe; swallow the\n // resulting EPIPE so the exec callback surfaces the real exit error instead.\n child.stdin?.on('error', () => undefined);\n child.stdin?.end(stdin);\n }\n });\n\n/** The durable store for this platform, or null where no built-in one exists. */\nfunction storeFor(deps: PassphraseDeps): PassphraseStore | null {\n switch (deps.platform ?? process.platform) {\n case 'darwin':\n return keychainStore(deps);\n case 'win32':\n return dpapiStore(deps);\n case 'linux':\n return secretServiceStore(deps);\n default:\n return null;\n }\n}\n\n/**\n * Resolve the passphrase to DECRYPT an existing wallet: env, then the platform's\n * OS store, then an interactive prompt. When none is available the caller cannot\n * sign, so this fails USAGE rather than guessing.\n */\nexport async function resolvePassphrase(deps: PassphraseDeps): Promise<ResolvedPassphrase> {\n const fromEnv = envPassphrase(deps.env);\n if (fromEnv !== null) return { passphrase: fromEnv, source: 'env' };\n\n const store = storeFor(deps);\n if (store !== null) {\n const fromStore = await store.read();\n if (fromStore !== null) return { passphrase: fromStore, source: store.source };\n }\n\n if (canPrompt(deps)) {\n const entered = await promptOf(deps)('Wallet passphrase: ');\n if (entered.length === 0) throw noPassphraseError();\n return { passphrase: entered, source: 'prompt' };\n }\n\n throw noPassphraseError();\n}\n\n/**\n * Resolve the passphrase to ENCRYPT a new wallet: env if set; else a strong random\n * passphrase auto-stored in the platform's OS store (so signing later is\n * transparent); else an interactive prompt asked twice; else USAGE. The store\n * write happens BEFORE the caller encrypts, so a fresh random passphrase can never\n * be lost between generating it and persisting the encrypted key.\n */\nexport async function resolvePassphraseForCreate(\n deps: PassphraseDeps,\n): Promise<ResolvedPassphrase> {\n const fromEnv = envPassphrase(deps.env);\n if (fromEnv !== null) return { passphrase: fromEnv, source: 'env' };\n\n const store = storeFor(deps);\n if (store !== null) {\n const generated = randomBytes(32).toString('base64url');\n if (await store.store(generated)) {\n return { passphrase: generated, source: store.source };\n }\n // Store unavailable (locked, not installed, no access): fall to prompt / USAGE.\n }\n\n if (canPrompt(deps)) {\n const prompt = promptOf(deps);\n const first = await prompt('Set a wallet passphrase: ');\n if (first.length === 0) {\n throw new CliError('USAGE', 'The wallet passphrase must not be empty.', {\n fix: 'Enter a non-empty passphrase, or set TENJIN_WALLET_PASSPHRASE.',\n });\n }\n const second = await prompt('Confirm passphrase: ');\n if (first !== second) {\n throw new CliError('USAGE', 'The passphrases did not match.', {\n fix: 'Run `tenjin wallet create` again and enter the same passphrase both times.',\n });\n }\n return { passphrase: first, source: 'prompt' };\n }\n\n throw noPassphraseError();\n}\n\n/**\n * macOS login keychain via the OS `security` tool — the same mechanism the GitHub\n * CLI uses. Reads use `-w`, so the secret comes back on stdout, never in argv.\n * Writes pipe an `add-generic-password` command to `security -i` over stdin so the\n * passphrase never appears in any argv either.\n */\nfunction keychainStore(deps: PassphraseDeps): PassphraseStore {\n const exec = deps.exec ?? defaultExec;\n return {\n source: 'keychain',\n async read() {\n try {\n const { stdout } = await exec('security', [\n 'find-generic-password',\n '-s',\n KEYCHAIN_SERVICE,\n '-a',\n KEYCHAIN_ACCOUNT,\n '-w',\n ]);\n return trimmedNonEmpty(stdout);\n } catch {\n // Not found, locked, or `security` unavailable: treat as \"no entry\".\n return null;\n }\n },\n async store(passphrase) {\n // We only ever store our own base64url passphrases, so single-quoting them\n // in the piped command line is safe (no quote or backslash to escape). Refuse\n // anything else as a store-failure rather than attempting general escaping.\n if (!BASE64URL_RE.test(passphrase)) return false;\n try {\n const command = `add-generic-password -U -s ${KEYCHAIN_SERVICE} -a ${KEYCHAIN_ACCOUNT} -w '${passphrase}'\\n`;\n await exec('security', ['-i'], command);\n return true;\n } catch {\n return false;\n }\n },\n };\n}\n\n// PowerShell scripts run via built-in Windows PowerShell 5.1 (zero dependency).\n// Each reads its input from stdin and writes its output to stdout, so the\n// passphrase and the blob transit ONLY stdin/stdout, never argv. The stored blob\n// is DPAPI-protected for the CurrentUser scope: it decrypts only as this user on\n// this machine, which is the protection class we want; it is NOT the passphrase in\n// plaintext.\nconst DPAPI_PROTECT_SCRIPT = [\n 'Add-Type -AssemblyName System.Security;',\n '$in = [Console]::In.ReadToEnd();',\n '$bytes = [System.Text.Encoding]::UTF8.GetBytes($in);',\n \"$prot = [System.Security.Cryptography.ProtectedData]::Protect($bytes, $null, 'CurrentUser');\",\n '[Console]::Out.Write([Convert]::ToBase64String($prot));',\n].join(' ');\nconst DPAPI_UNPROTECT_SCRIPT = [\n 'Add-Type -AssemblyName System.Security;',\n '$in = [Console]::In.ReadToEnd();',\n '$blob = [Convert]::FromBase64String($in.Trim());',\n \"$plain = [System.Security.Cryptography.ProtectedData]::Unprotect($blob, $null, 'CurrentUser');\",\n '[Console]::Out.Write([System.Text.Encoding]::UTF8.GetString($plain));',\n].join(' ');\n\nfunction powershellArgs(script: string): string[] {\n return ['-NoProfile', '-NonInteractive', '-Command', script];\n}\n\n/**\n * Windows DPAPI-protected file, via preinstalled PowerShell 5.1 (zero dependency).\n * store(): protect the passphrase through DPAPI (CurrentUser) and write the base64\n * blob to `<dataDir>/passphrase.dpapi` (clobber allowed — this file, unlike the\n * wallet, is safely regenerable). read(): a missing file is a miss; otherwise the\n * blob is unprotected back to the passphrase. Any PowerShell failure degrades.\n */\nfunction dpapiStore(deps: PassphraseDeps): PassphraseStore {\n const exec = deps.exec ?? defaultExec;\n const blobPath = passphraseBlobPath(deps.dir);\n return {\n source: 'dpapi',\n async read() {\n let blob: string;\n try {\n blob = await readFile(blobPath, 'utf8');\n } catch {\n return null; // No blob yet (or unreadable): a miss, not an error.\n }\n try {\n const { stdout } = await exec(\n 'powershell.exe',\n powershellArgs(DPAPI_UNPROTECT_SCRIPT),\n blob,\n );\n const passphrase = stdout.replace(/\\r?\\n$/, '');\n return passphrase.length > 0 ? passphrase : null;\n } catch {\n return null; // Wrong user/machine, tampered blob, or no PowerShell: degrade.\n }\n },\n async store(passphrase) {\n try {\n const { stdout } = await exec(\n 'powershell.exe',\n powershellArgs(DPAPI_PROTECT_SCRIPT),\n passphrase,\n );\n const blob = stdout.replace(/\\r?\\n$/, '').trim();\n if (blob.length === 0) return false;\n // DPAPI CurrentUser encryption is the real protection here; `mode` is inert\n // on win32 (writeFileAtomic drops it there) and only bites when a POSIX host\n // exercises this store in tests. The blob is ciphertext, not the passphrase.\n await writeFileAtomic(blobPath, blob, { mode: 0o600 });\n return true;\n } catch {\n return false;\n }\n },\n };\n}\n\n/**\n * Desktop-Linux Secret Service via `secret-tool` (libsecret-tools), best-effort.\n * `secret-tool` reads the secret from stdin when stdin is not a TTY, so the\n * passphrase never appears in argv. Headless Linux and CI have no built-in durable\n * store, so an absent `secret-tool` (ENOENT) or any failure degrades silently to\n * the next source (env/prompt); nothing is ever written to disk here.\n */\nfunction secretServiceStore(deps: PassphraseDeps): PassphraseStore {\n const exec = deps.exec ?? defaultExec;\n return {\n source: 'secret-service',\n async read() {\n try {\n const { stdout } = await exec('secret-tool', [\n 'lookup',\n 'service',\n KEYCHAIN_SERVICE,\n 'account',\n KEYCHAIN_ACCOUNT,\n ]);\n return trimmedNonEmpty(stdout);\n } catch {\n return null;\n }\n },\n async store(passphrase) {\n try {\n await exec(\n 'secret-tool',\n [\n 'store',\n '--label=tenjin-cli-wallet',\n 'service',\n KEYCHAIN_SERVICE,\n 'account',\n KEYCHAIN_ACCOUNT,\n ],\n passphrase,\n );\n return true;\n } catch {\n return false;\n }\n },\n };\n}\n\n/** A store payload with exactly one optional trailing newline stripped; null when empty. */\nfunction trimmedNonEmpty(stdout: string): string | null {\n const value = stdout.replace(/\\r?\\n$/, '');\n return value.length > 0 ? value : null;\n}\n\n/** The env passphrase, non-empty and used exactly as given; null when unset/empty. */\nfunction envPassphrase(env: NodeJS.ProcessEnv): string | null {\n const value = env.TENJIN_WALLET_PASSPHRASE;\n return value !== undefined && value.length > 0 ? value : null;\n}\n\nfunction canPrompt(deps: PassphraseDeps): boolean {\n return deps.isTTY ?? Boolean(process.stdin.isTTY);\n}\n\nfunction promptOf(deps: PassphraseDeps): PromptFn {\n return deps.prompt ?? promptHidden;\n}\n\nfunction noPassphraseError(): CliError {\n return new CliError('USAGE', 'No wallet passphrase is available.', {\n fix: 'Set TENJIN_WALLET_PASSPHRASE (headless) or run in a terminal.',\n });\n}\n\n// Control bytes handled by the raw-mode reader, named to avoid literal control\n// characters in the source.\nconst CTRL_C = 0x03;\nconst CTRL_D = 0x04;\nconst BACKSPACE = 0x7f;\nconst BACKSPACE_ALT = 0x08;\n\n/**\n * Read one line of input without echoing it. The prompt label goes to stderr so\n * stdout stays the single JSON envelope; typed characters are consumed in raw\n * mode and never printed. Only ever called on a real TTY (canPrompt gates it),\n * so setRawMode is present; tests inject `prompt` and never reach this.\n */\nfunction promptHidden(label: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const stdin = process.stdin;\n const stderr = process.stderr;\n const wasRaw = stdin.isRaw;\n let value = '';\n\n const cleanup = (): void => {\n stdin.setRawMode?.(wasRaw ?? false);\n stdin.pause();\n stdin.removeListener('data', onData);\n };\n const onData = (chunk: Buffer | string): void => {\n for (const ch of chunk.toString('utf8')) {\n const code = ch.charCodeAt(0);\n if (ch === '\\n' || ch === '\\r' || code === CTRL_D) {\n // Enter or Ctrl-D: submit what we have.\n cleanup();\n stderr.write('\\n');\n resolve(value);\n return;\n }\n if (code === CTRL_C) {\n cleanup();\n stderr.write('\\n');\n reject(\n new CliError('USAGE', 'Passphrase entry was cancelled.', {\n fix: 'Run the command again, or set TENJIN_WALLET_PASSPHRASE.',\n }),\n );\n return;\n }\n if (code === BACKSPACE || code === BACKSPACE_ALT) {\n value = value.slice(0, -1);\n } else {\n value += ch;\n }\n }\n };\n\n stderr.write(label);\n stdin.setRawMode?.(true);\n stdin.resume();\n stdin.on('data', onData);\n });\n}\n","import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';\nimport type { PrivateKeyAccount } from 'viem/accounts';\nimport type { Address, Hex } from 'viem';\nimport * as Keystore from 'ox/Keystore';\nimport { CliError } from '../errors';\nimport { walletPath } from '../paths';\nimport {\n PRIVATE_KEY_RE,\n readWalletRecord,\n walletFileMode,\n writeWalletRecord,\n type WalletRecord,\n} from './store';\nimport { resolvePassphrase, type PassphraseDeps } from './passphrase';\nimport type {\n TenjinSigner,\n WalletDescription,\n WalletDiagnostics,\n WalletProvider,\n} from './provider';\n\n/** Passphrase seams the local provider forwards to the resolver (env comes from `deps.env`). */\nexport type PassphraseOverrides = Omit<PassphraseDeps, 'env'>;\n\nexport interface LocalProviderDeps {\n dir: string;\n env: NodeJS.ProcessEnv;\n /** Test seam for keychain exec / TTY prompt / platform during decryption. */\n passphrase?: PassphraseOverrides;\n}\n\nconst isWindows = process.platform === 'win32';\nconst KEY_STORAGE = 'encrypted (keystore v3, scrypt)';\n\n/**\n * A one-shot decrypt cache. The CLI is a single invocation, so a signer derived\n * once (scrypt is deliberately slow) is reused for the rest of the process.\n * Keyed by the keystore's unique id, so distinct wallets never collide.\n */\nconst signerCache = new Map<string, PrivateKeyAccount>();\n\n/**\n * The only real B1 provider: a local viem account whose key comes from the env\n * override or the encrypted wallet file. `describe()` returns just the address\n * and posture WITHOUT a passphrase (the address is stored cleartext on purpose);\n * `getSigner()` is the single door to the key material and the only path that\n * decrypts the keystore.\n */\nexport function createLocalProvider(deps: LocalProviderDeps): WalletProvider {\n return {\n id: 'local',\n async describe(): Promise<WalletDescription> {\n const cred = resolveCredentialOrThrow(await loadCredential(deps));\n return {\n // A file credential's address is stored cleartext and returned as-is —\n // no decryption. An env credential derives (and thereby validates) its\n // key. getSigner is where a file wallet's key/address match is checked.\n address: cred.source === 'env' ? accountFromKey(cred.key, 'env').address : cred.address,\n provider: 'local',\n credentialSource: cred.source,\n policyEnforcement: 'client-only',\n };\n },\n async getSigner(): Promise<TenjinSigner> {\n const cred = resolveCredentialOrThrow(await loadCredential(deps));\n const account = await accountForSigning(cred, deps);\n return {\n address: account.address,\n signMessage: (args) => account.signMessage({ message: args.message }),\n signTypedData: (args) => account.signTypedData(args),\n };\n },\n diagnostics(): Promise<WalletDiagnostics> {\n return localWalletDiagnostics(deps);\n },\n };\n}\n\n/**\n * File-custody warnings for the local provider: an env key shadowing the file,\n * non-0600 perms, and the Windows \"perms not checkable\" note. Keyless. Also\n * reports the at-rest key protection (`keyStorage`) and — only when it is cheap\n * and side-effect-free (the env passphrase) — the passphrase source, so `show`\n * can surface custody posture without decrypting or probing the keychain.\n */\nexport async function localWalletDiagnostics(deps: LocalProviderDeps): Promise<WalletDiagnostics> {\n const mode = await walletFileMode(deps.dir);\n const fileExists = mode !== null;\n const envKey = deps.env.TENJIN_WALLET_KEY;\n const envSet = envKey !== undefined && envKey.length > 0;\n const path = walletPath(deps.dir);\n\n const warnings: string[] = [];\n if (envSet && fileExists) {\n warnings.push('TENJIN_WALLET_KEY is set and shadows the wallet file at runtime.');\n }\n if (mode !== null) {\n if (isWindows) {\n warnings.push('File permission checks are not available on Windows.');\n } else if (mode !== 0o600) {\n warnings.push(\n `Wallet file permissions are ${mode.toString(8)}, expected 600. Run \\`chmod 600 ${path}\\`.`,\n );\n }\n }\n const passphraseSource =\n deps.env.TENJIN_WALLET_PASSPHRASE !== undefined && deps.env.TENJIN_WALLET_PASSPHRASE.length > 0\n ? 'TENJIN_WALLET_PASSPHRASE'\n : undefined;\n return {\n ...(fileExists ? { walletPath: path, keyStorage: KEY_STORAGE } : {}),\n ...(fileExists && passphraseSource !== undefined ? { passphraseSource } : {}),\n warnings,\n };\n}\n\nexport interface LocalWalletInfo {\n address: Address;\n walletPath: string;\n}\n\n/**\n * Generate a fresh key, encrypt it into a Keystore v3 document with `passphrase`,\n * and persist the record NO-CLOBBER. The raw key exists only in memory here and\n * is never written to disk in cleartext. The write, not a caller's pre-check, is\n * the authority: a lost create race throws WALLET_EXISTS rather than overwriting\n * a funded key.\n */\nexport async function createLocalWallet(dir: string, passphrase: string): Promise<LocalWalletInfo> {\n const key = generatePrivateKey();\n const address = privateKeyToAccount(key).address;\n const keystore = await encryptToKeystore(key, passphrase);\n await writeWalletRecord(dir, walletRecord(address, keystore));\n return { address, walletPath: walletPath(dir) };\n}\n\ntype Credential =\n { source: 'env'; key: Hex } | { source: 'file'; keystore: Keystore.Keystore; address: Address };\n\n/** Env override beats the wallet file (CI + ephemeral agents); null when neither exists. */\nasync function loadCredential(deps: LocalProviderDeps): Promise<Credential | null> {\n const envKey = deps.env.TENJIN_WALLET_KEY;\n if (envKey !== undefined && envKey.trim().length > 0) {\n const key = envKey.trim();\n if (!PRIVATE_KEY_RE.test(key)) {\n throw new CliError('WALLET_INVALID_KEY', 'TENJIN_WALLET_KEY is not a valid private key.', {\n fix: 'Set TENJIN_WALLET_KEY to a 0x-prefixed 32-byte hex key, or unset it to use the wallet file.',\n });\n }\n return { source: 'env', key: key as Hex };\n }\n const record = await readWalletRecord(deps.dir);\n if (record !== null) {\n return { source: 'file', keystore: record.keystore, address: record.address as Address };\n }\n return null;\n}\n\n/**\n * Build the viem account for SIGNING. An env credential uses its raw key; a file\n * credential decrypts the keystore with the resolved passphrase, then verifies\n * the recovered key derives the stored cleartext address (a tamper signal) before\n * trusting it. A wrong passphrase or corrupt keystore surfaces as\n * WALLET_INVALID_KEY that names where the passphrase comes from.\n */\nasync function accountForSigning(\n cred: Credential,\n deps: LocalProviderDeps,\n): Promise<PrivateKeyAccount> {\n if (cred.source === 'env') return accountFromKey(cred.key, 'env');\n\n const cached = signerCache.get(cred.keystore.id);\n if (cached !== undefined) return cached;\n\n const { passphrase } = await resolvePassphrase({\n env: deps.env,\n dir: deps.dir,\n ...deps.passphrase,\n });\n let key: Hex;\n try {\n const derived = await Keystore.toKeyAsync(cred.keystore, { password: passphrase });\n key = Keystore.decrypt(cred.keystore, derived);\n } catch (err) {\n throw new CliError('WALLET_INVALID_KEY', 'Could not decrypt the wallet keystore.', {\n fix: 'Check the passphrase: TENJIN_WALLET_PASSPHRASE, the macOS keychain (service tenjin-cli), or the one you enter when prompted.',\n cause: err,\n });\n }\n const account = accountFromKey(key, 'file');\n if (account.address.toLowerCase() !== cred.address.toLowerCase()) {\n throw new CliError(\n 'WALLET_INVALID_KEY',\n `The decrypted key derives ${account.address}, not the wallet file's stored address ${cred.address}.`,\n {\n fix: 'The wallet file may be tampered. Move it aside, then run `tenjin wallet create` for a fresh key or set TENJIN_WALLET_KEY to use the intended one.',\n },\n );\n }\n signerCache.set(cred.keystore.id, account);\n return account;\n}\n\n/** viem account from a raw key, mapping viem's throw on a bad key to WALLET_INVALID_KEY. */\nfunction accountFromKey(key: Hex, source: 'env' | 'file'): PrivateKeyAccount {\n try {\n return privateKeyToAccount(key);\n } catch (err) {\n throw new CliError('WALLET_INVALID_KEY', 'The private key is not a valid secp256k1 key.', {\n fix:\n source === 'file'\n ? 'Move the wallet file aside, then run `tenjin wallet create` for a fresh key or set TENJIN_WALLET_KEY to use the intended one.'\n : 'Set TENJIN_WALLET_KEY to a valid 0x-prefixed 32-byte hex key.',\n cause: err,\n });\n }\n}\n\n/** Encrypt a raw key into a Keystore v3 document using ox's default scrypt parameters. */\nasync function encryptToKeystore(key: Hex, passphrase: string): Promise<Keystore.Keystore> {\n const [derivedKey, opts] = await Keystore.scryptAsync({ password: passphrase });\n return Keystore.encrypt(key, derivedKey, opts);\n}\n\nfunction resolveCredentialOrThrow(cred: Credential | null): Credential {\n if (cred === null) {\n throw new CliError('WALLET_MISSING', 'No wallet found.', {\n fix: 'Run `tenjin wallet create` to create one.',\n });\n }\n return cred;\n}\n\nfunction walletRecord(address: Address, keystore: Keystore.Keystore): WalletRecord {\n return {\n schemaVersion: 2,\n provider: 'local',\n address,\n keystore,\n createdAt: new Date().toISOString(),\n };\n}\n","import { CliError } from '../errors';\nimport { createLocalProvider } from './local';\nimport type { CommandContext } from '../../context';\nimport type { WalletDescription, WalletProvider } from './provider';\n\nexport * from './provider';\nexport { createLocalWallet, type LocalWalletInfo } from './local';\n\nexport interface ResolveWalletProviderOptions {\n /** Test-injection seam: bypass the local provider with a fake (e.g. a remote stub). */\n provider?: WalletProvider;\n}\n\n/**\n * The commands' one entry to a wallet. Production always gets the `local`\n * provider bound to the context's data dir and process env; tests pass\n * `opts.provider` to prove `show`/`balance` work against any provider without a\n * real key on disk.\n */\nexport function resolveWalletProvider(\n ctx: CommandContext,\n opts: ResolveWalletProviderOptions = {},\n): WalletProvider {\n if (opts.provider !== undefined) return opts.provider;\n return createLocalProvider({ dir: ctx.dataDir, env: process.env });\n}\n\n/**\n * Call `describe()` through the error contract: a CliError (e.g. WALLET_MISSING\n * from the local provider) passes through, but any other rejection — a remote\n * provider's network/refusal error — normalizes to PROVIDER_ERROR so callers\n * always see a coded failure, never a bare stack trace.\n */\nexport async function describeWallet(provider: WalletProvider): Promise<WalletDescription> {\n try {\n return await provider.describe();\n } catch (err) {\n if (err instanceof CliError) throw err;\n const message = err instanceof Error ? err.message : 'unknown error';\n throw new CliError('PROVIDER_ERROR', `Wallet provider \"${provider.id}\" failed: ${message}`, {\n fix: 'Check the wallet provider and try again.',\n cause: err,\n });\n }\n}\n"],"mappings":"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","names":["u32","clean","clean","sbox","sbox2","u32","clean","t0","t1","t2","t3","ctr","u32","i","clean","clean","keccak256","toHex","encrypt","pbkdf2","scryptAsync","toHex","crypto","scryptAsync","pbkdf2","scryptAsync","encrypt"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/config.ts","../src/lib/money.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { z } from 'zod';\nimport { CliError } from './errors';\nimport { configPath } from './paths';\nimport { writeFileAtomic } from './atomic-json';\n\n/** A non-negative integer string in USDC atomic units (6-decimal base). */\nconst atomicString = z.string().regex(/^\\d+$/, 'expected an atomic USDC integer string');\n\n/**\n * The persisted config shape. Spend keys are stored atomic (accepted as decimal\n * USD at the command edge, see lib/money); `confirm` is the stored form\n * \"always\" | \"above:<atomic>\". These are client-enforced guardrails, not a\n * security boundary — any process that runs the CLI can also edit this file.\n */\nexport const ConfigSchema = z.object({\n maxAutoSpend: atomicString,\n sessionBudget: atomicString,\n confirm: z.union([z.literal('always'), z.string().regex(/^above:\\d+$/)]),\n allowlistCreators: z.array(z.string()),\n baseUrl: z.url(),\n rpcUrl: z.url(),\n});\nexport type Config = z.infer<typeof ConfigSchema>;\n\n/** Values as they may appear in config.json — every key optional; absent = default. */\nexport const RawConfigSchema = ConfigSchema.partial();\nexport type PartialConfig = z.infer<typeof RawConfigSchema>;\n\nexport const CONFIG_DEFAULTS: Config = {\n maxAutoSpend: '0',\n sessionBudget: '0',\n confirm: 'always',\n allowlistCreators: [],\n baseUrl: 'https://tenjin.blog',\n rpcUrl: 'https://mainnet.base.org',\n};\n\nexport const CONFIG_KEYS = Object.keys(CONFIG_DEFAULTS) as Array<keyof Config>;\n\n/**\n * Read and validate config.json WITHOUT applying defaults, so provenance can\n * distinguish \"present in file\" from \"absent\". Missing file is fine (returns\n * {}); malformed JSON or a failed schema is CONFIG_INVALID with a fix.\n */\nexport async function loadRawConfig(dir: string): Promise<PartialConfig> {\n const path = configPath(dir);\n let raw: string;\n try {\n raw = await readFile(path, 'utf8');\n } catch (err) {\n if (isNotFound(err)) return {};\n throw new CliError('CONFIG_INVALID', `Could not read config at ${path}`, {\n fix: `Check file permissions on ${path}.`,\n cause: err,\n });\n }\n let json: unknown;\n try {\n json = JSON.parse(raw);\n } catch (err) {\n throw new CliError('CONFIG_INVALID', `Config at ${path} is not valid JSON`, {\n fix: `Fix the JSON syntax in ${path}, or delete it to restore defaults.`,\n cause: err,\n });\n }\n const parsed = RawConfigSchema.safeParse(json);\n if (!parsed.success) {\n throw new CliError('CONFIG_INVALID', `Config at ${path} is invalid`, {\n fix: `Correct the reported keys in ${path}, or delete it to restore defaults.`,\n details: parsed.error.issues,\n });\n }\n return parsed.data;\n}\n\n/** File values merged over defaults — the effective persisted config. */\nexport async function loadConfig(dir: string): Promise<Config> {\n return { ...CONFIG_DEFAULTS, ...(await loadRawConfig(dir)) };\n}\n\nexport type Provenance = 'default' | 'file' | 'env' | 'flag';\n\nexport interface ResolvedSetting<T> {\n value: T;\n source: Provenance;\n}\n\n/** Effective value + where it came from, per key. What `config` (bare) renders. */\nexport interface EffectiveSettings {\n maxAutoSpend: ResolvedSetting<string>;\n sessionBudget: ResolvedSetting<string>;\n confirm: ResolvedSetting<string>;\n allowlistCreators: ResolvedSetting<string[]>;\n baseUrl: ResolvedSetting<string>;\n rpcUrl: ResolvedSetting<string>;\n}\n\n/** CLI flags that participate in settings precedence (global `--base-url`). */\nexport interface SettingsFlags {\n baseUrl?: string;\n}\n\nexport interface ResolveSettingsInput {\n /** Raw file values (present keys only) — from loadRawConfig, not loadConfig. */\n config: PartialConfig;\n flags: SettingsFlags;\n env: NodeJS.ProcessEnv;\n}\n\n/**\n * Apply precedence flag > env > file > default per key, returning each effective\n * value with its source. In B1 only baseUrl has flag/env overrides\n * (`--base-url`, TENJIN_BASE_URL); the rest resolve file-or-default.\n */\nexport function resolveSettings(input: ResolveSettingsInput): EffectiveSettings {\n const { config, flags, env } = input;\n return {\n maxAutoSpend: fileOrDefault('maxAutoSpend', config),\n sessionBudget: fileOrDefault('sessionBudget', config),\n confirm: fileOrDefault('confirm', config),\n allowlistCreators: fileOrDefault('allowlistCreators', config),\n baseUrl: resolveBaseUrl(config, flags, env),\n rpcUrl: fileOrDefault('rpcUrl', config),\n };\n}\n\n/** Persist a full, validated config via the atomic writer (0700 dir, 0644 file). */\nexport async function writeConfig(dir: string, config: Config): Promise<void> {\n const validated = ConfigSchema.parse(config);\n await writeFileAtomic(configPath(dir), `${JSON.stringify(validated, null, 2)}\\n`, {\n mode: 0o644,\n dirMode: 0o700,\n });\n}\n\nfunction fileOrDefault<K extends keyof Config>(\n key: K,\n config: PartialConfig,\n): ResolvedSetting<Config[K]> {\n const fromFile = config[key];\n // PartialConfig[K] is Config[K] | undefined; narrowing an indexed access of a\n // type parameter doesn't refine K, so assert the excluded-undefined type.\n if (fromFile !== undefined) return { value: fromFile as Config[K], source: 'file' };\n return { value: CONFIG_DEFAULTS[key], source: 'default' };\n}\n\nfunction resolveBaseUrl(\n config: PartialConfig,\n flags: SettingsFlags,\n env: NodeJS.ProcessEnv,\n): ResolvedSetting<string> {\n if (flags.baseUrl !== undefined && flags.baseUrl.length > 0) {\n return { value: flags.baseUrl, source: 'flag' };\n }\n const fromEnv = env.TENJIN_BASE_URL;\n if (fromEnv !== undefined && fromEnv.length > 0) {\n return { value: fromEnv, source: 'env' };\n }\n if (config.baseUrl !== undefined) return { value: config.baseUrl, source: 'file' };\n return { value: CONFIG_DEFAULTS.baseUrl, source: 'default' };\n}\n\nfunction isNotFound(err: unknown): boolean {\n return (\n typeof err === 'object' &&\n err !== null &&\n 'code' in err &&\n (err as { code?: unknown }).code === 'ENOENT'\n );\n}\n","import { CliError } from './errors';\nimport type { Money } from '../schemas';\n\n/** USDC is a 6-decimal token; one dollar is 1_000_000 atomic units. */\nconst USDC_DECIMALS = 6;\n\n/**\n * Decimal USD at the CLI edge -> atomic USDC string (O1). Accepts \"0\", \"0.25\",\n * \"5\"; rejects negatives, non-numeric input, and more than 6 decimal places as\n * USAGE so a fat-fingered amount fails loudly instead of truncating money.\n * String math throughout — a float would lose precision at the 6th decimal.\n */\nexport function parseUsdToAtomic(input: string): string {\n const trimmed = input.trim();\n if (!/^\\d+(\\.\\d+)?$/.test(trimmed)) {\n throw new CliError('USAGE', `Invalid USD amount: ${JSON.stringify(input)}`, {\n fix: 'Pass a non-negative decimal like 0.25 or 5.',\n });\n }\n const [whole, frac = ''] = trimmed.split('.');\n if (frac.length > USDC_DECIMALS) {\n throw new CliError(\n 'USAGE',\n `USD amount ${JSON.stringify(input)} has more than 6 decimal places`,\n {\n fix: 'USDC supports at most 6 decimal places (micro-dollars).',\n },\n );\n }\n const atomic = BigInt(`${whole}${frac.padEnd(USDC_DECIMALS, '0')}`);\n return atomic.toString();\n}\n\n/**\n * Atomic USDC string -> decimal USD string, trailing zeros trimmed (\"250000\" ->\n * \"0.25\", \"5000000\" -> \"5\", \"0\" -> \"0\"). Throws INTERNAL on a malformed atomic\n * value: atomic strings come from validated config or on-chain reads, so a bad\n * one is a bug, not user input.\n */\nexport function atomicToUsd(atomic: string): string {\n const trimmed = atomic.trim();\n if (!/^\\d+$/.test(trimmed)) {\n throw new CliError('INTERNAL', `Malformed atomic amount: ${JSON.stringify(atomic)}`);\n }\n const value = BigInt(trimmed);\n const base = 10n ** BigInt(USDC_DECIMALS);\n const whole = value / base;\n const frac = (value % base).toString().padStart(USDC_DECIMALS, '0').replace(/0+$/, '');\n return frac.length > 0 ? `${whole}.${frac}` : whole.toString();\n}\n\n/** Dual-form money object for machine output. */\nexport function toMoney(atomic: string): Money {\n return { atomic, usd: atomicToUsd(atomic) };\n}\n"],"mappings":"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","names":[]}
|