@zkp2p/sdk 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,3080 @@
1
+ 'use strict';
2
+
3
+ var baseAddressesRaw = require('@zkp2p/contracts-v2/addresses/base');
4
+ var baseSepoliaAddressesRaw = require('@zkp2p/contracts-v2/addresses/baseSepolia');
5
+ var baseStagingAddressesRaw = require('@zkp2p/contracts-v2/addresses/baseStaging');
6
+ var EscrowBase = require('@zkp2p/contracts-v2/abis/base/Escrow.json');
7
+ var OrchestratorBase = require('@zkp2p/contracts-v2/abis/base/Orchestrator.json');
8
+ var ProtocolViewerBase = require('@zkp2p/contracts-v2/abis/base/ProtocolViewer.json');
9
+ var UnifiedPaymentVerifierBase = require('@zkp2p/contracts-v2/abis/base/UnifiedPaymentVerifier.json');
10
+ var EscrowBaseSepolia = require('@zkp2p/contracts-v2/abis/baseSepolia/Escrow.json');
11
+ var OrchestratorBaseSepolia = require('@zkp2p/contracts-v2/abis/baseSepolia/Orchestrator.json');
12
+ var ProtocolViewerBaseSepolia = require('@zkp2p/contracts-v2/abis/baseSepolia/ProtocolViewer.json');
13
+ var UnifiedPaymentVerifierBaseSepolia = require('@zkp2p/contracts-v2/abis/baseSepolia/UnifiedPaymentVerifier.json');
14
+ var EscrowBaseStaging = require('@zkp2p/contracts-v2/abis/baseStaging/Escrow.json');
15
+ var OrchestratorBaseStaging = require('@zkp2p/contracts-v2/abis/baseStaging/Orchestrator.json');
16
+ var UnifiedPaymentVerifierBaseStaging = require('@zkp2p/contracts-v2/abis/baseStaging/UnifiedPaymentVerifier.json');
17
+ var ProtocolViewerBaseStaging = require('@zkp2p/contracts-v2/abis/baseStaging/ProtocolViewer.json');
18
+ var baseConstantsRaw = require('@zkp2p/contracts-v2/constants/base');
19
+ var baseStagingConstantsRaw = require('@zkp2p/contracts-v2/constants/baseStaging');
20
+ var basePaymentMethodsRaw = require('@zkp2p/contracts-v2/paymentMethods/base.json');
21
+ var baseSepoliaPaymentMethodsRaw = require('@zkp2p/contracts-v2/paymentMethods/baseSepolia.json');
22
+ var baseStagingPaymentMethodsRaw = require('@zkp2p/contracts-v2/paymentMethods/baseStaging.json');
23
+ var viem = require('viem');
24
+ var baseSepoliaPaymentMethods2 = require('@zkp2p/contracts-v2/paymentMethods/baseSepolia');
25
+ var baseStagingPaymentMethods2 = require('@zkp2p/contracts-v2/paymentMethods/baseStaging');
26
+ var chains = require('viem/chains');
27
+ var ethers = require('ethers');
28
+ var erc8021 = require('ox/erc8021');
29
+
30
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
31
+
32
+ var baseAddressesRaw__default = /*#__PURE__*/_interopDefault(baseAddressesRaw);
33
+ var baseSepoliaAddressesRaw__default = /*#__PURE__*/_interopDefault(baseSepoliaAddressesRaw);
34
+ var baseStagingAddressesRaw__default = /*#__PURE__*/_interopDefault(baseStagingAddressesRaw);
35
+ var EscrowBase__default = /*#__PURE__*/_interopDefault(EscrowBase);
36
+ var OrchestratorBase__default = /*#__PURE__*/_interopDefault(OrchestratorBase);
37
+ var ProtocolViewerBase__default = /*#__PURE__*/_interopDefault(ProtocolViewerBase);
38
+ var UnifiedPaymentVerifierBase__default = /*#__PURE__*/_interopDefault(UnifiedPaymentVerifierBase);
39
+ var EscrowBaseSepolia__default = /*#__PURE__*/_interopDefault(EscrowBaseSepolia);
40
+ var OrchestratorBaseSepolia__default = /*#__PURE__*/_interopDefault(OrchestratorBaseSepolia);
41
+ var ProtocolViewerBaseSepolia__default = /*#__PURE__*/_interopDefault(ProtocolViewerBaseSepolia);
42
+ var UnifiedPaymentVerifierBaseSepolia__default = /*#__PURE__*/_interopDefault(UnifiedPaymentVerifierBaseSepolia);
43
+ var EscrowBaseStaging__default = /*#__PURE__*/_interopDefault(EscrowBaseStaging);
44
+ var OrchestratorBaseStaging__default = /*#__PURE__*/_interopDefault(OrchestratorBaseStaging);
45
+ var UnifiedPaymentVerifierBaseStaging__default = /*#__PURE__*/_interopDefault(UnifiedPaymentVerifierBaseStaging);
46
+ var ProtocolViewerBaseStaging__default = /*#__PURE__*/_interopDefault(ProtocolViewerBaseStaging);
47
+ var baseConstantsRaw__default = /*#__PURE__*/_interopDefault(baseConstantsRaw);
48
+ var baseStagingConstantsRaw__default = /*#__PURE__*/_interopDefault(baseStagingConstantsRaw);
49
+ var basePaymentMethodsRaw__default = /*#__PURE__*/_interopDefault(basePaymentMethodsRaw);
50
+ var baseSepoliaPaymentMethodsRaw__default = /*#__PURE__*/_interopDefault(baseSepoliaPaymentMethodsRaw);
51
+ var baseStagingPaymentMethodsRaw__default = /*#__PURE__*/_interopDefault(baseStagingPaymentMethodsRaw);
52
+ var baseSepoliaPaymentMethods2__default = /*#__PURE__*/_interopDefault(baseSepoliaPaymentMethods2);
53
+ var baseStagingPaymentMethods2__default = /*#__PURE__*/_interopDefault(baseStagingPaymentMethods2);
54
+
55
+ var __defProp = Object.defineProperty;
56
+ var __getOwnPropNames = Object.getOwnPropertyNames;
57
+ var __esm = (fn, res) => function __init() {
58
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
59
+ };
60
+ var __export = (target, all) => {
61
+ for (var name in all)
62
+ __defProp(target, name, { get: all[name], enumerable: true });
63
+ };
64
+ function unwrapAddresses(mod) {
65
+ if (!mod) return {};
66
+ const m = mod;
67
+ if (m.contracts) return m;
68
+ if (m.default?.contracts) return m.default;
69
+ try {
70
+ const d = typeof m.default === "function" ? m.default() : m.default;
71
+ if (d?.contracts) return d;
72
+ } catch {
73
+ }
74
+ return m;
75
+ }
76
+ function unwrapMethods(mod) {
77
+ if (!mod) return {};
78
+ const m = mod;
79
+ if (m.methods) return m;
80
+ if (m.default?.methods) return m.default;
81
+ try {
82
+ const d = typeof m.default === "function" ? m.default() : m.default;
83
+ if (d?.methods) return d;
84
+ } catch {
85
+ }
86
+ return m;
87
+ }
88
+ function unwrapConstants(mod) {
89
+ if (!mod) return {};
90
+ const m = mod;
91
+ if (m.USDC) return m;
92
+ if (m.default?.USDC) return m.default;
93
+ try {
94
+ const d = typeof m.default === "function" ? m.default() : m.default;
95
+ if (d?.USDC) return d;
96
+ } catch {
97
+ }
98
+ return m;
99
+ }
100
+ function networkKeyFromChainId(chainId) {
101
+ if (chainId === 84532) return "base_sepolia";
102
+ return "base";
103
+ }
104
+ function getContracts(chainId, env = "production") {
105
+ const key = networkKeyFromChainId(chainId);
106
+ const addressesByKey = {
107
+ base: {
108
+ escrow: baseAddresses.contracts?.Escrow ?? "",
109
+ orchestrator: baseAddresses.contracts?.Orchestrator ?? "",
110
+ unifiedPaymentVerifier: baseAddresses.contracts?.UnifiedPaymentVerifier ?? "",
111
+ protocolViewer: baseAddresses.contracts?.ProtocolViewer ?? "",
112
+ usdc: baseConstants.USDC
113
+ },
114
+ base_sepolia: {
115
+ escrow: baseSepoliaAddresses.contracts?.Escrow ?? "",
116
+ orchestrator: baseSepoliaAddresses.contracts?.Orchestrator ?? "",
117
+ unifiedPaymentVerifier: baseSepoliaAddresses.contracts?.UnifiedPaymentVerifier ?? "",
118
+ protocolViewer: baseSepoliaAddresses.contracts?.ProtocolViewer ?? "",
119
+ // Prefer mock USDC when available on testnet
120
+ usdc: baseSepoliaAddresses.contracts?.USDCMock
121
+ }
122
+ };
123
+ const abisByKey = {
124
+ base: {
125
+ escrow: EscrowBase__default.default,
126
+ orchestrator: OrchestratorBase__default.default,
127
+ unifiedPaymentVerifier: UnifiedPaymentVerifierBase__default.default,
128
+ protocolViewer: ProtocolViewerBase__default.default
129
+ },
130
+ base_sepolia: {
131
+ escrow: EscrowBaseSepolia__default.default,
132
+ orchestrator: OrchestratorBaseSepolia__default.default,
133
+ unifiedPaymentVerifier: UnifiedPaymentVerifierBaseSepolia__default.default,
134
+ protocolViewer: ProtocolViewerBaseSepolia__default.default
135
+ }
136
+ };
137
+ if (env === "staging") {
138
+ return {
139
+ addresses: {
140
+ escrow: baseStagingAddresses.contracts?.Escrow ?? "",
141
+ orchestrator: baseStagingAddresses.contracts?.Orchestrator ?? "",
142
+ unifiedPaymentVerifier: baseStagingAddresses.contracts?.UnifiedPaymentVerifier ?? "",
143
+ protocolViewer: baseStagingAddresses.contracts?.ProtocolViewer ?? "",
144
+ usdc: baseStagingConstants.USDC
145
+ },
146
+ abis: {
147
+ escrow: EscrowBaseStaging__default.default,
148
+ orchestrator: OrchestratorBaseStaging__default.default,
149
+ unifiedPaymentVerifier: UnifiedPaymentVerifierBaseStaging__default.default,
150
+ protocolViewer: ProtocolViewerBaseStaging__default.default
151
+ }
152
+ };
153
+ }
154
+ return { addresses: addressesByKey[key], abis: abisByKey[key] };
155
+ }
156
+ function getPaymentMethodsCatalog(chainId, env = "production") {
157
+ const isBaseSepolia = networkKeyFromChainId(chainId) === "base_sepolia";
158
+ const src = env === "staging" ? baseStagingPaymentMethods : isBaseSepolia ? baseSepoliaPaymentMethods : basePaymentMethods;
159
+ const methods = src?.methods ?? src?.default?.methods ?? {};
160
+ return methods;
161
+ }
162
+ function getGatingServiceAddress(chainId, env = "production") {
163
+ if (env === "staging") {
164
+ return "0x396D31055Db28C0C6f36e8b36f18FE7227248a97";
165
+ }
166
+ if (networkKeyFromChainId(chainId) === "base_sepolia") {
167
+ return "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266";
168
+ }
169
+ return "0x396D31055Db28C0C6f36e8b36f18FE7227248a97";
170
+ }
171
+ var baseAddresses, baseSepoliaAddresses, baseStagingAddresses, basePaymentMethods, baseSepoliaPaymentMethods, baseStagingPaymentMethods, baseConstants, baseStagingConstants;
172
+ var init_contracts = __esm({
173
+ "src/contracts.ts"() {
174
+ baseAddresses = unwrapAddresses(baseAddressesRaw__default.default);
175
+ baseSepoliaAddresses = unwrapAddresses(baseSepoliaAddressesRaw__default.default);
176
+ baseStagingAddresses = unwrapAddresses(baseStagingAddressesRaw__default.default);
177
+ basePaymentMethods = unwrapMethods(basePaymentMethodsRaw__default.default);
178
+ baseSepoliaPaymentMethods = unwrapMethods(baseSepoliaPaymentMethodsRaw__default.default);
179
+ baseStagingPaymentMethods = unwrapMethods(baseStagingPaymentMethodsRaw__default.default);
180
+ baseConstants = unwrapConstants(baseConstantsRaw__default.default);
181
+ baseStagingConstants = unwrapConstants(baseStagingConstantsRaw__default.default);
182
+ }
183
+ });
184
+
185
+ // src/errors/index.ts
186
+ exports.ErrorCode = void 0; exports.ZKP2PError = void 0; exports.ValidationError = void 0; exports.NetworkError = void 0; exports.APIError = void 0; exports.ContractError = void 0;
187
+ var init_errors = __esm({
188
+ "src/errors/index.ts"() {
189
+ exports.ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
190
+ ErrorCode2["VALIDATION"] = "VALIDATION";
191
+ ErrorCode2["NETWORK"] = "NETWORK";
192
+ ErrorCode2["API"] = "API";
193
+ ErrorCode2["CONTRACT"] = "CONTRACT";
194
+ ErrorCode2["UNKNOWN"] = "UNKNOWN";
195
+ return ErrorCode2;
196
+ })(exports.ErrorCode || {});
197
+ exports.ZKP2PError = class extends Error {
198
+ constructor(message, code = "UNKNOWN" /* UNKNOWN */, details, field) {
199
+ super(message);
200
+ this.name = "ZKP2PError";
201
+ this.code = code;
202
+ this.details = details;
203
+ this.field = field;
204
+ }
205
+ };
206
+ exports.ValidationError = class extends exports.ZKP2PError {
207
+ constructor(message, field, details) {
208
+ super(message, "VALIDATION" /* VALIDATION */, details, field);
209
+ this.name = "ValidationError";
210
+ }
211
+ };
212
+ exports.NetworkError = class extends exports.ZKP2PError {
213
+ constructor(message, details) {
214
+ super(message, "NETWORK" /* NETWORK */, details);
215
+ this.name = "NetworkError";
216
+ }
217
+ };
218
+ exports.APIError = class extends exports.ZKP2PError {
219
+ constructor(message, status, details) {
220
+ super(message, "API" /* API */, details);
221
+ this.status = status;
222
+ this.name = "APIError";
223
+ }
224
+ };
225
+ exports.ContractError = class extends exports.ZKP2PError {
226
+ constructor(message, details) {
227
+ super(message, "CONTRACT" /* CONTRACT */, details);
228
+ this.name = "ContractError";
229
+ }
230
+ };
231
+ }
232
+ });
233
+
234
+ // src/utils/timeout.ts
235
+ var timeout_exports = {};
236
+ __export(timeout_exports, {
237
+ DEFAULT_TIMEOUTS: () => DEFAULT_TIMEOUTS,
238
+ withTimeout: () => withTimeout
239
+ });
240
+ async function withTimeout(promise, timeoutMs, timeoutMessage) {
241
+ let timeoutId;
242
+ const timeoutPromise = new Promise((_, reject) => {
243
+ timeoutId = setTimeout(() => {
244
+ reject(new exports.NetworkError(timeoutMessage, { timeout: timeoutMs }));
245
+ }, timeoutMs);
246
+ });
247
+ try {
248
+ const result = await Promise.race([promise, timeoutPromise]);
249
+ if (timeoutId) clearTimeout(timeoutId);
250
+ return result;
251
+ } catch (error) {
252
+ if (timeoutId) clearTimeout(timeoutId);
253
+ throw error;
254
+ }
255
+ }
256
+ var DEFAULT_TIMEOUTS;
257
+ var init_timeout = __esm({
258
+ "src/utils/timeout.ts"() {
259
+ init_errors();
260
+ DEFAULT_TIMEOUTS = {
261
+ /** API call timeout (30 seconds) */
262
+ API: 3e4,
263
+ /** Blockchain transaction timeout (60 seconds) */
264
+ TRANSACTION: 6e4,
265
+ /** Proof generation timeout (120 seconds) */
266
+ PROOF_GENERATION: 12e4,
267
+ /** Extension communication timeout (60 seconds) */
268
+ EXTENSION: 6e4
269
+ };
270
+ }
271
+ });
272
+ function ensureBytes32(value, { hashIfAscii = false } = {}) {
273
+ if (value.startsWith("0x")) {
274
+ const bytes = viem.hexToBytes(value);
275
+ if (bytes.length !== 32) throw new Error("Expected 32-byte hex value");
276
+ return value;
277
+ }
278
+ if (!hashIfAscii) throw new Error("Expected 32-byte hex; received ascii string. Pass hashIfAscii=true to hash.");
279
+ const hashed = viem.keccak256(viem.toBytes(value));
280
+ return hashed;
281
+ }
282
+ function asciiToBytes32(value) {
283
+ const b = viem.toBytes(value);
284
+ if (b.length > 32) throw new Error("ASCII input exceeds 32 bytes");
285
+ const padded = new Uint8Array(32);
286
+ padded.set(b);
287
+ return `0x${viem.bytesToHex(padded)}`;
288
+ }
289
+ var init_bytes32 = __esm({
290
+ "src/utils/bytes32.ts"() {
291
+ }
292
+ });
293
+
294
+ // src/utils/paymentResolution.ts
295
+ var paymentResolution_exports = {};
296
+ __export(paymentResolution_exports, {
297
+ resolveFiatCurrencyBytes32: () => resolveFiatCurrencyBytes32,
298
+ resolvePaymentMethodHash: () => resolvePaymentMethodHash,
299
+ resolvePaymentMethodHashFromCatalog: () => resolvePaymentMethodHashFromCatalog,
300
+ resolvePaymentMethodNameFromHash: () => resolvePaymentMethodNameFromHash
301
+ });
302
+ function getPaymentMethodMap(env, network) {
303
+ if (env === "staging") {
304
+ const m = baseStagingPaymentMethods2__default.default?.methods ?? {};
305
+ return m && Object.keys(m).length ? m : null;
306
+ }
307
+ if (network === "base_sepolia") {
308
+ const m = baseSepoliaPaymentMethods2__default.default?.methods ?? {};
309
+ return m && Object.keys(m).length ? m : null;
310
+ }
311
+ return null;
312
+ }
313
+ function resolvePaymentMethodHash(nameOrBytes, opts = {}) {
314
+ const { env = "production", network = "base" } = opts;
315
+ if (nameOrBytes.startsWith("0x")) return ensureBytes32(nameOrBytes);
316
+ const mapping = getPaymentMethodMap(env, network);
317
+ if (mapping) {
318
+ const key = nameOrBytes.toLowerCase();
319
+ const entry = mapping[key];
320
+ if (entry?.paymentMethodHash) return entry.paymentMethodHash;
321
+ }
322
+ return ensureBytes32(nameOrBytes, { hashIfAscii: true });
323
+ }
324
+ function resolveFiatCurrencyBytes32(codeOrBytes) {
325
+ if (codeOrBytes.startsWith("0x")) return ensureBytes32(codeOrBytes);
326
+ return asciiToBytes32(codeOrBytes.toUpperCase());
327
+ }
328
+ function resolvePaymentMethodHashFromCatalog(processorName, catalog) {
329
+ if (!processorName) {
330
+ throw new Error("processorName is required to resolve paymentMethodHash");
331
+ }
332
+ if (processorName.startsWith("0x")) {
333
+ return ensureBytes32(processorName);
334
+ }
335
+ const key = processorName.toLowerCase();
336
+ const entry = catalog?.[key];
337
+ if (entry?.paymentMethodHash) return entry.paymentMethodHash;
338
+ const available = Object.keys(catalog || {}).sort().join(", ");
339
+ throw new Error(
340
+ available ? `Unknown processorName: ${processorName}. Available: ${available}` : `Unknown processorName: ${processorName}. The payment methods catalog is empty or unavailable.`
341
+ );
342
+ }
343
+ function resolvePaymentMethodNameFromHash(hash, catalog) {
344
+ if (!hash) return void 0;
345
+ const target = ensureBytes32(hash);
346
+ for (const [name, entry] of Object.entries(catalog || {})) {
347
+ if (entry?.paymentMethodHash?.toLowerCase() === target.toLowerCase()) return name;
348
+ }
349
+ return void 0;
350
+ }
351
+ var init_paymentResolution = __esm({
352
+ "src/utils/paymentResolution.ts"() {
353
+ init_bytes32();
354
+ }
355
+ });
356
+ var currencyKeccak256;
357
+ var init_keccak = __esm({
358
+ "src/utils/keccak.ts"() {
359
+ currencyKeccak256 = (inputString) => {
360
+ return viem.keccak256(viem.stringToHex(inputString));
361
+ };
362
+ }
363
+ });
364
+
365
+ // src/utils/currency.ts
366
+ var currency_exports = {};
367
+ __export(currency_exports, {
368
+ Currency: () => exports.Currency,
369
+ currencyInfo: () => exports.currencyInfo,
370
+ getCurrencyCodeFromHash: () => getCurrencyCodeFromHash,
371
+ getCurrencyInfoFromCountryCode: () => getCurrencyInfoFromCountryCode,
372
+ getCurrencyInfoFromHash: () => getCurrencyInfoFromHash,
373
+ isSupportedCurrencyHash: () => isSupportedCurrencyHash,
374
+ mapConversionRatesToOnchain: () => mapConversionRatesToOnchain,
375
+ mapConversionRatesToOnchainMinRate: () => mapConversionRatesToOnchainMinRate
376
+ });
377
+ function mapConversionRatesToOnchain(groups, expectedGroups) {
378
+ if (!Array.isArray(groups) || !Array.isArray(groups[0])) {
379
+ throw new Error("conversionRates must be a nested array per processor");
380
+ }
381
+ if (typeof expectedGroups === "number" && groups.length !== expectedGroups) {
382
+ throw new Error(`conversionRates length (${groups.length}) must match processorNames length (${expectedGroups})`);
383
+ }
384
+ return groups.map((group) => group.map((r) => {
385
+ const info = exports.currencyInfo[r.currency];
386
+ if (!info?.currencyCodeHash) throw new Error("Invalid currency");
387
+ return { code: info.currencyCodeHash, conversionRate: BigInt(r.conversionRate) };
388
+ }));
389
+ }
390
+ function mapConversionRatesToOnchainMinRate(groups, expectedGroups) {
391
+ if (!Array.isArray(groups) || !Array.isArray(groups[0])) {
392
+ throw new Error("conversionRates must be a nested array per payment method");
393
+ }
394
+ if (typeof expectedGroups === "number" && groups.length !== expectedGroups) {
395
+ throw new Error(`conversionRates length (${groups.length}) must match processorNames length (${expectedGroups})`);
396
+ }
397
+ return groups.map(
398
+ (group) => group.map((r) => {
399
+ const info = exports.currencyInfo[r.currency];
400
+ const hash = info?.currencyCodeHash;
401
+ if (!hash) throw new Error(`Invalid currency: ${r.currency}`);
402
+ return { code: hash, minConversionRate: BigInt(r.conversionRate) };
403
+ })
404
+ );
405
+ }
406
+ function getCurrencyInfoFromHash(hash) {
407
+ if (!hash) return void 0;
408
+ const h = hash.toLowerCase();
409
+ for (const key of Object.keys(exports.currencyInfo)) {
410
+ const info = exports.currencyInfo[key];
411
+ if (info?.currencyCodeHash?.toLowerCase() === h) return info;
412
+ }
413
+ return void 0;
414
+ }
415
+ function getCurrencyInfoFromCountryCode(code) {
416
+ if (!code) return void 0;
417
+ const upper = code.toUpperCase();
418
+ return exports.currencyInfo[upper];
419
+ }
420
+ function getCurrencyCodeFromHash(hash) {
421
+ return getCurrencyInfoFromHash(hash)?.currencyCode;
422
+ }
423
+ function isSupportedCurrencyHash(hash) {
424
+ return Boolean(getCurrencyInfoFromHash(hash));
425
+ }
426
+ exports.Currency = void 0; exports.currencyInfo = void 0;
427
+ var init_currency = __esm({
428
+ "src/utils/currency.ts"() {
429
+ init_keccak();
430
+ exports.Currency = {
431
+ AED: "AED",
432
+ ARS: "ARS",
433
+ AUD: "AUD",
434
+ CAD: "CAD",
435
+ CHF: "CHF",
436
+ CNY: "CNY",
437
+ CZK: "CZK",
438
+ DKK: "DKK",
439
+ EUR: "EUR",
440
+ GBP: "GBP",
441
+ HKD: "HKD",
442
+ HUF: "HUF",
443
+ IDR: "IDR",
444
+ ILS: "ILS",
445
+ INR: "INR",
446
+ JPY: "JPY",
447
+ KES: "KES",
448
+ MXN: "MXN",
449
+ MYR: "MYR",
450
+ NOK: "NOK",
451
+ NZD: "NZD",
452
+ PHP: "PHP",
453
+ PLN: "PLN",
454
+ RON: "RON",
455
+ SAR: "SAR",
456
+ SEK: "SEK",
457
+ SGD: "SGD",
458
+ THB: "THB",
459
+ TRY: "TRY",
460
+ UGX: "UGX",
461
+ USD: "USD",
462
+ VND: "VND",
463
+ ZAR: "ZAR"
464
+ };
465
+ exports.currencyInfo = {
466
+ AED: { currency: "AED", currencyCode: "AED", currencyName: "United Arab Emirates Dirham", currencyCodeHash: currencyKeccak256("AED"), currencySymbol: "\u062F.\u0625", countryCode: "ae" },
467
+ ARS: { currency: "ARS", currencyCode: "ARS", currencyName: "Argentine Peso", currencyCodeHash: currencyKeccak256("ARS"), currencySymbol: "$", countryCode: "ar" },
468
+ AUD: { currency: "AUD", currencyCode: "AUD", currencyName: "Australian Dollar", currencyCodeHash: currencyKeccak256("AUD"), currencySymbol: "A$", countryCode: "au" },
469
+ CAD: { currency: "CAD", currencyCode: "CAD", currencyName: "Canadian Dollar", currencyCodeHash: currencyKeccak256("CAD"), currencySymbol: "C$", countryCode: "ca" },
470
+ CHF: { currency: "CHF", currencyCode: "CHF", currencyName: "Swiss Franc", currencyCodeHash: currencyKeccak256("CHF"), currencySymbol: "Fr", countryCode: "ch" },
471
+ CNY: { currency: "CNY", currencyCode: "CNY", currencyName: "Chinese Yuan", currencyCodeHash: currencyKeccak256("CNY"), currencySymbol: "\xA5", countryCode: "cn" },
472
+ CZK: { currency: "CZK", currencyCode: "CZK", currencyName: "Czech Koruna", currencyCodeHash: currencyKeccak256("CZK"), currencySymbol: "K\u010D", countryCode: "cz" },
473
+ DKK: { currency: "DKK", currencyCode: "DKK", currencyName: "Danish Krone", currencyCodeHash: currencyKeccak256("DKK"), currencySymbol: "kr", countryCode: "dk" },
474
+ EUR: { currency: "EUR", currencyCode: "EUR", currencyName: "Euro", currencyCodeHash: currencyKeccak256("EUR"), currencySymbol: "\u20AC", countryCode: "eu" },
475
+ GBP: { currency: "GBP", currencyCode: "GBP", currencyName: "British Pound", currencyCodeHash: currencyKeccak256("GBP"), currencySymbol: "\xA3", countryCode: "gb" },
476
+ HKD: { currency: "HKD", currencyCode: "HKD", currencyName: "Hong Kong Dollar", currencyCodeHash: currencyKeccak256("HKD"), currencySymbol: "HK$", countryCode: "hk" },
477
+ HUF: { currency: "HUF", currencyCode: "HUF", currencyName: "Hungarian Forint", currencyCodeHash: currencyKeccak256("HUF"), currencySymbol: "Ft", countryCode: "hu" },
478
+ IDR: { currency: "IDR", currencyCode: "IDR", currencyName: "Indonesian Rupiah", currencyCodeHash: currencyKeccak256("IDR"), currencySymbol: "Rp", countryCode: "id" },
479
+ ILS: { currency: "ILS", currencyCode: "ILS", currencyName: "Israeli New Shekel", currencyCodeHash: currencyKeccak256("ILS"), currencySymbol: "\u20AA", countryCode: "il" },
480
+ INR: { currency: "INR", currencyCode: "INR", currencyName: "Indian Rupee", currencyCodeHash: currencyKeccak256("INR"), currencySymbol: "\u20B9", countryCode: "in" },
481
+ JPY: { currency: "JPY", currencyCode: "JPY", currencyName: "Japanese Yen", currencyCodeHash: currencyKeccak256("JPY"), currencySymbol: "\xA5", countryCode: "jp" },
482
+ KES: { currency: "KES", currencyCode: "KES", currencyName: "Kenyan Shilling", currencyCodeHash: currencyKeccak256("KES"), currencySymbol: "KSh", countryCode: "ke" },
483
+ MXN: { currency: "MXN", currencyCode: "MXN", currencyName: "Mexican Peso", currencyCodeHash: currencyKeccak256("MXN"), currencySymbol: "$", countryCode: "mx" },
484
+ MYR: { currency: "MYR", currencyCode: "MYR", currencyName: "Malaysian Ringgit", currencyCodeHash: currencyKeccak256("MYR"), currencySymbol: "RM", countryCode: "my" },
485
+ NOK: { currency: "NOK", currencyCode: "NOK", currencyName: "Norwegian Krone", currencyCodeHash: currencyKeccak256("NOK"), currencySymbol: "kr", countryCode: "no" },
486
+ NZD: { currency: "NZD", currencyCode: "NZD", currencyName: "New Zealand Dollar", currencyCodeHash: currencyKeccak256("NZD"), currencySymbol: "NZ$", countryCode: "nz" },
487
+ PHP: { currency: "PHP", currencyCode: "PHP", currencyName: "Philippine Peso", currencyCodeHash: currencyKeccak256("PHP"), currencySymbol: "\u20B1", countryCode: "ph" },
488
+ PLN: { currency: "PLN", currencyCode: "PLN", currencyName: "Polish Z\u0142oty", currencyCodeHash: currencyKeccak256("PLN"), currencySymbol: "z\u0142", countryCode: "pl" },
489
+ RON: { currency: "RON", currencyCode: "RON", currencyName: "Romanian Leu", currencyCodeHash: currencyKeccak256("RON"), currencySymbol: "lei", countryCode: "ro" },
490
+ SAR: { currency: "SAR", currencyCode: "SAR", currencyName: "Saudi Riyal", currencyCodeHash: currencyKeccak256("SAR"), currencySymbol: "\uFDFC", countryCode: "sa" },
491
+ SEK: { currency: "SEK", currencyCode: "SEK", currencyName: "Swedish Krona", currencyCodeHash: currencyKeccak256("SEK"), currencySymbol: "kr", countryCode: "se" },
492
+ SGD: { currency: "SGD", currencyCode: "SGD", currencyName: "Singapore Dollar", currencyCodeHash: currencyKeccak256("SGD"), currencySymbol: "S$", countryCode: "sg" },
493
+ THB: { currency: "THB", currencyCode: "THB", currencyName: "Thai Baht", currencyCodeHash: currencyKeccak256("THB"), currencySymbol: "\u0E3F", countryCode: "th" },
494
+ TRY: { currency: "TRY", currencyCode: "TRY", currencyName: "Turkish Lira", currencyCodeHash: currencyKeccak256("TRY"), currencySymbol: "\u20BA", countryCode: "tr" },
495
+ UGX: { currency: "UGX", currencyCode: "UGX", currencyName: "Ugandan Shilling", currencyCodeHash: currencyKeccak256("UGX"), currencySymbol: "USh", countryCode: "ug" },
496
+ USD: { currency: "USD", currencyCode: "USD", currencyName: "United States Dollar", currencyCodeHash: currencyKeccak256("USD"), currencySymbol: "$", countryCode: "us" },
497
+ VND: { currency: "VND", currencyCode: "VND", currencyName: "Vietnamese Dong", currencyCodeHash: currencyKeccak256("VND"), currencySymbol: "\u20AB", countryCode: "vn" },
498
+ ZAR: { currency: "ZAR", currencyCode: "ZAR", currencyName: "South African Rand", currencyCodeHash: currencyKeccak256("ZAR"), currencySymbol: "R", countryCode: "za" }
499
+ };
500
+ }
501
+ });
502
+
503
+ // src/types/index.ts
504
+ exports.PAYMENT_PLATFORMS = void 0;
505
+ var init_types = __esm({
506
+ "src/types/index.ts"() {
507
+ exports.PAYMENT_PLATFORMS = [
508
+ "wise",
509
+ "venmo",
510
+ "revolut",
511
+ "cashapp",
512
+ "mercadopago",
513
+ "zelle",
514
+ "paypal",
515
+ "monzo"
516
+ ];
517
+ }
518
+ });
519
+
520
+ // src/utils/constants.ts
521
+ var DEFAULT_BASE_API_URL, DEFAULT_WITNESS_URL, DEPLOYED_ADDRESSES;
522
+ var init_constants = __esm({
523
+ "src/utils/constants.ts"() {
524
+ DEFAULT_BASE_API_URL = "https://api.zkp2p.xyz";
525
+ DEFAULT_WITNESS_URL = "https://witness-proxy.zkp2p.xyz";
526
+ DEPLOYED_ADDRESSES = {
527
+ 8453: {
528
+ production: {
529
+ // external contracts
530
+ usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
531
+ // escrow + verifiers
532
+ escrow: "0xCA38607D85E8F6294Dc10728669605E6664C2D70",
533
+ // Processor names to deployed addresses
534
+ venmo: "0x9a733B55a875D0DB4915c6B36350b24F8AB99dF5",
535
+ revolut: "0xAA5A1B62B01781E789C900d616300717CD9A41aB",
536
+ cashapp: "0x76D33A33068D86016B806dF02376dDBb23Dd3703",
537
+ wise: "0xFF0149799631D7A5bdE2e7eA9b306c42b3d9a9ca",
538
+ mercadopago: "0xf2AC5be14F32Cbe6A613CFF8931d95460D6c33A3",
539
+ zelle: "0x431a078A5029146aAB239c768A615CD484519aF7",
540
+ paypal: "0x03d17E9371C858072E171276979f6B44571C5DeA",
541
+ monzo: "0x0dE46433bD251027f73eD8f28E01eF05DA36a2E0",
542
+ // offchain services
543
+ gatingService: "0x396D31055Db28C0C6f36e8b36f18FE7227248a97",
544
+ zkp2pWitnessSigner: "0x0636c417755E3ae25C6c166D181c0607F4C572A3"
545
+ },
546
+ staging: {
547
+ // external contracts
548
+ usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
549
+ // escrow + verifiers
550
+ escrow: "0xC8cd114C6274Ef1066840337E7678BC9731BEa68",
551
+ // Processor names to deployed addresses
552
+ venmo: "0xCE6454f272127ba69e8C8128B92F2388Ca343257",
553
+ revolut: "0xb941e69B6C1A23A88cf9DA7D243bAE1D2Cb8eb6b",
554
+ cashapp: "0xdDB9d452180398F456Fe89A43Df9C65B19756CEa",
555
+ wise: "0x79F35E2f65ff917BE35686d34932C8Ef5a30631f",
556
+ mercadopago: "0xA2d54F983B8201c7b276C9705641C49C2FBD1A36",
557
+ zelle: "0x0Ed3c3DB9CF8458e5D9991712552539675D2C896",
558
+ paypal: "0xB07764999679a9136d6853a5D4c70449afbfc2f8",
559
+ monzo: "0x179792F99C0eFBFa06c3F6747989a96c58544f6F",
560
+ // offchain services
561
+ gatingService: "0x396D31055Db28C0C6f36e8b36f18FE7227248a97",
562
+ zkp2pWitnessSigner: "0x0636c417755E3ae25C6c166D181c0607F4C572A3"
563
+ }
564
+ },
565
+ 84532: {
566
+ usdc: "0x17463cb89A62c7b4A5ecD949aFDEDBD0Aa047ad1",
567
+ escrow: "0x15EF83EBB422B4AC8e3b8393d016Ed076dc50CB7",
568
+ venmo: "0x8499f2e7c4496Acfe0D7Ca5C7b6522514877b33F",
569
+ revolut: "0x7E34909A1C1b2a4D2FAbA61c17a0F59ECAce6F29",
570
+ cashapp: "0xe4148B108Fe4D7421853FE8cFfd35bDc2c0d95Ec",
571
+ wise: "0x54c92a8828A393C5A6D1DfbB71d0e9e97329b39C",
572
+ mercadopago: "0x4367155Fe7BAA99d9AE99fE4F6aC1b8E87012e6b",
573
+ zelle: "0xbeeC239145b3c461422BC2fC45B78E5fd70862F1",
574
+ paypal: "0xC8cd114C6274Ef1066840337E7678BC9731BEa68",
575
+ monzo: "0xe2B378D9181046c84dB1156B0F90cF3108e25E9D",
576
+ gatingService: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
577
+ zkp2pWitnessSigner: "0x0636c417755E3ae25C6c166D181c0607F4C572A3"
578
+ },
579
+ 31337: {
580
+ usdc: "0x5FbDB2315678afecb367f032d93F642f64180aa3",
581
+ escrow: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
582
+ venmo: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9",
583
+ revolut: "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853",
584
+ cashapp: "0x610178dA211FEF7D417bC0e6FeD39F05609AD788",
585
+ wise: "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82",
586
+ mercadopago: "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1",
587
+ zelle: "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c",
588
+ paypal: "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E",
589
+ monzo: "0x9E545E3C0baAB3E08CdfD552C960A1050f373042",
590
+ // offchain services
591
+ gatingService: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
592
+ // Hardhat 0
593
+ zkp2pWitnessSigner: "0x0636c417755E3ae25C6c166D181c0607F4C572A3"
594
+ }
595
+ };
596
+ }
597
+ });
598
+
599
+ // src/constants.ts
600
+ var constants_exports = {};
601
+ __export(constants_exports, {
602
+ Currency: () => exports.Currency,
603
+ DEFAULT_BASE_API_URL: () => DEFAULT_BASE_API_URL,
604
+ DEFAULT_WITNESS_URL: () => DEFAULT_WITNESS_URL,
605
+ DEPLOYED_ADDRESSES: () => DEPLOYED_ADDRESSES,
606
+ PAYMENT_PLATFORMS: () => exports.PAYMENT_PLATFORMS,
607
+ PLATFORM_ATTESTATION_CONFIG: () => PLATFORM_ATTESTATION_CONFIG,
608
+ PLATFORM_METADATA: () => exports.PLATFORM_METADATA,
609
+ SUPPORTED_CHAIN_IDS: () => exports.SUPPORTED_CHAIN_IDS,
610
+ TOKEN_METADATA: () => exports.TOKEN_METADATA,
611
+ currencyInfo: () => exports.currencyInfo,
612
+ resolvePlatformAttestationConfig: () => resolvePlatformAttestationConfig
613
+ });
614
+ function resolvePlatformAttestationConfig(platformName) {
615
+ const normalized = platformName.toLowerCase();
616
+ const config = PLATFORM_ATTESTATION_CONFIG[normalized];
617
+ if (!config) {
618
+ throw new Error(`Unknown payment platform: ${platformName}`);
619
+ }
620
+ return config;
621
+ }
622
+ exports.SUPPORTED_CHAIN_IDS = void 0; exports.PLATFORM_METADATA = void 0; exports.TOKEN_METADATA = void 0; var PLATFORM_ATTESTATION_CONFIG;
623
+ var init_constants2 = __esm({
624
+ "src/constants.ts"() {
625
+ init_types();
626
+ init_currency();
627
+ init_constants();
628
+ init_constants();
629
+ exports.SUPPORTED_CHAIN_IDS = {
630
+ /** Base mainnet (8453) */
631
+ BASE_MAINNET: 8453,
632
+ /** Base Sepolia testnet (84532) */
633
+ BASE_SEPOLIA: 84532,
634
+ /** Scroll mainnet (534352) */
635
+ SCROLL_MAINNET: 534352,
636
+ /** Local Hardhat network (31337) */
637
+ HARDHAT: 31337
638
+ };
639
+ exports.PLATFORM_METADATA = {
640
+ venmo: {
641
+ name: "Venmo",
642
+ displayName: "Venmo",
643
+ logo: "\u{1F4B5}",
644
+ requiredProofs: 1
645
+ },
646
+ revolut: {
647
+ name: "Revolut",
648
+ displayName: "Revolut",
649
+ logo: "\u{1F4B3}",
650
+ requiredProofs: 1
651
+ },
652
+ cashapp: {
653
+ name: "CashApp",
654
+ displayName: "Cash App",
655
+ logo: "\u{1F4B8}",
656
+ requiredProofs: 1
657
+ },
658
+ wise: {
659
+ name: "Wise",
660
+ displayName: "Wise",
661
+ logo: "\u{1F30D}",
662
+ requiredProofs: 2
663
+ },
664
+ mercadopago: {
665
+ name: "MercadoPago",
666
+ displayName: "Mercado Pago",
667
+ logo: "\u{1F4B0}",
668
+ requiredProofs: 1
669
+ },
670
+ zelle: {
671
+ name: "Zelle",
672
+ displayName: "Zelle",
673
+ logo: "\u{1F4B2}",
674
+ requiredProofs: 1
675
+ },
676
+ paypal: {
677
+ name: "PayPal",
678
+ displayName: "PayPal",
679
+ logo: "\u{1F499}",
680
+ requiredProofs: 1
681
+ },
682
+ monzo: {
683
+ name: "Monzo",
684
+ displayName: "Monzo",
685
+ logo: "\u{1F3E6}",
686
+ requiredProofs: 1
687
+ }
688
+ };
689
+ exports.TOKEN_METADATA = {
690
+ USDC: {
691
+ symbol: "USDC",
692
+ decimals: 6,
693
+ name: "USD Coin"
694
+ }
695
+ };
696
+ PLATFORM_ATTESTATION_CONFIG = {
697
+ wise: { actionType: "transfer_wise", actionPlatform: "wise" },
698
+ venmo: { actionType: "transfer_venmo", actionPlatform: "venmo" },
699
+ revolut: { actionType: "transfer_revolut", actionPlatform: "revolut" },
700
+ cashapp: { actionType: "transfer_cashapp", actionPlatform: "cashapp" },
701
+ mercadopago: { actionType: "transfer_mercadopago", actionPlatform: "mercadopago" },
702
+ paypal: { actionType: "transfer_paypal", actionPlatform: "paypal" },
703
+ monzo: { actionType: "transfer_monzo", actionPlatform: "monzo" },
704
+ "zelle-chase": { actionType: "transfer_zelle", actionPlatform: "chase" },
705
+ "zelle-bofa": { actionType: "transfer_zelle", actionPlatform: "bankofamerica" },
706
+ "zelle-citi": { actionType: "transfer_zelle", actionPlatform: "citi" }
707
+ };
708
+ }
709
+ });
710
+
711
+ // src/utils/protocolViewerParsers.ts
712
+ var protocolViewerParsers_exports = {};
713
+ __export(protocolViewerParsers_exports, {
714
+ enrichPvDepositView: () => enrichPvDepositView,
715
+ enrichPvIntentView: () => enrichPvIntentView,
716
+ parseDepositView: () => parseDepositView,
717
+ parseIntentView: () => parseIntentView
718
+ });
719
+ function toBigInt2(v) {
720
+ if (typeof v === "bigint") return v;
721
+ if (typeof v === "number") return BigInt(v);
722
+ if (typeof v === "string") return BigInt(v);
723
+ if (v && typeof v.toString === "function") return BigInt(v.toString());
724
+ throw new Error("Unsupported numeric type for bigint conversion");
725
+ }
726
+ function parseDepositView(raw) {
727
+ return {
728
+ depositId: toBigInt2(raw.depositId),
729
+ deposit: {
730
+ depositor: raw.deposit.depositor,
731
+ delegate: raw.deposit.delegate,
732
+ token: raw.deposit.token,
733
+ amount: toBigInt2(raw.deposit.amount),
734
+ intentAmountRange: {
735
+ min: toBigInt2(raw.deposit.intentAmountRange.min),
736
+ max: toBigInt2(raw.deposit.intentAmountRange.max)
737
+ },
738
+ acceptingIntents: raw.deposit.acceptingIntents,
739
+ remainingDeposits: toBigInt2(raw.deposit.remainingDeposits),
740
+ outstandingIntentAmount: toBigInt2(raw.deposit.outstandingIntentAmount),
741
+ makerProtocolFee: toBigInt2(raw.deposit.makerProtocolFee ?? 0),
742
+ reservedMakerFees: toBigInt2(raw.deposit.reservedMakerFees ?? 0),
743
+ accruedMakerFees: toBigInt2(raw.deposit.accruedMakerFees ?? 0),
744
+ accruedReferrerFees: toBigInt2(raw.deposit.accruedReferrerFees ?? 0),
745
+ intentGuardian: raw.deposit.intentGuardian,
746
+ referrer: raw.deposit.referrer,
747
+ referrerFee: toBigInt2(raw.deposit.referrerFee ?? 0)
748
+ },
749
+ availableLiquidity: toBigInt2(raw.availableLiquidity),
750
+ paymentMethods: (raw.paymentMethods || []).map((pm) => ({
751
+ paymentMethod: pm.paymentMethod,
752
+ verificationData: {
753
+ intentGatingService: pm.verificationData.intentGatingService,
754
+ payeeDetails: pm.verificationData.payeeDetails,
755
+ data: pm.verificationData.data
756
+ },
757
+ currencies: (pm.currencies || []).map((c) => ({
758
+ code: c.code,
759
+ minConversionRate: toBigInt2(c.minConversionRate)
760
+ }))
761
+ })),
762
+ intentHashes: raw.intentHashes || []
763
+ };
764
+ }
765
+ function parseIntentView(raw) {
766
+ const parsedDeposit = parseDepositView(raw.deposit);
767
+ const deposit = {
768
+ depositId: parsedDeposit.depositId,
769
+ deposit: parsedDeposit.deposit,
770
+ availableLiquidity: parsedDeposit.availableLiquidity,
771
+ paymentMethods: parsedDeposit.paymentMethods
772
+ };
773
+ return {
774
+ intentHash: raw.intentHash,
775
+ intent: {
776
+ owner: raw.intent.owner,
777
+ to: raw.intent.to,
778
+ escrow: raw.intent.escrow,
779
+ depositId: toBigInt2(raw.intent.depositId),
780
+ amount: toBigInt2(raw.intent.amount),
781
+ timestamp: toBigInt2(raw.intent.timestamp),
782
+ paymentMethod: raw.intent.paymentMethod,
783
+ fiatCurrency: raw.intent.fiatCurrency,
784
+ conversionRate: toBigInt2(raw.intent.conversionRate),
785
+ referrer: raw.intent.referrer,
786
+ referrerFee: toBigInt2(raw.intent.referrerFee ?? 0),
787
+ postIntentHook: raw.intent.postIntentHook,
788
+ data: raw.intent.data
789
+ },
790
+ deposit
791
+ };
792
+ }
793
+ function enrichPvDepositView(view, chainId, env = "production") {
794
+ const catalog = getPaymentMethodsCatalog(chainId, env);
795
+ return {
796
+ ...view,
797
+ paymentMethods: view.paymentMethods.map((pm) => ({
798
+ ...pm,
799
+ processorName: resolvePaymentMethodNameFromHash(pm.paymentMethod, catalog),
800
+ currencies: pm.currencies.map((c) => ({
801
+ ...c,
802
+ currencyInfo: getCurrencyInfoFromHash(c.code)
803
+ }))
804
+ }))
805
+ };
806
+ }
807
+ function enrichPvIntentView(view, chainId, env = "production") {
808
+ const catalog = getPaymentMethodsCatalog(chainId, env);
809
+ return {
810
+ ...view,
811
+ intent: {
812
+ ...view.intent,
813
+ processorName: resolvePaymentMethodNameFromHash(view.intent.paymentMethod, catalog),
814
+ currencyInfo: getCurrencyInfoFromHash(view.intent.fiatCurrency)
815
+ },
816
+ deposit: enrichPvDepositView(view.deposit, chainId, env)
817
+ };
818
+ }
819
+ var init_protocolViewerParsers = __esm({
820
+ "src/utils/protocolViewerParsers.ts"() {
821
+ init_contracts();
822
+ init_paymentResolution();
823
+ init_currency();
824
+ }
825
+ });
826
+
827
+ // src/indexer/client.ts
828
+ var IndexerClient = class {
829
+ constructor(endpoint) {
830
+ this.endpoint = endpoint;
831
+ }
832
+ async _post(request, init) {
833
+ const res = await fetch(this.endpoint, {
834
+ method: "POST",
835
+ headers: { "Content-Type": "application/json" },
836
+ body: JSON.stringify(request),
837
+ cache: "no-store",
838
+ ...init
839
+ });
840
+ if (!res.ok) throw new Error(`Indexer request failed: ${res.status} ${res.statusText}`);
841
+ const json = await res.json();
842
+ if (json.errors?.length) {
843
+ const msg = json.errors.map((e) => e.message).join(", ");
844
+ throw new Error(`GraphQL errors: ${msg}`);
845
+ }
846
+ if (!json.data) throw new Error("No data returned from indexer");
847
+ return json.data;
848
+ }
849
+ async query(request, init) {
850
+ const retries = init?.retries ?? 1;
851
+ let lastErr;
852
+ for (let i = 0; i <= retries; i++) {
853
+ try {
854
+ return await this._post(request, init);
855
+ } catch (e) {
856
+ lastErr = e;
857
+ if (i === retries) break;
858
+ await new Promise((r) => setTimeout(r, 200 * (i + 1)));
859
+ }
860
+ }
861
+ throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));
862
+ }
863
+ };
864
+ function defaultIndexerEndpoint(env = "PRODUCTION") {
865
+ switch (env) {
866
+ case "PRODUCTION":
867
+ return "https://indexer.hyperindex.xyz/8fd74dc/v1/graphql";
868
+ case "PREPRODUCTION":
869
+ return "https://indexer.hyperindex.xyz/186c193/v1/graphql";
870
+ case "STAGING":
871
+ return "https://indexer.dev.hyperindex.xyz/3b6e163/v1/graphql";
872
+ case "DEV":
873
+ case "LOCAL":
874
+ case "STAGING_TESTNET":
875
+ return "https://indexer.dev.hyperindex.xyz/3b6e163/v1/graphql";
876
+ default:
877
+ return "https://indexer.hyperindex.xyz/8fd74dc/v1/graphql";
878
+ }
879
+ }
880
+
881
+ // src/indexer/queries.ts
882
+ var DEPOSIT_FIELDS = `
883
+ id
884
+ chainId
885
+ escrowAddress
886
+ depositId
887
+ depositor
888
+ token
889
+ remainingDeposits
890
+ intentAmountMin
891
+ intentAmountMax
892
+ acceptingIntents
893
+ status
894
+ outstandingIntentAmount
895
+ totalAmountTaken
896
+ totalWithdrawn
897
+ successRateBps
898
+ totalIntents
899
+ signaledIntents
900
+ fulfilledIntents
901
+ prunedIntents
902
+ blockNumber
903
+ timestamp
904
+ txHash
905
+ updatedAt
906
+ `;
907
+ var DEPOSITS_QUERY = (
908
+ /* GraphQL */
909
+ `
910
+ query GetDeposits(
911
+ $where: Deposit_bool_exp
912
+ $order_by: [Deposit_order_by!]
913
+ $limit: Int
914
+ $offset: Int
915
+ ) {
916
+ Deposit(where: $where, order_by: $order_by, limit: $limit, offset: $offset) {
917
+ ${DEPOSIT_FIELDS}
918
+ }
919
+ }
920
+ `
921
+ );
922
+ var DEPOSITS_BY_IDS_QUERY = (
923
+ /* GraphQL */
924
+ `
925
+ query GetDepositsByIds($ids: [String!]) {
926
+ Deposit(where: { id: { _in: $ids } }) {
927
+ ${DEPOSIT_FIELDS}
928
+ }
929
+ }
930
+ `
931
+ );
932
+ var DEPOSIT_RELATIONS_QUERY = (
933
+ /* GraphQL */
934
+ `
935
+ query GetDepositRelations($depositIds: [String!]) {
936
+ DepositPaymentMethod(where: { depositId: { _in: $depositIds } }) {
937
+ id
938
+ chainId
939
+ depositIdOnContract
940
+ depositId
941
+ paymentMethodHash
942
+ verifierAddress
943
+ intentGatingService
944
+ payeeDetailsHash
945
+ active
946
+ }
947
+ MethodCurrency(where: { depositId: { _in: $depositIds } }) {
948
+ id
949
+ chainId
950
+ depositIdOnContract
951
+ depositId
952
+ paymentMethodHash
953
+ currencyCode
954
+ minConversionRate
955
+ }
956
+ }
957
+ `
958
+ );
959
+ var PAYMENT_METHODS_BY_PAYEE_HASH_QUERY = (
960
+ /* GraphQL */
961
+ `
962
+ query GetPaymentMethodsByPayeeHash(
963
+ $where: DepositPaymentMethod_bool_exp!
964
+ $limit: Int
965
+ ) {
966
+ DepositPaymentMethod(where: $where, limit: $limit) {
967
+ id
968
+ chainId
969
+ depositIdOnContract
970
+ depositId
971
+ paymentMethodHash
972
+ verifierAddress
973
+ intentGatingService
974
+ payeeDetailsHash
975
+ active
976
+ }
977
+ }
978
+ `
979
+ );
980
+ var DEPOSIT_WITH_RELATIONS_QUERY = (
981
+ /* GraphQL */
982
+ `
983
+ query GetDepositWithRelations($id: String!) {
984
+ Deposit_by_pk(id: $id) {
985
+ ${DEPOSIT_FIELDS}
986
+ }
987
+ DepositPaymentMethod(where: { depositId: { _eq: $id } }) {
988
+ id
989
+ chainId
990
+ depositIdOnContract
991
+ depositId
992
+ paymentMethodHash
993
+ verifierAddress
994
+ intentGatingService
995
+ payeeDetailsHash
996
+ active
997
+ }
998
+ MethodCurrency(where: { depositId: { _eq: $id } }) {
999
+ id
1000
+ chainId
1001
+ depositIdOnContract
1002
+ depositId
1003
+ paymentMethodHash
1004
+ currencyCode
1005
+ minConversionRate
1006
+ }
1007
+ }
1008
+ `
1009
+ );
1010
+ var INTENTS_QUERY = (
1011
+ /* GraphQL */
1012
+ `
1013
+ query GetIntents(
1014
+ $where: Intent_bool_exp
1015
+ $order_by: [Intent_order_by!]
1016
+ $limit: Int
1017
+ $offset: Int
1018
+ ) {
1019
+ Intent(where: $where, order_by: $order_by, limit: $limit, offset: $offset) {
1020
+ id
1021
+ intentHash
1022
+ depositId
1023
+ orchestratorAddress
1024
+ verifier
1025
+ owner
1026
+ toAddress
1027
+ amount
1028
+ fiatCurrency
1029
+ conversionRate
1030
+ status
1031
+ isExpired
1032
+ signalTimestamp
1033
+ expiryTime
1034
+ fulfillTimestamp
1035
+ pruneTimestamp
1036
+ updatedAt
1037
+ signalTxHash
1038
+ fulfillTxHash
1039
+ pruneTxHash
1040
+ paymentMethodHash
1041
+ paymentAmount
1042
+ paymentCurrency
1043
+ paymentTimestamp
1044
+ paymentId
1045
+ releasedAmount
1046
+ takerAmountNetFees
1047
+ }
1048
+ }
1049
+ `
1050
+ );
1051
+ var EXPIRED_INTENTS_QUERY = (
1052
+ /* GraphQL */
1053
+ `
1054
+ query GetExpiredIntents(
1055
+ $now: numeric!
1056
+ $limit: Int
1057
+ $depositIds: [String!]
1058
+ ) {
1059
+ Intent(
1060
+ where: {
1061
+ status: { _eq: "SIGNALED" }
1062
+ expiryTime: { _lt: $now }
1063
+ depositId: { _in: $depositIds }
1064
+ }
1065
+ order_by: { expiryTime: asc }
1066
+ limit: $limit
1067
+ ) {
1068
+ id
1069
+ intentHash
1070
+ depositId
1071
+ owner
1072
+ toAddress
1073
+ amount
1074
+ expiryTime
1075
+ isExpired
1076
+ updatedAt
1077
+ paymentMethodHash
1078
+ }
1079
+ }
1080
+ `
1081
+ );
1082
+ var INTENT_FULFILLMENTS_QUERY = (
1083
+ /* GraphQL */
1084
+ `
1085
+ query GetFulfilledIntents($intentHashes: [String!]) {
1086
+ Orchestrator_V21_IntentFulfilled(
1087
+ where: { intentHash: { _in: $intentHashes } }
1088
+ ) {
1089
+ intentHash
1090
+ isManualRelease
1091
+ fundsTransferredTo
1092
+ }
1093
+ }
1094
+ `
1095
+ );
1096
+ var FULFILLMENT_AND_PAYMENT_QUERY = (
1097
+ /* GraphQL */
1098
+ `
1099
+ query PaymentVerificationForFulfilledIntent($intentHash: String!) {
1100
+ Orchestrator_V21_IntentFulfilled(
1101
+ where: { intentHash: { _eq: $intentHash } }
1102
+ ) {
1103
+ id
1104
+ intentHash
1105
+ amount
1106
+ isManualRelease
1107
+ fundsTransferredTo
1108
+ }
1109
+ UnifiedVerifier_V21_PaymentVerified(
1110
+ where: { intentHash: { _eq: $intentHash } }
1111
+ ) {
1112
+ id
1113
+ intentHash
1114
+ method
1115
+ currency
1116
+ amount
1117
+ timestamp
1118
+ paymentId
1119
+ payeeId
1120
+ }
1121
+ }
1122
+ `
1123
+ );
1124
+
1125
+ // src/indexer/converters.ts
1126
+ var ZERO = "0x0000000000000000000000000000000000000000";
1127
+ function toBigInt(value) {
1128
+ if (value === null || value === void 0) return 0n;
1129
+ try {
1130
+ return typeof value === "bigint" ? value : BigInt(value);
1131
+ } catch {
1132
+ return 0n;
1133
+ }
1134
+ }
1135
+ function normalizeAddress(value) {
1136
+ if (!value) return ZERO;
1137
+ return value.startsWith("0x") ? value : ZERO;
1138
+ }
1139
+ function extractDepositId(compositeId) {
1140
+ const parts = compositeId.split("_");
1141
+ return parts[1] || "0";
1142
+ }
1143
+ function createCompositeDepositId(escrowAddress, depositId) {
1144
+ return `${escrowAddress.toLowerCase()}_${depositId.toString()}`;
1145
+ }
1146
+ function convertIndexerDepositToEscrowView(deposit, _chainId, _escrowAddress) {
1147
+ const paymentMethods = (deposit.paymentMethods ?? []).filter((pm) => pm.active !== false);
1148
+ const currencies = deposit.currencies ?? [];
1149
+ const currenciesByPaymentMethod = /* @__PURE__ */ new Map();
1150
+ for (const c of currencies) {
1151
+ const bucket = currenciesByPaymentMethod.get(c.paymentMethodHash) ?? [];
1152
+ bucket.push(c);
1153
+ currenciesByPaymentMethod.set(c.paymentMethodHash, bucket);
1154
+ }
1155
+ const verifiers = paymentMethods.map((pm) => ({
1156
+ verifier: normalizeAddress(pm.verifierAddress),
1157
+ verificationData: {
1158
+ intentGatingService: normalizeAddress(pm.intentGatingService),
1159
+ payeeDetails: pm.payeeDetailsHash ?? "",
1160
+ data: ""
1161
+ },
1162
+ currencies: (currenciesByPaymentMethod.get(pm.paymentMethodHash) ?? []).map((cur) => ({
1163
+ code: cur.currencyCode,
1164
+ conversionRate: toBigInt(cur.minConversionRate)
1165
+ })),
1166
+ methodHash: pm.paymentMethodHash
1167
+ }));
1168
+ const uniqueIntentHashes = new Set((deposit.intents ?? []).map((i) => i.intentHash));
1169
+ const remaining = toBigInt(deposit.remainingDeposits);
1170
+ const outstanding = toBigInt(deposit.outstandingIntentAmount);
1171
+ const depositAmount = remaining + outstanding + toBigInt(deposit.totalAmountTaken ?? 0) + toBigInt(deposit.totalWithdrawn ?? 0);
1172
+ return {
1173
+ depositId: toBigInt(deposit.depositId),
1174
+ deposit: {
1175
+ depositor: normalizeAddress(deposit.depositor),
1176
+ token: normalizeAddress(deposit.token),
1177
+ depositAmount,
1178
+ intentAmountRange: { min: toBigInt(deposit.intentAmountMin), max: toBigInt(deposit.intentAmountMax) },
1179
+ acceptingIntents: Boolean(deposit.acceptingIntents),
1180
+ remainingDepositAmount: remaining,
1181
+ outstandingIntentAmount: outstanding,
1182
+ intentHashes: Array.from(uniqueIntentHashes)
1183
+ },
1184
+ verifiers
1185
+ };
1186
+ }
1187
+ function convertDepositsForLiquidity(deposits, chainId, escrowAddress) {
1188
+ return deposits.filter((d) => d.depositor && d.depositor.toLowerCase() !== ZERO && d.acceptingIntents && toBigInt(d.remainingDeposits) > 0n && d.status === "ACTIVE").map((d) => convertIndexerDepositToEscrowView(d));
1189
+ }
1190
+ function convertIndexerIntentsToEscrowViews(intents, depositViewsById) {
1191
+ const result = [];
1192
+ for (const intent of intents) {
1193
+ const depositView = depositViewsById.get(intent.depositId.toLowerCase());
1194
+ if (!depositView) continue;
1195
+ const rawDepositId = extractDepositId(intent.depositId);
1196
+ result.push({
1197
+ intentHash: intent.intentHash,
1198
+ intent: {
1199
+ owner: normalizeAddress(intent.owner),
1200
+ to: normalizeAddress(intent.toAddress),
1201
+ depositId: toBigInt(rawDepositId),
1202
+ amount: toBigInt(intent.amount),
1203
+ timestamp: toBigInt(intent.signalTimestamp),
1204
+ paymentVerifier: normalizeAddress(intent.verifier),
1205
+ fiatCurrency: intent.fiatCurrency,
1206
+ conversionRate: toBigInt(intent.conversionRate)
1207
+ },
1208
+ deposit: depositView
1209
+ });
1210
+ }
1211
+ return result;
1212
+ }
1213
+
1214
+ // src/indexer/service.ts
1215
+ function groupByDepositId(items) {
1216
+ const map = /* @__PURE__ */ new Map();
1217
+ for (const item of items) {
1218
+ if (!item.depositId) continue;
1219
+ const key = item.depositId.toLowerCase();
1220
+ const bucket = map.get(key);
1221
+ if (bucket) bucket.push(item);
1222
+ else map.set(key, [item]);
1223
+ }
1224
+ return map;
1225
+ }
1226
+ var DEFAULT_LIMIT = 100;
1227
+ var DEFAULT_ORDER_FIELD = "remainingDeposits";
1228
+ var IndexerDepositService = class {
1229
+ constructor(client) {
1230
+ this.client = client;
1231
+ }
1232
+ buildDepositWhere(filter) {
1233
+ if (!filter) return void 0;
1234
+ const where = {};
1235
+ if (filter.status) where.status = { _eq: filter.status };
1236
+ if (filter.depositor) where.depositor = { _ilike: filter.depositor };
1237
+ if (filter.chainId) where.chainId = { _eq: filter.chainId };
1238
+ if (filter.escrowAddresses && filter.escrowAddresses.length) {
1239
+ where.escrowAddress = { _in: filter.escrowAddresses };
1240
+ } else if (filter.escrowAddress) {
1241
+ where.escrowAddress = { _ilike: filter.escrowAddress };
1242
+ }
1243
+ if (filter.acceptingIntents !== void 0) where.acceptingIntents = { _eq: filter.acceptingIntents };
1244
+ if (filter.minLiquidity) where.remainingDeposits = { _gte: filter.minLiquidity };
1245
+ return Object.keys(where).length ? where : void 0;
1246
+ }
1247
+ buildOrderBy(pagination) {
1248
+ const field = pagination?.orderBy ?? DEFAULT_ORDER_FIELD;
1249
+ const direction = pagination?.orderDirection === "asc" ? "asc" : "desc";
1250
+ return [{ [field]: direction }];
1251
+ }
1252
+ async fetchRelations(depositIds) {
1253
+ if (!depositIds.length) {
1254
+ return {
1255
+ paymentMethodsByDeposit: /* @__PURE__ */ new Map(),
1256
+ currenciesByDeposit: /* @__PURE__ */ new Map()
1257
+ };
1258
+ }
1259
+ const result = await this.client.query({ query: DEPOSIT_RELATIONS_QUERY, variables: { depositIds } });
1260
+ const paymentMethodsByDeposit = groupByDepositId(result.DepositPaymentMethod ?? []);
1261
+ const currenciesByDeposit = groupByDepositId(result.MethodCurrency ?? []);
1262
+ return { paymentMethodsByDeposit, currenciesByDeposit };
1263
+ }
1264
+ async fetchIntents(params) {
1265
+ const where = {};
1266
+ if (params.depositIds?.length) where.depositId = { _in: params.depositIds };
1267
+ if (params.owner) where.owner = { _ilike: params.owner };
1268
+ if (params.statuses?.length) where.status = { _in: params.statuses };
1269
+ if (!Object.keys(where).length) return [];
1270
+ const result = await this.client.query({
1271
+ query: INTENTS_QUERY,
1272
+ variables: { where, order_by: [{ signalTimestamp: "desc" }], limit: params.limit, offset: params.offset }
1273
+ });
1274
+ return result.Intent ?? [];
1275
+ }
1276
+ async attachRelations(deposits, options = {}) {
1277
+ if (!deposits.length) return [];
1278
+ const depositIds = deposits.map((d) => d.id);
1279
+ const [{ paymentMethodsByDeposit, currenciesByDeposit }, intents] = await Promise.all([
1280
+ this.fetchRelations(depositIds),
1281
+ options.includeIntents ? this.fetchIntents({ depositIds, statuses: options.intentStatuses }) : Promise.resolve([])
1282
+ ]);
1283
+ const intentsByDeposit = options.includeIntents ? groupByDepositId(intents) : /* @__PURE__ */ new Map();
1284
+ return deposits.map((d) => {
1285
+ const key = d.id.toLowerCase();
1286
+ return {
1287
+ ...d,
1288
+ paymentMethods: paymentMethodsByDeposit.get(key) ?? [],
1289
+ currencies: currenciesByDeposit.get(key) ?? [],
1290
+ intents: options.includeIntents ? intentsByDeposit.get(key) ?? [] : void 0
1291
+ };
1292
+ });
1293
+ }
1294
+ async fetchDeposits(filter, pagination) {
1295
+ const result = await this.client.query({
1296
+ query: DEPOSITS_QUERY,
1297
+ variables: {
1298
+ where: this.buildDepositWhere(filter),
1299
+ order_by: this.buildOrderBy(pagination),
1300
+ limit: pagination?.limit ?? DEFAULT_LIMIT,
1301
+ offset: pagination?.offset ?? 0
1302
+ }
1303
+ });
1304
+ return result.Deposit ?? [];
1305
+ }
1306
+ async fetchDepositsWithRelations(filter, pagination, options = {}) {
1307
+ const deposits = await this.fetchDeposits(filter, pagination);
1308
+ return this.attachRelations(deposits, options);
1309
+ }
1310
+ async fetchDepositsByIds(ids) {
1311
+ if (!ids.length) return [];
1312
+ const result = await this.client.query({ query: DEPOSITS_BY_IDS_QUERY, variables: { ids } });
1313
+ return result.Deposit ?? [];
1314
+ }
1315
+ async fetchDepositsByIdsWithRelations(ids, options = {}) {
1316
+ const deposits = await this.fetchDepositsByIds(ids);
1317
+ return this.attachRelations(deposits, options);
1318
+ }
1319
+ async fetchIntentsForDeposits(depositIds, statuses) {
1320
+ if (!depositIds.length) return [];
1321
+ return this.fetchIntents({ depositIds, statuses });
1322
+ }
1323
+ async fetchIntentsByOwner(owner, statuses) {
1324
+ if (!owner) return [];
1325
+ return this.fetchIntents({ owner, statuses });
1326
+ }
1327
+ async fetchDepositWithRelations(id, options = {}) {
1328
+ const result = await this.client.query({ query: DEPOSIT_WITH_RELATIONS_QUERY, variables: { id } });
1329
+ const deposit = result.Deposit_by_pk;
1330
+ if (!deposit) return null;
1331
+ const base2 = { ...deposit, paymentMethods: result.DepositPaymentMethod ?? [], currencies: result.MethodCurrency ?? [] };
1332
+ if (!options.includeIntents) return base2;
1333
+ const intents = await this.fetchIntents({ depositIds: [deposit.id], statuses: options.intentStatuses });
1334
+ return { ...base2, intents };
1335
+ }
1336
+ async fetchExpiredIntents(params) {
1337
+ const depositIds = params.depositIds.map((id) => id.toLowerCase());
1338
+ if (!depositIds.length) return [];
1339
+ const result = await this.client.query({
1340
+ query: EXPIRED_INTENTS_QUERY,
1341
+ variables: {
1342
+ now: typeof params.now === "bigint" ? params.now.toString() : params.now,
1343
+ limit: params.limit ?? 1e3,
1344
+ depositIds
1345
+ }
1346
+ });
1347
+ return result.Intent ?? [];
1348
+ }
1349
+ async fetchFulfilledIntentEvents(intentHashes) {
1350
+ if (!intentHashes.length) return [];
1351
+ const uniqueHashes = Array.from(new Set(intentHashes)).filter(Boolean);
1352
+ if (!uniqueHashes.length) return [];
1353
+ const result = await this.client.query({
1354
+ query: INTENT_FULFILLMENTS_QUERY,
1355
+ variables: { intentHashes: uniqueHashes }
1356
+ });
1357
+ return result.Orchestrator_V21_IntentFulfilled ?? [];
1358
+ }
1359
+ async resolvePayeeHash(params) {
1360
+ try {
1361
+ const { escrowAddress, depositId, paymentMethodHash } = params;
1362
+ if (!escrowAddress || depositId === null || depositId === void 0 || !paymentMethodHash) return null;
1363
+ const compositeId = createCompositeDepositId(
1364
+ escrowAddress,
1365
+ typeof depositId === "bigint" ? depositId : depositId?.toString() ?? ""
1366
+ );
1367
+ const detail = await this.fetchDepositWithRelations(compositeId, { includeIntents: false });
1368
+ if (!detail?.paymentMethods?.length) return null;
1369
+ const target = paymentMethodHash.toLowerCase();
1370
+ const match = detail.paymentMethods.find((pm) => (pm.paymentMethodHash ?? "").toLowerCase() === target);
1371
+ return match?.payeeDetailsHash ?? null;
1372
+ } catch {
1373
+ return null;
1374
+ }
1375
+ }
1376
+ async fetchDepositsByPayeeHash(payeeHash, options = {}) {
1377
+ if (!payeeHash) return [];
1378
+ const normalizedHash = payeeHash.toLowerCase();
1379
+ const where = {
1380
+ payeeDetailsHash: { _ilike: normalizedHash }
1381
+ };
1382
+ if (options.paymentMethodHash) {
1383
+ where.paymentMethodHash = { _eq: options.paymentMethodHash.toLowerCase?.() ?? options.paymentMethodHash };
1384
+ }
1385
+ const result = await this.client.query({
1386
+ query: PAYMENT_METHODS_BY_PAYEE_HASH_QUERY,
1387
+ variables: { where, limit: options.limit }
1388
+ });
1389
+ const seen = /* @__PURE__ */ new Set();
1390
+ const depositIds = [];
1391
+ for (const pm of result.DepositPaymentMethod ?? []) {
1392
+ const id = pm.depositId;
1393
+ if (!id) continue;
1394
+ const key = id.toLowerCase();
1395
+ if (seen.has(key)) continue;
1396
+ seen.add(key);
1397
+ depositIds.push(id);
1398
+ }
1399
+ if (!depositIds.length) return [];
1400
+ return this.fetchDepositsByIdsWithRelations(depositIds, {
1401
+ includeIntents: options.includeIntents,
1402
+ intentStatuses: options.intentStatuses
1403
+ });
1404
+ }
1405
+ };
1406
+
1407
+ // src/indexer/intentVerification.ts
1408
+ async function fetchFulfillmentAndPayment(client, intentHash) {
1409
+ return client.query({
1410
+ query: FULFILLMENT_AND_PAYMENT_QUERY,
1411
+ variables: { intentHash }
1412
+ });
1413
+ }
1414
+
1415
+ // src/client/Zkp2pClient.ts
1416
+ init_contracts();
1417
+
1418
+ // src/adapters/verification.ts
1419
+ async function apiSignIntentV2(request, opts) {
1420
+ const controller = new AbortController();
1421
+ const id = setTimeout(() => controller.abort(), opts.timeoutMs ?? 15e3);
1422
+ try {
1423
+ const headers2 = { "Content-Type": "application/json" };
1424
+ if (opts.apiKey) headers2["x-api-key"] = opts.apiKey;
1425
+ if (opts.authorizationToken) headers2["authorization"] = `Bearer ${opts.authorizationToken}`;
1426
+ const res = await fetch(`${opts.baseApiUrl.replace(/\/$/, "")}/v2/verify/intent`, {
1427
+ method: "POST",
1428
+ headers: headers2,
1429
+ body: JSON.stringify(request),
1430
+ signal: controller.signal
1431
+ });
1432
+ if (!res.ok) {
1433
+ const text = await res.text().catch(() => "");
1434
+ throw new Error(`verify/intent failed: ${res.status} ${res.statusText} ${text}`);
1435
+ }
1436
+ const json = await res.json();
1437
+ const sig = json?.responseObject?.signedIntent;
1438
+ const expStr = json?.responseObject?.intentData?.signatureExpiration ?? json?.responseObject?.signatureExpiration;
1439
+ if (!sig || !expStr) throw new Error("verify/intent missing signature or expiration");
1440
+ return { signature: sig, signatureExpiration: BigInt(expStr) };
1441
+ } finally {
1442
+ clearTimeout(id);
1443
+ }
1444
+ }
1445
+
1446
+ // src/adapters/attestation.ts
1447
+ init_errors();
1448
+
1449
+ // src/errors/utils.ts
1450
+ init_errors();
1451
+ function parseAPIError(response, responseText) {
1452
+ let message = `Request failed: ${response.statusText}`;
1453
+ try {
1454
+ const parsed = responseText ? JSON.parse(responseText) : void 0;
1455
+ if (parsed && (parsed.error || parsed.message)) {
1456
+ message = parsed.error || parsed.message;
1457
+ }
1458
+ } catch {
1459
+ if (responseText && responseText.length < 200) message = responseText;
1460
+ }
1461
+ if (response.status === 429) {
1462
+ message = "Too many requests. Please try again later.";
1463
+ }
1464
+ return new exports.APIError(message, response.status, { url: response.url });
1465
+ }
1466
+ async function withRetry(fn, maxRetries = 3, delayMs = 1e3, timeoutMs) {
1467
+ let lastErr;
1468
+ for (let i = 0; i < maxRetries; i++) {
1469
+ try {
1470
+ if (timeoutMs) {
1471
+ const { withTimeout: withTimeout2 } = await Promise.resolve().then(() => (init_timeout(), timeout_exports));
1472
+ return await withTimeout2(fn(), timeoutMs, `Operation timed out after ${timeoutMs}ms`);
1473
+ }
1474
+ return await fn();
1475
+ } catch (err) {
1476
+ lastErr = err;
1477
+ const isNetwork = err instanceof exports.NetworkError;
1478
+ const isRateLimit = err instanceof exports.APIError && err.status === 429;
1479
+ const retryable = isNetwork || isRateLimit;
1480
+ if (!retryable || i === maxRetries - 1) throw err;
1481
+ const base2 = isRateLimit ? delayMs * Math.pow(2, i) : delayMs;
1482
+ const jitter = Math.floor(Math.random() * Math.min(1e3, base2));
1483
+ await new Promise((r) => setTimeout(r, base2 + jitter));
1484
+ }
1485
+ }
1486
+ throw lastErr;
1487
+ }
1488
+
1489
+ // src/adapters/attestation.ts
1490
+ function headers() {
1491
+ return { "Content-Type": "application/json" };
1492
+ }
1493
+ async function apiCreatePaymentAttestation(payload, attestationServiceUrl, platform, actionType) {
1494
+ return withRetry(async () => {
1495
+ let res;
1496
+ try {
1497
+ const endpoint = `/verify/${encodeURIComponent(platform)}/${encodeURIComponent(actionType)}`;
1498
+ res = await fetch(`${attestationServiceUrl}${endpoint}`, {
1499
+ method: "POST",
1500
+ headers: headers(),
1501
+ body: JSON.stringify(payload)
1502
+ });
1503
+ } catch (error) {
1504
+ throw new exports.NetworkError("Failed to connect to Attestation Service", {
1505
+ endpoint: `/verify/${platform}/${actionType}`,
1506
+ error
1507
+ });
1508
+ }
1509
+ if (!res.ok) {
1510
+ const errorText = await res.text();
1511
+ throw parseAPIError(res, errorText);
1512
+ }
1513
+ return res.json();
1514
+ });
1515
+ }
1516
+ var abiCoder = ethers.AbiCoder.defaultAbiCoder();
1517
+ function encodeVerifyPaymentData(params) {
1518
+ return abiCoder.encode(
1519
+ ["tuple(bytes32,bytes,bytes)"],
1520
+ [[params.intentHash, params.paymentProof, params.data]]
1521
+ );
1522
+ }
1523
+ function encodeAddressAsBytes(addr) {
1524
+ return abiCoder.encode(["address"], [addr]);
1525
+ }
1526
+ function encodePaymentAttestation(attestation) {
1527
+ const resp = attestation.responseObject;
1528
+ const td = resp.typedDataValue;
1529
+ const intentHash = td.intentHash;
1530
+ const releaseAmount = BigInt(td.releaseAmount);
1531
+ const dataHash = td.dataHash;
1532
+ const signatures = [resp.signature];
1533
+ const encodedPaymentDetails = resp.encodedPaymentDetails;
1534
+ if (!intentHash || !releaseAmount || !dataHash || !encodedPaymentDetails) {
1535
+ throw new Error("Attestation response missing required fields");
1536
+ }
1537
+ return abiCoder.encode(
1538
+ ["tuple(bytes32,uint256,bytes32,bytes[],bytes,bytes)"],
1539
+ [[intentHash, releaseAmount, dataHash, signatures, encodedPaymentDetails, "0x"]]
1540
+ );
1541
+ }
1542
+
1543
+ // src/adapters/api.ts
1544
+ init_errors();
1545
+ function createHeaders(apiKey, authToken) {
1546
+ const headers2 = { "Content-Type": "application/json" };
1547
+ if (apiKey) headers2["x-api-key"] = apiKey;
1548
+ if (authToken) headers2["Authorization"] = authToken.startsWith("Bearer ") ? authToken : `Bearer ${authToken}`;
1549
+ return headers2;
1550
+ }
1551
+ function withApiBase(baseApiUrl) {
1552
+ const trimmed = (baseApiUrl || "").trim();
1553
+ let base2 = trimmed.replace(/\/+$/, "");
1554
+ base2 = base2.replace(/\/v1$/i, "");
1555
+ base2 = base2.replace(/\/v2$/i, "");
1556
+ return base2;
1557
+ }
1558
+ async function apiFetch({
1559
+ url,
1560
+ method = "GET",
1561
+ body,
1562
+ apiKey,
1563
+ authToken,
1564
+ timeoutMs,
1565
+ retryCount = 3,
1566
+ retryDelayMs = 1e3
1567
+ }) {
1568
+ const endpoint = url.replace(/^[^/]*\/\/[^/]*/, "");
1569
+ return withRetry(async () => {
1570
+ let res;
1571
+ try {
1572
+ const options = {
1573
+ method,
1574
+ headers: createHeaders(apiKey, authToken)
1575
+ };
1576
+ if (body && method !== "GET") {
1577
+ options.body = JSON.stringify(body);
1578
+ }
1579
+ res = await fetch(url, options);
1580
+ } catch (error) {
1581
+ throw new exports.NetworkError("Failed to connect to API server", { endpoint, error });
1582
+ }
1583
+ if (!res.ok) {
1584
+ const errorText = await res.text();
1585
+ throw parseAPIError(res, errorText);
1586
+ }
1587
+ return res.json();
1588
+ }, retryCount, retryDelayMs, timeoutMs);
1589
+ }
1590
+ async function apiPostDepositDetails(req, baseApiUrl, timeoutMs) {
1591
+ return apiFetch({
1592
+ url: `${baseApiUrl.replace(/\/$/, "")}/v1/makers/create`,
1593
+ method: "POST",
1594
+ body: req,
1595
+ timeoutMs
1596
+ });
1597
+ }
1598
+ async function apiGetQuote(req, baseApiUrl, timeoutMs, apiKey, authToken) {
1599
+ if (req.quotesToReturn !== void 0) {
1600
+ if (!Number.isInteger(req.quotesToReturn) || req.quotesToReturn < 1) {
1601
+ throw new exports.ValidationError("quotesToReturn must be a positive integer", "quotesToReturn");
1602
+ }
1603
+ }
1604
+ const isExactFiat = req.isExactFiat !== false;
1605
+ const endpoint = isExactFiat ? "exact-fiat" : "exact-token";
1606
+ let url = `${withApiBase(baseApiUrl)}/v2/quote/${endpoint}`;
1607
+ if (req.quotesToReturn) url += `?quotesToReturn=${req.quotesToReturn}`;
1608
+ const requestBody = {
1609
+ ...req,
1610
+ [isExactFiat ? "exactFiatAmount" : "exactTokenAmount"]: req.amount,
1611
+ amount: void 0,
1612
+ isExactFiat: void 0,
1613
+ quotesToReturn: void 0
1614
+ };
1615
+ Object.keys(requestBody).forEach((k) => requestBody[k] === void 0 && delete requestBody[k]);
1616
+ return apiFetch({
1617
+ url,
1618
+ method: "POST",
1619
+ body: requestBody,
1620
+ apiKey,
1621
+ authToken,
1622
+ timeoutMs
1623
+ });
1624
+ }
1625
+ async function apiGetPayeeDetails(req, apiKey, baseApiUrl, authToken, timeoutMs) {
1626
+ return apiFetch({
1627
+ url: `${baseApiUrl.replace(/\/$/, "")}/v1/makers/${req.processorName}/${req.hashedOnchainId}`,
1628
+ method: "GET",
1629
+ apiKey,
1630
+ authToken,
1631
+ timeoutMs
1632
+ });
1633
+ }
1634
+ async function apiValidatePayeeDetails(req, baseApiUrl, timeoutMs) {
1635
+ const data = await apiFetch({
1636
+ url: `${baseApiUrl.replace(/\/$/, "")}/v1/makers/validate`,
1637
+ method: "POST",
1638
+ body: req,
1639
+ timeoutMs
1640
+ });
1641
+ if (typeof data?.responseObject === "boolean") {
1642
+ return {
1643
+ ...data,
1644
+ responseObject: { isValid: data.responseObject }
1645
+ };
1646
+ }
1647
+ return data;
1648
+ }
1649
+ async function apiGetTakerTier(req, apiKey, baseApiUrl, authToken, timeoutMs) {
1650
+ const normalizedOwner = req.owner.toLowerCase();
1651
+ const query = new URLSearchParams({
1652
+ owner: normalizedOwner,
1653
+ chainId: String(req.chainId)
1654
+ });
1655
+ const endpoint = `/v2/taker/tier?${query.toString()}`;
1656
+ return apiFetch({
1657
+ url: `${withApiBase(baseApiUrl)}${endpoint}`,
1658
+ method: "GET",
1659
+ apiKey,
1660
+ authToken,
1661
+ timeoutMs
1662
+ });
1663
+ }
1664
+
1665
+ // src/client/Zkp2pClient.ts
1666
+ init_contracts();
1667
+ init_paymentResolution();
1668
+ init_keccak();
1669
+
1670
+ // src/utils/erc20.ts
1671
+ var ERC20_ABI = [
1672
+ {
1673
+ type: "function",
1674
+ name: "allowance",
1675
+ stateMutability: "view",
1676
+ inputs: [
1677
+ { name: "owner", type: "address" },
1678
+ { name: "spender", type: "address" }
1679
+ ],
1680
+ outputs: [{ name: "amount", type: "uint256" }]
1681
+ },
1682
+ {
1683
+ type: "function",
1684
+ name: "approve",
1685
+ stateMutability: "nonpayable",
1686
+ inputs: [
1687
+ { name: "spender", type: "address" },
1688
+ { name: "amount", type: "uint256" }
1689
+ ],
1690
+ outputs: [{ name: "success", type: "bool" }]
1691
+ }
1692
+ ];
1693
+ var BASE_BUILDER_CODE = "bc_nbn6qkni";
1694
+ var ZKP2P_IOS_REFERRER = "zkp2p-ios";
1695
+ var ZKP2P_ANDROID_REFERRER = "zkp2p-android";
1696
+ function getAttributionDataSuffix(referrer) {
1697
+ const codes = [];
1698
+ if (referrer) {
1699
+ if (Array.isArray(referrer)) {
1700
+ codes.push(...referrer);
1701
+ } else {
1702
+ codes.push(referrer);
1703
+ }
1704
+ }
1705
+ codes.push(BASE_BUILDER_CODE);
1706
+ return erc8021.Attribution.toDataSuffix({ codes });
1707
+ }
1708
+ function appendAttributionToCalldata(calldata, referrer) {
1709
+ const suffix = getAttributionDataSuffix(referrer);
1710
+ return viem.concatHex([calldata, suffix]);
1711
+ }
1712
+ async function sendTransactionWithAttribution(walletClient, request, referrer, overrides) {
1713
+ const functionData = viem.encodeFunctionData({
1714
+ abi: request.abi,
1715
+ functionName: request.functionName,
1716
+ args: request.args || []
1717
+ });
1718
+ const dataWithAttribution = appendAttributionToCalldata(functionData, referrer);
1719
+ const {
1720
+ gas,
1721
+ gasPrice,
1722
+ maxFeePerGas,
1723
+ maxPriorityFeePerGas,
1724
+ nonce,
1725
+ value,
1726
+ accessList,
1727
+ authorizationList
1728
+ } = overrides ?? {};
1729
+ const optionalOverrides = {
1730
+ ...gas !== void 0 ? { gas } : {},
1731
+ ...gasPrice !== void 0 ? { gasPrice } : {},
1732
+ ...maxFeePerGas !== void 0 ? { maxFeePerGas } : {},
1733
+ ...maxPriorityFeePerGas !== void 0 ? { maxPriorityFeePerGas } : {},
1734
+ ...nonce !== void 0 ? { nonce } : {},
1735
+ ...accessList !== void 0 ? { accessList } : {},
1736
+ ...authorizationList !== void 0 ? { authorizationList } : {}
1737
+ };
1738
+ return walletClient.sendTransaction({
1739
+ to: request.address,
1740
+ data: dataWithAttribution,
1741
+ value: value ?? request.value,
1742
+ account: walletClient.account,
1743
+ chain: walletClient.chain,
1744
+ ...optionalOverrides
1745
+ });
1746
+ }
1747
+
1748
+ // src/client/Zkp2pClient.ts
1749
+ var Zkp2pClient = class {
1750
+ /**
1751
+ * Creates a new Zkp2pClient instance.
1752
+ *
1753
+ * @param opts - Configuration options
1754
+ * @throws Error if walletClient is missing an account
1755
+ */
1756
+ constructor(opts) {
1757
+ this.walletClient = opts.walletClient;
1758
+ this.chainId = opts.chainId;
1759
+ this.runtimeEnv = opts.runtimeEnv ?? "production";
1760
+ const inferredRpc = this.walletClient?.chain?.rpcUrls?.default?.http?.[0];
1761
+ const defaultRpcUrls = {
1762
+ [chains.base.id]: "https://mainnet.base.org",
1763
+ [chains.baseSepolia.id]: "https://sepolia.base.org",
1764
+ [chains.hardhat.id]: "http://127.0.0.1:8545"
1765
+ };
1766
+ const rpc = opts.rpcUrl ?? inferredRpc ?? defaultRpcUrls[opts.chainId] ?? "https://mainnet.base.org";
1767
+ const chainMap = { [chains.base.id]: chains.base, [chains.baseSepolia.id]: chains.baseSepolia, [chains.hardhat.id]: chains.hardhat };
1768
+ const selectedChain = chainMap[this.chainId];
1769
+ this.publicClient = viem.createPublicClient({ chain: selectedChain, transport: viem.http(rpc, { batch: false }) });
1770
+ const { addresses, abis } = getContracts(this.chainId, this.runtimeEnv);
1771
+ this.escrowAddress = addresses.escrow;
1772
+ this.escrowAbi = abis.escrow;
1773
+ this.orchestratorAddress = addresses.orchestrator;
1774
+ this.orchestratorAbi = abis.orchestrator;
1775
+ this.unifiedPaymentVerifier = addresses.unifiedPaymentVerifier;
1776
+ this.protocolViewerAddress = addresses.protocolViewer;
1777
+ this.protocolViewerAbi = abis.protocolViewer;
1778
+ const maybeUsdc = addresses.usdc;
1779
+ if (maybeUsdc) this._usdcAddress = maybeUsdc;
1780
+ const indexerEndpoint = opts.indexerUrl ?? defaultIndexerEndpoint(this.runtimeEnv === "staging" ? "STAGING" : "PRODUCTION");
1781
+ this._indexerClient = new IndexerClient(indexerEndpoint);
1782
+ this._indexerService = new IndexerDepositService(this._indexerClient);
1783
+ this.baseApiUrl = opts.baseApiUrl;
1784
+ this.apiKey = opts.apiKey;
1785
+ this.authorizationToken = opts.authorizationToken;
1786
+ this.apiTimeoutMs = opts.timeouts?.api ?? 15e3;
1787
+ }
1788
+ isValidHexAddress(addr) {
1789
+ if (typeof addr !== "string") return false;
1790
+ return /^0x[0-9a-fA-F]{40}$/.test(addr);
1791
+ }
1792
+ /**
1793
+ * Simulate a contract call (validation only) and send with ERC-8021 attribution.
1794
+ * Referrer codes are stripped from overrides for simulation and appended to calldata.
1795
+ */
1796
+ async simulateAndSendWithAttribution(opts) {
1797
+ const { referrer, ...txOverrides } = opts.txOverrides ?? {};
1798
+ await this.publicClient.simulateContract({
1799
+ address: opts.address,
1800
+ abi: opts.abi,
1801
+ functionName: opts.functionName,
1802
+ args: opts.args ?? [],
1803
+ account: this.walletClient.account,
1804
+ ...txOverrides
1805
+ });
1806
+ return sendTransactionWithAttribution(
1807
+ this.walletClient,
1808
+ {
1809
+ address: opts.address,
1810
+ abi: opts.abi,
1811
+ functionName: opts.functionName,
1812
+ args: opts.args ?? [],
1813
+ value: opts.value ?? txOverrides.value
1814
+ },
1815
+ referrer,
1816
+ txOverrides
1817
+ );
1818
+ }
1819
+ // ╔═══════════════════════════════════════════════════════════════════════════╗
1820
+ // ║ CORE: DEPOSIT QUERIES (RPC-first via ProtocolViewer) ║
1821
+ // ╚═══════════════════════════════════════════════════════════════════════════╝
1822
+ /**
1823
+ * Fetches all deposits owned by the connected wallet from on-chain.
1824
+ *
1825
+ * This is the primary method for liquidity providers to query their deposits.
1826
+ * Uses ProtocolViewer for instant on-chain reads (no indexer lag).
1827
+ *
1828
+ * @returns Array of deposit views with payment methods and currencies
1829
+ *
1830
+ * @example
1831
+ * ```typescript
1832
+ * const deposits = await client.getDeposits();
1833
+ * for (const d of deposits) {
1834
+ * console.log(`Deposit ${d.depositId}: ${d.availableLiquidity} available`);
1835
+ * }
1836
+ * ```
1837
+ */
1838
+ async getDeposits() {
1839
+ const owner = this.walletClient.account?.address;
1840
+ if (!owner) throw new Error("Wallet client is missing account");
1841
+ return this.getAccountDeposits(owner);
1842
+ }
1843
+ /**
1844
+ * Fetches all deposits owned by a specific address from on-chain.
1845
+ *
1846
+ * Uses ProtocolViewer for instant on-chain reads.
1847
+ *
1848
+ * @param owner - The owner's Ethereum address
1849
+ * @returns Array of deposit views with payment methods and currencies
1850
+ *
1851
+ * @example
1852
+ * ```typescript
1853
+ * const deposits = await client.getAccountDeposits('0x...');
1854
+ * ```
1855
+ */
1856
+ async getAccountDeposits(owner) {
1857
+ return this.getPvAccountDeposits(owner);
1858
+ }
1859
+ /**
1860
+ * Fetches a single deposit by its numeric ID from on-chain.
1861
+ *
1862
+ * Uses ProtocolViewer for instant on-chain reads.
1863
+ *
1864
+ * @param depositId - The deposit ID (numeric)
1865
+ * @returns Deposit view with payment methods, currencies, and intent hashes
1866
+ *
1867
+ * @example
1868
+ * ```typescript
1869
+ * const deposit = await client.getDeposit(42n);
1870
+ * console.log(`Available: ${deposit.availableLiquidity}`);
1871
+ * console.log(`Payment methods: ${deposit.paymentMethods.length}`);
1872
+ * ```
1873
+ */
1874
+ async getDeposit(depositId) {
1875
+ const id = typeof depositId === "bigint" ? depositId : BigInt(depositId);
1876
+ return this.getPvDepositById(id);
1877
+ }
1878
+ /**
1879
+ * Fetches multiple deposits by their IDs from on-chain in a batch.
1880
+ *
1881
+ * @param depositIds - Array of deposit IDs
1882
+ * @returns Array of deposit views
1883
+ */
1884
+ async getDepositsById(depositIds) {
1885
+ const ids = depositIds.map((id) => typeof id === "bigint" ? id : BigInt(id));
1886
+ return this.getPvDepositsFromIds(ids);
1887
+ }
1888
+ /**
1889
+ * Fetches all intents created by the connected wallet from on-chain.
1890
+ *
1891
+ * Uses ProtocolViewer for instant on-chain reads.
1892
+ *
1893
+ * @returns Array of intent views with deposit context
1894
+ *
1895
+ * @example
1896
+ * ```typescript
1897
+ * const intents = await client.getIntents();
1898
+ * for (const i of intents) {
1899
+ * console.log(`Intent ${i.intentHash}: ${i.intent.amount} tokens`);
1900
+ * }
1901
+ * ```
1902
+ */
1903
+ async getIntents() {
1904
+ const owner = this.walletClient.account?.address;
1905
+ if (!owner) throw new Error("Wallet client is missing account");
1906
+ return this.getAccountIntents(owner);
1907
+ }
1908
+ /**
1909
+ * Fetches all intents created by a specific address from on-chain.
1910
+ *
1911
+ * @param owner - The owner's Ethereum address
1912
+ * @returns Array of intent views with deposit context
1913
+ */
1914
+ async getAccountIntents(owner) {
1915
+ return this.getPvAccountIntents(owner);
1916
+ }
1917
+ /**
1918
+ * Fetches a single intent by its hash from on-chain.
1919
+ *
1920
+ * @param intentHash - The intent hash (0x-prefixed, 32 bytes)
1921
+ * @returns Intent view with deposit context
1922
+ */
1923
+ async getIntent(intentHash) {
1924
+ return this.getPvIntent(intentHash);
1925
+ }
1926
+ /**
1927
+ * Resolves the payee details hash for a deposit's payment method from on-chain.
1928
+ *
1929
+ * @param depositId - The deposit ID
1930
+ * @param paymentMethodHash - The payment method hash
1931
+ * @returns The payee details hash, or null if not found
1932
+ */
1933
+ async resolvePayeeHash(depositId, paymentMethodHash) {
1934
+ const deposit = await this.getDeposit(depositId);
1935
+ const pmLower = paymentMethodHash.toLowerCase();
1936
+ for (const pm of deposit.paymentMethods) {
1937
+ if (pm.paymentMethod.toLowerCase() === pmLower) {
1938
+ return pm.verificationData.payeeDetails;
1939
+ }
1940
+ }
1941
+ return null;
1942
+ }
1943
+ // ╔═══════════════════════════════════════════════════════════════════════════╗
1944
+ // ║ ADVANCED: INDEXER QUERIES (for historical/filtered data) ║
1945
+ // ╚═══════════════════════════════════════════════════════════════════════════╝
1946
+ /**
1947
+ * Access to the indexer for advanced queries.
1948
+ *
1949
+ * Use this for:
1950
+ * - Historical data (totalAmountTaken, totalWithdrawn)
1951
+ * - Filtered queries across all deposits (not just by owner)
1952
+ * - Pagination with ordering
1953
+ * - Fulfillment/verification records
1954
+ *
1955
+ * @example
1956
+ * ```typescript
1957
+ * // Query deposits with filters and pagination
1958
+ * const deposits = await client.indexer.getDeposits(
1959
+ * { status: 'ACTIVE', minLiquidity: '1000000' },
1960
+ * { limit: 50, orderBy: 'remainingDeposits', orderDirection: 'desc' }
1961
+ * );
1962
+ *
1963
+ * // Get historical fulfillment data
1964
+ * const fulfillments = await client.indexer.getFulfilledIntentEvents(['0x...']);
1965
+ * ```
1966
+ */
1967
+ get indexer() {
1968
+ const service = this._indexerService;
1969
+ const client = this._indexerClient;
1970
+ return {
1971
+ /** Raw GraphQL client for custom queries */
1972
+ client,
1973
+ /**
1974
+ * Fetches deposits from the indexer with optional filtering and pagination.
1975
+ * Use for advanced queries across all deposits, not just by owner.
1976
+ */
1977
+ getDeposits: (filter, pagination) => {
1978
+ return service.fetchDeposits(filter, pagination);
1979
+ },
1980
+ /**
1981
+ * Fetches deposits with their related payment methods and optionally intents.
1982
+ */
1983
+ getDepositsWithRelations: (filter, pagination, options) => {
1984
+ return service.fetchDepositsWithRelations(filter, pagination, options);
1985
+ },
1986
+ /**
1987
+ * Fetches a single deposit by its composite ID with all related data.
1988
+ * @param id - Composite ID format: "chainId_escrowAddress_depositId"
1989
+ */
1990
+ getDepositById: (id, options) => {
1991
+ return service.fetchDepositWithRelations(id, options);
1992
+ },
1993
+ /**
1994
+ * Fetches intents for multiple deposits.
1995
+ */
1996
+ getIntentsForDeposits: (depositIds, statuses = ["SIGNALED"]) => {
1997
+ return service.fetchIntentsForDeposits(depositIds, statuses);
1998
+ },
1999
+ /**
2000
+ * Fetches all intents created by a specific owner address.
2001
+ */
2002
+ getOwnerIntents: (owner, statuses) => {
2003
+ return service.fetchIntentsByOwner(owner, statuses);
2004
+ },
2005
+ /**
2006
+ * Fetches intents that have expired.
2007
+ */
2008
+ getExpiredIntents: (params) => {
2009
+ return service.fetchExpiredIntents(params);
2010
+ },
2011
+ /**
2012
+ * Fetches fulfillment events for completed intents.
2013
+ */
2014
+ getFulfilledIntentEvents: (intentHashes) => {
2015
+ return service.fetchFulfilledIntentEvents(intentHashes);
2016
+ },
2017
+ /**
2018
+ * Fetches both the fulfillment record and payment verification for an intent.
2019
+ */
2020
+ getFulfillmentAndPayment: (intentHash) => {
2021
+ return fetchFulfillmentAndPayment(client, intentHash);
2022
+ },
2023
+ /**
2024
+ * Fetches deposits that match a specific payee details hash.
2025
+ */
2026
+ getDepositsByPayeeHash: (payeeHash, options = {}) => {
2027
+ return service.fetchDepositsByPayeeHash(payeeHash, options);
2028
+ }
2029
+ };
2030
+ }
2031
+ // ╔═══════════════════════════════════════════════════════════════════════════╗
2032
+ // ║ CORE: DEPOSIT CREATION ║
2033
+ // ╚═══════════════════════════════════════════════════════════════════════════╝
2034
+ /**
2035
+ * Ensures ERC20 token allowance is sufficient for the Escrow contract.
2036
+ *
2037
+ * If the current allowance is less than the requested amount, this method
2038
+ * will submit an approval transaction. Use `maxApprove: true` for unlimited
2039
+ * approval to avoid repeated approval transactions.
2040
+ *
2041
+ * @param params.token - ERC20 token address to approve
2042
+ * @param params.amount - Minimum required allowance amount
2043
+ * @param params.spender - Spender address (defaults to Escrow contract)
2044
+ * @param params.maxApprove - If true, approves MaxUint256 instead of exact amount
2045
+ * @param params.txOverrides - Optional viem transaction overrides
2046
+ * @returns Object with `hadAllowance` (true if no approval needed) and optional `hash`
2047
+ *
2048
+ * @example
2049
+ * ```typescript
2050
+ * // Ensure allowance for 1000 USDC
2051
+ * const { hadAllowance, hash } = await client.ensureAllowance({
2052
+ * token: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913',
2053
+ * amount: 1000_000000n,
2054
+ * maxApprove: true,
2055
+ * });
2056
+ *
2057
+ * if (!hadAllowance) {
2058
+ * console.log('Approval tx:', hash);
2059
+ * }
2060
+ * ```
2061
+ */
2062
+ async ensureAllowance(params) {
2063
+ const owner = this.walletClient.account?.address;
2064
+ if (!owner) throw new Error("Wallet client is missing account");
2065
+ const spender = params.spender ?? this.escrowAddress;
2066
+ const allowance = await this.publicClient.readContract({ address: params.token, abi: ERC20_ABI, functionName: "allowance", args: [owner, spender] });
2067
+ if (allowance >= params.amount) return { hadAllowance: true };
2068
+ const MAX = (1n << 256n) - 1n;
2069
+ const value = params.maxApprove ? MAX : params.amount;
2070
+ const hash = await this.simulateAndSendWithAttribution({
2071
+ address: params.token,
2072
+ abi: ERC20_ABI,
2073
+ functionName: "approve",
2074
+ args: [spender, value],
2075
+ txOverrides: params.txOverrides
2076
+ });
2077
+ return { hadAllowance: false, hash };
2078
+ }
2079
+ /**
2080
+ * Creates a new USDC deposit in the Escrow contract.
2081
+ *
2082
+ * This is the primary method for liquidity providers to add funds to the protocol.
2083
+ * The deposit can accept intents from multiple payment platforms with different
2084
+ * conversion rates per currency.
2085
+ *
2086
+ * **Important**: Requires `apiKey` or `authorizationToken` to be set.
2087
+ * Call `ensureAllowance()` first to approve USDC spending.
2088
+ *
2089
+ * @param params.token - Token address (USDC)
2090
+ * @param params.amount - Total deposit amount in token units (6 decimals for USDC)
2091
+ * @param params.intentAmountRange - Min/max amount per intent
2092
+ * @param params.processorNames - Payment platforms to accept (e.g., ['wise', 'revolut'])
2093
+ * @param params.depositData - Payee details per processor (e.g., [{ email: '...' }])
2094
+ * @param params.conversionRates - Conversion rates per processor, grouped by currency
2095
+ * @param params.delegate - Optional delegate address that can manage the deposit
2096
+ * @param params.intentGuardian - Optional guardian for intent approval
2097
+ * @param params.retainOnEmpty - Keep deposit active when balance reaches zero
2098
+ * @param params.txOverrides - Optional viem transaction overrides
2099
+ * @returns The deposit details posted to API and the transaction hash
2100
+ *
2101
+ * @throws Error if apiKey/authorizationToken is missing
2102
+ * @throws Error if processorNames, depositData, and conversionRates lengths don't match
2103
+ * @throws Error if a currency is not supported by the specified processor
2104
+ *
2105
+ * @example
2106
+ * ```typescript
2107
+ * // Create a 1000 USDC deposit accepting Wise payments in USD and EUR
2108
+ * const { hash } = await client.createDeposit({
2109
+ * token: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913',
2110
+ * amount: 1000_000000n,
2111
+ * intentAmountRange: { min: 10_000000n, max: 500_000000n },
2112
+ * processorNames: ['wise'],
2113
+ * depositData: [{ email: 'you@example.com' }],
2114
+ * conversionRates: [[
2115
+ * { currency: 'USD', conversionRate: '1020000000000000000' }, // 1.02
2116
+ * { currency: 'EUR', conversionRate: '1100000000000000000' }, // 1.10
2117
+ * ]],
2118
+ * });
2119
+ * ```
2120
+ */
2121
+ async createDeposit(params) {
2122
+ const methods = getPaymentMethodsCatalog(this.chainId, this.runtimeEnv);
2123
+ if (!Array.isArray(params.processorNames) || params.processorNames.length === 0) {
2124
+ throw new Error("processorNames must be a non-empty array");
2125
+ }
2126
+ if (params.processorNames.length !== params.conversionRates.length) {
2127
+ throw new Error("processorNames and conversionRates length mismatch");
2128
+ }
2129
+ if (params.processorNames.length !== params.depositData.length) {
2130
+ throw new Error("processorNames and depositData length mismatch");
2131
+ }
2132
+ const paymentMethods = params.processorNames.map((name) => resolvePaymentMethodHashFromCatalog(name, methods));
2133
+ const intentGatingService = getGatingServiceAddress(this.chainId, this.runtimeEnv);
2134
+ const baseApiUrl = (this.baseApiUrl ?? "https://api.zkp2p.xyz").replace(/\/$/, "");
2135
+ if (!this.apiKey && !this.authorizationToken) {
2136
+ throw new Error("createDeposit requires apiKey or authorizationToken to post deposit details");
2137
+ }
2138
+ const depositDetails = params.processorNames.map((processorName, index) => ({
2139
+ processorName,
2140
+ depositData: params.depositData[index] || {}
2141
+ }));
2142
+ const apiResponses = await Promise.all(
2143
+ depositDetails.map((req) => apiPostDepositDetails(req, baseApiUrl, this.apiTimeoutMs))
2144
+ );
2145
+ if (!apiResponses.every((r) => r?.success)) {
2146
+ const failed = apiResponses.find((r) => !r?.success);
2147
+ throw new Error(failed?.message || "Failed to create deposit details");
2148
+ }
2149
+ const hashedOnchainIds = apiResponses.map((r) => r.responseObject?.hashedOnchainId);
2150
+ const paymentMethodData = hashedOnchainIds.map((hid) => ({ intentGatingService, payeeDetails: hid, data: "0x" }));
2151
+ params.conversionRates.forEach((group, i) => {
2152
+ const key = params.processorNames[i]?.toLowerCase();
2153
+ const allowed = methods[key]?.currencies?.map((c) => c.toLowerCase());
2154
+ if (allowed && allowed.length) {
2155
+ for (const { currency } of group) {
2156
+ const codeHash = currencyKeccak256(String(currency).toUpperCase()).toLowerCase();
2157
+ if (!allowed.includes(codeHash)) {
2158
+ throw new Error(`Currency ${currency} not supported by ${params.processorNames[i]}. Allowed: ${allowed.join(", ")}`);
2159
+ }
2160
+ }
2161
+ }
2162
+ });
2163
+ const { mapConversionRatesToOnchainMinRate: mapConversionRatesToOnchainMinRate2 } = await Promise.resolve().then(() => (init_currency(), currency_exports));
2164
+ const normalized = params.conversionRates.map((group) => group.map((r) => ({ currency: r.currency, conversionRate: r.conversionRate })));
2165
+ const currencies = mapConversionRatesToOnchainMinRate2(normalized, paymentMethods.length);
2166
+ const args = [{
2167
+ token: params.token,
2168
+ amount: params.amount,
2169
+ intentAmountRange: params.intentAmountRange,
2170
+ paymentMethods,
2171
+ paymentMethodData,
2172
+ currencies,
2173
+ delegate: params.delegate ?? "0x0000000000000000000000000000000000000000",
2174
+ intentGuardian: params.intentGuardian ?? "0x0000000000000000000000000000000000000000",
2175
+ retainOnEmpty: Boolean(params.retainOnEmpty ?? false)
2176
+ }];
2177
+ const hash = await this.simulateAndSendWithAttribution({
2178
+ address: this.escrowAddress,
2179
+ abi: this.escrowAbi,
2180
+ functionName: "createDeposit",
2181
+ args,
2182
+ txOverrides: params.txOverrides
2183
+ });
2184
+ return { depositDetails, hash };
2185
+ }
2186
+ // ╔═══════════════════════════════════════════════════════════════════════════╗
2187
+ // ║ CORE: DEPOSIT MANAGEMENT ║
2188
+ // ╚═══════════════════════════════════════════════════════════════════════════╝
2189
+ /**
2190
+ * Enables or disables a deposit from accepting new intents.
2191
+ *
2192
+ * @param params.depositId - The deposit ID
2193
+ * @param params.accepting - Whether to accept new intents
2194
+ * @param params.txOverrides - Optional viem transaction overrides
2195
+ * @returns Transaction hash
2196
+ */
2197
+ async setAcceptingIntents(params) {
2198
+ return this.simulateAndSendWithAttribution({
2199
+ address: this.escrowAddress,
2200
+ abi: this.escrowAbi,
2201
+ functionName: "setAcceptingIntents",
2202
+ args: [params.depositId, params.accepting],
2203
+ txOverrides: params.txOverrides
2204
+ });
2205
+ }
2206
+ /**
2207
+ * Updates the min/max intent amount range for a deposit.
2208
+ *
2209
+ * @param params.depositId - The deposit ID
2210
+ * @param params.min - Minimum intent amount
2211
+ * @param params.max - Maximum intent amount
2212
+ * @param params.txOverrides - Optional viem transaction overrides
2213
+ * @returns Transaction hash
2214
+ */
2215
+ async setIntentRange(params) {
2216
+ return this.simulateAndSendWithAttribution({
2217
+ address: this.escrowAddress,
2218
+ abi: this.escrowAbi,
2219
+ functionName: "setIntentRange",
2220
+ args: [params.depositId, { min: params.min, max: params.max }],
2221
+ txOverrides: params.txOverrides
2222
+ });
2223
+ }
2224
+ /**
2225
+ * Updates the minimum conversion rate for a specific currency on a payment method.
2226
+ *
2227
+ * @param params.depositId - The deposit ID
2228
+ * @param params.paymentMethod - Payment method hash (bytes32)
2229
+ * @param params.fiatCurrency - Fiat currency hash (bytes32)
2230
+ * @param params.minConversionRate - New minimum conversion rate (18 decimals)
2231
+ * @param params.txOverrides - Optional viem transaction overrides
2232
+ * @returns Transaction hash
2233
+ */
2234
+ async setCurrencyMinRate(params) {
2235
+ return this.simulateAndSendWithAttribution({
2236
+ address: this.escrowAddress,
2237
+ abi: this.escrowAbi,
2238
+ functionName: "setCurrencyMinRate",
2239
+ args: [params.depositId, params.paymentMethod, params.fiatCurrency, params.minConversionRate],
2240
+ txOverrides: params.txOverrides
2241
+ });
2242
+ }
2243
+ /**
2244
+ * Adds additional funds to an existing deposit.
2245
+ * Requires prior approval of the token amount.
2246
+ *
2247
+ * @param params.depositId - The deposit ID to add funds to
2248
+ * @param params.amount - Amount to add (in token units)
2249
+ * @param params.txOverrides - Optional viem transaction overrides
2250
+ * @returns Transaction hash
2251
+ */
2252
+ async addFunds(params) {
2253
+ return this.simulateAndSendWithAttribution({
2254
+ address: this.escrowAddress,
2255
+ abi: this.escrowAbi,
2256
+ functionName: "addFunds",
2257
+ args: [params.depositId, params.amount],
2258
+ txOverrides: params.txOverrides
2259
+ });
2260
+ }
2261
+ /**
2262
+ * Removes funds from a deposit (partial withdrawal).
2263
+ * Can only withdraw available (non-locked) funds.
2264
+ *
2265
+ * @param params.depositId - The deposit ID
2266
+ * @param params.amount - Amount to remove (in token units)
2267
+ * @param params.txOverrides - Optional viem transaction overrides
2268
+ * @returns Transaction hash
2269
+ */
2270
+ async removeFunds(params) {
2271
+ return this.simulateAndSendWithAttribution({
2272
+ address: this.escrowAddress,
2273
+ abi: this.escrowAbi,
2274
+ functionName: "removeFunds",
2275
+ args: [params.depositId, params.amount],
2276
+ txOverrides: params.txOverrides
2277
+ });
2278
+ }
2279
+ /**
2280
+ * Fully withdraws a deposit, returning all available funds to the owner.
2281
+ * The deposit must have no active intents.
2282
+ *
2283
+ * @param params.depositId - The deposit ID to withdraw
2284
+ * @param params.txOverrides - Optional viem transaction overrides
2285
+ * @returns Transaction hash
2286
+ */
2287
+ async withdrawDeposit(params) {
2288
+ return this.simulateAndSendWithAttribution({
2289
+ address: this.escrowAddress,
2290
+ abi: this.escrowAbi,
2291
+ functionName: "withdrawDeposit",
2292
+ args: [params.depositId],
2293
+ txOverrides: params.txOverrides
2294
+ });
2295
+ }
2296
+ // ╔═══════════════════════════════════════════════════════════════════════════╗
2297
+ // ║ CORE: ADVANCED DEPOSIT CONFIGURATION ║
2298
+ // ╚═══════════════════════════════════════════════════════════════════════════╝
2299
+ /**
2300
+ * Sets whether a deposit should remain active when its balance reaches zero.
2301
+ *
2302
+ * @param params.depositId - The deposit ID
2303
+ * @param params.retain - If true, deposit stays active when empty
2304
+ * @param params.txOverrides - Optional viem transaction overrides
2305
+ * @returns Transaction hash
2306
+ */
2307
+ async setRetainOnEmpty(params) {
2308
+ return this.simulateAndSendWithAttribution({
2309
+ address: this.escrowAddress,
2310
+ abi: this.escrowAbi,
2311
+ functionName: "setRetainOnEmpty",
2312
+ args: [params.depositId, params.retain],
2313
+ txOverrides: params.txOverrides
2314
+ });
2315
+ }
2316
+ /**
2317
+ * Assigns a delegate address that can manage the deposit on behalf of the owner.
2318
+ *
2319
+ * @param params.depositId - The deposit ID
2320
+ * @param params.delegate - Address to delegate management to
2321
+ * @param params.txOverrides - Optional viem transaction overrides
2322
+ * @returns Transaction hash
2323
+ */
2324
+ async setDelegate(params) {
2325
+ return this.simulateAndSendWithAttribution({
2326
+ address: this.escrowAddress,
2327
+ abi: this.escrowAbi,
2328
+ functionName: "setDelegate",
2329
+ args: [params.depositId, params.delegate],
2330
+ txOverrides: params.txOverrides
2331
+ });
2332
+ }
2333
+ /**
2334
+ * Removes the delegate from a deposit.
2335
+ *
2336
+ * @param params.depositId - The deposit ID
2337
+ * @param params.txOverrides - Optional viem transaction overrides
2338
+ * @returns Transaction hash
2339
+ */
2340
+ async removeDelegate(params) {
2341
+ return this.simulateAndSendWithAttribution({
2342
+ address: this.escrowAddress,
2343
+ abi: this.escrowAbi,
2344
+ functionName: "removeDelegate",
2345
+ args: [params.depositId],
2346
+ txOverrides: params.txOverrides
2347
+ });
2348
+ }
2349
+ /**
2350
+ * Adds new payment methods to an existing deposit.
2351
+ *
2352
+ * @param params.depositId - The deposit ID
2353
+ * @param params.paymentMethods - Array of payment method hashes to add
2354
+ * @param params.paymentMethodData - Corresponding payment method configuration
2355
+ * @param params.txOverrides - Optional viem transaction overrides
2356
+ * @returns Transaction hash
2357
+ */
2358
+ async addPaymentMethods(params) {
2359
+ return this.simulateAndSendWithAttribution({
2360
+ address: this.escrowAddress,
2361
+ abi: this.escrowAbi,
2362
+ functionName: "addPaymentMethods",
2363
+ args: [params.depositId, params.paymentMethods, params.paymentMethodData],
2364
+ txOverrides: params.txOverrides
2365
+ });
2366
+ }
2367
+ /**
2368
+ * Activates or deactivates a payment method on a deposit.
2369
+ *
2370
+ * @param params.depositId - The deposit ID
2371
+ * @param params.paymentMethod - Payment method hash to modify
2372
+ * @param params.isActive - Whether the payment method should accept intents
2373
+ * @param params.txOverrides - Optional viem transaction overrides
2374
+ * @returns Transaction hash
2375
+ */
2376
+ async setPaymentMethodActive(params) {
2377
+ return this.simulateAndSendWithAttribution({
2378
+ address: this.escrowAddress,
2379
+ abi: this.escrowAbi,
2380
+ functionName: "setPaymentMethodActive",
2381
+ args: [params.depositId, params.paymentMethod, params.isActive],
2382
+ txOverrides: params.txOverrides
2383
+ });
2384
+ }
2385
+ /**
2386
+ * Deactivates a payment method on a deposit (convenience alias for setPaymentMethodActive).
2387
+ *
2388
+ * @param params.depositId - The deposit ID
2389
+ * @param params.paymentMethod - Payment method hash to deactivate
2390
+ * @param params.txOverrides - Optional viem transaction overrides
2391
+ * @returns Transaction hash
2392
+ */
2393
+ async removePaymentMethod(params) {
2394
+ return this.setPaymentMethodActive({ depositId: params.depositId, paymentMethod: params.paymentMethod, isActive: false, txOverrides: params.txOverrides });
2395
+ }
2396
+ /**
2397
+ * Adds new currencies to a payment method on a deposit.
2398
+ *
2399
+ * @param params.depositId - The deposit ID
2400
+ * @param params.paymentMethod - Payment method hash to add currencies to
2401
+ * @param params.currencies - Array of currency configurations with code and min rate
2402
+ * @param params.txOverrides - Optional viem transaction overrides
2403
+ * @returns Transaction hash
2404
+ */
2405
+ async addCurrencies(params) {
2406
+ return this.simulateAndSendWithAttribution({
2407
+ address: this.escrowAddress,
2408
+ abi: this.escrowAbi,
2409
+ functionName: "addCurrencies",
2410
+ args: [params.depositId, params.paymentMethod, params.currencies],
2411
+ txOverrides: params.txOverrides
2412
+ });
2413
+ }
2414
+ /**
2415
+ * Deactivates a currency for a payment method on a deposit.
2416
+ *
2417
+ * @param params.depositId - The deposit ID
2418
+ * @param params.paymentMethod - Payment method hash
2419
+ * @param params.currencyCode - Currency code hash to deactivate
2420
+ * @param params.txOverrides - Optional viem transaction overrides
2421
+ * @returns Transaction hash
2422
+ */
2423
+ async deactivateCurrency(params) {
2424
+ return this.simulateAndSendWithAttribution({
2425
+ address: this.escrowAddress,
2426
+ abi: this.escrowAbi,
2427
+ functionName: "deactivateCurrency",
2428
+ args: [params.depositId, params.paymentMethod, params.currencyCode],
2429
+ txOverrides: params.txOverrides
2430
+ });
2431
+ }
2432
+ /**
2433
+ * Removes (deactivates) a currency from a payment method.
2434
+ * Alias for deactivateCurrency.
2435
+ *
2436
+ * @param params.depositId - The deposit ID
2437
+ * @param params.paymentMethod - Payment method hash
2438
+ * @param params.currencyCode - Currency code hash to remove
2439
+ * @param params.txOverrides - Optional viem transaction overrides
2440
+ * @returns Transaction hash
2441
+ */
2442
+ async removeCurrency(params) {
2443
+ return this.deactivateCurrency(params);
2444
+ }
2445
+ /**
2446
+ * Removes expired intents from a deposit, freeing up locked funds.
2447
+ * Can be called by anyone (permissionless cleanup).
2448
+ *
2449
+ * @param params.depositId - The deposit ID to prune
2450
+ * @param params.txOverrides - Optional viem transaction overrides
2451
+ * @returns Transaction hash
2452
+ */
2453
+ async pruneExpiredIntents(params) {
2454
+ return this.simulateAndSendWithAttribution({
2455
+ address: this.escrowAddress,
2456
+ abi: this.escrowAbi,
2457
+ functionName: "pruneExpiredIntents",
2458
+ args: [params.depositId],
2459
+ txOverrides: params.txOverrides
2460
+ });
2461
+ }
2462
+ // ───────────────────────────────────────────────────────────────────────────
2463
+ // SUPPORTING: INTENT OPERATIONS
2464
+ // (Used by takers/buyers - not primary SDK functionality)
2465
+ // ───────────────────────────────────────────────────────────────────────────
2466
+ /**
2467
+ * **Supporting Method** - Signals intent to use a deposit.
2468
+ *
2469
+ * > **Note**: This method is typically used by takers/buyers who want to
2470
+ * > purchase crypto by paying fiat. Liquidity providers generally don't
2471
+ * > need to call this method directly.
2472
+ *
2473
+ * This reserves funds from a deposit and creates an intent that must be
2474
+ * fulfilled (via `fulfillIntent`) or will expire. The taker commits to
2475
+ * sending fiat payment to the deposit's payee.
2476
+ *
2477
+ * If `gatingServiceSignature` is not provided, the SDK will automatically
2478
+ * fetch one from the API (requires `apiKey` or `authorizationToken`).
2479
+ *
2480
+ * @param params.depositId - The deposit to use
2481
+ * @param params.amount - Amount of tokens to claim (in token units)
2482
+ * @param params.toAddress - Address to receive the tokens when fulfilled
2483
+ * @param params.processorName - Payment platform (e.g., 'wise', 'revolut')
2484
+ * @param params.payeeDetails - Hashed payee details (from deposit)
2485
+ * @param params.fiatCurrencyCode - Fiat currency code (e.g., 'USD', 'EUR')
2486
+ * @param params.conversionRate - Agreed conversion rate (18 decimals)
2487
+ * @param params.referrer - Optional referrer address for fee sharing
2488
+ * @param params.referrerFee - Optional referrer fee amount
2489
+ * @param params.postIntentHook - Optional hook contract to call after signaling
2490
+ * @param params.data - Optional data to pass to the hook
2491
+ * @param params.gatingServiceSignature - Pre-obtained signature (if not auto-fetching)
2492
+ * @param params.signatureExpiration - Signature expiration timestamp
2493
+ * @param params.txOverrides - Optional viem transaction overrides
2494
+ * @returns Transaction hash
2495
+ *
2496
+ * @example
2497
+ * ```typescript
2498
+ * const hash = await client.signalIntent({
2499
+ * depositId: 42n,
2500
+ * amount: 100_000000n, // 100 USDC
2501
+ * toAddress: '0x...',
2502
+ * processorName: 'wise',
2503
+ * payeeDetails: '0x...',
2504
+ * fiatCurrencyCode: 'USD',
2505
+ * conversionRate: 1_020000000000000000n, // 1.02
2506
+ * });
2507
+ * ```
2508
+ */
2509
+ async signalIntent(params) {
2510
+ if (!this.orchestratorAddress || !this.orchestratorAbi) throw new Error("Orchestrator not available");
2511
+ const catalog = getPaymentMethodsCatalog(this.chainId, this.runtimeEnv);
2512
+ const paymentMethod = resolvePaymentMethodHashFromCatalog(params.processorName, catalog);
2513
+ const fiatCurrency = resolveFiatCurrencyBytes32(params.fiatCurrencyCode);
2514
+ const depositId = typeof params.depositId === "bigint" ? params.depositId : BigInt(params.depositId);
2515
+ const amount = typeof params.amount === "bigint" ? params.amount : BigInt(params.amount);
2516
+ const conversionRate = typeof params.conversionRate === "bigint" ? params.conversionRate : BigInt(params.conversionRate);
2517
+ const referrerFee = params.referrerFee === void 0 ? 0n : typeof params.referrerFee === "bigint" ? params.referrerFee : BigInt(params.referrerFee);
2518
+ let { gatingServiceSignature, signatureExpiration } = params;
2519
+ if ((!gatingServiceSignature || !signatureExpiration) && this.baseApiUrl && (this.apiKey || this.authorizationToken)) {
2520
+ const resp = await apiSignIntentV2(
2521
+ {
2522
+ processorName: params.processorName,
2523
+ payeeDetails: params.payeeDetails,
2524
+ depositId: depositId.toString(),
2525
+ amount: amount.toString(),
2526
+ toAddress: params.toAddress,
2527
+ paymentMethod,
2528
+ fiatCurrency,
2529
+ conversionRate: conversionRate.toString(),
2530
+ chainId: this.chainId.toString(),
2531
+ orchestratorAddress: this.orchestratorAddress,
2532
+ escrowAddress: this.escrowAddress
2533
+ },
2534
+ { baseApiUrl: this.baseApiUrl, apiKey: this.apiKey, authorizationToken: this.authorizationToken, timeoutMs: this.apiTimeoutMs }
2535
+ );
2536
+ gatingServiceSignature = resp.signature;
2537
+ signatureExpiration = resp.signatureExpiration;
2538
+ }
2539
+ if (!gatingServiceSignature || !signatureExpiration) throw new Error("Missing gatingServiceSignature/signatureExpiration");
2540
+ const args = [{
2541
+ escrow: this.escrowAddress,
2542
+ depositId,
2543
+ amount,
2544
+ to: params.toAddress,
2545
+ paymentMethod,
2546
+ fiatCurrency,
2547
+ conversionRate,
2548
+ referrer: params.referrer ?? "0x0000000000000000000000000000000000000000",
2549
+ referrerFee,
2550
+ gatingServiceSignature,
2551
+ signatureExpiration: typeof signatureExpiration === "bigint" ? signatureExpiration : BigInt(signatureExpiration),
2552
+ postIntentHook: params.postIntentHook ?? "0x0000000000000000000000000000000000000000",
2553
+ data: params.data ?? "0x"
2554
+ }];
2555
+ return this.simulateAndSendWithAttribution({
2556
+ address: this.orchestratorAddress,
2557
+ abi: this.orchestratorAbi,
2558
+ functionName: "signalIntent",
2559
+ args,
2560
+ txOverrides: params.txOverrides
2561
+ });
2562
+ }
2563
+ /**
2564
+ * **Supporting Method** - Cancels a signaled intent before fulfillment.
2565
+ *
2566
+ * Only the intent owner can cancel. Releases reserved funds back to the deposit.
2567
+ *
2568
+ * @param params.intentHash - The intent hash to cancel (0x-prefixed, 32 bytes)
2569
+ * @param params.txOverrides - Optional viem transaction overrides
2570
+ * @returns Transaction hash
2571
+ */
2572
+ async cancelIntent(params) {
2573
+ if (!this.orchestratorAddress || !this.orchestratorAbi) throw new Error("Orchestrator not available");
2574
+ return this.simulateAndSendWithAttribution({
2575
+ address: this.orchestratorAddress,
2576
+ abi: this.orchestratorAbi,
2577
+ functionName: "cancelIntent",
2578
+ args: [params.intentHash],
2579
+ txOverrides: params.txOverrides
2580
+ });
2581
+ }
2582
+ /**
2583
+ * **Supporting Method** - Releases funds back to the deposit owner.
2584
+ *
2585
+ * Called by the deposit owner when they want to reject an intent
2586
+ * (e.g., payment verification failed or intent expired).
2587
+ *
2588
+ * @param params.intentHash - The intent hash (0x-prefixed, 32 bytes)
2589
+ * @param params.txOverrides - Optional viem transaction overrides
2590
+ * @returns Transaction hash
2591
+ */
2592
+ async releaseFundsToPayer(params) {
2593
+ if (!this.orchestratorAddress || !this.orchestratorAbi) throw new Error("Orchestrator not available");
2594
+ return this.simulateAndSendWithAttribution({
2595
+ address: this.orchestratorAddress,
2596
+ abi: this.orchestratorAbi,
2597
+ functionName: "releaseFundsToPayer",
2598
+ args: [params.intentHash],
2599
+ txOverrides: params.txOverrides
2600
+ });
2601
+ }
2602
+ /**
2603
+ * **Supporting Method** - Fulfills an intent by submitting a payment proof.
2604
+ *
2605
+ * > **Note**: This method is typically used by takers/buyers after they've
2606
+ * > sent fiat payment. Liquidity providers generally don't call this directly.
2607
+ *
2608
+ * This is the final step in the off-ramp flow. After the taker has sent
2609
+ * fiat payment, they generate a proof (via the browser extension) and
2610
+ * submit it here. The SDK handles attestation service calls automatically.
2611
+ *
2612
+ * **Flow:**
2613
+ * 1. Intent parameters are derived from the indexer/ProtocolViewer
2614
+ * 2. Proof is sent to the attestation service for verification
2615
+ * 3. Attestation response is encoded and submitted on-chain
2616
+ * 4. Funds are released to the intent's `toAddress`
2617
+ *
2618
+ * @param params.intentHash - The intent hash to fulfill (0x-prefixed, 32 bytes)
2619
+ * @param params.proof - Payment proof from Reclaim (object or JSON string)
2620
+ * @param params.timestampBufferMs - Allowed timestamp variance (default: 300000ms)
2621
+ * @param params.attestationServiceUrl - Override attestation service URL
2622
+ * @param params.verifyingContract - Override verifier contract address
2623
+ * @param params.postIntentHookData - Data to pass to post-intent hook
2624
+ * @param params.txOverrides - Optional viem transaction overrides
2625
+ * @param params.callbacks - Lifecycle callbacks for UI updates
2626
+ * @returns Transaction hash
2627
+ */
2628
+ async fulfillIntent(params) {
2629
+ if (!this.orchestratorAddress || !this.orchestratorAbi) throw new Error("Orchestrator not available");
2630
+ const intentHash = params.intentHash;
2631
+ const attUrl = params.attestationServiceUrl ?? this.defaultAttestationService();
2632
+ const verifyingContract = params.verifyingContract ?? this.unifiedPaymentVerifier;
2633
+ const inputs = await this.getFulfillIntentInputs(intentHash);
2634
+ const amount = inputs.amount;
2635
+ const fiatCurrency = inputs.fiatCurrency;
2636
+ const conversionRate = inputs.conversionRate;
2637
+ const payeeDetails = inputs.payeeDetails;
2638
+ const timestampMs = inputs.intentTimestampMs;
2639
+ const paymentMethodHash = inputs.paymentMethodHash || "0x";
2640
+ const timestampBufferMs = params.timestampBufferMs ?? "300000";
2641
+ const catalog = getPaymentMethodsCatalog(this.chainId, this.runtimeEnv);
2642
+ const { resolvePaymentMethodNameFromHash: resolvePaymentMethodNameFromHash2 } = await Promise.resolve().then(() => (init_paymentResolution(), paymentResolution_exports));
2643
+ const platformName = resolvePaymentMethodNameFromHash2(paymentMethodHash, catalog);
2644
+ if (!platformName) throw new Error("Unknown paymentMethodHash for this network/env; update SDK catalogs.");
2645
+ const { resolvePlatformAttestationConfig: resolvePlatformAttestationConfig2 } = await Promise.resolve().then(() => (init_constants2(), constants_exports));
2646
+ const cfg = resolvePlatformAttestationConfig2(platformName);
2647
+ const platform = cfg.actionPlatform;
2648
+ const actionType = cfg.actionType;
2649
+ const zkTlsProof = typeof params.proof === "string" ? params.proof : JSON.stringify(params.proof);
2650
+ const payload = {
2651
+ proofType: "reclaim",
2652
+ proof: zkTlsProof,
2653
+ chainId: this.chainId,
2654
+ verifyingContract,
2655
+ intent: {
2656
+ intentHash,
2657
+ amount,
2658
+ timestampMs,
2659
+ paymentMethod: paymentMethodHash,
2660
+ fiatCurrency,
2661
+ conversionRate,
2662
+ payeeDetails,
2663
+ timestampBufferMs
2664
+ }
2665
+ };
2666
+ params?.callbacks?.onAttestationStart?.();
2667
+ const att = await apiCreatePaymentAttestation(payload, attUrl, platform, actionType);
2668
+ const paymentProof = encodePaymentAttestation(att);
2669
+ const verificationData = encodeVerifyPaymentData({
2670
+ intentHash,
2671
+ paymentProof,
2672
+ data: encodeAddressAsBytes(att.responseObject.signer)
2673
+ });
2674
+ const args = [{
2675
+ paymentProof,
2676
+ intentHash,
2677
+ verificationData,
2678
+ postIntentHookData: params.postIntentHookData ?? "0x"
2679
+ }];
2680
+ const txHash = await this.simulateAndSendWithAttribution({
2681
+ address: this.orchestratorAddress,
2682
+ abi: this.orchestratorAbi,
2683
+ functionName: "fulfillIntent",
2684
+ args,
2685
+ txOverrides: params.txOverrides
2686
+ });
2687
+ params?.callbacks?.onTxSent?.(txHash);
2688
+ return txHash;
2689
+ }
2690
+ defaultAttestationService() {
2691
+ return this.runtimeEnv === "staging" ? "https://attestation-service-staging.zkp2p.xyz" : "https://attestation-service.zkp2p.xyz";
2692
+ }
2693
+ // ───────────────────────────────────────────────────────────────────────────
2694
+ // SUPPORTING: QUOTES API
2695
+ // (Used by frontends to find available liquidity)
2696
+ // ───────────────────────────────────────────────────────────────────────────
2697
+ /**
2698
+ * **Supporting Method** - Fetches quotes for available liquidity.
2699
+ *
2700
+ * > **Note**: This method is typically used by frontend applications to
2701
+ * > display available off-ramp options to users. Liquidity providers can
2702
+ * > use it to see how their deposits appear to takers.
2703
+ *
2704
+ * Returns available quotes from liquidity providers matching the request
2705
+ * criteria. When authenticated, the API returns payee details in each quote.
2706
+ *
2707
+ * @param req - Quote request parameters
2708
+ * @param req.paymentPlatforms - Payment platforms to search (e.g., ['wise', 'revolut'])
2709
+ * @param req.fiatCurrency - Target fiat currency code (e.g., 'USD')
2710
+ * @param req.user - User's address
2711
+ * @param req.recipient - Token recipient address
2712
+ * @param req.destinationChainId - Chain ID for token delivery
2713
+ * @param req.destinationToken - Token address to receive
2714
+ * @param req.amount - Amount (in fiat if isExactFiat, else in tokens)
2715
+ * @param req.isExactFiat - If true, amount is in fiat; quotes return token amounts
2716
+ * @param req.escrowAddresses - Optional filter for specific escrow contracts
2717
+ * @param opts - Optional overrides for API URL and timeout
2718
+ * @returns Quote response with available options
2719
+ *
2720
+ * @example
2721
+ * ```typescript
2722
+ * const quote = await client.getQuote({
2723
+ * paymentPlatforms: ['wise'],
2724
+ * fiatCurrency: 'EUR',
2725
+ * user: '0x...',
2726
+ * recipient: '0x...',
2727
+ * destinationChainId: 8453,
2728
+ * destinationToken: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913',
2729
+ * amount: '100',
2730
+ * isExactFiat: true,
2731
+ * });
2732
+ *
2733
+ * for (const q of quote.responseObject.quotes) {
2734
+ * console.log(`${q.tokenAmountFormatted} USDC for ${q.fiatAmountFormatted}`);
2735
+ * }
2736
+ * ```
2737
+ */
2738
+ async getQuote(req, opts) {
2739
+ const baseApiUrl = (opts?.baseApiUrl ?? this.baseApiUrl ?? "https://api.zkp2p.xyz").replace(/\/$/, "");
2740
+ const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
2741
+ const reqWithEscrow = { ...req };
2742
+ if ((!reqWithEscrow.escrowAddresses || reqWithEscrow.escrowAddresses.length === 0) && this.escrowAddress) {
2743
+ reqWithEscrow.escrowAddresses = [this.escrowAddress];
2744
+ }
2745
+ const quote = await apiGetQuote(reqWithEscrow, baseApiUrl, timeoutMs, this.apiKey, this.authorizationToken);
2746
+ const quotes = quote?.responseObject?.quotes ?? [];
2747
+ for (const q of quotes) {
2748
+ const maker = q?.maker;
2749
+ if (maker?.depositData && typeof q === "object") {
2750
+ q.payeeData = maker.depositData;
2751
+ }
2752
+ }
2753
+ return quote;
2754
+ }
2755
+ // ───────────────────────────────────────────────────────────────────────────
2756
+ // SUPPORTING: TAKER TIER
2757
+ // (Used by frontends to display taker limits)
2758
+ // ───────────────────────────────────────────────────────────────────────────
2759
+ /**
2760
+ * **Supporting Method** - Fetches taker tier information for an address.
2761
+ *
2762
+ * > **Note**: Requires `apiKey` or `authorizationToken` to be set.
2763
+ *
2764
+ * @param req - Taker tier request parameters
2765
+ * @param req.owner - Taker address
2766
+ * @param req.chainId - Chain ID
2767
+ * @param opts - Optional overrides for API URL and timeout
2768
+ * @returns Taker tier response
2769
+ */
2770
+ async getTakerTier(req, opts) {
2771
+ const baseApiUrl = (opts?.baseApiUrl ?? this.baseApiUrl ?? "https://api.zkp2p.xyz").replace(/\/$/, "");
2772
+ const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
2773
+ if (!this.apiKey && !this.authorizationToken) {
2774
+ throw new Error("getTakerTier requires apiKey or authorizationToken");
2775
+ }
2776
+ return apiGetTakerTier(req, this.apiKey, baseApiUrl, this.authorizationToken, timeoutMs);
2777
+ }
2778
+ // ╔═══════════════════════════════════════════════════════════════════════════╗
2779
+ // ║ CORE: ON-CHAIN DEPOSIT VIEWS ║
2780
+ // ╚═══════════════════════════════════════════════════════════════════════════╝
2781
+ requireProtocolViewer() {
2782
+ if (!this.protocolViewerAddress || !this.protocolViewerAbi) {
2783
+ throw new Error("ProtocolViewer not available for this network");
2784
+ }
2785
+ return { address: this.protocolViewerAddress, abi: this.protocolViewerAbi };
2786
+ }
2787
+ /**
2788
+ * Fetches a deposit directly from on-chain ProtocolViewer contract.
2789
+ * Falls back to Escrow.getDeposit if ProtocolViewer is unavailable.
2790
+ *
2791
+ * @param depositId - The deposit ID (string or bigint)
2792
+ * @returns Parsed deposit view with all payment methods and currencies
2793
+ */
2794
+ async getPvDepositById(depositId) {
2795
+ const id = typeof depositId === "bigint" ? depositId : BigInt(depositId);
2796
+ try {
2797
+ const { address, abi } = this.requireProtocolViewer();
2798
+ const raw = await this.publicClient.readContract({ address, abi, functionName: "getDeposit", args: [id] });
2799
+ const { parseDepositView: parseDepositView2 } = await Promise.resolve().then(() => (init_protocolViewerParsers(), protocolViewerParsers_exports));
2800
+ return parseDepositView2(raw);
2801
+ } catch (e) {
2802
+ const raw = await this.publicClient.readContract({ address: this.escrowAddress, abi: this.escrowAbi, functionName: "getDeposit", args: [id] });
2803
+ const { parseDepositView: parseDepositView2 } = await Promise.resolve().then(() => (init_protocolViewerParsers(), protocolViewerParsers_exports));
2804
+ return parseDepositView2(raw);
2805
+ }
2806
+ }
2807
+ /**
2808
+ * Fetches multiple deposits by ID from on-chain in a batch call.
2809
+ *
2810
+ * @param ids - Array of deposit IDs
2811
+ * @returns Array of parsed deposit views
2812
+ */
2813
+ async getPvDepositsFromIds(ids) {
2814
+ if (!this.protocolViewerAddress || !this.protocolViewerAbi) {
2815
+ const { parseDepositView: parseDepositView3 } = await Promise.resolve().then(() => (init_protocolViewerParsers(), protocolViewerParsers_exports));
2816
+ const results = [];
2817
+ for (const id of ids) {
2818
+ const raw2 = await this.publicClient.readContract({
2819
+ address: this.escrowAddress,
2820
+ abi: this.escrowAbi,
2821
+ functionName: "getDeposit",
2822
+ args: [typeof id === "bigint" ? id : BigInt(id)]
2823
+ });
2824
+ results.push(parseDepositView3(raw2));
2825
+ }
2826
+ return results;
2827
+ }
2828
+ const bn = ids.map((id) => typeof id === "bigint" ? id : BigInt(id));
2829
+ const raw = await this.publicClient.readContract({
2830
+ address: this.protocolViewerAddress,
2831
+ abi: this.protocolViewerAbi,
2832
+ functionName: "getDepositFromIds",
2833
+ args: [bn]
2834
+ });
2835
+ const { parseDepositView: parseDepositView2 } = await Promise.resolve().then(() => (init_protocolViewerParsers(), protocolViewerParsers_exports));
2836
+ return raw.map(parseDepositView2);
2837
+ }
2838
+ /**
2839
+ * Fetches all deposits owned by an address from on-chain.
2840
+ *
2841
+ * @param owner - The owner address
2842
+ * @returns Array of parsed deposit views
2843
+ */
2844
+ async getPvAccountDeposits(owner) {
2845
+ try {
2846
+ const { address, abi } = this.requireProtocolViewer();
2847
+ const raw = await this.publicClient.readContract({ address, abi, functionName: "getAccountDeposits", args: [owner] });
2848
+ const { parseDepositView: parseDepositView2 } = await Promise.resolve().then(() => (init_protocolViewerParsers(), protocolViewerParsers_exports));
2849
+ return raw.map(parseDepositView2);
2850
+ } catch (e) {
2851
+ const raw = await this.publicClient.readContract({ address: this.escrowAddress, abi: this.escrowAbi, functionName: "getAccountDeposits", args: [owner] });
2852
+ const { parseDepositView: parseDepositView2 } = await Promise.resolve().then(() => (init_protocolViewerParsers(), protocolViewerParsers_exports));
2853
+ return raw.map(parseDepositView2);
2854
+ }
2855
+ }
2856
+ /**
2857
+ * Fetches all intents created by an address from on-chain.
2858
+ * Requires ProtocolViewer to be available.
2859
+ *
2860
+ * @param owner - The owner address
2861
+ * @returns Array of parsed intent views
2862
+ */
2863
+ async getPvAccountIntents(owner) {
2864
+ const { address, abi } = this.requireProtocolViewer();
2865
+ const raw = await this.publicClient.readContract({
2866
+ address,
2867
+ abi,
2868
+ functionName: "getAccountIntents",
2869
+ args: [owner]
2870
+ });
2871
+ const { parseIntentView: parseIntentView2 } = await Promise.resolve().then(() => (init_protocolViewerParsers(), protocolViewerParsers_exports));
2872
+ return raw.map(parseIntentView2);
2873
+ }
2874
+ /**
2875
+ * Fetches a single intent by hash from on-chain.
2876
+ *
2877
+ * @param intentHash - The intent hash (0x-prefixed, 32 bytes)
2878
+ * @returns Parsed intent view with deposit context
2879
+ */
2880
+ async getPvIntent(intentHash) {
2881
+ const { address, abi } = this.requireProtocolViewer();
2882
+ const raw = await this.publicClient.readContract({
2883
+ address,
2884
+ abi,
2885
+ functionName: "getIntent",
2886
+ args: [intentHash]
2887
+ });
2888
+ const { parseIntentView: parseIntentView2 } = await Promise.resolve().then(() => (init_protocolViewerParsers(), protocolViewerParsers_exports));
2889
+ return parseIntentView2(raw);
2890
+ }
2891
+ // ╔═══════════════════════════════════════════════════════════════════════════╗
2892
+ // ║ CORE: UTILITIES ║
2893
+ // ╚═══════════════════════════════════════════════════════════════════════════╝
2894
+ /**
2895
+ * Returns the USDC token address for the current network (if known).
2896
+ *
2897
+ * @returns USDC address or undefined if not configured
2898
+ */
2899
+ getUsdcAddress() {
2900
+ return this._usdcAddress;
2901
+ }
2902
+ /**
2903
+ * Returns all deployed contract addresses for the current network/environment.
2904
+ *
2905
+ * @returns Object with escrow, orchestrator, protocolViewer, verifier, and USDC addresses
2906
+ */
2907
+ getDeployedAddresses() {
2908
+ return {
2909
+ escrow: this.escrowAddress,
2910
+ orchestrator: this.orchestratorAddress,
2911
+ protocolViewer: this.protocolViewerAddress,
2912
+ unifiedPaymentVerifier: this.unifiedPaymentVerifier,
2913
+ usdc: this._usdcAddress
2914
+ };
2915
+ }
2916
+ /**
2917
+ * Resolves all parameters needed to fulfill an intent.
2918
+ *
2919
+ * Attempts to fetch from ProtocolViewer first (on-chain source of truth),
2920
+ * then falls back to the indexer. This is called internally by `fulfillIntent`
2921
+ * but exposed for advanced use cases.
2922
+ *
2923
+ * @param intentHash - The intent hash to resolve
2924
+ * @returns Intent parameters needed for fulfillment
2925
+ * @throws Error if intent not found or payee details cannot be resolved
2926
+ */
2927
+ async getFulfillIntentInputs(intentHash) {
2928
+ try {
2929
+ if (this.protocolViewerAddress && this.protocolViewerAbi) {
2930
+ const view = await this.getPvIntent(intentHash);
2931
+ const pmHash = view.intent.paymentMethod.toLowerCase();
2932
+ const matched = (view.deposit.paymentMethods || []).find((pm) => pm.paymentMethod?.toLowerCase?.() === pmHash);
2933
+ const payee2 = matched?.verificationData?.payeeDetails;
2934
+ if (payee2) {
2935
+ return {
2936
+ amount: view.intent.amount.toString(),
2937
+ fiatCurrency: view.intent.fiatCurrency,
2938
+ conversionRate: view.intent.conversionRate.toString(),
2939
+ payeeDetails: payee2,
2940
+ intentTimestampMs: (BigInt(view.intent.timestamp) * 1000n).toString(),
2941
+ paymentMethodHash: view.intent.paymentMethod
2942
+ };
2943
+ }
2944
+ }
2945
+ } catch {
2946
+ }
2947
+ const query = (
2948
+ /* GraphQL */
2949
+ `
2950
+ query GetIntentMinimal($hash: String!) {
2951
+ Intent(where: { intentHash: { _eq: $hash } }, limit: 1) {
2952
+ amount
2953
+ fiatCurrency
2954
+ conversionRate
2955
+ paymentMethodHash
2956
+ depositId
2957
+ signalTimestamp
2958
+ }
2959
+ }
2960
+ `
2961
+ );
2962
+ const res = await this._indexerClient.query({
2963
+ query,
2964
+ variables: { hash: intentHash.toLowerCase() }
2965
+ });
2966
+ const rec = res?.Intent?.[0];
2967
+ if (!rec) throw new Error("Intent not found on indexer");
2968
+ if (!rec.signalTimestamp) throw new Error("Intent signal timestamp not found on indexer");
2969
+ const deposit = await this._indexerService.fetchDepositWithRelations(rec.depositId, { includeIntents: false });
2970
+ let payee;
2971
+ const pmHashLower = (rec.paymentMethodHash || "").toLowerCase();
2972
+ for (const pm of deposit?.paymentMethods || []) {
2973
+ if ((pm.paymentMethodHash || "").toLowerCase() === pmHashLower) {
2974
+ payee = pm.payeeDetailsHash;
2975
+ break;
2976
+ }
2977
+ }
2978
+ if (!payee) throw new Error("Payee details not found for intent");
2979
+ return {
2980
+ amount: rec.amount,
2981
+ fiatCurrency: rec.fiatCurrency,
2982
+ conversionRate: rec.conversionRate,
2983
+ payeeDetails: payee,
2984
+ intentTimestampMs: (BigInt(rec.signalTimestamp) * 1000n).toString(),
2985
+ paymentMethodHash: rec.paymentMethodHash || "0x0000000000000000000000000000000000000000000000000000000000000000"
2986
+ };
2987
+ }
2988
+ };
2989
+
2990
+ // src/index.ts
2991
+ init_constants2();
2992
+ init_currency();
2993
+ init_paymentResolution();
2994
+ init_contracts();
2995
+ init_bytes32();
2996
+ init_protocolViewerParsers();
2997
+
2998
+ // src/utils/logger.ts
2999
+ var currentLevel = "info";
3000
+ function setLogLevel(level) {
3001
+ currentLevel = level;
3002
+ }
3003
+ function shouldLog(level) {
3004
+ switch (currentLevel) {
3005
+ case "debug":
3006
+ return true;
3007
+ case "info":
3008
+ return level !== "debug";
3009
+ case "error":
3010
+ return level === "error";
3011
+ default:
3012
+ return true;
3013
+ }
3014
+ }
3015
+ var logger = {
3016
+ debug: (...args) => {
3017
+ if (shouldLog("debug")) {
3018
+ console.log("[DEBUG]", ...args);
3019
+ }
3020
+ },
3021
+ info: (...args) => {
3022
+ if (shouldLog("info")) {
3023
+ console.log("[INFO]", ...args);
3024
+ }
3025
+ },
3026
+ warn: (...args) => {
3027
+ if (shouldLog("info")) {
3028
+ console.warn("[WARN]", ...args);
3029
+ }
3030
+ },
3031
+ error: (...args) => {
3032
+ console.error("[ERROR]", ...args);
3033
+ }
3034
+ };
3035
+
3036
+ // src/index.ts
3037
+ init_errors();
3038
+
3039
+ exports.BASE_BUILDER_CODE = BASE_BUILDER_CODE;
3040
+ exports.IndexerClient = IndexerClient;
3041
+ exports.IndexerDepositService = IndexerDepositService;
3042
+ exports.OfframpClient = Zkp2pClient;
3043
+ exports.ZKP2P_ANDROID_REFERRER = ZKP2P_ANDROID_REFERRER;
3044
+ exports.ZKP2P_IOS_REFERRER = ZKP2P_IOS_REFERRER;
3045
+ exports.Zkp2pClient = Zkp2pClient;
3046
+ exports.apiGetPayeeDetails = apiGetPayeeDetails;
3047
+ exports.apiGetTakerTier = apiGetTakerTier;
3048
+ exports.apiPostDepositDetails = apiPostDepositDetails;
3049
+ exports.apiValidatePayeeDetails = apiValidatePayeeDetails;
3050
+ exports.appendAttributionToCalldata = appendAttributionToCalldata;
3051
+ exports.asciiToBytes32 = asciiToBytes32;
3052
+ exports.convertDepositsForLiquidity = convertDepositsForLiquidity;
3053
+ exports.convertIndexerDepositToEscrowView = convertIndexerDepositToEscrowView;
3054
+ exports.convertIndexerIntentsToEscrowViews = convertIndexerIntentsToEscrowViews;
3055
+ exports.createCompositeDepositId = createCompositeDepositId;
3056
+ exports.defaultIndexerEndpoint = defaultIndexerEndpoint;
3057
+ exports.enrichPvDepositView = enrichPvDepositView;
3058
+ exports.enrichPvIntentView = enrichPvIntentView;
3059
+ exports.ensureBytes32 = ensureBytes32;
3060
+ exports.fetchIndexerFulfillmentAndPayment = fetchFulfillmentAndPayment;
3061
+ exports.getAttributionDataSuffix = getAttributionDataSuffix;
3062
+ exports.getContracts = getContracts;
3063
+ exports.getCurrencyCodeFromHash = getCurrencyCodeFromHash;
3064
+ exports.getCurrencyInfoFromCountryCode = getCurrencyInfoFromCountryCode;
3065
+ exports.getCurrencyInfoFromHash = getCurrencyInfoFromHash;
3066
+ exports.getGatingServiceAddress = getGatingServiceAddress;
3067
+ exports.getPaymentMethodsCatalog = getPaymentMethodsCatalog;
3068
+ exports.isSupportedCurrencyHash = isSupportedCurrencyHash;
3069
+ exports.logger = logger;
3070
+ exports.mapConversionRatesToOnchainMinRate = mapConversionRatesToOnchainMinRate;
3071
+ exports.parseDepositView = parseDepositView;
3072
+ exports.parseIntentView = parseIntentView;
3073
+ exports.resolveFiatCurrencyBytes32 = resolveFiatCurrencyBytes32;
3074
+ exports.resolvePaymentMethodHash = resolvePaymentMethodHash;
3075
+ exports.resolvePaymentMethodHashFromCatalog = resolvePaymentMethodHashFromCatalog;
3076
+ exports.resolvePaymentMethodNameFromHash = resolvePaymentMethodNameFromHash;
3077
+ exports.sendTransactionWithAttribution = sendTransactionWithAttribution;
3078
+ exports.setLogLevel = setLogLevel;
3079
+ //# sourceMappingURL=index.cjs.map
3080
+ //# sourceMappingURL=index.cjs.map