@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
package/dist/react.cjs CHANGED
@@ -33,10 +33,11 @@ __export(react_exports, {
33
33
  SdkProvider: () => SdkProvider,
34
34
  useFingerprint: () => useFingerprint,
35
35
  useFraudEngine: () => useFraudEngine,
36
- useOrderRouter: () => useOrderRouter,
37
- usePayloadGenerator: () => usePayloadGenerator,
36
+ useOrders: () => useOrders,
37
+ usePrices: () => usePrices,
38
38
  useProfile: () => useProfile,
39
39
  useSdk: () => useSdk,
40
+ useWatchOrders: () => useWatchOrders,
40
41
  useZkkyc: () => useZkkyc
41
42
  });
42
43
  module.exports = __toCommonJS(react_exports);
@@ -45,7 +46,7 @@ module.exports = __toCommonJS(react_exports);
45
46
  var import_react = require("react");
46
47
 
47
48
  // src/fraud-engine/client.ts
48
- var import_neverthrow3 = require("neverthrow");
49
+ var import_neverthrow4 = require("neverthrow");
49
50
 
50
51
  // src/lib/encoding.ts
51
52
  function hexToBytes(hex) {
@@ -78,48 +79,8 @@ function sleep(ms) {
78
79
  return new Promise((resolve) => setTimeout(resolve, ms));
79
80
  }
80
81
 
81
- // src/fraud-engine/device.ts
82
- function getBasicDeviceDetails() {
83
- const nav = typeof navigator !== "undefined" ? navigator : void 0;
84
- const win = typeof window !== "undefined" ? window : void 0;
85
- return {
86
- userAgent: nav?.userAgent ?? "",
87
- platform: nav?.platform ?? "",
88
- language: nav?.language ?? "",
89
- languages: nav ? Array.from(nav.languages) : [],
90
- screenWidth: win?.screen?.width ?? 0,
91
- screenHeight: win?.screen?.height ?? 0,
92
- devicePixelRatio: win?.devicePixelRatio ?? 1,
93
- timezone: Intl?.DateTimeFormat?.()?.resolvedOptions?.()?.timeZone ?? "",
94
- timezoneOffset: (/* @__PURE__ */ new Date()).getTimezoneOffset(),
95
- cookiesEnabled: nav?.cookieEnabled ?? false,
96
- doNotTrack: nav?.doNotTrack ?? null,
97
- online: nav?.onLine ?? true,
98
- connectionType: nav?.connection?.effectiveType,
99
- deviceMemory: nav?.deviceMemory,
100
- hardwareConcurrency: nav?.hardwareConcurrency,
101
- touchSupport: nav ? "ontouchstart" in window : false,
102
- maxTouchPoints: nav?.maxTouchPoints ?? 0,
103
- vendor: nav?.vendor ?? "",
104
- appVersion: nav?.appVersion ?? "",
105
- colorDepth: win?.screen?.colorDepth ?? 0,
106
- pixelDepth: win?.screen?.pixelDepth ?? 0
107
- };
108
- }
109
- async function fetchIpAddress() {
110
- try {
111
- const response = await fetch("https://api.ipify.org?format=json");
112
- const data = await response.json();
113
- return data.ip;
114
- } catch {
115
- return void 0;
116
- }
117
- }
118
- async function getDeviceDetails(seonSession) {
119
- const basic = getBasicDeviceDetails();
120
- const ip = await fetchIpAddress();
121
- return { ...basic, ip, seonSession };
122
- }
82
+ // src/lib/subgraph.ts
83
+ var import_neverthrow2 = require("neverthrow");
123
84
 
124
85
  // src/validation/errors.validation.ts
125
86
  var SdkError = class extends Error {
@@ -140,7 +101,7 @@ var import_neverthrow = require("neverthrow");
140
101
  var import_viem = require("viem");
141
102
  var import_zod = require("zod");
142
103
 
143
- // src/constants/currencies.constant.ts
104
+ // src/country/currency.ts
144
105
  var CURRENCY = {
145
106
  IDR: "IDR",
146
107
  INR: "INR",
@@ -153,17 +114,11 @@ var CURRENCY = {
153
114
  USD: "USD",
154
115
  COP: "COP"
155
116
  };
156
-
157
- // src/constants/orders.constant.ts
158
- var ORDER_TYPE = {
159
- BUY: 0,
160
- SELL: 1,
161
- PAY: 2
162
- };
117
+ var CURRENCY_CODES = Object.values(CURRENCY);
163
118
 
164
119
  // src/validation/schemas.validation.ts
165
120
  var ZodAddressSchema = import_zod.z.string().refine((s) => (0, import_viem.isAddress)(s), { message: "Invalid Ethereum address" });
166
- var ZodCurrencySchema = import_zod.z.enum(Object.values(CURRENCY));
121
+ var ZodCurrencySchema = import_zod.z.enum(CURRENCY_CODES);
167
122
  function validate(schema, data, toError) {
168
123
  const result = schema.safeParse(data);
169
124
  if (result.success) {
@@ -172,6 +127,132 @@ function validate(schema, data, toError) {
172
127
  return (0, import_neverthrow.err)(toError(import_zod.z.prettifyError(result.error), result.error, data));
173
128
  }
174
129
 
130
+ // src/lib/subgraph.ts
131
+ var DEFAULT_TIMEOUT_MS = 1e4;
132
+ var MAX_RETRIES = 3;
133
+ var BACKOFF_MS = 500;
134
+ var SubgraphError = class extends SdkError {
135
+ constructor(message, options) {
136
+ super(message, options);
137
+ this.name = "SubgraphError";
138
+ }
139
+ };
140
+ function isTransient(error) {
141
+ if (error instanceof SubgraphError) {
142
+ if (error.code !== "HTTP_ERROR") return false;
143
+ const status = error.context?.status;
144
+ return typeof status === "number" && status >= 500;
145
+ }
146
+ if (error instanceof DOMException && error.name === "AbortError") return true;
147
+ if (error instanceof TypeError) return true;
148
+ return false;
149
+ }
150
+ function querySubgraph(url, params) {
151
+ const timeoutMs = params.timeoutMs ?? DEFAULT_TIMEOUT_MS;
152
+ const fetchOnce = async () => {
153
+ const controller = new AbortController();
154
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
155
+ try {
156
+ const response = await fetch(url, {
157
+ method: "POST",
158
+ headers: { "Content-Type": "application/json" },
159
+ body: JSON.stringify({
160
+ query: params.query,
161
+ variables: params.variables
162
+ }),
163
+ signal: controller.signal
164
+ });
165
+ if (!response.ok) {
166
+ throw new SubgraphError(`Subgraph request failed (status: ${response.status})`, {
167
+ code: "HTTP_ERROR",
168
+ cause: response,
169
+ context: { status: response.status }
170
+ });
171
+ }
172
+ const json = await response.json();
173
+ if (json.errors?.length > 0) {
174
+ throw new SubgraphError("Subgraph returned GraphQL errors", {
175
+ code: "GRAPHQL_ERROR",
176
+ cause: json.errors,
177
+ context: { errors: json.errors }
178
+ });
179
+ }
180
+ if (!json.data) {
181
+ throw new SubgraphError("Subgraph returned no data", {
182
+ code: "NO_DATA",
183
+ cause: "Missing data field in GraphQL response",
184
+ context: { response: json }
185
+ });
186
+ }
187
+ return json.data;
188
+ } finally {
189
+ clearTimeout(timer);
190
+ }
191
+ };
192
+ const fetchWithRetry = async () => {
193
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
194
+ try {
195
+ return await fetchOnce();
196
+ } catch (error) {
197
+ const lastAttempt = attempt === MAX_RETRIES;
198
+ if (lastAttempt || !isTransient(error)) throw error;
199
+ await sleep(BACKOFF_MS * (attempt + 1));
200
+ }
201
+ }
202
+ throw new SubgraphError("Subgraph query exhausted retries", { code: "TRANSPORT_ERROR" });
203
+ };
204
+ return import_neverthrow2.ResultAsync.fromPromise(
205
+ fetchWithRetry(),
206
+ (error) => error instanceof SubgraphError ? error : new SubgraphError("Subgraph query failed", {
207
+ code: "TRANSPORT_ERROR",
208
+ cause: error
209
+ })
210
+ );
211
+ }
212
+
213
+ // src/fraud-engine/device.ts
214
+ function getBasicDeviceDetails() {
215
+ const nav = typeof navigator !== "undefined" ? navigator : void 0;
216
+ const win = typeof window !== "undefined" ? window : void 0;
217
+ return {
218
+ userAgent: nav?.userAgent ?? "",
219
+ platform: nav?.platform ?? "",
220
+ language: nav?.language ?? "",
221
+ languages: nav ? Array.from(nav.languages) : [],
222
+ screenWidth: win?.screen?.width ?? 0,
223
+ screenHeight: win?.screen?.height ?? 0,
224
+ devicePixelRatio: win?.devicePixelRatio ?? 1,
225
+ timezone: Intl?.DateTimeFormat?.()?.resolvedOptions?.()?.timeZone ?? "",
226
+ timezoneOffset: (/* @__PURE__ */ new Date()).getTimezoneOffset(),
227
+ cookiesEnabled: nav?.cookieEnabled ?? false,
228
+ doNotTrack: nav?.doNotTrack ?? null,
229
+ online: nav?.onLine ?? true,
230
+ connectionType: nav?.connection?.effectiveType,
231
+ deviceMemory: nav?.deviceMemory,
232
+ hardwareConcurrency: nav?.hardwareConcurrency,
233
+ touchSupport: nav ? "ontouchstart" in window : false,
234
+ maxTouchPoints: nav?.maxTouchPoints ?? 0,
235
+ vendor: nav?.vendor ?? "",
236
+ appVersion: nav?.appVersion ?? "",
237
+ colorDepth: win?.screen?.colorDepth ?? 0,
238
+ pixelDepth: win?.screen?.pixelDepth ?? 0
239
+ };
240
+ }
241
+ async function fetchIpAddress() {
242
+ try {
243
+ const response = await fetch("https://api.ipify.org?format=json");
244
+ const data = await response.json();
245
+ return data.ip;
246
+ } catch {
247
+ return void 0;
248
+ }
249
+ }
250
+ async function getDeviceDetails(seonSession) {
251
+ const basic = getBasicDeviceDetails();
252
+ const ip = await fetchIpAddress();
253
+ return { ...basic, ip, seonSession };
254
+ }
255
+
175
256
  // src/fraud-engine/errors.ts
176
257
  var FraudEngineError = class extends SdkError {
177
258
  constructor(message, options) {
@@ -302,7 +383,7 @@ async function getSignedHeaders(signer, action) {
302
383
  }
303
384
 
304
385
  // src/fraud-engine/validation.ts
305
- var import_neverthrow2 = require("neverthrow");
386
+ var import_neverthrow3 = require("neverthrow");
306
387
  var import_zod2 = require("zod");
307
388
  var ZodFraudEngineConfigSchema = import_zod2.z.object({
308
389
  apiUrl: import_zod2.z.url(),
@@ -334,9 +415,9 @@ var ZodLinkOrderParamsSchema = import_zod2.z.object({
334
415
  function validate2(schema, data) {
335
416
  const result = schema.safeParse(data);
336
417
  if (result.success) {
337
- return (0, import_neverthrow2.ok)(result.data);
418
+ return (0, import_neverthrow3.ok)(result.data);
338
419
  }
339
- return (0, import_neverthrow2.err)(
420
+ return (0, import_neverthrow3.err)(
340
421
  new FraudEngineError(import_zod2.z.prettifyError(result.error), {
341
422
  code: "VALIDATION_ERROR",
342
423
  cause: result.error,
@@ -363,7 +444,7 @@ function createFraudEngine(config) {
363
444
  );
364
445
  }
365
446
  function linkOrderInternal(signer, activityLogId, orderId) {
366
- return import_neverthrow3.ResultAsync.fromPromise(
447
+ return import_neverthrow4.ResultAsync.fromPromise(
367
448
  (async () => {
368
449
  logger.info("Linking order to activity log", { activityLogId, orderId });
369
450
  const signedHeaders = await getSignedHeaders(signer, "link-order");
@@ -480,8 +561,8 @@ function createFraudEngine(config) {
480
561
  logger.info("Fraud engine initialized");
481
562
  },
482
563
  checkBuyOrder(params) {
483
- if (configError) return (0, import_neverthrow3.errAsync)(configError);
484
- return import_neverthrow3.ResultAsync.fromPromise(
564
+ if (configError) return (0, import_neverthrow4.errAsync)(configError);
565
+ return import_neverthrow4.ResultAsync.fromPromise(
485
566
  checkBuyOrderInternal(params).then((data) => ({
486
567
  approved: data.approved,
487
568
  activityLogId: data.activity_log_id,
@@ -498,8 +579,8 @@ function createFraudEngine(config) {
498
579
  );
499
580
  },
500
581
  processBuyOrder(params) {
501
- if (configError) return (0, import_neverthrow3.errAsync)(configError);
502
- return import_neverthrow3.ResultAsync.fromPromise(
582
+ if (configError) return (0, import_neverthrow4.errAsync)(configError);
583
+ return import_neverthrow4.ResultAsync.fromPromise(
503
584
  (async () => {
504
585
  let activityLogId = null;
505
586
  try {
@@ -543,8 +624,8 @@ function createFraudEngine(config) {
543
624
  );
544
625
  },
545
626
  logFingerprint(params) {
546
- if (configError) return (0, import_neverthrow3.errAsync)(configError);
547
- return import_neverthrow3.ResultAsync.fromPromise(
627
+ if (configError) return (0, import_neverthrow4.errAsync)(configError);
628
+ return import_neverthrow4.ResultAsync.fromPromise(
548
629
  (async () => {
549
630
  logger.info("Logging fingerprint");
550
631
  const fingerprintResult = await getFingerprint(5e3);
@@ -603,8 +684,12 @@ function createFraudEngine(config) {
603
684
  };
604
685
  }
605
686
 
606
- // src/order-routing/client.ts
607
- var import_viem6 = require("viem");
687
+ // src/orders/client.ts
688
+ var import_neverthrow17 = require("neverthrow");
689
+
690
+ // src/contracts/order-processor/index.ts
691
+ var import_neverthrow5 = require("neverthrow");
692
+ var import_viem3 = require("viem");
608
693
 
609
694
  // src/contracts/abis/index.ts
610
695
  var import_viem2 = require("viem");
@@ -639,67 +724,442 @@ var orderFlowFacetAbi = [
639
724
  ],
640
725
  stateMutability: "view",
641
726
  type: "function"
642
- }
643
- ];
644
-
645
- // src/contracts/abis/p2p-config-facet.ts
646
- var p2pConfigFacetAbi = [
727
+ },
647
728
  {
648
729
  inputs: [
649
- {
650
- internalType: "bytes32",
651
- name: "_currency",
652
- type: "bytes32"
653
- }
730
+ { internalType: "string", name: "_pubKey", type: "string" },
731
+ { internalType: "uint256", name: "_amount", type: "uint256" },
732
+ { internalType: "address", name: "_recipientAddr", type: "address" },
733
+ { internalType: "uint8", name: "_orderType", type: "uint8" },
734
+ { internalType: "string", name: "_userUpi", type: "string" },
735
+ { internalType: "string", name: "_userPubKey", type: "string" },
736
+ { internalType: "bytes32", name: "_currency", type: "bytes32" },
737
+ { internalType: "uint256", name: "preferredPaymentChannelConfigId", type: "uint256" },
738
+ { internalType: "uint256", name: "_circleId", type: "uint256" },
739
+ { internalType: "uint256", name: "_fiatAmountLimit", type: "uint256" }
654
740
  ],
655
- name: "getPriceConfig",
656
- outputs: [
741
+ name: "placeOrder",
742
+ outputs: [],
743
+ stateMutability: "nonpayable",
744
+ type: "function"
745
+ },
746
+ {
747
+ inputs: [{ internalType: "uint256", name: "_orderId", type: "uint256" }],
748
+ name: "cancelOrder",
749
+ outputs: [],
750
+ stateMutability: "nonpayable",
751
+ type: "function"
752
+ },
753
+ {
754
+ inputs: [
755
+ { internalType: "uint256", name: "_orderId", type: "uint256" },
756
+ { internalType: "string", name: "_userEncUpi", type: "string" },
757
+ { internalType: "uint256", name: "_updatedAmount", type: "uint256" }
758
+ ],
759
+ name: "setSellOrderUpi",
760
+ outputs: [],
761
+ stateMutability: "nonpayable",
762
+ type: "function"
763
+ },
764
+ {
765
+ type: "event",
766
+ name: "OrderPlaced",
767
+ anonymous: false,
768
+ inputs: [
769
+ { indexed: true, name: "orderId", type: "uint256" },
770
+ { indexed: true, name: "user", type: "address" },
771
+ { indexed: true, name: "merchant", type: "address" },
772
+ { indexed: false, name: "amount", type: "uint256" },
773
+ { indexed: false, name: "orderType", type: "uint8" },
774
+ { indexed: false, name: "placedTimestamp", type: "uint256" },
657
775
  {
776
+ indexed: false,
777
+ name: "_order",
778
+ type: "tuple",
658
779
  components: [
780
+ { name: "amount", type: "uint256" },
781
+ { name: "fiatAmount", type: "uint256" },
782
+ { name: "placedTimestamp", type: "uint256" },
783
+ { name: "completedTimestamp", type: "uint256" },
784
+ { name: "userCompletedTimestamp", type: "uint256" },
785
+ { name: "acceptedMerchant", type: "address" },
786
+ { name: "user", type: "address" },
787
+ { name: "recipientAddr", type: "address" },
788
+ { name: "pubkey", type: "string" },
789
+ { name: "encUpi", type: "string" },
790
+ { name: "userCompleted", type: "bool" },
791
+ { name: "status", type: "uint8" },
792
+ { name: "orderType", type: "uint8" },
659
793
  {
660
- internalType: "uint256",
661
- name: "buyPrice",
662
- type: "uint256"
794
+ name: "disputeInfo",
795
+ type: "tuple",
796
+ components: [
797
+ { name: "raisedBy", type: "uint8" },
798
+ { name: "status", type: "uint8" },
799
+ { name: "redactTransId", type: "uint256" },
800
+ { name: "accountNumber", type: "uint256" }
801
+ ]
663
802
  },
803
+ { name: "id", type: "uint256" },
804
+ { name: "userPubKey", type: "string" },
805
+ { name: "encMerchantUpi", type: "string" },
806
+ { name: "acceptedAccountNo", type: "uint256" },
807
+ { name: "assignedAccountNos", type: "uint256[]" },
808
+ { name: "currency", type: "bytes32" },
809
+ { name: "preferredPaymentChannelConfigId", type: "uint256" },
810
+ { name: "circleId", type: "uint256" }
811
+ ]
812
+ }
813
+ ]
814
+ },
815
+ {
816
+ type: "event",
817
+ name: "OrderAccepted",
818
+ anonymous: false,
819
+ inputs: [
820
+ { indexed: true, name: "orderId", type: "uint256" },
821
+ { indexed: true, name: "merchant", type: "address" },
822
+ { indexed: false, name: "pubKey", type: "string" },
823
+ {
824
+ indexed: false,
825
+ name: "_order",
826
+ type: "tuple",
827
+ components: [
828
+ { name: "amount", type: "uint256" },
829
+ { name: "fiatAmount", type: "uint256" },
830
+ { name: "placedTimestamp", type: "uint256" },
831
+ { name: "completedTimestamp", type: "uint256" },
832
+ { name: "userCompletedTimestamp", type: "uint256" },
833
+ { name: "acceptedMerchant", type: "address" },
834
+ { name: "user", type: "address" },
835
+ { name: "recipientAddr", type: "address" },
836
+ { name: "pubkey", type: "string" },
837
+ { name: "encUpi", type: "string" },
838
+ { name: "userCompleted", type: "bool" },
839
+ { name: "status", type: "uint8" },
840
+ { name: "orderType", type: "uint8" },
664
841
  {
665
- internalType: "uint256",
666
- name: "sellPrice",
667
- type: "uint256"
842
+ name: "disputeInfo",
843
+ type: "tuple",
844
+ components: [
845
+ { name: "raisedBy", type: "uint8" },
846
+ { name: "status", type: "uint8" },
847
+ { name: "redactTransId", type: "uint256" },
848
+ { name: "accountNumber", type: "uint256" }
849
+ ]
668
850
  },
851
+ { name: "id", type: "uint256" },
852
+ { name: "userPubKey", type: "string" },
853
+ { name: "encMerchantUpi", type: "string" },
854
+ { name: "acceptedAccountNo", type: "uint256" },
855
+ { name: "assignedAccountNos", type: "uint256[]" },
856
+ { name: "currency", type: "bytes32" },
857
+ { name: "preferredPaymentChannelConfigId", type: "uint256" },
858
+ { name: "circleId", type: "uint256" }
859
+ ]
860
+ }
861
+ ]
862
+ },
863
+ {
864
+ type: "event",
865
+ name: "BuyOrderPaid",
866
+ anonymous: false,
867
+ inputs: [
868
+ { indexed: true, name: "orderId", type: "uint256" },
869
+ { indexed: true, name: "user", type: "address" },
870
+ {
871
+ indexed: false,
872
+ name: "_order",
873
+ type: "tuple",
874
+ components: [
875
+ { name: "amount", type: "uint256" },
876
+ { name: "fiatAmount", type: "uint256" },
877
+ { name: "placedTimestamp", type: "uint256" },
878
+ { name: "completedTimestamp", type: "uint256" },
879
+ { name: "userCompletedTimestamp", type: "uint256" },
880
+ { name: "acceptedMerchant", type: "address" },
881
+ { name: "user", type: "address" },
882
+ { name: "recipientAddr", type: "address" },
883
+ { name: "pubkey", type: "string" },
884
+ { name: "encUpi", type: "string" },
885
+ { name: "userCompleted", type: "bool" },
886
+ { name: "status", type: "uint8" },
887
+ { name: "orderType", type: "uint8" },
669
888
  {
670
- internalType: "int256",
671
- name: "buyPriceOffset",
672
- type: "int256"
889
+ name: "disputeInfo",
890
+ type: "tuple",
891
+ components: [
892
+ { name: "raisedBy", type: "uint8" },
893
+ { name: "status", type: "uint8" },
894
+ { name: "redactTransId", type: "uint256" },
895
+ { name: "accountNumber", type: "uint256" }
896
+ ]
673
897
  },
674
- {
675
- internalType: "uint256",
676
- name: "baseSpread",
677
- type: "uint256"
678
- }
679
- ],
680
- internalType: "struct P2pConfigStorage.PriceConfig",
681
- name: "",
682
- type: "tuple"
898
+ { name: "id", type: "uint256" },
899
+ { name: "userPubKey", type: "string" },
900
+ { name: "encMerchantUpi", type: "string" },
901
+ { name: "acceptedAccountNo", type: "uint256" },
902
+ { name: "assignedAccountNos", type: "uint256[]" },
903
+ { name: "currency", type: "bytes32" },
904
+ { name: "preferredPaymentChannelConfigId", type: "uint256" },
905
+ { name: "circleId", type: "uint256" }
906
+ ]
683
907
  }
684
- ],
685
- stateMutability: "view",
686
- type: "function"
908
+ ]
687
909
  },
688
910
  {
911
+ type: "event",
912
+ name: "OrderCompleted",
913
+ anonymous: false,
689
914
  inputs: [
915
+ { indexed: true, name: "orderId", type: "uint256" },
916
+ { indexed: true, name: "user", type: "address" },
917
+ { indexed: false, name: "completedTimestamp", type: "uint256" },
690
918
  {
691
- internalType: "bytes32",
692
- name: "_nativeCurrency",
693
- type: "bytes32"
919
+ indexed: false,
920
+ name: "_order",
921
+ type: "tuple",
922
+ components: [
923
+ { name: "amount", type: "uint256" },
924
+ { name: "fiatAmount", type: "uint256" },
925
+ { name: "placedTimestamp", type: "uint256" },
926
+ { name: "completedTimestamp", type: "uint256" },
927
+ { name: "userCompletedTimestamp", type: "uint256" },
928
+ { name: "acceptedMerchant", type: "address" },
929
+ { name: "user", type: "address" },
930
+ { name: "recipientAddr", type: "address" },
931
+ { name: "pubkey", type: "string" },
932
+ { name: "encUpi", type: "string" },
933
+ { name: "userCompleted", type: "bool" },
934
+ { name: "status", type: "uint8" },
935
+ { name: "orderType", type: "uint8" },
936
+ {
937
+ name: "disputeInfo",
938
+ type: "tuple",
939
+ components: [
940
+ { name: "raisedBy", type: "uint8" },
941
+ { name: "status", type: "uint8" },
942
+ { name: "redactTransId", type: "uint256" },
943
+ { name: "accountNumber", type: "uint256" }
944
+ ]
945
+ },
946
+ { name: "id", type: "uint256" },
947
+ { name: "userPubKey", type: "string" },
948
+ { name: "encMerchantUpi", type: "string" },
949
+ { name: "acceptedAccountNo", type: "uint256" },
950
+ { name: "assignedAccountNos", type: "uint256[]" },
951
+ { name: "currency", type: "bytes32" },
952
+ { name: "preferredPaymentChannelConfigId", type: "uint256" },
953
+ { name: "circleId", type: "uint256" }
954
+ ]
694
955
  }
695
- ],
696
- name: "getRpPerUsdtLimitRational",
697
- outputs: [
956
+ ]
957
+ },
958
+ {
959
+ type: "event",
960
+ name: "CancelledOrders",
961
+ anonymous: false,
962
+ inputs: [
963
+ { indexed: true, name: "orderId", type: "uint256" },
698
964
  {
699
- internalType: "uint256",
700
- name: "numerator",
701
- type: "uint256"
702
- },
965
+ indexed: false,
966
+ name: "_order",
967
+ type: "tuple",
968
+ components: [
969
+ { name: "amount", type: "uint256" },
970
+ { name: "fiatAmount", type: "uint256" },
971
+ { name: "placedTimestamp", type: "uint256" },
972
+ { name: "completedTimestamp", type: "uint256" },
973
+ { name: "userCompletedTimestamp", type: "uint256" },
974
+ { name: "acceptedMerchant", type: "address" },
975
+ { name: "user", type: "address" },
976
+ { name: "recipientAddr", type: "address" },
977
+ { name: "pubkey", type: "string" },
978
+ { name: "encUpi", type: "string" },
979
+ { name: "userCompleted", type: "bool" },
980
+ { name: "status", type: "uint8" },
981
+ { name: "orderType", type: "uint8" },
982
+ {
983
+ name: "disputeInfo",
984
+ type: "tuple",
985
+ components: [
986
+ { name: "raisedBy", type: "uint8" },
987
+ { name: "status", type: "uint8" },
988
+ { name: "redactTransId", type: "uint256" },
989
+ { name: "accountNumber", type: "uint256" }
990
+ ]
991
+ },
992
+ { name: "id", type: "uint256" },
993
+ { name: "userPubKey", type: "string" },
994
+ { name: "encMerchantUpi", type: "string" },
995
+ { name: "acceptedAccountNo", type: "uint256" },
996
+ { name: "assignedAccountNos", type: "uint256[]" },
997
+ { name: "currency", type: "bytes32" },
998
+ { name: "preferredPaymentChannelConfigId", type: "uint256" },
999
+ { name: "circleId", type: "uint256" }
1000
+ ]
1001
+ }
1002
+ ]
1003
+ }
1004
+ ];
1005
+
1006
+ // src/contracts/abis/order-processor-facet.ts
1007
+ var orderProcessorFacetAbi = [
1008
+ {
1009
+ type: "function",
1010
+ name: "getOrdersById",
1011
+ stateMutability: "view",
1012
+ inputs: [{ name: "orderId", type: "uint256" }],
1013
+ outputs: [
1014
+ {
1015
+ type: "tuple",
1016
+ components: [
1017
+ { name: "amount", type: "uint256" },
1018
+ { name: "fiatAmount", type: "uint256" },
1019
+ { name: "placedTimestamp", type: "uint256" },
1020
+ { name: "completedTimestamp", type: "uint256" },
1021
+ { name: "userCompletedTimestamp", type: "uint256" },
1022
+ { name: "acceptedMerchant", type: "address" },
1023
+ { name: "user", type: "address" },
1024
+ { name: "recipientAddr", type: "address" },
1025
+ { name: "pubkey", type: "string" },
1026
+ { name: "encUpi", type: "string" },
1027
+ { name: "userCompleted", type: "bool" },
1028
+ { name: "status", type: "uint8" },
1029
+ { name: "orderType", type: "uint8" },
1030
+ {
1031
+ name: "disputeInfo",
1032
+ type: "tuple",
1033
+ components: [
1034
+ { name: "raisedBy", type: "uint8" },
1035
+ { name: "status", type: "uint8" },
1036
+ { name: "redactTransId", type: "uint256" },
1037
+ { name: "accountNumber", type: "uint256" }
1038
+ ]
1039
+ },
1040
+ { name: "id", type: "uint256" },
1041
+ { name: "userPubKey", type: "string" },
1042
+ { name: "encMerchantUpi", type: "string" },
1043
+ { name: "acceptedAccountNo", type: "uint256" },
1044
+ { name: "assignedAccountNos", type: "uint256[]" },
1045
+ { name: "currency", type: "bytes32" },
1046
+ { name: "preferredPaymentChannelConfigId", type: "uint256" },
1047
+ { name: "circleId", type: "uint256" }
1048
+ ]
1049
+ }
1050
+ ]
1051
+ },
1052
+ {
1053
+ type: "function",
1054
+ name: "getAdditionalOrderDetails",
1055
+ stateMutability: "view",
1056
+ inputs: [{ name: "orderId", type: "uint256" }],
1057
+ outputs: [
1058
+ {
1059
+ type: "tuple",
1060
+ components: [
1061
+ { name: "fixedFeePaid", type: "uint64" },
1062
+ { name: "tipsPaid", type: "uint64" },
1063
+ { name: "acceptedTimestamp", type: "uint128" },
1064
+ { name: "paidTimestamp", type: "uint128" },
1065
+ { name: "reserved2", type: "uint128" },
1066
+ { name: "actualUsdtAmount", type: "uint256" },
1067
+ { name: "actualFiatAmount", type: "uint256" }
1068
+ ]
1069
+ }
1070
+ ]
1071
+ },
1072
+ {
1073
+ type: "function",
1074
+ name: "getSmallOrderThreshold",
1075
+ stateMutability: "view",
1076
+ inputs: [{ name: "currency", type: "bytes32" }],
1077
+ outputs: [{ name: "", type: "uint256" }]
1078
+ },
1079
+ {
1080
+ type: "function",
1081
+ name: "getSmallOrderFixedFee",
1082
+ stateMutability: "view",
1083
+ inputs: [{ name: "currency", type: "bytes32" }],
1084
+ outputs: [{ name: "", type: "uint256" }]
1085
+ },
1086
+ {
1087
+ type: "function",
1088
+ name: "raiseDispute",
1089
+ stateMutability: "nonpayable",
1090
+ inputs: [
1091
+ { name: "_orderId", type: "uint256" },
1092
+ { name: "redactTransId", type: "uint256" }
1093
+ ],
1094
+ outputs: []
1095
+ },
1096
+ {
1097
+ type: "function",
1098
+ name: "paidBuyOrder",
1099
+ stateMutability: "nonpayable",
1100
+ inputs: [{ name: "_orderId", type: "uint256" }],
1101
+ outputs: []
1102
+ }
1103
+ ];
1104
+
1105
+ // src/contracts/abis/p2p-config-facet.ts
1106
+ var p2pConfigFacetAbi = [
1107
+ {
1108
+ inputs: [
1109
+ {
1110
+ internalType: "bytes32",
1111
+ name: "_currency",
1112
+ type: "bytes32"
1113
+ }
1114
+ ],
1115
+ name: "getPriceConfig",
1116
+ outputs: [
1117
+ {
1118
+ components: [
1119
+ {
1120
+ internalType: "uint256",
1121
+ name: "buyPrice",
1122
+ type: "uint256"
1123
+ },
1124
+ {
1125
+ internalType: "uint256",
1126
+ name: "sellPrice",
1127
+ type: "uint256"
1128
+ },
1129
+ {
1130
+ internalType: "int256",
1131
+ name: "buyPriceOffset",
1132
+ type: "int256"
1133
+ },
1134
+ {
1135
+ internalType: "uint256",
1136
+ name: "baseSpread",
1137
+ type: "uint256"
1138
+ }
1139
+ ],
1140
+ internalType: "struct P2pConfigStorage.PriceConfig",
1141
+ name: "",
1142
+ type: "tuple"
1143
+ }
1144
+ ],
1145
+ stateMutability: "view",
1146
+ type: "function"
1147
+ },
1148
+ {
1149
+ inputs: [
1150
+ {
1151
+ internalType: "bytes32",
1152
+ name: "_nativeCurrency",
1153
+ type: "bytes32"
1154
+ }
1155
+ ],
1156
+ name: "getRpPerUsdtLimitRational",
1157
+ outputs: [
1158
+ {
1159
+ internalType: "uint256",
1160
+ name: "numerator",
1161
+ type: "uint256"
1162
+ },
703
1163
  {
704
1164
  internalType: "uint256",
705
1165
  name: "denominator",
@@ -914,11 +1374,16 @@ var reputationManagerAbi = [
914
1374
  ];
915
1375
 
916
1376
  // src/contracts/abis/index.ts
917
- var DIAMOND_ABI = [...orderFlowFacetAbi, ...p2pConfigFacetAbi];
1377
+ var DIAMOND_ABI = [
1378
+ ...orderFlowFacetAbi,
1379
+ ...orderProcessorFacetAbi,
1380
+ ...p2pConfigFacetAbi
1381
+ ];
918
1382
  var ABIS = {
919
1383
  DIAMOND: DIAMOND_ABI,
920
1384
  FACETS: {
921
1385
  ORDER_FLOW: orderFlowFacetAbi,
1386
+ ORDER_PROCESSOR: orderProcessorFacetAbi,
922
1387
  CONFIG: p2pConfigFacetAbi
923
1388
  },
924
1389
  EXTERNAL: {
@@ -927,817 +1392,663 @@ var ABIS = {
927
1392
  }
928
1393
  };
929
1394
 
930
- // src/contracts/order-flow/index.ts
931
- var import_neverthrow4 = require("neverthrow");
1395
+ // src/contracts/order-processor/index.ts
1396
+ function readOrderMulticall(publicClient, diamondAddress, orderId) {
1397
+ const calls = [
1398
+ {
1399
+ address: diamondAddress,
1400
+ abi: ABIS.FACETS.ORDER_PROCESSOR,
1401
+ functionName: "getOrdersById",
1402
+ args: [orderId]
1403
+ },
1404
+ {
1405
+ address: diamondAddress,
1406
+ abi: ABIS.FACETS.ORDER_PROCESSOR,
1407
+ functionName: "getAdditionalOrderDetails",
1408
+ args: [orderId]
1409
+ }
1410
+ ];
1411
+ const toError = (error) => new Error("Order contract read failed", { cause: error });
1412
+ const exec = async () => {
1413
+ if (publicClient.multicall) {
1414
+ const [order2, details2] = await publicClient.multicall({
1415
+ contracts: calls,
1416
+ allowFailure: false
1417
+ });
1418
+ return { order: order2, details: details2 };
1419
+ }
1420
+ const [order, details] = await Promise.all(
1421
+ calls.map((c) => publicClient.readContract(c))
1422
+ );
1423
+ return { order, details };
1424
+ };
1425
+ return import_neverthrow5.ResultAsync.fromPromise(exec(), toError);
1426
+ }
1427
+ function readFeeConfigMulticall(publicClient, diamondAddress, currency) {
1428
+ const currencyHex = (0, import_viem3.stringToHex)(currency, { size: 32 });
1429
+ const calls = [
1430
+ {
1431
+ address: diamondAddress,
1432
+ abi: ABIS.FACETS.ORDER_PROCESSOR,
1433
+ functionName: "getSmallOrderThreshold",
1434
+ args: [currencyHex]
1435
+ },
1436
+ {
1437
+ address: diamondAddress,
1438
+ abi: ABIS.FACETS.ORDER_PROCESSOR,
1439
+ functionName: "getSmallOrderFixedFee",
1440
+ args: [currencyHex]
1441
+ }
1442
+ ];
1443
+ const toError = (error) => new Error("Fee config contract read failed", { cause: error });
1444
+ const exec = async () => {
1445
+ if (publicClient.multicall) {
1446
+ const [smallOrderThreshold2, smallOrderFixedFee2] = await publicClient.multicall({
1447
+ contracts: calls,
1448
+ allowFailure: false
1449
+ });
1450
+ return { smallOrderThreshold: smallOrderThreshold2, smallOrderFixedFee: smallOrderFixedFee2 };
1451
+ }
1452
+ const [smallOrderThreshold, smallOrderFixedFee] = await Promise.all(
1453
+ calls.map((c) => publicClient.readContract(c))
1454
+ );
1455
+ return { smallOrderThreshold, smallOrderFixedFee };
1456
+ };
1457
+ return import_neverthrow5.ResultAsync.fromPromise(exec(), toError);
1458
+ }
932
1459
 
933
- // src/order-routing/errors.ts
934
- var OrderRoutingError = class extends SdkError {
1460
+ // src/orders/actions/approve-usdc.ts
1461
+ var import_viem4 = require("viem");
1462
+
1463
+ // src/orders/errors.ts
1464
+ var OrdersError = class extends SdkError {
935
1465
  constructor(message, options) {
936
1466
  super(message, options);
937
- this.name = "OrderRoutingError";
1467
+ this.name = "OrdersError";
938
1468
  }
939
1469
  };
940
1470
 
941
- // src/order-routing/validation.ts
1471
+ // src/orders/tx.ts
1472
+ var import_neverthrow6 = require("neverthrow");
1473
+ function submitPreparedTx(input) {
1474
+ const { prepared, walletClient, publicClient, waitForReceipt, extraMeta } = input;
1475
+ const account = walletClient.account;
1476
+ if (!account) {
1477
+ return (0, import_neverthrow6.errAsync)(
1478
+ new OrdersError("WalletClient is missing an account", {
1479
+ code: "TX_SUBMISSION_FAILED"
1480
+ })
1481
+ );
1482
+ }
1483
+ const chain = walletClient.chain;
1484
+ return import_neverthrow6.ResultAsync.fromPromise(
1485
+ walletClient.sendTransaction({
1486
+ account,
1487
+ chain,
1488
+ to: prepared.to,
1489
+ data: prepared.data,
1490
+ value: prepared.value
1491
+ }),
1492
+ (cause) => new OrdersError("walletClient.sendTransaction rejected", {
1493
+ code: "TX_SUBMISSION_FAILED",
1494
+ cause
1495
+ })
1496
+ ).andThen((hash) => {
1497
+ const combinedMeta = prepared.meta || extraMeta ? { ...prepared.meta, ...extraMeta } : void 0;
1498
+ if (!waitForReceipt) {
1499
+ return (0, import_neverthrow6.okAsync)({ hash, meta: combinedMeta });
1500
+ }
1501
+ return import_neverthrow6.ResultAsync.fromPromise(
1502
+ publicClient.waitForTransactionReceipt({ hash }),
1503
+ (cause) => new OrdersError("waitForTransactionReceipt failed", {
1504
+ code: "RECEIPT_TIMEOUT",
1505
+ cause
1506
+ })
1507
+ ).andThen((receipt) => {
1508
+ if (receipt.status !== "success") {
1509
+ return (0, import_neverthrow6.errAsync)(
1510
+ new OrdersError("Transaction reverted", {
1511
+ code: "TX_REVERTED",
1512
+ context: { hash, blockNumber: receipt.blockNumber.toString() }
1513
+ })
1514
+ );
1515
+ }
1516
+ return (0, import_neverthrow6.okAsync)({ hash, receipt, meta: combinedMeta });
1517
+ });
1518
+ });
1519
+ }
1520
+
1521
+ // src/orders/validation.ts
942
1522
  var import_zod3 = require("zod");
943
- var ZodCircleScoreStateSchema = import_zod3.z.object({
944
- activeMerchantsCount: import_zod3.z.coerce.number()
945
- });
946
- var ZodCircleMetricsForRoutingSchema = import_zod3.z.object({
947
- circleScore: import_zod3.z.coerce.number(),
948
- circleStatus: import_zod3.z.string(),
949
- scoreState: ZodCircleScoreStateSchema
1523
+ var ZodGetOrderParamsSchema = import_zod3.z.object({
1524
+ orderId: import_zod3.z.bigint().positive()
950
1525
  });
951
- var ZodCircleForRoutingSchema = import_zod3.z.object({
952
- circleId: import_zod3.z.string(),
953
- currency: import_zod3.z.string(),
954
- metrics: ZodCircleMetricsForRoutingSchema
1526
+ var ZodGetFeeConfigParamsSchema = import_zod3.z.object({
1527
+ currency: ZodCurrencySchema
955
1528
  });
956
- var ZodCirclesForRoutingResponseSchema = import_zod3.z.object({
957
- circles: import_zod3.z.array(ZodCircleForRoutingSchema)
1529
+ var ZodGetOrdersParamsSchema = import_zod3.z.object({
1530
+ userAddress: ZodAddressSchema,
1531
+ skip: import_zod3.z.number().int().min(0).default(0),
1532
+ limit: import_zod3.z.number().int().min(1).max(100).default(20)
958
1533
  });
959
- var ZodCheckCircleEligibilityParamsSchema = import_zod3.z.object({
960
- circleId: import_zod3.z.bigint(),
961
- currency: import_zod3.z.string(),
1534
+ var ZodPlaceOrderParamsSchema = import_zod3.z.object({
1535
+ orderType: import_zod3.z.number().int().min(0).max(2),
1536
+ currency: ZodCurrencySchema,
962
1537
  user: ZodAddressSchema,
963
- usdtAmount: import_zod3.z.bigint(),
1538
+ amount: import_zod3.z.bigint(),
964
1539
  fiatAmount: import_zod3.z.bigint(),
965
- orderType: import_zod3.z.bigint(),
966
- preferredPCConfigId: import_zod3.z.bigint()
1540
+ fiatAmountLimit: import_zod3.z.bigint().optional().default(0n),
1541
+ recipientAddr: ZodAddressSchema,
1542
+ preferredPaymentChannelConfigId: import_zod3.z.bigint().optional(),
1543
+ pubKey: import_zod3.z.string().optional()
967
1544
  });
968
- var ZodSelectCircleParamsSchema = import_zod3.z.object({
969
- currency: import_zod3.z.string().min(1),
970
- user: ZodAddressSchema,
971
- usdtAmount: import_zod3.z.bigint(),
972
- fiatAmount: import_zod3.z.bigint(),
973
- orderType: import_zod3.z.bigint(),
974
- preferredPCConfigId: import_zod3.z.bigint()
1545
+ var ZodCancelOrderParamsSchema = import_zod3.z.object({
1546
+ orderId: import_zod3.z.bigint().nonnegative()
975
1547
  });
976
-
977
- // src/contracts/order-flow/index.ts
978
- function checkCircleEligibility(publicClient, contractAddress, params, logger = noopLogger) {
979
- return validate(
980
- ZodCheckCircleEligibilityParamsSchema,
981
- params,
982
- (message, cause, d) => new OrderRoutingError(message, { code: "VALIDATION_ERROR", cause, context: { data: d } })
983
- ).asyncAndThen((validated) => {
984
- logger.debug("checking on-chain eligibility", {
985
- circleId: String(validated.circleId),
986
- contractAddress
987
- });
988
- return import_neverthrow4.ResultAsync.fromPromise(
989
- publicClient.readContract({
990
- address: contractAddress,
991
- abi: ABIS.FACETS.ORDER_FLOW,
992
- functionName: "getAssignableMerchantsFromCircle",
993
- args: [
994
- validated.circleId,
995
- 1n,
996
- validated.currency,
997
- validated.user,
998
- validated.usdtAmount,
999
- validated.fiatAmount,
1000
- validated.orderType,
1001
- validated.preferredPCConfigId
1002
- ]
1003
- }),
1004
- (error) => new OrderRoutingError("Eligibility check failed", {
1005
- code: "CONTRACT_READ_ERROR",
1006
- cause: error,
1007
- context: { circleId: String(params.circleId) }
1008
- })
1009
- );
1010
- }).map((merchants) => {
1011
- const arr = merchants;
1012
- const eligible = arr.length >= 1;
1013
- logger.debug("eligibility check result", {
1014
- circleId: String(params.circleId),
1015
- assignableMerchants: arr.length,
1016
- eligible
1017
- });
1018
- return eligible;
1019
- });
1020
- }
1021
-
1022
- // src/contracts/p2p-config/index.ts
1023
- var import_neverthrow5 = require("neverthrow");
1024
- var import_viem3 = require("viem");
1025
-
1026
- // src/profile/errors.ts
1027
- var ProfileError = class extends SdkError {
1028
- constructor(message, options) {
1029
- super(message, options);
1030
- this.name = "ProfileError";
1031
- }
1032
- };
1033
-
1034
- // src/profile/validation.ts
1035
- var import_zod4 = require("zod");
1036
- var ZodUsdcBalanceParamsSchema = import_zod4.z.object({
1037
- address: ZodAddressSchema
1548
+ var ZodSetSellOrderUpiParamsSchema = import_zod3.z.object({
1549
+ orderId: import_zod3.z.bigint().nonnegative(),
1550
+ paymentAddress: import_zod3.z.string().min(1),
1551
+ merchantPublicKey: import_zod3.z.string().min(1),
1552
+ updatedAmount: import_zod3.z.bigint()
1038
1553
  });
1039
- var ZodGetBalancesParamsSchema = import_zod4.z.object({
1040
- address: ZodAddressSchema,
1041
- currency: ZodCurrencySchema
1554
+ var ZodRaiseDisputeParamsSchema = import_zod3.z.object({
1555
+ orderId: import_zod3.z.bigint().nonnegative(),
1556
+ redactTransId: import_zod3.z.bigint().nonnegative()
1042
1557
  });
1043
- var ZodTxLimitsParamsSchema = import_zod4.z.object({
1044
- address: ZodAddressSchema,
1045
- currency: ZodCurrencySchema
1558
+ var ZodApproveUsdcParamsSchema = import_zod3.z.object({
1559
+ amount: import_zod3.z.bigint().nonnegative()
1046
1560
  });
1047
- var ZodPriceConfigParamsSchema = import_zod4.z.object({
1048
- currency: ZodCurrencySchema
1561
+ var ZodPaidBuyOrderParamsSchema = import_zod3.z.object({
1562
+ orderId: import_zod3.z.bigint().nonnegative()
1563
+ });
1564
+ var HexString = import_zod3.z.string().regex(/^0x[0-9a-fA-F]*$/, "Expected 0x-prefixed hex");
1565
+ var ZodSubgraphOrderSchema = import_zod3.z.object({
1566
+ orderId: import_zod3.z.string(),
1567
+ type: import_zod3.z.number().int().min(0),
1568
+ status: import_zod3.z.number().int().min(0),
1569
+ circleId: import_zod3.z.string(),
1570
+ userAddress: HexString,
1571
+ usdcRecipientAddress: HexString,
1572
+ acceptedMerchantAddress: HexString,
1573
+ usdcAmount: import_zod3.z.string(),
1574
+ fiatAmount: import_zod3.z.string(),
1575
+ actualUsdcAmount: import_zod3.z.string(),
1576
+ actualFiatAmount: import_zod3.z.string(),
1577
+ currency: HexString,
1578
+ placedAt: import_zod3.z.string(),
1579
+ acceptedAt: import_zod3.z.string(),
1580
+ paidAt: import_zod3.z.string(),
1581
+ completedAt: import_zod3.z.string(),
1582
+ fixedFeePaid: import_zod3.z.string(),
1583
+ tipsPaid: import_zod3.z.string(),
1584
+ disputeStatus: import_zod3.z.number().int().min(0)
1585
+ });
1586
+ var ZodSubgraphOrdersResponseSchema = import_zod3.z.object({
1587
+ orders_collection: import_zod3.z.array(ZodSubgraphOrderSchema)
1049
1588
  });
1050
1589
 
1051
- // src/contracts/p2p-config/index.ts
1052
- function getPriceConfig(publicClient, diamondAddress, params) {
1053
- return validate(
1054
- ZodPriceConfigParamsSchema,
1590
+ // src/orders/actions/approve-usdc.ts
1591
+ function createApproveUsdcAction(input) {
1592
+ const { publicClient, diamondAddress, usdcAddress } = input;
1593
+ const prepareFn = (params) => validate(
1594
+ ZodApproveUsdcParamsSchema,
1055
1595
  params,
1056
- (message, cause, data) => new ProfileError(message, {
1596
+ (message, cause, data) => new OrdersError(message, {
1057
1597
  code: "VALIDATION_ERROR",
1058
1598
  cause,
1059
- context: { params: data }
1599
+ context: { data }
1060
1600
  })
1061
- ).asyncAndThen(
1062
- (validated) => import_neverthrow5.ResultAsync.fromPromise(
1063
- publicClient.readContract({
1064
- address: diamondAddress,
1065
- abi: ABIS.FACETS.CONFIG,
1066
- functionName: "getPriceConfig",
1067
- args: [(0, import_viem3.stringToHex)(validated.currency, { size: 32 })]
1068
- }),
1069
- (error) => new ProfileError("Failed to read price config", {
1070
- code: "CONTRACT_READ_ERROR",
1071
- cause: error,
1072
- context: { currency: validated.currency, diamondAddress }
1073
- })
1074
- )
1075
- );
1601
+ ).map(({ amount }) => ({
1602
+ to: usdcAddress,
1603
+ data: (0, import_viem4.encodeFunctionData)({
1604
+ abi: import_viem4.erc20Abi,
1605
+ functionName: "approve",
1606
+ args: [diamondAddress, amount]
1607
+ }),
1608
+ value: 0n
1609
+ }));
1610
+ return {
1611
+ prepare(params) {
1612
+ return prepareFn(params).asyncMap(async (tx) => tx);
1613
+ },
1614
+ execute({ walletClient, waitForReceipt, ...params }) {
1615
+ return prepareFn(params).asyncAndThen(
1616
+ (prepared) => submitPreparedTx({ prepared, walletClient, publicClient, waitForReceipt })
1617
+ );
1618
+ }
1619
+ };
1076
1620
  }
1077
1621
 
1078
- // src/contracts/reputation-manager/writes.ts
1079
- var import_neverthrow6 = require("neverthrow");
1080
- var import_viem4 = require("viem");
1081
-
1082
- // src/zkkyc/errors.ts
1083
- var ZkkycError = class extends SdkError {
1084
- constructor(message, options) {
1085
- super(message, options);
1086
- this.name = "ZkkycError";
1087
- }
1088
- };
1089
-
1090
- // src/zkkyc/validation.ts
1091
- var import_zod5 = require("zod");
1092
- var ZodAnonAadharProofParamsSchema = import_zod5.z.object({
1093
- nullifierSeed: import_zod5.z.bigint(),
1094
- nullifier: import_zod5.z.bigint(),
1095
- timestamp: import_zod5.z.bigint(),
1096
- signal: import_zod5.z.bigint(),
1097
- revealArray: import_zod5.z.tuple([import_zod5.z.bigint(), import_zod5.z.bigint(), import_zod5.z.bigint(), import_zod5.z.bigint()]),
1098
- packedGroth16Proof: import_zod5.z.tuple([
1099
- import_zod5.z.bigint(),
1100
- import_zod5.z.bigint(),
1101
- import_zod5.z.bigint(),
1102
- import_zod5.z.bigint(),
1103
- import_zod5.z.bigint(),
1104
- import_zod5.z.bigint(),
1105
- import_zod5.z.bigint(),
1106
- import_zod5.z.bigint()
1107
- ])
1108
- });
1109
- var ZodSocialVerifyParamsSchema = import_zod5.z.object({
1110
- _socialName: import_zod5.z.string(),
1111
- proofs: import_zod5.z.array(
1112
- import_zod5.z.object({
1113
- claimInfo: import_zod5.z.object({
1114
- provider: import_zod5.z.string(),
1115
- parameters: import_zod5.z.string(),
1116
- context: import_zod5.z.string()
1117
- }),
1118
- signedClaim: import_zod5.z.object({
1119
- claim: import_zod5.z.object({
1120
- identifier: import_zod5.z.string(),
1121
- owner: ZodAddressSchema,
1122
- timestampS: import_zod5.z.number(),
1123
- epoch: import_zod5.z.number()
1124
- }),
1125
- signatures: import_zod5.z.array(import_zod5.z.string())
1126
- })
1622
+ // src/orders/actions/cancel-order.ts
1623
+ var import_viem5 = require("viem");
1624
+ function createCancelOrderAction(input) {
1625
+ const { publicClient, diamondAddress } = input;
1626
+ const prepareFn = (params) => validate(
1627
+ ZodCancelOrderParamsSchema,
1628
+ params,
1629
+ (message, cause, data) => new OrdersError(message, {
1630
+ code: "VALIDATION_ERROR",
1631
+ cause,
1632
+ context: { data }
1127
1633
  })
1128
- )
1129
- });
1130
- var ZodSolidityVerifierParametersSchema = import_zod5.z.object({
1131
- version: import_zod5.z.string().refine((val) => val.startsWith("0x"), {
1132
- message: "Version must be a hex string"
1133
- }),
1134
- proofVerificationData: import_zod5.z.object({
1135
- vkeyHash: import_zod5.z.string().refine((val) => /^0x[a-fA-F0-9]{64}$/.test(val), {
1136
- message: "Invalid bytes32 hex string"
1634
+ ).map(({ orderId }) => ({
1635
+ to: diamondAddress,
1636
+ data: (0, import_viem5.encodeFunctionData)({
1637
+ abi: ABIS.FACETS.ORDER_FLOW,
1638
+ functionName: "cancelOrder",
1639
+ args: [orderId]
1137
1640
  }),
1138
- proof: import_zod5.z.string().refine((val) => val.startsWith("0x"), {
1139
- message: "Proof must be a hex string"
1641
+ value: 0n
1642
+ }));
1643
+ return {
1644
+ prepare(params) {
1645
+ return prepareFn(params).asyncMap(async (tx) => tx);
1646
+ },
1647
+ execute({ walletClient, waitForReceipt, ...params }) {
1648
+ return prepareFn(params).asyncAndThen(
1649
+ (prepared) => submitPreparedTx({ prepared, walletClient, publicClient, waitForReceipt })
1650
+ );
1651
+ }
1652
+ };
1653
+ }
1654
+
1655
+ // src/orders/actions/paid-buy-order.ts
1656
+ var import_viem6 = require("viem");
1657
+ function createPaidBuyOrderAction(input) {
1658
+ const { publicClient, diamondAddress } = input;
1659
+ const prepareFn = (params) => validate(
1660
+ ZodPaidBuyOrderParamsSchema,
1661
+ params,
1662
+ (message, cause, data) => new OrdersError(message, {
1663
+ code: "VALIDATION_ERROR",
1664
+ cause,
1665
+ context: { data }
1666
+ })
1667
+ ).map(({ orderId }) => ({
1668
+ to: diamondAddress,
1669
+ data: (0, import_viem6.encodeFunctionData)({
1670
+ abi: ABIS.FACETS.ORDER_PROCESSOR,
1671
+ functionName: "paidBuyOrder",
1672
+ args: [orderId]
1140
1673
  }),
1141
- publicInputs: import_zod5.z.array(
1142
- import_zod5.z.string().refine((val) => /^0x[a-fA-F0-9]{64}$/.test(val), {
1143
- message: "Each public input must be a valid bytes32 hex string"
1144
- })
1145
- )
1146
- }),
1147
- committedInputs: import_zod5.z.string().refine((val) => val.startsWith("0x"), {
1148
- message: "Committed inputs must be a hex string"
1674
+ value: 0n
1675
+ }));
1676
+ return {
1677
+ prepare(params) {
1678
+ return prepareFn(params).asyncMap(async (tx) => tx);
1679
+ },
1680
+ execute({ walletClient, waitForReceipt, ...params }) {
1681
+ return prepareFn(params).asyncAndThen(
1682
+ (prepared) => submitPreparedTx({ prepared, walletClient, publicClient, waitForReceipt })
1683
+ );
1684
+ }
1685
+ };
1686
+ }
1687
+
1688
+ // src/orders/actions/place-order.ts
1689
+ var import_viem8 = require("viem");
1690
+
1691
+ // src/constants/orders.constant.ts
1692
+ var ORDER_TYPE = {
1693
+ BUY: 0,
1694
+ SELL: 1,
1695
+ PAY: 2
1696
+ };
1697
+ var ORDER_STATUS = {
1698
+ PLACED: 0,
1699
+ ACCEPTED: 1,
1700
+ PAID: 2,
1701
+ COMPLETED: 3,
1702
+ CANCELLED: 4
1703
+ };
1704
+ var DISPUTE_STATUS = {
1705
+ NONE: 0,
1706
+ OPEN: 1,
1707
+ RESOLVED: 2
1708
+ };
1709
+
1710
+ // src/orders/relay-identity/identity.ts
1711
+ var import_viem7 = require("viem");
1712
+ var import_accounts = require("viem/accounts");
1713
+ var import_zod4 = require("zod");
1714
+ var ZodRelayIdentitySchema = import_zod4.z.object({
1715
+ address: import_zod4.z.string().refine(import_viem7.isAddress, { message: "Invalid relay identity address" }),
1716
+ publicKey: import_zod4.z.string().refine((v) => (0, import_viem7.isHex)(`0x${v}`), {
1717
+ message: "Invalid relay identity public key"
1149
1718
  }),
1150
- serviceConfig: import_zod5.z.object({
1151
- validityPeriodInSeconds: import_zod5.z.number().int().nonnegative(),
1152
- domain: import_zod5.z.string(),
1153
- scope: import_zod5.z.string(),
1154
- devMode: import_zod5.z.boolean()
1155
- })
1156
- });
1157
- var ZodZkPassportRegisterParamsSchema = import_zod5.z.object({
1158
- params: ZodSolidityVerifierParametersSchema,
1159
- isIDCard: import_zod5.z.boolean()
1719
+ privateKey: import_zod4.z.string().refine(import_viem7.isHex, { message: "Invalid relay identity private key" })
1160
1720
  });
1721
+ function createRelayIdentity() {
1722
+ const privateKey = (0, import_accounts.generatePrivateKey)();
1723
+ const account = (0, import_accounts.privateKeyToAccount)(privateKey);
1724
+ const publicKey = account.publicKey.slice(4);
1725
+ return {
1726
+ address: account.address,
1727
+ publicKey,
1728
+ privateKey
1729
+ };
1730
+ }
1161
1731
 
1162
- // src/contracts/reputation-manager/writes.ts
1163
- function prepareSocialVerify(reputationManagerAddress, params) {
1164
- return validate(
1165
- ZodSocialVerifyParamsSchema,
1166
- params,
1167
- (message, cause, data) => new ZkkycError(message, { code: "VALIDATION_ERROR", cause, context: { params: data } })
1168
- ).andThen(
1169
- (validated) => import_neverthrow6.Result.fromThrowable(
1170
- () => ({
1171
- to: reputationManagerAddress,
1172
- data: (0, import_viem4.encodeFunctionData)({
1173
- abi: ABIS.EXTERNAL.REPUTATION_MANAGER,
1174
- functionName: "socialVerify",
1175
- args: [
1176
- validated._socialName,
1177
- validated.proofs.map((proof) => ({
1178
- ...proof,
1179
- signedClaim: {
1180
- ...proof.signedClaim,
1181
- claim: {
1182
- ...proof.signedClaim.claim,
1183
- identifier: proof.signedClaim.claim.identifier
1184
- },
1185
- signatures: proof.signedClaim.signatures
1186
- }
1187
- }))
1188
- ]
1732
+ // src/orders/relay-identity/resolve.ts
1733
+ var import_neverthrow7 = require("neverthrow");
1734
+
1735
+ // src/orders/relay-identity/stores.ts
1736
+ var RelayIdentityCorruptError = class extends Error {
1737
+ constructor(cause) {
1738
+ super("Stored relay identity is corrupt", { cause });
1739
+ this.name = "RelayIdentityCorruptError";
1740
+ }
1741
+ };
1742
+ function createInMemoryRelayStore() {
1743
+ let value = null;
1744
+ return {
1745
+ async get() {
1746
+ return value;
1747
+ },
1748
+ async set(identity) {
1749
+ value = identity;
1750
+ }
1751
+ };
1752
+ }
1753
+
1754
+ // src/orders/relay-identity/resolve.ts
1755
+ var pending = /* @__PURE__ */ new WeakMap();
1756
+ async function resolveFromStore(store) {
1757
+ let stored;
1758
+ try {
1759
+ stored = await store.get();
1760
+ } catch (cause) {
1761
+ if (cause instanceof RelayIdentityCorruptError) {
1762
+ return (0, import_neverthrow7.err)(
1763
+ new OrdersError("Stored relay identity is corrupt", {
1764
+ code: "RELAY_IDENTITY_CORRUPT",
1765
+ cause: cause.cause
1189
1766
  })
1190
- }),
1191
- (error) => new ZkkycError("Failed to encode socialVerify", {
1192
- code: "ENCODE_ERROR",
1193
- cause: error
1767
+ );
1768
+ }
1769
+ return (0, import_neverthrow7.err)(
1770
+ new OrdersError("Relay identity store.get failed", {
1771
+ code: "RELAY_IDENTITY_STORE_FAILED",
1772
+ cause
1194
1773
  })
1195
- )()
1196
- );
1197
- }
1198
- function prepareSubmitAnonAadharProof(reputationManagerAddress, params) {
1199
- return validate(
1200
- ZodAnonAadharProofParamsSchema,
1201
- params,
1202
- (message, cause, data) => new ZkkycError(message, { code: "VALIDATION_ERROR", cause, context: { params: data } })
1203
- ).andThen(
1204
- (validated) => import_neverthrow6.Result.fromThrowable(
1205
- () => ({
1206
- to: reputationManagerAddress,
1207
- data: (0, import_viem4.encodeFunctionData)({
1208
- abi: ABIS.EXTERNAL.REPUTATION_MANAGER,
1209
- functionName: "submitAnonAadharProof",
1210
- args: [
1211
- validated.nullifierSeed,
1212
- validated.nullifier,
1213
- validated.timestamp,
1214
- validated.signal,
1215
- validated.revealArray,
1216
- validated.packedGroth16Proof
1217
- ]
1774
+ );
1775
+ }
1776
+ if (stored !== null) {
1777
+ const parsed = ZodRelayIdentitySchema.safeParse(stored);
1778
+ if (!parsed.success) {
1779
+ return (0, import_neverthrow7.err)(
1780
+ new OrdersError("Stored relay identity failed validation", {
1781
+ code: "RELAY_IDENTITY_CORRUPT",
1782
+ cause: parsed.error
1218
1783
  })
1219
- }),
1220
- (error) => new ZkkycError("Failed to encode submitAnonAadharProof", {
1221
- code: "ENCODE_ERROR",
1222
- cause: error
1784
+ );
1785
+ }
1786
+ return (0, import_neverthrow7.ok)(stored);
1787
+ }
1788
+ const fresh = createRelayIdentity();
1789
+ try {
1790
+ await store.set(fresh);
1791
+ } catch (cause) {
1792
+ return (0, import_neverthrow7.err)(
1793
+ new OrdersError("Relay identity store.set failed", {
1794
+ code: "RELAY_IDENTITY_STORE_FAILED",
1795
+ cause
1223
1796
  })
1224
- )()
1225
- );
1797
+ );
1798
+ }
1799
+ return (0, import_neverthrow7.ok)(fresh);
1226
1800
  }
1227
- function prepareZkPassportRegister(reputationManagerAddress, params) {
1228
- return validate(
1229
- ZodZkPassportRegisterParamsSchema,
1230
- params,
1231
- (message, cause, data) => new ZkkycError(message, { code: "VALIDATION_ERROR", cause, context: { params: data } })
1232
- ).andThen(
1233
- (validated) => import_neverthrow6.Result.fromThrowable(
1234
- () => {
1235
- const { proofVerificationData, serviceConfig, committedInputs, version } = validated.params;
1236
- const proofVerificationParams = {
1237
- version,
1238
- proofVerificationData: {
1239
- vkeyHash: proofVerificationData.vkeyHash,
1240
- proof: proofVerificationData.proof,
1241
- publicInputs: proofVerificationData.publicInputs
1242
- },
1243
- committedInputs,
1244
- serviceConfig: {
1245
- validityPeriodInSeconds: BigInt(serviceConfig.validityPeriodInSeconds),
1246
- domain: serviceConfig.domain,
1247
- scope: serviceConfig.scope,
1248
- devMode: serviceConfig.devMode
1249
- }
1250
- };
1251
- return {
1252
- to: reputationManagerAddress,
1253
- data: (0, import_viem4.encodeFunctionData)({
1254
- abi: ABIS.EXTERNAL.REPUTATION_MANAGER,
1255
- functionName: "zkPassportRegister",
1256
- args: [proofVerificationParams, validated.isIDCard]
1257
- })
1258
- };
1259
- },
1260
- (error) => new ZkkycError("Failed to encode zkPassportRegister", {
1261
- code: "ENCODE_ERROR",
1262
- cause: error
1263
- })
1264
- )()
1265
- );
1801
+ function resolveRelayIdentity(input) {
1802
+ if (input.relayIdentity) {
1803
+ return (0, import_neverthrow7.okAsync)(input.relayIdentity);
1804
+ }
1805
+ const existing = pending.get(input.store);
1806
+ if (existing) {
1807
+ return import_neverthrow7.ResultAsync.fromSafePromise(existing).andThen((r) => r);
1808
+ }
1809
+ const promise = resolveFromStore(input.store).finally(() => {
1810
+ pending.delete(input.store);
1811
+ });
1812
+ pending.set(input.store, promise);
1813
+ return import_neverthrow7.ResultAsync.fromSafePromise(promise).andThen((r) => r);
1266
1814
  }
1267
1815
 
1268
- // src/contracts/tx-limits/index.ts
1269
- var import_neverthrow7 = require("neverthrow");
1270
- var import_viem5 = require("viem");
1271
- function getTxLimits(publicClient, diamondAddress, params) {
1272
- return validate(
1273
- ZodTxLimitsParamsSchema,
1816
+ // src/orders/actions/place-order.ts
1817
+ function enrichWithOrderId(result, userAddress) {
1818
+ if (!result.receipt) return result;
1819
+ try {
1820
+ const events = (0, import_viem8.parseEventLogs)({
1821
+ abi: ABIS.FACETS.ORDER_FLOW,
1822
+ eventName: "OrderPlaced",
1823
+ logs: result.receipt.logs
1824
+ });
1825
+ const lowered = userAddress.toLowerCase();
1826
+ const mine = events.find((e) => e.args.user?.toLowerCase() === lowered);
1827
+ const chosen = mine ?? events[0];
1828
+ if (!chosen) return result;
1829
+ const orderId = chosen.args.orderId;
1830
+ if (orderId === void 0) return result;
1831
+ return { ...result, meta: { ...result.meta, orderId } };
1832
+ } catch {
1833
+ return result;
1834
+ }
1835
+ }
1836
+ function createPlaceOrderAction(input) {
1837
+ const { publicClient, diamondAddress, orderRouter, relayIdentityStore, relayIdentity } = input;
1838
+ const prepareFn = (params) => validate(
1839
+ ZodPlaceOrderParamsSchema,
1274
1840
  params,
1275
- (message, cause, data) => new ProfileError(message, {
1841
+ (message, cause, data) => new OrdersError(message, {
1276
1842
  code: "VALIDATION_ERROR",
1277
1843
  cause,
1278
- context: { params: data }
1844
+ context: { data }
1279
1845
  })
1280
- ).asyncAndThen(
1281
- (validated) => import_neverthrow7.ResultAsync.fromPromise(
1282
- publicClient.readContract({
1283
- address: diamondAddress,
1284
- abi: ABIS.FACETS.ORDER_FLOW,
1285
- functionName: "userTxLimit",
1286
- args: [validated.address, (0, import_viem5.stringToHex)(validated.currency, { size: 32 })]
1287
- }),
1288
- (error) => new ProfileError("Failed to read tx limits", {
1289
- code: "CONTRACT_READ_ERROR",
1290
- cause: error,
1291
- context: { address: validated.address, currency: validated.currency, diamondAddress }
1846
+ ).asyncAndThen((v) => {
1847
+ const pcConfigId = v.preferredPaymentChannelConfigId ?? 0n;
1848
+ const circleResult = orderRouter.selectCircle({
1849
+ currency: v.currency,
1850
+ user: v.user,
1851
+ usdtAmount: v.amount,
1852
+ fiatAmount: v.fiatAmount,
1853
+ orderType: BigInt(v.orderType),
1854
+ preferredPCConfigId: pcConfigId
1855
+ }).mapErr(
1856
+ (cause) => new OrdersError(`Circle selection failed: ${cause.message}`, {
1857
+ code: "CIRCLE_SELECTION_FAILED",
1858
+ cause
1292
1859
  })
1293
- ).map(([buyLimit, sellLimit]) => ({
1294
- buyLimit: Number((0, import_viem5.formatUnits)(buyLimit, 6)),
1295
- sellLimit: Number((0, import_viem5.formatUnits)(sellLimit, 6))
1296
- }))
1297
- );
1860
+ );
1861
+ const identityResult = resolveRelayIdentity({
1862
+ relayIdentity,
1863
+ store: relayIdentityStore
1864
+ });
1865
+ return identityResult.andThen(
1866
+ (senderIdentity) => circleResult.map((circleId) => {
1867
+ const isBuy = v.orderType === ORDER_TYPE.BUY;
1868
+ const keyFromCaller = v.pubKey ?? senderIdentity.publicKey;
1869
+ const pubKey = isBuy ? keyFromCaller : "";
1870
+ const userPubKey = isBuy ? "" : keyFromCaller;
1871
+ const currencyBytes32 = (0, import_viem8.stringToHex)(v.currency, { size: 32 });
1872
+ const data = (0, import_viem8.encodeFunctionData)({
1873
+ abi: ABIS.FACETS.ORDER_FLOW,
1874
+ functionName: "placeOrder",
1875
+ args: [
1876
+ pubKey,
1877
+ v.amount,
1878
+ v.recipientAddr,
1879
+ v.orderType,
1880
+ "",
1881
+ // _userUpi — set later via setSellOrderUpi if applicable
1882
+ userPubKey,
1883
+ currencyBytes32,
1884
+ pcConfigId,
1885
+ circleId,
1886
+ v.fiatAmountLimit ?? 0n
1887
+ ]
1888
+ });
1889
+ return {
1890
+ to: diamondAddress,
1891
+ data,
1892
+ value: 0n,
1893
+ meta: { circleId, relayIdentity: senderIdentity }
1894
+ };
1895
+ })
1896
+ );
1897
+ });
1898
+ return {
1899
+ prepare(params) {
1900
+ return prepareFn(params);
1901
+ },
1902
+ execute({ walletClient, waitForReceipt, ...params }) {
1903
+ const owner = walletClient.account?.address;
1904
+ const enrich = (r) => owner ? enrichWithOrderId(r, owner) : r;
1905
+ return prepareFn(params).andThen(
1906
+ (prepared) => submitPreparedTx({ prepared, walletClient, publicClient, waitForReceipt }).map(enrich)
1907
+ );
1908
+ }
1909
+ };
1298
1910
  }
1299
- function getRpPerUsdtLimitRational(publicClient, diamondAddress, params) {
1300
- return validate(
1301
- ZodPriceConfigParamsSchema,
1911
+
1912
+ // src/orders/actions/raise-dispute.ts
1913
+ var import_viem9 = require("viem");
1914
+ function createRaiseDisputeAction(input) {
1915
+ const { publicClient, diamondAddress } = input;
1916
+ const prepareFn = (params) => validate(
1917
+ ZodRaiseDisputeParamsSchema,
1302
1918
  params,
1303
- (message, cause, data) => new ProfileError(message, {
1919
+ (message, cause, data) => new OrdersError(message, {
1304
1920
  code: "VALIDATION_ERROR",
1305
1921
  cause,
1306
- context: { params: data }
1922
+ context: { data }
1307
1923
  })
1308
- ).asyncAndThen(
1309
- (validated) => import_neverthrow7.ResultAsync.fromPromise(
1310
- publicClient.readContract({
1311
- address: diamondAddress,
1312
- abi: ABIS.DIAMOND,
1313
- functionName: "getRpPerUsdtLimitRational",
1314
- args: [(0, import_viem5.stringToHex)(validated.currency, { size: 32 })]
1315
- }),
1316
- (error) => new ProfileError("Failed to read RP per USDT limit rational", {
1317
- code: "CONTRACT_READ_ERROR",
1318
- cause: error,
1319
- context: { currency: validated.currency, diamondAddress }
1320
- })
1321
- ).map(([numerator, denominator]) => ({
1322
- numerator,
1323
- denominator,
1324
- multiplier: numerator > 0n ? Number(denominator) / Number(numerator) : 0
1325
- }))
1326
- );
1327
- }
1328
-
1329
- // src/contracts/usdc/index.ts
1330
- var import_neverthrow8 = require("neverthrow");
1331
- function getUsdcBalance(publicClient, usdcAddress, params) {
1332
- return validate(
1333
- ZodUsdcBalanceParamsSchema,
1334
- params,
1335
- (message, cause, data) => new ProfileError(message, {
1336
- code: "VALIDATION_ERROR",
1337
- cause,
1338
- context: { params: data }
1339
- })
1340
- ).asyncAndThen(
1341
- (validated) => import_neverthrow8.ResultAsync.fromPromise(
1342
- publicClient.readContract({
1343
- address: usdcAddress,
1344
- abi: ABIS.EXTERNAL.USDC,
1345
- functionName: "balanceOf",
1346
- args: [validated.address]
1347
- }),
1348
- (error) => new ProfileError("Failed to read USDC balance", {
1349
- code: "CONTRACT_READ_ERROR",
1350
- cause: error,
1351
- context: { address: validated.address, usdcAddress }
1352
- })
1353
- )
1354
- );
1924
+ ).map(({ orderId, redactTransId }) => ({
1925
+ to: diamondAddress,
1926
+ data: (0, import_viem9.encodeFunctionData)({
1927
+ abi: ABIS.FACETS.ORDER_PROCESSOR,
1928
+ functionName: "raiseDispute",
1929
+ args: [orderId, redactTransId]
1930
+ }),
1931
+ value: 0n
1932
+ }));
1933
+ return {
1934
+ prepare(params) {
1935
+ return prepareFn(params).asyncMap(async (tx) => tx);
1936
+ },
1937
+ execute({ walletClient, waitForReceipt, ...params }) {
1938
+ return prepareFn(params).asyncAndThen(
1939
+ (prepared) => submitPreparedTx({ prepared, walletClient, publicClient, waitForReceipt })
1940
+ );
1941
+ }
1942
+ };
1355
1943
  }
1356
1944
 
1357
- // src/order-routing/routing.ts
1358
- var import_neverthrow9 = require("neverthrow");
1359
- var EPSILON = 0.25;
1360
- var RECOVERY_SCALE = 0.3;
1361
- var BOOTSTRAP_MAX_WEIGHT = 25;
1362
- var MAX_VALIDATION_ATTEMPTS = 3;
1363
- function circleWeight(c) {
1364
- const score = c.metrics.circleScore;
1365
- if (c.metrics.circleStatus === "paused") {
1366
- return score * RECOVERY_SCALE;
1367
- }
1368
- if (c.metrics.circleStatus === "bootstrap") {
1369
- return Math.min(score, BOOTSTRAP_MAX_WEIGHT);
1370
- }
1371
- return score;
1945
+ // src/orders/actions/set-sell-order-upi.ts
1946
+ var import_viem11 = require("viem");
1947
+
1948
+ // src/orders/crypto/encryption.ts
1949
+ var import_neverthrow8 = require("neverthrow");
1950
+ var import_viem10 = require("viem");
1951
+ var import_accounts2 = require("viem/accounts");
1952
+ var import_zod5 = require("zod");
1953
+
1954
+ // node_modules/@noble/ciphers/esm/utils.js
1955
+ function isBytes(a) {
1956
+ return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
1372
1957
  }
1373
- function filterEligibleCircles(circles, orderCurrency) {
1374
- return circles.filter((c) => c.currency.toLowerCase() === orderCurrency.toLowerCase());
1958
+ function abytes(b, ...lengths) {
1959
+ if (!isBytes(b))
1960
+ throw new Error("Uint8Array expected");
1961
+ if (lengths.length > 0 && !lengths.includes(b.length))
1962
+ throw new Error("Uint8Array expected of length " + lengths + ", got length=" + b.length);
1375
1963
  }
1376
- function weightedRandomChoice(arr, weights) {
1377
- const totalWeight = weights.reduce((sum, w) => sum + w, 0);
1378
- if (totalWeight === 0) {
1379
- return arr[Math.floor(Math.random() * arr.length)];
1380
- }
1381
- let rand = Math.random() * totalWeight;
1382
- for (let i = 0; i < arr.length; i++) {
1383
- rand -= weights[i];
1384
- if (rand <= 0) {
1385
- return arr[i];
1386
- }
1387
- }
1388
- return arr[arr.length - 1];
1964
+ function u32(arr) {
1965
+ return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
1389
1966
  }
1390
- function selectCircle(eligible) {
1391
- if (eligible.length === 0) {
1392
- return null;
1393
- }
1394
- const activeCircles = eligible.filter((c) => c.metrics.circleStatus === "active");
1395
- const isExplore = Math.random() < EPSILON;
1396
- if (isExplore) {
1397
- const weights2 = eligible.map(circleWeight);
1398
- return weightedRandomChoice(eligible, weights2);
1399
- }
1400
- if (activeCircles.length === 0) {
1401
- const weights2 = eligible.map(circleWeight);
1402
- return weightedRandomChoice(eligible, weights2);
1967
+ function clean(...arrays) {
1968
+ for (let i = 0; i < arrays.length; i++) {
1969
+ arrays[i].fill(0);
1403
1970
  }
1404
- const weights = activeCircles.map((c) => c.metrics.circleScore);
1405
- return weightedRandomChoice(activeCircles, weights);
1406
1971
  }
1407
- function selectCircleForOrderAsync(circles, orderCurrency, validateCircle, logger = noopLogger) {
1408
- const eligible = filterEligibleCircles(circles, orderCurrency);
1409
- let remaining = [...eligible];
1410
- logger.debug("filtering eligible circles", {
1411
- total: circles.length,
1412
- eligible: eligible.length,
1413
- currency: orderCurrency,
1414
- circles: eligible
1415
- });
1416
- if (eligible.length === 0) {
1417
- logger.warn("no eligible circles found for currency", { currency: orderCurrency });
1418
- }
1419
- function attempt(attemptsLeft) {
1420
- if (attemptsLeft <= 0 || remaining.length === 0) {
1421
- logger.warn("exhausted all attempts or circles", {
1422
- attemptsLeft,
1423
- remainingCircles: remaining.length
1424
- });
1425
- return (0, import_neverthrow9.errAsync)(
1426
- new OrderRoutingError("No eligible circles found", {
1427
- code: "NO_ELIGIBLE_CIRCLES"
1428
- })
1429
- );
1972
+ var isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68)();
1973
+ function overlapBytes(a, b) {
1974
+ return a.buffer === b.buffer && // best we can do, may fail with an obscure Proxy
1975
+ a.byteOffset < b.byteOffset + b.byteLength && // a starts before b end
1976
+ b.byteOffset < a.byteOffset + a.byteLength;
1977
+ }
1978
+ function complexOverlapBytes(input, output) {
1979
+ if (overlapBytes(input, output) && input.byteOffset < output.byteOffset)
1980
+ throw new Error("complex overlap of input and output is not supported");
1981
+ }
1982
+ var wrapCipher = /* @__NO_SIDE_EFFECTS__ */ (params, constructor) => {
1983
+ function wrappedCipher(key, ...args) {
1984
+ abytes(key);
1985
+ if (!isLE)
1986
+ throw new Error("Non little-endian hardware is not yet supported");
1987
+ if (params.nonceLength !== void 0) {
1988
+ const nonce = args[0];
1989
+ if (!nonce)
1990
+ throw new Error("nonce / iv required");
1991
+ if (params.varSizeNonce)
1992
+ abytes(nonce);
1993
+ else
1994
+ abytes(nonce, params.nonceLength);
1430
1995
  }
1431
- const selected = selectCircle(remaining);
1432
- if (!selected) {
1433
- return (0, import_neverthrow9.errAsync)(
1434
- new OrderRoutingError("No eligible circles found", {
1435
- code: "NO_ELIGIBLE_CIRCLES"
1436
- })
1437
- );
1996
+ const tagl = params.tagLength;
1997
+ if (tagl && args[1] !== void 0) {
1998
+ abytes(args[1]);
1438
1999
  }
1439
- const circleId = BigInt(selected.circleId);
1440
- logger.debug("selected circle, validating on-chain", {
1441
- circleId: String(circleId),
1442
- status: selected.metrics.circleStatus,
1443
- score: selected.metrics.circleScore,
1444
- attemptsLeft
1445
- });
1446
- return validateCircle(circleId).orElse((error) => {
1447
- logger.warn("validation errored, treating as ineligible", {
1448
- circleId: String(circleId),
1449
- error: String(error)
1450
- });
1451
- return (0, import_neverthrow9.okAsync)(false);
1452
- }).andThen((isValid) => {
1453
- if (isValid) {
1454
- logger.info("circle validated successfully", { circleId: String(circleId) });
1455
- return (0, import_neverthrow9.okAsync)(circleId);
2000
+ const cipher = constructor(key, ...args);
2001
+ const checkOutput = (fnLength, output) => {
2002
+ if (output !== void 0) {
2003
+ if (fnLength !== 2)
2004
+ throw new Error("cipher output not supported");
2005
+ abytes(output);
1456
2006
  }
1457
- logger.debug("circle failed validation, retrying", {
1458
- circleId: String(circleId),
1459
- remainingCircles: remaining.length - 1
1460
- });
1461
- remaining = remaining.filter((c) => c.circleId !== selected.circleId);
1462
- return attempt(attemptsLeft - 1);
1463
- });
2007
+ };
2008
+ let called = false;
2009
+ const wrCipher = {
2010
+ encrypt(data, output) {
2011
+ if (called)
2012
+ throw new Error("cannot encrypt() twice with same key + nonce");
2013
+ called = true;
2014
+ abytes(data);
2015
+ checkOutput(cipher.encrypt.length, output);
2016
+ return cipher.encrypt(data, output);
2017
+ },
2018
+ decrypt(data, output) {
2019
+ abytes(data);
2020
+ if (tagl && data.length < tagl)
2021
+ throw new Error("invalid ciphertext length: smaller than tagLength=" + tagl);
2022
+ checkOutput(cipher.decrypt.length, output);
2023
+ return cipher.decrypt(data, output);
2024
+ }
2025
+ };
2026
+ return wrCipher;
1464
2027
  }
1465
- return attempt(MAX_VALIDATION_ATTEMPTS);
2028
+ Object.assign(wrappedCipher, params);
2029
+ return wrappedCipher;
2030
+ };
2031
+ function getOutput(expectedLength, out, onlyAligned = true) {
2032
+ if (out === void 0)
2033
+ return new Uint8Array(expectedLength);
2034
+ if (out.length !== expectedLength)
2035
+ throw new Error("invalid output length, expected " + expectedLength + ", got: " + out.length);
2036
+ if (onlyAligned && !isAligned32(out))
2037
+ throw new Error("invalid output, must be aligned");
2038
+ return out;
2039
+ }
2040
+ function isAligned32(bytes) {
2041
+ return bytes.byteOffset % 4 === 0;
2042
+ }
2043
+ function copyBytes(bytes) {
2044
+ return Uint8Array.from(bytes);
1466
2045
  }
1467
2046
 
1468
- // src/order-routing/subgraph/client.ts
1469
- var import_neverthrow10 = require("neverthrow");
1470
- var DEFAULT_TIMEOUT_MS = 1e4;
1471
- var MAX_RETRIES = 3;
1472
- var BACKOFF_MS = 500;
1473
- function isTransient(error) {
1474
- if (error instanceof OrderRoutingError) return false;
1475
- if (error instanceof DOMException && error.name === "AbortError") return true;
1476
- if (error instanceof TypeError) return true;
1477
- return false;
1478
- }
1479
- function querySubgraph(url, params) {
1480
- const timeoutMs = params.timeoutMs ?? DEFAULT_TIMEOUT_MS;
1481
- const fetchOnce = async () => {
1482
- const controller = new AbortController();
1483
- const timer = setTimeout(() => controller.abort(), timeoutMs);
1484
- try {
1485
- const response = await fetch(url, {
1486
- method: "POST",
1487
- headers: { "Content-Type": "application/json" },
1488
- body: JSON.stringify({
1489
- query: params.query,
1490
- variables: params.variables
1491
- }),
1492
- signal: controller.signal
1493
- });
1494
- if (!response.ok) {
1495
- throw new OrderRoutingError(`Subgraph request failed (status: ${response.status})`, {
1496
- code: "SUBGRAPH_ERROR",
1497
- cause: response,
1498
- context: { status: response.status }
1499
- });
1500
- }
1501
- const json = await response.json();
1502
- if (json.errors?.length > 0) {
1503
- throw new OrderRoutingError("Subgraph returned GraphQL errors", {
1504
- code: "SUBGRAPH_ERROR",
1505
- cause: json.errors,
1506
- context: { errors: json.errors }
1507
- });
1508
- }
1509
- if (!json.data) {
1510
- throw new OrderRoutingError("Subgraph returned no data", {
1511
- code: "SUBGRAPH_ERROR",
1512
- cause: "Missing data field in GraphQL response",
1513
- context: { response: json }
1514
- });
1515
- }
1516
- return json.data;
1517
- } finally {
1518
- clearTimeout(timer);
1519
- }
1520
- };
1521
- const fetchWithRetry = async () => {
1522
- for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
1523
- try {
1524
- return await fetchOnce();
1525
- } catch (error) {
1526
- const lastAttempt = attempt === MAX_RETRIES;
1527
- if (lastAttempt || !isTransient(error)) throw error;
1528
- await sleep(BACKOFF_MS * (attempt + 1));
1529
- }
1530
- }
1531
- throw new OrderRoutingError("Subgraph query exhausted retries", {
1532
- code: "SUBGRAPH_ERROR"
1533
- });
1534
- };
1535
- return import_neverthrow10.ResultAsync.fromPromise(
1536
- fetchWithRetry(),
1537
- (error) => error instanceof OrderRoutingError ? error : new OrderRoutingError("Subgraph query failed", {
1538
- code: "SUBGRAPH_ERROR",
1539
- cause: error
1540
- })
1541
- );
1542
- }
1543
-
1544
- // src/order-routing/subgraph/queries.ts
1545
- var CIRCLES_FOR_ROUTING_QUERY = (
1546
- /* GraphQL */
1547
- `
1548
- query CirclesForRouting($currency: Bytes!) {
1549
- circles(
1550
- first: 1000
1551
- where: {
1552
- currency: $currency
1553
- metrics_: {
1554
- circleStatus_in: ["active", "bootstrap", "paused"]
1555
- }
1556
- }
1557
- ) {
1558
- circleId
1559
- currency
1560
- metrics {
1561
- circleScore
1562
- circleStatus
1563
- scoreState {
1564
- activeMerchantsCount
1565
- }
1566
- }
1567
- }
1568
- }
1569
- `
1570
- );
1571
-
1572
- // src/order-routing/subgraph/index.ts
1573
- function getCirclesForRouting(subgraphUrl, currency, logger = noopLogger) {
1574
- logger.debug("fetching circles from subgraph", { subgraphUrl, currency });
1575
- return querySubgraph(subgraphUrl, {
1576
- query: CIRCLES_FOR_ROUTING_QUERY,
1577
- variables: { currency }
1578
- }).andThen(
1579
- (data) => validate(
1580
- ZodCirclesForRoutingResponseSchema,
1581
- data,
1582
- (message, cause, d) => new OrderRoutingError(message, { code: "VALIDATION_ERROR", cause, context: { data: d } })
1583
- ).map((validated) => {
1584
- const circles = validated.circles.filter(
1585
- (item) => Number(item.metrics.scoreState.activeMerchantsCount) > 0
1586
- );
1587
- logger.info("fetched circles from subgraph", {
1588
- total: validated.circles.length,
1589
- withActiveMerchants: circles.length,
1590
- circles
1591
- });
1592
- return circles;
1593
- })
1594
- );
1595
- }
1596
-
1597
- // src/order-routing/client.ts
1598
- function createOrderRouter(config) {
1599
- const { subgraphUrl, publicClient, contractAddress } = config;
1600
- const logger = config.logger ?? noopLogger;
1601
- return {
1602
- selectCircle(params) {
1603
- const currencyHex = (0, import_viem6.stringToHex)(params.currency, { size: 32 });
1604
- logger.info("selectCircle started", {
1605
- currency: params.currency,
1606
- user: params.user,
1607
- orderType: String(params.orderType)
1608
- });
1609
- return getCirclesForRouting(subgraphUrl, currencyHex, logger).andThen(
1610
- (circles) => selectCircleForOrderAsync(
1611
- circles,
1612
- currencyHex,
1613
- (circleId) => checkCircleEligibility(
1614
- publicClient,
1615
- contractAddress,
1616
- {
1617
- circleId,
1618
- currency: currencyHex,
1619
- user: params.user,
1620
- usdtAmount: params.usdtAmount,
1621
- fiatAmount: params.fiatAmount,
1622
- orderType: params.orderType,
1623
- preferredPCConfigId: params.preferredPCConfigId
1624
- },
1625
- logger
1626
- ),
1627
- logger
1628
- )
1629
- );
1630
- }
1631
- };
1632
- }
1633
-
1634
- // src/payload/actions.ts
1635
- var import_neverthrow13 = require("neverthrow");
1636
-
1637
- // src/payload/crypto.ts
1638
- var import_neverthrow12 = require("neverthrow");
1639
- var import_viem8 = require("viem");
1640
- var import_accounts2 = require("viem/accounts");
1641
- var import_zod7 = require("zod");
1642
-
1643
- // node_modules/@noble/ciphers/esm/utils.js
1644
- function isBytes(a) {
1645
- return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
1646
- }
1647
- function abytes(b, ...lengths) {
1648
- if (!isBytes(b))
1649
- throw new Error("Uint8Array expected");
1650
- if (lengths.length > 0 && !lengths.includes(b.length))
1651
- throw new Error("Uint8Array expected of length " + lengths + ", got length=" + b.length);
1652
- }
1653
- function u32(arr) {
1654
- return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
1655
- }
1656
- function clean(...arrays) {
1657
- for (let i = 0; i < arrays.length; i++) {
1658
- arrays[i].fill(0);
1659
- }
1660
- }
1661
- var isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68)();
1662
- function overlapBytes(a, b) {
1663
- return a.buffer === b.buffer && // best we can do, may fail with an obscure Proxy
1664
- a.byteOffset < b.byteOffset + b.byteLength && // a starts before b end
1665
- b.byteOffset < a.byteOffset + a.byteLength;
1666
- }
1667
- function complexOverlapBytes(input, output) {
1668
- if (overlapBytes(input, output) && input.byteOffset < output.byteOffset)
1669
- throw new Error("complex overlap of input and output is not supported");
1670
- }
1671
- var wrapCipher = /* @__NO_SIDE_EFFECTS__ */ (params, constructor) => {
1672
- function wrappedCipher(key, ...args) {
1673
- abytes(key);
1674
- if (!isLE)
1675
- throw new Error("Non little-endian hardware is not yet supported");
1676
- if (params.nonceLength !== void 0) {
1677
- const nonce = args[0];
1678
- if (!nonce)
1679
- throw new Error("nonce / iv required");
1680
- if (params.varSizeNonce)
1681
- abytes(nonce);
1682
- else
1683
- abytes(nonce, params.nonceLength);
1684
- }
1685
- const tagl = params.tagLength;
1686
- if (tagl && args[1] !== void 0) {
1687
- abytes(args[1]);
1688
- }
1689
- const cipher = constructor(key, ...args);
1690
- const checkOutput = (fnLength, output) => {
1691
- if (output !== void 0) {
1692
- if (fnLength !== 2)
1693
- throw new Error("cipher output not supported");
1694
- abytes(output);
1695
- }
1696
- };
1697
- let called = false;
1698
- const wrCipher = {
1699
- encrypt(data, output) {
1700
- if (called)
1701
- throw new Error("cannot encrypt() twice with same key + nonce");
1702
- called = true;
1703
- abytes(data);
1704
- checkOutput(cipher.encrypt.length, output);
1705
- return cipher.encrypt(data, output);
1706
- },
1707
- decrypt(data, output) {
1708
- abytes(data);
1709
- if (tagl && data.length < tagl)
1710
- throw new Error("invalid ciphertext length: smaller than tagLength=" + tagl);
1711
- checkOutput(cipher.decrypt.length, output);
1712
- return cipher.decrypt(data, output);
1713
- }
1714
- };
1715
- return wrCipher;
1716
- }
1717
- Object.assign(wrappedCipher, params);
1718
- return wrappedCipher;
1719
- };
1720
- function getOutput(expectedLength, out, onlyAligned = true) {
1721
- if (out === void 0)
1722
- return new Uint8Array(expectedLength);
1723
- if (out.length !== expectedLength)
1724
- throw new Error("invalid output length, expected " + expectedLength + ", got: " + out.length);
1725
- if (onlyAligned && !isAligned32(out))
1726
- throw new Error("invalid output, must be aligned");
1727
- return out;
1728
- }
1729
- function isAligned32(bytes) {
1730
- return bytes.byteOffset % 4 === 0;
1731
- }
1732
- function copyBytes(bytes) {
1733
- return Uint8Array.from(bytes);
1734
- }
1735
-
1736
- // node_modules/@noble/ciphers/esm/aes.js
1737
- var BLOCK_SIZE = 16;
1738
- var POLY = 283;
1739
- function mul2(n) {
1740
- return n << 1 ^ POLY & -(n >> 7);
2047
+ // node_modules/@noble/ciphers/esm/aes.js
2048
+ var BLOCK_SIZE = 16;
2049
+ var POLY = 283;
2050
+ function mul2(n) {
2051
+ return n << 1 ^ POLY & -(n >> 7);
1741
2052
  }
1742
2053
  function mul(a, b) {
1743
2054
  let res = 0;
@@ -3587,15 +3898,15 @@ function weierstrassPoints(opts) {
3587
3898
  throw new Error("ProjectivePoint expected");
3588
3899
  }
3589
3900
  const toAffineMemo = memoized((p, iz) => {
3590
- const { px: x, py: y, pz: z9 } = p;
3591
- if (Fp.eql(z9, Fp.ONE))
3901
+ const { px: x, py: y, pz: z10 } = p;
3902
+ if (Fp.eql(z10, Fp.ONE))
3592
3903
  return { x, y };
3593
3904
  const is0 = p.is0();
3594
3905
  if (iz == null)
3595
- iz = is0 ? Fp.ONE : Fp.inv(z9);
3906
+ iz = is0 ? Fp.ONE : Fp.inv(z10);
3596
3907
  const ax = Fp.mul(x, iz);
3597
3908
  const ay = Fp.mul(y, iz);
3598
- const zz = Fp.mul(z9, iz);
3909
+ const zz = Fp.mul(z10, iz);
3599
3910
  if (is0)
3600
3911
  return { x: Fp.ZERO, y: Fp.ZERO };
3601
3912
  if (!Fp.eql(zz, Fp.ONE))
@@ -4356,7 +4667,8 @@ var sha2562 = sha256;
4356
4667
  // node_modules/@noble/hashes/esm/sha512.js
4357
4668
  var sha5122 = sha512;
4358
4669
 
4359
- // src/payload/ecies.ts
4670
+ // src/orders/crypto/ecies.ts
4671
+ var MIN_CIPHER_BYTES = 82;
4360
4672
  function hexToBytes3(hex) {
4361
4673
  const bytes = new Uint8Array(hex.length / 2);
4362
4674
  for (let i = 0; i < bytes.length; i++) {
@@ -4369,243 +4681,1323 @@ function bytesToHex2(bytes) {
4369
4681
  for (const b of bytes) {
4370
4682
  hex += b.toString(16).padStart(2, "0");
4371
4683
  }
4372
- return hex;
4373
- }
4374
- function deriveKeys(sharedSecret) {
4375
- const hash = sha5122(sharedSecret);
4376
- return {
4377
- encKey: hash.slice(0, 32),
4378
- macKey: hash.slice(32)
4379
- };
4684
+ return hex;
4685
+ }
4686
+ function timingSafeEqual(a, b) {
4687
+ if (a.length !== b.length) return false;
4688
+ let diff = 0;
4689
+ for (let i = 0; i < a.length; i++) {
4690
+ diff |= a[i] ^ b[i];
4691
+ }
4692
+ return diff === 0;
4693
+ }
4694
+ function deriveKeys(sharedSecret) {
4695
+ const hash = sha5122(sharedSecret);
4696
+ return {
4697
+ encKey: hash.slice(0, 32),
4698
+ macKey: hash.slice(32)
4699
+ };
4700
+ }
4701
+ async function encryptWithPublicKey(publicKey, message) {
4702
+ const pubKeyBytes = hexToBytes3(`04${publicKey}`);
4703
+ const ephemPrivKey = randomBytes(32);
4704
+ const ephemPubKey = secp256k1.getPublicKey(ephemPrivKey, false);
4705
+ const sharedPoint = secp256k1.getSharedSecret(ephemPrivKey, pubKeyBytes, true);
4706
+ const sharedSecret = sharedPoint.slice(1);
4707
+ const { encKey, macKey } = deriveKeys(sharedSecret);
4708
+ const iv = randomBytes(16);
4709
+ const plaintext = new TextEncoder().encode(message);
4710
+ const cipher = cbc(encKey, iv);
4711
+ const ciphertext = cipher.encrypt(plaintext);
4712
+ const macData = concatBytes2(iv, ephemPubKey, ciphertext);
4713
+ const mac = hmac(sha2562, macKey, macData);
4714
+ return {
4715
+ iv: bytesToHex2(iv),
4716
+ ephemPublicKey: bytesToHex2(ephemPubKey),
4717
+ ciphertext: bytesToHex2(ciphertext),
4718
+ mac: bytesToHex2(mac)
4719
+ };
4720
+ }
4721
+ async function decryptWithPrivateKey(privateKey, encrypted) {
4722
+ const privKeyBytes = hexToBytes3(privateKey.replace(/^0x/, ""));
4723
+ const ephemPubKeyBytes = hexToBytes3(encrypted.ephemPublicKey);
4724
+ const ivBytes = hexToBytes3(encrypted.iv);
4725
+ const ciphertextBytes = hexToBytes3(encrypted.ciphertext);
4726
+ const macBytes = hexToBytes3(encrypted.mac);
4727
+ const sharedPoint = secp256k1.getSharedSecret(privKeyBytes, ephemPubKeyBytes, true);
4728
+ const sharedSecret = sharedPoint.slice(1);
4729
+ const { encKey, macKey } = deriveKeys(sharedSecret);
4730
+ const macData = concatBytes2(ivBytes, ephemPubKeyBytes, ciphertextBytes);
4731
+ const computedMac = hmac(sha2562, macKey, macData);
4732
+ if (!timingSafeEqual(computedMac, macBytes)) {
4733
+ throw new Error("MAC mismatch \u2014 ciphertext may be corrupted or tampered with");
4734
+ }
4735
+ const cipher = cbc(encKey, ivBytes);
4736
+ const plaintext = cipher.decrypt(ciphertextBytes);
4737
+ return new TextDecoder().decode(plaintext);
4738
+ }
4739
+ function cipherStringify(encrypted) {
4740
+ const ephemPubKeyBytes = hexToBytes3(encrypted.ephemPublicKey);
4741
+ const compressed = secp256k1.ProjectivePoint.fromHex(ephemPubKeyBytes).toRawBytes(true);
4742
+ const iv = hexToBytes3(encrypted.iv);
4743
+ const mac = hexToBytes3(encrypted.mac);
4744
+ const ciphertext = hexToBytes3(encrypted.ciphertext);
4745
+ return bytesToHex2(concatBytes2(iv, compressed, mac, ciphertext));
4746
+ }
4747
+ function cipherParse(str) {
4748
+ const buf = hexToBytes3(str);
4749
+ if (buf.length < MIN_CIPHER_BYTES) {
4750
+ throw new Error(
4751
+ `cipherParse: input too short (${buf.length} bytes, need at least ${MIN_CIPHER_BYTES})`
4752
+ );
4753
+ }
4754
+ const iv = buf.slice(0, 16);
4755
+ const compressed = buf.slice(16, 49);
4756
+ const mac = buf.slice(49, 81);
4757
+ const ciphertext = buf.slice(81);
4758
+ const ephemPubKey = secp256k1.ProjectivePoint.fromHex(compressed).toRawBytes(false);
4759
+ return {
4760
+ iv: bytesToHex2(iv),
4761
+ ephemPublicKey: bytesToHex2(ephemPubKey),
4762
+ ciphertext: bytesToHex2(ciphertext),
4763
+ mac: bytesToHex2(mac)
4764
+ };
4765
+ }
4766
+
4767
+ // src/orders/crypto/encryption.ts
4768
+ function tryParseLegacyEthCryptoEnvelope(input) {
4769
+ if (input.charCodeAt(0) !== 123) return void 0;
4770
+ let parsed;
4771
+ try {
4772
+ parsed = JSON.parse(input);
4773
+ } catch {
4774
+ return void 0;
4775
+ }
4776
+ if (!parsed || typeof parsed !== "object") return void 0;
4777
+ const o = parsed;
4778
+ if (typeof o.iv !== "string" || typeof o.ephemPublicKey !== "string" || typeof o.ciphertext !== "string" || typeof o.mac !== "string") {
4779
+ return void 0;
4780
+ }
4781
+ return {
4782
+ iv: o.iv,
4783
+ ephemPublicKey: o.ephemPublicKey,
4784
+ ciphertext: o.ciphertext,
4785
+ mac: o.mac
4786
+ };
4787
+ }
4788
+ function encryptPaymentAddress(input) {
4789
+ return (0, import_neverthrow8.safeTry)(async function* () {
4790
+ const messageHash = (0, import_viem10.keccak256)((0, import_viem10.stringToHex)(input.paymentAddress));
4791
+ const signature = yield* import_neverthrow8.ResultAsync.fromPromise(
4792
+ (0, import_accounts2.sign)({ hash: messageHash, privateKey: input.senderIdentity.privateKey }),
4793
+ (cause) => new OrdersError("Failed to sign payment address", {
4794
+ code: "ENCRYPTION_FAILED",
4795
+ cause
4796
+ })
4797
+ ).map(import_viem10.serializeSignature);
4798
+ const payload = JSON.stringify({ message: input.paymentAddress, signature });
4799
+ const encrypted = yield* import_neverthrow8.ResultAsync.fromPromise(
4800
+ encryptWithPublicKey(input.recipientPublicKey, payload),
4801
+ (cause) => new OrdersError("ECIES encryption failed", {
4802
+ code: "ENCRYPTION_FAILED",
4803
+ cause
4804
+ })
4805
+ );
4806
+ const safeStringify = import_neverthrow8.Result.fromThrowable(
4807
+ (e) => cipherStringify(e),
4808
+ (cause) => new OrdersError("Ciphertext stringify failed", {
4809
+ code: "ENCRYPTION_FAILED",
4810
+ cause
4811
+ })
4812
+ );
4813
+ return (0, import_neverthrow8.ok)(yield* safeStringify(encrypted));
4814
+ });
4815
+ }
4816
+ var ZodDecryptedPayloadSchema = import_zod5.z.object({
4817
+ message: import_zod5.z.string(),
4818
+ signature: import_zod5.z.string()
4819
+ });
4820
+ function decryptPaymentAddress(input) {
4821
+ return (0, import_neverthrow8.safeTry)(async function* () {
4822
+ const legacyEnvelope = tryParseLegacyEthCryptoEnvelope(input.encrypted);
4823
+ const safeCipherParse = import_neverthrow8.Result.fromThrowable(
4824
+ (s) => cipherParse(s),
4825
+ (cause) => new OrdersError("Failed to parse ciphertext", {
4826
+ code: "ENCRYPTION_FAILED",
4827
+ cause
4828
+ })
4829
+ );
4830
+ const encryptedData = legacyEnvelope ?? (yield* safeCipherParse(input.encrypted));
4831
+ const plaintext = yield* import_neverthrow8.ResultAsync.fromPromise(
4832
+ decryptWithPrivateKey(input.recipientIdentity.privateKey, encryptedData),
4833
+ (cause) => new OrdersError("ECIES decryption failed", {
4834
+ code: "ENCRYPTION_FAILED",
4835
+ cause
4836
+ })
4837
+ );
4838
+ if (legacyEnvelope) {
4839
+ return (0, import_neverthrow8.ok)(plaintext);
4840
+ }
4841
+ const safeJsonParse = import_neverthrow8.Result.fromThrowable(
4842
+ (s) => JSON.parse(s),
4843
+ (cause) => new OrdersError("Failed to parse decrypted payload JSON", {
4844
+ code: "ENCRYPTION_FAILED",
4845
+ cause
4846
+ })
4847
+ );
4848
+ const parsed = yield* safeJsonParse(plaintext);
4849
+ const payload = yield* validate(
4850
+ ZodDecryptedPayloadSchema,
4851
+ parsed,
4852
+ (message, cause, data) => new OrdersError(message, {
4853
+ code: "ENCRYPTION_FAILED",
4854
+ cause,
4855
+ context: { data }
4856
+ })
4857
+ );
4858
+ return (0, import_neverthrow8.ok)(payload.message);
4859
+ });
4860
+ }
4861
+
4862
+ // src/orders/actions/set-sell-order-upi.ts
4863
+ function createSetSellOrderUpiAction(input) {
4864
+ const { publicClient, diamondAddress, relayIdentityStore, relayIdentity } = input;
4865
+ const prepareFn = (params) => validate(
4866
+ ZodSetSellOrderUpiParamsSchema,
4867
+ params,
4868
+ (message, cause, data) => new OrdersError(message, {
4869
+ code: "VALIDATION_ERROR",
4870
+ cause,
4871
+ context: { data }
4872
+ })
4873
+ ).asyncAndThen(
4874
+ (v) => resolveRelayIdentity({ relayIdentity, store: relayIdentityStore }).andThen(
4875
+ (senderIdentity) => encryptPaymentAddress({
4876
+ paymentAddress: v.paymentAddress,
4877
+ recipientPublicKey: v.merchantPublicKey,
4878
+ senderIdentity
4879
+ }).map((userEncUpi) => ({ v, userEncUpi, senderIdentity }))
4880
+ )
4881
+ ).map(({ v, userEncUpi, senderIdentity }) => ({
4882
+ to: diamondAddress,
4883
+ data: (0, import_viem11.encodeFunctionData)({
4884
+ abi: ABIS.FACETS.ORDER_FLOW,
4885
+ functionName: "setSellOrderUpi",
4886
+ args: [v.orderId, userEncUpi, v.updatedAmount]
4887
+ }),
4888
+ value: 0n,
4889
+ meta: { relayIdentity: senderIdentity }
4890
+ }));
4891
+ return {
4892
+ prepare(params) {
4893
+ return prepareFn(params);
4894
+ },
4895
+ execute({ walletClient, waitForReceipt, ...params }) {
4896
+ return prepareFn(params).andThen(
4897
+ (prepared) => submitPreparedTx({ prepared, walletClient, publicClient, waitForReceipt })
4898
+ );
4899
+ }
4900
+ };
4901
+ }
4902
+
4903
+ // src/orders/internal/routing/client.ts
4904
+ var import_viem16 = require("viem");
4905
+
4906
+ // src/contracts/order-flow/index.ts
4907
+ var import_neverthrow9 = require("neverthrow");
4908
+
4909
+ // src/orders/internal/routing/errors.ts
4910
+ var OrderRoutingError = class extends SdkError {
4911
+ constructor(message, options) {
4912
+ super(message, options);
4913
+ this.name = "OrderRoutingError";
4914
+ }
4915
+ };
4916
+
4917
+ // src/orders/internal/routing/validation.ts
4918
+ var import_zod6 = require("zod");
4919
+ var ZodCircleScoreStateSchema = import_zod6.z.object({
4920
+ activeMerchantsCount: import_zod6.z.coerce.number()
4921
+ });
4922
+ var ZodCircleMetricsForRoutingSchema = import_zod6.z.object({
4923
+ circleScore: import_zod6.z.coerce.number(),
4924
+ circleStatus: import_zod6.z.string(),
4925
+ scoreState: ZodCircleScoreStateSchema
4926
+ });
4927
+ var ZodCircleForRoutingSchema = import_zod6.z.object({
4928
+ circleId: import_zod6.z.string(),
4929
+ currency: import_zod6.z.string(),
4930
+ metrics: ZodCircleMetricsForRoutingSchema
4931
+ });
4932
+ var ZodCirclesForRoutingResponseSchema = import_zod6.z.object({
4933
+ circles: import_zod6.z.array(ZodCircleForRoutingSchema)
4934
+ });
4935
+ var ZodCheckCircleEligibilityParamsSchema = import_zod6.z.object({
4936
+ circleId: import_zod6.z.bigint(),
4937
+ currency: import_zod6.z.string(),
4938
+ user: ZodAddressSchema,
4939
+ usdtAmount: import_zod6.z.bigint(),
4940
+ fiatAmount: import_zod6.z.bigint(),
4941
+ orderType: import_zod6.z.bigint(),
4942
+ preferredPCConfigId: import_zod6.z.bigint()
4943
+ });
4944
+ var ZodSelectCircleParamsSchema = import_zod6.z.object({
4945
+ currency: import_zod6.z.string().min(1),
4946
+ user: ZodAddressSchema,
4947
+ usdtAmount: import_zod6.z.bigint(),
4948
+ fiatAmount: import_zod6.z.bigint(),
4949
+ orderType: import_zod6.z.bigint(),
4950
+ preferredPCConfigId: import_zod6.z.bigint()
4951
+ });
4952
+
4953
+ // src/contracts/order-flow/index.ts
4954
+ function checkCircleEligibility(publicClient, contractAddress, params, logger = noopLogger) {
4955
+ return validate(
4956
+ ZodCheckCircleEligibilityParamsSchema,
4957
+ params,
4958
+ (message, cause, d) => new OrderRoutingError(message, { code: "VALIDATION_ERROR", cause, context: { data: d } })
4959
+ ).asyncAndThen((validated) => {
4960
+ logger.debug("checking on-chain eligibility", {
4961
+ circleId: String(validated.circleId),
4962
+ contractAddress
4963
+ });
4964
+ return import_neverthrow9.ResultAsync.fromPromise(
4965
+ publicClient.readContract({
4966
+ address: contractAddress,
4967
+ abi: ABIS.FACETS.ORDER_FLOW,
4968
+ functionName: "getAssignableMerchantsFromCircle",
4969
+ args: [
4970
+ validated.circleId,
4971
+ 1n,
4972
+ validated.currency,
4973
+ validated.user,
4974
+ validated.usdtAmount,
4975
+ validated.fiatAmount,
4976
+ validated.orderType,
4977
+ validated.preferredPCConfigId
4978
+ ]
4979
+ }),
4980
+ (error) => new OrderRoutingError("Eligibility check failed", {
4981
+ code: "CONTRACT_READ_ERROR",
4982
+ cause: error,
4983
+ context: { circleId: String(params.circleId) }
4984
+ })
4985
+ );
4986
+ }).map((merchants) => {
4987
+ const arr = merchants;
4988
+ const eligible = arr.length >= 1;
4989
+ logger.debug("eligibility check result", {
4990
+ circleId: String(params.circleId),
4991
+ assignableMerchants: arr.length,
4992
+ eligible
4993
+ });
4994
+ return eligible;
4995
+ });
4996
+ }
4997
+
4998
+ // src/contracts/p2p-config/index.ts
4999
+ var import_neverthrow10 = require("neverthrow");
5000
+ var import_viem12 = require("viem");
5001
+
5002
+ // src/prices/errors.ts
5003
+ var PricesError = class extends SdkError {
5004
+ constructor(message, options) {
5005
+ super(message, options);
5006
+ this.name = "PricesError";
5007
+ }
5008
+ };
5009
+
5010
+ // src/prices/validation.ts
5011
+ var import_zod7 = require("zod");
5012
+ var ZodCurrencyScopedParamsSchema = import_zod7.z.object({
5013
+ currency: ZodCurrencySchema
5014
+ });
5015
+
5016
+ // src/contracts/p2p-config/index.ts
5017
+ function getPriceConfig(publicClient, diamondAddress, params) {
5018
+ return validate(
5019
+ ZodCurrencyScopedParamsSchema,
5020
+ params,
5021
+ (message, cause, data) => new PricesError(message, {
5022
+ code: "VALIDATION_ERROR",
5023
+ cause,
5024
+ context: { params: data }
5025
+ })
5026
+ ).asyncAndThen(
5027
+ (validated) => import_neverthrow10.ResultAsync.fromPromise(
5028
+ publicClient.readContract({
5029
+ address: diamondAddress,
5030
+ abi: ABIS.FACETS.CONFIG,
5031
+ functionName: "getPriceConfig",
5032
+ args: [(0, import_viem12.stringToHex)(validated.currency, { size: 32 })]
5033
+ }),
5034
+ (error) => new PricesError("Failed to read price config", {
5035
+ code: "CONTRACT_READ_ERROR",
5036
+ cause: error,
5037
+ context: { currency: validated.currency, diamondAddress }
5038
+ })
5039
+ )
5040
+ );
5041
+ }
5042
+ function getReputationPerUsdcLimit(publicClient, diamondAddress, params) {
5043
+ return validate(
5044
+ ZodCurrencyScopedParamsSchema,
5045
+ params,
5046
+ (message, cause, data) => new PricesError(message, {
5047
+ code: "VALIDATION_ERROR",
5048
+ cause,
5049
+ context: { params: data }
5050
+ })
5051
+ ).asyncAndThen(
5052
+ (validated) => import_neverthrow10.ResultAsync.fromPromise(
5053
+ publicClient.readContract({
5054
+ address: diamondAddress,
5055
+ abi: ABIS.DIAMOND,
5056
+ functionName: "getRpPerUsdtLimitRational",
5057
+ args: [(0, import_viem12.stringToHex)(validated.currency, { size: 32 })]
5058
+ }),
5059
+ (error) => new PricesError("Failed to read reputation-per-USDC limit", {
5060
+ code: "CONTRACT_READ_ERROR",
5061
+ cause: error,
5062
+ context: { currency: validated.currency, diamondAddress }
5063
+ })
5064
+ ).map(([numerator, denominator]) => ({
5065
+ numerator,
5066
+ denominator,
5067
+ multiplier: numerator > 0n ? Number(denominator) / Number(numerator) : 0
5068
+ }))
5069
+ );
5070
+ }
5071
+
5072
+ // src/contracts/reputation-manager/writes.ts
5073
+ var import_neverthrow11 = require("neverthrow");
5074
+ var import_viem13 = require("viem");
5075
+
5076
+ // src/zkkyc/errors.ts
5077
+ var ZkkycError = class extends SdkError {
5078
+ constructor(message, options) {
5079
+ super(message, options);
5080
+ this.name = "ZkkycError";
5081
+ }
5082
+ };
5083
+
5084
+ // src/zkkyc/validation.ts
5085
+ var import_zod8 = require("zod");
5086
+ var ZodAnonAadharProofParamsSchema = import_zod8.z.object({
5087
+ nullifierSeed: import_zod8.z.bigint(),
5088
+ nullifier: import_zod8.z.bigint(),
5089
+ timestamp: import_zod8.z.bigint(),
5090
+ signal: import_zod8.z.bigint(),
5091
+ revealArray: import_zod8.z.tuple([import_zod8.z.bigint(), import_zod8.z.bigint(), import_zod8.z.bigint(), import_zod8.z.bigint()]),
5092
+ packedGroth16Proof: import_zod8.z.tuple([
5093
+ import_zod8.z.bigint(),
5094
+ import_zod8.z.bigint(),
5095
+ import_zod8.z.bigint(),
5096
+ import_zod8.z.bigint(),
5097
+ import_zod8.z.bigint(),
5098
+ import_zod8.z.bigint(),
5099
+ import_zod8.z.bigint(),
5100
+ import_zod8.z.bigint()
5101
+ ])
5102
+ });
5103
+ var ZodSocialVerifyParamsSchema = import_zod8.z.object({
5104
+ _socialName: import_zod8.z.string(),
5105
+ proofs: import_zod8.z.array(
5106
+ import_zod8.z.object({
5107
+ claimInfo: import_zod8.z.object({
5108
+ provider: import_zod8.z.string(),
5109
+ parameters: import_zod8.z.string(),
5110
+ context: import_zod8.z.string()
5111
+ }),
5112
+ signedClaim: import_zod8.z.object({
5113
+ claim: import_zod8.z.object({
5114
+ identifier: import_zod8.z.string(),
5115
+ owner: ZodAddressSchema,
5116
+ timestampS: import_zod8.z.number(),
5117
+ epoch: import_zod8.z.number()
5118
+ }),
5119
+ signatures: import_zod8.z.array(import_zod8.z.string())
5120
+ })
5121
+ })
5122
+ )
5123
+ });
5124
+ var ZodSolidityVerifierParametersSchema = import_zod8.z.object({
5125
+ version: import_zod8.z.string().refine((val) => val.startsWith("0x"), {
5126
+ message: "Version must be a hex string"
5127
+ }),
5128
+ proofVerificationData: import_zod8.z.object({
5129
+ vkeyHash: import_zod8.z.string().refine((val) => /^0x[a-fA-F0-9]{64}$/.test(val), {
5130
+ message: "Invalid bytes32 hex string"
5131
+ }),
5132
+ proof: import_zod8.z.string().refine((val) => val.startsWith("0x"), {
5133
+ message: "Proof must be a hex string"
5134
+ }),
5135
+ publicInputs: import_zod8.z.array(
5136
+ import_zod8.z.string().refine((val) => /^0x[a-fA-F0-9]{64}$/.test(val), {
5137
+ message: "Each public input must be a valid bytes32 hex string"
5138
+ })
5139
+ )
5140
+ }),
5141
+ committedInputs: import_zod8.z.string().refine((val) => val.startsWith("0x"), {
5142
+ message: "Committed inputs must be a hex string"
5143
+ }),
5144
+ serviceConfig: import_zod8.z.object({
5145
+ validityPeriodInSeconds: import_zod8.z.number().int().nonnegative(),
5146
+ domain: import_zod8.z.string(),
5147
+ scope: import_zod8.z.string(),
5148
+ devMode: import_zod8.z.boolean()
5149
+ })
5150
+ });
5151
+ var ZodZkPassportRegisterParamsSchema = import_zod8.z.object({
5152
+ params: ZodSolidityVerifierParametersSchema,
5153
+ isIDCard: import_zod8.z.boolean()
5154
+ });
5155
+
5156
+ // src/contracts/reputation-manager/writes.ts
5157
+ function prepareSocialVerify(reputationManagerAddress, params) {
5158
+ return validate(
5159
+ ZodSocialVerifyParamsSchema,
5160
+ params,
5161
+ (message, cause, data) => new ZkkycError(message, { code: "VALIDATION_ERROR", cause, context: { params: data } })
5162
+ ).andThen(
5163
+ (validated) => import_neverthrow11.Result.fromThrowable(
5164
+ () => ({
5165
+ to: reputationManagerAddress,
5166
+ data: (0, import_viem13.encodeFunctionData)({
5167
+ abi: ABIS.EXTERNAL.REPUTATION_MANAGER,
5168
+ functionName: "socialVerify",
5169
+ args: [
5170
+ validated._socialName,
5171
+ validated.proofs.map((proof) => ({
5172
+ ...proof,
5173
+ signedClaim: {
5174
+ ...proof.signedClaim,
5175
+ claim: {
5176
+ ...proof.signedClaim.claim,
5177
+ identifier: proof.signedClaim.claim.identifier
5178
+ },
5179
+ signatures: proof.signedClaim.signatures
5180
+ }
5181
+ }))
5182
+ ]
5183
+ })
5184
+ }),
5185
+ (error) => new ZkkycError("Failed to encode socialVerify", {
5186
+ code: "ENCODE_ERROR",
5187
+ cause: error
5188
+ })
5189
+ )()
5190
+ );
5191
+ }
5192
+ function prepareSubmitAnonAadharProof(reputationManagerAddress, params) {
5193
+ return validate(
5194
+ ZodAnonAadharProofParamsSchema,
5195
+ params,
5196
+ (message, cause, data) => new ZkkycError(message, { code: "VALIDATION_ERROR", cause, context: { params: data } })
5197
+ ).andThen(
5198
+ (validated) => import_neverthrow11.Result.fromThrowable(
5199
+ () => ({
5200
+ to: reputationManagerAddress,
5201
+ data: (0, import_viem13.encodeFunctionData)({
5202
+ abi: ABIS.EXTERNAL.REPUTATION_MANAGER,
5203
+ functionName: "submitAnonAadharProof",
5204
+ args: [
5205
+ validated.nullifierSeed,
5206
+ validated.nullifier,
5207
+ validated.timestamp,
5208
+ validated.signal,
5209
+ validated.revealArray,
5210
+ validated.packedGroth16Proof
5211
+ ]
5212
+ })
5213
+ }),
5214
+ (error) => new ZkkycError("Failed to encode submitAnonAadharProof", {
5215
+ code: "ENCODE_ERROR",
5216
+ cause: error
5217
+ })
5218
+ )()
5219
+ );
5220
+ }
5221
+ function prepareZkPassportRegister(reputationManagerAddress, params) {
5222
+ return validate(
5223
+ ZodZkPassportRegisterParamsSchema,
5224
+ params,
5225
+ (message, cause, data) => new ZkkycError(message, { code: "VALIDATION_ERROR", cause, context: { params: data } })
5226
+ ).andThen(
5227
+ (validated) => import_neverthrow11.Result.fromThrowable(
5228
+ () => {
5229
+ const { proofVerificationData, serviceConfig, committedInputs, version } = validated.params;
5230
+ const proofVerificationParams = {
5231
+ version,
5232
+ proofVerificationData: {
5233
+ vkeyHash: proofVerificationData.vkeyHash,
5234
+ proof: proofVerificationData.proof,
5235
+ publicInputs: proofVerificationData.publicInputs
5236
+ },
5237
+ committedInputs,
5238
+ serviceConfig: {
5239
+ validityPeriodInSeconds: BigInt(serviceConfig.validityPeriodInSeconds),
5240
+ domain: serviceConfig.domain,
5241
+ scope: serviceConfig.scope,
5242
+ devMode: serviceConfig.devMode
5243
+ }
5244
+ };
5245
+ return {
5246
+ to: reputationManagerAddress,
5247
+ data: (0, import_viem13.encodeFunctionData)({
5248
+ abi: ABIS.EXTERNAL.REPUTATION_MANAGER,
5249
+ functionName: "zkPassportRegister",
5250
+ args: [proofVerificationParams, validated.isIDCard]
5251
+ })
5252
+ };
5253
+ },
5254
+ (error) => new ZkkycError("Failed to encode zkPassportRegister", {
5255
+ code: "ENCODE_ERROR",
5256
+ cause: error
5257
+ })
5258
+ )()
5259
+ );
5260
+ }
5261
+
5262
+ // src/contracts/tx-limits/index.ts
5263
+ var import_neverthrow12 = require("neverthrow");
5264
+ var import_viem14 = require("viem");
5265
+
5266
+ // src/profile/errors.ts
5267
+ var ProfileError = class extends SdkError {
5268
+ constructor(message, options) {
5269
+ super(message, options);
5270
+ this.name = "ProfileError";
5271
+ }
5272
+ };
5273
+
5274
+ // src/profile/validation.ts
5275
+ var import_zod9 = require("zod");
5276
+ var ZodUsdcBalanceParamsSchema = import_zod9.z.object({
5277
+ address: ZodAddressSchema
5278
+ });
5279
+ var ZodUsdcAllowanceParamsSchema = import_zod9.z.object({
5280
+ owner: ZodAddressSchema
5281
+ });
5282
+ var ZodGetBalancesParamsSchema = import_zod9.z.object({
5283
+ address: ZodAddressSchema,
5284
+ currency: ZodCurrencySchema
5285
+ });
5286
+ var ZodTxLimitsParamsSchema = import_zod9.z.object({
5287
+ address: ZodAddressSchema,
5288
+ currency: ZodCurrencySchema
5289
+ });
5290
+
5291
+ // src/contracts/tx-limits/index.ts
5292
+ function getTxLimits(publicClient, diamondAddress, params) {
5293
+ return validate(
5294
+ ZodTxLimitsParamsSchema,
5295
+ params,
5296
+ (message, cause, data) => new ProfileError(message, {
5297
+ code: "VALIDATION_ERROR",
5298
+ cause,
5299
+ context: { params: data }
5300
+ })
5301
+ ).asyncAndThen(
5302
+ (validated) => import_neverthrow12.ResultAsync.fromPromise(
5303
+ publicClient.readContract({
5304
+ address: diamondAddress,
5305
+ abi: ABIS.FACETS.ORDER_FLOW,
5306
+ functionName: "userTxLimit",
5307
+ args: [validated.address, (0, import_viem14.stringToHex)(validated.currency, { size: 32 })]
5308
+ }),
5309
+ (error) => new ProfileError("Failed to read tx limits", {
5310
+ code: "CONTRACT_READ_ERROR",
5311
+ cause: error,
5312
+ context: { address: validated.address, currency: validated.currency, diamondAddress }
5313
+ })
5314
+ ).map(([buyLimit, sellLimit]) => ({
5315
+ buyLimit: Number((0, import_viem14.formatUnits)(buyLimit, 6)),
5316
+ sellLimit: Number((0, import_viem14.formatUnits)(sellLimit, 6))
5317
+ }))
5318
+ );
5319
+ }
5320
+
5321
+ // src/contracts/usdc/index.ts
5322
+ var import_neverthrow13 = require("neverthrow");
5323
+ var import_viem15 = require("viem");
5324
+ function getUsdcBalance(publicClient, usdcAddress, params) {
5325
+ return validate(
5326
+ ZodUsdcBalanceParamsSchema,
5327
+ params,
5328
+ (message, cause, data) => new ProfileError(message, {
5329
+ code: "VALIDATION_ERROR",
5330
+ cause,
5331
+ context: { params: data }
5332
+ })
5333
+ ).asyncAndThen(
5334
+ (validated) => import_neverthrow13.ResultAsync.fromPromise(
5335
+ publicClient.readContract({
5336
+ address: usdcAddress,
5337
+ abi: ABIS.EXTERNAL.USDC,
5338
+ functionName: "balanceOf",
5339
+ args: [validated.address]
5340
+ }),
5341
+ (error) => new ProfileError("Failed to read USDC balance", {
5342
+ code: "CONTRACT_READ_ERROR",
5343
+ cause: error,
5344
+ context: { address: validated.address, usdcAddress }
5345
+ })
5346
+ )
5347
+ );
5348
+ }
5349
+ function getUsdcAllowance(publicClient, usdcAddress, diamondAddress, params) {
5350
+ return validate(
5351
+ ZodUsdcAllowanceParamsSchema,
5352
+ params,
5353
+ (message, cause, data) => new ProfileError(message, {
5354
+ code: "VALIDATION_ERROR",
5355
+ cause,
5356
+ context: { params: data }
5357
+ })
5358
+ ).asyncAndThen(
5359
+ (validated) => import_neverthrow13.ResultAsync.fromPromise(
5360
+ publicClient.readContract({
5361
+ address: usdcAddress,
5362
+ abi: import_viem15.erc20Abi,
5363
+ functionName: "allowance",
5364
+ args: [validated.owner, diamondAddress]
5365
+ }),
5366
+ (error) => new ProfileError("Failed to read USDC allowance", {
5367
+ code: "CONTRACT_READ_ERROR",
5368
+ cause: error,
5369
+ context: { owner: validated.owner, usdcAddress, diamondAddress }
5370
+ })
5371
+ )
5372
+ );
5373
+ }
5374
+
5375
+ // src/orders/internal/routing/routing.ts
5376
+ var import_neverthrow14 = require("neverthrow");
5377
+ var EPSILON = 0.25;
5378
+ var RECOVERY_SCALE = 0.3;
5379
+ var BOOTSTRAP_MAX_WEIGHT = 25;
5380
+ var MAX_VALIDATION_ATTEMPTS = 3;
5381
+ function circleWeight(c) {
5382
+ const score = c.metrics.circleScore;
5383
+ if (c.metrics.circleStatus === "paused") {
5384
+ return score * RECOVERY_SCALE;
5385
+ }
5386
+ if (c.metrics.circleStatus === "bootstrap") {
5387
+ return Math.min(score, BOOTSTRAP_MAX_WEIGHT);
5388
+ }
5389
+ return score;
5390
+ }
5391
+ function filterEligibleCircles(circles, orderCurrency) {
5392
+ return circles.filter((c) => c.currency.toLowerCase() === orderCurrency.toLowerCase());
5393
+ }
5394
+ function weightedRandomChoice(arr, weights) {
5395
+ const totalWeight = weights.reduce((sum, w) => sum + w, 0);
5396
+ if (totalWeight === 0) {
5397
+ return arr[Math.floor(Math.random() * arr.length)];
5398
+ }
5399
+ let rand = Math.random() * totalWeight;
5400
+ for (let i = 0; i < arr.length; i++) {
5401
+ rand -= weights[i];
5402
+ if (rand <= 0) {
5403
+ return arr[i];
5404
+ }
5405
+ }
5406
+ return arr[arr.length - 1];
5407
+ }
5408
+ function selectCircle(eligible) {
5409
+ if (eligible.length === 0) {
5410
+ return null;
5411
+ }
5412
+ const activeCircles = eligible.filter((c) => c.metrics.circleStatus === "active");
5413
+ const isExplore = Math.random() < EPSILON;
5414
+ if (isExplore) {
5415
+ const weights2 = eligible.map(circleWeight);
5416
+ return weightedRandomChoice(eligible, weights2);
5417
+ }
5418
+ if (activeCircles.length === 0) {
5419
+ const weights2 = eligible.map(circleWeight);
5420
+ return weightedRandomChoice(eligible, weights2);
5421
+ }
5422
+ const weights = activeCircles.map((c) => c.metrics.circleScore);
5423
+ return weightedRandomChoice(activeCircles, weights);
5424
+ }
5425
+ function selectCircleForOrderAsync(circles, orderCurrency, validateCircle, logger = noopLogger) {
5426
+ const eligible = filterEligibleCircles(circles, orderCurrency);
5427
+ let remaining = [...eligible];
5428
+ logger.debug("filtering eligible circles", {
5429
+ total: circles.length,
5430
+ eligible: eligible.length,
5431
+ currency: orderCurrency,
5432
+ circles: eligible
5433
+ });
5434
+ if (eligible.length === 0) {
5435
+ logger.warn("no eligible circles found for currency", { currency: orderCurrency });
5436
+ }
5437
+ function attempt(attemptsLeft) {
5438
+ if (attemptsLeft <= 0 || remaining.length === 0) {
5439
+ logger.warn("exhausted all attempts or circles", {
5440
+ attemptsLeft,
5441
+ remainingCircles: remaining.length
5442
+ });
5443
+ return (0, import_neverthrow14.errAsync)(
5444
+ new OrderRoutingError("No eligible circles found", {
5445
+ code: "NO_ELIGIBLE_CIRCLES"
5446
+ })
5447
+ );
5448
+ }
5449
+ const selected = selectCircle(remaining);
5450
+ if (!selected) {
5451
+ return (0, import_neverthrow14.errAsync)(
5452
+ new OrderRoutingError("No eligible circles found", {
5453
+ code: "NO_ELIGIBLE_CIRCLES"
5454
+ })
5455
+ );
5456
+ }
5457
+ const circleId = BigInt(selected.circleId);
5458
+ logger.debug("selected circle, validating on-chain", {
5459
+ circleId: String(circleId),
5460
+ status: selected.metrics.circleStatus,
5461
+ score: selected.metrics.circleScore,
5462
+ attemptsLeft
5463
+ });
5464
+ return validateCircle(circleId).orElse((error) => {
5465
+ logger.warn("validation errored, treating as ineligible", {
5466
+ circleId: String(circleId),
5467
+ error: String(error)
5468
+ });
5469
+ return (0, import_neverthrow14.okAsync)(false);
5470
+ }).andThen((isValid) => {
5471
+ if (isValid) {
5472
+ logger.info("circle validated successfully", { circleId: String(circleId) });
5473
+ return (0, import_neverthrow14.okAsync)(circleId);
5474
+ }
5475
+ logger.debug("circle failed validation, retrying", {
5476
+ circleId: String(circleId),
5477
+ remainingCircles: remaining.length - 1
5478
+ });
5479
+ remaining = remaining.filter((c) => c.circleId !== selected.circleId);
5480
+ return attempt(attemptsLeft - 1);
5481
+ });
5482
+ }
5483
+ return attempt(MAX_VALIDATION_ATTEMPTS);
5484
+ }
5485
+
5486
+ // src/orders/internal/routing/subgraph/queries.ts
5487
+ var CIRCLES_FOR_ROUTING_QUERY = (
5488
+ /* GraphQL */
5489
+ `
5490
+ query CirclesForRouting($currency: Bytes!) {
5491
+ circles(
5492
+ first: 1000
5493
+ where: {
5494
+ currency: $currency
5495
+ metrics_: {
5496
+ circleStatus_in: ["active", "bootstrap", "paused"]
5497
+ }
5498
+ }
5499
+ ) {
5500
+ circleId
5501
+ currency
5502
+ metrics {
5503
+ circleScore
5504
+ circleStatus
5505
+ scoreState {
5506
+ activeMerchantsCount
5507
+ }
5508
+ }
5509
+ }
5510
+ }
5511
+ `
5512
+ );
5513
+
5514
+ // src/orders/internal/routing/subgraph/index.ts
5515
+ function getCirclesForRouting(subgraphUrl, currency, logger = noopLogger) {
5516
+ logger.debug("fetching circles from subgraph", { subgraphUrl, currency });
5517
+ return querySubgraph(subgraphUrl, {
5518
+ query: CIRCLES_FOR_ROUTING_QUERY,
5519
+ variables: { currency }
5520
+ }).mapErr(
5521
+ (e) => new OrderRoutingError(e.message, {
5522
+ code: "SUBGRAPH_ERROR",
5523
+ cause: e.cause ?? e,
5524
+ context: e.context
5525
+ })
5526
+ ).andThen(
5527
+ (data) => validate(
5528
+ ZodCirclesForRoutingResponseSchema,
5529
+ data,
5530
+ (message, cause, d) => new OrderRoutingError(message, { code: "VALIDATION_ERROR", cause, context: { data: d } })
5531
+ ).map((validated) => {
5532
+ const circles = validated.circles.filter(
5533
+ (item) => Number(item.metrics.scoreState.activeMerchantsCount) > 0
5534
+ );
5535
+ logger.info("fetched circles from subgraph", {
5536
+ total: validated.circles.length,
5537
+ withActiveMerchants: circles.length,
5538
+ circles
5539
+ });
5540
+ return circles;
5541
+ })
5542
+ );
4380
5543
  }
4381
- async function encryptWithPublicKey(publicKey, message) {
4382
- const pubKeyBytes = hexToBytes3(`04${publicKey}`);
4383
- const ephemPrivKey = randomBytes(32);
4384
- const ephemPubKey = secp256k1.getPublicKey(ephemPrivKey, false);
4385
- const sharedPoint = secp256k1.getSharedSecret(ephemPrivKey, pubKeyBytes, true);
4386
- const sharedSecret = sharedPoint.slice(1);
4387
- const { encKey, macKey } = deriveKeys(sharedSecret);
4388
- const iv = randomBytes(16);
4389
- const plaintext = new TextEncoder().encode(message);
4390
- const cipher = cbc(encKey, iv);
4391
- const ciphertext = cipher.encrypt(plaintext);
4392
- const macData = concatBytes2(iv, ephemPubKey, ciphertext);
4393
- const mac = hmac(sha2562, macKey, macData);
5544
+
5545
+ // src/orders/internal/routing/client.ts
5546
+ function createOrderRouter(config) {
5547
+ const { subgraphUrl, publicClient, contractAddress } = config;
5548
+ const logger = config.logger ?? noopLogger;
4394
5549
  return {
4395
- iv: bytesToHex2(iv),
4396
- ephemPublicKey: bytesToHex2(ephemPubKey),
4397
- ciphertext: bytesToHex2(ciphertext),
4398
- mac: bytesToHex2(mac)
5550
+ selectCircle(params) {
5551
+ const currencyHex = (0, import_viem16.stringToHex)(params.currency, { size: 32 });
5552
+ logger.info("selectCircle started", {
5553
+ currency: params.currency,
5554
+ user: params.user,
5555
+ orderType: String(params.orderType)
5556
+ });
5557
+ return getCirclesForRouting(subgraphUrl, currencyHex, logger).andThen(
5558
+ (circles) => selectCircleForOrderAsync(
5559
+ circles,
5560
+ currencyHex,
5561
+ (circleId) => checkCircleEligibility(
5562
+ publicClient,
5563
+ contractAddress,
5564
+ {
5565
+ circleId,
5566
+ currency: currencyHex,
5567
+ user: params.user,
5568
+ usdtAmount: params.usdtAmount,
5569
+ fiatAmount: params.fiatAmount,
5570
+ orderType: params.orderType,
5571
+ preferredPCConfigId: params.preferredPCConfigId
5572
+ },
5573
+ logger
5574
+ ),
5575
+ logger
5576
+ )
5577
+ );
5578
+ }
4399
5579
  };
4400
5580
  }
4401
- function cipherStringify(encrypted) {
4402
- const ephemPubKeyBytes = hexToBytes3(encrypted.ephemPublicKey);
4403
- const compressed = secp256k1.ProjectivePoint.fromHex(ephemPubKeyBytes).toRawBytes(true);
4404
- const iv = hexToBytes3(encrypted.iv);
4405
- const mac = hexToBytes3(encrypted.mac);
4406
- const ciphertext = hexToBytes3(encrypted.ciphertext);
4407
- return bytesToHex2(concatBytes2(iv, compressed, mac, ciphertext));
4408
- }
4409
5581
 
4410
- // src/payload/errors.ts
4411
- var PayloadError = class extends SdkError {
4412
- constructor(message, options) {
4413
- super(message, options);
4414
- this.name = "PayloadError";
4415
- }
5582
+ // src/orders/normalize.ts
5583
+ var import_neverthrow15 = require("neverthrow");
5584
+ var import_viem17 = require("viem");
5585
+ var ORDER_TYPE_MAP = {
5586
+ [ORDER_TYPE.BUY]: "buy",
5587
+ [ORDER_TYPE.SELL]: "sell",
5588
+ [ORDER_TYPE.PAY]: "pay"
4416
5589
  };
4417
-
4418
- // src/payload/relay-identity.ts
4419
- var import_neverthrow11 = require("neverthrow");
4420
- var import_viem7 = require("viem");
4421
- var import_accounts = require("viem/accounts");
4422
- var import_zod6 = require("zod");
4423
- var ZodRelayIdentitySchema = import_zod6.z.object({
4424
- address: import_zod6.z.string().refine(import_viem7.isAddress, { message: "Invalid relay identity address" }),
4425
- publicKey: import_zod6.z.string().refine((val) => (0, import_viem7.isHex)(`0x${val}`), {
4426
- message: "Invalid relay identity public key"
4427
- }),
4428
- privateKey: import_zod6.z.string().refine(import_viem7.isHex, { message: "Invalid relay identity private key" })
4429
- });
4430
- var STORAGE_KEY = "@P2PME:RELAY_IDENTITY";
4431
- function createRelayIdentity() {
4432
- const privateKey = (0, import_accounts.generatePrivateKey)();
4433
- const account = (0, import_accounts.privateKeyToAccount)(privateKey);
4434
- const rawPubKey = account.publicKey;
4435
- const publicKey = rawPubKey.slice(4);
4436
- const identity = {
4437
- address: account.address,
4438
- publicKey,
4439
- privateKey
4440
- };
4441
- localStorage.setItem(STORAGE_KEY, JSON.stringify(identity));
4442
- return identity;
5590
+ var ORDER_STATUS_MAP = {
5591
+ [ORDER_STATUS.PLACED]: "placed",
5592
+ [ORDER_STATUS.ACCEPTED]: "accepted",
5593
+ [ORDER_STATUS.PAID]: "paid",
5594
+ [ORDER_STATUS.COMPLETED]: "completed",
5595
+ [ORDER_STATUS.CANCELLED]: "cancelled"
5596
+ };
5597
+ var DISPUTE_STATUS_MAP = {
5598
+ [DISPUTE_STATUS.NONE]: "none",
5599
+ [DISPUTE_STATUS.OPEN]: "open",
5600
+ [DISPUTE_STATUS.RESOLVED]: "resolved"
5601
+ };
5602
+ function malformed(field, value, context) {
5603
+ return new OrdersError(`Unknown ${field}: ${String(value)}`, {
5604
+ code: "MALFORMED_ORDER",
5605
+ context: { field, value, ...context }
5606
+ });
4443
5607
  }
4444
- function getRelayIdentity() {
4445
- const data = localStorage.getItem(STORAGE_KEY);
4446
- if (!data) {
4447
- return (0, import_neverthrow11.ok)(createRelayIdentity());
4448
- }
4449
- let parsed;
4450
- try {
4451
- parsed = JSON.parse(data);
4452
- } catch {
4453
- return (0, import_neverthrow11.ok)(createRelayIdentity());
4454
- }
4455
- const result = validate(
4456
- ZodRelayIdentitySchema,
4457
- parsed,
4458
- (message, cause, d) => new PayloadError(message, { code: "VALIDATION_ERROR", cause, context: { data: d } })
4459
- );
4460
- if (result.isErr()) {
4461
- return (0, import_neverthrow11.ok)(createRelayIdentity());
4462
- }
4463
- return result;
5608
+ function mapOrderType(v, ctx) {
5609
+ const t = ORDER_TYPE_MAP[v];
5610
+ return t ? (0, import_neverthrow15.ok)(t) : (0, import_neverthrow15.err)(malformed("orderType", v, ctx));
5611
+ }
5612
+ function mapOrderStatus(v, ctx) {
5613
+ const s = ORDER_STATUS_MAP[v];
5614
+ return s ? (0, import_neverthrow15.ok)(s) : (0, import_neverthrow15.err)(malformed("status", v, ctx));
5615
+ }
5616
+ function mapDisputeStatus(v, ctx) {
5617
+ const s = DISPUTE_STATUS_MAP[v];
5618
+ return s ? (0, import_neverthrow15.ok)(s) : (0, import_neverthrow15.err)(malformed("disputeStatus", v, ctx));
5619
+ }
5620
+ function decodeCurrency(hex) {
5621
+ return (0, import_viem17.hexToString)(hex, { size: 32 }).replaceAll("\0", "");
5622
+ }
5623
+ function normalizeContractOrder(raw, details) {
5624
+ if (raw.id === 0n && (0, import_viem17.isAddressEqual)(raw.user, import_viem17.zeroAddress)) return (0, import_neverthrow15.ok)(null);
5625
+ const ctx = { orderId: raw.id.toString() };
5626
+ return import_neverthrow15.Result.combine([
5627
+ mapOrderType(raw.orderType, ctx),
5628
+ mapOrderStatus(raw.status, ctx),
5629
+ mapDisputeStatus(raw.disputeInfo.status, ctx)
5630
+ ]).map(([type, status, disputeStatus]) => ({
5631
+ orderId: raw.id,
5632
+ type,
5633
+ status,
5634
+ usdcAmount: raw.amount,
5635
+ fiatAmount: raw.fiatAmount,
5636
+ actualUsdcAmount: details.actualUsdtAmount,
5637
+ actualFiatAmount: details.actualFiatAmount,
5638
+ currency: decodeCurrency(raw.currency),
5639
+ user: raw.user,
5640
+ recipient: raw.recipientAddr,
5641
+ acceptedMerchant: raw.acceptedMerchant,
5642
+ placedAt: raw.placedTimestamp,
5643
+ acceptedAt: details.acceptedTimestamp,
5644
+ paidAt: details.paidTimestamp,
5645
+ completedAt: raw.completedTimestamp,
5646
+ circleId: raw.circleId,
5647
+ fixedFeePaid: details.fixedFeePaid,
5648
+ tipsPaid: details.tipsPaid,
5649
+ disputeStatus,
5650
+ encUpi: raw.encUpi,
5651
+ encMerchantUpi: raw.encMerchantUpi,
5652
+ pubkey: raw.pubkey
5653
+ }));
4464
5654
  }
4465
-
4466
- // src/payload/crypto.ts
4467
- function encryptPaymentAddress(paymentAddress, encryptionPublicKey) {
4468
- return (0, import_neverthrow12.safeTry)(async function* () {
4469
- const relayIdentity = yield* getRelayIdentity().mapErr(
4470
- (e) => new PayloadError(`Relay identity error: ${e.message}`, {
4471
- code: "ENCRYPTION_ERROR",
4472
- cause: e
4473
- })
4474
- );
4475
- const messageHash = (0, import_viem8.keccak256)((0, import_viem8.stringToHex)(paymentAddress));
4476
- const signResult = yield* import_neverthrow12.ResultAsync.fromPromise(
4477
- (0, import_accounts2.sign)({ hash: messageHash, privateKey: relayIdentity.privateKey }),
4478
- (error) => new PayloadError(
4479
- `Signing error: ${error instanceof Error ? error.message : "Unknown error"}`,
4480
- { code: "ENCRYPTION_ERROR", cause: error }
4481
- )
4482
- );
4483
- const signature = (0, import_viem8.serializeSignature)(signResult);
4484
- const payload = { message: paymentAddress, signature };
4485
- const encrypted = yield* import_neverthrow12.ResultAsync.fromPromise(
4486
- encryptWithPublicKey(encryptionPublicKey, JSON.stringify(payload)),
4487
- (error) => new PayloadError(
4488
- `Encryption error: ${error instanceof Error ? error.message : "Unknown error"}`,
4489
- { code: "ENCRYPTION_ERROR", cause: error }
4490
- )
4491
- );
4492
- const safeCipherStringify = import_neverthrow12.Result.fromThrowable(
4493
- (encryptedData) => cipherStringify(encryptedData),
4494
- (error) => new PayloadError(
4495
- `Stringify error: ${error instanceof Error ? error.message : "Unknown error"}`,
4496
- { code: "ENCRYPTION_ERROR", cause: error }
4497
- )
4498
- );
4499
- const stringified = yield* safeCipherStringify(encrypted);
4500
- return (0, import_neverthrow12.ok)(stringified);
4501
- });
5655
+ function normalizeSubgraphOrder(raw) {
5656
+ const ctx = { orderId: raw.orderId };
5657
+ return import_neverthrow15.Result.combine([
5658
+ mapOrderType(raw.type, ctx),
5659
+ mapOrderStatus(raw.status, ctx),
5660
+ mapDisputeStatus(raw.disputeStatus, ctx)
5661
+ ]).map(([type, status, disputeStatus]) => ({
5662
+ orderId: BigInt(raw.orderId),
5663
+ type,
5664
+ status,
5665
+ usdcAmount: BigInt(raw.usdcAmount),
5666
+ fiatAmount: BigInt(raw.fiatAmount),
5667
+ actualUsdcAmount: BigInt(raw.actualUsdcAmount),
5668
+ actualFiatAmount: BigInt(raw.actualFiatAmount),
5669
+ currency: decodeCurrency(raw.currency),
5670
+ user: raw.userAddress,
5671
+ recipient: raw.usdcRecipientAddress,
5672
+ acceptedMerchant: raw.acceptedMerchantAddress,
5673
+ placedAt: BigInt(raw.placedAt),
5674
+ acceptedAt: BigInt(raw.acceptedAt),
5675
+ paidAt: BigInt(raw.paidAt),
5676
+ completedAt: BigInt(raw.completedAt),
5677
+ circleId: BigInt(raw.circleId),
5678
+ fixedFeePaid: BigInt(raw.fixedFeePaid),
5679
+ tipsPaid: BigInt(raw.tipsPaid),
5680
+ disputeStatus,
5681
+ // Subgraph entity does not currently expose these encryption fields;
5682
+ // consumers needing them should fall back to the contract via getOrder.
5683
+ encUpi: "",
5684
+ encMerchantUpi: "",
5685
+ pubkey: ""
5686
+ }));
4502
5687
  }
4503
- var ZodEncryptedDataSchema = import_zod7.z.object({
4504
- ciphertext: import_zod7.z.string(),
4505
- iv: import_zod7.z.string(),
4506
- mac: import_zod7.z.string(),
4507
- ephemPublicKey: import_zod7.z.string()
4508
- });
4509
5688
 
4510
- // src/payload/validation.ts
4511
- var import_zod8 = require("zod");
4512
- var ZodPlaceOrderParamsSchema = import_zod8.z.object({
4513
- amount: import_zod8.z.bigint(),
4514
- recipientAddr: ZodAddressSchema,
4515
- orderType: import_zod8.z.number().int().min(0).max(2),
4516
- currency: ZodCurrencySchema,
4517
- fiatAmount: import_zod8.z.bigint(),
4518
- user: ZodAddressSchema,
4519
- pubKey: import_zod8.z.string().optional(),
4520
- preferredPaymentChannelConfigId: import_zod8.z.bigint().optional(),
4521
- fiatAmountLimit: import_zod8.z.bigint().optional().default(0n)
4522
- });
4523
- var ZodSetSellOrderUpiParamsSchema = import_zod8.z.object({
4524
- orderId: import_zod8.z.number().int().nonnegative(),
4525
- paymentAddress: import_zod8.z.string().min(1),
4526
- merchantPublicKey: import_zod8.z.string().min(1),
4527
- updatedAmount: import_zod8.z.bigint()
4528
- });
5689
+ // src/orders/subgraph/index.ts
5690
+ var import_neverthrow16 = require("neverthrow");
4529
5691
 
4530
- // src/payload/actions.ts
4531
- function buildPlaceOrderPayload(orderRouter, params) {
4532
- const validation = validate(
4533
- ZodPlaceOrderParamsSchema,
4534
- params,
4535
- (message, cause, data) => new PayloadError(message, { code: "VALIDATION_ERROR", cause, context: { data } })
4536
- );
4537
- if (validation.isErr()) {
4538
- return (0, import_neverthrow13.errAsync)(validation.error);
4539
- }
4540
- const v = validation.value;
4541
- const isBuy = v.orderType === ORDER_TYPE.BUY;
4542
- const pcConfigId = v.preferredPaymentChannelConfigId ?? 0n;
4543
- const circleResult = orderRouter.selectCircle({
4544
- currency: v.currency,
4545
- user: v.user,
4546
- usdtAmount: v.amount,
4547
- fiatAmount: v.fiatAmount,
4548
- orderType: BigInt(v.orderType),
4549
- preferredPCConfigId: pcConfigId
4550
- });
4551
- const relayResult = getRelayIdentity();
4552
- if (relayResult.isErr()) {
4553
- return (0, import_neverthrow13.errAsync)(relayResult.error);
4554
- }
4555
- const common = {
4556
- amount: v.amount,
4557
- recipientAddr: v.recipientAddr,
4558
- orderType: v.orderType,
4559
- userUpi: "",
4560
- currency: v.currency,
4561
- preferredPaymentChannelConfigId: pcConfigId,
4562
- fiatAmountLimit: v.fiatAmountLimit
4563
- };
4564
- const pubKeyValue = v.pubKey ?? relayResult.value.publicKey;
4565
- return circleResult.map((circleId) => ({
4566
- ...common,
4567
- pubKey: isBuy ? pubKeyValue : "",
4568
- userPubKey: isBuy ? "" : pubKeyValue,
4569
- circleId
4570
- })).mapErr(
4571
- (e) => new PayloadError(e.message, {
4572
- code: "CIRCLE_SELECTION_ERROR",
4573
- cause: e
5692
+ // src/orders/subgraph/queries.ts
5693
+ var ORDERS_BY_USER_QUERY = (
5694
+ /* GraphQL */
5695
+ `
5696
+ query OrdersByUser($user: Bytes!, $skip: Int!, $first: Int!) {
5697
+ orders_collection(
5698
+ where: { userAddress: $user }
5699
+ orderBy: placedAt
5700
+ orderDirection: desc
5701
+ skip: $skip
5702
+ first: $first
5703
+ ) {
5704
+ orderId
5705
+ type
5706
+ status
5707
+ circleId
5708
+ userAddress
5709
+ usdcRecipientAddress
5710
+ acceptedMerchantAddress
5711
+ usdcAmount
5712
+ fiatAmount
5713
+ actualUsdcAmount
5714
+ actualFiatAmount
5715
+ currency
5716
+ placedAt
5717
+ acceptedAt
5718
+ paidAt
5719
+ completedAt
5720
+ fixedFeePaid
5721
+ tipsPaid
5722
+ disputeStatus
5723
+ }
5724
+ }
5725
+ `
5726
+ );
5727
+
5728
+ // src/orders/subgraph/index.ts
5729
+ function getOrdersForUser(subgraphUrl, userAddress, skip, limit, logger = noopLogger) {
5730
+ const user = userAddress.toLowerCase();
5731
+ logger.debug("fetching orders from subgraph", { subgraphUrl, user, skip, limit });
5732
+ return querySubgraph(subgraphUrl, {
5733
+ query: ORDERS_BY_USER_QUERY,
5734
+ variables: { user, skip, first: limit }
5735
+ }).mapErr(
5736
+ (e) => new OrdersError(e.message, {
5737
+ code: "SUBGRAPH_REQUEST_FAILED",
5738
+ cause: e.cause ?? e,
5739
+ context: { user, skip, limit, ...e.context ?? {} }
4574
5740
  })
5741
+ ).andThen(
5742
+ (data) => validate(
5743
+ ZodSubgraphOrdersResponseSchema,
5744
+ data,
5745
+ (message, cause, d) => new OrdersError(message, {
5746
+ code: "SUBGRAPH_VALIDATION_FAILED",
5747
+ cause,
5748
+ context: { data: d }
5749
+ })
5750
+ ).andThen(
5751
+ (validated) => import_neverthrow16.Result.combine(validated.orders_collection.map(normalizeSubgraphOrder))
5752
+ )
4575
5753
  );
4576
5754
  }
4577
- function buildSetSellOrderUpiPayload(params) {
4578
- const validation = validate(
4579
- ZodSetSellOrderUpiParamsSchema,
4580
- params,
4581
- (message, cause, data) => new PayloadError(message, { code: "VALIDATION_ERROR", cause, context: { data } })
4582
- );
4583
- if (validation.isErr()) {
4584
- return (0, import_neverthrow13.errAsync)(validation.error);
4585
- }
4586
- const v = validation.value;
4587
- return encryptPaymentAddress(v.paymentAddress, v.merchantPublicKey).map((userEncUpi) => ({
4588
- orderId: v.orderId,
4589
- userEncUpi,
4590
- updatedAmount: v.updatedAmount
4591
- }));
5755
+
5756
+ // src/orders/watch-events.ts
5757
+ var PLACED_CONFIG = {
5758
+ eventName: "OrderPlaced",
5759
+ toEvent: (log) => ({
5760
+ type: "placed",
5761
+ orderId: log.args.orderId,
5762
+ user: log.args.user,
5763
+ orderType: log.args.orderType,
5764
+ blockNumber: log.blockNumber,
5765
+ txHash: log.transactionHash
5766
+ }),
5767
+ userFromLog: (log) => log.args.user
5768
+ };
5769
+ var ACCEPTED_CONFIG = {
5770
+ eventName: "OrderAccepted",
5771
+ toEvent: (log) => ({
5772
+ type: "accepted",
5773
+ orderId: log.args.orderId,
5774
+ merchant: log.args.merchant,
5775
+ blockNumber: log.blockNumber,
5776
+ txHash: log.transactionHash
5777
+ }),
5778
+ // OrderAccepted's top-level args are (orderId, merchant, pubKey, _order).
5779
+ // The buyer's address lives inside the _order tuple as _order.user.
5780
+ userFromLog: (log) => log.args._order?.user
5781
+ };
5782
+ var PAID_CONFIG = {
5783
+ eventName: "BuyOrderPaid",
5784
+ toEvent: (log) => ({
5785
+ type: "paid",
5786
+ orderId: log.args.orderId,
5787
+ blockNumber: log.blockNumber,
5788
+ txHash: log.transactionHash
5789
+ }),
5790
+ userFromLog: (log) => log.args.user
5791
+ };
5792
+ var COMPLETED_CONFIG = {
5793
+ eventName: "OrderCompleted",
5794
+ toEvent: (log) => ({
5795
+ type: "completed",
5796
+ orderId: log.args.orderId,
5797
+ blockNumber: log.blockNumber,
5798
+ txHash: log.transactionHash
5799
+ }),
5800
+ userFromLog: (log) => log.args.user
5801
+ };
5802
+ var CANCELLED_CONFIG = {
5803
+ eventName: "CancelledOrders",
5804
+ toEvent: (log) => ({
5805
+ type: "cancelled",
5806
+ orderId: log.args.orderId,
5807
+ blockNumber: log.blockNumber,
5808
+ txHash: log.transactionHash
5809
+ }),
5810
+ // CancelledOrders's top-level args are (orderId, _order). The buyer's
5811
+ // address lives inside the _order tuple as _order.user.
5812
+ userFromLog: (log) => log.args._order?.user
5813
+ };
5814
+ var ALL_CONFIGS = [
5815
+ PLACED_CONFIG,
5816
+ ACCEPTED_CONFIG,
5817
+ PAID_CONFIG,
5818
+ COMPLETED_CONFIG,
5819
+ CANCELLED_CONFIG
5820
+ ];
5821
+ function createWatchEvents(input) {
5822
+ const { publicClient, diamondAddress } = input;
5823
+ return ({ user, onEvent, onError }) => {
5824
+ const unwatchers = [];
5825
+ for (const config of ALL_CONFIGS) {
5826
+ try {
5827
+ const unwatch = publicClient.watchContractEvent({
5828
+ address: diamondAddress,
5829
+ abi: ABIS.DIAMOND,
5830
+ eventName: config.eventName,
5831
+ onLogs: (logs) => {
5832
+ for (const log of logs) {
5833
+ if (user && config.userFromLog) {
5834
+ const logUser = config.userFromLog(log);
5835
+ if (!logUser || logUser.toLowerCase() !== user.toLowerCase()) continue;
5836
+ }
5837
+ onEvent(config.toEvent(log));
5838
+ }
5839
+ },
5840
+ onError: (err5) => {
5841
+ onError?.(
5842
+ new OrdersError(`watchContractEvent failed for ${config.eventName}`, {
5843
+ code: "EVENT_WATCH_FAILED",
5844
+ cause: err5,
5845
+ context: { eventName: config.eventName }
5846
+ })
5847
+ );
5848
+ }
5849
+ });
5850
+ unwatchers.push(unwatch);
5851
+ } catch (err5) {
5852
+ onError?.(
5853
+ new OrdersError(`failed to subscribe to ${config.eventName}`, {
5854
+ code: "EVENT_WATCH_FAILED",
5855
+ cause: err5,
5856
+ context: { eventName: config.eventName }
5857
+ })
5858
+ );
5859
+ }
5860
+ }
5861
+ return () => {
5862
+ for (const u of unwatchers) {
5863
+ try {
5864
+ u();
5865
+ } catch {
5866
+ }
5867
+ }
5868
+ };
5869
+ };
4592
5870
  }
4593
5871
 
4594
- // src/payload/client.ts
4595
- function createPayloadGenerator(config) {
5872
+ // src/orders/client.ts
5873
+ function createOrders(config) {
5874
+ const { publicClient, diamondAddress, usdcAddress, subgraphUrl, relayIdentity } = config;
5875
+ const logger = config.logger ?? noopLogger;
5876
+ const relayIdentityStore = config.relayIdentityStore ?? createInMemoryRelayStore();
5877
+ const orderRouter = createOrderRouter({
5878
+ publicClient,
5879
+ subgraphUrl,
5880
+ contractAddress: diamondAddress,
5881
+ logger
5882
+ });
4596
5883
  return {
4597
- placeOrder(params) {
4598
- return buildPlaceOrderPayload(config.orderRouter, params);
5884
+ // ── Reads ─────────────────────────────────────────────────────────
5885
+ getOrder(params) {
5886
+ return validate(
5887
+ ZodGetOrderParamsSchema,
5888
+ params,
5889
+ (message, cause, d) => new OrdersError(message, {
5890
+ code: "INVALID_ORDER_ID",
5891
+ cause,
5892
+ context: { params: d }
5893
+ })
5894
+ ).asyncAndThen(
5895
+ ({ orderId }) => readOrderMulticall(publicClient, diamondAddress, orderId).mapErr(
5896
+ (cause) => new OrdersError("Order contract read failed", {
5897
+ code: "CONTRACT_READ_FAILED",
5898
+ cause,
5899
+ context: { orderId: orderId.toString() }
5900
+ })
5901
+ )
5902
+ ).andThen(
5903
+ ({ order, details }) => normalizeContractOrder(order, details).asyncAndThen((normalized) => {
5904
+ if (!normalized) {
5905
+ return (0, import_neverthrow17.errAsync)(
5906
+ new OrdersError("Order not found", {
5907
+ code: "ORDER_NOT_FOUND",
5908
+ context: { orderId: params.orderId.toString() }
5909
+ })
5910
+ );
5911
+ }
5912
+ logger.debug("getOrder resolved", { orderId: params.orderId.toString() });
5913
+ return (0, import_neverthrow17.okAsync)(normalized);
5914
+ })
5915
+ );
5916
+ },
5917
+ getOrders(params) {
5918
+ return validate(
5919
+ ZodGetOrdersParamsSchema,
5920
+ params,
5921
+ (message, cause, d) => new OrdersError(message, {
5922
+ code: "INVALID_GET_ORDERS_PARAMS",
5923
+ cause,
5924
+ context: { params: d }
5925
+ })
5926
+ ).asyncAndThen(
5927
+ ({ userAddress, skip, limit }) => getOrdersForUser(subgraphUrl, userAddress, skip, limit, logger)
5928
+ );
5929
+ },
5930
+ getFeeConfig(params) {
5931
+ return validate(
5932
+ ZodGetFeeConfigParamsSchema,
5933
+ params,
5934
+ (message, cause, d) => new OrdersError(message, {
5935
+ code: "INVALID_FEE_CONFIG_PARAMS",
5936
+ cause,
5937
+ context: { params: d }
5938
+ })
5939
+ ).asyncAndThen(
5940
+ ({ currency }) => readFeeConfigMulticall(publicClient, diamondAddress, currency).mapErr(
5941
+ (cause) => new OrdersError("Fee config contract read failed", {
5942
+ code: "CONTRACT_READ_FAILED",
5943
+ cause,
5944
+ context: { currency }
5945
+ })
5946
+ )
5947
+ ).map((config2) => {
5948
+ logger.debug("getFeeConfig resolved", { currency: params.currency });
5949
+ return config2;
5950
+ });
5951
+ },
5952
+ // ── Writes ────────────────────────────────────────────────────────
5953
+ placeOrder: createPlaceOrderAction({
5954
+ publicClient,
5955
+ diamondAddress,
5956
+ orderRouter,
5957
+ relayIdentityStore,
5958
+ relayIdentity
5959
+ }),
5960
+ cancelOrder: createCancelOrderAction({ publicClient, diamondAddress }),
5961
+ setSellOrderUpi: createSetSellOrderUpiAction({
5962
+ publicClient,
5963
+ diamondAddress,
5964
+ relayIdentityStore,
5965
+ relayIdentity
5966
+ }),
5967
+ raiseDispute: createRaiseDisputeAction({ publicClient, diamondAddress }),
5968
+ approveUsdc: createApproveUsdcAction({ publicClient, diamondAddress, usdcAddress }),
5969
+ paidBuyOrder: createPaidBuyOrderAction({ publicClient, diamondAddress }),
5970
+ watchEvents: createWatchEvents({ publicClient, diamondAddress }),
5971
+ // ── Crypto helpers ───────────────────────────────────────────────
5972
+ decryptPaymentAddress({ encrypted }) {
5973
+ return resolveRelayIdentity({ relayIdentity, store: relayIdentityStore }).andThen(
5974
+ (recipientIdentity) => decryptPaymentAddress({ encrypted, recipientIdentity })
5975
+ );
4599
5976
  },
4600
- setSellOrderUpi(params) {
4601
- return buildSetSellOrderUpiPayload(params);
5977
+ encryptPaymentAddress({ paymentAddress, recipientPublicKey }) {
5978
+ return resolveRelayIdentity({ relayIdentity, store: relayIdentityStore }).andThen(
5979
+ (senderIdentity) => encryptPaymentAddress({
5980
+ paymentAddress,
5981
+ recipientPublicKey,
5982
+ senderIdentity
5983
+ })
5984
+ );
4602
5985
  }
4603
5986
  };
4604
5987
  }
4605
5988
 
5989
+ // src/prices/client.ts
5990
+ function createPrices(config) {
5991
+ const { publicClient, diamondAddress } = config;
5992
+ return {
5993
+ getPriceConfig: (params) => getPriceConfig(publicClient, diamondAddress, params),
5994
+ getReputationPerUsdcLimit: (params) => getReputationPerUsdcLimit(publicClient, diamondAddress, params)
5995
+ };
5996
+ }
5997
+
4606
5998
  // src/profile/contracts/actions.ts
4607
- var import_neverthrow14 = require("neverthrow");
4608
- var import_viem9 = require("viem");
5999
+ var import_neverthrow18 = require("neverthrow");
6000
+ var import_viem18 = require("viem");
4609
6001
  function getBalances(publicClient, usdcAddress, diamondAddress, params) {
4610
6002
  return validate(
4611
6003
  ZodGetBalancesParamsSchema,
@@ -4616,16 +6008,22 @@ function getBalances(publicClient, usdcAddress, diamondAddress, params) {
4616
6008
  context: { params: data }
4617
6009
  })
4618
6010
  ).asyncAndThen(
4619
- (validated) => import_neverthrow14.ResultAsync.combine([
6011
+ (validated) => import_neverthrow18.ResultAsync.combine([
4620
6012
  getUsdcBalance(publicClient, usdcAddress, {
4621
6013
  address: validated.address
4622
6014
  }),
4623
6015
  getPriceConfig(publicClient, diamondAddress, {
4624
6016
  currency: validated.currency
4625
- })
6017
+ }).mapErr(
6018
+ (cause) => new ProfileError("Failed to read price config for balance conversion", {
6019
+ code: "CONTRACT_READ_ERROR",
6020
+ cause,
6021
+ context: { currency: validated.currency }
6022
+ })
6023
+ )
4626
6024
  ]).map(([usdc, priceConfig]) => {
4627
- const usdcFormatted = Number((0, import_viem9.formatUnits)(usdc, 6));
4628
- const sellPriceFormatted = Number((0, import_viem9.formatUnits)(priceConfig.sellPrice, 6));
6025
+ const usdcFormatted = Number((0, import_viem18.formatUnits)(usdc, 6));
6026
+ const sellPriceFormatted = Number((0, import_viem18.formatUnits)(priceConfig.sellPrice, 6));
4629
6027
  return {
4630
6028
  usdc: usdcFormatted,
4631
6029
  fiat: usdcFormatted * sellPriceFormatted,
@@ -4640,10 +6038,9 @@ function createProfile(config) {
4640
6038
  const { publicClient, diamondAddress, usdcAddress } = config;
4641
6039
  return {
4642
6040
  getUsdcBalance: (params) => getUsdcBalance(publicClient, usdcAddress, params),
4643
- getPriceConfig: (params) => getPriceConfig(publicClient, diamondAddress, params),
6041
+ getUsdcAllowance: (params) => getUsdcAllowance(publicClient, usdcAddress, diamondAddress, params),
4644
6042
  getBalances: (params) => getBalances(publicClient, usdcAddress, diamondAddress, params),
4645
- getTxLimits: (params) => getTxLimits(publicClient, diamondAddress, params),
4646
- getRpPerUsdtLimitRational: (params) => getRpPerUsdtLimitRational(publicClient, diamondAddress, params)
6043
+ getTxLimits: (params) => getTxLimits(publicClient, diamondAddress, params)
4647
6044
  };
4648
6045
  }
4649
6046
 
@@ -4684,21 +6081,28 @@ function SdkProvider({ children, ...config }) {
4684
6081
  initedRef.current = fraudEngine;
4685
6082
  fraudEngine.init();
4686
6083
  }, [fraudEngine]);
6084
+ const relayIdentityStore = config.orders?.relayIdentityStore;
6085
+ const relayIdentity = config.orders?.relayIdentity;
4687
6086
  const sdk = (0, import_react.useMemo)(() => {
4688
- const orderRouter = createOrderRouter({
4689
- publicClient,
4690
- subgraphUrl: config.subgraphUrl,
4691
- contractAddress: config.diamondAddress,
4692
- logger
4693
- });
4694
6087
  return {
4695
6088
  profile: createProfile({
4696
6089
  publicClient,
4697
6090
  diamondAddress: config.diamondAddress,
4698
6091
  usdcAddress: config.usdcAddress
4699
6092
  }),
4700
- orderRouter,
4701
- payload: createPayloadGenerator({ orderRouter }),
6093
+ prices: createPrices({
6094
+ publicClient,
6095
+ diamondAddress: config.diamondAddress
6096
+ }),
6097
+ orders: createOrders({
6098
+ publicClient,
6099
+ diamondAddress: config.diamondAddress,
6100
+ usdcAddress: config.usdcAddress,
6101
+ subgraphUrl: config.subgraphUrl,
6102
+ relayIdentityStore,
6103
+ relayIdentity,
6104
+ logger
6105
+ }),
4702
6106
  zkkyc: config.reputationManagerAddress ? createZkkyc({
4703
6107
  reputationManagerAddress: config.reputationManagerAddress
4704
6108
  }) : void 0,
@@ -4710,6 +6114,8 @@ function SdkProvider({ children, ...config }) {
4710
6114
  config.diamondAddress,
4711
6115
  config.usdcAddress,
4712
6116
  config.reputationManagerAddress,
6117
+ relayIdentityStore,
6118
+ relayIdentity,
4713
6119
  logger,
4714
6120
  fraudEngine
4715
6121
  ]);
@@ -4725,11 +6131,11 @@ function useSdk() {
4725
6131
  function useProfile() {
4726
6132
  return useSdk().profile;
4727
6133
  }
4728
- function useOrderRouter() {
4729
- return useSdk().orderRouter;
6134
+ function usePrices() {
6135
+ return useSdk().prices;
4730
6136
  }
4731
- function usePayloadGenerator() {
4732
- return useSdk().payload;
6137
+ function useOrders() {
6138
+ return useSdk().orders;
4733
6139
  }
4734
6140
  function useZkkyc() {
4735
6141
  const zkkyc = useSdk().zkkyc;
@@ -4746,13 +6152,32 @@ function useFraudEngine() {
4746
6152
  return fraudEngine;
4747
6153
  }
4748
6154
 
4749
- // src/fraud-engine/react/use-fingerprint.ts
6155
+ // src/react/use-watch-orders.ts
4750
6156
  var import_react2 = require("react");
4751
- function useFingerprint(enabled) {
4752
- const [data, setData] = (0, import_react2.useState)(null);
4753
- const [error, setError] = (0, import_react2.useState)(null);
4754
- const [isLoading, setIsLoading] = (0, import_react2.useState)(false);
6157
+ function useWatchOrders(params) {
6158
+ const orders = useOrders();
6159
+ const { user, onEvent, onError } = params;
6160
+ const onEventRef = (0, import_react2.useRef)(onEvent);
6161
+ const onErrorRef = (0, import_react2.useRef)(onError);
6162
+ onEventRef.current = onEvent;
6163
+ onErrorRef.current = onError;
4755
6164
  (0, import_react2.useEffect)(() => {
6165
+ const unsubscribe = orders.watchEvents({
6166
+ user,
6167
+ onEvent: (event) => onEventRef.current(event),
6168
+ onError: (error) => onErrorRef.current?.(error)
6169
+ });
6170
+ return unsubscribe;
6171
+ }, [orders, user]);
6172
+ }
6173
+
6174
+ // src/fraud-engine/react/use-fingerprint.ts
6175
+ var import_react3 = require("react");
6176
+ function useFingerprint(enabled) {
6177
+ const [data, setData] = (0, import_react3.useState)(null);
6178
+ const [error, setError] = (0, import_react3.useState)(null);
6179
+ const [isLoading, setIsLoading] = (0, import_react3.useState)(false);
6180
+ (0, import_react3.useEffect)(() => {
4756
6181
  if (!enabled) return;
4757
6182
  let cancelled = false;
4758
6183
  setIsLoading(true);
@@ -4784,10 +6209,11 @@ function useFingerprint(enabled) {
4784
6209
  SdkProvider,
4785
6210
  useFingerprint,
4786
6211
  useFraudEngine,
4787
- useOrderRouter,
4788
- usePayloadGenerator,
6212
+ useOrders,
6213
+ usePrices,
4789
6214
  useProfile,
4790
6215
  useSdk,
6216
+ useWatchOrders,
4791
6217
  useZkkyc
4792
6218
  });
4793
6219
  /*! Bundled license information: