@p2pdotme/sdk 1.0.4 → 1.1.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.
Files changed (64) hide show
  1. package/README.md +71 -41
  2. package/dist/country.cjs +9 -2
  3. package/dist/country.cjs.map +1 -1
  4. package/dist/country.d.cts +35 -10
  5. package/dist/country.d.ts +35 -10
  6. package/dist/country.mjs +6 -2
  7. package/dist/country.mjs.map +1 -1
  8. package/dist/fraud-engine.cjs +52 -48
  9. package/dist/fraud-engine.cjs.map +1 -1
  10. package/dist/fraud-engine.mjs +46 -42
  11. package/dist/fraud-engine.mjs.map +1 -1
  12. package/dist/index.cjs +4 -14
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +41 -36
  15. package/dist/index.d.ts +41 -36
  16. package/dist/index.mjs +4 -12
  17. package/dist/index.mjs.map +1 -1
  18. package/dist/{payload.cjs → orders.cjs} +2357 -253
  19. package/dist/orders.cjs.map +1 -0
  20. package/dist/orders.d.cts +399 -0
  21. package/dist/orders.d.ts +399 -0
  22. package/dist/{payload.mjs → orders.mjs} +2340 -237
  23. package/dist/orders.mjs.map +1 -0
  24. package/dist/prices.cjs +1008 -0
  25. package/dist/prices.cjs.map +1 -0
  26. package/dist/prices.d.cts +109 -0
  27. package/dist/prices.d.ts +109 -0
  28. package/dist/prices.mjs +980 -0
  29. package/dist/prices.mjs.map +1 -0
  30. package/dist/profile.cjs +475 -69
  31. package/dist/profile.cjs.map +1 -1
  32. package/dist/profile.d.cts +39 -27
  33. package/dist/profile.d.ts +39 -27
  34. package/dist/profile.mjs +468 -62
  35. package/dist/profile.mjs.map +1 -1
  36. package/dist/qr-parsers.cjs +7 -7
  37. package/dist/qr-parsers.cjs.map +1 -1
  38. package/dist/qr-parsers.d.cts +38 -16
  39. package/dist/qr-parsers.d.ts +38 -16
  40. package/dist/qr-parsers.mjs +7 -7
  41. package/dist/qr-parsers.mjs.map +1 -1
  42. package/dist/react.cjs +2531 -1105
  43. package/dist/react.cjs.map +1 -1
  44. package/dist/react.d.cts +384 -104
  45. package/dist/react.d.ts +384 -104
  46. package/dist/react.mjs +2417 -992
  47. package/dist/react.mjs.map +1 -1
  48. package/dist/zkkyc.cjs +405 -24
  49. package/dist/zkkyc.cjs.map +1 -1
  50. package/dist/zkkyc.d.cts +14 -9
  51. package/dist/zkkyc.d.ts +14 -9
  52. package/dist/zkkyc.mjs +405 -24
  53. package/dist/zkkyc.mjs.map +1 -1
  54. package/package.json +12 -12
  55. package/dist/order-routing.cjs +0 -888
  56. package/dist/order-routing.cjs.map +0 -1
  57. package/dist/order-routing.d.cts +0 -68
  58. package/dist/order-routing.d.ts +0 -68
  59. package/dist/order-routing.mjs +0 -860
  60. package/dist/order-routing.mjs.map +0 -1
  61. package/dist/payload.cjs.map +0 -1
  62. package/dist/payload.d.cts +0 -147
  63. package/dist/payload.d.ts +0 -147
  64. package/dist/payload.mjs.map +0 -1
@@ -1,27 +1,794 @@
1
- // src/payload/actions.ts
2
- import { errAsync } from "neverthrow";
1
+ // src/orders/client.ts
2
+ import { errAsync as errAsync3, okAsync as okAsync4 } from "neverthrow";
3
3
 
4
- // src/constants/currencies.constant.ts
5
- var CURRENCY = {
6
- IDR: "IDR",
7
- INR: "INR",
8
- BRL: "BRL",
9
- ARS: "ARS",
10
- MEX: "MEX",
11
- VEN: "VEN",
12
- EUR: "EUR",
13
- NGN: "NGN",
14
- USD: "USD",
15
- COP: "COP"
4
+ // src/contracts/order-processor/index.ts
5
+ import { ResultAsync } from "neverthrow";
6
+ import { stringToHex } from "viem";
7
+
8
+ // src/contracts/abis/index.ts
9
+ import { erc20Abi } from "viem";
10
+
11
+ // src/contracts/abis/order-flow-facet.ts
12
+ var orderFlowFacetAbi = [
13
+ {
14
+ inputs: [
15
+ { internalType: "uint256", name: "circleId", type: "uint256" },
16
+ { internalType: "uint256", name: "assignUpto", type: "uint256" },
17
+ { internalType: "bytes32", name: "currency", type: "bytes32" },
18
+ { internalType: "address", name: "user", type: "address" },
19
+ { internalType: "uint256", name: "usdtAmount", type: "uint256" },
20
+ { internalType: "uint256", name: "fiatAmount", type: "uint256" },
21
+ { internalType: "int256", name: "orderType", type: "int256" },
22
+ { internalType: "uint256", name: "preferredPCConfigId", type: "uint256" }
23
+ ],
24
+ name: "getAssignableMerchantsFromCircle",
25
+ outputs: [{ internalType: "address[]", name: "", type: "address[]" }],
26
+ stateMutability: "view",
27
+ type: "function"
28
+ },
29
+ {
30
+ inputs: [
31
+ { internalType: "address", name: "_user", type: "address" },
32
+ { internalType: "bytes32", name: "_nativeCurrency", type: "bytes32" }
33
+ ],
34
+ name: "userTxLimit",
35
+ outputs: [
36
+ { internalType: "uint256", name: "", type: "uint256" },
37
+ { internalType: "uint256", name: "", type: "uint256" }
38
+ ],
39
+ stateMutability: "view",
40
+ type: "function"
41
+ },
42
+ {
43
+ inputs: [
44
+ { internalType: "string", name: "_pubKey", type: "string" },
45
+ { internalType: "uint256", name: "_amount", type: "uint256" },
46
+ { internalType: "address", name: "_recipientAddr", type: "address" },
47
+ { internalType: "uint8", name: "_orderType", type: "uint8" },
48
+ { internalType: "string", name: "_userUpi", type: "string" },
49
+ { internalType: "string", name: "_userPubKey", type: "string" },
50
+ { internalType: "bytes32", name: "_currency", type: "bytes32" },
51
+ { internalType: "uint256", name: "preferredPaymentChannelConfigId", type: "uint256" },
52
+ { internalType: "uint256", name: "_circleId", type: "uint256" },
53
+ { internalType: "uint256", name: "_fiatAmountLimit", type: "uint256" }
54
+ ],
55
+ name: "placeOrder",
56
+ outputs: [],
57
+ stateMutability: "nonpayable",
58
+ type: "function"
59
+ },
60
+ {
61
+ inputs: [{ internalType: "uint256", name: "_orderId", type: "uint256" }],
62
+ name: "cancelOrder",
63
+ outputs: [],
64
+ stateMutability: "nonpayable",
65
+ type: "function"
66
+ },
67
+ {
68
+ inputs: [
69
+ { internalType: "uint256", name: "_orderId", type: "uint256" },
70
+ { internalType: "string", name: "_userEncUpi", type: "string" },
71
+ { internalType: "uint256", name: "_updatedAmount", type: "uint256" }
72
+ ],
73
+ name: "setSellOrderUpi",
74
+ outputs: [],
75
+ stateMutability: "nonpayable",
76
+ type: "function"
77
+ },
78
+ {
79
+ type: "event",
80
+ name: "OrderPlaced",
81
+ anonymous: false,
82
+ inputs: [
83
+ { indexed: true, name: "orderId", type: "uint256" },
84
+ { indexed: true, name: "user", type: "address" },
85
+ { indexed: true, name: "merchant", type: "address" },
86
+ { indexed: false, name: "amount", type: "uint256" },
87
+ { indexed: false, name: "orderType", type: "uint8" },
88
+ { indexed: false, name: "placedTimestamp", type: "uint256" },
89
+ {
90
+ indexed: false,
91
+ name: "_order",
92
+ type: "tuple",
93
+ components: [
94
+ { name: "amount", type: "uint256" },
95
+ { name: "fiatAmount", type: "uint256" },
96
+ { name: "placedTimestamp", type: "uint256" },
97
+ { name: "completedTimestamp", type: "uint256" },
98
+ { name: "userCompletedTimestamp", type: "uint256" },
99
+ { name: "acceptedMerchant", type: "address" },
100
+ { name: "user", type: "address" },
101
+ { name: "recipientAddr", type: "address" },
102
+ { name: "pubkey", type: "string" },
103
+ { name: "encUpi", type: "string" },
104
+ { name: "userCompleted", type: "bool" },
105
+ { name: "status", type: "uint8" },
106
+ { name: "orderType", type: "uint8" },
107
+ {
108
+ name: "disputeInfo",
109
+ type: "tuple",
110
+ components: [
111
+ { name: "raisedBy", type: "uint8" },
112
+ { name: "status", type: "uint8" },
113
+ { name: "redactTransId", type: "uint256" },
114
+ { name: "accountNumber", type: "uint256" }
115
+ ]
116
+ },
117
+ { name: "id", type: "uint256" },
118
+ { name: "userPubKey", type: "string" },
119
+ { name: "encMerchantUpi", type: "string" },
120
+ { name: "acceptedAccountNo", type: "uint256" },
121
+ { name: "assignedAccountNos", type: "uint256[]" },
122
+ { name: "currency", type: "bytes32" },
123
+ { name: "preferredPaymentChannelConfigId", type: "uint256" },
124
+ { name: "circleId", type: "uint256" }
125
+ ]
126
+ }
127
+ ]
128
+ },
129
+ {
130
+ type: "event",
131
+ name: "OrderAccepted",
132
+ anonymous: false,
133
+ inputs: [
134
+ { indexed: true, name: "orderId", type: "uint256" },
135
+ { indexed: true, name: "merchant", type: "address" },
136
+ { indexed: false, name: "pubKey", type: "string" },
137
+ {
138
+ indexed: false,
139
+ name: "_order",
140
+ type: "tuple",
141
+ components: [
142
+ { name: "amount", type: "uint256" },
143
+ { name: "fiatAmount", type: "uint256" },
144
+ { name: "placedTimestamp", type: "uint256" },
145
+ { name: "completedTimestamp", type: "uint256" },
146
+ { name: "userCompletedTimestamp", type: "uint256" },
147
+ { name: "acceptedMerchant", type: "address" },
148
+ { name: "user", type: "address" },
149
+ { name: "recipientAddr", type: "address" },
150
+ { name: "pubkey", type: "string" },
151
+ { name: "encUpi", type: "string" },
152
+ { name: "userCompleted", type: "bool" },
153
+ { name: "status", type: "uint8" },
154
+ { name: "orderType", type: "uint8" },
155
+ {
156
+ name: "disputeInfo",
157
+ type: "tuple",
158
+ components: [
159
+ { name: "raisedBy", type: "uint8" },
160
+ { name: "status", type: "uint8" },
161
+ { name: "redactTransId", type: "uint256" },
162
+ { name: "accountNumber", type: "uint256" }
163
+ ]
164
+ },
165
+ { name: "id", type: "uint256" },
166
+ { name: "userPubKey", type: "string" },
167
+ { name: "encMerchantUpi", type: "string" },
168
+ { name: "acceptedAccountNo", type: "uint256" },
169
+ { name: "assignedAccountNos", type: "uint256[]" },
170
+ { name: "currency", type: "bytes32" },
171
+ { name: "preferredPaymentChannelConfigId", type: "uint256" },
172
+ { name: "circleId", type: "uint256" }
173
+ ]
174
+ }
175
+ ]
176
+ },
177
+ {
178
+ type: "event",
179
+ name: "BuyOrderPaid",
180
+ anonymous: false,
181
+ inputs: [
182
+ { indexed: true, name: "orderId", type: "uint256" },
183
+ { indexed: true, name: "user", type: "address" },
184
+ {
185
+ indexed: false,
186
+ name: "_order",
187
+ type: "tuple",
188
+ components: [
189
+ { name: "amount", type: "uint256" },
190
+ { name: "fiatAmount", type: "uint256" },
191
+ { name: "placedTimestamp", type: "uint256" },
192
+ { name: "completedTimestamp", type: "uint256" },
193
+ { name: "userCompletedTimestamp", type: "uint256" },
194
+ { name: "acceptedMerchant", type: "address" },
195
+ { name: "user", type: "address" },
196
+ { name: "recipientAddr", type: "address" },
197
+ { name: "pubkey", type: "string" },
198
+ { name: "encUpi", type: "string" },
199
+ { name: "userCompleted", type: "bool" },
200
+ { name: "status", type: "uint8" },
201
+ { name: "orderType", type: "uint8" },
202
+ {
203
+ name: "disputeInfo",
204
+ type: "tuple",
205
+ components: [
206
+ { name: "raisedBy", type: "uint8" },
207
+ { name: "status", type: "uint8" },
208
+ { name: "redactTransId", type: "uint256" },
209
+ { name: "accountNumber", type: "uint256" }
210
+ ]
211
+ },
212
+ { name: "id", type: "uint256" },
213
+ { name: "userPubKey", type: "string" },
214
+ { name: "encMerchantUpi", type: "string" },
215
+ { name: "acceptedAccountNo", type: "uint256" },
216
+ { name: "assignedAccountNos", type: "uint256[]" },
217
+ { name: "currency", type: "bytes32" },
218
+ { name: "preferredPaymentChannelConfigId", type: "uint256" },
219
+ { name: "circleId", type: "uint256" }
220
+ ]
221
+ }
222
+ ]
223
+ },
224
+ {
225
+ type: "event",
226
+ name: "OrderCompleted",
227
+ anonymous: false,
228
+ inputs: [
229
+ { indexed: true, name: "orderId", type: "uint256" },
230
+ { indexed: true, name: "user", type: "address" },
231
+ { indexed: false, name: "completedTimestamp", type: "uint256" },
232
+ {
233
+ indexed: false,
234
+ name: "_order",
235
+ type: "tuple",
236
+ components: [
237
+ { name: "amount", type: "uint256" },
238
+ { name: "fiatAmount", type: "uint256" },
239
+ { name: "placedTimestamp", type: "uint256" },
240
+ { name: "completedTimestamp", type: "uint256" },
241
+ { name: "userCompletedTimestamp", type: "uint256" },
242
+ { name: "acceptedMerchant", type: "address" },
243
+ { name: "user", type: "address" },
244
+ { name: "recipientAddr", type: "address" },
245
+ { name: "pubkey", type: "string" },
246
+ { name: "encUpi", type: "string" },
247
+ { name: "userCompleted", type: "bool" },
248
+ { name: "status", type: "uint8" },
249
+ { name: "orderType", type: "uint8" },
250
+ {
251
+ name: "disputeInfo",
252
+ type: "tuple",
253
+ components: [
254
+ { name: "raisedBy", type: "uint8" },
255
+ { name: "status", type: "uint8" },
256
+ { name: "redactTransId", type: "uint256" },
257
+ { name: "accountNumber", type: "uint256" }
258
+ ]
259
+ },
260
+ { name: "id", type: "uint256" },
261
+ { name: "userPubKey", type: "string" },
262
+ { name: "encMerchantUpi", type: "string" },
263
+ { name: "acceptedAccountNo", type: "uint256" },
264
+ { name: "assignedAccountNos", type: "uint256[]" },
265
+ { name: "currency", type: "bytes32" },
266
+ { name: "preferredPaymentChannelConfigId", type: "uint256" },
267
+ { name: "circleId", type: "uint256" }
268
+ ]
269
+ }
270
+ ]
271
+ },
272
+ {
273
+ type: "event",
274
+ name: "CancelledOrders",
275
+ anonymous: false,
276
+ inputs: [
277
+ { indexed: true, name: "orderId", type: "uint256" },
278
+ {
279
+ indexed: false,
280
+ name: "_order",
281
+ type: "tuple",
282
+ components: [
283
+ { name: "amount", type: "uint256" },
284
+ { name: "fiatAmount", type: "uint256" },
285
+ { name: "placedTimestamp", type: "uint256" },
286
+ { name: "completedTimestamp", type: "uint256" },
287
+ { name: "userCompletedTimestamp", type: "uint256" },
288
+ { name: "acceptedMerchant", type: "address" },
289
+ { name: "user", type: "address" },
290
+ { name: "recipientAddr", type: "address" },
291
+ { name: "pubkey", type: "string" },
292
+ { name: "encUpi", type: "string" },
293
+ { name: "userCompleted", type: "bool" },
294
+ { name: "status", type: "uint8" },
295
+ { name: "orderType", type: "uint8" },
296
+ {
297
+ name: "disputeInfo",
298
+ type: "tuple",
299
+ components: [
300
+ { name: "raisedBy", type: "uint8" },
301
+ { name: "status", type: "uint8" },
302
+ { name: "redactTransId", type: "uint256" },
303
+ { name: "accountNumber", type: "uint256" }
304
+ ]
305
+ },
306
+ { name: "id", type: "uint256" },
307
+ { name: "userPubKey", type: "string" },
308
+ { name: "encMerchantUpi", type: "string" },
309
+ { name: "acceptedAccountNo", type: "uint256" },
310
+ { name: "assignedAccountNos", type: "uint256[]" },
311
+ { name: "currency", type: "bytes32" },
312
+ { name: "preferredPaymentChannelConfigId", type: "uint256" },
313
+ { name: "circleId", type: "uint256" }
314
+ ]
315
+ }
316
+ ]
317
+ }
318
+ ];
319
+
320
+ // src/contracts/abis/order-processor-facet.ts
321
+ var orderProcessorFacetAbi = [
322
+ {
323
+ type: "function",
324
+ name: "getOrdersById",
325
+ stateMutability: "view",
326
+ inputs: [{ name: "orderId", type: "uint256" }],
327
+ outputs: [
328
+ {
329
+ type: "tuple",
330
+ components: [
331
+ { name: "amount", type: "uint256" },
332
+ { name: "fiatAmount", type: "uint256" },
333
+ { name: "placedTimestamp", type: "uint256" },
334
+ { name: "completedTimestamp", type: "uint256" },
335
+ { name: "userCompletedTimestamp", type: "uint256" },
336
+ { name: "acceptedMerchant", type: "address" },
337
+ { name: "user", type: "address" },
338
+ { name: "recipientAddr", type: "address" },
339
+ { name: "pubkey", type: "string" },
340
+ { name: "encUpi", type: "string" },
341
+ { name: "userCompleted", type: "bool" },
342
+ { name: "status", type: "uint8" },
343
+ { name: "orderType", type: "uint8" },
344
+ {
345
+ name: "disputeInfo",
346
+ type: "tuple",
347
+ components: [
348
+ { name: "raisedBy", type: "uint8" },
349
+ { name: "status", type: "uint8" },
350
+ { name: "redactTransId", type: "uint256" },
351
+ { name: "accountNumber", type: "uint256" }
352
+ ]
353
+ },
354
+ { name: "id", type: "uint256" },
355
+ { name: "userPubKey", type: "string" },
356
+ { name: "encMerchantUpi", type: "string" },
357
+ { name: "acceptedAccountNo", type: "uint256" },
358
+ { name: "assignedAccountNos", type: "uint256[]" },
359
+ { name: "currency", type: "bytes32" },
360
+ { name: "preferredPaymentChannelConfigId", type: "uint256" },
361
+ { name: "circleId", type: "uint256" }
362
+ ]
363
+ }
364
+ ]
365
+ },
366
+ {
367
+ type: "function",
368
+ name: "getAdditionalOrderDetails",
369
+ stateMutability: "view",
370
+ inputs: [{ name: "orderId", type: "uint256" }],
371
+ outputs: [
372
+ {
373
+ type: "tuple",
374
+ components: [
375
+ { name: "fixedFeePaid", type: "uint64" },
376
+ { name: "tipsPaid", type: "uint64" },
377
+ { name: "acceptedTimestamp", type: "uint128" },
378
+ { name: "paidTimestamp", type: "uint128" },
379
+ { name: "reserved2", type: "uint128" },
380
+ { name: "actualUsdtAmount", type: "uint256" },
381
+ { name: "actualFiatAmount", type: "uint256" }
382
+ ]
383
+ }
384
+ ]
385
+ },
386
+ {
387
+ type: "function",
388
+ name: "getSmallOrderThreshold",
389
+ stateMutability: "view",
390
+ inputs: [{ name: "currency", type: "bytes32" }],
391
+ outputs: [{ name: "", type: "uint256" }]
392
+ },
393
+ {
394
+ type: "function",
395
+ name: "getSmallOrderFixedFee",
396
+ stateMutability: "view",
397
+ inputs: [{ name: "currency", type: "bytes32" }],
398
+ outputs: [{ name: "", type: "uint256" }]
399
+ },
400
+ {
401
+ type: "function",
402
+ name: "raiseDispute",
403
+ stateMutability: "nonpayable",
404
+ inputs: [
405
+ { name: "_orderId", type: "uint256" },
406
+ { name: "redactTransId", type: "uint256" }
407
+ ],
408
+ outputs: []
409
+ },
410
+ {
411
+ type: "function",
412
+ name: "paidBuyOrder",
413
+ stateMutability: "nonpayable",
414
+ inputs: [{ name: "_orderId", type: "uint256" }],
415
+ outputs: []
416
+ }
417
+ ];
418
+
419
+ // src/contracts/abis/p2p-config-facet.ts
420
+ var p2pConfigFacetAbi = [
421
+ {
422
+ inputs: [
423
+ {
424
+ internalType: "bytes32",
425
+ name: "_currency",
426
+ type: "bytes32"
427
+ }
428
+ ],
429
+ name: "getPriceConfig",
430
+ outputs: [
431
+ {
432
+ components: [
433
+ {
434
+ internalType: "uint256",
435
+ name: "buyPrice",
436
+ type: "uint256"
437
+ },
438
+ {
439
+ internalType: "uint256",
440
+ name: "sellPrice",
441
+ type: "uint256"
442
+ },
443
+ {
444
+ internalType: "int256",
445
+ name: "buyPriceOffset",
446
+ type: "int256"
447
+ },
448
+ {
449
+ internalType: "uint256",
450
+ name: "baseSpread",
451
+ type: "uint256"
452
+ }
453
+ ],
454
+ internalType: "struct P2pConfigStorage.PriceConfig",
455
+ name: "",
456
+ type: "tuple"
457
+ }
458
+ ],
459
+ stateMutability: "view",
460
+ type: "function"
461
+ },
462
+ {
463
+ inputs: [
464
+ {
465
+ internalType: "bytes32",
466
+ name: "_nativeCurrency",
467
+ type: "bytes32"
468
+ }
469
+ ],
470
+ name: "getRpPerUsdtLimitRational",
471
+ outputs: [
472
+ {
473
+ internalType: "uint256",
474
+ name: "numerator",
475
+ type: "uint256"
476
+ },
477
+ {
478
+ internalType: "uint256",
479
+ name: "denominator",
480
+ type: "uint256"
481
+ }
482
+ ],
483
+ stateMutability: "view",
484
+ type: "function"
485
+ }
486
+ ];
487
+
488
+ // src/contracts/abis/reputation-manager.ts
489
+ var reputationManagerAbi = [
490
+ {
491
+ inputs: [
492
+ {
493
+ internalType: "string",
494
+ name: "_socialName",
495
+ type: "string"
496
+ },
497
+ {
498
+ components: [
499
+ {
500
+ components: [
501
+ {
502
+ internalType: "string",
503
+ name: "provider",
504
+ type: "string"
505
+ },
506
+ {
507
+ internalType: "string",
508
+ name: "parameters",
509
+ type: "string"
510
+ },
511
+ {
512
+ internalType: "string",
513
+ name: "context",
514
+ type: "string"
515
+ }
516
+ ],
517
+ internalType: "struct IReclaimSDK.ClaimInfo",
518
+ name: "claimInfo",
519
+ type: "tuple"
520
+ },
521
+ {
522
+ components: [
523
+ {
524
+ components: [
525
+ {
526
+ internalType: "bytes32",
527
+ name: "identifier",
528
+ type: "bytes32"
529
+ },
530
+ {
531
+ internalType: "address",
532
+ name: "owner",
533
+ type: "address"
534
+ },
535
+ {
536
+ internalType: "uint32",
537
+ name: "timestampS",
538
+ type: "uint32"
539
+ },
540
+ {
541
+ internalType: "uint32",
542
+ name: "epoch",
543
+ type: "uint32"
544
+ }
545
+ ],
546
+ internalType: "struct IReclaimSDK.CompleteClaimData",
547
+ name: "claim",
548
+ type: "tuple"
549
+ },
550
+ {
551
+ internalType: "bytes[]",
552
+ name: "signatures",
553
+ type: "bytes[]"
554
+ }
555
+ ],
556
+ internalType: "struct IReclaimSDK.SignedClaim",
557
+ name: "signedClaim",
558
+ type: "tuple"
559
+ }
560
+ ],
561
+ internalType: "struct IReclaimSDK.Proof[]",
562
+ name: "proofs",
563
+ type: "tuple[]"
564
+ }
565
+ ],
566
+ name: "socialVerify",
567
+ outputs: [],
568
+ stateMutability: "nonpayable",
569
+ type: "function"
570
+ },
571
+ {
572
+ inputs: [
573
+ {
574
+ internalType: "uint256",
575
+ name: "nullifierSeed",
576
+ type: "uint256"
577
+ },
578
+ {
579
+ internalType: "uint256",
580
+ name: "nullifier",
581
+ type: "uint256"
582
+ },
583
+ {
584
+ internalType: "uint256",
585
+ name: "timestamp",
586
+ type: "uint256"
587
+ },
588
+ {
589
+ internalType: "uint256",
590
+ name: "signal",
591
+ type: "uint256"
592
+ },
593
+ {
594
+ internalType: "uint256[4]",
595
+ name: "revealArray",
596
+ type: "uint256[4]"
597
+ },
598
+ {
599
+ internalType: "uint256[8]",
600
+ name: "groth16Proof",
601
+ type: "uint256[8]"
602
+ }
603
+ ],
604
+ name: "submitAnonAadharProof",
605
+ outputs: [],
606
+ stateMutability: "nonpayable",
607
+ type: "function"
608
+ },
609
+ {
610
+ inputs: [
611
+ {
612
+ components: [
613
+ {
614
+ internalType: "bytes32",
615
+ name: "version",
616
+ type: "bytes32"
617
+ },
618
+ {
619
+ components: [
620
+ {
621
+ internalType: "bytes32",
622
+ name: "vkeyHash",
623
+ type: "bytes32"
624
+ },
625
+ {
626
+ internalType: "bytes",
627
+ name: "proof",
628
+ type: "bytes"
629
+ },
630
+ {
631
+ internalType: "bytes32[]",
632
+ name: "publicInputs",
633
+ type: "bytes32[]"
634
+ }
635
+ ],
636
+ internalType: "struct ProofVerificationData",
637
+ name: "proofVerificationData",
638
+ type: "tuple"
639
+ },
640
+ {
641
+ internalType: "bytes",
642
+ name: "committedInputs",
643
+ type: "bytes"
644
+ },
645
+ {
646
+ components: [
647
+ {
648
+ internalType: "uint256",
649
+ name: "validityPeriodInSeconds",
650
+ type: "uint256"
651
+ },
652
+ {
653
+ internalType: "string",
654
+ name: "domain",
655
+ type: "string"
656
+ },
657
+ {
658
+ internalType: "string",
659
+ name: "scope",
660
+ type: "string"
661
+ },
662
+ {
663
+ internalType: "bool",
664
+ name: "devMode",
665
+ type: "bool"
666
+ }
667
+ ],
668
+ internalType: "struct ServiceConfig",
669
+ name: "serviceConfig",
670
+ type: "tuple"
671
+ }
672
+ ],
673
+ internalType: "struct ProofVerificationParams",
674
+ name: "params",
675
+ type: "tuple"
676
+ },
677
+ {
678
+ internalType: "bool",
679
+ name: "isIDCard",
680
+ type: "bool"
681
+ }
682
+ ],
683
+ name: "zkPassportRegister",
684
+ outputs: [],
685
+ stateMutability: "nonpayable",
686
+ type: "function"
687
+ }
688
+ ];
689
+
690
+ // src/contracts/abis/index.ts
691
+ var DIAMOND_ABI = [
692
+ ...orderFlowFacetAbi,
693
+ ...orderProcessorFacetAbi,
694
+ ...p2pConfigFacetAbi
695
+ ];
696
+ var ABIS = {
697
+ DIAMOND: DIAMOND_ABI,
698
+ FACETS: {
699
+ ORDER_FLOW: orderFlowFacetAbi,
700
+ ORDER_PROCESSOR: orderProcessorFacetAbi,
701
+ CONFIG: p2pConfigFacetAbi
702
+ },
703
+ EXTERNAL: {
704
+ USDC: erc20Abi,
705
+ REPUTATION_MANAGER: reputationManagerAbi
706
+ }
16
707
  };
17
708
 
18
- // src/constants/orders.constant.ts
19
- var ORDER_TYPE = {
20
- BUY: 0,
21
- SELL: 1,
22
- PAY: 2
709
+ // src/contracts/order-processor/index.ts
710
+ function readOrderMulticall(publicClient, diamondAddress, orderId) {
711
+ const calls = [
712
+ {
713
+ address: diamondAddress,
714
+ abi: ABIS.FACETS.ORDER_PROCESSOR,
715
+ functionName: "getOrdersById",
716
+ args: [orderId]
717
+ },
718
+ {
719
+ address: diamondAddress,
720
+ abi: ABIS.FACETS.ORDER_PROCESSOR,
721
+ functionName: "getAdditionalOrderDetails",
722
+ args: [orderId]
723
+ }
724
+ ];
725
+ const toError = (error) => new Error("Order contract read failed", { cause: error });
726
+ const exec = async () => {
727
+ if (publicClient.multicall) {
728
+ const [order2, details2] = await publicClient.multicall({
729
+ contracts: calls,
730
+ allowFailure: false
731
+ });
732
+ return { order: order2, details: details2 };
733
+ }
734
+ const [order, details] = await Promise.all(
735
+ calls.map((c) => publicClient.readContract(c))
736
+ );
737
+ return { order, details };
738
+ };
739
+ return ResultAsync.fromPromise(exec(), toError);
740
+ }
741
+ function readFeeConfigMulticall(publicClient, diamondAddress, currency) {
742
+ const currencyHex = stringToHex(currency, { size: 32 });
743
+ const calls = [
744
+ {
745
+ address: diamondAddress,
746
+ abi: ABIS.FACETS.ORDER_PROCESSOR,
747
+ functionName: "getSmallOrderThreshold",
748
+ args: [currencyHex]
749
+ },
750
+ {
751
+ address: diamondAddress,
752
+ abi: ABIS.FACETS.ORDER_PROCESSOR,
753
+ functionName: "getSmallOrderFixedFee",
754
+ args: [currencyHex]
755
+ }
756
+ ];
757
+ const toError = (error) => new Error("Fee config contract read failed", { cause: error });
758
+ const exec = async () => {
759
+ if (publicClient.multicall) {
760
+ const [smallOrderThreshold2, smallOrderFixedFee2] = await publicClient.multicall({
761
+ contracts: calls,
762
+ allowFailure: false
763
+ });
764
+ return { smallOrderThreshold: smallOrderThreshold2, smallOrderFixedFee: smallOrderFixedFee2 };
765
+ }
766
+ const [smallOrderThreshold, smallOrderFixedFee] = await Promise.all(
767
+ calls.map((c) => publicClient.readContract(c))
768
+ );
769
+ return { smallOrderThreshold, smallOrderFixedFee };
770
+ };
771
+ return ResultAsync.fromPromise(exec(), toError);
772
+ }
773
+
774
+ // src/lib/logger.ts
775
+ var noop = () => {
776
+ };
777
+ var noopLogger = {
778
+ debug: noop,
779
+ info: noop,
780
+ warn: noop,
781
+ error: noop
23
782
  };
24
783
 
784
+ // src/lib/sleep.ts
785
+ function sleep(ms) {
786
+ return new Promise((resolve) => setTimeout(resolve, ms));
787
+ }
788
+
789
+ // src/lib/subgraph.ts
790
+ import { ResultAsync as ResultAsync2 } from "neverthrow";
791
+
25
792
  // src/validation/errors.validation.ts
26
793
  var SdkError = class extends Error {
27
794
  code;
@@ -40,8 +807,25 @@ var SdkError = class extends Error {
40
807
  import { err, ok } from "neverthrow";
41
808
  import { isAddress } from "viem";
42
809
  import { z } from "zod";
810
+
811
+ // src/country/currency.ts
812
+ var CURRENCY = {
813
+ IDR: "IDR",
814
+ INR: "INR",
815
+ BRL: "BRL",
816
+ ARS: "ARS",
817
+ MEX: "MEX",
818
+ VEN: "VEN",
819
+ EUR: "EUR",
820
+ NGN: "NGN",
821
+ USD: "USD",
822
+ COP: "COP"
823
+ };
824
+ var CURRENCY_CODES = Object.values(CURRENCY);
825
+
826
+ // src/validation/schemas.validation.ts
43
827
  var ZodAddressSchema = z.string().refine((s) => isAddress(s), { message: "Invalid Ethereum address" });
44
- var ZodCurrencySchema = z.enum(Object.values(CURRENCY));
828
+ var ZodCurrencySchema = z.enum(CURRENCY_CODES);
45
829
  function validate(schema, data, toError) {
46
830
  const result = schema.safeParse(data);
47
831
  if (result.success) {
@@ -50,11 +834,600 @@ function validate(schema, data, toError) {
50
834
  return err(toError(z.prettifyError(result.error), result.error, data));
51
835
  }
52
836
 
53
- // src/payload/crypto.ts
54
- import { ok as ok3, Result, ResultAsync, safeTry } from "neverthrow";
55
- import { keccak256, serializeSignature, stringToHex } from "viem";
56
- import { sign } from "viem/accounts";
837
+ // src/lib/subgraph.ts
838
+ var DEFAULT_TIMEOUT_MS = 1e4;
839
+ var MAX_RETRIES = 3;
840
+ var BACKOFF_MS = 500;
841
+ var SubgraphError = class extends SdkError {
842
+ constructor(message, options) {
843
+ super(message, options);
844
+ this.name = "SubgraphError";
845
+ }
846
+ };
847
+ function isTransient(error) {
848
+ if (error instanceof SubgraphError) {
849
+ if (error.code !== "HTTP_ERROR") return false;
850
+ const status = error.context?.status;
851
+ return typeof status === "number" && status >= 500;
852
+ }
853
+ if (error instanceof DOMException && error.name === "AbortError") return true;
854
+ if (error instanceof TypeError) return true;
855
+ return false;
856
+ }
857
+ function querySubgraph(url, params) {
858
+ const timeoutMs = params.timeoutMs ?? DEFAULT_TIMEOUT_MS;
859
+ const fetchOnce = async () => {
860
+ const controller = new AbortController();
861
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
862
+ try {
863
+ const response = await fetch(url, {
864
+ method: "POST",
865
+ headers: { "Content-Type": "application/json" },
866
+ body: JSON.stringify({
867
+ query: params.query,
868
+ variables: params.variables
869
+ }),
870
+ signal: controller.signal
871
+ });
872
+ if (!response.ok) {
873
+ throw new SubgraphError(`Subgraph request failed (status: ${response.status})`, {
874
+ code: "HTTP_ERROR",
875
+ cause: response,
876
+ context: { status: response.status }
877
+ });
878
+ }
879
+ const json = await response.json();
880
+ if (json.errors?.length > 0) {
881
+ throw new SubgraphError("Subgraph returned GraphQL errors", {
882
+ code: "GRAPHQL_ERROR",
883
+ cause: json.errors,
884
+ context: { errors: json.errors }
885
+ });
886
+ }
887
+ if (!json.data) {
888
+ throw new SubgraphError("Subgraph returned no data", {
889
+ code: "NO_DATA",
890
+ cause: "Missing data field in GraphQL response",
891
+ context: { response: json }
892
+ });
893
+ }
894
+ return json.data;
895
+ } finally {
896
+ clearTimeout(timer);
897
+ }
898
+ };
899
+ const fetchWithRetry = async () => {
900
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
901
+ try {
902
+ return await fetchOnce();
903
+ } catch (error) {
904
+ const lastAttempt = attempt === MAX_RETRIES;
905
+ if (lastAttempt || !isTransient(error)) throw error;
906
+ await sleep(BACKOFF_MS * (attempt + 1));
907
+ }
908
+ }
909
+ throw new SubgraphError("Subgraph query exhausted retries", { code: "TRANSPORT_ERROR" });
910
+ };
911
+ return ResultAsync2.fromPromise(
912
+ fetchWithRetry(),
913
+ (error) => error instanceof SubgraphError ? error : new SubgraphError("Subgraph query failed", {
914
+ code: "TRANSPORT_ERROR",
915
+ cause: error
916
+ })
917
+ );
918
+ }
919
+
920
+ // src/orders/actions/approve-usdc.ts
921
+ import { encodeFunctionData, erc20Abi as erc20Abi2 } from "viem";
922
+
923
+ // src/orders/errors.ts
924
+ var OrdersError = class extends SdkError {
925
+ constructor(message, options) {
926
+ super(message, options);
927
+ this.name = "OrdersError";
928
+ }
929
+ };
930
+
931
+ // src/orders/tx.ts
932
+ import { errAsync, okAsync, ResultAsync as ResultAsync3 } from "neverthrow";
933
+ function submitPreparedTx(input) {
934
+ const { prepared, walletClient, publicClient, waitForReceipt, extraMeta } = input;
935
+ const account = walletClient.account;
936
+ if (!account) {
937
+ return errAsync(
938
+ new OrdersError("WalletClient is missing an account", {
939
+ code: "TX_SUBMISSION_FAILED"
940
+ })
941
+ );
942
+ }
943
+ const chain = walletClient.chain;
944
+ return ResultAsync3.fromPromise(
945
+ walletClient.sendTransaction({
946
+ account,
947
+ chain,
948
+ to: prepared.to,
949
+ data: prepared.data,
950
+ value: prepared.value
951
+ }),
952
+ (cause) => new OrdersError("walletClient.sendTransaction rejected", {
953
+ code: "TX_SUBMISSION_FAILED",
954
+ cause
955
+ })
956
+ ).andThen((hash) => {
957
+ const combinedMeta = prepared.meta || extraMeta ? { ...prepared.meta, ...extraMeta } : void 0;
958
+ if (!waitForReceipt) {
959
+ return okAsync({ hash, meta: combinedMeta });
960
+ }
961
+ return ResultAsync3.fromPromise(
962
+ publicClient.waitForTransactionReceipt({ hash }),
963
+ (cause) => new OrdersError("waitForTransactionReceipt failed", {
964
+ code: "RECEIPT_TIMEOUT",
965
+ cause
966
+ })
967
+ ).andThen((receipt) => {
968
+ if (receipt.status !== "success") {
969
+ return errAsync(
970
+ new OrdersError("Transaction reverted", {
971
+ code: "TX_REVERTED",
972
+ context: { hash, blockNumber: receipt.blockNumber.toString() }
973
+ })
974
+ );
975
+ }
976
+ return okAsync({ hash, receipt, meta: combinedMeta });
977
+ });
978
+ });
979
+ }
980
+
981
+ // src/orders/validation.ts
982
+ import { z as z2 } from "zod";
983
+ var ZodGetOrderParamsSchema = z2.object({
984
+ orderId: z2.bigint().positive()
985
+ });
986
+ var ZodGetFeeConfigParamsSchema = z2.object({
987
+ currency: ZodCurrencySchema
988
+ });
989
+ var ZodGetOrdersParamsSchema = z2.object({
990
+ userAddress: ZodAddressSchema,
991
+ skip: z2.number().int().min(0).default(0),
992
+ limit: z2.number().int().min(1).max(100).default(20)
993
+ });
994
+ var ZodPlaceOrderParamsSchema = z2.object({
995
+ orderType: z2.number().int().min(0).max(2),
996
+ currency: ZodCurrencySchema,
997
+ user: ZodAddressSchema,
998
+ amount: z2.bigint(),
999
+ fiatAmount: z2.bigint(),
1000
+ fiatAmountLimit: z2.bigint().optional().default(0n),
1001
+ recipientAddr: ZodAddressSchema,
1002
+ preferredPaymentChannelConfigId: z2.bigint().optional(),
1003
+ pubKey: z2.string().optional()
1004
+ });
1005
+ var ZodCancelOrderParamsSchema = z2.object({
1006
+ orderId: z2.bigint().nonnegative()
1007
+ });
1008
+ var ZodSetSellOrderUpiParamsSchema = z2.object({
1009
+ orderId: z2.bigint().nonnegative(),
1010
+ paymentAddress: z2.string().min(1),
1011
+ merchantPublicKey: z2.string().min(1),
1012
+ updatedAmount: z2.bigint()
1013
+ });
1014
+ var ZodRaiseDisputeParamsSchema = z2.object({
1015
+ orderId: z2.bigint().nonnegative(),
1016
+ redactTransId: z2.bigint().nonnegative()
1017
+ });
1018
+ var ZodApproveUsdcParamsSchema = z2.object({
1019
+ amount: z2.bigint().nonnegative()
1020
+ });
1021
+ var ZodPaidBuyOrderParamsSchema = z2.object({
1022
+ orderId: z2.bigint().nonnegative()
1023
+ });
1024
+ var HexString = z2.string().regex(/^0x[0-9a-fA-F]*$/, "Expected 0x-prefixed hex");
1025
+ var ZodSubgraphOrderSchema = z2.object({
1026
+ orderId: z2.string(),
1027
+ type: z2.number().int().min(0),
1028
+ status: z2.number().int().min(0),
1029
+ circleId: z2.string(),
1030
+ userAddress: HexString,
1031
+ usdcRecipientAddress: HexString,
1032
+ acceptedMerchantAddress: HexString,
1033
+ usdcAmount: z2.string(),
1034
+ fiatAmount: z2.string(),
1035
+ actualUsdcAmount: z2.string(),
1036
+ actualFiatAmount: z2.string(),
1037
+ currency: HexString,
1038
+ placedAt: z2.string(),
1039
+ acceptedAt: z2.string(),
1040
+ paidAt: z2.string(),
1041
+ completedAt: z2.string(),
1042
+ fixedFeePaid: z2.string(),
1043
+ tipsPaid: z2.string(),
1044
+ disputeStatus: z2.number().int().min(0)
1045
+ });
1046
+ var ZodSubgraphOrdersResponseSchema = z2.object({
1047
+ orders_collection: z2.array(ZodSubgraphOrderSchema)
1048
+ });
1049
+
1050
+ // src/orders/actions/approve-usdc.ts
1051
+ function createApproveUsdcAction(input) {
1052
+ const { publicClient, diamondAddress, usdcAddress } = input;
1053
+ const prepareFn = (params) => validate(
1054
+ ZodApproveUsdcParamsSchema,
1055
+ params,
1056
+ (message, cause, data) => new OrdersError(message, {
1057
+ code: "VALIDATION_ERROR",
1058
+ cause,
1059
+ context: { data }
1060
+ })
1061
+ ).map(({ amount }) => ({
1062
+ to: usdcAddress,
1063
+ data: encodeFunctionData({
1064
+ abi: erc20Abi2,
1065
+ functionName: "approve",
1066
+ args: [diamondAddress, amount]
1067
+ }),
1068
+ value: 0n
1069
+ }));
1070
+ return {
1071
+ prepare(params) {
1072
+ return prepareFn(params).asyncMap(async (tx) => tx);
1073
+ },
1074
+ execute({ walletClient, waitForReceipt, ...params }) {
1075
+ return prepareFn(params).asyncAndThen(
1076
+ (prepared) => submitPreparedTx({ prepared, walletClient, publicClient, waitForReceipt })
1077
+ );
1078
+ }
1079
+ };
1080
+ }
1081
+
1082
+ // src/orders/actions/cancel-order.ts
1083
+ import { encodeFunctionData as encodeFunctionData2 } from "viem";
1084
+ function createCancelOrderAction(input) {
1085
+ const { publicClient, diamondAddress } = input;
1086
+ const prepareFn = (params) => validate(
1087
+ ZodCancelOrderParamsSchema,
1088
+ params,
1089
+ (message, cause, data) => new OrdersError(message, {
1090
+ code: "VALIDATION_ERROR",
1091
+ cause,
1092
+ context: { data }
1093
+ })
1094
+ ).map(({ orderId }) => ({
1095
+ to: diamondAddress,
1096
+ data: encodeFunctionData2({
1097
+ abi: ABIS.FACETS.ORDER_FLOW,
1098
+ functionName: "cancelOrder",
1099
+ args: [orderId]
1100
+ }),
1101
+ value: 0n
1102
+ }));
1103
+ return {
1104
+ prepare(params) {
1105
+ return prepareFn(params).asyncMap(async (tx) => tx);
1106
+ },
1107
+ execute({ walletClient, waitForReceipt, ...params }) {
1108
+ return prepareFn(params).asyncAndThen(
1109
+ (prepared) => submitPreparedTx({ prepared, walletClient, publicClient, waitForReceipt })
1110
+ );
1111
+ }
1112
+ };
1113
+ }
1114
+
1115
+ // src/orders/actions/paid-buy-order.ts
1116
+ import { encodeFunctionData as encodeFunctionData3 } from "viem";
1117
+ function createPaidBuyOrderAction(input) {
1118
+ const { publicClient, diamondAddress } = input;
1119
+ const prepareFn = (params) => validate(
1120
+ ZodPaidBuyOrderParamsSchema,
1121
+ params,
1122
+ (message, cause, data) => new OrdersError(message, {
1123
+ code: "VALIDATION_ERROR",
1124
+ cause,
1125
+ context: { data }
1126
+ })
1127
+ ).map(({ orderId }) => ({
1128
+ to: diamondAddress,
1129
+ data: encodeFunctionData3({
1130
+ abi: ABIS.FACETS.ORDER_PROCESSOR,
1131
+ functionName: "paidBuyOrder",
1132
+ args: [orderId]
1133
+ }),
1134
+ value: 0n
1135
+ }));
1136
+ return {
1137
+ prepare(params) {
1138
+ return prepareFn(params).asyncMap(async (tx) => tx);
1139
+ },
1140
+ execute({ walletClient, waitForReceipt, ...params }) {
1141
+ return prepareFn(params).asyncAndThen(
1142
+ (prepared) => submitPreparedTx({ prepared, walletClient, publicClient, waitForReceipt })
1143
+ );
1144
+ }
1145
+ };
1146
+ }
1147
+
1148
+ // src/orders/actions/place-order.ts
1149
+ import { encodeFunctionData as encodeFunctionData4, parseEventLogs, stringToHex as stringToHex2 } from "viem";
1150
+
1151
+ // src/constants/orders.constant.ts
1152
+ var ORDER_TYPE = {
1153
+ BUY: 0,
1154
+ SELL: 1,
1155
+ PAY: 2
1156
+ };
1157
+ var ORDER_STATUS = {
1158
+ PLACED: 0,
1159
+ ACCEPTED: 1,
1160
+ PAID: 2,
1161
+ COMPLETED: 3,
1162
+ CANCELLED: 4
1163
+ };
1164
+ var DISPUTE_STATUS = {
1165
+ NONE: 0,
1166
+ OPEN: 1,
1167
+ RESOLVED: 2
1168
+ };
1169
+
1170
+ // src/orders/relay-identity/identity.ts
1171
+ import { isAddress as isAddress2, isHex } from "viem";
1172
+ import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
57
1173
  import { z as z3 } from "zod";
1174
+ var ZodRelayIdentitySchema = z3.object({
1175
+ address: z3.string().refine(isAddress2, { message: "Invalid relay identity address" }),
1176
+ publicKey: z3.string().refine((v) => isHex(`0x${v}`), {
1177
+ message: "Invalid relay identity public key"
1178
+ }),
1179
+ privateKey: z3.string().refine(isHex, { message: "Invalid relay identity private key" })
1180
+ });
1181
+ function createRelayIdentity() {
1182
+ const privateKey = generatePrivateKey();
1183
+ const account = privateKeyToAccount(privateKey);
1184
+ const publicKey = account.publicKey.slice(4);
1185
+ return {
1186
+ address: account.address,
1187
+ publicKey,
1188
+ privateKey
1189
+ };
1190
+ }
1191
+
1192
+ // src/orders/relay-identity/resolve.ts
1193
+ import { err as err2, ok as ok2, okAsync as okAsync2, ResultAsync as ResultAsync4 } from "neverthrow";
1194
+
1195
+ // src/orders/relay-identity/stores.ts
1196
+ var RelayIdentityCorruptError = class extends Error {
1197
+ constructor(cause) {
1198
+ super("Stored relay identity is corrupt", { cause });
1199
+ this.name = "RelayIdentityCorruptError";
1200
+ }
1201
+ };
1202
+ function createInMemoryRelayStore() {
1203
+ let value = null;
1204
+ return {
1205
+ async get() {
1206
+ return value;
1207
+ },
1208
+ async set(identity) {
1209
+ value = identity;
1210
+ }
1211
+ };
1212
+ }
1213
+ var DEFAULT_KEY = "@P2PME:RELAY_IDENTITY";
1214
+ function createLocalStorageRelayStore(options = {}) {
1215
+ const key = options.key ?? DEFAULT_KEY;
1216
+ return {
1217
+ async get() {
1218
+ const raw = localStorage.getItem(key);
1219
+ if (!raw) return null;
1220
+ try {
1221
+ return JSON.parse(raw);
1222
+ } catch (cause) {
1223
+ throw new RelayIdentityCorruptError(cause);
1224
+ }
1225
+ },
1226
+ async set(identity) {
1227
+ localStorage.setItem(key, JSON.stringify(identity));
1228
+ }
1229
+ };
1230
+ }
1231
+
1232
+ // src/orders/relay-identity/resolve.ts
1233
+ var pending = /* @__PURE__ */ new WeakMap();
1234
+ async function resolveFromStore(store) {
1235
+ let stored;
1236
+ try {
1237
+ stored = await store.get();
1238
+ } catch (cause) {
1239
+ if (cause instanceof RelayIdentityCorruptError) {
1240
+ return err2(
1241
+ new OrdersError("Stored relay identity is corrupt", {
1242
+ code: "RELAY_IDENTITY_CORRUPT",
1243
+ cause: cause.cause
1244
+ })
1245
+ );
1246
+ }
1247
+ return err2(
1248
+ new OrdersError("Relay identity store.get failed", {
1249
+ code: "RELAY_IDENTITY_STORE_FAILED",
1250
+ cause
1251
+ })
1252
+ );
1253
+ }
1254
+ if (stored !== null) {
1255
+ const parsed = ZodRelayIdentitySchema.safeParse(stored);
1256
+ if (!parsed.success) {
1257
+ return err2(
1258
+ new OrdersError("Stored relay identity failed validation", {
1259
+ code: "RELAY_IDENTITY_CORRUPT",
1260
+ cause: parsed.error
1261
+ })
1262
+ );
1263
+ }
1264
+ return ok2(stored);
1265
+ }
1266
+ const fresh = createRelayIdentity();
1267
+ try {
1268
+ await store.set(fresh);
1269
+ } catch (cause) {
1270
+ return err2(
1271
+ new OrdersError("Relay identity store.set failed", {
1272
+ code: "RELAY_IDENTITY_STORE_FAILED",
1273
+ cause
1274
+ })
1275
+ );
1276
+ }
1277
+ return ok2(fresh);
1278
+ }
1279
+ function resolveRelayIdentity(input) {
1280
+ if (input.relayIdentity) {
1281
+ return okAsync2(input.relayIdentity);
1282
+ }
1283
+ const existing = pending.get(input.store);
1284
+ if (existing) {
1285
+ return ResultAsync4.fromSafePromise(existing).andThen((r) => r);
1286
+ }
1287
+ const promise = resolveFromStore(input.store).finally(() => {
1288
+ pending.delete(input.store);
1289
+ });
1290
+ pending.set(input.store, promise);
1291
+ return ResultAsync4.fromSafePromise(promise).andThen((r) => r);
1292
+ }
1293
+
1294
+ // src/orders/actions/place-order.ts
1295
+ function enrichWithOrderId(result, userAddress) {
1296
+ if (!result.receipt) return result;
1297
+ try {
1298
+ const events = parseEventLogs({
1299
+ abi: ABIS.FACETS.ORDER_FLOW,
1300
+ eventName: "OrderPlaced",
1301
+ logs: result.receipt.logs
1302
+ });
1303
+ const lowered = userAddress.toLowerCase();
1304
+ const mine = events.find((e) => e.args.user?.toLowerCase() === lowered);
1305
+ const chosen = mine ?? events[0];
1306
+ if (!chosen) return result;
1307
+ const orderId = chosen.args.orderId;
1308
+ if (orderId === void 0) return result;
1309
+ return { ...result, meta: { ...result.meta, orderId } };
1310
+ } catch {
1311
+ return result;
1312
+ }
1313
+ }
1314
+ function createPlaceOrderAction(input) {
1315
+ const { publicClient, diamondAddress, orderRouter, relayIdentityStore, relayIdentity } = input;
1316
+ const prepareFn = (params) => validate(
1317
+ ZodPlaceOrderParamsSchema,
1318
+ params,
1319
+ (message, cause, data) => new OrdersError(message, {
1320
+ code: "VALIDATION_ERROR",
1321
+ cause,
1322
+ context: { data }
1323
+ })
1324
+ ).asyncAndThen((v) => {
1325
+ const pcConfigId = v.preferredPaymentChannelConfigId ?? 0n;
1326
+ const circleResult = orderRouter.selectCircle({
1327
+ currency: v.currency,
1328
+ user: v.user,
1329
+ usdtAmount: v.amount,
1330
+ fiatAmount: v.fiatAmount,
1331
+ orderType: BigInt(v.orderType),
1332
+ preferredPCConfigId: pcConfigId
1333
+ }).mapErr(
1334
+ (cause) => new OrdersError(`Circle selection failed: ${cause.message}`, {
1335
+ code: "CIRCLE_SELECTION_FAILED",
1336
+ cause
1337
+ })
1338
+ );
1339
+ const identityResult = resolveRelayIdentity({
1340
+ relayIdentity,
1341
+ store: relayIdentityStore
1342
+ });
1343
+ return identityResult.andThen(
1344
+ (senderIdentity) => circleResult.map((circleId) => {
1345
+ const isBuy = v.orderType === ORDER_TYPE.BUY;
1346
+ const keyFromCaller = v.pubKey ?? senderIdentity.publicKey;
1347
+ const pubKey = isBuy ? keyFromCaller : "";
1348
+ const userPubKey = isBuy ? "" : keyFromCaller;
1349
+ const currencyBytes32 = stringToHex2(v.currency, { size: 32 });
1350
+ const data = encodeFunctionData4({
1351
+ abi: ABIS.FACETS.ORDER_FLOW,
1352
+ functionName: "placeOrder",
1353
+ args: [
1354
+ pubKey,
1355
+ v.amount,
1356
+ v.recipientAddr,
1357
+ v.orderType,
1358
+ "",
1359
+ // _userUpi — set later via setSellOrderUpi if applicable
1360
+ userPubKey,
1361
+ currencyBytes32,
1362
+ pcConfigId,
1363
+ circleId,
1364
+ v.fiatAmountLimit ?? 0n
1365
+ ]
1366
+ });
1367
+ return {
1368
+ to: diamondAddress,
1369
+ data,
1370
+ value: 0n,
1371
+ meta: { circleId, relayIdentity: senderIdentity }
1372
+ };
1373
+ })
1374
+ );
1375
+ });
1376
+ return {
1377
+ prepare(params) {
1378
+ return prepareFn(params);
1379
+ },
1380
+ execute({ walletClient, waitForReceipt, ...params }) {
1381
+ const owner = walletClient.account?.address;
1382
+ const enrich = (r) => owner ? enrichWithOrderId(r, owner) : r;
1383
+ return prepareFn(params).andThen(
1384
+ (prepared) => submitPreparedTx({ prepared, walletClient, publicClient, waitForReceipt }).map(enrich)
1385
+ );
1386
+ }
1387
+ };
1388
+ }
1389
+
1390
+ // src/orders/actions/raise-dispute.ts
1391
+ import { encodeFunctionData as encodeFunctionData5 } from "viem";
1392
+ function createRaiseDisputeAction(input) {
1393
+ const { publicClient, diamondAddress } = input;
1394
+ const prepareFn = (params) => validate(
1395
+ ZodRaiseDisputeParamsSchema,
1396
+ params,
1397
+ (message, cause, data) => new OrdersError(message, {
1398
+ code: "VALIDATION_ERROR",
1399
+ cause,
1400
+ context: { data }
1401
+ })
1402
+ ).map(({ orderId, redactTransId }) => ({
1403
+ to: diamondAddress,
1404
+ data: encodeFunctionData5({
1405
+ abi: ABIS.FACETS.ORDER_PROCESSOR,
1406
+ functionName: "raiseDispute",
1407
+ args: [orderId, redactTransId]
1408
+ }),
1409
+ value: 0n
1410
+ }));
1411
+ return {
1412
+ prepare(params) {
1413
+ return prepareFn(params).asyncMap(async (tx) => tx);
1414
+ },
1415
+ execute({ walletClient, waitForReceipt, ...params }) {
1416
+ return prepareFn(params).asyncAndThen(
1417
+ (prepared) => submitPreparedTx({ prepared, walletClient, publicClient, waitForReceipt })
1418
+ );
1419
+ }
1420
+ };
1421
+ }
1422
+
1423
+ // src/orders/actions/set-sell-order-upi.ts
1424
+ import { encodeFunctionData as encodeFunctionData6 } from "viem";
1425
+
1426
+ // src/orders/crypto/encryption.ts
1427
+ import { ok as ok3, Result, ResultAsync as ResultAsync5, safeTry } from "neverthrow";
1428
+ import { keccak256, serializeSignature, stringToHex as stringToHex3 } from "viem";
1429
+ import { sign } from "viem/accounts";
1430
+ import { z as z4 } from "zod";
58
1431
 
59
1432
  // node_modules/@noble/ciphers/esm/utils.js
60
1433
  function isBytes(a) {
@@ -1118,7 +2491,7 @@ function asciiToBase16(ch) {
1118
2491
  return ch - (asciis.a - 10);
1119
2492
  return;
1120
2493
  }
1121
- function hexToBytes(hex) {
2494
+ function hexToBytes2(hex) {
1122
2495
  if (typeof hex !== "string")
1123
2496
  throw new Error("hex string expected, got " + typeof hex);
1124
2497
  if (hasHexBuiltin)
@@ -1147,7 +2520,7 @@ function bytesToNumberLE(bytes) {
1147
2520
  return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
1148
2521
  }
1149
2522
  function numberToBytesBE(n, len) {
1150
- return hexToBytes(n.toString(16).padStart(len * 2, "0"));
2523
+ return hexToBytes2(n.toString(16).padStart(len * 2, "0"));
1151
2524
  }
1152
2525
  function numberToBytesLE(n, len) {
1153
2526
  return numberToBytesBE(n, len).reverse();
@@ -1156,7 +2529,7 @@ function ensureBytes(title, hex, expectedLength) {
1156
2529
  let res;
1157
2530
  if (typeof hex === "string") {
1158
2531
  try {
1159
- res = hexToBytes(hex);
2532
+ res = hexToBytes2(hex);
1160
2533
  } catch (e) {
1161
2534
  throw new Error(title + " must be hex string or Uint8Array, cause: " + e);
1162
2535
  }
@@ -2003,15 +3376,15 @@ function weierstrassPoints(opts) {
2003
3376
  throw new Error("ProjectivePoint expected");
2004
3377
  }
2005
3378
  const toAffineMemo = memoized((p, iz) => {
2006
- const { px: x, py: y, pz: z5 } = p;
2007
- if (Fp.eql(z5, Fp.ONE))
3379
+ const { px: x, py: y, pz: z9 } = p;
3380
+ if (Fp.eql(z9, Fp.ONE))
2008
3381
  return { x, y };
2009
3382
  const is0 = p.is0();
2010
3383
  if (iz == null)
2011
- iz = is0 ? Fp.ONE : Fp.inv(z5);
3384
+ iz = is0 ? Fp.ONE : Fp.inv(z9);
2012
3385
  const ax = Fp.mul(x, iz);
2013
3386
  const ay = Fp.mul(y, iz);
2014
- const zz = Fp.mul(z5, iz);
3387
+ const zz = Fp.mul(z9, iz);
2015
3388
  if (is0)
2016
3389
  return { x: Fp.ZERO, y: Fp.ZERO };
2017
3390
  if (!Fp.eql(zz, Fp.ONE))
@@ -2483,14 +3856,14 @@ function weierstrass(curveDef) {
2483
3856
  }
2484
3857
  // DER-encoded
2485
3858
  toDERRawBytes() {
2486
- return hexToBytes(this.toDERHex());
3859
+ return hexToBytes2(this.toDERHex());
2487
3860
  }
2488
3861
  toDERHex() {
2489
3862
  return DER.hexFromSig(this);
2490
3863
  }
2491
3864
  // padded bytes of r, then padded bytes of s
2492
3865
  toCompactRawBytes() {
2493
- return hexToBytes(this.toCompactHex());
3866
+ return hexToBytes2(this.toCompactHex());
2494
3867
  }
2495
3868
  toCompactHex() {
2496
3869
  const l = nByteLength;
@@ -2772,9 +4145,9 @@ var sha2562 = sha256;
2772
4145
  // node_modules/@noble/hashes/esm/sha512.js
2773
4146
  var sha5122 = sha512;
2774
4147
 
2775
- // src/payload/ecies.ts
4148
+ // src/orders/crypto/ecies.ts
2776
4149
  var MIN_CIPHER_BYTES = 82;
2777
- function hexToBytes2(hex) {
4150
+ function hexToBytes3(hex) {
2778
4151
  const bytes = new Uint8Array(hex.length / 2);
2779
4152
  for (let i = 0; i < bytes.length; i++) {
2780
4153
  bytes[i] = Number.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
@@ -2804,7 +4177,7 @@ function deriveKeys(sharedSecret) {
2804
4177
  };
2805
4178
  }
2806
4179
  async function encryptWithPublicKey(publicKey, message) {
2807
- const pubKeyBytes = hexToBytes2(`04${publicKey}`);
4180
+ const pubKeyBytes = hexToBytes3(`04${publicKey}`);
2808
4181
  const ephemPrivKey = randomBytes(32);
2809
4182
  const ephemPubKey = secp256k1.getPublicKey(ephemPrivKey, false);
2810
4183
  const sharedPoint = secp256k1.getSharedSecret(ephemPrivKey, pubKeyBytes, true);
@@ -2824,11 +4197,11 @@ async function encryptWithPublicKey(publicKey, message) {
2824
4197
  };
2825
4198
  }
2826
4199
  async function decryptWithPrivateKey(privateKey, encrypted) {
2827
- const privKeyBytes = hexToBytes2(privateKey.replace(/^0x/, ""));
2828
- const ephemPubKeyBytes = hexToBytes2(encrypted.ephemPublicKey);
2829
- const ivBytes = hexToBytes2(encrypted.iv);
2830
- const ciphertextBytes = hexToBytes2(encrypted.ciphertext);
2831
- const macBytes = hexToBytes2(encrypted.mac);
4200
+ const privKeyBytes = hexToBytes3(privateKey.replace(/^0x/, ""));
4201
+ const ephemPubKeyBytes = hexToBytes3(encrypted.ephemPublicKey);
4202
+ const ivBytes = hexToBytes3(encrypted.iv);
4203
+ const ciphertextBytes = hexToBytes3(encrypted.ciphertext);
4204
+ const macBytes = hexToBytes3(encrypted.mac);
2832
4205
  const sharedPoint = secp256k1.getSharedSecret(privKeyBytes, ephemPubKeyBytes, true);
2833
4206
  const sharedSecret = sharedPoint.slice(1);
2834
4207
  const { encKey, macKey } = deriveKeys(sharedSecret);
@@ -2842,15 +4215,15 @@ async function decryptWithPrivateKey(privateKey, encrypted) {
2842
4215
  return new TextDecoder().decode(plaintext);
2843
4216
  }
2844
4217
  function cipherStringify(encrypted) {
2845
- const ephemPubKeyBytes = hexToBytes2(encrypted.ephemPublicKey);
4218
+ const ephemPubKeyBytes = hexToBytes3(encrypted.ephemPublicKey);
2846
4219
  const compressed = secp256k1.ProjectivePoint.fromHex(ephemPubKeyBytes).toRawBytes(true);
2847
- const iv = hexToBytes2(encrypted.iv);
2848
- const mac = hexToBytes2(encrypted.mac);
2849
- const ciphertext = hexToBytes2(encrypted.ciphertext);
4220
+ const iv = hexToBytes3(encrypted.iv);
4221
+ const mac = hexToBytes3(encrypted.mac);
4222
+ const ciphertext = hexToBytes3(encrypted.ciphertext);
2850
4223
  return bytesToHex2(concatBytes2(iv, compressed, mac, ciphertext));
2851
4224
  }
2852
4225
  function cipherParse(str) {
2853
- const buf = hexToBytes2(str);
4226
+ const buf = hexToBytes3(str);
2854
4227
  if (buf.length < MIN_CIPHER_BYTES) {
2855
4228
  throw new Error(
2856
4229
  `cipherParse: input too short (${buf.length} bytes, need at least ${MIN_CIPHER_BYTES})`
@@ -2869,241 +4242,971 @@ function cipherParse(str) {
2869
4242
  };
2870
4243
  }
2871
4244
 
2872
- // src/payload/errors.ts
2873
- var PayloadError = class extends SdkError {
2874
- constructor(message, options) {
2875
- super(message, options);
2876
- this.name = "PayloadError";
2877
- }
2878
- };
2879
-
2880
- // src/payload/relay-identity.ts
2881
- import { ok as ok2 } from "neverthrow";
2882
- import { isAddress as isAddress2, isHex } from "viem";
2883
- import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
2884
- import { z as z2 } from "zod";
2885
- var ZodRelayIdentitySchema = z2.object({
2886
- address: z2.string().refine(isAddress2, { message: "Invalid relay identity address" }),
2887
- publicKey: z2.string().refine((val) => isHex(`0x${val}`), {
2888
- message: "Invalid relay identity public key"
2889
- }),
2890
- privateKey: z2.string().refine(isHex, { message: "Invalid relay identity private key" })
2891
- });
2892
- var STORAGE_KEY = "@P2PME:RELAY_IDENTITY";
2893
- function createRelayIdentity() {
2894
- const privateKey = generatePrivateKey();
2895
- const account = privateKeyToAccount(privateKey);
2896
- const rawPubKey = account.publicKey;
2897
- const publicKey = rawPubKey.slice(4);
2898
- const identity = {
2899
- address: account.address,
2900
- publicKey,
2901
- privateKey
2902
- };
2903
- localStorage.setItem(STORAGE_KEY, JSON.stringify(identity));
2904
- return identity;
2905
- }
2906
- function getRelayIdentity() {
2907
- const data = localStorage.getItem(STORAGE_KEY);
2908
- if (!data) {
2909
- return ok2(createRelayIdentity());
2910
- }
4245
+ // src/orders/crypto/encryption.ts
4246
+ function tryParseLegacyEthCryptoEnvelope(input) {
4247
+ if (input.charCodeAt(0) !== 123) return void 0;
2911
4248
  let parsed;
2912
4249
  try {
2913
- parsed = JSON.parse(data);
4250
+ parsed = JSON.parse(input);
2914
4251
  } catch {
2915
- return ok2(createRelayIdentity());
4252
+ return void 0;
2916
4253
  }
2917
- const result = validate(
2918
- ZodRelayIdentitySchema,
2919
- parsed,
2920
- (message, cause, d) => new PayloadError(message, { code: "VALIDATION_ERROR", cause, context: { data: d } })
2921
- );
2922
- if (result.isErr()) {
2923
- return ok2(createRelayIdentity());
4254
+ if (!parsed || typeof parsed !== "object") return void 0;
4255
+ const o = parsed;
4256
+ if (typeof o.iv !== "string" || typeof o.ephemPublicKey !== "string" || typeof o.ciphertext !== "string" || typeof o.mac !== "string") {
4257
+ return void 0;
2924
4258
  }
2925
- return result;
4259
+ return {
4260
+ iv: o.iv,
4261
+ ephemPublicKey: o.ephemPublicKey,
4262
+ ciphertext: o.ciphertext,
4263
+ mac: o.mac
4264
+ };
2926
4265
  }
2927
-
2928
- // src/payload/crypto.ts
2929
- function encryptPaymentAddress(paymentAddress, encryptionPublicKey) {
4266
+ function encryptPaymentAddress(input) {
2930
4267
  return safeTry(async function* () {
2931
- const relayIdentity = yield* getRelayIdentity().mapErr(
2932
- (e) => new PayloadError(`Relay identity error: ${e.message}`, {
2933
- code: "ENCRYPTION_ERROR",
2934
- cause: e
4268
+ const messageHash = keccak256(stringToHex3(input.paymentAddress));
4269
+ const signature = yield* ResultAsync5.fromPromise(
4270
+ sign({ hash: messageHash, privateKey: input.senderIdentity.privateKey }),
4271
+ (cause) => new OrdersError("Failed to sign payment address", {
4272
+ code: "ENCRYPTION_FAILED",
4273
+ cause
4274
+ })
4275
+ ).map(serializeSignature);
4276
+ const payload = JSON.stringify({ message: input.paymentAddress, signature });
4277
+ const encrypted = yield* ResultAsync5.fromPromise(
4278
+ encryptWithPublicKey(input.recipientPublicKey, payload),
4279
+ (cause) => new OrdersError("ECIES encryption failed", {
4280
+ code: "ENCRYPTION_FAILED",
4281
+ cause
2935
4282
  })
2936
4283
  );
2937
- const messageHash = keccak256(stringToHex(paymentAddress));
2938
- const signResult = yield* ResultAsync.fromPromise(
2939
- sign({ hash: messageHash, privateKey: relayIdentity.privateKey }),
2940
- (error) => new PayloadError(
2941
- `Signing error: ${error instanceof Error ? error.message : "Unknown error"}`,
2942
- { code: "ENCRYPTION_ERROR", cause: error }
2943
- )
2944
- );
2945
- const signature = serializeSignature(signResult);
2946
- const payload = { message: paymentAddress, signature };
2947
- const encrypted = yield* ResultAsync.fromPromise(
2948
- encryptWithPublicKey(encryptionPublicKey, JSON.stringify(payload)),
2949
- (error) => new PayloadError(
2950
- `Encryption error: ${error instanceof Error ? error.message : "Unknown error"}`,
2951
- { code: "ENCRYPTION_ERROR", cause: error }
2952
- )
2953
- );
2954
- const safeCipherStringify = Result.fromThrowable(
2955
- (encryptedData) => cipherStringify(encryptedData),
2956
- (error) => new PayloadError(
2957
- `Stringify error: ${error instanceof Error ? error.message : "Unknown error"}`,
2958
- { code: "ENCRYPTION_ERROR", cause: error }
2959
- )
4284
+ const safeStringify = Result.fromThrowable(
4285
+ (e) => cipherStringify(e),
4286
+ (cause) => new OrdersError("Ciphertext stringify failed", {
4287
+ code: "ENCRYPTION_FAILED",
4288
+ cause
4289
+ })
2960
4290
  );
2961
- const stringified = yield* safeCipherStringify(encrypted);
2962
- return ok3(stringified);
4291
+ return ok3(yield* safeStringify(encrypted));
2963
4292
  });
2964
4293
  }
2965
- var ZodEncryptedDataSchema = z3.object({
2966
- ciphertext: z3.string(),
2967
- iv: z3.string(),
2968
- mac: z3.string(),
2969
- ephemPublicKey: z3.string()
4294
+ var ZodDecryptedPayloadSchema = z4.object({
4295
+ message: z4.string(),
4296
+ signature: z4.string()
2970
4297
  });
2971
- function decryptPaymentAddress(encryptedPaymentAddress) {
4298
+ function decryptPaymentAddress(input) {
2972
4299
  return safeTry(async function* () {
2973
- const relayIdentity = yield* getRelayIdentity().mapErr(
2974
- (e) => new PayloadError(`Relay identity error: ${e.message}`, {
2975
- code: "DECRYPTION_ERROR",
2976
- cause: e
4300
+ const legacyEnvelope = tryParseLegacyEthCryptoEnvelope(input.encrypted);
4301
+ const safeCipherParse = Result.fromThrowable(
4302
+ (s) => cipherParse(s),
4303
+ (cause) => new OrdersError("Failed to parse ciphertext", {
4304
+ code: "ENCRYPTION_FAILED",
4305
+ cause
2977
4306
  })
2978
4307
  );
4308
+ const encryptedData = legacyEnvelope ?? (yield* safeCipherParse(input.encrypted));
4309
+ const plaintext = yield* ResultAsync5.fromPromise(
4310
+ decryptWithPrivateKey(input.recipientIdentity.privateKey, encryptedData),
4311
+ (cause) => new OrdersError("ECIES decryption failed", {
4312
+ code: "ENCRYPTION_FAILED",
4313
+ cause
4314
+ })
4315
+ );
4316
+ if (legacyEnvelope) {
4317
+ return ok3(plaintext);
4318
+ }
2979
4319
  const safeJsonParse = Result.fromThrowable(
2980
- (str) => JSON.parse(str),
2981
- (error) => new PayloadError(
2982
- `JSON parse error: ${error instanceof Error ? error.message : "Unknown error"}`,
2983
- { code: "DECRYPTION_ERROR", cause: error }
2984
- )
4320
+ (s) => JSON.parse(s),
4321
+ (cause) => new OrdersError("Failed to parse decrypted payload JSON", {
4322
+ code: "ENCRYPTION_FAILED",
4323
+ cause
4324
+ })
2985
4325
  );
2986
- const parsed = yield* safeJsonParse(encryptedPaymentAddress);
2987
- const encryptedData = yield* validate(
2988
- ZodEncryptedDataSchema,
4326
+ const parsed = yield* safeJsonParse(plaintext);
4327
+ const payload = yield* validate(
4328
+ ZodDecryptedPayloadSchema,
2989
4329
  parsed,
2990
- (message, cause, data) => new PayloadError(message, { code: "DECRYPTION_ERROR", cause, context: { data } })
2991
- );
2992
- const decrypted = yield* ResultAsync.fromPromise(
2993
- decryptWithPrivateKey(relayIdentity.privateKey, encryptedData),
2994
- (error) => new PayloadError(
2995
- `Decryption error: ${error instanceof Error ? error.message : "Unknown error"}`,
2996
- { code: "DECRYPTION_ERROR", cause: error }
2997
- )
4330
+ (message, cause, data) => new OrdersError(message, {
4331
+ code: "ENCRYPTION_FAILED",
4332
+ cause,
4333
+ context: { data }
4334
+ })
2998
4335
  );
2999
- return ok3(decrypted);
4336
+ return ok3(payload.message);
3000
4337
  });
3001
4338
  }
3002
4339
 
3003
- // src/payload/validation.ts
3004
- import { z as z4 } from "zod";
3005
- var ZodPlaceOrderParamsSchema = z4.object({
3006
- amount: z4.bigint(),
3007
- recipientAddr: ZodAddressSchema,
3008
- orderType: z4.number().int().min(0).max(2),
3009
- currency: ZodCurrencySchema,
3010
- fiatAmount: z4.bigint(),
4340
+ // src/orders/actions/set-sell-order-upi.ts
4341
+ function createSetSellOrderUpiAction(input) {
4342
+ const { publicClient, diamondAddress, relayIdentityStore, relayIdentity } = input;
4343
+ const prepareFn = (params) => validate(
4344
+ ZodSetSellOrderUpiParamsSchema,
4345
+ params,
4346
+ (message, cause, data) => new OrdersError(message, {
4347
+ code: "VALIDATION_ERROR",
4348
+ cause,
4349
+ context: { data }
4350
+ })
4351
+ ).asyncAndThen(
4352
+ (v) => resolveRelayIdentity({ relayIdentity, store: relayIdentityStore }).andThen(
4353
+ (senderIdentity) => encryptPaymentAddress({
4354
+ paymentAddress: v.paymentAddress,
4355
+ recipientPublicKey: v.merchantPublicKey,
4356
+ senderIdentity
4357
+ }).map((userEncUpi) => ({ v, userEncUpi, senderIdentity }))
4358
+ )
4359
+ ).map(({ v, userEncUpi, senderIdentity }) => ({
4360
+ to: diamondAddress,
4361
+ data: encodeFunctionData6({
4362
+ abi: ABIS.FACETS.ORDER_FLOW,
4363
+ functionName: "setSellOrderUpi",
4364
+ args: [v.orderId, userEncUpi, v.updatedAmount]
4365
+ }),
4366
+ value: 0n,
4367
+ meta: { relayIdentity: senderIdentity }
4368
+ }));
4369
+ return {
4370
+ prepare(params) {
4371
+ return prepareFn(params);
4372
+ },
4373
+ execute({ walletClient, waitForReceipt, ...params }) {
4374
+ return prepareFn(params).andThen(
4375
+ (prepared) => submitPreparedTx({ prepared, walletClient, publicClient, waitForReceipt })
4376
+ );
4377
+ }
4378
+ };
4379
+ }
4380
+
4381
+ // src/orders/internal/routing/client.ts
4382
+ import { stringToHex as stringToHex6 } from "viem";
4383
+
4384
+ // src/contracts/order-flow/index.ts
4385
+ import { ResultAsync as ResultAsync6 } from "neverthrow";
4386
+
4387
+ // src/orders/internal/routing/errors.ts
4388
+ var OrderRoutingError = class extends SdkError {
4389
+ constructor(message, options) {
4390
+ super(message, options);
4391
+ this.name = "OrderRoutingError";
4392
+ }
4393
+ };
4394
+
4395
+ // src/orders/internal/routing/validation.ts
4396
+ import { z as z5 } from "zod";
4397
+ var ZodCircleScoreStateSchema = z5.object({
4398
+ activeMerchantsCount: z5.coerce.number()
4399
+ });
4400
+ var ZodCircleMetricsForRoutingSchema = z5.object({
4401
+ circleScore: z5.coerce.number(),
4402
+ circleStatus: z5.string(),
4403
+ scoreState: ZodCircleScoreStateSchema
4404
+ });
4405
+ var ZodCircleForRoutingSchema = z5.object({
4406
+ circleId: z5.string(),
4407
+ currency: z5.string(),
4408
+ metrics: ZodCircleMetricsForRoutingSchema
4409
+ });
4410
+ var ZodCirclesForRoutingResponseSchema = z5.object({
4411
+ circles: z5.array(ZodCircleForRoutingSchema)
4412
+ });
4413
+ var ZodCheckCircleEligibilityParamsSchema = z5.object({
4414
+ circleId: z5.bigint(),
4415
+ currency: z5.string(),
3011
4416
  user: ZodAddressSchema,
3012
- pubKey: z4.string().optional(),
3013
- preferredPaymentChannelConfigId: z4.bigint().optional(),
3014
- fiatAmountLimit: z4.bigint().optional().default(0n)
4417
+ usdtAmount: z5.bigint(),
4418
+ fiatAmount: z5.bigint(),
4419
+ orderType: z5.bigint(),
4420
+ preferredPCConfigId: z5.bigint()
3015
4421
  });
3016
- var ZodSetSellOrderUpiParamsSchema = z4.object({
3017
- orderId: z4.number().int().nonnegative(),
3018
- paymentAddress: z4.string().min(1),
3019
- merchantPublicKey: z4.string().min(1),
3020
- updatedAmount: z4.bigint()
4422
+ var ZodSelectCircleParamsSchema = z5.object({
4423
+ currency: z5.string().min(1),
4424
+ user: ZodAddressSchema,
4425
+ usdtAmount: z5.bigint(),
4426
+ fiatAmount: z5.bigint(),
4427
+ orderType: z5.bigint(),
4428
+ preferredPCConfigId: z5.bigint()
3021
4429
  });
3022
4430
 
3023
- // src/payload/actions.ts
3024
- function buildPlaceOrderPayload(orderRouter, params) {
3025
- const validation = validate(
3026
- ZodPlaceOrderParamsSchema,
4431
+ // src/contracts/order-flow/index.ts
4432
+ function checkCircleEligibility(publicClient, contractAddress, params, logger = noopLogger) {
4433
+ return validate(
4434
+ ZodCheckCircleEligibilityParamsSchema,
3027
4435
  params,
3028
- (message, cause, data) => new PayloadError(message, { code: "VALIDATION_ERROR", cause, context: { data } })
3029
- );
3030
- if (validation.isErr()) {
3031
- return errAsync(validation.error);
3032
- }
3033
- const v = validation.value;
3034
- const isBuy = v.orderType === ORDER_TYPE.BUY;
3035
- const pcConfigId = v.preferredPaymentChannelConfigId ?? 0n;
3036
- const circleResult = orderRouter.selectCircle({
3037
- currency: v.currency,
3038
- user: v.user,
3039
- usdtAmount: v.amount,
3040
- fiatAmount: v.fiatAmount,
3041
- orderType: BigInt(v.orderType),
3042
- preferredPCConfigId: pcConfigId
4436
+ (message, cause, d) => new OrderRoutingError(message, { code: "VALIDATION_ERROR", cause, context: { data: d } })
4437
+ ).asyncAndThen((validated) => {
4438
+ logger.debug("checking on-chain eligibility", {
4439
+ circleId: String(validated.circleId),
4440
+ contractAddress
4441
+ });
4442
+ return ResultAsync6.fromPromise(
4443
+ publicClient.readContract({
4444
+ address: contractAddress,
4445
+ abi: ABIS.FACETS.ORDER_FLOW,
4446
+ functionName: "getAssignableMerchantsFromCircle",
4447
+ args: [
4448
+ validated.circleId,
4449
+ 1n,
4450
+ validated.currency,
4451
+ validated.user,
4452
+ validated.usdtAmount,
4453
+ validated.fiatAmount,
4454
+ validated.orderType,
4455
+ validated.preferredPCConfigId
4456
+ ]
4457
+ }),
4458
+ (error) => new OrderRoutingError("Eligibility check failed", {
4459
+ code: "CONTRACT_READ_ERROR",
4460
+ cause: error,
4461
+ context: { circleId: String(params.circleId) }
4462
+ })
4463
+ );
4464
+ }).map((merchants) => {
4465
+ const arr = merchants;
4466
+ const eligible = arr.length >= 1;
4467
+ logger.debug("eligibility check result", {
4468
+ circleId: String(params.circleId),
4469
+ assignableMerchants: arr.length,
4470
+ eligible
4471
+ });
4472
+ return eligible;
3043
4473
  });
3044
- const relayResult = getRelayIdentity();
3045
- if (relayResult.isErr()) {
3046
- return errAsync(relayResult.error);
3047
- }
3048
- const common = {
3049
- amount: v.amount,
3050
- recipientAddr: v.recipientAddr,
3051
- orderType: v.orderType,
3052
- userUpi: "",
3053
- currency: v.currency,
3054
- preferredPaymentChannelConfigId: pcConfigId,
3055
- fiatAmountLimit: v.fiatAmountLimit
3056
- };
3057
- const pubKeyValue = v.pubKey ?? relayResult.value.publicKey;
3058
- return circleResult.map((circleId) => ({
3059
- ...common,
3060
- pubKey: isBuy ? pubKeyValue : "",
3061
- userPubKey: isBuy ? "" : pubKeyValue,
3062
- circleId
3063
- })).mapErr(
3064
- (e) => new PayloadError(e.message, {
3065
- code: "CIRCLE_SELECTION_ERROR",
3066
- cause: e
4474
+ }
4475
+
4476
+ // src/contracts/p2p-config/index.ts
4477
+ import { ResultAsync as ResultAsync7 } from "neverthrow";
4478
+ import { stringToHex as stringToHex4 } from "viem";
4479
+
4480
+ // src/prices/validation.ts
4481
+ import { z as z6 } from "zod";
4482
+ var ZodCurrencyScopedParamsSchema = z6.object({
4483
+ currency: ZodCurrencySchema
4484
+ });
4485
+
4486
+ // src/contracts/reputation-manager/writes.ts
4487
+ import { Result as Result2 } from "neverthrow";
4488
+ import { encodeFunctionData as encodeFunctionData7 } from "viem";
4489
+
4490
+ // src/zkkyc/validation.ts
4491
+ import { z as z7 } from "zod";
4492
+ var ZodAnonAadharProofParamsSchema = z7.object({
4493
+ nullifierSeed: z7.bigint(),
4494
+ nullifier: z7.bigint(),
4495
+ timestamp: z7.bigint(),
4496
+ signal: z7.bigint(),
4497
+ revealArray: z7.tuple([z7.bigint(), z7.bigint(), z7.bigint(), z7.bigint()]),
4498
+ packedGroth16Proof: z7.tuple([
4499
+ z7.bigint(),
4500
+ z7.bigint(),
4501
+ z7.bigint(),
4502
+ z7.bigint(),
4503
+ z7.bigint(),
4504
+ z7.bigint(),
4505
+ z7.bigint(),
4506
+ z7.bigint()
4507
+ ])
4508
+ });
4509
+ var ZodSocialVerifyParamsSchema = z7.object({
4510
+ _socialName: z7.string(),
4511
+ proofs: z7.array(
4512
+ z7.object({
4513
+ claimInfo: z7.object({
4514
+ provider: z7.string(),
4515
+ parameters: z7.string(),
4516
+ context: z7.string()
4517
+ }),
4518
+ signedClaim: z7.object({
4519
+ claim: z7.object({
4520
+ identifier: z7.string(),
4521
+ owner: ZodAddressSchema,
4522
+ timestampS: z7.number(),
4523
+ epoch: z7.number()
4524
+ }),
4525
+ signatures: z7.array(z7.string())
4526
+ })
3067
4527
  })
3068
- );
4528
+ )
4529
+ });
4530
+ var ZodSolidityVerifierParametersSchema = z7.object({
4531
+ version: z7.string().refine((val) => val.startsWith("0x"), {
4532
+ message: "Version must be a hex string"
4533
+ }),
4534
+ proofVerificationData: z7.object({
4535
+ vkeyHash: z7.string().refine((val) => /^0x[a-fA-F0-9]{64}$/.test(val), {
4536
+ message: "Invalid bytes32 hex string"
4537
+ }),
4538
+ proof: z7.string().refine((val) => val.startsWith("0x"), {
4539
+ message: "Proof must be a hex string"
4540
+ }),
4541
+ publicInputs: z7.array(
4542
+ z7.string().refine((val) => /^0x[a-fA-F0-9]{64}$/.test(val), {
4543
+ message: "Each public input must be a valid bytes32 hex string"
4544
+ })
4545
+ )
4546
+ }),
4547
+ committedInputs: z7.string().refine((val) => val.startsWith("0x"), {
4548
+ message: "Committed inputs must be a hex string"
4549
+ }),
4550
+ serviceConfig: z7.object({
4551
+ validityPeriodInSeconds: z7.number().int().nonnegative(),
4552
+ domain: z7.string(),
4553
+ scope: z7.string(),
4554
+ devMode: z7.boolean()
4555
+ })
4556
+ });
4557
+ var ZodZkPassportRegisterParamsSchema = z7.object({
4558
+ params: ZodSolidityVerifierParametersSchema,
4559
+ isIDCard: z7.boolean()
4560
+ });
4561
+
4562
+ // src/contracts/tx-limits/index.ts
4563
+ import { ResultAsync as ResultAsync8 } from "neverthrow";
4564
+ import { formatUnits, stringToHex as stringToHex5 } from "viem";
4565
+
4566
+ // src/profile/validation.ts
4567
+ import { z as z8 } from "zod";
4568
+ var ZodUsdcBalanceParamsSchema = z8.object({
4569
+ address: ZodAddressSchema
4570
+ });
4571
+ var ZodUsdcAllowanceParamsSchema = z8.object({
4572
+ owner: ZodAddressSchema
4573
+ });
4574
+ var ZodGetBalancesParamsSchema = z8.object({
4575
+ address: ZodAddressSchema,
4576
+ currency: ZodCurrencySchema
4577
+ });
4578
+ var ZodTxLimitsParamsSchema = z8.object({
4579
+ address: ZodAddressSchema,
4580
+ currency: ZodCurrencySchema
4581
+ });
4582
+
4583
+ // src/contracts/usdc/index.ts
4584
+ import { ResultAsync as ResultAsync9 } from "neverthrow";
4585
+ import { erc20Abi as erc20Abi3 } from "viem";
4586
+
4587
+ // src/orders/internal/routing/routing.ts
4588
+ import { errAsync as errAsync2, okAsync as okAsync3 } from "neverthrow";
4589
+ var EPSILON = 0.25;
4590
+ var RECOVERY_SCALE = 0.3;
4591
+ var BOOTSTRAP_MAX_WEIGHT = 25;
4592
+ var MAX_VALIDATION_ATTEMPTS = 3;
4593
+ function circleWeight(c) {
4594
+ const score = c.metrics.circleScore;
4595
+ if (c.metrics.circleStatus === "paused") {
4596
+ return score * RECOVERY_SCALE;
4597
+ }
4598
+ if (c.metrics.circleStatus === "bootstrap") {
4599
+ return Math.min(score, BOOTSTRAP_MAX_WEIGHT);
4600
+ }
4601
+ return score;
3069
4602
  }
3070
- function buildSetSellOrderUpiPayload(params) {
3071
- const validation = validate(
3072
- ZodSetSellOrderUpiParamsSchema,
3073
- params,
3074
- (message, cause, data) => new PayloadError(message, { code: "VALIDATION_ERROR", cause, context: { data } })
4603
+ function filterEligibleCircles(circles, orderCurrency) {
4604
+ return circles.filter((c) => c.currency.toLowerCase() === orderCurrency.toLowerCase());
4605
+ }
4606
+ function weightedRandomChoice(arr, weights) {
4607
+ const totalWeight = weights.reduce((sum, w) => sum + w, 0);
4608
+ if (totalWeight === 0) {
4609
+ return arr[Math.floor(Math.random() * arr.length)];
4610
+ }
4611
+ let rand = Math.random() * totalWeight;
4612
+ for (let i = 0; i < arr.length; i++) {
4613
+ rand -= weights[i];
4614
+ if (rand <= 0) {
4615
+ return arr[i];
4616
+ }
4617
+ }
4618
+ return arr[arr.length - 1];
4619
+ }
4620
+ function selectCircle(eligible) {
4621
+ if (eligible.length === 0) {
4622
+ return null;
4623
+ }
4624
+ const activeCircles = eligible.filter((c) => c.metrics.circleStatus === "active");
4625
+ const isExplore = Math.random() < EPSILON;
4626
+ if (isExplore) {
4627
+ const weights2 = eligible.map(circleWeight);
4628
+ return weightedRandomChoice(eligible, weights2);
4629
+ }
4630
+ if (activeCircles.length === 0) {
4631
+ const weights2 = eligible.map(circleWeight);
4632
+ return weightedRandomChoice(eligible, weights2);
4633
+ }
4634
+ const weights = activeCircles.map((c) => c.metrics.circleScore);
4635
+ return weightedRandomChoice(activeCircles, weights);
4636
+ }
4637
+ function selectCircleForOrderAsync(circles, orderCurrency, validateCircle, logger = noopLogger) {
4638
+ const eligible = filterEligibleCircles(circles, orderCurrency);
4639
+ let remaining = [...eligible];
4640
+ logger.debug("filtering eligible circles", {
4641
+ total: circles.length,
4642
+ eligible: eligible.length,
4643
+ currency: orderCurrency,
4644
+ circles: eligible
4645
+ });
4646
+ if (eligible.length === 0) {
4647
+ logger.warn("no eligible circles found for currency", { currency: orderCurrency });
4648
+ }
4649
+ function attempt(attemptsLeft) {
4650
+ if (attemptsLeft <= 0 || remaining.length === 0) {
4651
+ logger.warn("exhausted all attempts or circles", {
4652
+ attemptsLeft,
4653
+ remainingCircles: remaining.length
4654
+ });
4655
+ return errAsync2(
4656
+ new OrderRoutingError("No eligible circles found", {
4657
+ code: "NO_ELIGIBLE_CIRCLES"
4658
+ })
4659
+ );
4660
+ }
4661
+ const selected = selectCircle(remaining);
4662
+ if (!selected) {
4663
+ return errAsync2(
4664
+ new OrderRoutingError("No eligible circles found", {
4665
+ code: "NO_ELIGIBLE_CIRCLES"
4666
+ })
4667
+ );
4668
+ }
4669
+ const circleId = BigInt(selected.circleId);
4670
+ logger.debug("selected circle, validating on-chain", {
4671
+ circleId: String(circleId),
4672
+ status: selected.metrics.circleStatus,
4673
+ score: selected.metrics.circleScore,
4674
+ attemptsLeft
4675
+ });
4676
+ return validateCircle(circleId).orElse((error) => {
4677
+ logger.warn("validation errored, treating as ineligible", {
4678
+ circleId: String(circleId),
4679
+ error: String(error)
4680
+ });
4681
+ return okAsync3(false);
4682
+ }).andThen((isValid) => {
4683
+ if (isValid) {
4684
+ logger.info("circle validated successfully", { circleId: String(circleId) });
4685
+ return okAsync3(circleId);
4686
+ }
4687
+ logger.debug("circle failed validation, retrying", {
4688
+ circleId: String(circleId),
4689
+ remainingCircles: remaining.length - 1
4690
+ });
4691
+ remaining = remaining.filter((c) => c.circleId !== selected.circleId);
4692
+ return attempt(attemptsLeft - 1);
4693
+ });
4694
+ }
4695
+ return attempt(MAX_VALIDATION_ATTEMPTS);
4696
+ }
4697
+
4698
+ // src/orders/internal/routing/subgraph/queries.ts
4699
+ var CIRCLES_FOR_ROUTING_QUERY = (
4700
+ /* GraphQL */
4701
+ `
4702
+ query CirclesForRouting($currency: Bytes!) {
4703
+ circles(
4704
+ first: 1000
4705
+ where: {
4706
+ currency: $currency
4707
+ metrics_: {
4708
+ circleStatus_in: ["active", "bootstrap", "paused"]
4709
+ }
4710
+ }
4711
+ ) {
4712
+ circleId
4713
+ currency
4714
+ metrics {
4715
+ circleScore
4716
+ circleStatus
4717
+ scoreState {
4718
+ activeMerchantsCount
4719
+ }
4720
+ }
4721
+ }
4722
+ }
4723
+ `
4724
+ );
4725
+
4726
+ // src/orders/internal/routing/subgraph/index.ts
4727
+ function getCirclesForRouting(subgraphUrl, currency, logger = noopLogger) {
4728
+ logger.debug("fetching circles from subgraph", { subgraphUrl, currency });
4729
+ return querySubgraph(subgraphUrl, {
4730
+ query: CIRCLES_FOR_ROUTING_QUERY,
4731
+ variables: { currency }
4732
+ }).mapErr(
4733
+ (e) => new OrderRoutingError(e.message, {
4734
+ code: "SUBGRAPH_ERROR",
4735
+ cause: e.cause ?? e,
4736
+ context: e.context
4737
+ })
4738
+ ).andThen(
4739
+ (data) => validate(
4740
+ ZodCirclesForRoutingResponseSchema,
4741
+ data,
4742
+ (message, cause, d) => new OrderRoutingError(message, { code: "VALIDATION_ERROR", cause, context: { data: d } })
4743
+ ).map((validated) => {
4744
+ const circles = validated.circles.filter(
4745
+ (item) => Number(item.metrics.scoreState.activeMerchantsCount) > 0
4746
+ );
4747
+ logger.info("fetched circles from subgraph", {
4748
+ total: validated.circles.length,
4749
+ withActiveMerchants: circles.length,
4750
+ circles
4751
+ });
4752
+ return circles;
4753
+ })
3075
4754
  );
3076
- if (validation.isErr()) {
3077
- return errAsync(validation.error);
3078
- }
3079
- const v = validation.value;
3080
- return encryptPaymentAddress(v.paymentAddress, v.merchantPublicKey).map((userEncUpi) => ({
3081
- orderId: v.orderId,
3082
- userEncUpi,
3083
- updatedAmount: v.updatedAmount
4755
+ }
4756
+
4757
+ // src/orders/internal/routing/client.ts
4758
+ function createOrderRouter(config) {
4759
+ const { subgraphUrl, publicClient, contractAddress } = config;
4760
+ const logger = config.logger ?? noopLogger;
4761
+ return {
4762
+ selectCircle(params) {
4763
+ const currencyHex = stringToHex6(params.currency, { size: 32 });
4764
+ logger.info("selectCircle started", {
4765
+ currency: params.currency,
4766
+ user: params.user,
4767
+ orderType: String(params.orderType)
4768
+ });
4769
+ return getCirclesForRouting(subgraphUrl, currencyHex, logger).andThen(
4770
+ (circles) => selectCircleForOrderAsync(
4771
+ circles,
4772
+ currencyHex,
4773
+ (circleId) => checkCircleEligibility(
4774
+ publicClient,
4775
+ contractAddress,
4776
+ {
4777
+ circleId,
4778
+ currency: currencyHex,
4779
+ user: params.user,
4780
+ usdtAmount: params.usdtAmount,
4781
+ fiatAmount: params.fiatAmount,
4782
+ orderType: params.orderType,
4783
+ preferredPCConfigId: params.preferredPCConfigId
4784
+ },
4785
+ logger
4786
+ ),
4787
+ logger
4788
+ )
4789
+ );
4790
+ }
4791
+ };
4792
+ }
4793
+
4794
+ // src/orders/normalize.ts
4795
+ import { err as err3, ok as ok4, Result as Result3 } from "neverthrow";
4796
+ import { hexToString, isAddressEqual, zeroAddress } from "viem";
4797
+ var ORDER_TYPE_MAP = {
4798
+ [ORDER_TYPE.BUY]: "buy",
4799
+ [ORDER_TYPE.SELL]: "sell",
4800
+ [ORDER_TYPE.PAY]: "pay"
4801
+ };
4802
+ var ORDER_STATUS_MAP = {
4803
+ [ORDER_STATUS.PLACED]: "placed",
4804
+ [ORDER_STATUS.ACCEPTED]: "accepted",
4805
+ [ORDER_STATUS.PAID]: "paid",
4806
+ [ORDER_STATUS.COMPLETED]: "completed",
4807
+ [ORDER_STATUS.CANCELLED]: "cancelled"
4808
+ };
4809
+ var DISPUTE_STATUS_MAP = {
4810
+ [DISPUTE_STATUS.NONE]: "none",
4811
+ [DISPUTE_STATUS.OPEN]: "open",
4812
+ [DISPUTE_STATUS.RESOLVED]: "resolved"
4813
+ };
4814
+ function malformed(field, value, context) {
4815
+ return new OrdersError(`Unknown ${field}: ${String(value)}`, {
4816
+ code: "MALFORMED_ORDER",
4817
+ context: { field, value, ...context }
4818
+ });
4819
+ }
4820
+ function mapOrderType(v, ctx) {
4821
+ const t = ORDER_TYPE_MAP[v];
4822
+ return t ? ok4(t) : err3(malformed("orderType", v, ctx));
4823
+ }
4824
+ function mapOrderStatus(v, ctx) {
4825
+ const s = ORDER_STATUS_MAP[v];
4826
+ return s ? ok4(s) : err3(malformed("status", v, ctx));
4827
+ }
4828
+ function mapDisputeStatus(v, ctx) {
4829
+ const s = DISPUTE_STATUS_MAP[v];
4830
+ return s ? ok4(s) : err3(malformed("disputeStatus", v, ctx));
4831
+ }
4832
+ function decodeCurrency(hex) {
4833
+ return hexToString(hex, { size: 32 }).replaceAll("\0", "");
4834
+ }
4835
+ function normalizeContractOrder(raw, details) {
4836
+ if (raw.id === 0n && isAddressEqual(raw.user, zeroAddress)) return ok4(null);
4837
+ const ctx = { orderId: raw.id.toString() };
4838
+ return Result3.combine([
4839
+ mapOrderType(raw.orderType, ctx),
4840
+ mapOrderStatus(raw.status, ctx),
4841
+ mapDisputeStatus(raw.disputeInfo.status, ctx)
4842
+ ]).map(([type, status, disputeStatus]) => ({
4843
+ orderId: raw.id,
4844
+ type,
4845
+ status,
4846
+ usdcAmount: raw.amount,
4847
+ fiatAmount: raw.fiatAmount,
4848
+ actualUsdcAmount: details.actualUsdtAmount,
4849
+ actualFiatAmount: details.actualFiatAmount,
4850
+ currency: decodeCurrency(raw.currency),
4851
+ user: raw.user,
4852
+ recipient: raw.recipientAddr,
4853
+ acceptedMerchant: raw.acceptedMerchant,
4854
+ placedAt: raw.placedTimestamp,
4855
+ acceptedAt: details.acceptedTimestamp,
4856
+ paidAt: details.paidTimestamp,
4857
+ completedAt: raw.completedTimestamp,
4858
+ circleId: raw.circleId,
4859
+ fixedFeePaid: details.fixedFeePaid,
4860
+ tipsPaid: details.tipsPaid,
4861
+ disputeStatus,
4862
+ encUpi: raw.encUpi,
4863
+ encMerchantUpi: raw.encMerchantUpi,
4864
+ pubkey: raw.pubkey
3084
4865
  }));
3085
4866
  }
4867
+ function normalizeSubgraphOrder(raw) {
4868
+ const ctx = { orderId: raw.orderId };
4869
+ return Result3.combine([
4870
+ mapOrderType(raw.type, ctx),
4871
+ mapOrderStatus(raw.status, ctx),
4872
+ mapDisputeStatus(raw.disputeStatus, ctx)
4873
+ ]).map(([type, status, disputeStatus]) => ({
4874
+ orderId: BigInt(raw.orderId),
4875
+ type,
4876
+ status,
4877
+ usdcAmount: BigInt(raw.usdcAmount),
4878
+ fiatAmount: BigInt(raw.fiatAmount),
4879
+ actualUsdcAmount: BigInt(raw.actualUsdcAmount),
4880
+ actualFiatAmount: BigInt(raw.actualFiatAmount),
4881
+ currency: decodeCurrency(raw.currency),
4882
+ user: raw.userAddress,
4883
+ recipient: raw.usdcRecipientAddress,
4884
+ acceptedMerchant: raw.acceptedMerchantAddress,
4885
+ placedAt: BigInt(raw.placedAt),
4886
+ acceptedAt: BigInt(raw.acceptedAt),
4887
+ paidAt: BigInt(raw.paidAt),
4888
+ completedAt: BigInt(raw.completedAt),
4889
+ circleId: BigInt(raw.circleId),
4890
+ fixedFeePaid: BigInt(raw.fixedFeePaid),
4891
+ tipsPaid: BigInt(raw.tipsPaid),
4892
+ disputeStatus,
4893
+ // Subgraph entity does not currently expose these encryption fields;
4894
+ // consumers needing them should fall back to the contract via getOrder.
4895
+ encUpi: "",
4896
+ encMerchantUpi: "",
4897
+ pubkey: ""
4898
+ }));
4899
+ }
4900
+
4901
+ // src/orders/subgraph/index.ts
4902
+ import { Result as Result4 } from "neverthrow";
4903
+
4904
+ // src/orders/subgraph/queries.ts
4905
+ var ORDERS_BY_USER_QUERY = (
4906
+ /* GraphQL */
4907
+ `
4908
+ query OrdersByUser($user: Bytes!, $skip: Int!, $first: Int!) {
4909
+ orders_collection(
4910
+ where: { userAddress: $user }
4911
+ orderBy: placedAt
4912
+ orderDirection: desc
4913
+ skip: $skip
4914
+ first: $first
4915
+ ) {
4916
+ orderId
4917
+ type
4918
+ status
4919
+ circleId
4920
+ userAddress
4921
+ usdcRecipientAddress
4922
+ acceptedMerchantAddress
4923
+ usdcAmount
4924
+ fiatAmount
4925
+ actualUsdcAmount
4926
+ actualFiatAmount
4927
+ currency
4928
+ placedAt
4929
+ acceptedAt
4930
+ paidAt
4931
+ completedAt
4932
+ fixedFeePaid
4933
+ tipsPaid
4934
+ disputeStatus
4935
+ }
4936
+ }
4937
+ `
4938
+ );
3086
4939
 
3087
- // src/payload/client.ts
3088
- function createPayloadGenerator(config) {
4940
+ // src/orders/subgraph/index.ts
4941
+ function getOrdersForUser(subgraphUrl, userAddress, skip, limit, logger = noopLogger) {
4942
+ const user = userAddress.toLowerCase();
4943
+ logger.debug("fetching orders from subgraph", { subgraphUrl, user, skip, limit });
4944
+ return querySubgraph(subgraphUrl, {
4945
+ query: ORDERS_BY_USER_QUERY,
4946
+ variables: { user, skip, first: limit }
4947
+ }).mapErr(
4948
+ (e) => new OrdersError(e.message, {
4949
+ code: "SUBGRAPH_REQUEST_FAILED",
4950
+ cause: e.cause ?? e,
4951
+ context: { user, skip, limit, ...e.context ?? {} }
4952
+ })
4953
+ ).andThen(
4954
+ (data) => validate(
4955
+ ZodSubgraphOrdersResponseSchema,
4956
+ data,
4957
+ (message, cause, d) => new OrdersError(message, {
4958
+ code: "SUBGRAPH_VALIDATION_FAILED",
4959
+ cause,
4960
+ context: { data: d }
4961
+ })
4962
+ ).andThen(
4963
+ (validated) => Result4.combine(validated.orders_collection.map(normalizeSubgraphOrder))
4964
+ )
4965
+ );
4966
+ }
4967
+
4968
+ // src/orders/watch-events.ts
4969
+ var PLACED_CONFIG = {
4970
+ eventName: "OrderPlaced",
4971
+ toEvent: (log) => ({
4972
+ type: "placed",
4973
+ orderId: log.args.orderId,
4974
+ user: log.args.user,
4975
+ orderType: log.args.orderType,
4976
+ blockNumber: log.blockNumber,
4977
+ txHash: log.transactionHash
4978
+ }),
4979
+ userFromLog: (log) => log.args.user
4980
+ };
4981
+ var ACCEPTED_CONFIG = {
4982
+ eventName: "OrderAccepted",
4983
+ toEvent: (log) => ({
4984
+ type: "accepted",
4985
+ orderId: log.args.orderId,
4986
+ merchant: log.args.merchant,
4987
+ blockNumber: log.blockNumber,
4988
+ txHash: log.transactionHash
4989
+ }),
4990
+ // OrderAccepted's top-level args are (orderId, merchant, pubKey, _order).
4991
+ // The buyer's address lives inside the _order tuple as _order.user.
4992
+ userFromLog: (log) => log.args._order?.user
4993
+ };
4994
+ var PAID_CONFIG = {
4995
+ eventName: "BuyOrderPaid",
4996
+ toEvent: (log) => ({
4997
+ type: "paid",
4998
+ orderId: log.args.orderId,
4999
+ blockNumber: log.blockNumber,
5000
+ txHash: log.transactionHash
5001
+ }),
5002
+ userFromLog: (log) => log.args.user
5003
+ };
5004
+ var COMPLETED_CONFIG = {
5005
+ eventName: "OrderCompleted",
5006
+ toEvent: (log) => ({
5007
+ type: "completed",
5008
+ orderId: log.args.orderId,
5009
+ blockNumber: log.blockNumber,
5010
+ txHash: log.transactionHash
5011
+ }),
5012
+ userFromLog: (log) => log.args.user
5013
+ };
5014
+ var CANCELLED_CONFIG = {
5015
+ eventName: "CancelledOrders",
5016
+ toEvent: (log) => ({
5017
+ type: "cancelled",
5018
+ orderId: log.args.orderId,
5019
+ blockNumber: log.blockNumber,
5020
+ txHash: log.transactionHash
5021
+ }),
5022
+ // CancelledOrders's top-level args are (orderId, _order). The buyer's
5023
+ // address lives inside the _order tuple as _order.user.
5024
+ userFromLog: (log) => log.args._order?.user
5025
+ };
5026
+ var ALL_CONFIGS = [
5027
+ PLACED_CONFIG,
5028
+ ACCEPTED_CONFIG,
5029
+ PAID_CONFIG,
5030
+ COMPLETED_CONFIG,
5031
+ CANCELLED_CONFIG
5032
+ ];
5033
+ function createWatchEvents(input) {
5034
+ const { publicClient, diamondAddress } = input;
5035
+ return ({ user, onEvent, onError }) => {
5036
+ const unwatchers = [];
5037
+ for (const config of ALL_CONFIGS) {
5038
+ try {
5039
+ const unwatch = publicClient.watchContractEvent({
5040
+ address: diamondAddress,
5041
+ abi: ABIS.DIAMOND,
5042
+ eventName: config.eventName,
5043
+ onLogs: (logs) => {
5044
+ for (const log of logs) {
5045
+ if (user && config.userFromLog) {
5046
+ const logUser = config.userFromLog(log);
5047
+ if (!logUser || logUser.toLowerCase() !== user.toLowerCase()) continue;
5048
+ }
5049
+ onEvent(config.toEvent(log));
5050
+ }
5051
+ },
5052
+ onError: (err4) => {
5053
+ onError?.(
5054
+ new OrdersError(`watchContractEvent failed for ${config.eventName}`, {
5055
+ code: "EVENT_WATCH_FAILED",
5056
+ cause: err4,
5057
+ context: { eventName: config.eventName }
5058
+ })
5059
+ );
5060
+ }
5061
+ });
5062
+ unwatchers.push(unwatch);
5063
+ } catch (err4) {
5064
+ onError?.(
5065
+ new OrdersError(`failed to subscribe to ${config.eventName}`, {
5066
+ code: "EVENT_WATCH_FAILED",
5067
+ cause: err4,
5068
+ context: { eventName: config.eventName }
5069
+ })
5070
+ );
5071
+ }
5072
+ }
5073
+ return () => {
5074
+ for (const u of unwatchers) {
5075
+ try {
5076
+ u();
5077
+ } catch {
5078
+ }
5079
+ }
5080
+ };
5081
+ };
5082
+ }
5083
+
5084
+ // src/orders/client.ts
5085
+ function createOrders(config) {
5086
+ const { publicClient, diamondAddress, usdcAddress, subgraphUrl, relayIdentity } = config;
5087
+ const logger = config.logger ?? noopLogger;
5088
+ const relayIdentityStore = config.relayIdentityStore ?? createInMemoryRelayStore();
5089
+ const orderRouter = createOrderRouter({
5090
+ publicClient,
5091
+ subgraphUrl,
5092
+ contractAddress: diamondAddress,
5093
+ logger
5094
+ });
3089
5095
  return {
3090
- placeOrder(params) {
3091
- return buildPlaceOrderPayload(config.orderRouter, params);
5096
+ // ── Reads ─────────────────────────────────────────────────────────
5097
+ getOrder(params) {
5098
+ return validate(
5099
+ ZodGetOrderParamsSchema,
5100
+ params,
5101
+ (message, cause, d) => new OrdersError(message, {
5102
+ code: "INVALID_ORDER_ID",
5103
+ cause,
5104
+ context: { params: d }
5105
+ })
5106
+ ).asyncAndThen(
5107
+ ({ orderId }) => readOrderMulticall(publicClient, diamondAddress, orderId).mapErr(
5108
+ (cause) => new OrdersError("Order contract read failed", {
5109
+ code: "CONTRACT_READ_FAILED",
5110
+ cause,
5111
+ context: { orderId: orderId.toString() }
5112
+ })
5113
+ )
5114
+ ).andThen(
5115
+ ({ order, details }) => normalizeContractOrder(order, details).asyncAndThen((normalized) => {
5116
+ if (!normalized) {
5117
+ return errAsync3(
5118
+ new OrdersError("Order not found", {
5119
+ code: "ORDER_NOT_FOUND",
5120
+ context: { orderId: params.orderId.toString() }
5121
+ })
5122
+ );
5123
+ }
5124
+ logger.debug("getOrder resolved", { orderId: params.orderId.toString() });
5125
+ return okAsync4(normalized);
5126
+ })
5127
+ );
5128
+ },
5129
+ getOrders(params) {
5130
+ return validate(
5131
+ ZodGetOrdersParamsSchema,
5132
+ params,
5133
+ (message, cause, d) => new OrdersError(message, {
5134
+ code: "INVALID_GET_ORDERS_PARAMS",
5135
+ cause,
5136
+ context: { params: d }
5137
+ })
5138
+ ).asyncAndThen(
5139
+ ({ userAddress, skip, limit }) => getOrdersForUser(subgraphUrl, userAddress, skip, limit, logger)
5140
+ );
5141
+ },
5142
+ getFeeConfig(params) {
5143
+ return validate(
5144
+ ZodGetFeeConfigParamsSchema,
5145
+ params,
5146
+ (message, cause, d) => new OrdersError(message, {
5147
+ code: "INVALID_FEE_CONFIG_PARAMS",
5148
+ cause,
5149
+ context: { params: d }
5150
+ })
5151
+ ).asyncAndThen(
5152
+ ({ currency }) => readFeeConfigMulticall(publicClient, diamondAddress, currency).mapErr(
5153
+ (cause) => new OrdersError("Fee config contract read failed", {
5154
+ code: "CONTRACT_READ_FAILED",
5155
+ cause,
5156
+ context: { currency }
5157
+ })
5158
+ )
5159
+ ).map((config2) => {
5160
+ logger.debug("getFeeConfig resolved", { currency: params.currency });
5161
+ return config2;
5162
+ });
5163
+ },
5164
+ // ── Writes ────────────────────────────────────────────────────────
5165
+ placeOrder: createPlaceOrderAction({
5166
+ publicClient,
5167
+ diamondAddress,
5168
+ orderRouter,
5169
+ relayIdentityStore,
5170
+ relayIdentity
5171
+ }),
5172
+ cancelOrder: createCancelOrderAction({ publicClient, diamondAddress }),
5173
+ setSellOrderUpi: createSetSellOrderUpiAction({
5174
+ publicClient,
5175
+ diamondAddress,
5176
+ relayIdentityStore,
5177
+ relayIdentity
5178
+ }),
5179
+ raiseDispute: createRaiseDisputeAction({ publicClient, diamondAddress }),
5180
+ approveUsdc: createApproveUsdcAction({ publicClient, diamondAddress, usdcAddress }),
5181
+ paidBuyOrder: createPaidBuyOrderAction({ publicClient, diamondAddress }),
5182
+ watchEvents: createWatchEvents({ publicClient, diamondAddress }),
5183
+ // ── Crypto helpers ───────────────────────────────────────────────
5184
+ decryptPaymentAddress({ encrypted }) {
5185
+ return resolveRelayIdentity({ relayIdentity, store: relayIdentityStore }).andThen(
5186
+ (recipientIdentity) => decryptPaymentAddress({ encrypted, recipientIdentity })
5187
+ );
3092
5188
  },
3093
- setSellOrderUpi(params) {
3094
- return buildSetSellOrderUpiPayload(params);
5189
+ encryptPaymentAddress({ paymentAddress, recipientPublicKey }) {
5190
+ return resolveRelayIdentity({ relayIdentity, store: relayIdentityStore }).andThen(
5191
+ (senderIdentity) => encryptPaymentAddress({
5192
+ paymentAddress,
5193
+ recipientPublicKey,
5194
+ senderIdentity
5195
+ })
5196
+ );
3095
5197
  }
3096
5198
  };
3097
5199
  }
3098
5200
  export {
3099
- PayloadError,
5201
+ OrdersError,
3100
5202
  cipherParse,
3101
5203
  cipherStringify,
3102
- createPayloadGenerator,
5204
+ createInMemoryRelayStore,
5205
+ createLocalStorageRelayStore,
5206
+ createOrders,
3103
5207
  createRelayIdentity,
3104
5208
  decryptPaymentAddress,
3105
- encryptPaymentAddress,
3106
- getRelayIdentity
5209
+ encryptPaymentAddress
3107
5210
  };
3108
5211
  /*! Bundled license information:
3109
5212
 
@@ -3121,4 +5224,4 @@ export {
3121
5224
  @noble/curves/esm/secp256k1.js:
3122
5225
  (*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
3123
5226
  */
3124
- //# sourceMappingURL=payload.mjs.map
5227
+ //# sourceMappingURL=orders.mjs.map