tenjin-cli 0.1.0-alpha.0 → 0.1.0-alpha.1

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.
Files changed (51) hide show
  1. package/README.md +39 -7
  2. package/dist/{ccip-FXWZDDF5.js → ccip-UCLT5VOW.js} +4 -4
  3. package/dist/{chunk-F5DZJLU3.js → chunk-BRJHUQSY.js} +770 -59
  4. package/dist/chunk-BRJHUQSY.js.map +1 -0
  5. package/dist/{chunk-CPUZRZ2A.js → chunk-CUWUHTIL.js} +42 -1
  6. package/dist/{chunk-CPUZRZ2A.js.map → chunk-CUWUHTIL.js.map} +1 -1
  7. package/dist/{chunk-376LHMK2.js → chunk-DXPYFVKG.js} +32 -6
  8. package/dist/chunk-DXPYFVKG.js.map +1 -0
  9. package/dist/chunk-EXBMF5X7.js +1198 -0
  10. package/dist/chunk-EXBMF5X7.js.map +1 -0
  11. package/dist/{chunk-LTTRND4A.js → chunk-EZROUI5U.js} +2 -2
  12. package/dist/{chunk-PAAL45FJ.js → chunk-IPOWB3G3.js} +123 -133
  13. package/dist/chunk-IPOWB3G3.js.map +1 -0
  14. package/dist/{chunk-WOHCAMDQ.js → chunk-LPRVHM7P.js} +14 -697
  15. package/dist/chunk-LPRVHM7P.js.map +1 -0
  16. package/dist/{chunk-TX5T3LKJ.js → chunk-Q53IYV2G.js} +3 -2
  17. package/dist/{chunk-SXQQ2ZSR.js → chunk-T4LKNY7T.js} +24 -11
  18. package/dist/chunk-T4LKNY7T.js.map +1 -0
  19. package/dist/chunk-YBMMV4Y4.js +51 -0
  20. package/dist/chunk-YBMMV4Y4.js.map +1 -0
  21. package/dist/{chunk-FIYZLITH.js → chunk-YG2DO46P.js} +6 -2
  22. package/dist/{chunk-FIYZLITH.js.map → chunk-YG2DO46P.js.map} +1 -1
  23. package/dist/{cli-LMHGCZ5S.js → cli-WA65NP4Y.js} +13 -17
  24. package/dist/{cli-LMHGCZ5S.js.map → cli-WA65NP4Y.js.map} +1 -1
  25. package/dist/{config-XVXZ3V2Q.js → config-CEFTL5ZL.js} +9 -51
  26. package/dist/config-CEFTL5ZL.js.map +1 -0
  27. package/dist/{doctor-MVLZRVPU.js → doctor-3QBYN46N.js} +7 -7
  28. package/dist/index.js +1 -1
  29. package/dist/{secp256k1-35YNNB6F.js → secp256k1-BEZS642W.js} +3 -3
  30. package/dist/{usdc-OQUOFF6R.js → usdc-44R6XZF2.js} +7 -7
  31. package/dist/{wallet-QUWK2PA4.js → wallet-ELBTBMXO.js} +8 -10
  32. package/dist/wallet-XD576HF3.js +173 -0
  33. package/dist/wallet-XD576HF3.js.map +1 -0
  34. package/package.json +3 -1
  35. package/dist/chunk-376LHMK2.js.map +0 -1
  36. package/dist/chunk-F5DZJLU3.js.map +0 -1
  37. package/dist/chunk-PAAL45FJ.js.map +0 -1
  38. package/dist/chunk-QHIEYBLV.js +0 -320
  39. package/dist/chunk-QHIEYBLV.js.map +0 -1
  40. package/dist/chunk-SXQQ2ZSR.js.map +0 -1
  41. package/dist/chunk-WOHCAMDQ.js.map +0 -1
  42. package/dist/config-XVXZ3V2Q.js.map +0 -1
  43. package/dist/wallet-NRKWLKHX.js +0 -153
  44. package/dist/wallet-NRKWLKHX.js.map +0 -1
  45. /package/dist/{ccip-FXWZDDF5.js.map → ccip-UCLT5VOW.js.map} +0 -0
  46. /package/dist/{chunk-LTTRND4A.js.map → chunk-EZROUI5U.js.map} +0 -0
  47. /package/dist/{chunk-TX5T3LKJ.js.map → chunk-Q53IYV2G.js.map} +0 -0
  48. /package/dist/{doctor-MVLZRVPU.js.map → doctor-3QBYN46N.js.map} +0 -0
  49. /package/dist/{secp256k1-35YNNB6F.js.map → secp256k1-BEZS642W.js.map} +0 -0
  50. /package/dist/{usdc-OQUOFF6R.js.map → usdc-44R6XZF2.js.map} +0 -0
  51. /package/dist/{wallet-QUWK2PA4.js.map → wallet-ELBTBMXO.js.map} +0 -0
@@ -0,0 +1,1198 @@
1
+ import { createRequire as __tenjinCreateRequire } from 'node:module'; const require = __tenjinCreateRequire(import.meta.url);
2
+ import {
3
+ hashAuthorization,
4
+ hashMessage,
5
+ hashTypedData,
6
+ keccak256 as keccak2562,
7
+ publicKeyToAddress,
8
+ serializeSignature,
9
+ serializeTransaction
10
+ } from "./chunk-T4LKNY7T.js";
11
+ import {
12
+ hmac,
13
+ secp256k1,
14
+ sha256
15
+ } from "./chunk-Q53IYV2G.js";
16
+ import {
17
+ InvalidAddressError,
18
+ concat3 as concat,
19
+ from2 as from,
20
+ hexToBytes,
21
+ isAddress,
22
+ isEqual,
23
+ isHex,
24
+ keccak256,
25
+ numberToHex,
26
+ random,
27
+ slice3 as slice,
28
+ toHex,
29
+ toHex2
30
+ } from "./chunk-BRJHUQSY.js";
31
+ import {
32
+ ahash,
33
+ anumber,
34
+ asyncLoop,
35
+ checkOpts,
36
+ clean,
37
+ createView,
38
+ kdfInputToBytes,
39
+ rotl,
40
+ swap32IfBE,
41
+ u32
42
+ } from "./chunk-CUWUHTIL.js";
43
+ import {
44
+ PRIVATE_KEY_RE,
45
+ readWalletRecord,
46
+ walletFileMode,
47
+ writeWalletRecord
48
+ } from "./chunk-DXPYFVKG.js";
49
+ import {
50
+ writeFileAtomic
51
+ } from "./chunk-ZPZFPVDN.js";
52
+ import {
53
+ CliError,
54
+ passphraseBlobPath,
55
+ walletPath
56
+ } from "./chunk-YG2DO46P.js";
57
+
58
+ // node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/pbkdf2.js
59
+ function pbkdf2Init(hash, _password, _salt, _opts) {
60
+ ahash(hash);
61
+ const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts);
62
+ const { c, dkLen, asyncTick } = opts;
63
+ anumber(c);
64
+ anumber(dkLen);
65
+ anumber(asyncTick);
66
+ if (c < 1)
67
+ throw new Error("iterations (c) should be >= 1");
68
+ const password = kdfInputToBytes(_password);
69
+ const salt = kdfInputToBytes(_salt);
70
+ const DK = new Uint8Array(dkLen);
71
+ const PRF = hmac.create(hash, password);
72
+ const PRFSalt = PRF._cloneInto().update(salt);
73
+ return { c, dkLen, asyncTick, DK, PRF, PRFSalt };
74
+ }
75
+ function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
76
+ PRF.destroy();
77
+ PRFSalt.destroy();
78
+ if (prfW)
79
+ prfW.destroy();
80
+ clean(u);
81
+ return DK;
82
+ }
83
+ function pbkdf2(hash, password, salt, opts) {
84
+ const { c, dkLen, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
85
+ let prfW;
86
+ const arr = new Uint8Array(4);
87
+ const view = createView(arr);
88
+ const u = new Uint8Array(PRF.outputLen);
89
+ for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
90
+ const Ti = DK.subarray(pos, pos + PRF.outputLen);
91
+ view.setInt32(0, ti, false);
92
+ (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);
93
+ Ti.set(u.subarray(0, Ti.length));
94
+ for (let ui = 1; ui < c; ui++) {
95
+ PRF._cloneInto(prfW).update(u).digestInto(u);
96
+ for (let i = 0; i < Ti.length; i++)
97
+ Ti[i] ^= u[i];
98
+ }
99
+ }
100
+ return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);
101
+ }
102
+
103
+ // node_modules/.pnpm/viem@2.55.2_typescript@6.0.3_zod@4.4.3/node_modules/viem/_esm/accounts/generatePrivateKey.js
104
+ function generatePrivateKey() {
105
+ return toHex(secp256k1.utils.randomPrivateKey());
106
+ }
107
+
108
+ // node_modules/.pnpm/viem@2.55.2_typescript@6.0.3_zod@4.4.3/node_modules/viem/_esm/accounts/toAccount.js
109
+ function toAccount(source) {
110
+ if (typeof source === "string") {
111
+ if (!isAddress(source, { strict: false }))
112
+ throw new InvalidAddressError({ address: source });
113
+ return {
114
+ address: source,
115
+ type: "json-rpc"
116
+ };
117
+ }
118
+ if (!isAddress(source.address, { strict: false }))
119
+ throw new InvalidAddressError({ address: source.address });
120
+ return {
121
+ address: source.address,
122
+ nonceManager: source.nonceManager,
123
+ sign: source.sign,
124
+ signAuthorization: source.signAuthorization,
125
+ signMessage: source.signMessage,
126
+ signTransaction: source.signTransaction,
127
+ signTypedData: source.signTypedData,
128
+ source: "custom",
129
+ type: "local"
130
+ };
131
+ }
132
+
133
+ // node_modules/.pnpm/viem@2.55.2_typescript@6.0.3_zod@4.4.3/node_modules/viem/_esm/accounts/utils/sign.js
134
+ var extraEntropy = false;
135
+ async function sign({ hash, privateKey, to = "object" }) {
136
+ const { r, s, recovery } = secp256k1.sign(hash.slice(2), privateKey.slice(2), {
137
+ lowS: true,
138
+ extraEntropy: isHex(extraEntropy, { strict: false }) ? hexToBytes(extraEntropy) : extraEntropy
139
+ });
140
+ const signature = {
141
+ r: numberToHex(r, { size: 32 }),
142
+ s: numberToHex(s, { size: 32 }),
143
+ v: recovery ? 28n : 27n,
144
+ yParity: recovery
145
+ };
146
+ return (() => {
147
+ if (to === "bytes" || to === "hex")
148
+ return serializeSignature({ ...signature, to });
149
+ return signature;
150
+ })();
151
+ }
152
+
153
+ // node_modules/.pnpm/viem@2.55.2_typescript@6.0.3_zod@4.4.3/node_modules/viem/_esm/accounts/utils/signAuthorization.js
154
+ async function signAuthorization(parameters) {
155
+ const { chainId, nonce, privateKey, to = "object" } = parameters;
156
+ const address = parameters.contractAddress ?? parameters.address;
157
+ const signature = await sign({
158
+ hash: hashAuthorization({ address, chainId, nonce }),
159
+ privateKey,
160
+ to
161
+ });
162
+ if (to === "object")
163
+ return {
164
+ address,
165
+ chainId,
166
+ nonce,
167
+ ...signature
168
+ };
169
+ return signature;
170
+ }
171
+
172
+ // node_modules/.pnpm/viem@2.55.2_typescript@6.0.3_zod@4.4.3/node_modules/viem/_esm/accounts/utils/signMessage.js
173
+ async function signMessage({ message, privateKey }) {
174
+ return await sign({ hash: hashMessage(message), privateKey, to: "hex" });
175
+ }
176
+
177
+ // node_modules/.pnpm/viem@2.55.2_typescript@6.0.3_zod@4.4.3/node_modules/viem/_esm/accounts/utils/signTransaction.js
178
+ async function signTransaction(parameters) {
179
+ const { privateKey, transaction, serializer = serializeTransaction } = parameters;
180
+ const signableTransaction = (() => {
181
+ if (transaction.type === "eip4844")
182
+ return {
183
+ ...transaction,
184
+ sidecars: false
185
+ };
186
+ return transaction;
187
+ })();
188
+ const signature = await sign({
189
+ hash: keccak256(await serializer(signableTransaction)),
190
+ privateKey
191
+ });
192
+ return await serializer(transaction, signature);
193
+ }
194
+
195
+ // node_modules/.pnpm/viem@2.55.2_typescript@6.0.3_zod@4.4.3/node_modules/viem/_esm/accounts/utils/signTypedData.js
196
+ async function signTypedData(parameters) {
197
+ const { privateKey, ...typedData } = parameters;
198
+ return await sign({
199
+ hash: hashTypedData(typedData),
200
+ privateKey,
201
+ to: "hex"
202
+ });
203
+ }
204
+
205
+ // node_modules/.pnpm/viem@2.55.2_typescript@6.0.3_zod@4.4.3/node_modules/viem/_esm/accounts/privateKeyToAccount.js
206
+ function privateKeyToAccount(privateKey, options = {}) {
207
+ const { nonceManager } = options;
208
+ const publicKey = toHex(secp256k1.getPublicKey(privateKey.slice(2), false));
209
+ const address = publicKeyToAddress(publicKey);
210
+ const account = toAccount({
211
+ address,
212
+ nonceManager,
213
+ async sign({ hash }) {
214
+ return sign({ hash, privateKey, to: "hex" });
215
+ },
216
+ async signAuthorization(authorization) {
217
+ return signAuthorization({ ...authorization, privateKey });
218
+ },
219
+ async signMessage({ message }) {
220
+ return signMessage({ message, privateKey });
221
+ },
222
+ async signTransaction(transaction, { serializer } = {}) {
223
+ return signTransaction({ privateKey, transaction, serializer });
224
+ },
225
+ async signTypedData(typedData) {
226
+ return signTypedData({ ...typedData, privateKey });
227
+ }
228
+ });
229
+ return {
230
+ ...account,
231
+ publicKey,
232
+ source: "privateKey"
233
+ };
234
+ }
235
+
236
+ // node_modules/.pnpm/@noble+ciphers@1.3.0/node_modules/@noble/ciphers/esm/utils.js
237
+ function isBytes(a) {
238
+ return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
239
+ }
240
+ function abytes(b, ...lengths) {
241
+ if (!isBytes(b))
242
+ throw new Error("Uint8Array expected");
243
+ if (lengths.length > 0 && !lengths.includes(b.length))
244
+ throw new Error("Uint8Array expected of length " + lengths + ", got length=" + b.length);
245
+ }
246
+ function u8(arr) {
247
+ return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);
248
+ }
249
+ function u322(arr) {
250
+ return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
251
+ }
252
+ function clean2(...arrays) {
253
+ for (let i = 0; i < arrays.length; i++) {
254
+ arrays[i].fill(0);
255
+ }
256
+ }
257
+ var isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68)();
258
+ function overlapBytes(a, b) {
259
+ return a.buffer === b.buffer && // best we can do, may fail with an obscure Proxy
260
+ a.byteOffset < b.byteOffset + b.byteLength && // a starts before b end
261
+ b.byteOffset < a.byteOffset + a.byteLength;
262
+ }
263
+ function complexOverlapBytes(input, output) {
264
+ if (overlapBytes(input, output) && input.byteOffset < output.byteOffset)
265
+ throw new Error("complex overlap of input and output is not supported");
266
+ }
267
+ var wrapCipher = /* @__NO_SIDE_EFFECTS__ */ (params, constructor) => {
268
+ function wrappedCipher(key, ...args) {
269
+ abytes(key);
270
+ if (!isLE)
271
+ throw new Error("Non little-endian hardware is not yet supported");
272
+ if (params.nonceLength !== void 0) {
273
+ const nonce = args[0];
274
+ if (!nonce)
275
+ throw new Error("nonce / iv required");
276
+ if (params.varSizeNonce)
277
+ abytes(nonce);
278
+ else
279
+ abytes(nonce, params.nonceLength);
280
+ }
281
+ const tagl = params.tagLength;
282
+ if (tagl && args[1] !== void 0) {
283
+ abytes(args[1]);
284
+ }
285
+ const cipher = constructor(key, ...args);
286
+ const checkOutput = (fnLength, output) => {
287
+ if (output !== void 0) {
288
+ if (fnLength !== 2)
289
+ throw new Error("cipher output not supported");
290
+ abytes(output);
291
+ }
292
+ };
293
+ let called = false;
294
+ const wrCipher = {
295
+ encrypt(data, output) {
296
+ if (called)
297
+ throw new Error("cannot encrypt() twice with same key + nonce");
298
+ called = true;
299
+ abytes(data);
300
+ checkOutput(cipher.encrypt.length, output);
301
+ return cipher.encrypt(data, output);
302
+ },
303
+ decrypt(data, output) {
304
+ abytes(data);
305
+ if (tagl && data.length < tagl)
306
+ throw new Error("invalid ciphertext length: smaller than tagLength=" + tagl);
307
+ checkOutput(cipher.decrypt.length, output);
308
+ return cipher.decrypt(data, output);
309
+ }
310
+ };
311
+ return wrCipher;
312
+ }
313
+ Object.assign(wrappedCipher, params);
314
+ return wrappedCipher;
315
+ };
316
+ function getOutput(expectedLength, out, onlyAligned = true) {
317
+ if (out === void 0)
318
+ return new Uint8Array(expectedLength);
319
+ if (out.length !== expectedLength)
320
+ throw new Error("invalid output length, expected " + expectedLength + ", got: " + out.length);
321
+ if (onlyAligned && !isAligned32(out))
322
+ throw new Error("invalid output, must be aligned");
323
+ return out;
324
+ }
325
+ function isAligned32(bytes) {
326
+ return bytes.byteOffset % 4 === 0;
327
+ }
328
+ function copyBytes(bytes) {
329
+ return Uint8Array.from(bytes);
330
+ }
331
+
332
+ // node_modules/.pnpm/@noble+ciphers@1.3.0/node_modules/@noble/ciphers/esm/aes.js
333
+ var BLOCK_SIZE = 16;
334
+ var BLOCK_SIZE32 = 4;
335
+ var POLY = 283;
336
+ function mul2(n) {
337
+ return n << 1 ^ POLY & -(n >> 7);
338
+ }
339
+ function mul(a, b) {
340
+ let res = 0;
341
+ for (; b > 0; b >>= 1) {
342
+ res ^= a & -(b & 1);
343
+ a = mul2(a);
344
+ }
345
+ return res;
346
+ }
347
+ var sbox = /* @__PURE__ */ (() => {
348
+ const t = new Uint8Array(256);
349
+ for (let i = 0, x = 1; i < 256; i++, x ^= mul2(x))
350
+ t[i] = x;
351
+ const box = new Uint8Array(256);
352
+ box[0] = 99;
353
+ for (let i = 0; i < 255; i++) {
354
+ let x = t[255 - i];
355
+ x |= x << 8;
356
+ box[t[i]] = (x ^ x >> 4 ^ x >> 5 ^ x >> 6 ^ x >> 7 ^ 99) & 255;
357
+ }
358
+ clean2(t);
359
+ return box;
360
+ })();
361
+ var rotr32_8 = (n) => n << 24 | n >>> 8;
362
+ var rotl32_8 = (n) => n << 8 | n >>> 24;
363
+ function genTtable(sbox2, fn) {
364
+ if (sbox2.length !== 256)
365
+ throw new Error("Wrong sbox length");
366
+ const T0 = new Uint32Array(256).map((_, j) => fn(sbox2[j]));
367
+ const T1 = T0.map(rotl32_8);
368
+ const T2 = T1.map(rotl32_8);
369
+ const T3 = T2.map(rotl32_8);
370
+ const T01 = new Uint32Array(256 * 256);
371
+ const T23 = new Uint32Array(256 * 256);
372
+ const sbox22 = new Uint16Array(256 * 256);
373
+ for (let i = 0; i < 256; i++) {
374
+ for (let j = 0; j < 256; j++) {
375
+ const idx = i * 256 + j;
376
+ T01[idx] = T0[i] ^ T1[j];
377
+ T23[idx] = T2[i] ^ T3[j];
378
+ sbox22[idx] = sbox2[i] << 8 | sbox2[j];
379
+ }
380
+ }
381
+ return { sbox: sbox2, sbox2: sbox22, T0, T1, T2, T3, T01, T23 };
382
+ }
383
+ var tableEncoding = /* @__PURE__ */ genTtable(sbox, (s) => mul(s, 3) << 24 | s << 16 | s << 8 | mul(s, 2));
384
+ var xPowers = /* @__PURE__ */ (() => {
385
+ const p = new Uint8Array(16);
386
+ for (let i = 0, x = 1; i < 16; i++, x = mul2(x))
387
+ p[i] = x;
388
+ return p;
389
+ })();
390
+ function expandKeyLE(key) {
391
+ abytes(key);
392
+ const len = key.length;
393
+ if (![16, 24, 32].includes(len))
394
+ throw new Error("aes: invalid key size, should be 16, 24 or 32, got " + len);
395
+ const { sbox2 } = tableEncoding;
396
+ const toClean = [];
397
+ if (!isAligned32(key))
398
+ toClean.push(key = copyBytes(key));
399
+ const k32 = u322(key);
400
+ const Nk = k32.length;
401
+ const subByte = (n) => applySbox(sbox2, n, n, n, n);
402
+ const xk = new Uint32Array(len + 28);
403
+ xk.set(k32);
404
+ for (let i = Nk; i < xk.length; i++) {
405
+ let t = xk[i - 1];
406
+ if (i % Nk === 0)
407
+ t = subByte(rotr32_8(t)) ^ xPowers[i / Nk - 1];
408
+ else if (Nk > 6 && i % Nk === 4)
409
+ t = subByte(t);
410
+ xk[i] = xk[i - Nk] ^ t;
411
+ }
412
+ clean2(...toClean);
413
+ return xk;
414
+ }
415
+ function apply0123(T01, T23, s0, s1, s2, s3) {
416
+ return T01[s0 << 8 & 65280 | s1 >>> 8 & 255] ^ T23[s2 >>> 8 & 65280 | s3 >>> 24 & 255];
417
+ }
418
+ function applySbox(sbox2, s0, s1, s2, s3) {
419
+ return sbox2[s0 & 255 | s1 & 65280] | sbox2[s2 >>> 16 & 255 | s3 >>> 16 & 65280] << 16;
420
+ }
421
+ function encrypt(xk, s0, s1, s2, s3) {
422
+ const { sbox2, T01, T23 } = tableEncoding;
423
+ let k = 0;
424
+ s0 ^= xk[k++], s1 ^= xk[k++], s2 ^= xk[k++], s3 ^= xk[k++];
425
+ const rounds = xk.length / 4 - 2;
426
+ for (let i = 0; i < rounds; i++) {
427
+ const t02 = xk[k++] ^ apply0123(T01, T23, s0, s1, s2, s3);
428
+ const t12 = xk[k++] ^ apply0123(T01, T23, s1, s2, s3, s0);
429
+ const t22 = xk[k++] ^ apply0123(T01, T23, s2, s3, s0, s1);
430
+ const t32 = xk[k++] ^ apply0123(T01, T23, s3, s0, s1, s2);
431
+ s0 = t02, s1 = t12, s2 = t22, s3 = t32;
432
+ }
433
+ const t0 = xk[k++] ^ applySbox(sbox2, s0, s1, s2, s3);
434
+ const t1 = xk[k++] ^ applySbox(sbox2, s1, s2, s3, s0);
435
+ const t2 = xk[k++] ^ applySbox(sbox2, s2, s3, s0, s1);
436
+ const t3 = xk[k++] ^ applySbox(sbox2, s3, s0, s1, s2);
437
+ return { s0: t0, s1: t1, s2: t2, s3: t3 };
438
+ }
439
+ function ctrCounter(xk, nonce, src, dst) {
440
+ abytes(nonce, BLOCK_SIZE);
441
+ abytes(src);
442
+ const srcLen = src.length;
443
+ dst = getOutput(srcLen, dst);
444
+ complexOverlapBytes(src, dst);
445
+ const ctr2 = nonce;
446
+ const c32 = u322(ctr2);
447
+ let { s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]);
448
+ const src32 = u322(src);
449
+ const dst32 = u322(dst);
450
+ for (let i = 0; i + 4 <= src32.length; i += 4) {
451
+ dst32[i + 0] = src32[i + 0] ^ s0;
452
+ dst32[i + 1] = src32[i + 1] ^ s1;
453
+ dst32[i + 2] = src32[i + 2] ^ s2;
454
+ dst32[i + 3] = src32[i + 3] ^ s3;
455
+ let carry = 1;
456
+ for (let i2 = ctr2.length - 1; i2 >= 0; i2--) {
457
+ carry = carry + (ctr2[i2] & 255) | 0;
458
+ ctr2[i2] = carry & 255;
459
+ carry >>>= 8;
460
+ }
461
+ ({ s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]));
462
+ }
463
+ const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);
464
+ if (start < srcLen) {
465
+ const b32 = new Uint32Array([s0, s1, s2, s3]);
466
+ const buf = u8(b32);
467
+ for (let i = start, pos = 0; i < srcLen; i++, pos++)
468
+ dst[i] = src[i] ^ buf[pos];
469
+ clean2(b32);
470
+ }
471
+ return dst;
472
+ }
473
+ var ctr = /* @__PURE__ */ wrapCipher({ blockSize: 16, nonceLength: 16 }, function aesctr(key, nonce) {
474
+ function processCtr(buf, dst) {
475
+ abytes(buf);
476
+ if (dst !== void 0) {
477
+ abytes(dst);
478
+ if (!isAligned32(dst))
479
+ throw new Error("unaligned destination");
480
+ }
481
+ const xk = expandKeyLE(key);
482
+ const n = copyBytes(nonce);
483
+ const toClean = [xk, n];
484
+ if (!isAligned32(buf))
485
+ toClean.push(buf = copyBytes(buf));
486
+ const out = ctrCounter(xk, n, buf, dst);
487
+ clean2(...toClean);
488
+ return out;
489
+ }
490
+ return {
491
+ encrypt: (plaintext, dst) => processCtr(plaintext, dst),
492
+ decrypt: (ciphertext, dst) => processCtr(ciphertext, dst)
493
+ };
494
+ });
495
+
496
+ // node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/scrypt.js
497
+ function XorAndSalsa(prev, pi, input, ii, out, oi) {
498
+ let y00 = prev[pi++] ^ input[ii++], y01 = prev[pi++] ^ input[ii++];
499
+ let y02 = prev[pi++] ^ input[ii++], y03 = prev[pi++] ^ input[ii++];
500
+ let y04 = prev[pi++] ^ input[ii++], y05 = prev[pi++] ^ input[ii++];
501
+ let y06 = prev[pi++] ^ input[ii++], y07 = prev[pi++] ^ input[ii++];
502
+ let y08 = prev[pi++] ^ input[ii++], y09 = prev[pi++] ^ input[ii++];
503
+ let y10 = prev[pi++] ^ input[ii++], y11 = prev[pi++] ^ input[ii++];
504
+ let y12 = prev[pi++] ^ input[ii++], y13 = prev[pi++] ^ input[ii++];
505
+ let y14 = prev[pi++] ^ input[ii++], y15 = prev[pi++] ^ input[ii++];
506
+ let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15;
507
+ for (let i = 0; i < 8; i += 2) {
508
+ x04 ^= rotl(x00 + x12 | 0, 7);
509
+ x08 ^= rotl(x04 + x00 | 0, 9);
510
+ x12 ^= rotl(x08 + x04 | 0, 13);
511
+ x00 ^= rotl(x12 + x08 | 0, 18);
512
+ x09 ^= rotl(x05 + x01 | 0, 7);
513
+ x13 ^= rotl(x09 + x05 | 0, 9);
514
+ x01 ^= rotl(x13 + x09 | 0, 13);
515
+ x05 ^= rotl(x01 + x13 | 0, 18);
516
+ x14 ^= rotl(x10 + x06 | 0, 7);
517
+ x02 ^= rotl(x14 + x10 | 0, 9);
518
+ x06 ^= rotl(x02 + x14 | 0, 13);
519
+ x10 ^= rotl(x06 + x02 | 0, 18);
520
+ x03 ^= rotl(x15 + x11 | 0, 7);
521
+ x07 ^= rotl(x03 + x15 | 0, 9);
522
+ x11 ^= rotl(x07 + x03 | 0, 13);
523
+ x15 ^= rotl(x11 + x07 | 0, 18);
524
+ x01 ^= rotl(x00 + x03 | 0, 7);
525
+ x02 ^= rotl(x01 + x00 | 0, 9);
526
+ x03 ^= rotl(x02 + x01 | 0, 13);
527
+ x00 ^= rotl(x03 + x02 | 0, 18);
528
+ x06 ^= rotl(x05 + x04 | 0, 7);
529
+ x07 ^= rotl(x06 + x05 | 0, 9);
530
+ x04 ^= rotl(x07 + x06 | 0, 13);
531
+ x05 ^= rotl(x04 + x07 | 0, 18);
532
+ x11 ^= rotl(x10 + x09 | 0, 7);
533
+ x08 ^= rotl(x11 + x10 | 0, 9);
534
+ x09 ^= rotl(x08 + x11 | 0, 13);
535
+ x10 ^= rotl(x09 + x08 | 0, 18);
536
+ x12 ^= rotl(x15 + x14 | 0, 7);
537
+ x13 ^= rotl(x12 + x15 | 0, 9);
538
+ x14 ^= rotl(x13 + x12 | 0, 13);
539
+ x15 ^= rotl(x14 + x13 | 0, 18);
540
+ }
541
+ out[oi++] = y00 + x00 | 0;
542
+ out[oi++] = y01 + x01 | 0;
543
+ out[oi++] = y02 + x02 | 0;
544
+ out[oi++] = y03 + x03 | 0;
545
+ out[oi++] = y04 + x04 | 0;
546
+ out[oi++] = y05 + x05 | 0;
547
+ out[oi++] = y06 + x06 | 0;
548
+ out[oi++] = y07 + x07 | 0;
549
+ out[oi++] = y08 + x08 | 0;
550
+ out[oi++] = y09 + x09 | 0;
551
+ out[oi++] = y10 + x10 | 0;
552
+ out[oi++] = y11 + x11 | 0;
553
+ out[oi++] = y12 + x12 | 0;
554
+ out[oi++] = y13 + x13 | 0;
555
+ out[oi++] = y14 + x14 | 0;
556
+ out[oi++] = y15 + x15 | 0;
557
+ }
558
+ function BlockMix(input, ii, out, oi, r) {
559
+ let head = oi + 0;
560
+ let tail = oi + 16 * r;
561
+ for (let i = 0; i < 16; i++)
562
+ out[tail + i] = input[ii + (2 * r - 1) * 16 + i];
563
+ for (let i = 0; i < r; i++, head += 16, ii += 16) {
564
+ XorAndSalsa(out, tail, input, ii, out, head);
565
+ if (i > 0)
566
+ tail += 16;
567
+ XorAndSalsa(out, head, input, ii += 16, out, tail);
568
+ }
569
+ }
570
+ function scryptInit(password, salt, _opts) {
571
+ const opts = checkOpts({
572
+ dkLen: 32,
573
+ asyncTick: 10,
574
+ maxmem: 1024 ** 3 + 1024
575
+ }, _opts);
576
+ const { N, r, p, dkLen, asyncTick, maxmem, onProgress } = opts;
577
+ anumber(N);
578
+ anumber(r);
579
+ anumber(p);
580
+ anumber(dkLen);
581
+ anumber(asyncTick);
582
+ anumber(maxmem);
583
+ if (onProgress !== void 0 && typeof onProgress !== "function")
584
+ throw new Error("progressCb should be function");
585
+ const blockSize = 128 * r;
586
+ const blockSize32 = blockSize / 4;
587
+ const pow32 = Math.pow(2, 32);
588
+ if (N <= 1 || (N & N - 1) !== 0 || N > pow32) {
589
+ throw new Error("Scrypt: N must be larger than 1, a power of 2, and less than 2^32");
590
+ }
591
+ if (p < 0 || p > (pow32 - 1) * 32 / blockSize) {
592
+ throw new Error("Scrypt: p must be a positive integer less than or equal to ((2^32 - 1) * 32) / (128 * r)");
593
+ }
594
+ if (dkLen < 0 || dkLen > (pow32 - 1) * 32) {
595
+ throw new Error("Scrypt: dkLen should be positive integer less than or equal to (2^32 - 1) * 32");
596
+ }
597
+ const memUsed = blockSize * (N + p);
598
+ if (memUsed > maxmem) {
599
+ throw new Error("Scrypt: memused is bigger than maxMem. Expected 128 * r * (N + p) > maxmem of " + maxmem);
600
+ }
601
+ const B = pbkdf2(sha256, password, salt, { c: 1, dkLen: blockSize * p });
602
+ const B32 = u32(B);
603
+ const V = u32(new Uint8Array(blockSize * N));
604
+ const tmp = u32(new Uint8Array(blockSize));
605
+ let blockMixCb = () => {
606
+ };
607
+ if (onProgress) {
608
+ const totalBlockMix = 2 * N * p;
609
+ const callbackPer = Math.max(Math.floor(totalBlockMix / 1e4), 1);
610
+ let blockMixCnt = 0;
611
+ blockMixCb = () => {
612
+ blockMixCnt++;
613
+ if (onProgress && (!(blockMixCnt % callbackPer) || blockMixCnt === totalBlockMix))
614
+ onProgress(blockMixCnt / totalBlockMix);
615
+ };
616
+ }
617
+ return { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick };
618
+ }
619
+ function scryptOutput(password, dkLen, B, V, tmp) {
620
+ const res = pbkdf2(sha256, password, B, { c: 1, dkLen });
621
+ clean(B, V, tmp);
622
+ return res;
623
+ }
624
+ async function scryptAsync(password, salt, opts) {
625
+ const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick } = scryptInit(password, salt, opts);
626
+ swap32IfBE(B32);
627
+ for (let pi = 0; pi < p; pi++) {
628
+ const Pi = blockSize32 * pi;
629
+ for (let i = 0; i < blockSize32; i++)
630
+ V[i] = B32[Pi + i];
631
+ let pos = 0;
632
+ await asyncLoop(N - 1, asyncTick, () => {
633
+ BlockMix(V, pos, V, pos += blockSize32, r);
634
+ blockMixCb();
635
+ });
636
+ BlockMix(V, (N - 1) * blockSize32, B32, Pi, r);
637
+ blockMixCb();
638
+ await asyncLoop(N, asyncTick, () => {
639
+ const j = B32[Pi + blockSize32 - 16] % N;
640
+ for (let k = 0; k < blockSize32; k++)
641
+ tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k];
642
+ BlockMix(tmp, 0, B32, Pi, r);
643
+ blockMixCb();
644
+ });
645
+ }
646
+ swap32IfBE(B32);
647
+ return scryptOutput(password, dkLen, B, V, tmp);
648
+ }
649
+
650
+ // node_modules/.pnpm/ox@0.14.30_typescript@6.0.3_zod@4.4.3/node_modules/ox/_esm/core/Keystore.js
651
+ function decrypt(keystore, key, options = {}) {
652
+ const { as = "Hex" } = options;
653
+ const key_ = from(typeof key === "function" ? key() : key);
654
+ const encKey = slice(key_, 0, 16);
655
+ const macKey = slice(key_, 16, 32);
656
+ const ciphertext = from(`0x${keystore.crypto.ciphertext}`);
657
+ const mac = keccak2562(concat(macKey, ciphertext));
658
+ if (!isEqual(mac, from(`0x${keystore.crypto.mac}`)))
659
+ throw new Error("corrupt keystore");
660
+ const data = ctr(encKey, from(`0x${keystore.crypto.cipherparams.iv}`)).decrypt(ciphertext);
661
+ if (as === "Hex")
662
+ return toHex2(data);
663
+ return data;
664
+ }
665
+ function encrypt2(privateKey, key, options) {
666
+ const { id = crypto.randomUUID(), kdf, kdfparams, iv } = options;
667
+ const key_ = from(typeof key === "function" ? key() : key);
668
+ const value_ = from(privateKey);
669
+ const encKey = slice(key_, 0, 16);
670
+ const macKey = slice(key_, 16, 32);
671
+ const ciphertext = ctr(encKey, iv).encrypt(value_);
672
+ const mac = keccak2562(concat(macKey, ciphertext));
673
+ return {
674
+ crypto: {
675
+ cipher: "aes-128-ctr",
676
+ ciphertext: toHex2(ciphertext).slice(2),
677
+ cipherparams: { iv: toHex2(iv).slice(2) },
678
+ kdf,
679
+ kdfparams,
680
+ mac: toHex2(mac).slice(2)
681
+ },
682
+ id,
683
+ version: 3
684
+ };
685
+ }
686
+ function pbkdf22(options) {
687
+ const { iv, iterations = 262144, password } = options;
688
+ const salt = options.salt ? from(options.salt) : random(32);
689
+ const key = toHex2(pbkdf2(sha256, password, salt, { c: iterations, dkLen: 32 }));
690
+ return defineKey(() => key, {
691
+ iv,
692
+ kdfparams: {
693
+ c: iterations,
694
+ dklen: 32,
695
+ prf: "hmac-sha256",
696
+ salt: toHex2(salt).slice(2)
697
+ },
698
+ kdf: "pbkdf2"
699
+ });
700
+ }
701
+ async function scryptAsync2(options) {
702
+ const { iv, n = 262144, password } = options;
703
+ const p = 8;
704
+ const r = 1;
705
+ const salt = options.salt ? from(options.salt) : random(32);
706
+ const key = toHex2(await scryptAsync(password, salt, { N: n, dkLen: 32, r, p }));
707
+ return defineKey(() => key, {
708
+ iv,
709
+ kdfparams: {
710
+ dklen: 32,
711
+ n,
712
+ p,
713
+ r,
714
+ salt: toHex2(salt).slice(2)
715
+ },
716
+ kdf: "scrypt"
717
+ });
718
+ }
719
+ async function toKeyAsync(keystore, options) {
720
+ const { crypto: crypto2 } = keystore;
721
+ const { password } = options;
722
+ const { cipherparams, kdf, kdfparams } = crypto2;
723
+ const { iv } = cipherparams;
724
+ const { c, n, p, r, salt } = kdfparams;
725
+ const [key] = await (async () => {
726
+ switch (kdf) {
727
+ case "scrypt":
728
+ return await scryptAsync2({
729
+ iv: from(`0x${iv}`),
730
+ n,
731
+ p,
732
+ r,
733
+ salt: from(`0x${salt}`),
734
+ password
735
+ });
736
+ case "pbkdf2":
737
+ return await pbkdf22({
738
+ iv: from(`0x${iv}`),
739
+ iterations: c,
740
+ password,
741
+ salt: from(`0x${salt}`)
742
+ });
743
+ default:
744
+ throw new Error("unsupported kdf");
745
+ }
746
+ })();
747
+ return key;
748
+ }
749
+ function defineKey(key, options) {
750
+ const iv = options.iv ? from(options.iv) : random(16);
751
+ return [key, { ...options, iv }];
752
+ }
753
+
754
+ // src/lib/wallet/passphrase.ts
755
+ import { execFile } from "child_process";
756
+ import { randomBytes } from "crypto";
757
+ import { readFile } from "fs/promises";
758
+ var KEYCHAIN_SERVICE = "tenjin-cli";
759
+ var KEYCHAIN_ACCOUNT = "wallet";
760
+ var BASE64URL_RE = /^[A-Za-z0-9_-]+$/;
761
+ var defaultExec = (file, args, stdin) => new Promise((resolve, reject) => {
762
+ const child = execFile(file, args, { encoding: "utf8" }, (err, stdout, stderr) => {
763
+ if (err) reject(err);
764
+ else resolve({ stdout, stderr });
765
+ });
766
+ if (stdin !== void 0) {
767
+ child.stdin?.on("error", () => void 0);
768
+ child.stdin?.end(stdin);
769
+ }
770
+ });
771
+ function storeFor(deps) {
772
+ switch (deps.platform ?? process.platform) {
773
+ case "darwin":
774
+ return keychainStore(deps);
775
+ case "win32":
776
+ return dpapiStore(deps);
777
+ case "linux":
778
+ return secretServiceStore(deps);
779
+ default:
780
+ return null;
781
+ }
782
+ }
783
+ async function resolvePassphrase(deps) {
784
+ const fromEnv = envPassphrase(deps.env);
785
+ if (fromEnv !== null) return { passphrase: fromEnv, source: "env" };
786
+ const store = storeFor(deps);
787
+ if (store !== null) {
788
+ const fromStore = await store.read();
789
+ if (fromStore !== null) return { passphrase: fromStore, source: store.source };
790
+ }
791
+ if (canPrompt(deps)) {
792
+ const entered = await promptOf(deps)("Wallet passphrase: ");
793
+ if (entered.length === 0) throw noPassphraseError();
794
+ return { passphrase: entered, source: "prompt" };
795
+ }
796
+ throw noPassphraseError();
797
+ }
798
+ async function resolvePassphraseForCreate(deps) {
799
+ const fromEnv = envPassphrase(deps.env);
800
+ if (fromEnv !== null) return { passphrase: fromEnv, source: "env" };
801
+ const store = storeFor(deps);
802
+ if (store !== null) {
803
+ const generated = randomBytes(32).toString("base64url");
804
+ if (await store.store(generated)) {
805
+ return { passphrase: generated, source: store.source };
806
+ }
807
+ }
808
+ if (canPrompt(deps)) {
809
+ const prompt = promptOf(deps);
810
+ const first = await prompt("Set a wallet passphrase: ");
811
+ if (first.length === 0) {
812
+ throw new CliError("USAGE", "The wallet passphrase must not be empty.", {
813
+ fix: "Enter a non-empty passphrase, or set TENJIN_WALLET_PASSPHRASE."
814
+ });
815
+ }
816
+ const second = await prompt("Confirm passphrase: ");
817
+ if (first !== second) {
818
+ throw new CliError("USAGE", "The passphrases did not match.", {
819
+ fix: "Run `tenjin wallet create` again and enter the same passphrase both times."
820
+ });
821
+ }
822
+ return { passphrase: first, source: "prompt" };
823
+ }
824
+ throw noPassphraseError();
825
+ }
826
+ function keychainStore(deps) {
827
+ const exec = deps.exec ?? defaultExec;
828
+ return {
829
+ source: "keychain",
830
+ async read() {
831
+ try {
832
+ const { stdout } = await exec("security", [
833
+ "find-generic-password",
834
+ "-s",
835
+ KEYCHAIN_SERVICE,
836
+ "-a",
837
+ KEYCHAIN_ACCOUNT,
838
+ "-w"
839
+ ]);
840
+ return trimmedNonEmpty(stdout);
841
+ } catch {
842
+ return null;
843
+ }
844
+ },
845
+ async store(passphrase) {
846
+ if (!BASE64URL_RE.test(passphrase)) return false;
847
+ try {
848
+ const command = `add-generic-password -U -s ${KEYCHAIN_SERVICE} -a ${KEYCHAIN_ACCOUNT} -w '${passphrase}'
849
+ `;
850
+ await exec("security", ["-i"], command);
851
+ return true;
852
+ } catch {
853
+ return false;
854
+ }
855
+ }
856
+ };
857
+ }
858
+ var DPAPI_PROTECT_SCRIPT = [
859
+ "Add-Type -AssemblyName System.Security;",
860
+ "$in = [Console]::In.ReadToEnd();",
861
+ "$bytes = [System.Text.Encoding]::UTF8.GetBytes($in);",
862
+ "$prot = [System.Security.Cryptography.ProtectedData]::Protect($bytes, $null, 'CurrentUser');",
863
+ "[Console]::Out.Write([Convert]::ToBase64String($prot));"
864
+ ].join(" ");
865
+ var DPAPI_UNPROTECT_SCRIPT = [
866
+ "Add-Type -AssemblyName System.Security;",
867
+ "$in = [Console]::In.ReadToEnd();",
868
+ "$blob = [Convert]::FromBase64String($in.Trim());",
869
+ "$plain = [System.Security.Cryptography.ProtectedData]::Unprotect($blob, $null, 'CurrentUser');",
870
+ "[Console]::Out.Write([System.Text.Encoding]::UTF8.GetString($plain));"
871
+ ].join(" ");
872
+ function powershellArgs(script) {
873
+ return ["-NoProfile", "-NonInteractive", "-Command", script];
874
+ }
875
+ function dpapiStore(deps) {
876
+ const exec = deps.exec ?? defaultExec;
877
+ const blobPath = passphraseBlobPath(deps.dir);
878
+ return {
879
+ source: "dpapi",
880
+ async read() {
881
+ let blob;
882
+ try {
883
+ blob = await readFile(blobPath, "utf8");
884
+ } catch {
885
+ return null;
886
+ }
887
+ try {
888
+ const { stdout } = await exec(
889
+ "powershell.exe",
890
+ powershellArgs(DPAPI_UNPROTECT_SCRIPT),
891
+ blob
892
+ );
893
+ const passphrase = stdout.replace(/\r?\n$/, "");
894
+ return passphrase.length > 0 ? passphrase : null;
895
+ } catch {
896
+ return null;
897
+ }
898
+ },
899
+ async store(passphrase) {
900
+ try {
901
+ const { stdout } = await exec(
902
+ "powershell.exe",
903
+ powershellArgs(DPAPI_PROTECT_SCRIPT),
904
+ passphrase
905
+ );
906
+ const blob = stdout.replace(/\r?\n$/, "").trim();
907
+ if (blob.length === 0) return false;
908
+ await writeFileAtomic(blobPath, blob, { mode: 384 });
909
+ return true;
910
+ } catch {
911
+ return false;
912
+ }
913
+ }
914
+ };
915
+ }
916
+ function secretServiceStore(deps) {
917
+ const exec = deps.exec ?? defaultExec;
918
+ return {
919
+ source: "secret-service",
920
+ async read() {
921
+ try {
922
+ const { stdout } = await exec("secret-tool", [
923
+ "lookup",
924
+ "service",
925
+ KEYCHAIN_SERVICE,
926
+ "account",
927
+ KEYCHAIN_ACCOUNT
928
+ ]);
929
+ return trimmedNonEmpty(stdout);
930
+ } catch {
931
+ return null;
932
+ }
933
+ },
934
+ async store(passphrase) {
935
+ try {
936
+ await exec(
937
+ "secret-tool",
938
+ [
939
+ "store",
940
+ "--label=tenjin-cli-wallet",
941
+ "service",
942
+ KEYCHAIN_SERVICE,
943
+ "account",
944
+ KEYCHAIN_ACCOUNT
945
+ ],
946
+ passphrase
947
+ );
948
+ return true;
949
+ } catch {
950
+ return false;
951
+ }
952
+ }
953
+ };
954
+ }
955
+ function trimmedNonEmpty(stdout) {
956
+ const value = stdout.replace(/\r?\n$/, "");
957
+ return value.length > 0 ? value : null;
958
+ }
959
+ function envPassphrase(env) {
960
+ const value = env.TENJIN_WALLET_PASSPHRASE;
961
+ return value !== void 0 && value.length > 0 ? value : null;
962
+ }
963
+ function canPrompt(deps) {
964
+ return deps.isTTY ?? Boolean(process.stdin.isTTY);
965
+ }
966
+ function promptOf(deps) {
967
+ return deps.prompt ?? promptHidden;
968
+ }
969
+ function noPassphraseError() {
970
+ return new CliError("USAGE", "No wallet passphrase is available.", {
971
+ fix: "Set TENJIN_WALLET_PASSPHRASE (headless) or run in a terminal."
972
+ });
973
+ }
974
+ var CTRL_C = 3;
975
+ var CTRL_D = 4;
976
+ var BACKSPACE = 127;
977
+ var BACKSPACE_ALT = 8;
978
+ function promptHidden(label) {
979
+ return new Promise((resolve, reject) => {
980
+ const stdin = process.stdin;
981
+ const stderr = process.stderr;
982
+ const wasRaw = stdin.isRaw;
983
+ let value = "";
984
+ const cleanup = () => {
985
+ stdin.setRawMode?.(wasRaw ?? false);
986
+ stdin.pause();
987
+ stdin.removeListener("data", onData);
988
+ };
989
+ const onData = (chunk) => {
990
+ for (const ch of chunk.toString("utf8")) {
991
+ const code = ch.charCodeAt(0);
992
+ if (ch === "\n" || ch === "\r" || code === CTRL_D) {
993
+ cleanup();
994
+ stderr.write("\n");
995
+ resolve(value);
996
+ return;
997
+ }
998
+ if (code === CTRL_C) {
999
+ cleanup();
1000
+ stderr.write("\n");
1001
+ reject(
1002
+ new CliError("USAGE", "Passphrase entry was cancelled.", {
1003
+ fix: "Run the command again, or set TENJIN_WALLET_PASSPHRASE."
1004
+ })
1005
+ );
1006
+ return;
1007
+ }
1008
+ if (code === BACKSPACE || code === BACKSPACE_ALT) {
1009
+ value = value.slice(0, -1);
1010
+ } else {
1011
+ value += ch;
1012
+ }
1013
+ }
1014
+ };
1015
+ stderr.write(label);
1016
+ stdin.setRawMode?.(true);
1017
+ stdin.resume();
1018
+ stdin.on("data", onData);
1019
+ });
1020
+ }
1021
+
1022
+ // src/lib/wallet/local.ts
1023
+ var isWindows = process.platform === "win32";
1024
+ var KEY_STORAGE = "encrypted (keystore v3, scrypt)";
1025
+ var signerCache = /* @__PURE__ */ new Map();
1026
+ function createLocalProvider(deps) {
1027
+ return {
1028
+ id: "local",
1029
+ async describe() {
1030
+ const cred = resolveCredentialOrThrow(await loadCredential(deps));
1031
+ return {
1032
+ // A file credential's address is stored cleartext and returned as-is —
1033
+ // no decryption. An env credential derives (and thereby validates) its
1034
+ // key. getSigner is where a file wallet's key/address match is checked.
1035
+ address: cred.source === "env" ? accountFromKey(cred.key, "env").address : cred.address,
1036
+ provider: "local",
1037
+ credentialSource: cred.source,
1038
+ policyEnforcement: "client-only"
1039
+ };
1040
+ },
1041
+ async getSigner() {
1042
+ const cred = resolveCredentialOrThrow(await loadCredential(deps));
1043
+ const account = await accountForSigning(cred, deps);
1044
+ return {
1045
+ address: account.address,
1046
+ signMessage: (args) => account.signMessage({ message: args.message }),
1047
+ signTypedData: (args) => account.signTypedData(args)
1048
+ };
1049
+ },
1050
+ diagnostics() {
1051
+ return localWalletDiagnostics(deps);
1052
+ }
1053
+ };
1054
+ }
1055
+ async function localWalletDiagnostics(deps) {
1056
+ const mode = await walletFileMode(deps.dir);
1057
+ const fileExists = mode !== null;
1058
+ const envKey = deps.env.TENJIN_WALLET_KEY;
1059
+ const envSet = envKey !== void 0 && envKey.length > 0;
1060
+ const path = walletPath(deps.dir);
1061
+ const warnings = [];
1062
+ if (envSet && fileExists) {
1063
+ warnings.push("TENJIN_WALLET_KEY is set and shadows the wallet file at runtime.");
1064
+ }
1065
+ if (mode !== null) {
1066
+ if (isWindows) {
1067
+ warnings.push("File permission checks are not available on Windows.");
1068
+ } else if (mode !== 384) {
1069
+ warnings.push(
1070
+ `Wallet file permissions are ${mode.toString(8)}, expected 600. Run \`chmod 600 ${path}\`.`
1071
+ );
1072
+ }
1073
+ }
1074
+ const passphraseSource = deps.env.TENJIN_WALLET_PASSPHRASE !== void 0 && deps.env.TENJIN_WALLET_PASSPHRASE.length > 0 ? "TENJIN_WALLET_PASSPHRASE" : void 0;
1075
+ return {
1076
+ ...fileExists ? { walletPath: path, keyStorage: KEY_STORAGE } : {},
1077
+ ...fileExists && passphraseSource !== void 0 ? { passphraseSource } : {},
1078
+ warnings
1079
+ };
1080
+ }
1081
+ async function createLocalWallet(dir, passphrase) {
1082
+ const key = generatePrivateKey();
1083
+ const address = privateKeyToAccount(key).address;
1084
+ const keystore = await encryptToKeystore(key, passphrase);
1085
+ await writeWalletRecord(dir, walletRecord(address, keystore));
1086
+ return { address, walletPath: walletPath(dir) };
1087
+ }
1088
+ async function loadCredential(deps) {
1089
+ const envKey = deps.env.TENJIN_WALLET_KEY;
1090
+ if (envKey !== void 0 && envKey.trim().length > 0) {
1091
+ const key = envKey.trim();
1092
+ if (!PRIVATE_KEY_RE.test(key)) {
1093
+ throw new CliError("WALLET_INVALID_KEY", "TENJIN_WALLET_KEY is not a valid private key.", {
1094
+ fix: "Set TENJIN_WALLET_KEY to a 0x-prefixed 32-byte hex key, or unset it to use the wallet file."
1095
+ });
1096
+ }
1097
+ return { source: "env", key };
1098
+ }
1099
+ const record = await readWalletRecord(deps.dir);
1100
+ if (record !== null) {
1101
+ return { source: "file", keystore: record.keystore, address: record.address };
1102
+ }
1103
+ return null;
1104
+ }
1105
+ async function accountForSigning(cred, deps) {
1106
+ if (cred.source === "env") return accountFromKey(cred.key, "env");
1107
+ const cached = signerCache.get(cred.keystore.id);
1108
+ if (cached !== void 0) return cached;
1109
+ const { passphrase } = await resolvePassphrase({
1110
+ env: deps.env,
1111
+ dir: deps.dir,
1112
+ ...deps.passphrase
1113
+ });
1114
+ let key;
1115
+ try {
1116
+ const derived = await toKeyAsync(cred.keystore, { password: passphrase });
1117
+ key = decrypt(cred.keystore, derived);
1118
+ } catch (err) {
1119
+ throw new CliError("WALLET_INVALID_KEY", "Could not decrypt the wallet keystore.", {
1120
+ fix: "Check the passphrase: TENJIN_WALLET_PASSPHRASE, the macOS keychain (service tenjin-cli), or the one you enter when prompted.",
1121
+ cause: err
1122
+ });
1123
+ }
1124
+ const account = accountFromKey(key, "file");
1125
+ if (account.address.toLowerCase() !== cred.address.toLowerCase()) {
1126
+ throw new CliError(
1127
+ "WALLET_INVALID_KEY",
1128
+ `The decrypted key derives ${account.address}, not the wallet file's stored address ${cred.address}.`,
1129
+ {
1130
+ 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."
1131
+ }
1132
+ );
1133
+ }
1134
+ signerCache.set(cred.keystore.id, account);
1135
+ return account;
1136
+ }
1137
+ function accountFromKey(key, source) {
1138
+ try {
1139
+ return privateKeyToAccount(key);
1140
+ } catch (err) {
1141
+ throw new CliError("WALLET_INVALID_KEY", "The private key is not a valid secp256k1 key.", {
1142
+ fix: source === "file" ? "Move the wallet file aside, then run `tenjin wallet create` for a fresh key or set TENJIN_WALLET_KEY to use the intended one." : "Set TENJIN_WALLET_KEY to a valid 0x-prefixed 32-byte hex key.",
1143
+ cause: err
1144
+ });
1145
+ }
1146
+ }
1147
+ async function encryptToKeystore(key, passphrase) {
1148
+ const [derivedKey, opts] = await scryptAsync2({ password: passphrase });
1149
+ return encrypt2(key, derivedKey, opts);
1150
+ }
1151
+ function resolveCredentialOrThrow(cred) {
1152
+ if (cred === null) {
1153
+ throw new CliError("WALLET_MISSING", "No wallet found.", {
1154
+ fix: "Run `tenjin wallet create` to create one."
1155
+ });
1156
+ }
1157
+ return cred;
1158
+ }
1159
+ function walletRecord(address, keystore) {
1160
+ return {
1161
+ schemaVersion: 2,
1162
+ provider: "local",
1163
+ address,
1164
+ keystore,
1165
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
1166
+ };
1167
+ }
1168
+
1169
+ // src/lib/wallet/index.ts
1170
+ function resolveWalletProvider(ctx, opts = {}) {
1171
+ if (opts.provider !== void 0) return opts.provider;
1172
+ return createLocalProvider({ dir: ctx.dataDir, env: process.env });
1173
+ }
1174
+ async function describeWallet(provider) {
1175
+ try {
1176
+ return await provider.describe();
1177
+ } catch (err) {
1178
+ if (err instanceof CliError) throw err;
1179
+ const message = err instanceof Error ? err.message : "unknown error";
1180
+ throw new CliError("PROVIDER_ERROR", `Wallet provider "${provider.id}" failed: ${message}`, {
1181
+ fix: "Check the wallet provider and try again.",
1182
+ cause: err
1183
+ });
1184
+ }
1185
+ }
1186
+
1187
+ export {
1188
+ resolvePassphraseForCreate,
1189
+ createLocalWallet,
1190
+ resolveWalletProvider,
1191
+ describeWallet
1192
+ };
1193
+ /*! Bundled license information:
1194
+
1195
+ @noble/ciphers/esm/utils.js:
1196
+ (*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) *)
1197
+ */
1198
+ //# sourceMappingURL=chunk-EXBMF5X7.js.map