@p2pdotme/sdk 1.0.5 → 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 +8 -1
  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 +5 -1
  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 +6 -6
  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 +6 -6
  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,888 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/order-routing/index.ts
21
- var order_routing_exports = {};
22
- __export(order_routing_exports, {
23
- OrderRoutingError: () => OrderRoutingError,
24
- createOrderRouter: () => createOrderRouter
25
- });
26
- module.exports = __toCommonJS(order_routing_exports);
27
-
28
- // src/order-routing/client.ts
29
- var import_viem6 = require("viem");
30
-
31
- // src/contracts/abis/index.ts
32
- var import_viem = require("viem");
33
-
34
- // src/contracts/abis/order-flow-facet.ts
35
- var orderFlowFacetAbi = [
36
- {
37
- inputs: [
38
- { internalType: "uint256", name: "circleId", type: "uint256" },
39
- { internalType: "uint256", name: "assignUpto", type: "uint256" },
40
- { internalType: "bytes32", name: "currency", type: "bytes32" },
41
- { internalType: "address", name: "user", type: "address" },
42
- { internalType: "uint256", name: "usdtAmount", type: "uint256" },
43
- { internalType: "uint256", name: "fiatAmount", type: "uint256" },
44
- { internalType: "int256", name: "orderType", type: "int256" },
45
- { internalType: "uint256", name: "preferredPCConfigId", type: "uint256" }
46
- ],
47
- name: "getAssignableMerchantsFromCircle",
48
- outputs: [{ internalType: "address[]", name: "", type: "address[]" }],
49
- stateMutability: "view",
50
- type: "function"
51
- },
52
- {
53
- inputs: [
54
- { internalType: "address", name: "_user", type: "address" },
55
- { internalType: "bytes32", name: "_nativeCurrency", type: "bytes32" }
56
- ],
57
- name: "userTxLimit",
58
- outputs: [
59
- { internalType: "uint256", name: "", type: "uint256" },
60
- { internalType: "uint256", name: "", type: "uint256" }
61
- ],
62
- stateMutability: "view",
63
- type: "function"
64
- }
65
- ];
66
-
67
- // src/contracts/abis/p2p-config-facet.ts
68
- var p2pConfigFacetAbi = [
69
- {
70
- inputs: [
71
- {
72
- internalType: "bytes32",
73
- name: "_currency",
74
- type: "bytes32"
75
- }
76
- ],
77
- name: "getPriceConfig",
78
- outputs: [
79
- {
80
- components: [
81
- {
82
- internalType: "uint256",
83
- name: "buyPrice",
84
- type: "uint256"
85
- },
86
- {
87
- internalType: "uint256",
88
- name: "sellPrice",
89
- type: "uint256"
90
- },
91
- {
92
- internalType: "int256",
93
- name: "buyPriceOffset",
94
- type: "int256"
95
- },
96
- {
97
- internalType: "uint256",
98
- name: "baseSpread",
99
- type: "uint256"
100
- }
101
- ],
102
- internalType: "struct P2pConfigStorage.PriceConfig",
103
- name: "",
104
- type: "tuple"
105
- }
106
- ],
107
- stateMutability: "view",
108
- type: "function"
109
- },
110
- {
111
- inputs: [
112
- {
113
- internalType: "bytes32",
114
- name: "_nativeCurrency",
115
- type: "bytes32"
116
- }
117
- ],
118
- name: "getRpPerUsdtLimitRational",
119
- outputs: [
120
- {
121
- internalType: "uint256",
122
- name: "numerator",
123
- type: "uint256"
124
- },
125
- {
126
- internalType: "uint256",
127
- name: "denominator",
128
- type: "uint256"
129
- }
130
- ],
131
- stateMutability: "view",
132
- type: "function"
133
- }
134
- ];
135
-
136
- // src/contracts/abis/reputation-manager.ts
137
- var reputationManagerAbi = [
138
- {
139
- inputs: [
140
- {
141
- internalType: "string",
142
- name: "_socialName",
143
- type: "string"
144
- },
145
- {
146
- components: [
147
- {
148
- components: [
149
- {
150
- internalType: "string",
151
- name: "provider",
152
- type: "string"
153
- },
154
- {
155
- internalType: "string",
156
- name: "parameters",
157
- type: "string"
158
- },
159
- {
160
- internalType: "string",
161
- name: "context",
162
- type: "string"
163
- }
164
- ],
165
- internalType: "struct IReclaimSDK.ClaimInfo",
166
- name: "claimInfo",
167
- type: "tuple"
168
- },
169
- {
170
- components: [
171
- {
172
- components: [
173
- {
174
- internalType: "bytes32",
175
- name: "identifier",
176
- type: "bytes32"
177
- },
178
- {
179
- internalType: "address",
180
- name: "owner",
181
- type: "address"
182
- },
183
- {
184
- internalType: "uint32",
185
- name: "timestampS",
186
- type: "uint32"
187
- },
188
- {
189
- internalType: "uint32",
190
- name: "epoch",
191
- type: "uint32"
192
- }
193
- ],
194
- internalType: "struct IReclaimSDK.CompleteClaimData",
195
- name: "claim",
196
- type: "tuple"
197
- },
198
- {
199
- internalType: "bytes[]",
200
- name: "signatures",
201
- type: "bytes[]"
202
- }
203
- ],
204
- internalType: "struct IReclaimSDK.SignedClaim",
205
- name: "signedClaim",
206
- type: "tuple"
207
- }
208
- ],
209
- internalType: "struct IReclaimSDK.Proof[]",
210
- name: "proofs",
211
- type: "tuple[]"
212
- }
213
- ],
214
- name: "socialVerify",
215
- outputs: [],
216
- stateMutability: "nonpayable",
217
- type: "function"
218
- },
219
- {
220
- inputs: [
221
- {
222
- internalType: "uint256",
223
- name: "nullifierSeed",
224
- type: "uint256"
225
- },
226
- {
227
- internalType: "uint256",
228
- name: "nullifier",
229
- type: "uint256"
230
- },
231
- {
232
- internalType: "uint256",
233
- name: "timestamp",
234
- type: "uint256"
235
- },
236
- {
237
- internalType: "uint256",
238
- name: "signal",
239
- type: "uint256"
240
- },
241
- {
242
- internalType: "uint256[4]",
243
- name: "revealArray",
244
- type: "uint256[4]"
245
- },
246
- {
247
- internalType: "uint256[8]",
248
- name: "groth16Proof",
249
- type: "uint256[8]"
250
- }
251
- ],
252
- name: "submitAnonAadharProof",
253
- outputs: [],
254
- stateMutability: "nonpayable",
255
- type: "function"
256
- },
257
- {
258
- inputs: [
259
- {
260
- components: [
261
- {
262
- internalType: "bytes32",
263
- name: "version",
264
- type: "bytes32"
265
- },
266
- {
267
- components: [
268
- {
269
- internalType: "bytes32",
270
- name: "vkeyHash",
271
- type: "bytes32"
272
- },
273
- {
274
- internalType: "bytes",
275
- name: "proof",
276
- type: "bytes"
277
- },
278
- {
279
- internalType: "bytes32[]",
280
- name: "publicInputs",
281
- type: "bytes32[]"
282
- }
283
- ],
284
- internalType: "struct ProofVerificationData",
285
- name: "proofVerificationData",
286
- type: "tuple"
287
- },
288
- {
289
- internalType: "bytes",
290
- name: "committedInputs",
291
- type: "bytes"
292
- },
293
- {
294
- components: [
295
- {
296
- internalType: "uint256",
297
- name: "validityPeriodInSeconds",
298
- type: "uint256"
299
- },
300
- {
301
- internalType: "string",
302
- name: "domain",
303
- type: "string"
304
- },
305
- {
306
- internalType: "string",
307
- name: "scope",
308
- type: "string"
309
- },
310
- {
311
- internalType: "bool",
312
- name: "devMode",
313
- type: "bool"
314
- }
315
- ],
316
- internalType: "struct ServiceConfig",
317
- name: "serviceConfig",
318
- type: "tuple"
319
- }
320
- ],
321
- internalType: "struct ProofVerificationParams",
322
- name: "params",
323
- type: "tuple"
324
- },
325
- {
326
- internalType: "bool",
327
- name: "isIDCard",
328
- type: "bool"
329
- }
330
- ],
331
- name: "zkPassportRegister",
332
- outputs: [],
333
- stateMutability: "nonpayable",
334
- type: "function"
335
- }
336
- ];
337
-
338
- // src/contracts/abis/index.ts
339
- var DIAMOND_ABI = [...orderFlowFacetAbi, ...p2pConfigFacetAbi];
340
- var ABIS = {
341
- DIAMOND: DIAMOND_ABI,
342
- FACETS: {
343
- ORDER_FLOW: orderFlowFacetAbi,
344
- CONFIG: p2pConfigFacetAbi
345
- },
346
- EXTERNAL: {
347
- USDC: import_viem.erc20Abi,
348
- REPUTATION_MANAGER: reputationManagerAbi
349
- }
350
- };
351
-
352
- // src/contracts/order-flow/index.ts
353
- var import_neverthrow2 = require("neverthrow");
354
-
355
- // src/lib/logger.ts
356
- var noop = () => {
357
- };
358
- var noopLogger = {
359
- debug: noop,
360
- info: noop,
361
- warn: noop,
362
- error: noop
363
- };
364
-
365
- // src/lib/sleep.ts
366
- function sleep(ms) {
367
- return new Promise((resolve) => setTimeout(resolve, ms));
368
- }
369
-
370
- // src/validation/errors.validation.ts
371
- var SdkError = class extends Error {
372
- code;
373
- cause;
374
- context;
375
- constructor(message, options) {
376
- super(message);
377
- this.name = "SdkError";
378
- this.code = options.code;
379
- this.cause = options.cause;
380
- this.context = options.context;
381
- }
382
- };
383
-
384
- // src/validation/schemas.validation.ts
385
- var import_neverthrow = require("neverthrow");
386
- var import_viem2 = require("viem");
387
- var import_zod = require("zod");
388
-
389
- // src/constants/currencies.constant.ts
390
- var CURRENCY = {
391
- IDR: "IDR",
392
- INR: "INR",
393
- BRL: "BRL",
394
- ARS: "ARS",
395
- MEX: "MEX",
396
- VEN: "VEN",
397
- EUR: "EUR",
398
- NGN: "NGN",
399
- USD: "USD",
400
- COP: "COP"
401
- };
402
-
403
- // src/validation/schemas.validation.ts
404
- var ZodAddressSchema = import_zod.z.string().refine((s) => (0, import_viem2.isAddress)(s), { message: "Invalid Ethereum address" });
405
- var ZodCurrencySchema = import_zod.z.enum(Object.values(CURRENCY));
406
- function validate(schema, data, toError) {
407
- const result = schema.safeParse(data);
408
- if (result.success) {
409
- return (0, import_neverthrow.ok)(result.data);
410
- }
411
- return (0, import_neverthrow.err)(toError(import_zod.z.prettifyError(result.error), result.error, data));
412
- }
413
-
414
- // src/order-routing/errors.ts
415
- var OrderRoutingError = class extends SdkError {
416
- constructor(message, options) {
417
- super(message, options);
418
- this.name = "OrderRoutingError";
419
- }
420
- };
421
-
422
- // src/order-routing/validation.ts
423
- var import_zod2 = require("zod");
424
- var ZodCircleScoreStateSchema = import_zod2.z.object({
425
- activeMerchantsCount: import_zod2.z.coerce.number()
426
- });
427
- var ZodCircleMetricsForRoutingSchema = import_zod2.z.object({
428
- circleScore: import_zod2.z.coerce.number(),
429
- circleStatus: import_zod2.z.string(),
430
- scoreState: ZodCircleScoreStateSchema
431
- });
432
- var ZodCircleForRoutingSchema = import_zod2.z.object({
433
- circleId: import_zod2.z.string(),
434
- currency: import_zod2.z.string(),
435
- metrics: ZodCircleMetricsForRoutingSchema
436
- });
437
- var ZodCirclesForRoutingResponseSchema = import_zod2.z.object({
438
- circles: import_zod2.z.array(ZodCircleForRoutingSchema)
439
- });
440
- var ZodCheckCircleEligibilityParamsSchema = import_zod2.z.object({
441
- circleId: import_zod2.z.bigint(),
442
- currency: import_zod2.z.string(),
443
- user: ZodAddressSchema,
444
- usdtAmount: import_zod2.z.bigint(),
445
- fiatAmount: import_zod2.z.bigint(),
446
- orderType: import_zod2.z.bigint(),
447
- preferredPCConfigId: import_zod2.z.bigint()
448
- });
449
- var ZodSelectCircleParamsSchema = import_zod2.z.object({
450
- currency: import_zod2.z.string().min(1),
451
- user: ZodAddressSchema,
452
- usdtAmount: import_zod2.z.bigint(),
453
- fiatAmount: import_zod2.z.bigint(),
454
- orderType: import_zod2.z.bigint(),
455
- preferredPCConfigId: import_zod2.z.bigint()
456
- });
457
-
458
- // src/contracts/order-flow/index.ts
459
- function checkCircleEligibility(publicClient, contractAddress, params, logger = noopLogger) {
460
- return validate(
461
- ZodCheckCircleEligibilityParamsSchema,
462
- params,
463
- (message, cause, d) => new OrderRoutingError(message, { code: "VALIDATION_ERROR", cause, context: { data: d } })
464
- ).asyncAndThen((validated) => {
465
- logger.debug("checking on-chain eligibility", {
466
- circleId: String(validated.circleId),
467
- contractAddress
468
- });
469
- return import_neverthrow2.ResultAsync.fromPromise(
470
- publicClient.readContract({
471
- address: contractAddress,
472
- abi: ABIS.FACETS.ORDER_FLOW,
473
- functionName: "getAssignableMerchantsFromCircle",
474
- args: [
475
- validated.circleId,
476
- 1n,
477
- validated.currency,
478
- validated.user,
479
- validated.usdtAmount,
480
- validated.fiatAmount,
481
- validated.orderType,
482
- validated.preferredPCConfigId
483
- ]
484
- }),
485
- (error) => new OrderRoutingError("Eligibility check failed", {
486
- code: "CONTRACT_READ_ERROR",
487
- cause: error,
488
- context: { circleId: String(params.circleId) }
489
- })
490
- );
491
- }).map((merchants) => {
492
- const arr = merchants;
493
- const eligible = arr.length >= 1;
494
- logger.debug("eligibility check result", {
495
- circleId: String(params.circleId),
496
- assignableMerchants: arr.length,
497
- eligible
498
- });
499
- return eligible;
500
- });
501
- }
502
-
503
- // src/contracts/p2p-config/index.ts
504
- var import_neverthrow3 = require("neverthrow");
505
- var import_viem3 = require("viem");
506
-
507
- // src/profile/validation.ts
508
- var import_zod3 = require("zod");
509
- var ZodUsdcBalanceParamsSchema = import_zod3.z.object({
510
- address: ZodAddressSchema
511
- });
512
- var ZodGetBalancesParamsSchema = import_zod3.z.object({
513
- address: ZodAddressSchema,
514
- currency: ZodCurrencySchema
515
- });
516
- var ZodTxLimitsParamsSchema = import_zod3.z.object({
517
- address: ZodAddressSchema,
518
- currency: ZodCurrencySchema
519
- });
520
- var ZodPriceConfigParamsSchema = import_zod3.z.object({
521
- currency: ZodCurrencySchema
522
- });
523
-
524
- // src/contracts/reputation-manager/writes.ts
525
- var import_neverthrow4 = require("neverthrow");
526
- var import_viem4 = require("viem");
527
-
528
- // src/zkkyc/validation.ts
529
- var import_zod4 = require("zod");
530
- var ZodAnonAadharProofParamsSchema = import_zod4.z.object({
531
- nullifierSeed: import_zod4.z.bigint(),
532
- nullifier: import_zod4.z.bigint(),
533
- timestamp: import_zod4.z.bigint(),
534
- signal: import_zod4.z.bigint(),
535
- revealArray: import_zod4.z.tuple([import_zod4.z.bigint(), import_zod4.z.bigint(), import_zod4.z.bigint(), import_zod4.z.bigint()]),
536
- packedGroth16Proof: import_zod4.z.tuple([
537
- import_zod4.z.bigint(),
538
- import_zod4.z.bigint(),
539
- import_zod4.z.bigint(),
540
- import_zod4.z.bigint(),
541
- import_zod4.z.bigint(),
542
- import_zod4.z.bigint(),
543
- import_zod4.z.bigint(),
544
- import_zod4.z.bigint()
545
- ])
546
- });
547
- var ZodSocialVerifyParamsSchema = import_zod4.z.object({
548
- _socialName: import_zod4.z.string(),
549
- proofs: import_zod4.z.array(
550
- import_zod4.z.object({
551
- claimInfo: import_zod4.z.object({
552
- provider: import_zod4.z.string(),
553
- parameters: import_zod4.z.string(),
554
- context: import_zod4.z.string()
555
- }),
556
- signedClaim: import_zod4.z.object({
557
- claim: import_zod4.z.object({
558
- identifier: import_zod4.z.string(),
559
- owner: ZodAddressSchema,
560
- timestampS: import_zod4.z.number(),
561
- epoch: import_zod4.z.number()
562
- }),
563
- signatures: import_zod4.z.array(import_zod4.z.string())
564
- })
565
- })
566
- )
567
- });
568
- var ZodSolidityVerifierParametersSchema = import_zod4.z.object({
569
- version: import_zod4.z.string().refine((val) => val.startsWith("0x"), {
570
- message: "Version must be a hex string"
571
- }),
572
- proofVerificationData: import_zod4.z.object({
573
- vkeyHash: import_zod4.z.string().refine((val) => /^0x[a-fA-F0-9]{64}$/.test(val), {
574
- message: "Invalid bytes32 hex string"
575
- }),
576
- proof: import_zod4.z.string().refine((val) => val.startsWith("0x"), {
577
- message: "Proof must be a hex string"
578
- }),
579
- publicInputs: import_zod4.z.array(
580
- import_zod4.z.string().refine((val) => /^0x[a-fA-F0-9]{64}$/.test(val), {
581
- message: "Each public input must be a valid bytes32 hex string"
582
- })
583
- )
584
- }),
585
- committedInputs: import_zod4.z.string().refine((val) => val.startsWith("0x"), {
586
- message: "Committed inputs must be a hex string"
587
- }),
588
- serviceConfig: import_zod4.z.object({
589
- validityPeriodInSeconds: import_zod4.z.number().int().nonnegative(),
590
- domain: import_zod4.z.string(),
591
- scope: import_zod4.z.string(),
592
- devMode: import_zod4.z.boolean()
593
- })
594
- });
595
- var ZodZkPassportRegisterParamsSchema = import_zod4.z.object({
596
- params: ZodSolidityVerifierParametersSchema,
597
- isIDCard: import_zod4.z.boolean()
598
- });
599
-
600
- // src/contracts/tx-limits/index.ts
601
- var import_neverthrow5 = require("neverthrow");
602
- var import_viem5 = require("viem");
603
-
604
- // src/contracts/usdc/index.ts
605
- var import_neverthrow6 = require("neverthrow");
606
-
607
- // src/order-routing/routing.ts
608
- var import_neverthrow7 = require("neverthrow");
609
- var EPSILON = 0.25;
610
- var RECOVERY_SCALE = 0.3;
611
- var BOOTSTRAP_MAX_WEIGHT = 25;
612
- var MAX_VALIDATION_ATTEMPTS = 3;
613
- function circleWeight(c) {
614
- const score = c.metrics.circleScore;
615
- if (c.metrics.circleStatus === "paused") {
616
- return score * RECOVERY_SCALE;
617
- }
618
- if (c.metrics.circleStatus === "bootstrap") {
619
- return Math.min(score, BOOTSTRAP_MAX_WEIGHT);
620
- }
621
- return score;
622
- }
623
- function filterEligibleCircles(circles, orderCurrency) {
624
- return circles.filter((c) => c.currency.toLowerCase() === orderCurrency.toLowerCase());
625
- }
626
- function weightedRandomChoice(arr, weights) {
627
- const totalWeight = weights.reduce((sum, w) => sum + w, 0);
628
- if (totalWeight === 0) {
629
- return arr[Math.floor(Math.random() * arr.length)];
630
- }
631
- let rand = Math.random() * totalWeight;
632
- for (let i = 0; i < arr.length; i++) {
633
- rand -= weights[i];
634
- if (rand <= 0) {
635
- return arr[i];
636
- }
637
- }
638
- return arr[arr.length - 1];
639
- }
640
- function selectCircle(eligible) {
641
- if (eligible.length === 0) {
642
- return null;
643
- }
644
- const activeCircles = eligible.filter((c) => c.metrics.circleStatus === "active");
645
- const isExplore = Math.random() < EPSILON;
646
- if (isExplore) {
647
- const weights2 = eligible.map(circleWeight);
648
- return weightedRandomChoice(eligible, weights2);
649
- }
650
- if (activeCircles.length === 0) {
651
- const weights2 = eligible.map(circleWeight);
652
- return weightedRandomChoice(eligible, weights2);
653
- }
654
- const weights = activeCircles.map((c) => c.metrics.circleScore);
655
- return weightedRandomChoice(activeCircles, weights);
656
- }
657
- function selectCircleForOrderAsync(circles, orderCurrency, validateCircle, logger = noopLogger) {
658
- const eligible = filterEligibleCircles(circles, orderCurrency);
659
- let remaining = [...eligible];
660
- logger.debug("filtering eligible circles", {
661
- total: circles.length,
662
- eligible: eligible.length,
663
- currency: orderCurrency,
664
- circles: eligible
665
- });
666
- if (eligible.length === 0) {
667
- logger.warn("no eligible circles found for currency", { currency: orderCurrency });
668
- }
669
- function attempt(attemptsLeft) {
670
- if (attemptsLeft <= 0 || remaining.length === 0) {
671
- logger.warn("exhausted all attempts or circles", {
672
- attemptsLeft,
673
- remainingCircles: remaining.length
674
- });
675
- return (0, import_neverthrow7.errAsync)(
676
- new OrderRoutingError("No eligible circles found", {
677
- code: "NO_ELIGIBLE_CIRCLES"
678
- })
679
- );
680
- }
681
- const selected = selectCircle(remaining);
682
- if (!selected) {
683
- return (0, import_neverthrow7.errAsync)(
684
- new OrderRoutingError("No eligible circles found", {
685
- code: "NO_ELIGIBLE_CIRCLES"
686
- })
687
- );
688
- }
689
- const circleId = BigInt(selected.circleId);
690
- logger.debug("selected circle, validating on-chain", {
691
- circleId: String(circleId),
692
- status: selected.metrics.circleStatus,
693
- score: selected.metrics.circleScore,
694
- attemptsLeft
695
- });
696
- return validateCircle(circleId).orElse((error) => {
697
- logger.warn("validation errored, treating as ineligible", {
698
- circleId: String(circleId),
699
- error: String(error)
700
- });
701
- return (0, import_neverthrow7.okAsync)(false);
702
- }).andThen((isValid) => {
703
- if (isValid) {
704
- logger.info("circle validated successfully", { circleId: String(circleId) });
705
- return (0, import_neverthrow7.okAsync)(circleId);
706
- }
707
- logger.debug("circle failed validation, retrying", {
708
- circleId: String(circleId),
709
- remainingCircles: remaining.length - 1
710
- });
711
- remaining = remaining.filter((c) => c.circleId !== selected.circleId);
712
- return attempt(attemptsLeft - 1);
713
- });
714
- }
715
- return attempt(MAX_VALIDATION_ATTEMPTS);
716
- }
717
-
718
- // src/order-routing/subgraph/client.ts
719
- var import_neverthrow8 = require("neverthrow");
720
- var DEFAULT_TIMEOUT_MS = 1e4;
721
- var MAX_RETRIES = 3;
722
- var BACKOFF_MS = 500;
723
- function isTransient(error) {
724
- if (error instanceof OrderRoutingError) return false;
725
- if (error instanceof DOMException && error.name === "AbortError") return true;
726
- if (error instanceof TypeError) return true;
727
- return false;
728
- }
729
- function querySubgraph(url, params) {
730
- const timeoutMs = params.timeoutMs ?? DEFAULT_TIMEOUT_MS;
731
- const fetchOnce = async () => {
732
- const controller = new AbortController();
733
- const timer = setTimeout(() => controller.abort(), timeoutMs);
734
- try {
735
- const response = await fetch(url, {
736
- method: "POST",
737
- headers: { "Content-Type": "application/json" },
738
- body: JSON.stringify({
739
- query: params.query,
740
- variables: params.variables
741
- }),
742
- signal: controller.signal
743
- });
744
- if (!response.ok) {
745
- throw new OrderRoutingError(`Subgraph request failed (status: ${response.status})`, {
746
- code: "SUBGRAPH_ERROR",
747
- cause: response,
748
- context: { status: response.status }
749
- });
750
- }
751
- const json = await response.json();
752
- if (json.errors?.length > 0) {
753
- throw new OrderRoutingError("Subgraph returned GraphQL errors", {
754
- code: "SUBGRAPH_ERROR",
755
- cause: json.errors,
756
- context: { errors: json.errors }
757
- });
758
- }
759
- if (!json.data) {
760
- throw new OrderRoutingError("Subgraph returned no data", {
761
- code: "SUBGRAPH_ERROR",
762
- cause: "Missing data field in GraphQL response",
763
- context: { response: json }
764
- });
765
- }
766
- return json.data;
767
- } finally {
768
- clearTimeout(timer);
769
- }
770
- };
771
- const fetchWithRetry = async () => {
772
- for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
773
- try {
774
- return await fetchOnce();
775
- } catch (error) {
776
- const lastAttempt = attempt === MAX_RETRIES;
777
- if (lastAttempt || !isTransient(error)) throw error;
778
- await sleep(BACKOFF_MS * (attempt + 1));
779
- }
780
- }
781
- throw new OrderRoutingError("Subgraph query exhausted retries", {
782
- code: "SUBGRAPH_ERROR"
783
- });
784
- };
785
- return import_neverthrow8.ResultAsync.fromPromise(
786
- fetchWithRetry(),
787
- (error) => error instanceof OrderRoutingError ? error : new OrderRoutingError("Subgraph query failed", {
788
- code: "SUBGRAPH_ERROR",
789
- cause: error
790
- })
791
- );
792
- }
793
-
794
- // src/order-routing/subgraph/queries.ts
795
- var CIRCLES_FOR_ROUTING_QUERY = (
796
- /* GraphQL */
797
- `
798
- query CirclesForRouting($currency: Bytes!) {
799
- circles(
800
- first: 1000
801
- where: {
802
- currency: $currency
803
- metrics_: {
804
- circleStatus_in: ["active", "bootstrap", "paused"]
805
- }
806
- }
807
- ) {
808
- circleId
809
- currency
810
- metrics {
811
- circleScore
812
- circleStatus
813
- scoreState {
814
- activeMerchantsCount
815
- }
816
- }
817
- }
818
- }
819
- `
820
- );
821
-
822
- // src/order-routing/subgraph/index.ts
823
- function getCirclesForRouting(subgraphUrl, currency, logger = noopLogger) {
824
- logger.debug("fetching circles from subgraph", { subgraphUrl, currency });
825
- return querySubgraph(subgraphUrl, {
826
- query: CIRCLES_FOR_ROUTING_QUERY,
827
- variables: { currency }
828
- }).andThen(
829
- (data) => validate(
830
- ZodCirclesForRoutingResponseSchema,
831
- data,
832
- (message, cause, d) => new OrderRoutingError(message, { code: "VALIDATION_ERROR", cause, context: { data: d } })
833
- ).map((validated) => {
834
- const circles = validated.circles.filter(
835
- (item) => Number(item.metrics.scoreState.activeMerchantsCount) > 0
836
- );
837
- logger.info("fetched circles from subgraph", {
838
- total: validated.circles.length,
839
- withActiveMerchants: circles.length,
840
- circles
841
- });
842
- return circles;
843
- })
844
- );
845
- }
846
-
847
- // src/order-routing/client.ts
848
- function createOrderRouter(config) {
849
- const { subgraphUrl, publicClient, contractAddress } = config;
850
- const logger = config.logger ?? noopLogger;
851
- return {
852
- selectCircle(params) {
853
- const currencyHex = (0, import_viem6.stringToHex)(params.currency, { size: 32 });
854
- logger.info("selectCircle started", {
855
- currency: params.currency,
856
- user: params.user,
857
- orderType: String(params.orderType)
858
- });
859
- return getCirclesForRouting(subgraphUrl, currencyHex, logger).andThen(
860
- (circles) => selectCircleForOrderAsync(
861
- circles,
862
- currencyHex,
863
- (circleId) => checkCircleEligibility(
864
- publicClient,
865
- contractAddress,
866
- {
867
- circleId,
868
- currency: currencyHex,
869
- user: params.user,
870
- usdtAmount: params.usdtAmount,
871
- fiatAmount: params.fiatAmount,
872
- orderType: params.orderType,
873
- preferredPCConfigId: params.preferredPCConfigId
874
- },
875
- logger
876
- ),
877
- logger
878
- )
879
- );
880
- }
881
- };
882
- }
883
- // Annotate the CommonJS export names for ESM import in node:
884
- 0 && (module.exports = {
885
- OrderRoutingError,
886
- createOrderRouter
887
- });
888
- //# sourceMappingURL=order-routing.cjs.map