@paybox-sh/sdk 0.8.5 → 2.0.0

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/dist/cli.js CHANGED
@@ -1,23 +1,688 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  PayboxClient,
4
- agentClientId,
5
4
  appBaseFrom,
6
5
  configDir,
7
6
  configFile,
8
7
  didNotHappen,
8
+ encodeToken,
9
9
  loadConfig,
10
10
  loginDevice,
11
11
  openBrowser,
12
+ refreshTokens,
12
13
  saveConfig
13
- } from "./chunk-WRPYONXW.js";
14
+ } from "./chunk-66FQ2R7G.js";
14
15
 
15
16
  // src/cli.ts
16
17
  import { spawnSync } from "node:child_process";
17
18
  import { readFileSync, rmSync } from "node:fs";
18
19
  import { createRequire } from "node:module";
19
- import { createInterface } from "node:readline/promises";
20
20
  import { Command } from "commander";
21
+
22
+ // src/pairing.ts
23
+ import nacl from "tweetnacl";
24
+
25
+ // node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/utils.js
26
+ function isBytes(a) {
27
+ return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
28
+ }
29
+ function abytes(b, ...lengths) {
30
+ if (!isBytes(b))
31
+ throw new Error("Uint8Array expected");
32
+ if (lengths.length > 0 && !lengths.includes(b.length))
33
+ throw new Error("Uint8Array expected of length " + lengths + ", got length=" + b.length);
34
+ }
35
+ function aexists(instance, checkFinished = true) {
36
+ if (instance.destroyed)
37
+ throw new Error("Hash instance has been destroyed");
38
+ if (checkFinished && instance.finished)
39
+ throw new Error("Hash#digest() has already been called");
40
+ }
41
+ function aoutput(out, instance) {
42
+ abytes(out);
43
+ const min = instance.outputLen;
44
+ if (out.length < min) {
45
+ throw new Error("digestInto() expects output buffer of length at least " + min);
46
+ }
47
+ }
48
+ function clean(...arrays) {
49
+ for (let i = 0; i < arrays.length; i++) {
50
+ arrays[i].fill(0);
51
+ }
52
+ }
53
+ function createView(arr) {
54
+ return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
55
+ }
56
+ function rotr(word, shift) {
57
+ return word << 32 - shift | word >>> shift;
58
+ }
59
+ function utf8ToBytes(str) {
60
+ if (typeof str !== "string")
61
+ throw new Error("string expected");
62
+ return new Uint8Array(new TextEncoder().encode(str));
63
+ }
64
+ function toBytes(data) {
65
+ if (typeof data === "string")
66
+ data = utf8ToBytes(data);
67
+ abytes(data);
68
+ return data;
69
+ }
70
+ var Hash = class {
71
+ };
72
+ function createHasher(hashCons) {
73
+ const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
74
+ const tmp = hashCons();
75
+ hashC.outputLen = tmp.outputLen;
76
+ hashC.blockLen = tmp.blockLen;
77
+ hashC.create = () => hashCons();
78
+ return hashC;
79
+ }
80
+
81
+ // node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/_md.js
82
+ function setBigUint64(view, byteOffset, value, isLE) {
83
+ if (typeof view.setBigUint64 === "function")
84
+ return view.setBigUint64(byteOffset, value, isLE);
85
+ const _32n = BigInt(32);
86
+ const _u32_max = BigInt(4294967295);
87
+ const wh = Number(value >> _32n & _u32_max);
88
+ const wl = Number(value & _u32_max);
89
+ const h = isLE ? 4 : 0;
90
+ const l = isLE ? 0 : 4;
91
+ view.setUint32(byteOffset + h, wh, isLE);
92
+ view.setUint32(byteOffset + l, wl, isLE);
93
+ }
94
+ function Chi(a, b, c) {
95
+ return a & b ^ ~a & c;
96
+ }
97
+ function Maj(a, b, c) {
98
+ return a & b ^ a & c ^ b & c;
99
+ }
100
+ var HashMD = class extends Hash {
101
+ constructor(blockLen, outputLen, padOffset, isLE) {
102
+ super();
103
+ this.finished = false;
104
+ this.length = 0;
105
+ this.pos = 0;
106
+ this.destroyed = false;
107
+ this.blockLen = blockLen;
108
+ this.outputLen = outputLen;
109
+ this.padOffset = padOffset;
110
+ this.isLE = isLE;
111
+ this.buffer = new Uint8Array(blockLen);
112
+ this.view = createView(this.buffer);
113
+ }
114
+ update(data) {
115
+ aexists(this);
116
+ data = toBytes(data);
117
+ abytes(data);
118
+ const { view, buffer, blockLen } = this;
119
+ const len = data.length;
120
+ for (let pos = 0; pos < len; ) {
121
+ const take = Math.min(blockLen - this.pos, len - pos);
122
+ if (take === blockLen) {
123
+ const dataView = createView(data);
124
+ for (; blockLen <= len - pos; pos += blockLen)
125
+ this.process(dataView, pos);
126
+ continue;
127
+ }
128
+ buffer.set(data.subarray(pos, pos + take), this.pos);
129
+ this.pos += take;
130
+ pos += take;
131
+ if (this.pos === blockLen) {
132
+ this.process(view, 0);
133
+ this.pos = 0;
134
+ }
135
+ }
136
+ this.length += data.length;
137
+ this.roundClean();
138
+ return this;
139
+ }
140
+ digestInto(out) {
141
+ aexists(this);
142
+ aoutput(out, this);
143
+ this.finished = true;
144
+ const { buffer, view, blockLen, isLE } = this;
145
+ let { pos } = this;
146
+ buffer[pos++] = 128;
147
+ clean(this.buffer.subarray(pos));
148
+ if (this.padOffset > blockLen - pos) {
149
+ this.process(view, 0);
150
+ pos = 0;
151
+ }
152
+ for (let i = pos; i < blockLen; i++)
153
+ buffer[i] = 0;
154
+ setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
155
+ this.process(view, 0);
156
+ const oview = createView(out);
157
+ const len = this.outputLen;
158
+ if (len % 4)
159
+ throw new Error("_sha2: outputLen should be aligned to 32bit");
160
+ const outLen = len / 4;
161
+ const state = this.get();
162
+ if (outLen > state.length)
163
+ throw new Error("_sha2: outputLen bigger than state");
164
+ for (let i = 0; i < outLen; i++)
165
+ oview.setUint32(4 * i, state[i], isLE);
166
+ }
167
+ digest() {
168
+ const { buffer, outputLen } = this;
169
+ this.digestInto(buffer);
170
+ const res = buffer.slice(0, outputLen);
171
+ this.destroy();
172
+ return res;
173
+ }
174
+ _cloneInto(to) {
175
+ to || (to = new this.constructor());
176
+ to.set(...this.get());
177
+ const { blockLen, buffer, length, finished, destroyed, pos } = this;
178
+ to.destroyed = destroyed;
179
+ to.finished = finished;
180
+ to.length = length;
181
+ to.pos = pos;
182
+ if (length % blockLen)
183
+ to.buffer.set(buffer);
184
+ return to;
185
+ }
186
+ clone() {
187
+ return this._cloneInto();
188
+ }
189
+ };
190
+ var SHA256_IV = /* @__PURE__ */ Uint32Array.from([
191
+ 1779033703,
192
+ 3144134277,
193
+ 1013904242,
194
+ 2773480762,
195
+ 1359893119,
196
+ 2600822924,
197
+ 528734635,
198
+ 1541459225
199
+ ]);
200
+
201
+ // node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/sha2.js
202
+ var SHA256_K = /* @__PURE__ */ Uint32Array.from([
203
+ 1116352408,
204
+ 1899447441,
205
+ 3049323471,
206
+ 3921009573,
207
+ 961987163,
208
+ 1508970993,
209
+ 2453635748,
210
+ 2870763221,
211
+ 3624381080,
212
+ 310598401,
213
+ 607225278,
214
+ 1426881987,
215
+ 1925078388,
216
+ 2162078206,
217
+ 2614888103,
218
+ 3248222580,
219
+ 3835390401,
220
+ 4022224774,
221
+ 264347078,
222
+ 604807628,
223
+ 770255983,
224
+ 1249150122,
225
+ 1555081692,
226
+ 1996064986,
227
+ 2554220882,
228
+ 2821834349,
229
+ 2952996808,
230
+ 3210313671,
231
+ 3336571891,
232
+ 3584528711,
233
+ 113926993,
234
+ 338241895,
235
+ 666307205,
236
+ 773529912,
237
+ 1294757372,
238
+ 1396182291,
239
+ 1695183700,
240
+ 1986661051,
241
+ 2177026350,
242
+ 2456956037,
243
+ 2730485921,
244
+ 2820302411,
245
+ 3259730800,
246
+ 3345764771,
247
+ 3516065817,
248
+ 3600352804,
249
+ 4094571909,
250
+ 275423344,
251
+ 430227734,
252
+ 506948616,
253
+ 659060556,
254
+ 883997877,
255
+ 958139571,
256
+ 1322822218,
257
+ 1537002063,
258
+ 1747873779,
259
+ 1955562222,
260
+ 2024104815,
261
+ 2227730452,
262
+ 2361852424,
263
+ 2428436474,
264
+ 2756734187,
265
+ 3204031479,
266
+ 3329325298
267
+ ]);
268
+ var SHA256_W = /* @__PURE__ */ new Uint32Array(64);
269
+ var SHA256 = class extends HashMD {
270
+ constructor(outputLen = 32) {
271
+ super(64, outputLen, 8, false);
272
+ this.A = SHA256_IV[0] | 0;
273
+ this.B = SHA256_IV[1] | 0;
274
+ this.C = SHA256_IV[2] | 0;
275
+ this.D = SHA256_IV[3] | 0;
276
+ this.E = SHA256_IV[4] | 0;
277
+ this.F = SHA256_IV[5] | 0;
278
+ this.G = SHA256_IV[6] | 0;
279
+ this.H = SHA256_IV[7] | 0;
280
+ }
281
+ get() {
282
+ const { A, B, C, D, E, F, G, H } = this;
283
+ return [A, B, C, D, E, F, G, H];
284
+ }
285
+ // prettier-ignore
286
+ set(A, B, C, D, E, F, G, H) {
287
+ this.A = A | 0;
288
+ this.B = B | 0;
289
+ this.C = C | 0;
290
+ this.D = D | 0;
291
+ this.E = E | 0;
292
+ this.F = F | 0;
293
+ this.G = G | 0;
294
+ this.H = H | 0;
295
+ }
296
+ process(view, offset) {
297
+ for (let i = 0; i < 16; i++, offset += 4)
298
+ SHA256_W[i] = view.getUint32(offset, false);
299
+ for (let i = 16; i < 64; i++) {
300
+ const W15 = SHA256_W[i - 15];
301
+ const W2 = SHA256_W[i - 2];
302
+ const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3;
303
+ const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10;
304
+ SHA256_W[i] = s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16] | 0;
305
+ }
306
+ let { A, B, C, D, E, F, G, H } = this;
307
+ for (let i = 0; i < 64; i++) {
308
+ const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
309
+ const T1 = H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i] | 0;
310
+ const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
311
+ const T2 = sigma0 + Maj(A, B, C) | 0;
312
+ H = G;
313
+ G = F;
314
+ F = E;
315
+ E = D + T1 | 0;
316
+ D = C;
317
+ C = B;
318
+ B = A;
319
+ A = T1 + T2 | 0;
320
+ }
321
+ A = A + this.A | 0;
322
+ B = B + this.B | 0;
323
+ C = C + this.C | 0;
324
+ D = D + this.D | 0;
325
+ E = E + this.E | 0;
326
+ F = F + this.F | 0;
327
+ G = G + this.G | 0;
328
+ H = H + this.H | 0;
329
+ this.set(A, B, C, D, E, F, G, H);
330
+ }
331
+ roundClean() {
332
+ clean(SHA256_W);
333
+ }
334
+ destroy() {
335
+ this.set(0, 0, 0, 0, 0, 0, 0, 0);
336
+ clean(this.buffer);
337
+ }
338
+ };
339
+ var sha256 = /* @__PURE__ */ createHasher(() => new SHA256());
340
+
341
+ // node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/sha256.js
342
+ var sha2562 = sha256;
343
+
344
+ // node_modules/.pnpm/@paybox+mcp-app@file+..+mcp-app_@modelcontextprotocol+sdk@1.29.0_zod@4.4.3__bn.js@5.2.3_ac1e09a20c76a1143611be5dd3d4f9db/node_modules/@paybox/mcp-app/src/signing/agent-code.ts
345
+ var ALPHABET = [
346
+ "\u{1F436}",
347
+ "\u{1F431}",
348
+ "\u{1F42D}",
349
+ "\u{1F430}",
350
+ "\u{1F98A}",
351
+ "\u{1F43B}",
352
+ "\u{1F43C}",
353
+ "\u{1F981}",
354
+ "\u{1F42E}",
355
+ "\u{1F437}",
356
+ "\u{1F438}",
357
+ "\u{1F435}",
358
+ "\u{1F414}",
359
+ "\u{1F427}",
360
+ "\u{1F426}",
361
+ "\u{1F424}",
362
+ "\u{1F986}",
363
+ "\u{1F985}",
364
+ "\u{1F989}",
365
+ "\u{1F987}",
366
+ "\u{1F417}",
367
+ "\u{1F434}",
368
+ "\u{1F984}",
369
+ "\u{1F41D}",
370
+ "\u{1F41B}",
371
+ "\u{1F98B}",
372
+ "\u{1F40C}",
373
+ "\u{1F41E}",
374
+ "\u{1F41C}",
375
+ "\u{1F422}",
376
+ "\u{1F40D}",
377
+ "\u{1F98E}",
378
+ "\u{1F419}",
379
+ "\u{1F990}",
380
+ "\u{1F980}",
381
+ "\u{1F421}",
382
+ "\u{1F420}",
383
+ "\u{1F42C}",
384
+ "\u{1F433}",
385
+ "\u{1F988}",
386
+ "\u{1F406}",
387
+ "\u{1F993}",
388
+ "\u{1F98D}",
389
+ "\u{1F418}",
390
+ "\u{1F98F}",
391
+ "\u{1F42A}",
392
+ "\u{1F992}",
393
+ "\u{1F411}",
394
+ "\u{1F98C}",
395
+ "\u{1F983}",
396
+ "\u{1F99A}",
397
+ "\u{1F335}",
398
+ "\u{1F384}",
399
+ "\u{1F333}",
400
+ "\u{1F334}",
401
+ "\u{1F331}",
402
+ "\u{1F340}",
403
+ "\u{1F38D}",
404
+ "\u{1F341}",
405
+ "\u{1F342}",
406
+ "\u{1F343}",
407
+ "\u{1F33B}",
408
+ "\u{1F339}",
409
+ "\u{1F337}",
410
+ "\u{1F338}",
411
+ "\u{1F33C}",
412
+ "\u{1F33E}",
413
+ "\u{1F490}",
414
+ "\u{1F344}",
415
+ "\u{1F330}",
416
+ "\u{1F30D}",
417
+ "\u{1F319}",
418
+ "\u2B50",
419
+ "\u{1F308}",
420
+ "\u{1F525}",
421
+ "\u{1F4A7}",
422
+ "\u{1F30A}",
423
+ "\u{1F32A}",
424
+ "\u{1F329}",
425
+ "\u{1F347}",
426
+ "\u{1F349}",
427
+ "\u{1F34A}",
428
+ "\u{1F34B}",
429
+ "\u{1F34C}",
430
+ "\u{1F34D}",
431
+ "\u{1F34E}",
432
+ "\u{1F350}",
433
+ "\u{1F351}",
434
+ "\u{1F352}",
435
+ "\u{1F353}",
436
+ "\u{1F95D}",
437
+ "\u{1F951}",
438
+ "\u{1F346}",
439
+ "\u{1F955}",
440
+ "\u{1F33D}",
441
+ "\u{1F966}",
442
+ "\u{1F952}",
443
+ "\u{1F95C}",
444
+ "\u{1F35E}",
445
+ "\u{1F950}",
446
+ "\u{1F9C0}",
447
+ "\u{1F373}",
448
+ "\u{1F95E}",
449
+ "\u{1F354}",
450
+ "\u{1F35F}",
451
+ "\u{1F355}",
452
+ "\u{1F32D}",
453
+ "\u{1F32E}",
454
+ "\u{1F32F}",
455
+ "\u{1F35C}",
456
+ "\u{1F360}",
457
+ "\u{1F364}",
458
+ "\u{1F365}",
459
+ "\u{1F366}",
460
+ "\u{1F368}",
461
+ "\u{1F369}",
462
+ "\u{1F36A}",
463
+ "\u{1F382}",
464
+ "\u{1F370}",
465
+ "\u{1F36B}",
466
+ "\u{1F36C}",
467
+ "\u{1F36D}",
468
+ "\u{1F36E}",
469
+ "\u{1F36F}",
470
+ "\u{1F37C}",
471
+ "\u{1F95B}",
472
+ "\u2615",
473
+ "\u{1F375}",
474
+ "\u{1F376}",
475
+ "\u{1F37E}",
476
+ "\u{1F377}",
477
+ "\u{1F378}",
478
+ "\u{1F379}",
479
+ "\u{1F37A}",
480
+ "\u{1F943}",
481
+ "\u26BD",
482
+ "\u{1F3C0}",
483
+ "\u{1F3C8}",
484
+ "\u26BE",
485
+ "\u{1F3BE}",
486
+ "\u{1F3B1}",
487
+ "\u{1F3D3}",
488
+ "\u{1F3F8}",
489
+ "\u{1F945}",
490
+ "\u{1F3D2}",
491
+ "\u{1F3F9}",
492
+ "\u{1F3A3}",
493
+ "\u{1F94A}",
494
+ "\u{1F3BF}",
495
+ "\u{1F6F7}",
496
+ "\u{1F3AF}",
497
+ "\u{1F3AE}",
498
+ "\u{1F3B2}",
499
+ "\u{1F3B8}",
500
+ "\u{1F3BA}",
501
+ "\u{1F941}",
502
+ "\u{1F3B9}",
503
+ "\u{1F3A4}",
504
+ "\u{1F3A7}",
505
+ "\u{1F4FB}",
506
+ "\u{1F3AC}",
507
+ "\u{1F3A8}",
508
+ "\u{1F3AA}",
509
+ "\u{1F680}",
510
+ "\u{1F6F8}",
511
+ "\u{1F681}",
512
+ "\u{1F682}",
513
+ "\u{1F684}",
514
+ "\u{1F68C}",
515
+ "\u{1F691}",
516
+ "\u{1F693}",
517
+ "\u{1F695}",
518
+ "\u{1F697}",
519
+ "\u{1F69A}",
520
+ "\u{1F69C}",
521
+ "\u{1F6B2}",
522
+ "\u26F5",
523
+ "\u{1F6F6}",
524
+ "\u{1F6A4}",
525
+ "\u{1F5FF}",
526
+ "\u{1F5FD}",
527
+ "\u{1F3A1}",
528
+ "\u{1F3A2}",
529
+ "\u{1F3A0}",
530
+ "\u26F2",
531
+ "\u{1F3F0}",
532
+ "\u{1F3DF}",
533
+ "\u{1F3AD}",
534
+ "\u{1F381}",
535
+ "\u{1F9ED}",
536
+ "\u231A",
537
+ "\u{1F4F1}",
538
+ "\u{1F4BB}",
539
+ "\u{1F4F7}",
540
+ "\u{1F4FA}",
541
+ "\u{1F4DE}",
542
+ "\u{1F4E0}",
543
+ "\u{1F50B}",
544
+ "\u{1F50C}",
545
+ "\u{1F4A1}",
546
+ "\u{1F526}",
547
+ "\u{1F56F}",
548
+ "\u{1F5D1}",
549
+ "\u{1F4B8}",
550
+ "\u{1F4B0}",
551
+ "\u{1F4B3}",
552
+ "\u{1F48E}",
553
+ "\u{1F527}",
554
+ "\u{1F528}",
555
+ "\u{1F529}",
556
+ "\u{1F52B}",
557
+ "\u{1F4A3}",
558
+ "\u{1F52A}",
559
+ "\u{1F52E}",
560
+ "\u{1F4FF}",
561
+ "\u{1F52C}",
562
+ "\u{1F4D4}",
563
+ "\u{1F4DA}",
564
+ "\u{1F31E}",
565
+ "\u26C4",
566
+ "\u2614",
567
+ "\u{1F30B}",
568
+ "\u{1F94C}",
569
+ "\u{1F3E0}",
570
+ "\u{1F3E5}",
571
+ "\u{1F3ED}",
572
+ "\u{1F511}",
573
+ "\u{1F512}",
574
+ "\u23F0",
575
+ "\u231B",
576
+ "\u{1F4C5}",
577
+ "\u{1F4CC}",
578
+ "\u{1F4CE}",
579
+ "\u{1F4CF}",
580
+ "\u{1F388}",
581
+ "\u{1F383}",
582
+ "\u{1F451}",
583
+ "\u{1F453}",
584
+ "\u{1F3A9}",
585
+ "\u{1F45F}",
586
+ "\u{1F462}",
587
+ "\u{1F45C}",
588
+ "\u{1F392}",
589
+ "\u{1F9F2}",
590
+ "\u{1F9EA}",
591
+ "\u{1F9EC}",
592
+ "\u{1F9F8}",
593
+ "\u{1F9E6}",
594
+ "\u{1F9E2}",
595
+ "\u{1F3C6}",
596
+ "\u{1F6F4}",
597
+ "\u{1FA90}",
598
+ "\u{1F3B3}",
599
+ "\u{1F6A6}",
600
+ "\u{1F9EF}",
601
+ "\u{1F9F9}"
602
+ ];
603
+ function toHex(bytes) {
604
+ return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
605
+ }
606
+ var CODE_LENGTH = 8;
607
+ if (ALPHABET.length !== 256) {
608
+ throw new Error(`agent-code alphabet must be exactly 256 entries, got ${ALPHABET.length}`);
609
+ }
610
+ function sha2563(bytes) {
611
+ return sha2562(bytes);
612
+ }
613
+ function codeFromDigest(digest) {
614
+ const code = [];
615
+ for (let i = 0; i < CODE_LENGTH; i += 1) code.push(ALPHABET[digest[i]]);
616
+ return code;
617
+ }
618
+ async function deriveAgentCode(publicKey) {
619
+ if (publicKey.length !== 32) {
620
+ throw new Error(`public key must be 32 bytes, got ${publicKey.length}`);
621
+ }
622
+ return codeFromDigest(sha2563(publicKey));
623
+ }
624
+
625
+ // src/pairing.ts
626
+ var POLL_MS = 1500;
627
+ var TIMEOUT_MS = 10 * 60 * 1e3;
628
+ var MAX_BACKOFF_MS = 15e3;
629
+ var GIVE_UP_AFTER_FAILING_MS = 9e4;
630
+ async function json(url, init) {
631
+ const res = await fetch(url, init);
632
+ if (!res.ok) {
633
+ const body = await res.text().catch(() => "");
634
+ throw new Error(`${init.method ?? "GET"} ${new URL(url).pathname} failed (${res.status})${body ? `: ${body.slice(0, 200)}` : ""}`);
635
+ }
636
+ return res.json();
637
+ }
638
+ async function pairSigningKey(opts) {
639
+ const { pairing_token, client_id } = await json(`${opts.baseUrl}/api/agent-pairings/token`, {
640
+ method: "POST",
641
+ headers: { authorization: `Bearer ${opts.bearer}`, accept: "application/json" }
642
+ });
643
+ const seed = nacl.randomBytes(nacl.sign.seedLength);
644
+ const pair = nacl.sign.keyPair.fromSeed(seed);
645
+ const keypair = { apiPubHex: toHex(pair.publicKey), apiPrivHex: toHex(seed) };
646
+ const { pairing_id } = await json(`${opts.baseUrl}/iframe/pairing`, {
647
+ method: "POST",
648
+ headers: {
649
+ authorization: `Bearer ${pairing_token}`,
650
+ "content-type": "application/json",
651
+ accept: "application/json"
652
+ },
653
+ body: JSON.stringify({ api_pub_hex: keypair.apiPubHex })
654
+ });
655
+ const url = `${opts.appBase}/agent-key?client_id=${client_id}&pairing_id=${pairing_id}`;
656
+ opts.onCode(await deriveAgentCode(pair.publicKey), url);
657
+ const deadline = Date.now() + TIMEOUT_MS;
658
+ let failures = 0;
659
+ let failingSince = 0;
660
+ while (Date.now() < deadline) {
661
+ const backoff = failures ? Math.min(POLL_MS * 2 ** failures, MAX_BACKOFF_MS) : POLL_MS;
662
+ await new Promise((resolve) => setTimeout(resolve, backoff));
663
+ let status;
664
+ try {
665
+ status = (await json(`${opts.baseUrl}/iframe/pairing/${pairing_id}`, {
666
+ headers: { accept: "application/json" }
667
+ })).status;
668
+ failures = 0;
669
+ failingSince = 0;
670
+ } catch (err) {
671
+ failures += 1;
672
+ failingSince ||= Date.now();
673
+ if (Date.now() - failingSince >= GIVE_UP_AFTER_FAILING_MS) {
674
+ throw new Error(`lost contact with PayBox while waiting: ${err.message}`);
675
+ }
676
+ continue;
677
+ }
678
+ if (status === "completed") return encodeToken(keypair);
679
+ if (status === "cancelled") throw new Error("that request was declined in PayBox");
680
+ if (status === "expired") throw new Error("that request expired \u2014 run `paybox connect` again");
681
+ }
682
+ throw new Error("timed out waiting for you to pick the code in PayBox");
683
+ }
684
+
685
+ // src/cli.ts
21
686
  var DEFAULT_BASE_URL = "https://api.paybox.sh";
22
687
  var PKG = "@paybox-sh/sdk";
23
688
  var VERSION = createRequire(import.meta.url)("../package.json").version;
@@ -30,7 +695,9 @@ function emit(data) {
30
695
  if (jsonMode()) console.log(JSON.stringify(data, null, 2));
31
696
  else console.dir(data, { depth: null, colors: process.stdout.isTTY });
32
697
  const d = data;
33
- if (didNotHappen(d) || didNotHappen(d?.response)) process.exitCode = 1;
698
+ if (didNotHappen(d) || didNotHappen(d?.response) || d?.isError === true) {
699
+ process.exitCode = 1;
700
+ }
34
701
  }
35
702
  function client() {
36
703
  return PayboxClient.fromConfig({ baseUrl: program.opts().baseUrl });
@@ -39,6 +706,13 @@ function readIntent(value) {
39
706
  const raw = value.startsWith("@") ? readFileSync(value.slice(1), "utf8") : value;
40
707
  return JSON.parse(raw);
41
708
  }
709
+ function readObject(value) {
710
+ const parsed = readIntent(value);
711
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
712
+ throw new Error("--input must be a JSON object");
713
+ }
714
+ return parsed;
715
+ }
42
716
  function int(flag, value) {
43
717
  const n = Number(value);
44
718
  if (!Number.isInteger(n)) {
@@ -78,15 +752,6 @@ function isNewer(a, b) {
78
752
  }
79
753
  return false;
80
754
  }
81
- async function prompt(question) {
82
- if (!process.stdin.isTTY) return "";
83
- const rl = createInterface({ input: process.stdin, output: process.stderr });
84
- try {
85
- return (await rl.question(question)).trim();
86
- } finally {
87
- rl.close();
88
- }
89
- }
90
755
  async function run(fn) {
91
756
  try {
92
757
  await fn();
@@ -100,61 +765,62 @@ async function run(fn) {
100
765
  function warnIfUnsignable(c, status) {
101
766
  if (status === "pending_signature" && !c.canSign) {
102
767
  console.error(
103
- "awaiting signatures but no valid pbxk1. signing key is set \u2014 set PAYBOX_SIGNING_KEY and re-run `paybox login`, then poll `paybox request <id>`."
768
+ "awaiting signatures but this machine has no signing key \u2014 run `paybox connect`, then poll `paybox request <id>`."
104
769
  );
105
770
  }
106
771
  }
107
- program.command("login").description("Authenticate via OAuth (browser + passkey), or store a pbx_live_ key").option("--key <key>", "store a pbx_live_ personal API key instead of OAuth").option(
108
- "--signing-key <token>",
109
- "store a pbxk1. wallet signing key; prefer PAYBOX_SIGNING_KEY (an argument is visible in shell history)"
110
- ).option("--app-url <url>", "PayBox app origin for key provisioning (default: derived from --base-url)").option("--no-provision", "skip the wallet signing-key provisioning step").action(
772
+ function resolveBaseUrl() {
773
+ const cfg = loadConfig();
774
+ return (program.opts().baseUrl ?? process.env.PAYBOX_API_URL ?? cfg.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
775
+ }
776
+ program.command("login").description("Authenticate via OAuth (browser + passkey), or store a pbx_live_ key").option("--key <key>", "store a pbx_live_ personal API key instead of OAuth").action(
111
777
  (opts) => run(async () => {
112
778
  const cfg = loadConfig();
113
- const baseUrl = (program.opts().baseUrl ?? process.env.PAYBOX_API_URL ?? cfg.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
114
- cfg.baseUrl = baseUrl;
115
- if (opts.appUrl) cfg.appUrl = opts.appUrl;
116
- const keepExistingLogin = Boolean(opts.signingKey) && Boolean(cfg.apiKey ?? cfg.oauth);
779
+ cfg.baseUrl = resolveBaseUrl();
117
780
  if (opts.key) {
118
781
  cfg.apiKey = opts.key;
119
782
  delete cfg.oauth;
120
- } else if (!keepExistingLogin) {
121
- cfg.oauth = await loginDevice(baseUrl);
783
+ } else {
784
+ cfg.oauth = await loginDevice(cfg.baseUrl);
122
785
  delete cfg.apiKey;
123
786
  }
124
- if (opts.signingKey) cfg.signingKey = opts.signingKey;
787
+ delete cfg.signingKey;
125
788
  saveConfig(cfg);
126
789
  console.error(`Saved credentials to ${configFile()}`);
127
- if (!cfg.oauth || opts.signingKey || opts.provision === false) return;
128
- const cid = agentClientId(cfg.oauth.accessToken);
129
- const appBase = appBaseFrom(baseUrl, opts.appUrl ?? process.env.PAYBOX_APP_URL ?? cfg.appUrl);
130
- if (!cid || !appBase) {
131
- console.error(
132
- "To enable wallet sign/swap, provision a signing key, then set\n PAYBOX_SIGNING_KEY=<pbxk1...> and re-run `paybox login`" + (cid && !appBase ? " (or pass --app-url <paybox app origin>)" : "")
133
- );
134
- return;
790
+ if (!process.env.PAYBOX_SIGNING_KEY) {
791
+ console.error("Run `paybox connect` to connect a signing key; until then sign and swap stop at pending_signature.");
135
792
  }
136
- const url = `${appBase}/agent-key?client_id=${cid}`;
137
- console.error(
138
- `
139
- Next, provision a wallet signing key for this agent (needed for sign/swap):
140
- ${url}
141
- `
142
- );
143
- openBrowser(url);
144
- const key = process.stdin.isTTY ? await prompt("Paste the pbxk1. signing key when ready (or Enter to skip): ") : (process.env.PAYBOX_SIGNING_KEY ?? "").trim();
145
- if (key) {
146
- cfg.signingKey = key;
793
+ })
794
+ );
795
+ program.command("connect").description("Connect a wallet signing key to this machine by picking a code in PayBox").option("--app-url <url>", "PayBox app origin (default: derived from --base-url)").action(
796
+ (opts) => run(async () => {
797
+ const cfg = loadConfig();
798
+ const baseUrl = resolveBaseUrl();
799
+ const appBase = appBaseFrom(baseUrl, opts.appUrl ?? process.env.PAYBOX_APP_URL ?? cfg.appUrl);
800
+ if (!appBase) throw new Error("could not derive the PayBox app origin \u2014 pass --app-url");
801
+ if (opts.appUrl) cfg.appUrl = opts.appUrl;
802
+ if (!cfg.apiKey && cfg.oauth?.expiresAt && Date.now() > cfg.oauth.expiresAt - 3e4) {
803
+ cfg.oauth = await refreshTokens(baseUrl, cfg.oauth);
147
804
  saveConfig(cfg);
148
- console.error("Signing key saved \u2014 sign/swap enabled.");
149
- } else if (process.stdin.isTTY) {
150
- console.error(
151
- "Skipped \u2014 provision one later by setting PAYBOX_SIGNING_KEY and re-running `paybox login`."
152
- );
153
- } else {
154
- console.error(
155
- "No signing key configured, so sign and swap will stop at pending_signature.\nSet PAYBOX_SIGNING_KEY to the `pbxk1.` token and re-run `paybox login`."
156
- );
157
805
  }
806
+ const bearer = cfg.apiKey ?? cfg.oauth?.accessToken;
807
+ if (!bearer) throw new Error("not authenticated \u2014 run `paybox login` first");
808
+ cfg.signingKey = await pairSigningKey({
809
+ baseUrl,
810
+ appBase,
811
+ bearer,
812
+ onCode(code, url) {
813
+ console.error(`
814
+ ${code.join(" ")}
815
+ `);
816
+ console.error(`Open this on any device and pick that code to connect this machine:
817
+ ${url}
818
+ `);
819
+ openBrowser(url);
820
+ }
821
+ });
822
+ saveConfig(cfg);
823
+ console.error("Connected \u2014 sign and swap are enabled on this machine.");
158
824
  })
159
825
  );
160
826
  program.command("logout").description("Forget stored credentials").action(
@@ -267,9 +933,16 @@ program.command("use-service").description("Fetch a paid x402 resource and have
267
933
  emit(result);
268
934
  })
269
935
  );
270
- program.command("portfolio").description("List a wallet address's token balances across chains").requiredOption("--address <addr>").option("--networks <ids>", 'comma-separated network IDs, e.g. "1,8453"').action(
936
+ program.command("portfolio").description("List a wallet address's token balances across chains").requiredOption("--address <addr>").option("--networks <ids>", 'comma-separated network IDs, e.g. "1,8453"').option("--token <addr>", "mint, ERC-20, or native").option("--network-id <id>", "MoonX network id required with --token").action(
271
937
  (o) => run(
272
- async () => emit(await client().getPortfolio({ address: o.address, networkIds: o.networks }))
938
+ async () => emit(
939
+ await client().getPortfolio({
940
+ address: o.address,
941
+ networkIds: o.networks,
942
+ token: o.token,
943
+ networkId: o.networkId == null ? void 0 : Number(o.networkId)
944
+ })
945
+ )
273
946
  )
274
947
  );
275
948
  program.command("verify-solana-balance").description("Verify a Solana transaction's wallet/token effect and current balance").requiredOption("--address <addr>", "canonical Solana wallet address").requiredOption("--mint <addr>", "canonical SPL or Token-2022 mint").requiredOption("--transaction <signature>", "confirmed Solana transaction signature").action(
@@ -285,9 +958,19 @@ program.command("verify-solana-balance").description("Verify a Solana transactio
285
958
  );
286
959
  program.command("claim <request-id>").description("Claim the usable card credentials of an approved payment (one-time)").action((id) => run(async () => emit(await client().claimPaymentCredentials(requestId(id)))));
287
960
  program.command("account-change").description("Get a manage_url for the USER to update this client's access in the app").option("--note <text>", "why the change is needed (shown to the user)").action((o) => run(async () => emit(await client().requestAccountChange(o.note))));
961
+ program.command("deposit-link").description("Open Deposit URL for a granted wallet (charges nothing)").requiredOption("--credential <id>", "a granted wallet credential").option("--amount-usd <n>", "optional amount hint in USD").action(
962
+ (o) => run(
963
+ async () => emit(
964
+ await client().getDepositLink({
965
+ credentialId: credentialId(o.credential),
966
+ amountUsd: o.amountUsd === void 0 ? void 0 : Number(o.amountUsd)
967
+ })
968
+ )
969
+ )
970
+ );
288
971
  program.command("buy-link").description("Signed MoonPay checkout URL funding a granted wallet (charges nothing)").requiredOption("--credential <id>", "a granted wallet credential").option(
289
972
  "--destination <chain>",
290
- "exact network: eip155:8453 (default EVM), eip155:1, or solana:mainnet"
973
+ "exact network: eip155:8453 (default EVM), eip155:1, eip155:4663, or solana:mainnet"
291
974
  ).option("--currency <code>", "enabled MoonPay code matching the exact destination").option("--amount-usd <n>", "prefill amount in USD").action(
292
975
  (o) => run(
293
976
  async () => emit(
@@ -300,47 +983,39 @@ program.command("buy-link").description("Signed MoonPay checkout URL funding a g
300
983
  )
301
984
  )
302
985
  );
303
- var world = program.command("world").description("World prediction markets (requires the world plugin)");
304
- world.command("markets").description("Browse markets (or events with --events)").option("--events", "list events (each groups its markets)").option("--limit <n>").option("--cursor <n>", "rows to skip; the response carries the next cursor").option("--event-ticker <ticker>").option("--series-ticker <ticker>").option("--status <status>", "active | initialized | determined | finalized").action(
305
- (o) => run(
986
+ var plugins = program.command("plugins").description("Discover and use enabled plugins");
987
+ plugins.command("list [query]").description("Discover plugins at runtime").option("--source <source>", "all | official | user", "all").option("--status <status>", "all | enabled | disabled", "all").option("--limit <n>", "results per page").option("--cursor <cursor>", "cursor returned by the previous page").action(
988
+ (query, o) => run(
306
989
  async () => emit(
307
- await client().worldMarkets({
308
- events: Boolean(o.events),
990
+ await client().discoverPlugins({
991
+ query,
992
+ source: o.source,
993
+ status: o.status,
309
994
  limit: optInt("limit", o.limit),
310
- cursor: optInt("cursor", o.cursor),
311
- eventTicker: o.eventTicker,
312
- seriesTicker: o.seriesTicker,
313
- status: o.status
995
+ cursor: o.cursor
314
996
  })
315
997
  )
316
998
  )
317
999
  );
318
- world.command("market <event-ticker>").description("One event with its nested markets (disable with --no-nested)").option("--no-nested", "exclude the event's markets").action(
319
- (ticker, o) => run(async () => emit(await client().worldMarket(ticker, Boolean(o.nested))))
1000
+ plugins.command("contract <contract-uri>").description("Read an official plugin contract returned by discovery").action(
1001
+ (contractUri) => run(async () => emit(await client().getPluginContract(contractUri)))
320
1002
  );
321
- world.command("orderbook <id>").description("A market's orderbook (id is a ticker, or a mint with --by-mint)").option("--by-mint", "look up by outcome mint instead of ticker").action(
322
- (id, o) => run(async () => emit(await client().worldOrderbook(id, Boolean(o.byMint))))
323
- );
324
- world.command("prices <ticker>").description("A market's price history").requiredOption("--start <unix-ts>").requiredOption("--end <unix-ts>").option("--resolution <n>").action(
325
- (ticker, o) => run(
1003
+ plugins.command("use <plugin-id> <tool-id>").description("Invoke a tool from its discovered plugin contract").option("--input <json>", "JSON object or @file", "{}").option("--invocation-id <uuid>", "reuse only for the same unofficial plugin call").action(
1004
+ (pluginId, toolId, o) => run(
326
1005
  async () => emit(
327
- await client().worldPrices({
328
- ticker,
329
- startTs: int("start", o.start),
330
- endTs: int("end", o.end),
331
- resolution: optInt("resolution", o.resolution)
1006
+ await client().usePlugin({
1007
+ pluginId,
1008
+ toolId,
1009
+ input: readObject(o.input),
1010
+ invocationId: o.invocationId === void 0 ? void 0 : uuid(
1011
+ o.invocationId,
1012
+ "--invocation-id expects a UUID",
1013
+ "Reuse it only to retrieve the same unofficial plugin invocation."
1014
+ )
332
1015
  })
333
1016
  )
334
1017
  )
335
1018
  );
336
- world.command("filter-mints <addresses...>").description("Filter addresses down to World outcome mints").action(
337
- (addresses) => run(async () => emit(await client().worldFilterOutcomeMints(addresses)))
338
- );
339
- world.command("positions <address>").description("Solana token positions for an address").action((address) => run(async () => emit(await client().worldPositions(address))));
340
- var hyperliquid = program.command("hyperliquid").description("Hyperliquid spot discovery (requires the hyperliquid plugin)");
341
- hyperliquid.command("markets").description("Spot markets").action(() => run(async () => emit(await client().hyperliquidMarkets())));
342
- hyperliquid.command("prices").description("Spot prices").action(() => run(async () => emit(await client().hyperliquidPrices())));
343
- hyperliquid.command("token <name>").description("Resolve one token by name").action((name) => run(async () => emit(await client().hyperliquidToken(name))));
344
1019
  program.command("request <id>").description("Poll a request's status").option("--wait", "block until it leaves the pending state").action(
345
1020
  (id, o) => run(async () => {
346
1021
  const c = client();
@@ -420,4 +1095,9 @@ function rejectUnknownCommand(argv) {
420
1095
  }
421
1096
  rejectUnknownCommand(process.argv);
422
1097
  program.parseAsync(process.argv);
1098
+ /*! Bundled license information:
1099
+
1100
+ @noble/hashes/esm/utils.js:
1101
+ (*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
1102
+ */
423
1103
  //# sourceMappingURL=cli.js.map