@zkp2p/sdk 0.1.0-rc.8 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +73 -14
  2. package/dist/{chunk-6YLLNF6Q.mjs → chunk-JH74HXTS.mjs} +103 -11
  3. package/dist/chunk-JH74HXTS.mjs.map +1 -0
  4. package/dist/{chunk-456CSWDT.mjs → chunk-YLITJ7SI.mjs} +2 -2
  5. package/dist/{chunk-456CSWDT.mjs.map → chunk-YLITJ7SI.mjs.map} +1 -1
  6. package/dist/{chunk-PQQWQF3C.mjs → chunk-ZFBH4HD7.mjs} +10 -4
  7. package/dist/chunk-ZFBH4HD7.mjs.map +1 -0
  8. package/dist/{currency-5RZ6VCEA.mjs → currency-PKI2EGJD.mjs} +3 -4
  9. package/dist/{currency-5RZ6VCEA.mjs.map → currency-PKI2EGJD.mjs.map} +1 -1
  10. package/dist/index.cjs +3152 -5150
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.mts +73 -34
  13. package/dist/index.d.ts +73 -34
  14. package/dist/index.mjs +2553 -1604
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/protocolViewerParsers-QVG4JP23.mjs +4 -0
  17. package/dist/{protocolViewerParsers-EUBHHIPL.mjs.map → protocolViewerParsers-QVG4JP23.mjs.map} +1 -1
  18. package/dist/react.cjs.map +1 -1
  19. package/dist/react.d.mts +3 -2
  20. package/dist/react.d.ts +3 -2
  21. package/dist/react.mjs +2 -2
  22. package/dist/{vaultUtils-CZKrvm9v.d.mts → vaultUtils-J1WboG1T.d.mts} +123 -228
  23. package/dist/{vaultUtils-CZKrvm9v.d.ts → vaultUtils-J1WboG1T.d.ts} +123 -228
  24. package/package.json +10 -3
  25. package/dist/chunk-37HJPVJE.mjs +0 -11
  26. package/dist/chunk-37HJPVJE.mjs.map +0 -1
  27. package/dist/chunk-6YLLNF6Q.mjs.map +0 -1
  28. package/dist/chunk-E5SYWOUK.mjs +0 -231
  29. package/dist/chunk-E5SYWOUK.mjs.map +0 -1
  30. package/dist/chunk-F7USDS7O.mjs +0 -408
  31. package/dist/chunk-F7USDS7O.mjs.map +0 -1
  32. package/dist/chunk-PQQWQF3C.mjs.map +0 -1
  33. package/dist/constants-YK56UVLH.mjs +0 -5
  34. package/dist/constants-YK56UVLH.mjs.map +0 -1
  35. package/dist/paymentResolution-3TC4HRHU.mjs +0 -4
  36. package/dist/paymentResolution-3TC4HRHU.mjs.map +0 -1
  37. package/dist/protocolViewerParsers-EUBHHIPL.mjs +0 -6
package/dist/index.mjs CHANGED
@@ -1,20 +1,26 @@
1
- export { ZERO_RATE_MANAGER_ID, classifyDelegationState, getDelegationRoute, isZeroRateManagerId, normalizeRateManagerId, normalizeRegistry } from './chunk-456CSWDT.mjs';
1
+ export { ZERO_RATE_MANAGER_ID, classifyDelegationState, getDelegationRoute, isZeroRateManagerId, normalizeRateManagerId, normalizeRegistry } from './chunk-YLITJ7SI.mjs';
2
2
  import { ValidationError, NetworkError, APIError } from './chunk-GHQK65J2.mjs';
3
3
  export { APIError, ContractError, ErrorCode, NetworkError, ValidationError, ZKP2PError } from './chunk-GHQK65J2.mjs';
4
- export { CHAINLINK_ORACLE_ADAPTER, CHAINLINK_ORACLE_FEEDS, DEFAULT_ORACLE_MAX_STALENESS_SECONDS, PAYMENT_PLATFORMS, PLATFORM_METADATA, PYTH_ORACLE_ADAPTER, PYTH_ORACLE_FEEDS, SPREAD_ORACLE_FEEDS, SUPPORTED_CHAIN_IDS, TOKEN_METADATA, encodePythAdapterConfig, encodeSpreadOracleAdapterConfig, getSpreadOracleConfig } from './chunk-F7USDS7O.mjs';
5
- import { getContracts, getRateManagerContracts, parseBigIntLike, getPaymentMethodsCatalog, getGatingServiceAddress } from './chunk-6YLLNF6Q.mjs';
6
- export { HISTORICAL_ESCROW_ADDRESSES, enrichPvDepositView, enrichPvIntentView, getContracts, getGatingServiceAddress, getPaymentMethodsCatalog, getRateManagerContracts, parseDepositView, parseIntentView } from './chunk-6YLLNF6Q.mjs';
7
- import { resolvePaymentMethodHashFromCatalog, resolveFiatCurrencyBytes32 } from './chunk-E5SYWOUK.mjs';
8
- export { asciiToBytes32, ensureBytes32, resolveFiatCurrencyBytes32, resolvePaymentMethodHash, resolvePaymentMethodHashFromCatalog, resolvePaymentMethodNameFromHash } from './chunk-E5SYWOUK.mjs';
9
- export { Currency, currencyInfo, getCurrencyCodeFromHash, getCurrencyInfoFromCountryCode, getCurrencyInfoFromHash, isSupportedCurrencyHash, mapConversionRatesToOnchainMinRate } from './chunk-PQQWQF3C.mjs';
10
- import { currencyKeccak256 } from './chunk-37HJPVJE.mjs';
11
- import { concatHex, encodeFunctionData, createPublicClient, http } from 'viem';
4
+ import { getContracts, getRateManagerContracts, getPaymentMethodsCatalog, resolvePaymentMethodHashFromCatalog, getGatingServiceAddress, parseBigIntLike, resolveFiatCurrencyBytes32, resolvePaymentMethodNameFromHash } from './chunk-JH74HXTS.mjs';
5
+ export { HISTORICAL_ESCROW_ADDRESSES, asciiToBytes32, enrichPvDepositView, enrichPvIntentView, ensureBytes32, getContracts, getGatingServiceAddress, getPaymentMethodsCatalog, getRateManagerContracts, parseDepositView, parseIntentView, resolveFiatCurrencyBytes32, resolvePaymentMethodHash, resolvePaymentMethodHashFromCatalog, resolvePaymentMethodNameFromHash } from './chunk-JH74HXTS.mjs';
6
+ import { Currency, currencyKeccak256 } from './chunk-ZFBH4HD7.mjs';
7
+ export { Currency, currencyInfo, getCurrencyCodeFromHash, getCurrencyInfoFromCountryCode, getCurrencyInfoFromHash, isSupportedCurrencyHash, mapConversionRatesToOnchainMinRate } from './chunk-ZFBH4HD7.mjs';
8
+ import { concatHex, encodeFunctionData, encodeAbiParameters, createPublicClient, http, formatUnits } from 'viem';
12
9
  import { hardhat, base } from 'viem/chains';
13
10
  import { AbiCoder } from 'ethers';
14
11
  import { Attribution } from 'ox/erc8021';
12
+ import chainlinkFeeds from '@zkp2p/contracts-v2/oracleFeeds/chainlink.json';
15
13
 
16
- // src/client/ContractRouter.ts
17
- var isSameAddress = (left, right) => !!left && !!right && left.toLowerCase() === right.toLowerCase();
14
+ // src/client/clientUtils.ts
15
+ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
16
+ var MIN_ORACLE_SPREAD_BPS = -32768;
17
+ var MAX_ORACLE_SPREAD_BPS = 32767;
18
+ var EMPTY_ORACLE_RATE_CONFIG = {
19
+ adapter: ZERO_ADDRESS,
20
+ adapterConfig: "0x",
21
+ spreadBps: 0,
22
+ maxStaleness: 0
23
+ };
18
24
  var isValidHexAddress = (addr) => {
19
25
  if (typeof addr !== "string") return false;
20
26
  return /^0x[0-9a-fA-F]{40}$/.test(addr);
@@ -30,6 +36,106 @@ var parseEscrowAddressFromCompositeDepositId = (depositId) => {
30
36
  const maybeEscrow = parts.length >= 3 ? parts[parts.length - 2] : parts[0];
31
37
  return normalizeAddress(maybeEscrow);
32
38
  };
39
+ var parseRawDepositId = (depositId) => {
40
+ if (typeof depositId === "bigint") return depositId;
41
+ if (typeof depositId === "number") return parseBigIntLike(depositId, "Invalid deposit id");
42
+ const parts = depositId.split("_");
43
+ const raw = parts[parts.length - 1] ?? depositId;
44
+ return parseBigIntLike(raw, "Invalid deposit id");
45
+ };
46
+ var normalizeOracleRateConfig = (config) => {
47
+ const spreadBps = Number(config.spreadBps);
48
+ if (!Number.isFinite(spreadBps) || spreadBps < MIN_ORACLE_SPREAD_BPS || spreadBps > MAX_ORACLE_SPREAD_BPS) {
49
+ throw new Error(
50
+ `Oracle spreadBps must be between ${MIN_ORACLE_SPREAD_BPS} and ${MAX_ORACLE_SPREAD_BPS}`
51
+ );
52
+ }
53
+ const maxStaleness = Number(config.maxStaleness);
54
+ if (!Number.isFinite(maxStaleness) || maxStaleness < 0 || maxStaleness > 4294967295) {
55
+ throw new Error("Oracle maxStaleness must be between 0 and 4294967295");
56
+ }
57
+ return {
58
+ adapter: config.adapter,
59
+ adapterConfig: config.adapterConfig,
60
+ spreadBps: Math.round(spreadBps),
61
+ maxStaleness: Math.round(maxStaleness)
62
+ };
63
+ };
64
+ var escrowCurrencyHasOracleConfig = (abi) => {
65
+ if (!Array.isArray(abi)) return false;
66
+ const fnNames = ["createDeposit", "addPaymentMethods", "addCurrencies"];
67
+ for (const fnName of fnNames) {
68
+ const fn = abi.find(
69
+ (item) => item.type === "function" && item.name === fnName
70
+ );
71
+ if (!fn) continue;
72
+ const inputs = fn.inputs ?? [];
73
+ const hasCurrencyOracle = (items) => {
74
+ for (const item of items) {
75
+ const components = item.components ?? [];
76
+ if (components.some((component) => component.name === "code") && components.some((component) => component.name === "oracleRateConfig")) {
77
+ return true;
78
+ }
79
+ if (components.length > 0 && hasCurrencyOracle(components)) return true;
80
+ }
81
+ return false;
82
+ };
83
+ if (hasCurrencyOracle(inputs)) return true;
84
+ }
85
+ return false;
86
+ };
87
+ var normalizeCurrencyTuples = (currencies, escrowAbi) => {
88
+ const needsOracle = escrowCurrencyHasOracleConfig(escrowAbi);
89
+ if (!needsOracle) {
90
+ return currencies.map((currency) => ({
91
+ code: currency.code,
92
+ minConversionRate: currency.minConversionRate
93
+ }));
94
+ }
95
+ return currencies.map((currency) => ({
96
+ code: currency.code,
97
+ minConversionRate: currency.minConversionRate,
98
+ oracleRateConfig: currency.oracleRateConfig ? normalizeOracleRateConfig(currency.oracleRateConfig) : EMPTY_ORACLE_RATE_CONFIG
99
+ }));
100
+ };
101
+ var getAbiFunction = (abi, ...names) => {
102
+ if (!Array.isArray(abi)) return null;
103
+ for (const name of names) {
104
+ const match = abi.find(
105
+ (item) => item.type === "function" && item.name === name
106
+ );
107
+ if (match) return match;
108
+ }
109
+ return null;
110
+ };
111
+ var resolveAbiFunctionName = (abi, names) => {
112
+ const match = getAbiFunction(abi, ...names);
113
+ const resolved = match?.name;
114
+ if (typeof resolved === "string") return resolved;
115
+ throw new Error(`Contract does not expose any of: ${names.join(", ")}`);
116
+ };
117
+ var abiTupleHasComponent = (abi, functionName, componentName) => {
118
+ const fn = getAbiFunction(abi, functionName);
119
+ const inputs = fn?.inputs ?? [];
120
+ const tupleInput = inputs.find((input) => input.type === "tuple");
121
+ const components = tupleInput?.components ?? [];
122
+ return components.some((component) => component.name === componentName);
123
+ };
124
+ var abiFunctionHasInput = (abi, functionName, inputName) => {
125
+ const fn = getAbiFunction(abi, functionName);
126
+ const inputs = fn?.inputs ?? [];
127
+ return inputs.some((input) => input.name === inputName);
128
+ };
129
+ var parseManagerFeeFromRead = (result) => {
130
+ if (Array.isArray(result)) {
131
+ const candidate = result.length > 1 ? result[1] : result[0];
132
+ return parseBigIntLike(candidate, "Unexpected numeric response");
133
+ }
134
+ return parseBigIntLike(result, "Unexpected numeric response");
135
+ };
136
+
137
+ // src/client/ContractRouter.ts
138
+ var isSameAddress = (left, right) => !!left && !!right && left.toLowerCase() === right.toLowerCase();
33
139
  var ContractRouter = class {
34
140
  constructor(config) {
35
141
  this._escrowContextsByAddress = /* @__PURE__ */ new Map();
@@ -271,121 +377,2060 @@ var ContractRouter = class {
271
377
  }
272
378
  };
273
379
 
274
- // src/indexer/client.ts
275
- var IndexerHttpError = class extends Error {
276
- constructor(status, statusText, options) {
277
- super(`Indexer request failed: ${status} ${statusText}`);
278
- this.name = "IndexerHttpError";
279
- this.status = status;
280
- this.retryAfterSeconds = options?.retryAfterSeconds;
380
+ // src/errors/utils.ts
381
+ function parseAPIError(response, responseText) {
382
+ let message = `Request failed: ${response.statusText}`;
383
+ try {
384
+ const parsed = responseText ? JSON.parse(responseText) : void 0;
385
+ if (parsed && (parsed.error || parsed.message)) {
386
+ message = parsed.error || parsed.message;
387
+ }
388
+ } catch {
389
+ if (responseText && responseText.length < 200) message = responseText;
281
390
  }
282
- };
283
- function parseRetryAfterSeconds(rawHeader) {
284
- if (!rawHeader) return void 0;
285
- const parsedSeconds = Number(rawHeader);
286
- if (Number.isFinite(parsedSeconds) && parsedSeconds >= 0) {
287
- return Math.ceil(parsedSeconds);
391
+ if (response.status === 429) {
392
+ message = "Too many requests. Please try again later.";
288
393
  }
289
- const parsedDateMs = Date.parse(rawHeader);
290
- if (!Number.isFinite(parsedDateMs)) return void 0;
291
- const secondsUntilRetry = Math.ceil((parsedDateMs - Date.now()) / 1e3);
292
- return Math.max(0, secondsUntilRetry);
293
- }
294
- function createAbortError() {
295
- const error = new Error("The operation was aborted");
296
- error.name = "AbortError";
297
- return error;
394
+ return new APIError(message, response.status, { url: response.url });
298
395
  }
299
- function delay(ms, signal) {
300
- if (ms <= 0) {
301
- return Promise.resolve();
302
- }
303
- return new Promise((resolve, reject) => {
304
- if (signal?.aborted) {
305
- reject(createAbortError());
306
- return;
396
+ async function withRetry(fn, maxRetries = 3, delayMs = 1e3, timeoutMs) {
397
+ let lastErr;
398
+ for (let i = 0; i < maxRetries; i++) {
399
+ try {
400
+ if (timeoutMs) {
401
+ const { withTimeout } = await import('./timeout-QB7K5SOB.mjs');
402
+ return await withTimeout(fn(), timeoutMs, `Operation timed out after ${timeoutMs}ms`);
403
+ }
404
+ return await fn();
405
+ } catch (err) {
406
+ lastErr = err;
407
+ const isNetwork = err instanceof NetworkError;
408
+ const isRateLimit = err instanceof APIError && err.status === 429;
409
+ const retryable = isNetwork || isRateLimit;
410
+ if (!retryable || i === maxRetries - 1) throw err;
411
+ const base2 = isRateLimit ? delayMs * Math.pow(2, i) : delayMs;
412
+ const jitter = Math.floor(Math.random() * Math.min(1e3, base2));
413
+ await new Promise((r) => setTimeout(r, base2 + jitter));
307
414
  }
308
- const timer = setTimeout(() => {
309
- signal?.removeEventListener("abort", onAbort);
310
- resolve();
311
- }, ms);
312
- const onAbort = () => {
313
- clearTimeout(timer);
314
- signal?.removeEventListener("abort", onAbort);
315
- reject(createAbortError());
316
- };
317
- signal?.addEventListener("abort", onAbort);
318
- });
319
- }
320
- var IndexerClient = class {
321
- constructor(endpoint, options = {}) {
322
- this.endpoint = endpoint;
323
- this.options = options;
324
- this.hasLoggedTokenProviderError = false;
325
415
  }
326
- async resolveAuthorizationToken() {
327
- if (this.options.getAuthorizationToken) {
416
+ throw lastErr;
417
+ }
418
+
419
+ // src/adapters/verification.ts
420
+ function createHeaders(apiKey, authorizationToken) {
421
+ const headers2 = { "Content-Type": "application/json" };
422
+ if (apiKey) headers2["x-api-key"] = apiKey;
423
+ if (authorizationToken)
424
+ headers2["Authorization"] = authorizationToken.startsWith("Bearer ") ? authorizationToken : `Bearer ${authorizationToken}`;
425
+ return headers2;
426
+ }
427
+ async function postSignIntentWithRetry(endpoint, request, opts) {
428
+ const url = `${opts.baseApiUrl.replace(/\/$/, "")}${endpoint}`;
429
+ return withRetry(
430
+ async () => {
431
+ let res;
328
432
  try {
329
- const token = await this.options.getAuthorizationToken();
330
- return token ?? void 0;
433
+ res = await fetch(url, {
434
+ method: "POST",
435
+ headers: createHeaders(opts.apiKey, opts.authorizationToken),
436
+ body: JSON.stringify(request)
437
+ });
331
438
  } catch (error) {
332
- if (this.options.onAuthorizationTokenError) {
333
- this.options.onAuthorizationTokenError(error);
334
- } else if (!this.hasLoggedTokenProviderError) {
335
- this.hasLoggedTokenProviderError = true;
336
- console.warn(
337
- "[IndexerClient] getAuthorizationToken failed; continuing without Authorization header",
338
- error
339
- );
340
- }
341
- return void 0;
439
+ throw new NetworkError("Failed to connect to API server", { endpoint, error });
342
440
  }
343
- }
344
- return this.options.authorizationToken;
345
- }
346
- async _post(request, init) {
347
- const token = await this.resolveAuthorizationToken();
348
- const headers2 = new Headers(init?.headers);
349
- if (!headers2.has("Content-Type")) {
350
- headers2.set("Content-Type", "application/json");
351
- }
352
- if (token && !headers2.has("Authorization")) {
353
- headers2.set("Authorization", token.startsWith("Bearer ") ? token : `Bearer ${token}`);
354
- }
355
- if (this.options.apiKey && !headers2.has("x-api-key")) {
356
- headers2.set("x-api-key", this.options.apiKey);
357
- }
358
- const res = await fetch(this.endpoint, {
359
- method: "POST",
360
- headers: headers2,
361
- body: JSON.stringify(request),
362
- cache: "no-store",
363
- ...init
364
- });
365
- if (!res.ok) {
366
- throw new IndexerHttpError(res.status, res.statusText, {
367
- retryAfterSeconds: parseRetryAfterSeconds(res.headers.get("Retry-After"))
441
+ if (!res.ok) {
442
+ const text = await res.text().catch(() => "");
443
+ throw parseAPIError(res, text);
444
+ }
445
+ return await res.json();
446
+ },
447
+ 3,
448
+ 1e3,
449
+ opts.timeoutMs
450
+ );
451
+ }
452
+ async function apiSignIntentV3(request, opts) {
453
+ const json = await postSignIntentWithRetry("/v3/intent", request, opts);
454
+ const sig = json?.responseObject?.signedIntent;
455
+ const expStr = json?.responseObject?.intentData?.signatureExpiration ?? json?.responseObject?.signatureExpiration;
456
+ const preIntentHookData = json?.responseObject?.intentData?.preIntentHookData ?? json?.responseObject?.preIntentHookData;
457
+ if (!sig || !expStr) throw new Error("v3/intent missing signature or expiration");
458
+ return {
459
+ signature: sig,
460
+ signatureExpiration: BigInt(expStr),
461
+ preIntentHookData
462
+ };
463
+ }
464
+ async function apiSignIntentV2(request, opts) {
465
+ const json = await postSignIntentWithRetry(
466
+ "/v2/verify/intent",
467
+ request,
468
+ opts
469
+ );
470
+ const sig = json?.responseObject?.signedIntent;
471
+ const expStr = json?.responseObject?.intentData?.signatureExpiration ?? json?.responseObject?.signatureExpiration;
472
+ const preIntentHookData = json?.responseObject?.intentData?.preIntentHookData ?? json?.responseObject?.preIntentHookData;
473
+ if (!sig || !expStr) throw new Error("verify/intent missing signature or expiration");
474
+ return {
475
+ signature: sig,
476
+ signatureExpiration: BigInt(expStr),
477
+ preIntentHookData
478
+ };
479
+ }
480
+
481
+ // src/adapters/attestation.ts
482
+ function headers() {
483
+ return { "Content-Type": "application/json" };
484
+ }
485
+ async function apiCreatePaymentAttestation(payload, attestationServiceUrl, platform, actionType) {
486
+ return withRetry(async () => {
487
+ let res;
488
+ try {
489
+ const endpoint = `/verify/${encodeURIComponent(platform)}/${encodeURIComponent(actionType)}`;
490
+ res = await fetch(`${attestationServiceUrl}${endpoint}`, {
491
+ method: "POST",
492
+ headers: headers(),
493
+ body: JSON.stringify(payload)
494
+ });
495
+ } catch (error) {
496
+ throw new NetworkError("Failed to connect to Attestation Service", {
497
+ endpoint: `/verify/${platform}/${actionType}`,
498
+ error
368
499
  });
369
500
  }
370
- const json = await res.json();
371
- if (json.errors?.length) {
372
- const msg = json.errors.map((e) => e.message).join(", ");
373
- throw new Error(`GraphQL errors: ${msg}`);
501
+ if (!res.ok) {
502
+ const errorText = await res.text();
503
+ throw parseAPIError(res, errorText);
374
504
  }
375
- if (!json.data) throw new Error("No data returned from indexer");
376
- return json.data;
377
- }
378
- async query(request, init) {
379
- const retries = Math.max(0, init?.retries ?? 1);
380
- const rateLimitRetries = Math.max(0, init?.rateLimitRetries ?? 2);
381
- const maxAttempts = 1 + Math.max(retries, rateLimitRetries);
382
- const {
383
- retries: _unusedRetries,
384
- rateLimitRetries: _unusedRateLimitRetries,
385
- ...requestInit
386
- } = init ?? {};
387
- let attempts = 0;
388
- let rateLimitAttempt = 0;
505
+ return res.json();
506
+ });
507
+ }
508
+ var abiCoder = AbiCoder.defaultAbiCoder();
509
+ function encodeVerifyPaymentData(params) {
510
+ return abiCoder.encode(
511
+ ["tuple(bytes32,bytes,bytes)"],
512
+ [[params.intentHash, params.paymentProof, params.data]]
513
+ );
514
+ }
515
+ function encodeAddressAsBytes(addr) {
516
+ return abiCoder.encode(["address"], [addr]);
517
+ }
518
+ function encodePaymentAttestation(attestation) {
519
+ const resp = attestation.responseObject;
520
+ const td = resp.typedDataValue;
521
+ const intentHash = td.intentHash;
522
+ const releaseAmount = BigInt(td.releaseAmount);
523
+ const dataHash = td.dataHash;
524
+ const signatures = [resp.signature];
525
+ const encodedPaymentDetails = resp.encodedPaymentDetails;
526
+ if (!intentHash || !releaseAmount || !dataHash || !encodedPaymentDetails) {
527
+ throw new Error("Attestation response missing required fields");
528
+ }
529
+ return abiCoder.encode(
530
+ ["tuple(bytes32,uint256,bytes32,bytes[],bytes,bytes)"],
531
+ [[intentHash, releaseAmount, dataHash, signatures, encodedPaymentDetails, "0x"]]
532
+ );
533
+ }
534
+
535
+ // src/referrerFeeConfig.ts
536
+ var evmAddressRegex = /^0x[a-fA-F0-9]{40}$/;
537
+ var isValidReferrerFeeRecipient = (value) => evmAddressRegex.test(value);
538
+ var isValidReferrerFeeBps = (value) => Number.isInteger(value) && value >= 0 && value <= 1e4;
539
+ var assertValidReferrerFeeConfig = (config, context) => {
540
+ if (!config) {
541
+ return void 0;
542
+ }
543
+ if (!isValidReferrerFeeRecipient(config.recipient)) {
544
+ throw new Error(`${context} referrerFeeConfig.recipient must be a valid 0x address.`);
545
+ }
546
+ if (!isValidReferrerFeeBps(config.feeBps)) {
547
+ throw new Error(`${context} referrerFeeConfig.feeBps must be an integer between 0 and 10000.`);
548
+ }
549
+ return config;
550
+ };
551
+ var parseReferrerFeeConfig = (recipient, feeBpsValue) => {
552
+ const normalizedRecipient = recipient?.trim();
553
+ if (!normalizedRecipient || feeBpsValue === null || feeBpsValue === void 0) {
554
+ return null;
555
+ }
556
+ if (!isValidReferrerFeeRecipient(normalizedRecipient)) {
557
+ return null;
558
+ }
559
+ const feeBps = typeof feeBpsValue === "number" ? feeBpsValue : Number(feeBpsValue.trim());
560
+ if (!isValidReferrerFeeBps(feeBps)) {
561
+ return null;
562
+ }
563
+ return {
564
+ recipient: normalizedRecipient,
565
+ feeBps
566
+ };
567
+ };
568
+ var referrerFeeConfigToPreciseUnits = (config) => BigInt(config.feeBps) * 100000000000000n;
569
+ var BASE_BUILDER_CODE = "bc_nbn6qkni";
570
+ var ZKP2P_IOS_REFERRER = "zkp2p-ios";
571
+ var ZKP2P_ANDROID_REFERRER = "zkp2p-android";
572
+ function getAttributionDataSuffix(referrer) {
573
+ const codes = [];
574
+ if (referrer) {
575
+ if (Array.isArray(referrer)) {
576
+ codes.push(...referrer);
577
+ } else {
578
+ codes.push(referrer);
579
+ }
580
+ }
581
+ codes.push(BASE_BUILDER_CODE);
582
+ return Attribution.toDataSuffix({ codes });
583
+ }
584
+ function appendAttributionToCalldata(calldata, referrer) {
585
+ const suffix = getAttributionDataSuffix(referrer);
586
+ return concatHex([calldata, suffix]);
587
+ }
588
+ function encodeWithAttribution(request, referrer) {
589
+ const functionData = encodeFunctionData({
590
+ abi: request.abi,
591
+ functionName: request.functionName,
592
+ args: request.args || []
593
+ });
594
+ return appendAttributionToCalldata(functionData, referrer);
595
+ }
596
+ async function sendTransactionWithAttribution(walletClient, request, referrer, overrides) {
597
+ const functionData = encodeFunctionData({
598
+ abi: request.abi,
599
+ functionName: request.functionName,
600
+ args: request.args || []
601
+ });
602
+ const dataWithAttribution = appendAttributionToCalldata(functionData, referrer);
603
+ const {
604
+ gas,
605
+ gasPrice,
606
+ maxFeePerGas,
607
+ maxPriorityFeePerGas,
608
+ nonce,
609
+ value,
610
+ accessList,
611
+ authorizationList
612
+ } = overrides ?? {};
613
+ const optionalOverrides = {
614
+ ...gas !== void 0 ? { gas } : {},
615
+ ...gasPrice !== void 0 ? { gasPrice } : {},
616
+ ...maxFeePerGas !== void 0 ? { maxFeePerGas } : {},
617
+ ...maxPriorityFeePerGas !== void 0 ? { maxPriorityFeePerGas } : {},
618
+ ...nonce !== void 0 ? { nonce } : {},
619
+ ...accessList !== void 0 ? { accessList } : {},
620
+ ...authorizationList !== void 0 ? { authorizationList } : {}
621
+ };
622
+ return walletClient.sendTransaction({
623
+ to: request.address,
624
+ data: dataWithAttribution,
625
+ value: value ?? request.value,
626
+ account: walletClient.account,
627
+ chain: walletClient.chain,
628
+ ...optionalOverrides
629
+ });
630
+ }
631
+
632
+ // src/types/index.ts
633
+ var PAYMENT_PLATFORMS = [
634
+ "wise",
635
+ "venmo",
636
+ "revolut",
637
+ "cashapp",
638
+ "mercadopago",
639
+ "zelle",
640
+ "paypal",
641
+ "monzo",
642
+ "chime",
643
+ "luxon",
644
+ "n26"
645
+ ];
646
+ var ZERO_ADDRESS2 = "0x0000000000000000000000000000000000000000";
647
+ var CHAINLINK_ORACLE_ADAPTER = "0xfc81d1b5841e697973af3072fc8e03af76cb39ef";
648
+ var PYTH_ORACLE_ADAPTER = "0xaa2bBDa3072bD37af76613846268Ec48bd0bB885";
649
+ var DEFAULT_ORACLE_MAX_STALENESS_SECONDS = 86400;
650
+ var PYTH_CONTRACT_BASE = "0xff1a0f4744e8582DF1aE09D5611b887B6a12925C";
651
+ var CHAINLINK_LATEST_ROUND_ABI = [
652
+ {
653
+ name: "latestRoundData",
654
+ type: "function",
655
+ stateMutability: "view",
656
+ inputs: [],
657
+ outputs: [
658
+ { name: "roundId", type: "uint80" },
659
+ { name: "answer", type: "int256" },
660
+ { name: "startedAt", type: "uint256" },
661
+ { name: "updatedAt", type: "uint256" },
662
+ { name: "answeredInRound", type: "uint80" }
663
+ ]
664
+ }
665
+ ];
666
+ function parseUsdPair(pair) {
667
+ const [base2, quote] = pair.split("/");
668
+ if (!base2 || !quote) return null;
669
+ if (quote === "USD" && Object.prototype.hasOwnProperty.call(Currency, base2)) {
670
+ return { currency: base2, invert: true };
671
+ }
672
+ if (base2 === "USD" && Object.prototype.hasOwnProperty.call(Currency, quote)) {
673
+ return { currency: quote, invert: false };
674
+ }
675
+ return null;
676
+ }
677
+ function buildChainlinkOracleFeeds() {
678
+ const map = {};
679
+ for (const feed of chainlinkFeeds.feeds) {
680
+ const parsed = parseUsdPair(feed.pair);
681
+ if (!parsed) continue;
682
+ map[parsed.currency] = {
683
+ feed: feed.feed.toLowerCase(),
684
+ decimals: feed.decimals,
685
+ invert: parsed.invert
686
+ };
687
+ }
688
+ return map;
689
+ }
690
+ var CHAINLINK_ORACLE_FEEDS = {
691
+ ...buildChainlinkOracleFeeds(),
692
+ [Currency.USD]: {
693
+ feed: ZERO_ADDRESS2,
694
+ decimals: 0,
695
+ invert: false
696
+ }
697
+ };
698
+ var SPREAD_ORACLE_FEEDS = CHAINLINK_ORACLE_FEEDS;
699
+ var PYTH_ORACLE_FEEDS = {};
700
+ function encodeSpreadOracleAdapterConfig(config) {
701
+ return encodeAbiParameters(
702
+ [
703
+ { name: "feed", type: "address" },
704
+ { name: "invert", type: "bool" }
705
+ ],
706
+ [config.feed, config.invert]
707
+ );
708
+ }
709
+ function encodePythAdapterConfig(config) {
710
+ return encodeAbiParameters(
711
+ [
712
+ { name: "feedId", type: "bytes32" },
713
+ { name: "invert", type: "bool" }
714
+ ],
715
+ [config.feedId, config.invert]
716
+ );
717
+ }
718
+ function getSpreadOracleConfig(currency, adapters) {
719
+ const chainlinkAdapter = adapters?.chainlinkOracleAdapter ?? CHAINLINK_ORACLE_ADAPTER;
720
+ const chainlinkFeed = CHAINLINK_ORACLE_FEEDS[currency];
721
+ if (!chainlinkFeed) {
722
+ return null;
723
+ }
724
+ return {
725
+ ...chainlinkFeed,
726
+ adapter: chainlinkAdapter,
727
+ adapterConfig: encodeSpreadOracleAdapterConfig(chainlinkFeed),
728
+ maxStaleness: DEFAULT_ORACLE_MAX_STALENESS_SECONDS,
729
+ kind: "oracle_chainlink"
730
+ };
731
+ }
732
+ async function validateOracleFeedsOnChain(publicClient, _pythContract) {
733
+ const currencies = [];
734
+ const contracts = [];
735
+ for (const [currency, config] of Object.entries(CHAINLINK_ORACLE_FEEDS)) {
736
+ if (config.feed === ZERO_ADDRESS2) continue;
737
+ currencies.push(currency);
738
+ contracts.push({
739
+ address: config.feed,
740
+ abi: CHAINLINK_LATEST_ROUND_ABI,
741
+ functionName: "latestRoundData",
742
+ args: []
743
+ });
744
+ }
745
+ if (contracts.length === 0) return /* @__PURE__ */ new Set([Currency.USD]);
746
+ const results = await publicClient.multicall({
747
+ contracts,
748
+ allowFailure: true
749
+ });
750
+ const available = /* @__PURE__ */ new Set([Currency.USD]);
751
+ for (let i = 0; i < currencies.length; i++) {
752
+ if (results[i].status === "success") {
753
+ available.add(currencies[i]);
754
+ }
755
+ }
756
+ return available;
757
+ }
758
+
759
+ // src/constants.ts
760
+ var SUPPORTED_CHAIN_IDS = {
761
+ /** Base mainnet (8453) */
762
+ BASE_MAINNET: 8453,
763
+ /** Scroll mainnet (534352) */
764
+ SCROLL_MAINNET: 534352,
765
+ /** Local Hardhat network (31337) */
766
+ HARDHAT: 31337
767
+ };
768
+ var PLATFORM_METADATA = {
769
+ venmo: {
770
+ name: "Venmo",
771
+ displayName: "Venmo",
772
+ logo: "\u{1F4B5}",
773
+ requiredProofs: 1
774
+ },
775
+ revolut: {
776
+ name: "Revolut",
777
+ displayName: "Revolut",
778
+ logo: "\u{1F4B3}",
779
+ requiredProofs: 1
780
+ },
781
+ cashapp: {
782
+ name: "CashApp",
783
+ displayName: "Cash App",
784
+ logo: "\u{1F4B8}",
785
+ requiredProofs: 1
786
+ },
787
+ wise: {
788
+ name: "Wise",
789
+ displayName: "Wise",
790
+ logo: "\u{1F30D}",
791
+ requiredProofs: 2
792
+ },
793
+ mercadopago: {
794
+ name: "MercadoPago",
795
+ displayName: "Mercado Pago",
796
+ logo: "\u{1F4B0}",
797
+ requiredProofs: 1
798
+ },
799
+ zelle: {
800
+ name: "Zelle",
801
+ displayName: "Zelle",
802
+ logo: "\u{1F4B2}",
803
+ requiredProofs: 1
804
+ },
805
+ paypal: {
806
+ name: "PayPal",
807
+ displayName: "PayPal",
808
+ logo: "\u{1F499}",
809
+ requiredProofs: 1
810
+ },
811
+ monzo: {
812
+ name: "Monzo",
813
+ displayName: "Monzo",
814
+ logo: "\u{1F3E6}",
815
+ requiredProofs: 1
816
+ },
817
+ chime: {
818
+ name: "Chime",
819
+ displayName: "Chime",
820
+ logo: "\u{1F3E6}",
821
+ requiredProofs: 1
822
+ },
823
+ luxon: {
824
+ name: "Luxon",
825
+ displayName: "Luxon",
826
+ logo: "\u2728",
827
+ requiredProofs: 1
828
+ },
829
+ n26: {
830
+ name: "N26",
831
+ displayName: "N26",
832
+ logo: "\u{1F3E6}",
833
+ requiredProofs: 1
834
+ }
835
+ };
836
+ var TOKEN_METADATA = {
837
+ USDC: {
838
+ symbol: "USDC",
839
+ decimals: 6,
840
+ name: "USD Coin"
841
+ }
842
+ };
843
+ var PLATFORM_ATTESTATION_CONFIG = {
844
+ wise: { actionType: "transfer_wise", actionPlatform: "wise" },
845
+ venmo: { actionType: "transfer_venmo", actionPlatform: "venmo" },
846
+ revolut: { actionType: "transfer_revolut", actionPlatform: "revolut" },
847
+ cashapp: { actionType: "transfer_cashapp", actionPlatform: "cashapp" },
848
+ mercadopago: { actionType: "transfer_mercadopago", actionPlatform: "mercadopago" },
849
+ paypal: { actionType: "transfer_paypal", actionPlatform: "paypal" },
850
+ monzo: { actionType: "transfer_monzo", actionPlatform: "monzo" },
851
+ chime: { actionType: "transfer_chime", actionPlatform: "chime" },
852
+ luxon: { actionType: "transfer_luxon", actionPlatform: "luxon" },
853
+ n26: { actionType: "transfer_n26", actionPlatform: "n26" },
854
+ "zelle-chase": { actionType: "transfer_zelle", actionPlatform: "chase" },
855
+ "zelle-bofa": { actionType: "transfer_zelle", actionPlatform: "bankofamerica" },
856
+ "zelle-citi": { actionType: "transfer_zelle", actionPlatform: "citi" }
857
+ };
858
+ function resolvePlatformAttestationConfig(platformName) {
859
+ const normalized = platformName.toLowerCase();
860
+ const config = PLATFORM_ATTESTATION_CONFIG[normalized];
861
+ if (!config) {
862
+ throw new Error(`Unknown payment platform: ${platformName}`);
863
+ }
864
+ return config;
865
+ }
866
+
867
+ // src/utils/logger.ts
868
+ var currentLevel = "info";
869
+ function setLogLevel(level) {
870
+ currentLevel = level;
871
+ }
872
+ function shouldLog(level) {
873
+ switch (currentLevel) {
874
+ case "debug":
875
+ return true;
876
+ case "info":
877
+ return level !== "debug";
878
+ case "error":
879
+ return level === "error";
880
+ default:
881
+ return true;
882
+ }
883
+ }
884
+ var logger = {
885
+ debug: (...args) => {
886
+ if (shouldLog("debug")) {
887
+ console.log("[DEBUG]", ...args);
888
+ }
889
+ },
890
+ info: (...args) => {
891
+ if (shouldLog("info")) {
892
+ console.log("[INFO]", ...args);
893
+ }
894
+ },
895
+ warn: (...args) => {
896
+ if (shouldLog("info")) {
897
+ console.warn("[WARN]", ...args);
898
+ }
899
+ },
900
+ error: (...args) => {
901
+ console.error("[ERROR]", ...args);
902
+ }
903
+ };
904
+
905
+ // src/client/IntentOperations.ts
906
+ var IntentOperations = class {
907
+ constructor(config) {
908
+ this.config = config;
909
+ }
910
+ async prepareSignalIntent(params) {
911
+ const referrerFeeConfig = assertValidReferrerFeeConfig(
912
+ params.referrerFeeConfig,
913
+ "signalIntent"
914
+ );
915
+ if (referrerFeeConfig && (params.referralFees !== void 0 || params.referrer !== void 0 || params.referrerFee !== void 0)) {
916
+ throw new Error(
917
+ "signalIntent referrerFeeConfig cannot be combined with referralFees, referrer, or referrerFee."
918
+ );
919
+ }
920
+ const preferV2 = this.config.getDefaultPreferV2();
921
+ const escrowContext = this.config.host.resolveEscrowContext({
922
+ escrowAddress: params.escrowAddress,
923
+ depositId: params.depositId,
924
+ preferV2
925
+ });
926
+ const orchestratorContext = await this.config.host.resolveOrchestratorContext({
927
+ orchestratorAddress: params.orchestratorAddress,
928
+ escrowAddress: escrowContext.address,
929
+ preferV2
930
+ });
931
+ const catalog = getPaymentMethodsCatalog(this.config.getChainId(), this.config.getRuntimeEnv());
932
+ const paymentMethod = resolvePaymentMethodHashFromCatalog(params.processorName, catalog);
933
+ const fiatCurrency = resolveFiatCurrencyBytes32(params.fiatCurrencyCode);
934
+ const depositId = parseRawDepositId(params.depositId);
935
+ const amount = typeof params.amount === "bigint" ? params.amount : BigInt(params.amount);
936
+ const conversionRate = typeof params.conversionRate === "bigint" ? params.conversionRate : BigInt(params.conversionRate);
937
+ const referralFees = referrerFeeConfig !== void 0 ? [
938
+ {
939
+ recipient: referrerFeeConfig.recipient,
940
+ fee: referrerFeeConfigToPreciseUnits(referrerFeeConfig)
941
+ }
942
+ ] : normalizeSignalIntentReferralFees(params);
943
+ let { gatingServiceSignature, signatureExpiration } = params;
944
+ let preIntentHookData = params.preIntentHookData;
945
+ const baseApiUrl = this.config.getBaseApiUrl();
946
+ const apiKey = this.config.getApiKey();
947
+ const authorizationToken = this.config.getAuthorizationToken();
948
+ if ((!gatingServiceSignature || !signatureExpiration) && baseApiUrl && (apiKey || authorizationToken)) {
949
+ const baseRequest = {
950
+ processorName: params.processorName,
951
+ payeeDetails: params.payeeDetails,
952
+ depositId: depositId.toString(),
953
+ amount: amount.toString(),
954
+ toAddress: params.toAddress,
955
+ paymentMethod,
956
+ fiatCurrency,
957
+ conversionRate: conversionRate.toString(),
958
+ chainId: this.config.getChainId().toString(),
959
+ orchestratorAddress: orchestratorContext.address,
960
+ escrowAddress: escrowContext.address
961
+ };
962
+ const apiOpts = {
963
+ baseApiUrl,
964
+ apiKey,
965
+ authorizationToken,
966
+ timeoutMs: this.config.getApiTimeoutMs()
967
+ };
968
+ const response = orchestratorContext.version === "v2" ? await apiSignIntentV3(
969
+ {
970
+ ...baseRequest,
971
+ callerAddress: this.config.getWalletClient().account.address,
972
+ referralFees: referralFees.map((referralFee) => ({
973
+ recipient: referralFee.recipient,
974
+ fee: referralFee.fee.toString()
975
+ }))
976
+ },
977
+ apiOpts
978
+ ) : await apiSignIntentV2(baseRequest, apiOpts);
979
+ gatingServiceSignature = response.signature;
980
+ signatureExpiration = response.signatureExpiration;
981
+ preIntentHookData = response.preIntentHookData ?? preIntentHookData;
982
+ }
983
+ if (!gatingServiceSignature || !signatureExpiration) {
984
+ throw new Error("Missing gatingServiceSignature/signatureExpiration");
985
+ }
986
+ const commonFields = {
987
+ escrow: escrowContext.address,
988
+ depositId,
989
+ amount,
990
+ to: params.toAddress,
991
+ paymentMethod,
992
+ fiatCurrency,
993
+ conversionRate,
994
+ gatingServiceSignature,
995
+ signatureExpiration: typeof signatureExpiration === "bigint" ? signatureExpiration : BigInt(signatureExpiration),
996
+ postIntentHook: params.postIntentHook ?? ZERO_ADDRESS,
997
+ data: params.data ?? "0x"
998
+ };
999
+ const args = orchestratorContext.version === "v2" ? [
1000
+ {
1001
+ ...commonFields,
1002
+ referralFees,
1003
+ preIntentHookData: preIntentHookData ?? "0x"
1004
+ }
1005
+ ] : [
1006
+ {
1007
+ ...commonFields,
1008
+ referrer: referralFees[0]?.recipient ?? ZERO_ADDRESS,
1009
+ referrerFee: referralFees[0]?.fee ?? 0n
1010
+ }
1011
+ ];
1012
+ const { referrer } = params.txOverrides ?? {};
1013
+ const data = encodeWithAttribution(
1014
+ {
1015
+ abi: orchestratorContext.abi,
1016
+ functionName: "signalIntent",
1017
+ args
1018
+ },
1019
+ referrer
1020
+ );
1021
+ return {
1022
+ to: orchestratorContext.address,
1023
+ data,
1024
+ value: 0n,
1025
+ chainId: this.config.getChainId(),
1026
+ abi: orchestratorContext.abi,
1027
+ functionName: "signalIntent",
1028
+ args
1029
+ };
1030
+ }
1031
+ async prepareCancelIntent(params) {
1032
+ const orchestratorContext = await this.config.host.resolveOrchestratorContext({
1033
+ orchestratorAddress: params.orchestratorAddress,
1034
+ intentHash: params.intentHash,
1035
+ preferV2: this.config.getDefaultPreferV2()
1036
+ });
1037
+ const args = [params.intentHash];
1038
+ const { referrer } = params.txOverrides ?? {};
1039
+ const data = encodeWithAttribution(
1040
+ {
1041
+ abi: orchestratorContext.abi,
1042
+ functionName: "cancelIntent",
1043
+ args
1044
+ },
1045
+ referrer
1046
+ );
1047
+ return {
1048
+ to: orchestratorContext.address,
1049
+ data,
1050
+ value: 0n,
1051
+ chainId: this.config.getChainId(),
1052
+ abi: orchestratorContext.abi,
1053
+ functionName: "cancelIntent",
1054
+ args
1055
+ };
1056
+ }
1057
+ async prepareReleaseFundsToPayer(params) {
1058
+ const orchestratorContext = await this.config.host.resolveOrchestratorContext({
1059
+ orchestratorAddress: params.orchestratorAddress,
1060
+ intentHash: params.intentHash,
1061
+ preferV2: this.config.getDefaultPreferV2()
1062
+ });
1063
+ const args = [params.intentHash];
1064
+ const { referrer } = params.txOverrides ?? {};
1065
+ const data = encodeWithAttribution(
1066
+ {
1067
+ abi: orchestratorContext.abi,
1068
+ functionName: "releaseFundsToPayer",
1069
+ args
1070
+ },
1071
+ referrer
1072
+ );
1073
+ return {
1074
+ to: orchestratorContext.address,
1075
+ data,
1076
+ value: 0n,
1077
+ chainId: this.config.getChainId(),
1078
+ abi: orchestratorContext.abi,
1079
+ functionName: "releaseFundsToPayer",
1080
+ args
1081
+ };
1082
+ }
1083
+ async prepareSetDepositPreIntentHook(params) {
1084
+ const escrowAddress = this.config.host.resolveEscrowAddressOrThrow(
1085
+ params.escrowAddress,
1086
+ params.depositId,
1087
+ "setDepositPreIntentHook",
1088
+ { preferV2: this.config.getDefaultPreferV2() }
1089
+ );
1090
+ const orchestratorContext = await this.config.host.resolveOrchestratorContext({
1091
+ orchestratorAddress: params.orchestratorAddress,
1092
+ escrowAddress,
1093
+ preferV2: this.config.getDefaultPreferV2()
1094
+ });
1095
+ return this.config.host.prepareResolvedOrchestratorTransaction({
1096
+ orchestrator: orchestratorContext,
1097
+ functionNames: ["setDepositPreIntentHook"],
1098
+ args: [escrowAddress, parseRawDepositId(params.depositId), params.preIntentHook],
1099
+ txOverrides: params.txOverrides
1100
+ });
1101
+ }
1102
+ async prepareSetDepositWhitelistHook(params) {
1103
+ const escrowAddress = this.config.host.resolveEscrowAddressOrThrow(
1104
+ params.escrowAddress,
1105
+ params.depositId,
1106
+ "setDepositWhitelistHook",
1107
+ { preferV2: this.config.getDefaultPreferV2() }
1108
+ );
1109
+ const orchestratorContext = await this.config.host.resolveOrchestratorContext({
1110
+ orchestratorAddress: params.orchestratorAddress,
1111
+ escrowAddress,
1112
+ preferV2: this.config.getDefaultPreferV2()
1113
+ });
1114
+ return this.config.host.prepareResolvedOrchestratorTransaction({
1115
+ orchestrator: orchestratorContext,
1116
+ functionNames: ["setDepositWhitelistHook"],
1117
+ args: [escrowAddress, parseRawDepositId(params.depositId), params.whitelistHook],
1118
+ txOverrides: params.txOverrides
1119
+ });
1120
+ }
1121
+ async prepareCleanupOrphanedIntents(params) {
1122
+ const orchestratorContext = await this.config.host.resolveOrchestratorContext({
1123
+ orchestratorAddress: params.orchestratorAddress,
1124
+ escrowAddress: params.escrowAddress,
1125
+ preferV2: this.config.getDefaultPreferV2()
1126
+ });
1127
+ return this.config.host.prepareResolvedOrchestratorTransaction({
1128
+ orchestrator: orchestratorContext,
1129
+ functionNames: ["cleanupOrphanedIntents"],
1130
+ args: [params.intentHashes],
1131
+ txOverrides: params.txOverrides
1132
+ });
1133
+ }
1134
+ async getDepositPreIntentHook(depositId, options) {
1135
+ const escrowAddress = this.config.host.resolveEscrowAddressOrThrow(
1136
+ options?.escrowAddress,
1137
+ depositId,
1138
+ "getDepositPreIntentHook",
1139
+ { preferV2: this.config.getDefaultPreferV2() }
1140
+ );
1141
+ const orchestratorContext = await this.config.host.resolveOrchestratorContext({
1142
+ orchestratorAddress: options?.orchestratorAddress,
1143
+ escrowAddress,
1144
+ preferV2: this.config.getDefaultPreferV2()
1145
+ });
1146
+ const functionName = resolveAbiFunctionName(orchestratorContext.abi, [
1147
+ "getDepositPreIntentHook"
1148
+ ]);
1149
+ return await this.config.getPublicClient().readContract({
1150
+ address: orchestratorContext.address,
1151
+ abi: orchestratorContext.abi,
1152
+ functionName,
1153
+ args: [escrowAddress, parseRawDepositId(depositId)]
1154
+ });
1155
+ }
1156
+ async getDepositWhitelistHook(depositId, options) {
1157
+ const escrowAddress = this.config.host.resolveEscrowAddressOrThrow(
1158
+ options?.escrowAddress,
1159
+ depositId,
1160
+ "getDepositWhitelistHook",
1161
+ { preferV2: this.config.getDefaultPreferV2() }
1162
+ );
1163
+ const orchestratorContext = await this.config.host.resolveOrchestratorContext({
1164
+ orchestratorAddress: options?.orchestratorAddress,
1165
+ escrowAddress,
1166
+ preferV2: this.config.getDefaultPreferV2()
1167
+ });
1168
+ const functionName = resolveAbiFunctionName(orchestratorContext.abi, [
1169
+ "getDepositWhitelistHook"
1170
+ ]);
1171
+ return await this.config.getPublicClient().readContract({
1172
+ address: orchestratorContext.address,
1173
+ abi: orchestratorContext.abi,
1174
+ functionName,
1175
+ args: [escrowAddress, parseRawDepositId(depositId)]
1176
+ });
1177
+ }
1178
+ async prepareFulfillIntent(params) {
1179
+ const intentHash = params.intentHash;
1180
+ const orchestratorContext = await this.config.host.resolveOrchestratorContext({
1181
+ orchestratorAddress: params.orchestratorAddress,
1182
+ intentHash,
1183
+ preferV2: this.config.getDefaultPreferV2()
1184
+ });
1185
+ const precomputed = params.precomputedAttestation;
1186
+ let paymentProof;
1187
+ let verificationData;
1188
+ if (precomputed) {
1189
+ if (!precomputed.paymentProof || !precomputed.verificationData) {
1190
+ throw new Error("Precomputed attestation requires both proof and verification data");
1191
+ }
1192
+ paymentProof = precomputed.paymentProof;
1193
+ verificationData = precomputed.verificationData;
1194
+ } else {
1195
+ const attestationServiceUrl = params.attestationServiceUrl ?? this.defaultAttestationService();
1196
+ const inputs = await this.config.host.getFulfillIntentInputs(intentHash);
1197
+ const paymentMethodHash = inputs.paymentMethodHash || "0x";
1198
+ const catalog = getPaymentMethodsCatalog(
1199
+ this.config.getChainId(),
1200
+ this.config.getRuntimeEnv()
1201
+ );
1202
+ const platformName = resolvePaymentMethodNameFromHash(paymentMethodHash, catalog);
1203
+ if (!platformName) {
1204
+ throw new Error("Unknown paymentMethodHash for this network/env; update SDK catalogs.");
1205
+ }
1206
+ const platformConfig = resolvePlatformAttestationConfig(platformName);
1207
+ const zkTlsProof = typeof params.proof === "string" ? params.proof : serializeProofInput(params.proof);
1208
+ const payload = {
1209
+ proofType: "reclaim",
1210
+ proof: zkTlsProof,
1211
+ chainId: this.config.getChainId(),
1212
+ intent: {
1213
+ intentHash,
1214
+ amount: inputs.amount,
1215
+ timestampMs: inputs.intentTimestampMs,
1216
+ paymentMethod: paymentMethodHash,
1217
+ fiatCurrency: inputs.fiatCurrency,
1218
+ conversionRate: inputs.conversionRate,
1219
+ payeeDetails: inputs.payeeDetails,
1220
+ timestampBufferMs: params.timestampBufferMs ?? "300000"
1221
+ }
1222
+ };
1223
+ const attestation = await apiCreatePaymentAttestation(
1224
+ payload,
1225
+ attestationServiceUrl,
1226
+ platformConfig.actionPlatform,
1227
+ platformConfig.actionType
1228
+ );
1229
+ paymentProof = encodePaymentAttestation(attestation);
1230
+ verificationData = encodeVerifyPaymentData({
1231
+ intentHash,
1232
+ paymentProof,
1233
+ data: encodeAddressAsBytes(attestation.responseObject.signer)
1234
+ });
1235
+ }
1236
+ const args = [
1237
+ {
1238
+ paymentProof,
1239
+ intentHash,
1240
+ verificationData,
1241
+ postIntentHookData: params.postIntentHookData ?? "0x"
1242
+ }
1243
+ ];
1244
+ const { referrer } = params.txOverrides ?? {};
1245
+ const data = encodeWithAttribution(
1246
+ {
1247
+ abi: orchestratorContext.abi,
1248
+ functionName: "fulfillIntent",
1249
+ args
1250
+ },
1251
+ referrer
1252
+ );
1253
+ return {
1254
+ to: orchestratorContext.address,
1255
+ data,
1256
+ value: 0n,
1257
+ chainId: this.config.getChainId(),
1258
+ abi: orchestratorContext.abi,
1259
+ functionName: "fulfillIntent",
1260
+ args
1261
+ };
1262
+ }
1263
+ defaultAttestationService() {
1264
+ return this.config.getRuntimeEnv() === "staging" ? "https://attestation-service-staging.zkp2p.xyz" : "https://attestation-service.zkp2p.xyz";
1265
+ }
1266
+ async getFulfillIntentInputs(intentHash) {
1267
+ try {
1268
+ if (this.config.getProtocolViewerAddress() && this.config.getProtocolViewerAbi()) {
1269
+ const view = await this.config.host.getPvIntent(intentHash);
1270
+ const paymentMethodHash = view.intent.paymentMethod.toLowerCase();
1271
+ const matched = (view.deposit.paymentMethods || []).find(
1272
+ (pm) => pm.paymentMethod?.toLowerCase?.() === paymentMethodHash
1273
+ );
1274
+ const payee2 = matched?.verificationData?.payeeDetails;
1275
+ if (payee2) {
1276
+ return {
1277
+ amount: view.intent.amount.toString(),
1278
+ fiatCurrency: view.intent.fiatCurrency,
1279
+ conversionRate: view.intent.conversionRate.toString(),
1280
+ payeeDetails: payee2,
1281
+ intentTimestampMs: (BigInt(view.intent.timestamp) * 1000n).toString(),
1282
+ paymentMethodHash: view.intent.paymentMethod
1283
+ };
1284
+ }
1285
+ }
1286
+ } catch (error) {
1287
+ logger.debug("ProtocolViewer lookup failed, falling back to indexer", {
1288
+ intentHash,
1289
+ error: error instanceof Error ? error.message : String(error)
1290
+ });
1291
+ }
1292
+ const response = await this.config.getIndexerClient().query({
1293
+ query: (
1294
+ /* GraphQL */
1295
+ `
1296
+ query GetIntentMinimal($hash: String!) {
1297
+ Intent(where: { intentHash: { _eq: $hash } }, limit: 1) {
1298
+ amount
1299
+ fiatCurrency
1300
+ conversionRate
1301
+ paymentMethodHash
1302
+ depositId
1303
+ signalTimestamp
1304
+ verifier
1305
+ }
1306
+ }
1307
+ `
1308
+ ),
1309
+ variables: { hash: intentHash.toLowerCase() }
1310
+ });
1311
+ const record = response?.Intent?.[0];
1312
+ if (!record) throw new Error("Intent not found on indexer");
1313
+ if (!record.signalTimestamp) throw new Error("Intent signal timestamp not found on indexer");
1314
+ const deposit = await this.config.getIndexerService().fetchDepositWithRelations(record.depositId, {
1315
+ includeIntents: false
1316
+ });
1317
+ let payee;
1318
+ const paymentMethodHashLower = (record.paymentMethodHash || "").toLowerCase();
1319
+ for (const paymentMethod of deposit?.paymentMethods || []) {
1320
+ if ((paymentMethod.paymentMethodHash || "").toLowerCase() === paymentMethodHashLower) {
1321
+ payee = paymentMethod.payeeDetailsHash;
1322
+ break;
1323
+ }
1324
+ }
1325
+ if (!payee) throw new Error("Payee details not found for intent");
1326
+ return {
1327
+ amount: record.amount,
1328
+ fiatCurrency: record.fiatCurrency,
1329
+ conversionRate: record.conversionRate,
1330
+ payeeDetails: payee,
1331
+ intentTimestampMs: (BigInt(record.signalTimestamp) * 1000n).toString(),
1332
+ paymentMethodHash: record.paymentMethodHash || "0x0000000000000000000000000000000000000000000000000000000000000000",
1333
+ paymentVerifier: record.verifier || void 0
1334
+ };
1335
+ }
1336
+ };
1337
+ function serializeProofInput(proof) {
1338
+ return JSON.stringify(
1339
+ proof,
1340
+ (_key, value) => typeof value === "bigint" ? value.toString() : value
1341
+ );
1342
+ }
1343
+ function normalizeSignalIntentReferralFees(params) {
1344
+ if (params.referralFees) {
1345
+ return params.referralFees.map((referralFee) => ({
1346
+ recipient: referralFee.recipient,
1347
+ fee: typeof referralFee.fee === "bigint" ? referralFee.fee : BigInt(referralFee.fee)
1348
+ }));
1349
+ }
1350
+ if (params.referrer && params.referrer.toLowerCase() !== ZERO_ADDRESS.toLowerCase()) {
1351
+ const fee = params.referrerFee === void 0 ? 0n : typeof params.referrerFee === "bigint" ? params.referrerFee : BigInt(params.referrerFee);
1352
+ return [{ recipient: params.referrer, fee }];
1353
+ }
1354
+ return [];
1355
+ }
1356
+
1357
+ // src/client/ProtocolViewerReader.ts
1358
+ async function tryContexts(contexts, attempt, notFoundMessage) {
1359
+ let attemptedRead = false;
1360
+ let hadSuccessfulRead = false;
1361
+ let lastError;
1362
+ for (const context of contexts) {
1363
+ attemptedRead = true;
1364
+ try {
1365
+ const result = await attempt(context);
1366
+ hadSuccessfulRead = true;
1367
+ if (result !== void 0) {
1368
+ return result;
1369
+ }
1370
+ } catch (readError) {
1371
+ lastError = readError;
1372
+ }
1373
+ }
1374
+ if (!hadSuccessfulRead && attemptedRead && lastError) {
1375
+ throw lastError;
1376
+ }
1377
+ throw new Error(notFoundMessage);
1378
+ }
1379
+ async function collectFromContexts(contexts, attempt) {
1380
+ let attemptedRead = false;
1381
+ let hadSuccessfulRead = false;
1382
+ let lastError;
1383
+ const results = [];
1384
+ for (const context of contexts) {
1385
+ attemptedRead = true;
1386
+ try {
1387
+ const items = await attempt(context);
1388
+ hadSuccessfulRead = true;
1389
+ results.push(...items);
1390
+ } catch (readError) {
1391
+ lastError = readError;
1392
+ }
1393
+ }
1394
+ return { results, attemptedRead, hadSuccessfulRead, lastError };
1395
+ }
1396
+ var ProtocolViewerReader = class {
1397
+ constructor(config) {
1398
+ this.config = config;
1399
+ }
1400
+ requireProtocolViewer() {
1401
+ const address = this.config.getProtocolViewerAddress();
1402
+ const abi = this.config.getProtocolViewerAbi();
1403
+ if (!address || !abi) {
1404
+ throw new Error("ProtocolViewer not available for this network");
1405
+ }
1406
+ return { address, abi };
1407
+ }
1408
+ protocolViewerFunctionInputCount(functionName) {
1409
+ const fn = getAbiFunction(this.config.getProtocolViewerAbi(), functionName);
1410
+ if (!fn) return null;
1411
+ const inputs = fn.inputs ?? [];
1412
+ return inputs.length;
1413
+ }
1414
+ pvEntryFunctionInputCount(entry, functionName) {
1415
+ const fn = getAbiFunction(entry.abi, functionName);
1416
+ if (!fn) return null;
1417
+ const inputs = fn.inputs ?? [];
1418
+ return inputs.length;
1419
+ }
1420
+ isZeroAddressValue(value) {
1421
+ return !value || value.toLowerCase() === ZERO_ADDRESS.toLowerCase();
1422
+ }
1423
+ toBigIntOrZero(value, fieldName = "numeric field") {
1424
+ if (value === null || value === void 0) return 0n;
1425
+ try {
1426
+ return parseBigIntLike(value);
1427
+ } catch (err) {
1428
+ const detail = err instanceof Error ? err.message : String(err);
1429
+ throw new Error(`Invalid ${fieldName}: ${detail}`);
1430
+ }
1431
+ }
1432
+ buildProtocolViewerContexts(options) {
1433
+ return this.config.getRouterBuildProtocolViewerContexts()(options);
1434
+ }
1435
+ isProtocolViewerDepositPopulated(view) {
1436
+ return !this.isZeroAddressValue(view.deposit?.depositor);
1437
+ }
1438
+ isProtocolViewerIntentPopulated(view) {
1439
+ return !this.isZeroAddressValue(view.intent?.owner);
1440
+ }
1441
+ buildDepositViewFromEscrowDeposit(rawDeposit, depositId) {
1442
+ const deposit = rawDeposit ?? {};
1443
+ const remaining = this.toBigIntOrZero(
1444
+ deposit.remainingDeposits ?? deposit.remainingDepositAmount,
1445
+ "deposit remaining amount"
1446
+ );
1447
+ const outstanding = this.toBigIntOrZero(
1448
+ deposit.outstandingIntentAmount,
1449
+ "deposit outstanding intent amount"
1450
+ );
1451
+ const amount = this.toBigIntOrZero(deposit.amount, "deposit amount") || remaining + outstanding;
1452
+ return {
1453
+ depositId,
1454
+ deposit: {
1455
+ depositor: normalizeAddress(deposit.depositor) ?? ZERO_ADDRESS,
1456
+ delegate: normalizeAddress(deposit.delegate) ?? ZERO_ADDRESS,
1457
+ token: normalizeAddress(deposit.token) ?? ZERO_ADDRESS,
1458
+ amount,
1459
+ intentAmountRange: {
1460
+ min: this.toBigIntOrZero(
1461
+ deposit.intentAmountRange?.min,
1462
+ "minimum intent amount"
1463
+ ),
1464
+ max: this.toBigIntOrZero(
1465
+ deposit.intentAmountRange?.max,
1466
+ "maximum intent amount"
1467
+ )
1468
+ },
1469
+ acceptingIntents: Boolean(deposit.acceptingIntents),
1470
+ remainingDeposits: remaining,
1471
+ outstandingIntentAmount: outstanding,
1472
+ makerProtocolFee: this.toBigIntOrZero(deposit.makerProtocolFee, "maker protocol fee"),
1473
+ reservedMakerFees: this.toBigIntOrZero(
1474
+ deposit.reservedMakerFees,
1475
+ "reserved maker fee amount"
1476
+ ),
1477
+ accruedMakerFees: this.toBigIntOrZero(deposit.accruedMakerFees, "accrued maker fee amount"),
1478
+ accruedReferrerFees: this.toBigIntOrZero(
1479
+ deposit.accruedReferrerFees,
1480
+ "accrued referrer fee amount"
1481
+ ),
1482
+ intentGuardian: normalizeAddress(deposit.intentGuardian) ?? ZERO_ADDRESS,
1483
+ retainOnEmpty: Boolean(deposit.retainOnEmpty),
1484
+ referrer: normalizeAddress(deposit.referrer) ?? ZERO_ADDRESS,
1485
+ referrerFee: this.toBigIntOrZero(deposit.referrerFee, "referrer fee")
1486
+ },
1487
+ availableLiquidity: remaining,
1488
+ paymentMethods: [],
1489
+ intentHashes: []
1490
+ };
1491
+ }
1492
+ convertIndexerDepositToPvView(deposit) {
1493
+ const paymentMethods = (deposit.paymentMethods ?? []).filter(
1494
+ (paymentMethod) => paymentMethod.active !== false
1495
+ );
1496
+ const currenciesByPaymentMethod = /* @__PURE__ */ new Map();
1497
+ for (const currency of deposit.currencies ?? []) {
1498
+ const key = currency.paymentMethodHash.toLowerCase();
1499
+ const existing = currenciesByPaymentMethod.get(key) ?? [];
1500
+ existing.push(currency);
1501
+ currenciesByPaymentMethod.set(key, existing);
1502
+ }
1503
+ const remaining = this.toBigIntOrZero(deposit.remainingDeposits, "remaining deposits");
1504
+ const outstanding = this.toBigIntOrZero(
1505
+ deposit.outstandingIntentAmount,
1506
+ "outstanding intent amount"
1507
+ );
1508
+ const totalAmountTaken = this.toBigIntOrZero(deposit.totalAmountTaken, "total amount taken");
1509
+ const totalWithdrawn = this.toBigIntOrZero(deposit.totalWithdrawn, "total withdrawn amount");
1510
+ const depositAmount = remaining + outstanding + totalAmountTaken + totalWithdrawn;
1511
+ return {
1512
+ depositId: this.toBigIntOrZero(deposit.depositId, "deposit id"),
1513
+ deposit: {
1514
+ depositor: normalizeAddress(deposit.depositor) ?? ZERO_ADDRESS,
1515
+ delegate: normalizeAddress(deposit.delegate ?? void 0) ?? ZERO_ADDRESS,
1516
+ token: normalizeAddress(deposit.token) ?? ZERO_ADDRESS,
1517
+ amount: depositAmount,
1518
+ intentAmountRange: {
1519
+ min: this.toBigIntOrZero(deposit.intentAmountMin, "minimum intent amount"),
1520
+ max: this.toBigIntOrZero(deposit.intentAmountMax, "maximum intent amount")
1521
+ },
1522
+ acceptingIntents: Boolean(deposit.acceptingIntents),
1523
+ remainingDeposits: remaining,
1524
+ outstandingIntentAmount: outstanding,
1525
+ makerProtocolFee: 0n,
1526
+ reservedMakerFees: 0n,
1527
+ accruedMakerFees: 0n,
1528
+ accruedReferrerFees: 0n,
1529
+ intentGuardian: ZERO_ADDRESS,
1530
+ retainOnEmpty: Boolean(deposit.retainOnEmpty ?? false),
1531
+ referrer: ZERO_ADDRESS,
1532
+ referrerFee: 0n
1533
+ },
1534
+ availableLiquidity: remaining,
1535
+ paymentMethods: paymentMethods.map((method) => ({
1536
+ paymentMethod: method.paymentMethodHash,
1537
+ verificationData: {
1538
+ intentGatingService: normalizeAddress(method.intentGatingService) ?? ZERO_ADDRESS,
1539
+ payeeDetails: method.payeeDetailsHash || "0x",
1540
+ data: "0x"
1541
+ },
1542
+ currencies: (currenciesByPaymentMethod.get(method.paymentMethodHash.toLowerCase()) ?? []).map((currency) => ({
1543
+ code: currency.currencyCode,
1544
+ minConversionRate: this.toBigIntOrZero(
1545
+ currency.conversionRate ?? currency.minConversionRate,
1546
+ "conversion rate"
1547
+ )
1548
+ }))
1549
+ })),
1550
+ intentHashes: Array.from(new Set((deposit.intents ?? []).map((intent) => intent.intentHash)))
1551
+ };
1552
+ }
1553
+ async getPvAccountDepositsFromIndexer(owner) {
1554
+ const filter = { depositor: owner, status: "ACTIVE" };
1555
+ const escrowAddresses = this.config.getEscrowAddresses();
1556
+ if (escrowAddresses.length > 0) {
1557
+ filter.escrowAddresses = escrowAddresses.map((escrow) => escrow);
1558
+ }
1559
+ const deposits = await this.config.getIndexerService().fetchDepositsWithRelations(
1560
+ filter,
1561
+ { limit: 1e3, orderBy: "timestamp", orderDirection: "desc" },
1562
+ { includeIntents: true }
1563
+ );
1564
+ return deposits.map((deposit) => this.convertIndexerDepositToPvView(deposit));
1565
+ }
1566
+ async getPvDepositById(depositId, options) {
1567
+ const id = typeof depositId === "bigint" ? depositId : parseRawDepositId(depositId);
1568
+ const hintedEscrow = typeof depositId === "string" ? parseEscrowAddressFromCompositeDepositId(depositId) : void 0;
1569
+ const strictEscrow = Boolean(options?.strictEscrow && hintedEscrow);
1570
+ const protocolViewerContexts = strictEscrow && hintedEscrow ? this.config.host.buildProtocolViewerContexts({ escrowAddress: hintedEscrow }).filter((context) => context.escrow.toLowerCase() === hintedEscrow.toLowerCase()) : this.config.host.buildProtocolViewerContexts({ escrowAddress: hintedEscrow });
1571
+ const protocolViewerAddress = this.config.getProtocolViewerAddress();
1572
+ const protocolViewerAbi = this.config.getProtocolViewerAbi();
1573
+ if (protocolViewerAddress && protocolViewerAbi) {
1574
+ const { address, abi } = this.config.host.requireProtocolViewer();
1575
+ const inputCount = this.config.host.protocolViewerFunctionInputCount("getDeposit");
1576
+ if (inputCount === null) {
1577
+ throw new Error("Configured ProtocolViewer ABI does not expose getDeposit");
1578
+ }
1579
+ const { parseDepositView: parseDepositView2 } = await import('./protocolViewerParsers-QVG4JP23.mjs');
1580
+ if (inputCount >= 3) {
1581
+ return tryContexts(
1582
+ protocolViewerContexts,
1583
+ async (context) => {
1584
+ const raw = await this.config.getPublicClient().readContract({
1585
+ address,
1586
+ abi,
1587
+ functionName: "getDeposit",
1588
+ args: [context.escrow, context.orchestrator, id]
1589
+ });
1590
+ const parsed = parseDepositView2(raw);
1591
+ return this.config.host.isProtocolViewerDepositPopulated(parsed) ? parsed : void 0;
1592
+ },
1593
+ "Deposit not found in configured ProtocolViewer contexts"
1594
+ );
1595
+ }
1596
+ if (inputCount >= 2) {
1597
+ return tryContexts(
1598
+ protocolViewerContexts,
1599
+ async (context) => {
1600
+ const raw = await this.config.getPublicClient().readContract({
1601
+ address,
1602
+ abi,
1603
+ functionName: "getDeposit",
1604
+ args: [context.escrow, id]
1605
+ });
1606
+ const parsed = parseDepositView2(raw);
1607
+ return this.config.host.isProtocolViewerDepositPopulated(parsed) ? parsed : void 0;
1608
+ },
1609
+ "Deposit not found in configured ProtocolViewer escrows"
1610
+ );
1611
+ }
1612
+ if (!strictEscrow) {
1613
+ const raw = await this.config.getPublicClient().readContract({
1614
+ address,
1615
+ abi,
1616
+ functionName: "getDeposit",
1617
+ args: [id]
1618
+ });
1619
+ const parsed = parseDepositView2(raw);
1620
+ if (this.config.host.isProtocolViewerDepositPopulated(parsed)) {
1621
+ return parsed;
1622
+ }
1623
+ throw new Error("Deposit not found");
1624
+ }
1625
+ }
1626
+ const contexts = strictEscrow && hintedEscrow ? this.config.host.getEscrowContexts().filter((context) => context.address.toLowerCase() === hintedEscrow.toLowerCase()) : this.config.host.getEscrowContexts();
1627
+ if (!strictEscrow && hintedEscrow) {
1628
+ contexts.sort((left, right) => {
1629
+ const leftMatch = left.address.toLowerCase() === hintedEscrow.toLowerCase() ? 1 : 0;
1630
+ const rightMatch = right.address.toLowerCase() === hintedEscrow.toLowerCase() ? 1 : 0;
1631
+ return rightMatch - leftMatch;
1632
+ });
1633
+ }
1634
+ return tryContexts(
1635
+ contexts,
1636
+ async (context) => {
1637
+ const raw = await this.config.getPublicClient().readContract({
1638
+ address: context.address,
1639
+ abi: context.abi,
1640
+ functionName: "getDeposit",
1641
+ args: [id]
1642
+ });
1643
+ const parsed = this.config.host.buildDepositViewFromEscrowDeposit(raw, id);
1644
+ return this.config.host.isProtocolViewerDepositPopulated(parsed) ? parsed : void 0;
1645
+ },
1646
+ "Failed to fetch deposit from configured escrows"
1647
+ );
1648
+ }
1649
+ async getPvDepositsFromIds(ids) {
1650
+ if (!ids.length) return [];
1651
+ const inputCount = this.config.host.protocolViewerFunctionInputCount("getDepositFromIds");
1652
+ const protocolViewerAddress = this.config.getProtocolViewerAddress();
1653
+ const protocolViewerAbi = this.config.getProtocolViewerAbi();
1654
+ if (!protocolViewerAddress || !protocolViewerAbi || inputCount === null || inputCount >= 3) {
1655
+ return Promise.all(ids.map((id) => this.config.host.getPvDepositById(id)));
1656
+ }
1657
+ const bn = ids.map((id) => typeof id === "bigint" ? id : parseRawDepositId(id));
1658
+ const { parseDepositView: parseDepositView2 } = await import('./protocolViewerParsers-QVG4JP23.mjs');
1659
+ if (inputCount >= 2) {
1660
+ const requests = ids.map((id, index) => ({
1661
+ index,
1662
+ id,
1663
+ rawId: bn[index],
1664
+ hintedEscrow: typeof id === "string" ? parseEscrowAddressFromCompositeDepositId(id) : void 0
1665
+ }));
1666
+ const resolved = new Array(requests.length);
1667
+ let attemptedBatchRead = false;
1668
+ let hadSuccessfulBatchRead = false;
1669
+ let lastBatchError;
1670
+ const resolveBatch = async (escrow, entries) => {
1671
+ if (!entries.length) return;
1672
+ attemptedBatchRead = true;
1673
+ try {
1674
+ const raw2 = await this.config.getPublicClient().readContract({
1675
+ address: protocolViewerAddress,
1676
+ abi: protocolViewerAbi,
1677
+ functionName: "getDepositFromIds",
1678
+ args: [escrow, entries.map((entry) => entry.rawId)]
1679
+ });
1680
+ hadSuccessfulBatchRead = true;
1681
+ const items = Array.isArray(raw2) ? raw2 : [];
1682
+ if (items.length === entries.length) {
1683
+ for (let index = 0; index < entries.length; index += 1) {
1684
+ const entry = entries[index];
1685
+ if (!entry || resolved[entry.index]) continue;
1686
+ const parsed = parseDepositView2(items[index]);
1687
+ if (this.config.host.isProtocolViewerDepositPopulated(parsed)) {
1688
+ resolved[entry.index] = parsed;
1689
+ }
1690
+ }
1691
+ return;
1692
+ }
1693
+ for (const item of items) {
1694
+ const parsed = parseDepositView2(item);
1695
+ if (!this.config.host.isProtocolViewerDepositPopulated(parsed)) continue;
1696
+ const match = entries.find(
1697
+ (entry) => !resolved[entry.index] && entry.rawId === parsed.depositId
1698
+ );
1699
+ if (match) {
1700
+ resolved[match.index] = parsed;
1701
+ }
1702
+ }
1703
+ } catch (batchError) {
1704
+ lastBatchError = batchError;
1705
+ }
1706
+ };
1707
+ const hintedGroups = /* @__PURE__ */ new Map();
1708
+ for (const request of requests) {
1709
+ if (!request.hintedEscrow) continue;
1710
+ const key = request.hintedEscrow.toLowerCase();
1711
+ const group = hintedGroups.get(key);
1712
+ if (group) {
1713
+ group.entries.push(request);
1714
+ } else {
1715
+ hintedGroups.set(key, { escrow: request.hintedEscrow, entries: [request] });
1716
+ }
1717
+ }
1718
+ for (const { escrow, entries } of hintedGroups.values()) {
1719
+ await resolveBatch(escrow, entries);
1720
+ }
1721
+ const escrows = [];
1722
+ const seenEscrows = /* @__PURE__ */ new Set();
1723
+ for (const context of this.config.host.buildProtocolViewerContexts()) {
1724
+ const key = context.escrow.toLowerCase();
1725
+ if (seenEscrows.has(key)) continue;
1726
+ seenEscrows.add(key);
1727
+ escrows.push(context.escrow);
1728
+ }
1729
+ for (const escrow of escrows) {
1730
+ const pending = requests.filter(
1731
+ (entry) => !entry.hintedEscrow && resolved[entry.index] === void 0
1732
+ );
1733
+ if (!pending.length) break;
1734
+ await resolveBatch(escrow, pending);
1735
+ }
1736
+ if (requests.every((entry) => resolved[entry.index] !== void 0)) {
1737
+ return resolved;
1738
+ }
1739
+ if (!hadSuccessfulBatchRead && attemptedBatchRead && lastBatchError) {
1740
+ throw lastBatchError;
1741
+ }
1742
+ return Promise.all(
1743
+ requests.map(
1744
+ (entry) => resolved[entry.index] ?? this.config.host.getPvDepositById(entry.id)
1745
+ )
1746
+ );
1747
+ }
1748
+ const raw = await this.config.getPublicClient().readContract({
1749
+ address: protocolViewerAddress,
1750
+ abi: protocolViewerAbi,
1751
+ functionName: "getDepositFromIds",
1752
+ args: [bn]
1753
+ });
1754
+ return raw.map(parseDepositView2);
1755
+ }
1756
+ async getPvAccountDeposits(owner) {
1757
+ const inputCount = this.config.host.protocolViewerFunctionInputCount("getAccountDeposits");
1758
+ const protocolViewerAddress = this.config.getProtocolViewerAddress();
1759
+ const protocolViewerAbi = this.config.getProtocolViewerAbi();
1760
+ if (!protocolViewerAddress || !protocolViewerAbi || inputCount === null) {
1761
+ return this.config.host.getPvAccountDepositsFromIndexer(owner);
1762
+ }
1763
+ const { parseDepositView: parseDepositView2 } = await import('./protocolViewerParsers-QVG4JP23.mjs');
1764
+ const { address, abi } = this.config.host.requireProtocolViewer();
1765
+ if (inputCount >= 2) {
1766
+ const readAndFilter = async (raw2) => {
1767
+ const filtered = [];
1768
+ for (const item of raw2) {
1769
+ const parsed = parseDepositView2(item);
1770
+ if (this.config.host.isProtocolViewerDepositPopulated(parsed)) {
1771
+ filtered.push(parsed);
1772
+ }
1773
+ }
1774
+ return filtered;
1775
+ };
1776
+ if (inputCount >= 3) {
1777
+ const { results: results2, attemptedRead: attemptedRead2, hadSuccessfulRead: hadSuccessfulRead2, lastError: lastError2 } = await collectFromContexts(
1778
+ this.config.host.buildProtocolViewerContexts(),
1779
+ async (context) => {
1780
+ const raw2 = await this.config.getPublicClient().readContract({
1781
+ address,
1782
+ abi,
1783
+ functionName: "getAccountDeposits",
1784
+ args: [context.escrow, context.orchestrator, owner]
1785
+ });
1786
+ return readAndFilter(raw2);
1787
+ }
1788
+ );
1789
+ if (!hadSuccessfulRead2 && attemptedRead2 && lastError2) {
1790
+ throw lastError2;
1791
+ }
1792
+ return results2;
1793
+ }
1794
+ const seenEscrows = /* @__PURE__ */ new Set();
1795
+ const escrowAddresses = [
1796
+ ...this.config.host.buildProtocolViewerContexts().map((context) => context.escrow),
1797
+ ...this.config.host.getEscrowContexts().map((context) => context.address)
1798
+ ].filter((escrow) => {
1799
+ const key = escrow.toLowerCase();
1800
+ if (seenEscrows.has(key)) return false;
1801
+ seenEscrows.add(key);
1802
+ return true;
1803
+ });
1804
+ const { results, attemptedRead, hadSuccessfulRead, lastError } = await collectFromContexts(
1805
+ escrowAddresses,
1806
+ async (escrow) => {
1807
+ const raw2 = await this.config.getPublicClient().readContract({
1808
+ address,
1809
+ abi,
1810
+ functionName: "getAccountDeposits",
1811
+ args: [escrow, owner]
1812
+ });
1813
+ return readAndFilter(raw2);
1814
+ }
1815
+ );
1816
+ if (!hadSuccessfulRead && attemptedRead && lastError) {
1817
+ throw lastError;
1818
+ }
1819
+ return results;
1820
+ }
1821
+ const raw = await this.config.getPublicClient().readContract({
1822
+ address,
1823
+ abi,
1824
+ functionName: "getAccountDeposits",
1825
+ args: [owner]
1826
+ });
1827
+ return raw.map(parseDepositView2).filter((view) => this.config.host.isProtocolViewerDepositPopulated(view));
1828
+ }
1829
+ async getPvAccountIntents(owner) {
1830
+ const protocolViewerEntries = this.config.getProtocolViewerEntries();
1831
+ if (protocolViewerEntries.length === 0) {
1832
+ throw new Error("ProtocolViewer not available for this network");
1833
+ }
1834
+ const { parseIntentView: parseIntentView2 } = await import('./protocolViewerParsers-QVG4JP23.mjs');
1835
+ const intentsByHash = /* @__PURE__ */ new Map();
1836
+ let attemptedRead = false;
1837
+ let hadSuccessfulRead = false;
1838
+ let lastError;
1839
+ const runtimeProcess = globalThis.process;
1840
+ const protocolViewerDebugEnv = runtimeProcess?.env?.ZKP2P_DEBUG_PROTOCOL_VIEWER;
1841
+ const isDebugLoggingEnabled = protocolViewerDebugEnv === "1" || protocolViewerDebugEnv === "true" || runtimeProcess?.env?.NODE_ENV === "development";
1842
+ for (const pvEntry of protocolViewerEntries) {
1843
+ const inputCount = this.pvEntryFunctionInputCount(pvEntry, "getAccountIntents");
1844
+ if (inputCount === null) continue;
1845
+ if (inputCount >= 2) {
1846
+ for (const context of this.config.host.buildProtocolViewerContexts()) {
1847
+ if (isDebugLoggingEnabled) {
1848
+ console.debug("[Zkp2pClient] getPvAccountIntents read context", {
1849
+ protocolViewerAddress: pvEntry.address,
1850
+ owner,
1851
+ escrow: context.escrow,
1852
+ orchestrator: context.orchestrator,
1853
+ inputCount
1854
+ });
1855
+ }
1856
+ attemptedRead = true;
1857
+ try {
1858
+ const args = inputCount >= 3 ? [context.escrow, context.orchestrator, owner] : [context.orchestrator, owner];
1859
+ const raw = await this.config.getPublicClient().readContract({
1860
+ address: pvEntry.address,
1861
+ abi: pvEntry.abi,
1862
+ functionName: "getAccountIntents",
1863
+ args
1864
+ });
1865
+ hadSuccessfulRead = true;
1866
+ for (const item of raw) {
1867
+ const parsed = parseIntentView2(item);
1868
+ if (!this.config.host.isProtocolViewerIntentPopulated(parsed)) continue;
1869
+ intentsByHash.set(parsed.intentHash.toLowerCase(), parsed);
1870
+ }
1871
+ } catch (readError) {
1872
+ lastError = readError;
1873
+ if (isDebugLoggingEnabled) {
1874
+ console.warn("[Zkp2pClient] getPvAccountIntents context read failed", {
1875
+ protocolViewerAddress: pvEntry.address,
1876
+ owner,
1877
+ escrow: context.escrow,
1878
+ orchestrator: context.orchestrator,
1879
+ inputCount,
1880
+ error: readError instanceof Error ? readError.message : String(readError)
1881
+ });
1882
+ }
1883
+ }
1884
+ }
1885
+ } else {
1886
+ if (isDebugLoggingEnabled) {
1887
+ console.debug("[Zkp2pClient] getPvAccountIntents read legacy context", {
1888
+ protocolViewerAddress: pvEntry.address,
1889
+ owner,
1890
+ inputCount
1891
+ });
1892
+ }
1893
+ attemptedRead = true;
1894
+ try {
1895
+ const raw = await this.config.getPublicClient().readContract({
1896
+ address: pvEntry.address,
1897
+ abi: pvEntry.abi,
1898
+ functionName: "getAccountIntents",
1899
+ args: [owner]
1900
+ });
1901
+ hadSuccessfulRead = true;
1902
+ for (const item of raw) {
1903
+ const parsed = parseIntentView2(item);
1904
+ if (!this.config.host.isProtocolViewerIntentPopulated(parsed)) continue;
1905
+ if (!intentsByHash.has(parsed.intentHash.toLowerCase())) {
1906
+ intentsByHash.set(parsed.intentHash.toLowerCase(), parsed);
1907
+ }
1908
+ }
1909
+ } catch (readError) {
1910
+ lastError = readError;
1911
+ if (isDebugLoggingEnabled) {
1912
+ console.warn("[Zkp2pClient] getPvAccountIntents legacy read failed", {
1913
+ protocolViewerAddress: pvEntry.address,
1914
+ owner,
1915
+ inputCount,
1916
+ error: readError instanceof Error ? readError.message : String(readError)
1917
+ });
1918
+ }
1919
+ }
1920
+ }
1921
+ }
1922
+ if (!hadSuccessfulRead && attemptedRead && lastError) {
1923
+ throw lastError;
1924
+ }
1925
+ if (!attemptedRead && isDebugLoggingEnabled) {
1926
+ console.warn(
1927
+ "[Zkp2pClient] getPvAccountIntents did not execute any reads; verify ProtocolViewer ABI/configuration"
1928
+ );
1929
+ }
1930
+ return Array.from(intentsByHash.values()).sort((left, right) => {
1931
+ if (left.intent.timestamp === right.intent.timestamp) {
1932
+ return left.intentHash.localeCompare(right.intentHash);
1933
+ }
1934
+ return left.intent.timestamp < right.intent.timestamp ? -1 : 1;
1935
+ });
1936
+ }
1937
+ async getPvIntent(intentHash) {
1938
+ const protocolViewerEntries = this.config.getProtocolViewerEntries();
1939
+ if (protocolViewerEntries.length === 0) {
1940
+ throw new Error("ProtocolViewer not available for this network");
1941
+ }
1942
+ const { parseIntentView: parseIntentView2 } = await import('./protocolViewerParsers-QVG4JP23.mjs');
1943
+ let lastError;
1944
+ for (const pvEntry of protocolViewerEntries) {
1945
+ const inputCount = this.pvEntryFunctionInputCount(pvEntry, "getIntent");
1946
+ if (inputCount === null) continue;
1947
+ if (inputCount >= 2) {
1948
+ let routing = {};
1949
+ try {
1950
+ routing = await this.config.host.lookupIntentRouting(intentHash);
1951
+ } catch (routingError) {
1952
+ lastError = routingError;
1953
+ }
1954
+ for (const context of this.config.host.buildProtocolViewerContexts({
1955
+ escrowAddress: routing.escrowAddress,
1956
+ orchestratorAddress: routing.orchestratorAddress
1957
+ })) {
1958
+ try {
1959
+ const args = inputCount >= 3 ? [context.escrow, context.orchestrator, intentHash] : [context.orchestrator, intentHash];
1960
+ const raw = await this.config.getPublicClient().readContract({
1961
+ address: pvEntry.address,
1962
+ abi: pvEntry.abi,
1963
+ functionName: "getIntent",
1964
+ args
1965
+ });
1966
+ const parsed = parseIntentView2(raw);
1967
+ if (this.config.host.isProtocolViewerIntentPopulated(parsed)) {
1968
+ return parsed;
1969
+ }
1970
+ lastError = new Error("Intent not found");
1971
+ } catch (readError) {
1972
+ lastError = readError;
1973
+ }
1974
+ }
1975
+ } else {
1976
+ try {
1977
+ const raw = await this.config.getPublicClient().readContract({
1978
+ address: pvEntry.address,
1979
+ abi: pvEntry.abi,
1980
+ functionName: "getIntent",
1981
+ args: [intentHash]
1982
+ });
1983
+ const parsed = parseIntentView2(raw);
1984
+ if (this.config.host.isProtocolViewerIntentPopulated(parsed)) {
1985
+ return parsed;
1986
+ }
1987
+ lastError = new Error("Intent not found");
1988
+ } catch (readError) {
1989
+ lastError = readError;
1990
+ }
1991
+ }
1992
+ }
1993
+ throw lastError ?? new Error("Intent not found");
1994
+ }
1995
+ };
1996
+
1997
+ // src/client/VaultOperations.ts
1998
+ var VaultOperations = class {
1999
+ constructor(config) {
2000
+ this.config = config;
2001
+ }
2002
+ supportsInlineOracleRateConfig(params) {
2003
+ const escrowContext = this.config.host.resolveEscrowContext({
2004
+ escrowAddress: params?.escrowAddress,
2005
+ preferV2: params?.preferV2
2006
+ });
2007
+ return escrowCurrencyHasOracleConfig(escrowContext.abi);
2008
+ }
2009
+ resolveRateManagerRegistryContract(registryAddress) {
2010
+ const abi = this.config.getRateManagerRegistryAbi();
2011
+ if (!abi) {
2012
+ throw this.buildRateManagerUnavailableError("Rate manager registry not available");
2013
+ }
2014
+ if (registryAddress) {
2015
+ return {
2016
+ address: registryAddress,
2017
+ abi
2018
+ };
2019
+ }
2020
+ const address = this.config.getRateManagerRegistryAddress();
2021
+ if (!address) {
2022
+ throw this.buildRateManagerUnavailableError("Rate manager registry not available");
2023
+ }
2024
+ return {
2025
+ address,
2026
+ abi
2027
+ };
2028
+ }
2029
+ buildRateManagerUnavailableError(reason) {
2030
+ const initError = this.config.getRateManagerInitError();
2031
+ if (!initError) {
2032
+ return new Error(reason);
2033
+ }
2034
+ return new Error(
2035
+ `${reason}. Rate manager contracts failed to initialize: ${initError.message}`
2036
+ );
2037
+ }
2038
+ buildCreateRateManagerConfig(config) {
2039
+ const registryAbi = this.config.getRateManagerRegistryAbi();
2040
+ const includeDepositHook = abiTupleHasComponent(
2041
+ registryAbi,
2042
+ "createRateManager",
2043
+ "depositHook"
2044
+ );
2045
+ const includeMinLiquidity = abiTupleHasComponent(
2046
+ registryAbi,
2047
+ "createRateManager",
2048
+ "minLiquidity"
2049
+ );
2050
+ const result = {
2051
+ manager: config.manager,
2052
+ feeRecipient: config.feeRecipient,
2053
+ maxFee: config.maxFee,
2054
+ fee: config.fee
2055
+ };
2056
+ if (includeDepositHook) {
2057
+ result.depositHook = config.depositHook ?? ZERO_ADDRESS;
2058
+ }
2059
+ if (includeMinLiquidity) {
2060
+ result.minLiquidity = config.minLiquidity ?? 0n;
2061
+ }
2062
+ result.name = config.name;
2063
+ result.uri = config.uri;
2064
+ return result;
2065
+ }
2066
+ buildSetRateManagerConfigArgs(params) {
2067
+ const registryAbi = this.config.getRateManagerRegistryAbi();
2068
+ const includeHook = abiFunctionHasInput(registryAbi, "setRateManagerConfig", "_newHook") || abiFunctionHasInput(registryAbi, "setRateManagerConfig", "newHook");
2069
+ if (includeHook) {
2070
+ return [
2071
+ params.rateManagerId,
2072
+ params.newManager,
2073
+ params.newFeeRecipient,
2074
+ params.newHook ?? ZERO_ADDRESS,
2075
+ params.newName,
2076
+ params.newUri
2077
+ ];
2078
+ }
2079
+ return [
2080
+ params.rateManagerId,
2081
+ params.newManager,
2082
+ params.newFeeRecipient,
2083
+ params.newName,
2084
+ params.newUri
2085
+ ];
2086
+ }
2087
+ prepareRateManagerRegistryTransaction(opts) {
2088
+ const contract = this.resolveRateManagerRegistryContract(opts.registry);
2089
+ const functionName = resolveAbiFunctionName(contract.abi, opts.functionNames);
2090
+ return this.config.host.prepareContractTransaction({
2091
+ address: contract.address,
2092
+ abi: contract.abi,
2093
+ functionName,
2094
+ args: opts.args,
2095
+ txOverrides: opts.txOverrides
2096
+ });
2097
+ }
2098
+ prepareCreateRateManagerTransaction(params) {
2099
+ return this.prepareRateManagerRegistryTransaction({
2100
+ functionNames: ["createRateManager"],
2101
+ args: [this.buildCreateRateManagerConfig(params.config)],
2102
+ txOverrides: params.txOverrides
2103
+ });
2104
+ }
2105
+ prepareSetVaultRateTransaction(params) {
2106
+ return this.prepareRateManagerRegistryTransaction({
2107
+ functionNames: ["setRate", "setMinRate"],
2108
+ args: [params.rateManagerId, params.paymentMethodHash, params.currencyHash, params.rate],
2109
+ txOverrides: params.txOverrides
2110
+ });
2111
+ }
2112
+ prepareSetVaultRatesBatchTransaction(params) {
2113
+ return this.prepareRateManagerRegistryTransaction({
2114
+ functionNames: ["setRateBatch", "setMinRatesBatch"],
2115
+ args: [params.rateManagerId, params.paymentMethods, params.currencies, params.rates],
2116
+ txOverrides: params.txOverrides
2117
+ });
2118
+ }
2119
+ prepareSetOracleRateConfigTransaction(params) {
2120
+ const escrowContext = this.config.host.resolveEscrowContext({
2121
+ escrowAddress: params.escrowAddress,
2122
+ depositId: params.depositId,
2123
+ preferV2: true
2124
+ });
2125
+ if (escrowContext.version !== "v2") {
2126
+ throw new Error("setOracleRateConfig requires EscrowV2");
2127
+ }
2128
+ const functionName = resolveAbiFunctionName(escrowContext.abi, ["setOracleRateConfig"]);
2129
+ return this.config.host.prepareEscrowTransaction({
2130
+ functionName,
2131
+ args: [
2132
+ parseRawDepositId(params.depositId),
2133
+ params.paymentMethodHash,
2134
+ params.currencyHash,
2135
+ normalizeOracleRateConfig(params.config)
2136
+ ],
2137
+ txOverrides: params.txOverrides,
2138
+ escrowAddress: escrowContext.address,
2139
+ escrowAbi: escrowContext.abi
2140
+ });
2141
+ }
2142
+ prepareRemoveOracleRateConfigTransaction(params) {
2143
+ const escrowContext = this.config.host.resolveEscrowContext({
2144
+ escrowAddress: params.escrowAddress,
2145
+ depositId: params.depositId,
2146
+ preferV2: true
2147
+ });
2148
+ if (escrowContext.version !== "v2") {
2149
+ throw new Error("removeOracleRateConfig requires EscrowV2");
2150
+ }
2151
+ const functionName = resolveAbiFunctionName(escrowContext.abi, ["removeOracleRateConfig"]);
2152
+ return this.config.host.prepareEscrowTransaction({
2153
+ functionName,
2154
+ args: [parseRawDepositId(params.depositId), params.paymentMethodHash, params.currencyHash],
2155
+ txOverrides: params.txOverrides,
2156
+ escrowAddress: escrowContext.address,
2157
+ escrowAbi: escrowContext.abi
2158
+ });
2159
+ }
2160
+ prepareSetOracleRateConfigBatchTransaction(params) {
2161
+ const escrowContext = this.config.host.resolveEscrowContext({
2162
+ escrowAddress: params.escrowAddress,
2163
+ depositId: params.depositId,
2164
+ preferV2: true
2165
+ });
2166
+ if (escrowContext.version !== "v2") {
2167
+ throw new Error("setOracleRateConfigBatch requires EscrowV2");
2168
+ }
2169
+ const functionName = resolveAbiFunctionName(escrowContext.abi, ["setOracleRateConfigBatch"]);
2170
+ return this.config.host.prepareEscrowTransaction({
2171
+ functionName,
2172
+ args: [
2173
+ parseRawDepositId(params.depositId),
2174
+ params.paymentMethods,
2175
+ params.currencies,
2176
+ params.configs.map((group) => group.map((config) => normalizeOracleRateConfig(config)))
2177
+ ],
2178
+ txOverrides: params.txOverrides,
2179
+ escrowAddress: escrowContext.address,
2180
+ escrowAbi: escrowContext.abi
2181
+ });
2182
+ }
2183
+ prepareUpdateCurrencyConfigBatchTransaction(params) {
2184
+ const escrowContext = this.config.host.resolveEscrowContext({
2185
+ escrowAddress: params.escrowAddress,
2186
+ depositId: params.depositId,
2187
+ preferV2: true
2188
+ });
2189
+ if (escrowContext.version !== "v2") {
2190
+ throw new Error("updateCurrencyConfigBatch requires EscrowV2");
2191
+ }
2192
+ const functionName = resolveAbiFunctionName(escrowContext.abi, ["updateCurrencyConfigBatch"]);
2193
+ return this.config.host.prepareEscrowTransaction({
2194
+ functionName,
2195
+ args: [
2196
+ parseRawDepositId(params.depositId),
2197
+ params.paymentMethods,
2198
+ params.updates.map(
2199
+ (group) => group.map((update) => ({
2200
+ code: update.code,
2201
+ minConversionRate: typeof update.minConversionRate === "bigint" ? update.minConversionRate : BigInt(update.minConversionRate),
2202
+ updateOracle: update.updateOracle,
2203
+ oracleRateConfig: normalizeOracleRateConfig(update.oracleRateConfig)
2204
+ }))
2205
+ )
2206
+ ],
2207
+ txOverrides: params.txOverrides,
2208
+ escrowAddress: escrowContext.address,
2209
+ escrowAbi: escrowContext.abi
2210
+ });
2211
+ }
2212
+ prepareDeactivateCurrenciesBatchTransaction(params) {
2213
+ const escrowContext = this.config.host.resolveEscrowContext({
2214
+ escrowAddress: params.escrowAddress,
2215
+ depositId: params.depositId,
2216
+ preferV2: true
2217
+ });
2218
+ if (escrowContext.version !== "v2") {
2219
+ throw new Error("deactivateCurrenciesBatch requires EscrowV2");
2220
+ }
2221
+ const functionName = resolveAbiFunctionName(escrowContext.abi, ["deactivateCurrenciesBatch"]);
2222
+ return this.config.host.prepareEscrowTransaction({
2223
+ functionName,
2224
+ args: [parseRawDepositId(params.depositId), params.paymentMethods, params.currencyCodes],
2225
+ txOverrides: params.txOverrides,
2226
+ escrowAddress: escrowContext.address,
2227
+ escrowAbi: escrowContext.abi
2228
+ });
2229
+ }
2230
+ prepareSetVaultConfigTransaction(params) {
2231
+ return this.prepareRateManagerRegistryTransaction({
2232
+ functionNames: ["setRateManagerConfig"],
2233
+ args: this.buildSetRateManagerConfigArgs(params),
2234
+ txOverrides: params.txOverrides
2235
+ });
2236
+ }
2237
+ async getDepositRateManager(escrow, depositId) {
2238
+ const id = parseRawDepositId(depositId);
2239
+ const escrowContext = this.config.host.resolveEscrowContext({
2240
+ escrowAddress: escrow,
2241
+ depositId
2242
+ });
2243
+ if (getRateManagerReadFunction(escrowContext.abi, "getDepositRateManager")) {
2244
+ const result = await this.config.getPublicClient().readContract({
2245
+ address: escrowContext.address,
2246
+ abi: escrowContext.abi,
2247
+ functionName: "getDepositRateManager",
2248
+ args: [id]
2249
+ });
2250
+ if (result && result.length >= 2) {
2251
+ return {
2252
+ registry: result[0],
2253
+ rateManagerId: result[1]
2254
+ };
2255
+ }
2256
+ }
2257
+ const controllerAddress = this.config.getRateManagerControllerAddress();
2258
+ const controllerAbi = this.config.getRateManagerControllerAbi();
2259
+ if (!controllerAddress || !controllerAbi) {
2260
+ throw this.buildRateManagerUnavailableError("Rate manager controller not available");
2261
+ }
2262
+ const legacyResult = await this.config.getPublicClient().readContract({
2263
+ address: controllerAddress,
2264
+ abi: controllerAbi,
2265
+ functionName: "getDepositRateManager",
2266
+ args: [escrow, id]
2267
+ });
2268
+ return {
2269
+ registry: legacyResult[0],
2270
+ rateManagerId: legacyResult[1]
2271
+ };
2272
+ }
2273
+ async getManagerFee(escrow, depositId) {
2274
+ const id = parseRawDepositId(depositId);
2275
+ const escrowContext = this.config.host.resolveEscrowContext({
2276
+ escrowAddress: escrow,
2277
+ depositId
2278
+ });
2279
+ if (getRateManagerReadFunction(escrowContext.abi, "getManagerFee")) {
2280
+ const result2 = await this.config.getPublicClient().readContract({
2281
+ address: escrowContext.address,
2282
+ abi: escrowContext.abi,
2283
+ functionName: "getManagerFee",
2284
+ args: [id]
2285
+ });
2286
+ return parseManagerFeeFromRead(result2);
2287
+ }
2288
+ const controllerAddress = this.config.getRateManagerControllerAddress();
2289
+ const controllerAbi = this.config.getRateManagerControllerAbi();
2290
+ if (!controllerAddress || !controllerAbi) {
2291
+ throw this.buildRateManagerUnavailableError("Rate manager controller not available");
2292
+ }
2293
+ const result = await this.config.getPublicClient().readContract({
2294
+ address: controllerAddress,
2295
+ abi: controllerAbi,
2296
+ functionName: "getManagerFee",
2297
+ args: [escrow, id]
2298
+ });
2299
+ return parseManagerFeeFromRead(result);
2300
+ }
2301
+ async getEffectiveRate(params) {
2302
+ const escrowContext = this.config.host.resolveEscrowContext({
2303
+ escrowAddress: params.escrow,
2304
+ depositId: params.depositId
2305
+ });
2306
+ const id = parseRawDepositId(params.depositId);
2307
+ return await this.config.getPublicClient().readContract({
2308
+ address: escrowContext.address,
2309
+ abi: escrowContext.abi,
2310
+ functionName: "getEffectiveRate",
2311
+ args: [id, params.paymentMethod, params.fiatCurrency]
2312
+ });
2313
+ }
2314
+ };
2315
+ var getRateManagerReadFunction = (abi, functionName) => Array.isArray(abi) && abi.some(
2316
+ (item) => item.type === "function" && item.name === functionName
2317
+ );
2318
+
2319
+ // src/indexer/client.ts
2320
+ var IndexerHttpError = class extends Error {
2321
+ constructor(status, statusText, options) {
2322
+ super(`Indexer request failed: ${status} ${statusText}`);
2323
+ this.name = "IndexerHttpError";
2324
+ this.status = status;
2325
+ this.retryAfterSeconds = options?.retryAfterSeconds;
2326
+ }
2327
+ };
2328
+ function parseRetryAfterSeconds(rawHeader) {
2329
+ if (!rawHeader) return void 0;
2330
+ const parsedSeconds = Number(rawHeader);
2331
+ if (Number.isFinite(parsedSeconds) && parsedSeconds >= 0) {
2332
+ return Math.ceil(parsedSeconds);
2333
+ }
2334
+ const parsedDateMs = Date.parse(rawHeader);
2335
+ if (!Number.isFinite(parsedDateMs)) return void 0;
2336
+ const secondsUntilRetry = Math.ceil((parsedDateMs - Date.now()) / 1e3);
2337
+ return Math.max(0, secondsUntilRetry);
2338
+ }
2339
+ function createAbortError() {
2340
+ const error = new Error("The operation was aborted");
2341
+ error.name = "AbortError";
2342
+ return error;
2343
+ }
2344
+ function delay(ms, signal) {
2345
+ if (ms <= 0) {
2346
+ return Promise.resolve();
2347
+ }
2348
+ return new Promise((resolve, reject) => {
2349
+ if (signal?.aborted) {
2350
+ reject(createAbortError());
2351
+ return;
2352
+ }
2353
+ const timer = setTimeout(() => {
2354
+ signal?.removeEventListener("abort", onAbort);
2355
+ resolve();
2356
+ }, ms);
2357
+ const onAbort = () => {
2358
+ clearTimeout(timer);
2359
+ signal?.removeEventListener("abort", onAbort);
2360
+ reject(createAbortError());
2361
+ };
2362
+ signal?.addEventListener("abort", onAbort);
2363
+ });
2364
+ }
2365
+ var IndexerClient = class {
2366
+ constructor(endpoint, options = {}) {
2367
+ this.endpoint = endpoint;
2368
+ this.options = options;
2369
+ this.hasLoggedTokenProviderError = false;
2370
+ }
2371
+ async resolveAuthorizationToken() {
2372
+ if (this.options.getAuthorizationToken) {
2373
+ try {
2374
+ const token = await this.options.getAuthorizationToken();
2375
+ return token ?? void 0;
2376
+ } catch (error) {
2377
+ if (this.options.onAuthorizationTokenError) {
2378
+ this.options.onAuthorizationTokenError(error);
2379
+ } else if (!this.hasLoggedTokenProviderError) {
2380
+ this.hasLoggedTokenProviderError = true;
2381
+ console.warn(
2382
+ "[IndexerClient] getAuthorizationToken failed; continuing without Authorization header",
2383
+ error
2384
+ );
2385
+ }
2386
+ return void 0;
2387
+ }
2388
+ }
2389
+ return this.options.authorizationToken;
2390
+ }
2391
+ async _post(request, init) {
2392
+ const token = await this.resolveAuthorizationToken();
2393
+ const headers2 = new Headers(init?.headers);
2394
+ if (!headers2.has("Content-Type")) {
2395
+ headers2.set("Content-Type", "application/json");
2396
+ }
2397
+ if (token && !headers2.has("Authorization")) {
2398
+ headers2.set("Authorization", token.startsWith("Bearer ") ? token : `Bearer ${token}`);
2399
+ }
2400
+ if (this.options.apiKey && !headers2.has("x-api-key")) {
2401
+ headers2.set("x-api-key", this.options.apiKey);
2402
+ }
2403
+ const res = await fetch(this.endpoint, {
2404
+ method: "POST",
2405
+ headers: headers2,
2406
+ body: JSON.stringify(request),
2407
+ cache: "no-store",
2408
+ ...init
2409
+ });
2410
+ if (!res.ok) {
2411
+ throw new IndexerHttpError(res.status, res.statusText, {
2412
+ retryAfterSeconds: parseRetryAfterSeconds(res.headers.get("Retry-After"))
2413
+ });
2414
+ }
2415
+ const json = await res.json();
2416
+ if (json.errors?.length) {
2417
+ const msg = json.errors.map((e) => e.message).join(", ");
2418
+ throw new Error(`GraphQL errors: ${msg}`);
2419
+ }
2420
+ if (!json.data) throw new Error("No data returned from indexer");
2421
+ return json.data;
2422
+ }
2423
+ async query(request, init) {
2424
+ const retries = Math.max(0, init?.retries ?? 1);
2425
+ const rateLimitRetries = Math.max(0, init?.rateLimitRetries ?? 2);
2426
+ const maxAttempts = 1 + Math.max(retries, rateLimitRetries);
2427
+ const {
2428
+ retries: _unusedRetries,
2429
+ rateLimitRetries: _unusedRateLimitRetries,
2430
+ ...requestInit
2431
+ } = init ?? {};
2432
+ let attempts = 0;
2433
+ let rateLimitAttempt = 0;
389
2434
  let standardRetryAttempt = 0;
390
2435
  let lastErr;
391
2436
  while (attempts < maxAttempts) {
@@ -1442,6 +3487,21 @@ function normalizeAddress2(value) {
1442
3487
  if (!value) return ZERO;
1443
3488
  return value.startsWith("0x") ? value : ZERO;
1444
3489
  }
3490
+ function resolveActiveConversionRate(currency) {
3491
+ const candidates = [
3492
+ currency.effectiveOracleRate,
3493
+ currency.conversionRate,
3494
+ currency.minConversionRate
3495
+ ];
3496
+ for (const candidate of candidates) {
3497
+ if (candidate === null || candidate === void 0) continue;
3498
+ const parsed = toBigInt(candidate);
3499
+ if (parsed > 0n) {
3500
+ return candidate;
3501
+ }
3502
+ }
3503
+ return currency.effectiveOracleRate ?? currency.conversionRate ?? currency.minConversionRate;
3504
+ }
1445
3505
  function extractDepositId(compositeId) {
1446
3506
  const parts = compositeId.split("_");
1447
3507
  return parts[1] || "0";
@@ -1469,7 +3529,7 @@ function convertIndexerDepositToEscrowView(deposit, _chainId, _escrowAddress) {
1469
3529
  },
1470
3530
  currencies: (currenciesByPaymentMethod.get(pm.paymentMethodHash) ?? []).map((cur) => ({
1471
3531
  code: cur.currencyCode,
1472
- conversionRate: toBigInt(cur.conversionRate ?? cur.minConversionRate)
3532
+ conversionRate: toBigInt(resolveActiveConversionRate(cur))
1473
3533
  })),
1474
3534
  methodHash: pm.paymentMethodHash
1475
3535
  }));
@@ -1525,6 +3585,14 @@ function convertIndexerIntentsToEscrowViews(intents, depositViewsById) {
1525
3585
  return result;
1526
3586
  }
1527
3587
 
3588
+ // src/indexer/schemaCompatibility.ts
3589
+ function isSchemaCompatibilityError(error) {
3590
+ if (!(error instanceof Error)) return false;
3591
+ const message = error.message.toLowerCase();
3592
+ if (!message.includes("graphql errors")) return false;
3593
+ return message.includes("cannot query field") || message.includes("does not exist") || message.includes("not found in type");
3594
+ }
3595
+
1528
3596
  // src/indexer/service.ts
1529
3597
  function groupByDepositId(items) {
1530
3598
  const map = /* @__PURE__ */ new Map();
@@ -1539,13 +3607,7 @@ function groupByDepositId(items) {
1539
3607
  }
1540
3608
  var DEFAULT_LIMIT = 100;
1541
3609
  var DEFAULT_ORDER_FIELD = "remainingDeposits";
1542
- var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
1543
- function isSchemaCompatibilityError(error) {
1544
- if (!(error instanceof Error)) return false;
1545
- const message = error.message.toLowerCase();
1546
- if (!message.includes("graphql errors")) return false;
1547
- return message.includes("cannot query field") || message.includes("does not exist") || message.includes("not found in type");
1548
- }
3610
+ var ZERO_ADDRESS3 = "0x0000000000000000000000000000000000000000";
1549
3611
  var IndexerDepositService = class {
1550
3612
  constructor(client) {
1551
3613
  this.client = client;
@@ -1574,7 +3636,7 @@ var IndexerDepositService = class {
1574
3636
  if (filter.delegate) {
1575
3637
  where.delegate = { _ilike: filter.delegate };
1576
3638
  } else if (filter.delegateIsSet !== void 0) {
1577
- where.delegate = filter.delegateIsSet ? { _neq: ZERO_ADDRESS } : { _eq: ZERO_ADDRESS };
3639
+ where.delegate = filter.delegateIsSet ? { _neq: ZERO_ADDRESS3 } : { _eq: ZERO_ADDRESS3 };
1578
3640
  }
1579
3641
  if (filter.chainId) where.chainId = { _eq: filter.chainId };
1580
3642
  if (filter.escrowAddresses && filter.escrowAddresses.length) {
@@ -1912,12 +3974,6 @@ function normalizeRateManagerId2(value) {
1912
3974
  if (!value) return "";
1913
3975
  return value.toLowerCase();
1914
3976
  }
1915
- function isSchemaCompatibilityError2(error) {
1916
- if (!(error instanceof Error)) return false;
1917
- const message = error.message.toLowerCase();
1918
- if (!message.includes("graphql errors")) return false;
1919
- return message.includes("cannot query field") || message.includes("does not exist") || message.includes("not found in type");
1920
- }
1921
3977
  function normalizeAddress3(value) {
1922
3978
  if (!value) return "";
1923
3979
  return value.toLowerCase();
@@ -2217,7 +4273,7 @@ var IndexerRateManagerService = class {
2217
4273
  offset += RATE_MANAGER_HISTORY_PAGE_SIZE;
2218
4274
  }
2219
4275
  } catch (error) {
2220
- if (!isSchemaCompatibilityError2(error)) {
4276
+ if (!isSchemaCompatibilityError(error)) {
2221
4277
  throw error;
2222
4278
  }
2223
4279
  }
@@ -2326,7 +4382,7 @@ var IndexerRateManagerService = class {
2326
4382
  (stats) => (normalizeAddress3(stats.rateManagerAddress) || extractRateManagerAddressFromScopedId(stats.id)) === scopedRateManagerAddress
2327
4383
  ) ?? result.ManagerAggregateStats?.[0] ?? null;
2328
4384
  } catch (error) {
2329
- if (!isSchemaCompatibilityError2(error)) {
4385
+ if (!isSchemaCompatibilityError(error)) {
2330
4386
  throw error;
2331
4387
  }
2332
4388
  const legacyResult = await this.client.query({
@@ -2380,7 +4436,7 @@ var IndexerRateManagerService = class {
2380
4436
  });
2381
4437
  return (result.Deposit ?? []).map((deposit) => toDelegationEntityFromDeposit(deposit)).filter((delegation) => Boolean(delegation));
2382
4438
  } catch (error) {
2383
- if (!isSchemaCompatibilityError2(error)) {
4439
+ if (!isSchemaCompatibilityError(error)) {
2384
4440
  throw error;
2385
4441
  }
2386
4442
  const legacyResult = await this.client.query({
@@ -2418,7 +4474,7 @@ var IndexerRateManagerService = class {
2418
4474
  });
2419
4475
  return result.ManagerDailySnapshot ?? [];
2420
4476
  } catch (error) {
2421
- if (!isSchemaCompatibilityError2(error)) {
4477
+ if (!isSchemaCompatibilityError(error)) {
2422
4478
  throw error;
2423
4479
  }
2424
4480
  return [];
@@ -2440,7 +4496,7 @@ var IndexerRateManagerService = class {
2440
4496
  }
2441
4497
  return toDelegationEntityFromDeposit(delegationDeposit) ?? null;
2442
4498
  } catch (error) {
2443
- if (!isSchemaCompatibilityError2(error)) {
4499
+ if (!isSchemaCompatibilityError(error)) {
2444
4500
  throw error;
2445
4501
  }
2446
4502
  const legacyResult = await this.client.query({
@@ -2481,7 +4537,7 @@ var IndexerRateManagerService = class {
2481
4537
  minRate: e.minRate ?? e.rate ?? "0"
2482
4538
  })).sort((a, b) => compareEventCursorIdsByRecency(a.id, b.id));
2483
4539
  } catch (error) {
2484
- if (!isSchemaCompatibilityError2(error)) {
4540
+ if (!isSchemaCompatibilityError(error)) {
2485
4541
  throw error;
2486
4542
  }
2487
4543
  return [];
@@ -2536,7 +4592,7 @@ var IndexerRateManagerService = class {
2536
4592
  spreadBps: e.spreadBps ?? 0
2537
4593
  })).sort((a, b) => compareEventCursorIdsByRecency(a.id, b.id));
2538
4594
  } catch (error) {
2539
- if (isSchemaCompatibilityError2(error)) ; else {
4595
+ if (isSchemaCompatibilityError(error)) ; else {
2540
4596
  throw error;
2541
4597
  }
2542
4598
  const legacyResult = await this.client.query({
@@ -2573,162 +4629,7 @@ async function fetchFulfillmentAndPayment(client, intentHash) {
2573
4629
  return client.query({
2574
4630
  query: FULFILLMENT_AND_PAYMENT_QUERY,
2575
4631
  variables: { intentHash }
2576
- });
2577
- }
2578
-
2579
- // src/errors/utils.ts
2580
- function parseAPIError(response, responseText) {
2581
- let message = `Request failed: ${response.statusText}`;
2582
- try {
2583
- const parsed = responseText ? JSON.parse(responseText) : void 0;
2584
- if (parsed && (parsed.error || parsed.message)) {
2585
- message = parsed.error || parsed.message;
2586
- }
2587
- } catch {
2588
- if (responseText && responseText.length < 200) message = responseText;
2589
- }
2590
- if (response.status === 429) {
2591
- message = "Too many requests. Please try again later.";
2592
- }
2593
- return new APIError(message, response.status, { url: response.url });
2594
- }
2595
- async function withRetry(fn, maxRetries = 3, delayMs = 1e3, timeoutMs) {
2596
- let lastErr;
2597
- for (let i = 0; i < maxRetries; i++) {
2598
- try {
2599
- if (timeoutMs) {
2600
- const { withTimeout } = await import('./timeout-QB7K5SOB.mjs');
2601
- return await withTimeout(fn(), timeoutMs, `Operation timed out after ${timeoutMs}ms`);
2602
- }
2603
- return await fn();
2604
- } catch (err) {
2605
- lastErr = err;
2606
- const isNetwork = err instanceof NetworkError;
2607
- const isRateLimit = err instanceof APIError && err.status === 429;
2608
- const retryable = isNetwork || isRateLimit;
2609
- if (!retryable || i === maxRetries - 1) throw err;
2610
- const base2 = isRateLimit ? delayMs * Math.pow(2, i) : delayMs;
2611
- const jitter = Math.floor(Math.random() * Math.min(1e3, base2));
2612
- await new Promise((r) => setTimeout(r, base2 + jitter));
2613
- }
2614
- }
2615
- throw lastErr;
2616
- }
2617
-
2618
- // src/adapters/verification.ts
2619
- function createHeaders(apiKey, authorizationToken) {
2620
- const headers2 = { "Content-Type": "application/json" };
2621
- if (apiKey) headers2["x-api-key"] = apiKey;
2622
- if (authorizationToken)
2623
- headers2["Authorization"] = authorizationToken.startsWith("Bearer ") ? authorizationToken : `Bearer ${authorizationToken}`;
2624
- return headers2;
2625
- }
2626
- async function postSignIntentWithRetry(endpoint, request, opts) {
2627
- const url = `${opts.baseApiUrl.replace(/\/$/, "")}${endpoint}`;
2628
- return withRetry(
2629
- async () => {
2630
- let res;
2631
- try {
2632
- res = await fetch(url, {
2633
- method: "POST",
2634
- headers: createHeaders(opts.apiKey, opts.authorizationToken),
2635
- body: JSON.stringify(request)
2636
- });
2637
- } catch (error) {
2638
- throw new NetworkError("Failed to connect to API server", { endpoint, error });
2639
- }
2640
- if (!res.ok) {
2641
- const text = await res.text().catch(() => "");
2642
- throw parseAPIError(res, text);
2643
- }
2644
- return await res.json();
2645
- },
2646
- 3,
2647
- 1e3,
2648
- opts.timeoutMs
2649
- );
2650
- }
2651
- async function apiSignIntentV3(request, opts) {
2652
- const json = await postSignIntentWithRetry("/v3/intent", request, opts);
2653
- const sig = json?.responseObject?.signedIntent;
2654
- const expStr = json?.responseObject?.intentData?.signatureExpiration ?? json?.responseObject?.signatureExpiration;
2655
- const preIntentHookData = json?.responseObject?.intentData?.preIntentHookData ?? json?.responseObject?.preIntentHookData;
2656
- if (!sig || !expStr) throw new Error("v3/intent missing signature or expiration");
2657
- return {
2658
- signature: sig,
2659
- signatureExpiration: BigInt(expStr),
2660
- preIntentHookData
2661
- };
2662
- }
2663
- async function apiSignIntentV2(request, opts) {
2664
- const json = await postSignIntentWithRetry(
2665
- "/v2/verify/intent",
2666
- request,
2667
- opts
2668
- );
2669
- const sig = json?.responseObject?.signedIntent;
2670
- const expStr = json?.responseObject?.intentData?.signatureExpiration ?? json?.responseObject?.signatureExpiration;
2671
- const preIntentHookData = json?.responseObject?.intentData?.preIntentHookData ?? json?.responseObject?.preIntentHookData;
2672
- if (!sig || !expStr) throw new Error("verify/intent missing signature or expiration");
2673
- return {
2674
- signature: sig,
2675
- signatureExpiration: BigInt(expStr),
2676
- preIntentHookData
2677
- };
2678
- }
2679
-
2680
- // src/adapters/attestation.ts
2681
- function headers() {
2682
- return { "Content-Type": "application/json" };
2683
- }
2684
- async function apiCreatePaymentAttestation(payload, attestationServiceUrl, platform, actionType) {
2685
- return withRetry(async () => {
2686
- let res;
2687
- try {
2688
- const endpoint = `/verify/${encodeURIComponent(platform)}/${encodeURIComponent(actionType)}`;
2689
- res = await fetch(`${attestationServiceUrl}${endpoint}`, {
2690
- method: "POST",
2691
- headers: headers(),
2692
- body: JSON.stringify(payload)
2693
- });
2694
- } catch (error) {
2695
- throw new NetworkError("Failed to connect to Attestation Service", {
2696
- endpoint: `/verify/${platform}/${actionType}`,
2697
- error
2698
- });
2699
- }
2700
- if (!res.ok) {
2701
- const errorText = await res.text();
2702
- throw parseAPIError(res, errorText);
2703
- }
2704
- return res.json();
2705
- });
2706
- }
2707
- var abiCoder = AbiCoder.defaultAbiCoder();
2708
- function encodeVerifyPaymentData(params) {
2709
- return abiCoder.encode(
2710
- ["tuple(bytes32,bytes,bytes)"],
2711
- [[params.intentHash, params.paymentProof, params.data]]
2712
- );
2713
- }
2714
- function encodeAddressAsBytes(addr) {
2715
- return abiCoder.encode(["address"], [addr]);
2716
- }
2717
- function encodePaymentAttestation(attestation) {
2718
- const resp = attestation.responseObject;
2719
- const td = resp.typedDataValue;
2720
- const intentHash = td.intentHash;
2721
- const releaseAmount = BigInt(td.releaseAmount);
2722
- const dataHash = td.dataHash;
2723
- const signatures = [resp.signature];
2724
- const encodedPaymentDetails = resp.encodedPaymentDetails;
2725
- if (!intentHash || !releaseAmount || !dataHash || !encodedPaymentDetails) {
2726
- throw new Error("Attestation response missing required fields");
2727
- }
2728
- return abiCoder.encode(
2729
- ["tuple(bytes32,uint256,bytes32,bytes[],bytes,bytes)"],
2730
- [[intentHash, releaseAmount, dataHash, signatures, encodedPaymentDetails, "0x"]]
2731
- );
4632
+ });
2732
4633
  }
2733
4634
 
2734
4635
  // src/adapters/api.ts
@@ -2986,7 +4887,7 @@ async function apiGetOwnerDeposits(req, apiKey, baseApiUrl, authToken, timeoutMs
2986
4887
  statusCode: 200
2987
4888
  };
2988
4889
  }
2989
- async function apiGetTakerTier(req, apiKey, baseApiUrl, authToken, timeoutMs) {
4890
+ async function apiGetTakerTier(req, apiKey, baseApiUrl, timeoutMs) {
2990
4891
  const normalizedOwner = req.owner.toLowerCase();
2991
4892
  const query = new URLSearchParams({
2992
4893
  owner: normalizedOwner,
@@ -2997,10 +4898,102 @@ async function apiGetTakerTier(req, apiKey, baseApiUrl, authToken, timeoutMs) {
2997
4898
  url: `${withApiBase(baseApiUrl)}${endpoint}`,
2998
4899
  method: "GET",
2999
4900
  apiKey,
3000
- authToken,
3001
4901
  timeoutMs
3002
4902
  });
3003
4903
  }
4904
+ var formatTokenAmountForDisplay = (amount, decimals) => {
4905
+ const formatted = formatUnits(amount, decimals);
4906
+ if (!formatted.includes(".")) {
4907
+ return formatted;
4908
+ }
4909
+ const trimmed = formatted.replace(/\.?0+$/, "");
4910
+ return trimmed.length > 0 ? trimmed : "0";
4911
+ };
4912
+ var applyReferrerFeeDisplayFieldsToTokenAmount = (tokenAmount, referrerFeeConfig, decimals) => {
4913
+ try {
4914
+ const grossAmount = BigInt(tokenAmount);
4915
+ const feeAmount = grossAmount * BigInt(referrerFeeConfig.feeBps) / 10000n;
4916
+ const netAmount = grossAmount - feeAmount;
4917
+ return {
4918
+ tokenAmount: netAmount.toString(),
4919
+ tokenAmountFormatted: formatTokenAmountForDisplay(netAmount, decimals),
4920
+ referrerFeeAmount: feeAmount.toString(),
4921
+ referrerFeeAmountFormatted: formatTokenAmountForDisplay(feeAmount, decimals),
4922
+ referrerFeeBps: referrerFeeConfig.feeBps,
4923
+ signalIntentAmount: grossAmount.toString(),
4924
+ signalIntentAmountFormatted: formatTokenAmountForDisplay(grossAmount, decimals)
4925
+ };
4926
+ } catch {
4927
+ return null;
4928
+ }
4929
+ };
4930
+ var applyReferrerFeeDisplayFieldsToQuote = (quote, referrerFeeConfig, decimals) => {
4931
+ const adjusted = applyReferrerFeeDisplayFieldsToTokenAmount(
4932
+ quote.tokenAmount,
4933
+ referrerFeeConfig,
4934
+ decimals
4935
+ );
4936
+ if (!adjusted) {
4937
+ return quote;
4938
+ }
4939
+ return {
4940
+ ...quote,
4941
+ ...adjusted
4942
+ };
4943
+ };
4944
+ var appendReferrerFeeDisplayFields = (quoteResponse, referrerFeeConfig) => {
4945
+ if (!referrerFeeConfig) {
4946
+ return quoteResponse;
4947
+ }
4948
+ const decimals = quoteResponse.responseObject?.token?.decimals ?? 6;
4949
+ const enrichedQuotes = (quoteResponse.responseObject?.quotes ?? []).map(
4950
+ (quote) => applyReferrerFeeDisplayFieldsToQuote(quote, referrerFeeConfig, decimals)
4951
+ );
4952
+ const enrichedNearbySuggestions = quoteResponse.responseObject?.nearbySuggestions ? {
4953
+ below: quoteResponse.responseObject.nearbySuggestions.below.map((suggestion) => {
4954
+ const adjustedSuggestionAmount = suggestion.suggestedTokenAmount ? applyReferrerFeeDisplayFieldsToTokenAmount(
4955
+ suggestion.suggestedTokenAmount,
4956
+ referrerFeeConfig,
4957
+ decimals
4958
+ ) : null;
4959
+ return {
4960
+ ...suggestion,
4961
+ suggestedTokenAmount: adjustedSuggestionAmount?.tokenAmount ?? suggestion.suggestedTokenAmount,
4962
+ suggestedTokenAmountFormatted: adjustedSuggestionAmount?.tokenAmountFormatted ?? suggestion.suggestedTokenAmountFormatted,
4963
+ quote: applyReferrerFeeDisplayFieldsToQuote(
4964
+ suggestion.quote,
4965
+ referrerFeeConfig,
4966
+ decimals
4967
+ )
4968
+ };
4969
+ }),
4970
+ above: quoteResponse.responseObject.nearbySuggestions.above.map((suggestion) => {
4971
+ const adjustedSuggestionAmount = suggestion.suggestedTokenAmount ? applyReferrerFeeDisplayFieldsToTokenAmount(
4972
+ suggestion.suggestedTokenAmount,
4973
+ referrerFeeConfig,
4974
+ decimals
4975
+ ) : null;
4976
+ return {
4977
+ ...suggestion,
4978
+ suggestedTokenAmount: adjustedSuggestionAmount?.tokenAmount ?? suggestion.suggestedTokenAmount,
4979
+ suggestedTokenAmountFormatted: adjustedSuggestionAmount?.tokenAmountFormatted ?? suggestion.suggestedTokenAmountFormatted,
4980
+ quote: applyReferrerFeeDisplayFieldsToQuote(
4981
+ suggestion.quote,
4982
+ referrerFeeConfig,
4983
+ decimals
4984
+ )
4985
+ };
4986
+ })
4987
+ } : void 0;
4988
+ return {
4989
+ ...quoteResponse,
4990
+ responseObject: {
4991
+ ...quoteResponse.responseObject,
4992
+ quotes: enrichedQuotes,
4993
+ nearbySuggestions: enrichedNearbySuggestions
4994
+ }
4995
+ };
4996
+ };
3004
4997
 
3005
4998
  // src/utils/erc20.ts
3006
4999
  var ERC20_ABI = [
@@ -3025,72 +5018,9 @@ var ERC20_ABI = [
3025
5018
  outputs: [{ name: "success", type: "bool" }]
3026
5019
  }
3027
5020
  ];
3028
- var BASE_BUILDER_CODE = "bc_nbn6qkni";
3029
- var ZKP2P_IOS_REFERRER = "zkp2p-ios";
3030
- var ZKP2P_ANDROID_REFERRER = "zkp2p-android";
3031
- function getAttributionDataSuffix(referrer) {
3032
- const codes = [];
3033
- if (referrer) {
3034
- if (Array.isArray(referrer)) {
3035
- codes.push(...referrer);
3036
- } else {
3037
- codes.push(referrer);
3038
- }
3039
- }
3040
- codes.push(BASE_BUILDER_CODE);
3041
- return Attribution.toDataSuffix({ codes });
3042
- }
3043
- function appendAttributionToCalldata(calldata, referrer) {
3044
- const suffix = getAttributionDataSuffix(referrer);
3045
- return concatHex([calldata, suffix]);
3046
- }
3047
- function encodeWithAttribution(request, referrer) {
3048
- const functionData = encodeFunctionData({
3049
- abi: request.abi,
3050
- functionName: request.functionName,
3051
- args: request.args || []
3052
- });
3053
- return appendAttributionToCalldata(functionData, referrer);
3054
- }
3055
- async function sendTransactionWithAttribution(walletClient, request, referrer, overrides) {
3056
- const functionData = encodeFunctionData({
3057
- abi: request.abi,
3058
- functionName: request.functionName,
3059
- args: request.args || []
3060
- });
3061
- const dataWithAttribution = appendAttributionToCalldata(functionData, referrer);
3062
- const {
3063
- gas,
3064
- gasPrice,
3065
- maxFeePerGas,
3066
- maxPriorityFeePerGas,
3067
- nonce,
3068
- value,
3069
- accessList,
3070
- authorizationList
3071
- } = overrides ?? {};
3072
- const optionalOverrides = {
3073
- ...gas !== void 0 ? { gas } : {},
3074
- ...gasPrice !== void 0 ? { gasPrice } : {},
3075
- ...maxFeePerGas !== void 0 ? { maxFeePerGas } : {},
3076
- ...maxPriorityFeePerGas !== void 0 ? { maxPriorityFeePerGas } : {},
3077
- ...nonce !== void 0 ? { nonce } : {},
3078
- ...accessList !== void 0 ? { accessList } : {},
3079
- ...authorizationList !== void 0 ? { authorizationList } : {}
3080
- };
3081
- return walletClient.sendTransaction({
3082
- to: request.address,
3083
- data: dataWithAttribution,
3084
- value: value ?? request.value,
3085
- account: walletClient.account,
3086
- chain: walletClient.chain,
3087
- ...optionalOverrides
3088
- });
3089
- }
3090
5021
 
3091
5022
  // src/client/Zkp2pClient.ts
3092
- var ZERO_ADDRESS2 = "0x0000000000000000000000000000000000000000";
3093
- var _Zkp2pClient = class _Zkp2pClient {
5023
+ var Zkp2pClient = class {
3094
5024
  /**
3095
5025
  * Creates a new Zkp2pClient instance.
3096
5026
  *
@@ -3199,6 +5129,46 @@ var _Zkp2pClient = class _Zkp2pClient {
3199
5129
  }
3200
5130
  }
3201
5131
  );
5132
+ /**
5133
+ * Batch update currency min-rate and oracle-config entries for an EscrowV2 deposit.
5134
+ */
5135
+ this.updateCurrencyConfigBatch = Object.assign(
5136
+ async (params) => {
5137
+ const prepared = this.prepareUpdateCurrencyConfigBatchTransaction(params);
5138
+ return this.executePreparedTransaction(prepared, params.txOverrides);
5139
+ },
5140
+ {
5141
+ prepare: async (params) => {
5142
+ const prepared = this.prepareUpdateCurrencyConfigBatchTransaction(params);
5143
+ return {
5144
+ to: prepared.to,
5145
+ data: prepared.data,
5146
+ value: prepared.value,
5147
+ chainId: prepared.chainId
5148
+ };
5149
+ }
5150
+ }
5151
+ );
5152
+ /**
5153
+ * Batch deactivate currencies for an EscrowV2 deposit.
5154
+ */
5155
+ this.deactivateCurrenciesBatch = Object.assign(
5156
+ async (params) => {
5157
+ const prepared = this.prepareDeactivateCurrenciesBatchTransaction(params);
5158
+ return this.executePreparedTransaction(prepared, params.txOverrides);
5159
+ },
5160
+ {
5161
+ prepare: async (params) => {
5162
+ const prepared = this.prepareDeactivateCurrenciesBatchTransaction(params);
5163
+ return {
5164
+ to: prepared.to,
5165
+ data: prepared.data,
5166
+ value: prepared.value,
5167
+ chainId: prepared.chainId
5168
+ };
5169
+ }
5170
+ }
5171
+ );
3202
5172
  /**
3203
5173
  * Adds additional funds to an existing deposit.
3204
5174
  * Requires prior approval of the token amount.
@@ -3612,8 +5582,9 @@ var _Zkp2pClient = class _Zkp2pClient {
3612
5582
  * @param params.payeeDetails - Hashed payee details (from deposit)
3613
5583
  * @param params.fiatCurrencyCode - Fiat currency code (e.g., 'USD', 'EUR')
3614
5584
  * @param params.conversionRate - Agreed conversion rate (18 decimals)
3615
- * @param params.referrer - Optional referrer address for fee sharing
3616
- * @param params.referrerFee - Optional referrer fee amount
5585
+ * @param params.referralFees - Optional referral fee recipients and fee amounts
5586
+ * @param params.referrer - Deprecated legacy single-referrer address
5587
+ * @param params.referrerFee - Deprecated legacy single-referrer fee amount
3617
5588
  * @param params.postIntentHook - Optional hook contract to call after signaling
3618
5589
  * @param params.data - Optional data to pass to the hook
3619
5590
  * @param params.gatingServiceSignature - Pre-obtained signature (if not auto-fetching)
@@ -3976,7 +5947,8 @@ var _Zkp2pClient = class _Zkp2pClient {
3976
5947
  if (!this.rateManagerControllerAbi && rateManagerContracts.abis.controller) {
3977
5948
  this.rateManagerControllerAbi = rateManagerContracts.abis.controller;
3978
5949
  }
3979
- } catch {
5950
+ } catch (error) {
5951
+ this._rateManagerInitError = error instanceof Error ? error : new Error(String(error));
3980
5952
  }
3981
5953
  }
3982
5954
  this._router = new ContractRouter({
@@ -4015,316 +5987,144 @@ var _Zkp2pClient = class _Zkp2pClient {
4015
5987
  this.apiKey = opts.apiKey;
4016
5988
  this.authorizationToken = opts.authorizationToken;
4017
5989
  this.apiTimeoutMs = opts.timeouts?.api ?? 15e3;
5990
+ this._pvReader = new ProtocolViewerReader({
5991
+ getPublicClient: () => this.publicClient,
5992
+ getProtocolViewerAddress: () => this.protocolViewerAddress,
5993
+ getProtocolViewerAbi: () => this.protocolViewerAbi,
5994
+ getProtocolViewerEntries: () => this._protocolViewerEntries,
5995
+ getEscrowAddresses: () => this.escrowAddresses,
5996
+ getIndexerService: () => this._indexerService,
5997
+ getRouterBuildProtocolViewerContexts: () => this._router.buildProtocolViewerContexts.bind(this._router),
5998
+ host: {
5999
+ requireProtocolViewer: () => this.requireProtocolViewer(),
6000
+ protocolViewerFunctionInputCount: (functionName) => this.protocolViewerFunctionInputCount(functionName),
6001
+ buildProtocolViewerContexts: (options) => this.buildProtocolViewerContexts(options),
6002
+ isProtocolViewerDepositPopulated: (view) => this.isProtocolViewerDepositPopulated(view),
6003
+ isProtocolViewerIntentPopulated: (view) => this.isProtocolViewerIntentPopulated(view),
6004
+ buildDepositViewFromEscrowDeposit: (rawDeposit, depositId) => this.buildDepositViewFromEscrowDeposit(rawDeposit, depositId),
6005
+ getPvAccountDepositsFromIndexer: (owner) => this.getPvAccountDepositsFromIndexer(owner),
6006
+ getPvDepositById: (depositId, options) => options === void 0 ? this.getPvDepositById(depositId) : this.getPvDepositById(depositId, options),
6007
+ getEscrowContexts: () => this.getEscrowContexts(),
6008
+ lookupIntentRouting: (intentHash) => this.lookupIntentRouting(intentHash)
6009
+ }
6010
+ });
6011
+ this._vaultOps = new VaultOperations({
6012
+ getPublicClient: () => this.publicClient,
6013
+ getRateManagerRegistryAddress: () => this.rateManagerRegistryAddress,
6014
+ getRateManagerRegistryAbi: () => this.rateManagerRegistryAbi,
6015
+ getRateManagerControllerAddress: () => this.rateManagerControllerAddress,
6016
+ getRateManagerControllerAbi: () => this.rateManagerControllerAbi,
6017
+ getRateManagerInitError: () => this._rateManagerInitError,
6018
+ host: {
6019
+ resolveEscrowContext: (options) => this.resolveEscrowContext(options),
6020
+ prepareEscrowTransaction: (tx) => this.prepareEscrowTransaction(tx),
6021
+ prepareContractTransaction: (tx) => this.prepareContractTransaction(tx)
6022
+ }
6023
+ });
6024
+ this._intentOps = new IntentOperations({
6025
+ getWalletClient: () => this.walletClient,
6026
+ getPublicClient: () => this.publicClient,
6027
+ getChainId: () => this.chainId,
6028
+ getRuntimeEnv: () => this.runtimeEnv,
6029
+ getBaseApiUrl: () => this.baseApiUrl,
6030
+ getApiKey: () => this.apiKey,
6031
+ getAuthorizationToken: () => this.authorizationToken,
6032
+ getApiTimeoutMs: () => this.apiTimeoutMs,
6033
+ getProtocolViewerAddress: () => this.protocolViewerAddress,
6034
+ getProtocolViewerAbi: () => this.protocolViewerAbi,
6035
+ getIndexerClient: () => this._indexerClient,
6036
+ getIndexerService: () => this._indexerService,
6037
+ getDefaultPreferV2: () => this._router.defaultPreferV2,
6038
+ host: {
6039
+ resolveEscrowContext: (options) => this.resolveEscrowContext(options),
6040
+ resolveOrchestratorContext: (options) => this.resolveOrchestratorContext(options),
6041
+ resolveEscrowAddressOrThrow: (escrowAddress, depositId, methodName, options) => this.resolveEscrowAddressOrThrow(escrowAddress, depositId, methodName, options),
6042
+ prepareResolvedOrchestratorTransaction: (tx) => this.prepareResolvedOrchestratorTransaction(tx),
6043
+ getFulfillIntentInputs: (intentHash) => this.getFulfillIntentInputs(intentHash),
6044
+ getPvIntent: (intentHash) => this.getPvIntent(intentHash)
6045
+ }
6046
+ });
4018
6047
  }
4019
6048
  isValidHexAddress(addr) {
4020
- if (typeof addr !== "string") return false;
4021
- return /^0x[0-9a-fA-F]{40}$/.test(addr);
6049
+ return isValidHexAddress(addr);
4022
6050
  }
4023
6051
  normalizeAddress(addr) {
4024
- if (!this.isValidHexAddress(addr)) return void 0;
4025
- return addr;
6052
+ return normalizeAddress(addr);
4026
6053
  }
4027
6054
  parseEscrowAddressFromCompositeDepositId(depositId) {
4028
- if (typeof depositId !== "string") return void 0;
4029
- const parts = depositId.split("_");
4030
- if (parts.length < 2) return void 0;
4031
- const maybeEscrow = parts.length >= 3 ? parts[parts.length - 2] : parts[0];
4032
- return this.normalizeAddress(maybeEscrow);
6055
+ return parseEscrowAddressFromCompositeDepositId(depositId);
4033
6056
  }
4034
6057
  parseRawDepositId(depositId) {
4035
- if (typeof depositId === "bigint") return depositId;
4036
- if (typeof depositId === "number") return parseBigIntLike(depositId, "Invalid deposit id");
4037
- const parts = depositId.split("_");
4038
- const raw = parts[parts.length - 1] ?? depositId;
4039
- return parseBigIntLike(raw, "Invalid deposit id");
6058
+ return parseRawDepositId(depositId);
4040
6059
  }
4041
6060
  normalizeOracleRateConfig(config) {
4042
- const spreadBps = Number(config.spreadBps);
4043
- if (!Number.isFinite(spreadBps) || spreadBps < 0 || spreadBps > 65535) {
4044
- throw new Error("Oracle spreadBps must be between 0 and 65535");
4045
- }
4046
- const maxStaleness = Number(config.maxStaleness);
4047
- if (!Number.isFinite(maxStaleness) || maxStaleness < 0 || maxStaleness > 4294967295) {
4048
- throw new Error("Oracle maxStaleness must be between 0 and 4294967295");
4049
- }
4050
- return {
4051
- adapter: config.adapter,
4052
- adapterConfig: config.adapterConfig,
4053
- spreadBps: Math.round(spreadBps),
4054
- maxStaleness: Math.round(maxStaleness)
4055
- };
6061
+ return normalizeOracleRateConfig(config);
4056
6062
  }
4057
- /**
4058
- * Checks whether the Currency struct in the ABI includes an `oracleRateConfig` component.
4059
- * This is a deep check: createDeposit takes a top-level tuple with a `currencies` field
4060
- * that is a tuple[][] — each inner tuple is a Currency struct.
4061
- */
4062
6063
  escrowCurrencyHasOracleConfig(abi) {
4063
- if (!Array.isArray(abi)) return false;
4064
- const fnNames = ["createDeposit", "addPaymentMethods", "addCurrencies"];
4065
- for (const fnName of fnNames) {
4066
- const fn = abi.find(
4067
- (item) => item.type === "function" && item.name === fnName
4068
- );
4069
- if (!fn) continue;
4070
- const inputs = fn.inputs ?? [];
4071
- const hasCurrencyOracle = (items) => {
4072
- for (const item of items) {
4073
- const components = item.components ?? [];
4074
- if (components.some((c) => c.name === "code") && components.some((c) => c.name === "oracleRateConfig")) {
4075
- return true;
4076
- }
4077
- if (components.length > 0 && hasCurrencyOracle(components)) return true;
4078
- }
4079
- return false;
4080
- };
4081
- if (hasCurrencyOracle(inputs)) return true;
4082
- }
4083
- return false;
6064
+ return escrowCurrencyHasOracleConfig(abi);
4084
6065
  }
4085
6066
  /**
4086
6067
  * Normalizes currency tuples by appending an empty `oracleRateConfig` when the ABI
4087
6068
  * requires it and the caller hasn't provided one.
4088
6069
  */
4089
6070
  normalizeCurrencyTuples(currencies, escrowAbi) {
4090
- const needsOracle = this.escrowCurrencyHasOracleConfig(escrowAbi);
4091
- if (!needsOracle) {
4092
- return currencies.map((c) => ({
4093
- code: c.code,
4094
- minConversionRate: c.minConversionRate
4095
- }));
4096
- }
4097
- return currencies.map((c) => ({
4098
- code: c.code,
4099
- minConversionRate: c.minConversionRate,
4100
- oracleRateConfig: c.oracleRateConfig ? this.normalizeOracleRateConfig(c.oracleRateConfig) : _Zkp2pClient.EMPTY_ORACLE_RATE_CONFIG
4101
- }));
6071
+ return normalizeCurrencyTuples(currencies, escrowAbi);
4102
6072
  }
4103
6073
  supportsInlineOracleRateConfig(params) {
4104
- const escrowContext = this.resolveEscrowContext({
6074
+ return this._vaultOps.supportsInlineOracleRateConfig({
4105
6075
  escrowAddress: params?.escrowAddress,
4106
6076
  preferV2: params?.preferV2 ?? this._router.defaultPreferV2
4107
6077
  });
4108
- return this.escrowCurrencyHasOracleConfig(escrowContext.abi);
4109
6078
  }
4110
6079
  parseManagerFeeFromRead(result) {
4111
- if (Array.isArray(result)) {
4112
- const candidate = result.length > 1 ? result[1] : result[0];
4113
- return parseBigIntLike(candidate, "Unexpected numeric response");
4114
- }
4115
- return parseBigIntLike(result, "Unexpected numeric response");
6080
+ return parseManagerFeeFromRead(result);
4116
6081
  }
4117
6082
  getAbiFunction(abi, ...names) {
4118
- if (!Array.isArray(abi)) return null;
4119
- for (const name of names) {
4120
- const match = abi.find(
4121
- (item) => item.type === "function" && item.name === name
4122
- );
4123
- if (match) return match;
4124
- }
4125
- return null;
6083
+ return getAbiFunction(abi, ...names);
4126
6084
  }
4127
6085
  resolveAbiFunctionName(abi, names) {
4128
- const match = this.getAbiFunction(abi, ...names);
4129
- const resolved = match?.name;
4130
- if (typeof resolved === "string") return resolved;
4131
- throw new Error(`Contract does not expose any of: ${names.join(", ")}`);
6086
+ return resolveAbiFunctionName(abi, names);
4132
6087
  }
4133
6088
  abiTupleHasComponent(abi, functionName, componentName) {
4134
- const fn = this.getAbiFunction(abi, functionName);
4135
- const inputs = fn?.inputs ?? [];
4136
- const tupleInput = inputs.find((input) => input.type === "tuple");
4137
- const components = tupleInput?.components ?? [];
4138
- return components.some((component) => component.name === componentName);
6089
+ return abiTupleHasComponent(abi, functionName, componentName);
4139
6090
  }
4140
6091
  abiFunctionHasInput(abi, functionName, inputName) {
4141
- const fn = this.getAbiFunction(abi, functionName);
4142
- const inputs = fn?.inputs ?? [];
4143
- return inputs.some((input) => input.name === inputName);
6092
+ return abiFunctionHasInput(abi, functionName, inputName);
4144
6093
  }
4145
6094
  resolveEscrowAddressOrThrow(escrowAddress, depositId, methodName, options) {
4146
- const resolved = escrowAddress ?? this.parseEscrowAddressFromCompositeDepositId(depositId);
4147
- if (resolved) return resolved;
4148
- if (options?.preferV2 !== void 0) {
4149
- return this.resolveEscrowContext({ preferV2: options.preferV2 }).address;
4150
- }
4151
- throw new Error(`${methodName} requires escrowAddress or composite depositId`);
4152
- }
4153
- resolveRateManagerRegistryContract(registryAddress) {
4154
- if (!this.rateManagerRegistryAbi) {
4155
- throw new Error("Rate manager registry not available");
4156
- }
4157
- if (registryAddress) {
4158
- return {
4159
- address: registryAddress,
4160
- abi: this.rateManagerRegistryAbi
4161
- };
4162
- }
4163
- if (!this.rateManagerRegistryAddress) {
4164
- throw new Error("Rate manager registry not available");
4165
- }
4166
- return {
4167
- address: this.rateManagerRegistryAddress,
4168
- abi: this.rateManagerRegistryAbi
4169
- };
4170
- }
4171
- buildCreateRateManagerConfig(config) {
4172
- const includeDepositHook = this.abiTupleHasComponent(
4173
- this.rateManagerRegistryAbi,
4174
- "createRateManager",
4175
- "depositHook"
4176
- );
4177
- const includeMinLiquidity = this.abiTupleHasComponent(
4178
- this.rateManagerRegistryAbi,
4179
- "createRateManager",
4180
- "minLiquidity"
4181
- );
4182
- const result = {
4183
- manager: config.manager,
4184
- feeRecipient: config.feeRecipient,
4185
- maxFee: config.maxFee,
4186
- fee: config.fee
4187
- };
4188
- if (includeDepositHook) {
4189
- result.depositHook = config.depositHook ?? ZERO_ADDRESS2;
4190
- }
4191
- if (includeMinLiquidity) {
4192
- result.minLiquidity = config.minLiquidity ?? 0n;
4193
- }
4194
- result.name = config.name;
4195
- result.uri = config.uri;
4196
- return result;
4197
- }
4198
- buildSetRateManagerConfigArgs(params) {
4199
- const includeHook = this.abiFunctionHasInput(this.rateManagerRegistryAbi, "setRateManagerConfig", "_newHook") || this.abiFunctionHasInput(this.rateManagerRegistryAbi, "setRateManagerConfig", "newHook");
4200
- if (includeHook) {
4201
- return [
4202
- params.rateManagerId,
4203
- params.newManager,
4204
- params.newFeeRecipient,
4205
- params.newHook ?? ZERO_ADDRESS2,
4206
- params.newName,
4207
- params.newUri
4208
- ];
4209
- }
4210
- return [
4211
- params.rateManagerId,
4212
- params.newManager,
4213
- params.newFeeRecipient,
4214
- params.newName,
4215
- params.newUri
4216
- ];
4217
- }
4218
- prepareRateManagerRegistryTransaction(opts) {
4219
- const contract = this.resolveRateManagerRegistryContract(opts.registry);
4220
- const functionName = this.resolveAbiFunctionName(contract.abi, opts.functionNames);
4221
- return this.prepareContractTransaction({
4222
- address: contract.address,
4223
- abi: contract.abi,
4224
- functionName,
4225
- args: opts.args,
4226
- txOverrides: opts.txOverrides
4227
- });
4228
- }
4229
- prepareCreateRateManagerTransaction(params) {
4230
- return this.prepareRateManagerRegistryTransaction({
4231
- functionNames: ["createRateManager"],
4232
- args: [this.buildCreateRateManagerConfig(params.config)],
4233
- txOverrides: params.txOverrides
4234
- });
4235
- }
4236
- prepareSetVaultRateTransaction(params) {
4237
- return this.prepareRateManagerRegistryTransaction({
4238
- functionNames: ["setRate", "setMinRate"],
4239
- args: [params.rateManagerId, params.paymentMethodHash, params.currencyHash, params.rate],
4240
- txOverrides: params.txOverrides
4241
- });
4242
- }
4243
- prepareSetVaultRatesBatchTransaction(params) {
4244
- return this.prepareRateManagerRegistryTransaction({
4245
- functionNames: ["setRateBatch", "setMinRatesBatch"],
4246
- args: [params.rateManagerId, params.paymentMethods, params.currencies, params.rates],
4247
- txOverrides: params.txOverrides
4248
- });
4249
- }
4250
- prepareSetOracleRateConfigTransaction(params) {
4251
- const escrowContext = this.resolveEscrowContext({
4252
- escrowAddress: params.escrowAddress,
4253
- depositId: params.depositId,
4254
- preferV2: true
4255
- });
4256
- if (escrowContext.version !== "v2") {
4257
- throw new Error("setOracleRateConfig requires EscrowV2");
4258
- }
4259
- const functionName = this.resolveAbiFunctionName(escrowContext.abi, ["setOracleRateConfig"]);
4260
- return this.prepareEscrowTransaction({
4261
- functionName,
4262
- args: [
4263
- this.parseRawDepositId(params.depositId),
4264
- params.paymentMethodHash,
4265
- params.currencyHash,
4266
- this.normalizeOracleRateConfig(params.config)
4267
- ],
4268
- txOverrides: params.txOverrides,
4269
- escrowAddress: escrowContext.address,
4270
- escrowAbi: escrowContext.abi
4271
- });
6095
+ const resolved = escrowAddress ?? this.parseEscrowAddressFromCompositeDepositId(depositId);
6096
+ if (resolved) return resolved;
6097
+ if (options?.preferV2 !== void 0) {
6098
+ return this.resolveEscrowContext({ preferV2: options.preferV2 }).address;
6099
+ }
6100
+ throw new Error(`${methodName} requires escrowAddress or composite depositId`);
6101
+ }
6102
+ prepareCreateRateManagerTransaction(params) {
6103
+ return this._vaultOps.prepareCreateRateManagerTransaction(params);
6104
+ }
6105
+ prepareSetVaultRateTransaction(params) {
6106
+ return this._vaultOps.prepareSetVaultRateTransaction(params);
6107
+ }
6108
+ prepareSetVaultRatesBatchTransaction(params) {
6109
+ return this._vaultOps.prepareSetVaultRatesBatchTransaction(params);
6110
+ }
6111
+ prepareSetOracleRateConfigTransaction(params) {
6112
+ return this._vaultOps.prepareSetOracleRateConfigTransaction(params);
4272
6113
  }
4273
6114
  prepareRemoveOracleRateConfigTransaction(params) {
4274
- const escrowContext = this.resolveEscrowContext({
4275
- escrowAddress: params.escrowAddress,
4276
- depositId: params.depositId,
4277
- preferV2: true
4278
- });
4279
- if (escrowContext.version !== "v2") {
4280
- throw new Error("removeOracleRateConfig requires EscrowV2");
4281
- }
4282
- const functionName = this.resolveAbiFunctionName(escrowContext.abi, ["removeOracleRateConfig"]);
4283
- return this.prepareEscrowTransaction({
4284
- functionName,
4285
- args: [
4286
- this.parseRawDepositId(params.depositId),
4287
- params.paymentMethodHash,
4288
- params.currencyHash
4289
- ],
4290
- txOverrides: params.txOverrides,
4291
- escrowAddress: escrowContext.address,
4292
- escrowAbi: escrowContext.abi
4293
- });
6115
+ return this._vaultOps.prepareRemoveOracleRateConfigTransaction(params);
4294
6116
  }
4295
6117
  prepareSetOracleRateConfigBatchTransaction(params) {
4296
- const escrowContext = this.resolveEscrowContext({
4297
- escrowAddress: params.escrowAddress,
4298
- depositId: params.depositId,
4299
- preferV2: true
4300
- });
4301
- if (escrowContext.version !== "v2") {
4302
- throw new Error("setOracleRateConfigBatch requires EscrowV2");
4303
- }
4304
- const functionName = this.resolveAbiFunctionName(escrowContext.abi, [
4305
- "setOracleRateConfigBatch"
4306
- ]);
4307
- return this.prepareEscrowTransaction({
4308
- functionName,
4309
- args: [
4310
- this.parseRawDepositId(params.depositId),
4311
- params.paymentMethods,
4312
- params.currencies,
4313
- params.configs.map(
4314
- (group) => group.map((config) => this.normalizeOracleRateConfig(config))
4315
- )
4316
- ],
4317
- txOverrides: params.txOverrides,
4318
- escrowAddress: escrowContext.address,
4319
- escrowAbi: escrowContext.abi
4320
- });
6118
+ return this._vaultOps.prepareSetOracleRateConfigBatchTransaction(params);
6119
+ }
6120
+ prepareUpdateCurrencyConfigBatchTransaction(params) {
6121
+ return this._vaultOps.prepareUpdateCurrencyConfigBatchTransaction(params);
6122
+ }
6123
+ prepareDeactivateCurrenciesBatchTransaction(params) {
6124
+ return this._vaultOps.prepareDeactivateCurrenciesBatchTransaction(params);
4321
6125
  }
4322
6126
  prepareSetVaultConfigTransaction(params) {
4323
- return this.prepareRateManagerRegistryTransaction({
4324
- functionNames: ["setRateManagerConfig"],
4325
- args: this.buildSetRateManagerConfigArgs(params),
4326
- txOverrides: params.txOverrides
4327
- });
6127
+ return this._vaultOps.prepareSetVaultConfigTransaction(params);
4328
6128
  }
4329
6129
  getEscrowContextByAddress(address) {
4330
6130
  return this._router.getEscrowContextByAddress(address);
@@ -4346,6 +6146,7 @@ var _Zkp2pClient = class _Zkp2pClient {
4346
6146
  }
4347
6147
  const rawDepositId = this.parseRawDepositId(options.depositId);
4348
6148
  const matches = [];
6149
+ const probeErrors = [];
4349
6150
  for (const context of contexts) {
4350
6151
  try {
4351
6152
  const raw = await this.publicClient.readContract({
@@ -4358,7 +6159,8 @@ var _Zkp2pClient = class _Zkp2pClient {
4358
6159
  if (this.isProtocolViewerDepositPopulated(parsed)) {
4359
6160
  matches.push(context);
4360
6161
  }
4361
- } catch {
6162
+ } catch (error) {
6163
+ probeErrors.push(error);
4362
6164
  }
4363
6165
  }
4364
6166
  if (matches.length === 1) {
@@ -4369,6 +6171,12 @@ var _Zkp2pClient = class _Zkp2pClient {
4369
6171
  `${options?.methodName ?? "Deposit mutation"} is ambiguous for depositId ${rawDepositId.toString()}: found in multiple escrows. Pass escrowAddress or composite depositId.`
4370
6172
  );
4371
6173
  }
6174
+ if (probeErrors.length > 0) {
6175
+ const probeFailureMessage = probeErrors.map((error) => error instanceof Error ? error.message : String(error)).join("; ");
6176
+ throw new Error(
6177
+ `${options?.methodName ?? "Deposit mutation"} could not verify depositId ${rawDepositId.toString()} across configured escrows because one or more escrow probes failed: ${probeFailureMessage}`
6178
+ );
6179
+ }
4372
6180
  return this.resolveEscrowContext(options);
4373
6181
  }
4374
6182
  getEscrowContexts() {
@@ -4400,18 +6208,29 @@ var _Zkp2pClient = class _Zkp2pClient {
4400
6208
  const orchestratorAddress = this.normalizeAddress(intent?.orchestratorAddress ?? void 0);
4401
6209
  const escrowAddress = intent?.depositId && intent.depositId.includes("_") ? this.parseEscrowAddressFromCompositeDepositId(intent.depositId) : void 0;
4402
6210
  return { orchestratorAddress, escrowAddress };
4403
- } catch {
4404
- return {};
6211
+ } catch (error) {
6212
+ const message = error instanceof Error ? error.message : "Unknown indexer routing error";
6213
+ throw new Error(`Failed to resolve intent routing for ${intentHash}: ${message}`);
4405
6214
  }
4406
6215
  }
4407
6216
  async lookupIntentEscrowOnchain(intentHash) {
4408
6217
  try {
4409
6218
  const view = await this.getPvIntent(intentHash);
4410
6219
  return this.normalizeAddress(view?.intent?.escrow);
4411
- } catch {
4412
- return void 0;
6220
+ } catch (error) {
6221
+ if (error instanceof Error && error.message === "Intent not found") {
6222
+ return void 0;
6223
+ }
6224
+ const message = error instanceof Error ? error.message : "Unknown on-chain routing error";
6225
+ throw new Error(`Failed to resolve intent escrow on-chain for ${intentHash}: ${message}`);
4413
6226
  }
4414
6227
  }
6228
+ warnOrchestratorFallback(intentHash, source, error) {
6229
+ const message = error instanceof Error ? error.message : "Unknown routing error";
6230
+ console.warn(
6231
+ `[Zkp2pClient] ${source} failed for ${intentHash}; continuing with configured orchestrator fallback. ${message}`
6232
+ );
6233
+ }
4415
6234
  async resolveOrchestratorContext(options) {
4416
6235
  const explicit = this.getOrchestratorContextByAddress(options?.orchestratorAddress);
4417
6236
  if (explicit) return explicit;
@@ -4434,17 +6253,32 @@ var _Zkp2pClient = class _Zkp2pClient {
4434
6253
  return { address: addr, abi, version };
4435
6254
  }
4436
6255
  if (options?.intentHash) {
4437
- const routing = await this.lookupIntentRouting(options.intentHash);
4438
- const fromIntent = this.getOrchestratorContextByAddress(routing.orchestratorAddress);
4439
- if (fromIntent) return fromIntent;
4440
- const fromIntentEscrow = this.resolveOrchestratorForEscrow(
4441
- routing.escrowAddress,
4442
- options.preferV2
4443
- );
4444
- if (fromIntentEscrow) return fromIntentEscrow;
4445
- const onchainEscrow = await this.lookupIntentEscrowOnchain(options.intentHash);
4446
- const fromOnchainEscrow = this.resolveOrchestratorForEscrow(onchainEscrow, options.preferV2);
4447
- if (fromOnchainEscrow) return fromOnchainEscrow;
6256
+ try {
6257
+ const routing = await this.lookupIntentRouting(options.intentHash);
6258
+ const fromIntent = this.getOrchestratorContextByAddress(routing.orchestratorAddress);
6259
+ if (fromIntent) return fromIntent;
6260
+ if (routing.escrowAddress) {
6261
+ const fromIntentEscrow = this.resolveOrchestratorForEscrow(
6262
+ routing.escrowAddress,
6263
+ options.preferV2
6264
+ );
6265
+ if (fromIntentEscrow) return fromIntentEscrow;
6266
+ }
6267
+ } catch (error) {
6268
+ this.warnOrchestratorFallback(options.intentHash, "Indexer intent routing lookup", error);
6269
+ }
6270
+ try {
6271
+ const onchainEscrow = await this.lookupIntentEscrowOnchain(options.intentHash);
6272
+ if (onchainEscrow) {
6273
+ const fromOnchainEscrow = this.resolveOrchestratorForEscrow(
6274
+ onchainEscrow,
6275
+ options.preferV2
6276
+ );
6277
+ if (fromOnchainEscrow) return fromOnchainEscrow;
6278
+ }
6279
+ } catch (error) {
6280
+ this.warnOrchestratorFallback(options.intentHash, "On-chain intent escrow lookup", error);
6281
+ }
4448
6282
  }
4449
6283
  if (options?.escrowAddress) {
4450
6284
  const fromEscrow = this.resolveOrchestratorForEscrow(options.escrowAddress, options.preferV2);
@@ -5103,8 +6937,6 @@ var _Zkp2pClient = class _Zkp2pClient {
5103
6937
  * `createDeposit` to obtain `payeeDetailsHashes`, or use it independently to
5104
6938
  * register maker payment details with the curator service.
5105
6939
  *
5106
- * Requires `apiKey` or `authorizationToken` to be set.
5107
- *
5108
6940
  * @param params.processorNames - Payment platforms (e.g., ['wise', 'revolut'])
5109
6941
  * @param params.depositData - Payee details per processor (e.g., [{ email: '...' }])
5110
6942
  * @returns The posted deposit details and their corresponding hashed on-chain IDs
@@ -5125,9 +6957,6 @@ var _Zkp2pClient = class _Zkp2pClient {
5125
6957
  if (params.processorNames.length !== params.depositData.length) {
5126
6958
  throw new Error("processorNames and depositData length mismatch");
5127
6959
  }
5128
- if (!this.apiKey && !this.authorizationToken) {
5129
- throw new Error("registerPayeeDetails requires apiKey or authorizationToken");
5130
- }
5131
6960
  const baseApiUrl = (this.baseApiUrl ?? "https://api.zkp2p.xyz").replace(/\/$/, "");
5132
6961
  const depositDetails = params.processorNames.map(
5133
6962
  (processorName, index) => ({
@@ -5268,7 +7097,7 @@ var _Zkp2pClient = class _Zkp2pClient {
5268
7097
  throw new Error("payeeDetailsHashes length must match processorNames length");
5269
7098
  }
5270
7099
  hashedOnchainIds = params.payeeDetailsHashes;
5271
- } else if (this.apiKey || this.authorizationToken) {
7100
+ } else {
5272
7101
  const baseApiUrl = (this.baseApiUrl ?? "https://api.zkp2p.xyz").replace(/\/$/, "");
5273
7102
  const apiResponses = await Promise.all(
5274
7103
  depositDetails.map(
@@ -5288,10 +7117,6 @@ var _Zkp2pClient = class _Zkp2pClient {
5288
7117
  hashedOnchainIds = apiResponses.map(
5289
7118
  (r) => r.responseObject?.hashedOnchainId
5290
7119
  );
5291
- } else {
5292
- throw new Error(
5293
- "createDeposit requires either payeeDetailsHashes (from registerPayeeDetails) or apiKey/authorizationToken"
5294
- );
5295
7120
  }
5296
7121
  paymentMethodData = hashedOnchainIds.map((hid) => ({
5297
7122
  intentGatingService,
@@ -5312,7 +7137,7 @@ var _Zkp2pClient = class _Zkp2pClient {
5312
7137
  }
5313
7138
  }
5314
7139
  });
5315
- const { mapConversionRatesToOnchainMinRate: mapConversionRatesToOnchainMinRate2 } = await import('./currency-5RZ6VCEA.mjs');
7140
+ const { mapConversionRatesToOnchainMinRate: mapConversionRatesToOnchainMinRate2 } = await import('./currency-PKI2EGJD.mjs');
5316
7141
  const normalized = params.conversionRates.map(
5317
7142
  (group) => group.map((r) => ({ currency: r.currency, conversionRate: r.conversionRate }))
5318
7143
  );
@@ -5351,415 +7176,66 @@ var _Zkp2pClient = class _Zkp2pClient {
5351
7176
  * Read controller delegation state for a deposit.
5352
7177
  */
5353
7178
  async getDepositRateManager(escrow, depositId) {
5354
- const id = this.parseRawDepositId(depositId);
5355
- const escrowContext = this.resolveEscrowContext({ escrowAddress: escrow, depositId });
5356
- try {
5357
- const result = await this.publicClient.readContract({
5358
- address: escrowContext.address,
5359
- abi: escrowContext.abi,
5360
- functionName: "getDepositRateManager",
5361
- args: [id]
5362
- });
5363
- if (result && result.length >= 2) {
5364
- return {
5365
- registry: result[0],
5366
- rateManagerId: result[1]
5367
- };
5368
- }
5369
- } catch {
5370
- }
5371
- if (!this.rateManagerControllerAddress || !this.rateManagerControllerAbi) {
5372
- throw new Error("Rate manager controller not available");
5373
- }
5374
- const legacyResult = await this.publicClient.readContract({
5375
- address: this.rateManagerControllerAddress,
5376
- abi: this.rateManagerControllerAbi,
5377
- functionName: "getDepositRateManager",
5378
- args: [escrow, id]
5379
- });
5380
- return {
5381
- registry: legacyResult[0],
5382
- rateManagerId: legacyResult[1]
5383
- };
7179
+ return this._vaultOps.getDepositRateManager(escrow, depositId);
5384
7180
  }
5385
7181
  /**
5386
7182
  * Read effective manager fee for a deposit.
5387
- */
5388
- async getManagerFee(escrow, depositId) {
5389
- const id = this.parseRawDepositId(depositId);
5390
- const escrowContext = this.resolveEscrowContext({ escrowAddress: escrow, depositId });
5391
- try {
5392
- const result = await this.publicClient.readContract({
5393
- address: escrowContext.address,
5394
- abi: escrowContext.abi,
5395
- functionName: "getManagerFee",
5396
- args: [id]
5397
- });
5398
- return this.parseManagerFeeFromRead(result);
5399
- } catch {
5400
- if (!this.rateManagerControllerAddress || !this.rateManagerControllerAbi) {
5401
- throw new Error("Rate manager controller not available");
5402
- }
5403
- const result = await this.publicClient.readContract({
5404
- address: this.rateManagerControllerAddress,
5405
- abi: this.rateManagerControllerAbi,
5406
- functionName: "getManagerFee",
5407
- args: [escrow, id]
5408
- });
5409
- return this.parseManagerFeeFromRead(result);
5410
- }
5411
- }
5412
- /**
5413
- * Read the effective conversion rate on EscrowV2.
5414
- */
5415
- async getEffectiveRate(params) {
5416
- const escrowContext = this.resolveEscrowContext({
5417
- escrowAddress: params.escrow,
5418
- depositId: params.depositId
5419
- });
5420
- const id = this.parseRawDepositId(params.depositId);
5421
- return await this.publicClient.readContract({
5422
- address: escrowContext.address,
5423
- abi: escrowContext.abi,
5424
- functionName: "getEffectiveRate",
5425
- args: [id, params.paymentMethod, params.fiatCurrency]
5426
- });
5427
- }
5428
- /**
5429
- * Prepare signalIntent transaction (all logic except simulation/send).
5430
- * Returns the prepared transaction with encoded calldata.
5431
- */
5432
- async prepareSignalIntent(params) {
5433
- const escrowContext = this.resolveEscrowContext({
5434
- escrowAddress: params.escrowAddress,
5435
- depositId: params.depositId,
5436
- preferV2: this._router.defaultPreferV2
5437
- });
5438
- const orchestratorContext = await this.resolveOrchestratorContext({
5439
- orchestratorAddress: params.orchestratorAddress,
5440
- escrowAddress: escrowContext.address,
5441
- preferV2: this._router.defaultPreferV2
5442
- });
5443
- const catalog = getPaymentMethodsCatalog(this.chainId, this.runtimeEnv);
5444
- const paymentMethod = resolvePaymentMethodHashFromCatalog(params.processorName, catalog);
5445
- const fiatCurrency = resolveFiatCurrencyBytes32(params.fiatCurrencyCode);
5446
- const depositId = this.parseRawDepositId(params.depositId);
5447
- const amount = typeof params.amount === "bigint" ? params.amount : BigInt(params.amount);
5448
- const conversionRate = typeof params.conversionRate === "bigint" ? params.conversionRate : BigInt(params.conversionRate);
5449
- const referrerFee = params.referrerFee === void 0 ? 0n : typeof params.referrerFee === "bigint" ? params.referrerFee : BigInt(params.referrerFee);
5450
- let { gatingServiceSignature, signatureExpiration } = params;
5451
- let preIntentHookData = params.preIntentHookData;
5452
- if ((!gatingServiceSignature || !signatureExpiration) && this.baseApiUrl && (this.apiKey || this.authorizationToken)) {
5453
- const baseRequest = {
5454
- processorName: params.processorName,
5455
- payeeDetails: params.payeeDetails,
5456
- depositId: depositId.toString(),
5457
- amount: amount.toString(),
5458
- toAddress: params.toAddress,
5459
- paymentMethod,
5460
- fiatCurrency,
5461
- conversionRate: conversionRate.toString(),
5462
- chainId: this.chainId.toString(),
5463
- orchestratorAddress: orchestratorContext.address,
5464
- escrowAddress: escrowContext.address
5465
- };
5466
- const apiOpts = {
5467
- baseApiUrl: this.baseApiUrl,
5468
- apiKey: this.apiKey,
5469
- authorizationToken: this.authorizationToken,
5470
- timeoutMs: this.apiTimeoutMs
5471
- };
5472
- const resp = orchestratorContext.version === "v2" ? await apiSignIntentV3(
5473
- {
5474
- ...baseRequest,
5475
- callerAddress: this.walletClient.account.address,
5476
- referrer: params.referrer ?? "0x0000000000000000000000000000000000000000",
5477
- referrerFee: referrerFee.toString()
5478
- },
5479
- apiOpts
5480
- ) : await apiSignIntentV2(baseRequest, apiOpts);
5481
- gatingServiceSignature = resp.signature;
5482
- signatureExpiration = resp.signatureExpiration;
5483
- preIntentHookData = resp.preIntentHookData ?? preIntentHookData;
5484
- }
5485
- if (!gatingServiceSignature || !signatureExpiration)
5486
- throw new Error("Missing gatingServiceSignature/signatureExpiration");
5487
- const args = [
5488
- {
5489
- escrow: escrowContext.address,
5490
- depositId,
5491
- amount,
5492
- to: params.toAddress,
5493
- paymentMethod,
5494
- fiatCurrency,
5495
- conversionRate,
5496
- referrer: params.referrer ?? "0x0000000000000000000000000000000000000000",
5497
- referrerFee,
5498
- gatingServiceSignature,
5499
- signatureExpiration: typeof signatureExpiration === "bigint" ? signatureExpiration : BigInt(signatureExpiration),
5500
- postIntentHook: params.postIntentHook ?? "0x0000000000000000000000000000000000000000",
5501
- preIntentHookData: preIntentHookData ?? "0x",
5502
- data: params.data ?? "0x"
5503
- }
5504
- ];
5505
- const { referrer } = params.txOverrides ?? {};
5506
- const data = encodeWithAttribution(
5507
- {
5508
- abi: orchestratorContext.abi,
5509
- functionName: "signalIntent",
5510
- args
5511
- },
5512
- referrer
5513
- );
5514
- return {
5515
- to: orchestratorContext.address,
5516
- data,
5517
- value: 0n,
5518
- chainId: this.chainId,
5519
- abi: orchestratorContext.abi,
5520
- functionName: "signalIntent",
5521
- args
5522
- };
5523
- }
5524
- /**
5525
- * Prepare cancelIntent transaction (all logic except simulation/send).
5526
- */
5527
- async prepareCancelIntent(params) {
5528
- const orchestratorContext = await this.resolveOrchestratorContext({
5529
- orchestratorAddress: params.orchestratorAddress,
5530
- intentHash: params.intentHash,
5531
- preferV2: this._router.defaultPreferV2
5532
- });
5533
- const args = [params.intentHash];
5534
- const { referrer } = params.txOverrides ?? {};
5535
- const data = encodeWithAttribution(
5536
- {
5537
- abi: orchestratorContext.abi,
5538
- functionName: "cancelIntent",
5539
- args
5540
- },
5541
- referrer
5542
- );
5543
- return {
5544
- to: orchestratorContext.address,
5545
- data,
5546
- value: 0n,
5547
- chainId: this.chainId,
5548
- abi: orchestratorContext.abi,
5549
- functionName: "cancelIntent",
5550
- args
5551
- };
5552
- }
5553
- async prepareReleaseFundsToPayer(params) {
5554
- const orchestratorContext = await this.resolveOrchestratorContext({
5555
- orchestratorAddress: params.orchestratorAddress,
5556
- intentHash: params.intentHash,
5557
- preferV2: this._router.defaultPreferV2
5558
- });
5559
- const args = [params.intentHash];
5560
- const { referrer } = params.txOverrides ?? {};
5561
- const data = encodeWithAttribution(
5562
- {
5563
- abi: orchestratorContext.abi,
5564
- functionName: "releaseFundsToPayer",
5565
- args
5566
- },
5567
- referrer
5568
- );
5569
- return {
5570
- to: orchestratorContext.address,
5571
- data,
5572
- value: 0n,
5573
- chainId: this.chainId,
5574
- abi: orchestratorContext.abi,
5575
- functionName: "releaseFundsToPayer",
5576
- args
5577
- };
7183
+ */
7184
+ async getManagerFee(escrow, depositId) {
7185
+ return this._vaultOps.getManagerFee(escrow, depositId);
7186
+ }
7187
+ /**
7188
+ * Read the effective conversion rate on EscrowV2.
7189
+ */
7190
+ async getEffectiveRate(params) {
7191
+ return this._vaultOps.getEffectiveRate(params);
7192
+ }
7193
+ /**
7194
+ * Prepare signalIntent transaction (all logic except simulation/send).
7195
+ * Returns the prepared transaction with encoded calldata.
7196
+ */
7197
+ async prepareSignalIntent(params) {
7198
+ return this._intentOps.prepareSignalIntent(params);
7199
+ }
7200
+ /**
7201
+ * Prepare cancelIntent transaction (all logic except simulation/send).
7202
+ */
7203
+ async prepareCancelIntent(params) {
7204
+ return this._intentOps.prepareCancelIntent(params);
7205
+ }
7206
+ async prepareReleaseFundsToPayer(params) {
7207
+ return this._intentOps.prepareReleaseFundsToPayer(params);
5578
7208
  }
5579
7209
  async prepareSetDepositPreIntentHook(params) {
5580
- const escrowAddress = this.resolveEscrowAddressOrThrow(
5581
- params.escrowAddress,
5582
- params.depositId,
5583
- "setDepositPreIntentHook",
5584
- { preferV2: this._router.defaultPreferV2 }
5585
- );
5586
- const orchestratorContext = await this.resolveOrchestratorContext({
5587
- orchestratorAddress: params.orchestratorAddress,
5588
- escrowAddress,
5589
- preferV2: this._router.defaultPreferV2
5590
- });
5591
- return this.prepareResolvedOrchestratorTransaction({
5592
- orchestrator: orchestratorContext,
5593
- functionNames: ["setDepositPreIntentHook"],
5594
- args: [escrowAddress, this.parseRawDepositId(params.depositId), params.preIntentHook],
5595
- txOverrides: params.txOverrides
5596
- });
7210
+ return this._intentOps.prepareSetDepositPreIntentHook(params);
5597
7211
  }
5598
7212
  async prepareSetDepositWhitelistHook(params) {
5599
- const escrowAddress = this.resolveEscrowAddressOrThrow(
5600
- params.escrowAddress,
5601
- params.depositId,
5602
- "setDepositWhitelistHook",
5603
- { preferV2: this._router.defaultPreferV2 }
5604
- );
5605
- const orchestratorContext = await this.resolveOrchestratorContext({
5606
- orchestratorAddress: params.orchestratorAddress,
5607
- escrowAddress,
5608
- preferV2: this._router.defaultPreferV2
5609
- });
5610
- return this.prepareResolvedOrchestratorTransaction({
5611
- orchestrator: orchestratorContext,
5612
- functionNames: ["setDepositWhitelistHook"],
5613
- args: [escrowAddress, this.parseRawDepositId(params.depositId), params.whitelistHook],
5614
- txOverrides: params.txOverrides
5615
- });
7213
+ return this._intentOps.prepareSetDepositWhitelistHook(params);
5616
7214
  }
5617
7215
  async prepareCleanupOrphanedIntents(params) {
5618
- const orchestratorContext = await this.resolveOrchestratorContext({
5619
- orchestratorAddress: params.orchestratorAddress,
5620
- escrowAddress: params.escrowAddress,
5621
- preferV2: this._router.defaultPreferV2
5622
- });
5623
- return this.prepareResolvedOrchestratorTransaction({
5624
- orchestrator: orchestratorContext,
5625
- functionNames: ["cleanupOrphanedIntents"],
5626
- args: [params.intentHashes],
5627
- txOverrides: params.txOverrides
5628
- });
7216
+ return this._intentOps.prepareCleanupOrphanedIntents(params);
5629
7217
  }
5630
7218
  /**
5631
7219
  * Read configured pre-intent hook for a deposit from OrchestratorV2.
5632
7220
  */
5633
7221
  async getDepositPreIntentHook(depositId, options) {
5634
- const escrowAddress = this.resolveEscrowAddressOrThrow(
5635
- options?.escrowAddress,
5636
- depositId,
5637
- "getDepositPreIntentHook",
5638
- { preferV2: this._router.defaultPreferV2 }
5639
- );
5640
- const orchestratorContext = await this.resolveOrchestratorContext({
5641
- orchestratorAddress: options?.orchestratorAddress,
5642
- escrowAddress,
5643
- preferV2: this._router.defaultPreferV2
5644
- });
5645
- const functionName = this.resolveAbiFunctionName(orchestratorContext.abi, [
5646
- "getDepositPreIntentHook"
5647
- ]);
5648
- const result = await this.publicClient.readContract({
5649
- address: orchestratorContext.address,
5650
- abi: orchestratorContext.abi,
5651
- functionName,
5652
- args: [escrowAddress, this.parseRawDepositId(depositId)]
5653
- });
5654
- return result;
7222
+ return this._intentOps.getDepositPreIntentHook(depositId, options);
5655
7223
  }
5656
7224
  /**
5657
7225
  * Read configured whitelist hook for a deposit from OrchestratorV2.
5658
7226
  */
5659
7227
  async getDepositWhitelistHook(depositId, options) {
5660
- const escrowAddress = this.resolveEscrowAddressOrThrow(
5661
- options?.escrowAddress,
5662
- depositId,
5663
- "getDepositWhitelistHook",
5664
- { preferV2: this._router.defaultPreferV2 }
5665
- );
5666
- const orchestratorContext = await this.resolveOrchestratorContext({
5667
- orchestratorAddress: options?.orchestratorAddress,
5668
- escrowAddress,
5669
- preferV2: this._router.defaultPreferV2
5670
- });
5671
- const functionName = this.resolveAbiFunctionName(orchestratorContext.abi, [
5672
- "getDepositWhitelistHook"
5673
- ]);
5674
- const result = await this.publicClient.readContract({
5675
- address: orchestratorContext.address,
5676
- abi: orchestratorContext.abi,
5677
- functionName,
5678
- args: [escrowAddress, this.parseRawDepositId(depositId)]
5679
- });
5680
- return result;
7228
+ return this._intentOps.getDepositWhitelistHook(depositId, options);
5681
7229
  }
5682
7230
  /**
5683
7231
  * Prepare fulfillIntent transaction (all logic except simulation/send).
5684
7232
  * Includes fetching intent inputs and calling attestation service.
5685
7233
  */
5686
7234
  async prepareFulfillIntent(params) {
5687
- const intentHash = params.intentHash;
5688
- const orchestratorContext = await this.resolveOrchestratorContext({
5689
- orchestratorAddress: params.orchestratorAddress,
5690
- intentHash,
5691
- preferV2: this._router.defaultPreferV2
5692
- });
5693
- const attUrl = params.attestationServiceUrl ?? this.defaultAttestationService();
5694
- const inputs = await this.getFulfillIntentInputs(intentHash);
5695
- const paymentMethodHash = inputs.paymentMethodHash || "0x";
5696
- const amount = inputs.amount;
5697
- const fiatCurrency = inputs.fiatCurrency;
5698
- const conversionRate = inputs.conversionRate;
5699
- const payeeDetails = inputs.payeeDetails;
5700
- const timestampMs = inputs.intentTimestampMs;
5701
- const timestampBufferMs = params.timestampBufferMs ?? "300000";
5702
- const catalog = getPaymentMethodsCatalog(this.chainId, this.runtimeEnv);
5703
- const { resolvePaymentMethodNameFromHash: resolvePaymentMethodNameFromHash2 } = await import('./paymentResolution-3TC4HRHU.mjs');
5704
- const platformName = resolvePaymentMethodNameFromHash2(paymentMethodHash, catalog);
5705
- if (!platformName)
5706
- throw new Error("Unknown paymentMethodHash for this network/env; update SDK catalogs.");
5707
- const { resolvePlatformAttestationConfig } = await import('./constants-YK56UVLH.mjs');
5708
- const cfg = resolvePlatformAttestationConfig(platformName);
5709
- const platform = cfg.actionPlatform;
5710
- const actionType = cfg.actionType;
5711
- const zkTlsProof = typeof params.proof === "string" ? params.proof : JSON.stringify(params.proof);
5712
- const payload = {
5713
- proofType: "reclaim",
5714
- proof: zkTlsProof,
5715
- chainId: this.chainId,
5716
- intent: {
5717
- intentHash,
5718
- amount,
5719
- timestampMs,
5720
- paymentMethod: paymentMethodHash,
5721
- fiatCurrency,
5722
- conversionRate,
5723
- payeeDetails,
5724
- timestampBufferMs
5725
- }
5726
- };
5727
- const att = await apiCreatePaymentAttestation(payload, attUrl, platform, actionType);
5728
- const paymentProof = encodePaymentAttestation(att);
5729
- const verificationData = encodeVerifyPaymentData({
5730
- intentHash,
5731
- paymentProof,
5732
- data: encodeAddressAsBytes(att.responseObject.signer)
5733
- });
5734
- const args = [
5735
- {
5736
- paymentProof,
5737
- intentHash,
5738
- verificationData,
5739
- postIntentHookData: params.postIntentHookData ?? "0x"
5740
- }
5741
- ];
5742
- const { referrer } = params.txOverrides ?? {};
5743
- const data = encodeWithAttribution(
5744
- {
5745
- abi: orchestratorContext.abi,
5746
- functionName: "fulfillIntent",
5747
- args
5748
- },
5749
- referrer
5750
- );
5751
- return {
5752
- to: orchestratorContext.address,
5753
- data,
5754
- value: 0n,
5755
- chainId: this.chainId,
5756
- abi: orchestratorContext.abi,
5757
- functionName: "fulfillIntent",
5758
- args
5759
- };
7235
+ return this._intentOps.prepareFulfillIntent(params);
5760
7236
  }
5761
7237
  defaultAttestationService() {
5762
- return this.runtimeEnv === "staging" ? "https://attestation-service-staging.zkp2p.xyz" : "https://attestation-service.zkp2p.xyz";
7238
+ return this._intentOps.defaultAttestationService();
5763
7239
  }
5764
7240
  // ───────────────────────────────────────────────────────────────────────────
5765
7241
  // SUPPORTING: QUOTES API
@@ -5807,6 +7283,7 @@ var _Zkp2pClient = class _Zkp2pClient {
5807
7283
  * ```
5808
7284
  */
5809
7285
  async getQuote(req, opts) {
7286
+ const referrerFeeConfig = assertValidReferrerFeeConfig(req.referrerFeeConfig, "getQuote");
5810
7287
  const baseApiUrl = (opts?.baseApiUrl ?? this.baseApiUrl ?? "https://api.zkp2p.xyz").replace(
5811
7288
  /\/$/,
5812
7289
  ""
@@ -5833,7 +7310,7 @@ var _Zkp2pClient = class _Zkp2pClient {
5833
7310
  q.payeeData = maker.depositData;
5834
7311
  }
5835
7312
  }
5836
- return quote;
7313
+ return appendReferrerFeeDisplayFields(quote, referrerFeeConfig);
5837
7314
  }
5838
7315
  // ───────────────────────────────────────────────────────────────────────────
5839
7316
  // SUPPORTING: TAKER TIER
@@ -5842,8 +7319,6 @@ var _Zkp2pClient = class _Zkp2pClient {
5842
7319
  /**
5843
7320
  * **Supporting Method** - Fetches taker tier information for an address.
5844
7321
  *
5845
- * > **Note**: Requires `apiKey` or `authorizationToken` to be set.
5846
- *
5847
7322
  * @param req - Taker tier request parameters
5848
7323
  * @param req.owner - Taker address
5849
7324
  * @param req.chainId - Chain ID
@@ -5856,249 +7331,57 @@ var _Zkp2pClient = class _Zkp2pClient {
5856
7331
  ""
5857
7332
  );
5858
7333
  const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
5859
- if (!this.apiKey && !this.authorizationToken) {
5860
- throw new Error("getTakerTier requires apiKey or authorizationToken");
5861
- }
5862
- return apiGetTakerTier(req, this.apiKey, baseApiUrl, this.authorizationToken, timeoutMs);
7334
+ return apiGetTakerTier(req, this.apiKey, baseApiUrl, timeoutMs);
5863
7335
  }
5864
7336
  // ╔═══════════════════════════════════════════════════════════════════════════╗
5865
7337
  // ║ CORE: ON-CHAIN DEPOSIT VIEWS ║
5866
7338
  // ╚═══════════════════════════════════════════════════════════════════════════╝
5867
7339
  requireProtocolViewer() {
5868
- if (!this.protocolViewerAddress || !this.protocolViewerAbi) {
5869
- throw new Error("ProtocolViewer not available for this network");
5870
- }
5871
- return { address: this.protocolViewerAddress, abi: this.protocolViewerAbi };
7340
+ return this._pvReader.requireProtocolViewer();
5872
7341
  }
5873
7342
  protocolViewerFunctionInputCount(functionName) {
5874
- const fn = this.getAbiFunction(this.protocolViewerAbi, functionName);
5875
- if (!fn) return null;
5876
- const inputs = fn.inputs ?? [];
5877
- return inputs.length;
7343
+ return this._pvReader.protocolViewerFunctionInputCount(functionName);
5878
7344
  }
5879
7345
  /**
5880
7346
  * Returns the input count for a function on a specific PV entry's ABI.
5881
7347
  * Used to branch between 1-input (V1) and 2-input (V2) PV call signatures.
5882
7348
  */
5883
7349
  pvEntryFunctionInputCount(entry, functionName) {
5884
- const fn = this.getAbiFunction(entry.abi, functionName);
5885
- if (!fn) return null;
5886
- const inputs = fn.inputs ?? [];
5887
- return inputs.length;
7350
+ return this._pvReader.pvEntryFunctionInputCount(entry, functionName);
5888
7351
  }
5889
7352
  isZeroAddressValue(value) {
5890
- return !value || value.toLowerCase() === ZERO_ADDRESS2.toLowerCase();
7353
+ return this._pvReader.isZeroAddressValue(value);
5891
7354
  }
5892
- toBigIntOrZero(value) {
5893
- if (value === null || value === void 0) return 0n;
5894
- try {
5895
- return parseBigIntLike(value);
5896
- } catch {
5897
- return 0n;
5898
- }
7355
+ toBigIntOrZero(value, fieldName = "numeric field") {
7356
+ return this._pvReader.toBigIntOrZero(value, fieldName);
5899
7357
  }
5900
7358
  buildProtocolViewerContexts(options) {
5901
- return this._router.buildProtocolViewerContexts(options);
7359
+ return this._pvReader.buildProtocolViewerContexts(options);
5902
7360
  }
5903
7361
  isProtocolViewerDepositPopulated(view) {
5904
- return !this.isZeroAddressValue(view.deposit?.depositor);
7362
+ return this._pvReader.isProtocolViewerDepositPopulated(view);
5905
7363
  }
5906
7364
  isProtocolViewerIntentPopulated(view) {
5907
- return !this.isZeroAddressValue(view.intent?.owner);
5908
- }
5909
- buildDepositViewFromEscrowDeposit(rawDeposit, depositId) {
5910
- const deposit = rawDeposit ?? {};
5911
- const remaining = this.toBigIntOrZero(
5912
- deposit.remainingDeposits ?? deposit.remainingDepositAmount
5913
- );
5914
- const outstanding = this.toBigIntOrZero(deposit.outstandingIntentAmount);
5915
- const amount = this.toBigIntOrZero(deposit.amount) || remaining + outstanding;
5916
- return {
5917
- depositId,
5918
- deposit: {
5919
- depositor: this.normalizeAddress(deposit.depositor) ?? ZERO_ADDRESS2,
5920
- delegate: this.normalizeAddress(deposit.delegate) ?? ZERO_ADDRESS2,
5921
- token: this.normalizeAddress(deposit.token) ?? ZERO_ADDRESS2,
5922
- amount,
5923
- intentAmountRange: {
5924
- min: this.toBigIntOrZero(
5925
- deposit.intentAmountRange?.min
5926
- ),
5927
- max: this.toBigIntOrZero(
5928
- deposit.intentAmountRange?.max
5929
- )
5930
- },
5931
- acceptingIntents: Boolean(deposit.acceptingIntents),
5932
- remainingDeposits: remaining,
5933
- outstandingIntentAmount: outstanding,
5934
- makerProtocolFee: this.toBigIntOrZero(deposit.makerProtocolFee),
5935
- reservedMakerFees: this.toBigIntOrZero(deposit.reservedMakerFees),
5936
- accruedMakerFees: this.toBigIntOrZero(deposit.accruedMakerFees),
5937
- accruedReferrerFees: this.toBigIntOrZero(deposit.accruedReferrerFees),
5938
- intentGuardian: this.normalizeAddress(deposit.intentGuardian) ?? ZERO_ADDRESS2,
5939
- referrer: this.normalizeAddress(deposit.referrer) ?? ZERO_ADDRESS2,
5940
- referrerFee: this.toBigIntOrZero(deposit.referrerFee)
5941
- },
5942
- availableLiquidity: remaining,
5943
- paymentMethods: [],
5944
- intentHashes: []
5945
- };
5946
- }
5947
- convertIndexerDepositToPvView(deposit) {
5948
- const paymentMethods = (deposit.paymentMethods ?? []).filter(
5949
- (pm) => pm.active !== false
5950
- );
5951
- const currenciesByPaymentMethod = /* @__PURE__ */ new Map();
5952
- for (const currency of deposit.currencies ?? []) {
5953
- const key = currency.paymentMethodHash.toLowerCase();
5954
- const existing = currenciesByPaymentMethod.get(key) ?? [];
5955
- existing.push(currency);
5956
- currenciesByPaymentMethod.set(key, existing);
5957
- }
5958
- const remaining = this.toBigIntOrZero(deposit.remainingDeposits);
5959
- const outstanding = this.toBigIntOrZero(deposit.outstandingIntentAmount);
5960
- const totalAmountTaken = this.toBigIntOrZero(deposit.totalAmountTaken);
5961
- const totalWithdrawn = this.toBigIntOrZero(deposit.totalWithdrawn);
5962
- const depositAmount = remaining + outstanding + totalAmountTaken + totalWithdrawn;
5963
- return {
5964
- depositId: this.toBigIntOrZero(deposit.depositId),
5965
- deposit: {
5966
- depositor: this.normalizeAddress(deposit.depositor) ?? ZERO_ADDRESS2,
5967
- delegate: this.normalizeAddress(deposit.delegate ?? void 0) ?? ZERO_ADDRESS2,
5968
- token: this.normalizeAddress(deposit.token) ?? ZERO_ADDRESS2,
5969
- amount: depositAmount,
5970
- intentAmountRange: {
5971
- min: this.toBigIntOrZero(deposit.intentAmountMin),
5972
- max: this.toBigIntOrZero(deposit.intentAmountMax)
5973
- },
5974
- acceptingIntents: Boolean(deposit.acceptingIntents),
5975
- remainingDeposits: remaining,
5976
- outstandingIntentAmount: outstanding,
5977
- makerProtocolFee: 0n,
5978
- reservedMakerFees: 0n,
5979
- accruedMakerFees: 0n,
5980
- accruedReferrerFees: 0n,
5981
- intentGuardian: ZERO_ADDRESS2,
5982
- referrer: ZERO_ADDRESS2,
5983
- referrerFee: 0n
5984
- },
5985
- availableLiquidity: remaining,
5986
- paymentMethods: paymentMethods.map((method) => ({
5987
- paymentMethod: method.paymentMethodHash,
5988
- verificationData: {
5989
- intentGatingService: this.normalizeAddress(method.intentGatingService) ?? ZERO_ADDRESS2,
5990
- payeeDetails: method.payeeDetailsHash || "0x",
5991
- data: "0x"
5992
- },
5993
- currencies: (currenciesByPaymentMethod.get(method.paymentMethodHash.toLowerCase()) ?? []).map((currency) => ({
5994
- code: currency.currencyCode,
5995
- minConversionRate: this.toBigIntOrZero(
5996
- currency.conversionRate ?? currency.minConversionRate
5997
- )
5998
- }))
5999
- })),
6000
- intentHashes: Array.from(new Set((deposit.intents ?? []).map((intent) => intent.intentHash)))
6001
- };
6002
- }
6003
- async getPvAccountDepositsFromIndexer(owner) {
6004
- const filter = { depositor: owner, status: "ACTIVE" };
6005
- if (this.escrowAddresses.length > 0) {
6006
- filter.escrowAddresses = this.escrowAddresses.map((escrow) => escrow);
6007
- }
6008
- const deposits = await this._indexerService.fetchDepositsWithRelations(
6009
- filter,
6010
- { limit: 1e3, orderBy: "timestamp", orderDirection: "desc" },
6011
- { includeIntents: true }
6012
- );
6013
- return deposits.map((deposit) => this.convertIndexerDepositToPvView(deposit));
7365
+ return this._pvReader.isProtocolViewerIntentPopulated(view);
6014
7366
  }
6015
- /**
6016
- * Fetches a deposit directly from on-chain ProtocolViewer contract.
6017
- * Falls back to Escrow.getDeposit if ProtocolViewer is unavailable.
6018
- *
6019
- * @param depositId - The deposit ID (string or bigint)
6020
- * @returns Parsed deposit view with all payment methods and currencies
6021
- */
6022
- async getPvDepositById(depositId) {
6023
- const id = typeof depositId === "bigint" ? depositId : this.parseRawDepositId(depositId);
6024
- const hintedEscrow = typeof depositId === "string" ? this.parseEscrowAddressFromCompositeDepositId(depositId) : void 0;
6025
- try {
6026
- const { address, abi } = this.requireProtocolViewer();
6027
- const inputCount = this.protocolViewerFunctionInputCount("getDeposit");
6028
- if (inputCount === null) {
6029
- throw new Error("Configured ProtocolViewer ABI does not expose getDeposit");
6030
- }
6031
- const { parseDepositView: parseDepositView2 } = await import('./protocolViewerParsers-EUBHHIPL.mjs');
6032
- if (inputCount >= 3) {
6033
- for (const context of this.buildProtocolViewerContexts({ escrowAddress: hintedEscrow })) {
6034
- const raw2 = await this.publicClient.readContract({
6035
- address,
6036
- abi,
6037
- functionName: "getDeposit",
6038
- args: [context.escrow, context.orchestrator, id]
6039
- });
6040
- const parsed2 = parseDepositView2(raw2);
6041
- if (this.isProtocolViewerDepositPopulated(parsed2)) {
6042
- return parsed2;
6043
- }
6044
- }
6045
- throw new Error("Deposit not found in configured ProtocolViewer contexts");
6046
- }
6047
- if (inputCount >= 2) {
6048
- for (const context of this.buildProtocolViewerContexts({ escrowAddress: hintedEscrow })) {
6049
- const raw2 = await this.publicClient.readContract({
6050
- address,
6051
- abi,
6052
- functionName: "getDeposit",
6053
- args: [context.escrow, id]
6054
- });
6055
- const parsed2 = parseDepositView2(raw2);
6056
- if (this.isProtocolViewerDepositPopulated(parsed2)) {
6057
- return parsed2;
6058
- }
6059
- }
6060
- throw new Error("Deposit not found in configured ProtocolViewer escrows");
6061
- }
6062
- const raw = await this.publicClient.readContract({
6063
- address,
6064
- abi,
6065
- functionName: "getDeposit",
6066
- args: [id]
6067
- });
6068
- const parsed = parseDepositView2(raw);
6069
- if (this.isProtocolViewerDepositPopulated(parsed)) {
6070
- return parsed;
6071
- }
6072
- throw new Error("Deposit not found");
6073
- } catch {
6074
- let lastError;
6075
- const contexts = this.getEscrowContexts();
6076
- if (hintedEscrow) {
6077
- contexts.sort((left, right) => {
6078
- const leftMatch = left.address.toLowerCase() === hintedEscrow.toLowerCase() ? 1 : 0;
6079
- const rightMatch = right.address.toLowerCase() === hintedEscrow.toLowerCase() ? 1 : 0;
6080
- return rightMatch - leftMatch;
6081
- });
6082
- }
6083
- for (const context of contexts) {
6084
- try {
6085
- const raw = await this.publicClient.readContract({
6086
- address: context.address,
6087
- abi: context.abi,
6088
- functionName: "getDeposit",
6089
- args: [id]
6090
- });
6091
- const parsed = this.buildDepositViewFromEscrowDeposit(raw, id);
6092
- if (this.isProtocolViewerDepositPopulated(parsed)) {
6093
- return parsed;
6094
- }
6095
- lastError = new Error(`Deposit ${id.toString()} not found in escrow ${context.address}`);
6096
- } catch (readError) {
6097
- lastError = readError;
6098
- }
6099
- }
6100
- throw lastError ?? new Error("Failed to fetch deposit from configured escrows");
6101
- }
7367
+ buildDepositViewFromEscrowDeposit(rawDeposit, depositId) {
7368
+ return this._pvReader.buildDepositViewFromEscrowDeposit(rawDeposit, depositId);
7369
+ }
7370
+ convertIndexerDepositToPvView(deposit) {
7371
+ return this._pvReader.convertIndexerDepositToPvView(deposit);
7372
+ }
7373
+ async getPvAccountDepositsFromIndexer(owner) {
7374
+ return this._pvReader.getPvAccountDepositsFromIndexer(owner);
7375
+ }
7376
+ /**
7377
+ * Fetches a deposit directly from on-chain ProtocolViewer contract.
7378
+ * Falls back to Escrow.getDeposit if ProtocolViewer is unavailable.
7379
+ *
7380
+ * @param depositId - The deposit ID (string or bigint)
7381
+ * @returns Parsed deposit view with all payment methods and currencies
7382
+ */
7383
+ async getPvDepositById(depositId, options) {
7384
+ return this._pvReader.getPvDepositById(depositId, options);
6102
7385
  }
6103
7386
  /**
6104
7387
  * Fetches multiple deposits by ID from on-chain in a batch call.
@@ -6107,98 +7390,7 @@ var _Zkp2pClient = class _Zkp2pClient {
6107
7390
  * @returns Array of parsed deposit views
6108
7391
  */
6109
7392
  async getPvDepositsFromIds(ids) {
6110
- if (!ids.length) return [];
6111
- const inputCount = this.protocolViewerFunctionInputCount("getDepositFromIds");
6112
- if (!this.protocolViewerAddress || !this.protocolViewerAbi || inputCount === null || inputCount >= 3) {
6113
- return Promise.all(ids.map((id) => this.getPvDepositById(id)));
6114
- }
6115
- const bn = ids.map((id) => typeof id === "bigint" ? id : this.parseRawDepositId(id));
6116
- const { parseDepositView: parseDepositView2 } = await import('./protocolViewerParsers-EUBHHIPL.mjs');
6117
- if (inputCount >= 2) {
6118
- const requests = ids.map((id, index) => ({
6119
- index,
6120
- id,
6121
- rawId: bn[index],
6122
- hintedEscrow: typeof id === "string" ? this.parseEscrowAddressFromCompositeDepositId(id) : void 0
6123
- }));
6124
- const resolved = new Array(requests.length);
6125
- const resolveBatch = async (escrow, entries) => {
6126
- if (!entries.length) return;
6127
- try {
6128
- const raw2 = await this.publicClient.readContract({
6129
- address: this.protocolViewerAddress,
6130
- abi: this.protocolViewerAbi,
6131
- functionName: "getDepositFromIds",
6132
- args: [escrow, entries.map((entry) => entry.rawId)]
6133
- });
6134
- const items = Array.isArray(raw2) ? raw2 : [];
6135
- if (items.length === entries.length) {
6136
- for (let index = 0; index < entries.length; index++) {
6137
- const entry = entries[index];
6138
- if (!entry || resolved[entry.index]) continue;
6139
- const parsed = parseDepositView2(items[index]);
6140
- if (this.isProtocolViewerDepositPopulated(parsed)) {
6141
- resolved[entry.index] = parsed;
6142
- }
6143
- }
6144
- return;
6145
- }
6146
- for (const item of items) {
6147
- const parsed = parseDepositView2(item);
6148
- if (!this.isProtocolViewerDepositPopulated(parsed)) continue;
6149
- const match = entries.find(
6150
- (entry) => !resolved[entry.index] && entry.rawId === parsed.depositId
6151
- );
6152
- if (match) {
6153
- resolved[match.index] = parsed;
6154
- }
6155
- }
6156
- } catch {
6157
- }
6158
- };
6159
- const hintedGroups = /* @__PURE__ */ new Map();
6160
- for (const request of requests) {
6161
- if (!request.hintedEscrow) continue;
6162
- const key = request.hintedEscrow.toLowerCase();
6163
- const group = hintedGroups.get(key);
6164
- if (group) {
6165
- group.entries.push(request);
6166
- } else {
6167
- hintedGroups.set(key, { escrow: request.hintedEscrow, entries: [request] });
6168
- }
6169
- }
6170
- for (const { escrow, entries } of hintedGroups.values()) {
6171
- await resolveBatch(escrow, entries);
6172
- }
6173
- const escrows = [];
6174
- const seenEscrows = /* @__PURE__ */ new Set();
6175
- for (const context of this.buildProtocolViewerContexts()) {
6176
- const key = context.escrow.toLowerCase();
6177
- if (seenEscrows.has(key)) continue;
6178
- seenEscrows.add(key);
6179
- escrows.push(context.escrow);
6180
- }
6181
- for (const escrow of escrows) {
6182
- const pending = requests.filter(
6183
- (entry) => !entry.hintedEscrow && resolved[entry.index] === void 0
6184
- );
6185
- if (!pending.length) break;
6186
- await resolveBatch(escrow, pending);
6187
- }
6188
- if (resolved.every((view) => Boolean(view))) {
6189
- return resolved;
6190
- }
6191
- return Promise.all(
6192
- requests.map((entry) => resolved[entry.index] ?? this.getPvDepositById(entry.id))
6193
- );
6194
- }
6195
- const raw = await this.publicClient.readContract({
6196
- address: this.protocolViewerAddress,
6197
- abi: this.protocolViewerAbi,
6198
- functionName: "getDepositFromIds",
6199
- args: [bn]
6200
- });
6201
- return raw.map(parseDepositView2);
7393
+ return this._pvReader.getPvDepositsFromIds(ids);
6202
7394
  }
6203
7395
  /**
6204
7396
  * Fetches all deposits owned by an address from on-chain.
@@ -6207,41 +7399,7 @@ var _Zkp2pClient = class _Zkp2pClient {
6207
7399
  * @returns Array of parsed deposit views
6208
7400
  */
6209
7401
  async getPvAccountDeposits(owner) {
6210
- const inputCount = this.protocolViewerFunctionInputCount("getAccountDeposits");
6211
- if (!this.protocolViewerAddress || !this.protocolViewerAbi || inputCount === null) {
6212
- return this.getPvAccountDepositsFromIndexer(owner);
6213
- }
6214
- try {
6215
- const { parseDepositView: parseDepositView2 } = await import('./protocolViewerParsers-EUBHHIPL.mjs');
6216
- const { address, abi } = this.requireProtocolViewer();
6217
- if (inputCount >= 3) {
6218
- const merged = [];
6219
- for (const context of this.buildProtocolViewerContexts()) {
6220
- const raw2 = await this.publicClient.readContract({
6221
- address,
6222
- abi,
6223
- functionName: "getAccountDeposits",
6224
- args: [context.escrow, context.orchestrator, owner]
6225
- });
6226
- for (const item of raw2) {
6227
- const parsed = parseDepositView2(item);
6228
- if (this.isProtocolViewerDepositPopulated(parsed)) {
6229
- merged.push(parsed);
6230
- }
6231
- }
6232
- }
6233
- return merged;
6234
- }
6235
- const raw = await this.publicClient.readContract({
6236
- address,
6237
- abi,
6238
- functionName: "getAccountDeposits",
6239
- args: [owner]
6240
- });
6241
- return raw.map(parseDepositView2).filter((view) => this.isProtocolViewerDepositPopulated(view));
6242
- } catch {
6243
- return this.getPvAccountDepositsFromIndexer(owner);
6244
- }
7402
+ return this._pvReader.getPvAccountDeposits(owner);
6245
7403
  }
6246
7404
  /**
6247
7405
  * Fetches all intents created by an address from on-chain.
@@ -6252,57 +7410,7 @@ var _Zkp2pClient = class _Zkp2pClient {
6252
7410
  * @returns Array of parsed intent views (deduplicated by intentHash)
6253
7411
  */
6254
7412
  async getPvAccountIntents(owner) {
6255
- if (this._protocolViewerEntries.length === 0) {
6256
- throw new Error("ProtocolViewer not available for this network");
6257
- }
6258
- const { parseIntentView: parseIntentView2 } = await import('./protocolViewerParsers-EUBHHIPL.mjs');
6259
- const intentsByHash = /* @__PURE__ */ new Map();
6260
- for (const pvEntry of this._protocolViewerEntries) {
6261
- const inputCount = this.pvEntryFunctionInputCount(pvEntry, "getAccountIntents");
6262
- if (inputCount === null) continue;
6263
- if (inputCount >= 2) {
6264
- for (const context of this.buildProtocolViewerContexts()) {
6265
- try {
6266
- const args = inputCount >= 3 ? [context.escrow, context.orchestrator, owner] : [context.orchestrator, owner];
6267
- const raw = await this.publicClient.readContract({
6268
- address: pvEntry.address,
6269
- abi: pvEntry.abi,
6270
- functionName: "getAccountIntents",
6271
- args
6272
- });
6273
- for (const item of raw) {
6274
- const parsed = parseIntentView2(item);
6275
- if (!this.isProtocolViewerIntentPopulated(parsed)) continue;
6276
- intentsByHash.set(parsed.intentHash.toLowerCase(), parsed);
6277
- }
6278
- } catch {
6279
- }
6280
- }
6281
- } else {
6282
- try {
6283
- const raw = await this.publicClient.readContract({
6284
- address: pvEntry.address,
6285
- abi: pvEntry.abi,
6286
- functionName: "getAccountIntents",
6287
- args: [owner]
6288
- });
6289
- for (const item of raw) {
6290
- const parsed = parseIntentView2(item);
6291
- if (!this.isProtocolViewerIntentPopulated(parsed)) continue;
6292
- if (!intentsByHash.has(parsed.intentHash.toLowerCase())) {
6293
- intentsByHash.set(parsed.intentHash.toLowerCase(), parsed);
6294
- }
6295
- }
6296
- } catch {
6297
- }
6298
- }
6299
- }
6300
- return Array.from(intentsByHash.values()).sort((a, b) => {
6301
- if (a.intent.timestamp === b.intent.timestamp) {
6302
- return a.intentHash.localeCompare(b.intentHash);
6303
- }
6304
- return a.intent.timestamp < b.intent.timestamp ? -1 : 1;
6305
- });
7413
+ return this._pvReader.getPvAccountIntents(owner);
6306
7414
  }
6307
7415
  /**
6308
7416
  * Fetches a single intent by hash from on-chain.
@@ -6312,56 +7420,7 @@ var _Zkp2pClient = class _Zkp2pClient {
6312
7420
  * @returns Parsed intent view with deposit context
6313
7421
  */
6314
7422
  async getPvIntent(intentHash) {
6315
- if (this._protocolViewerEntries.length === 0) {
6316
- throw new Error("ProtocolViewer not available for this network");
6317
- }
6318
- const { parseIntentView: parseIntentView2 } = await import('./protocolViewerParsers-EUBHHIPL.mjs');
6319
- let lastError;
6320
- for (const pvEntry of this._protocolViewerEntries) {
6321
- const inputCount = this.pvEntryFunctionInputCount(pvEntry, "getIntent");
6322
- if (inputCount === null) continue;
6323
- if (inputCount >= 2) {
6324
- const routing = await this.lookupIntentRouting(intentHash);
6325
- for (const context of this.buildProtocolViewerContexts({
6326
- escrowAddress: routing.escrowAddress,
6327
- orchestratorAddress: routing.orchestratorAddress
6328
- })) {
6329
- try {
6330
- const args = inputCount >= 3 ? [context.escrow, context.orchestrator, intentHash] : [context.orchestrator, intentHash];
6331
- const raw = await this.publicClient.readContract({
6332
- address: pvEntry.address,
6333
- abi: pvEntry.abi,
6334
- functionName: "getIntent",
6335
- args
6336
- });
6337
- const parsed = parseIntentView2(raw);
6338
- if (this.isProtocolViewerIntentPopulated(parsed)) {
6339
- return parsed;
6340
- }
6341
- lastError = new Error("Intent not found");
6342
- } catch (readError) {
6343
- lastError = readError;
6344
- }
6345
- }
6346
- } else {
6347
- try {
6348
- const raw = await this.publicClient.readContract({
6349
- address: pvEntry.address,
6350
- abi: pvEntry.abi,
6351
- functionName: "getIntent",
6352
- args: [intentHash]
6353
- });
6354
- const parsed = parseIntentView2(raw);
6355
- if (this.isProtocolViewerIntentPopulated(parsed)) {
6356
- return parsed;
6357
- }
6358
- lastError = new Error("Intent not found");
6359
- } catch (readError) {
6360
- lastError = readError;
6361
- }
6362
- }
6363
- }
6364
- throw lastError ?? new Error("Intent not found");
7423
+ return this._pvReader.getPvIntent(intentHash);
6365
7424
  }
6366
7425
  // ╔═══════════════════════════════════════════════════════════════════════════╗
6367
7426
  // ║ CORE: UTILITIES ║
@@ -6409,80 +7468,9 @@ var _Zkp2pClient = class _Zkp2pClient {
6409
7468
  * @throws Error if intent not found or payee details cannot be resolved
6410
7469
  */
6411
7470
  async getFulfillIntentInputs(intentHash) {
6412
- try {
6413
- if (this.protocolViewerAddress && this.protocolViewerAbi) {
6414
- const view = await this.getPvIntent(intentHash);
6415
- const pmHash = view.intent.paymentMethod.toLowerCase();
6416
- const matched = (view.deposit.paymentMethods || []).find(
6417
- (pm) => pm.paymentMethod?.toLowerCase?.() === pmHash
6418
- );
6419
- const payee2 = matched?.verificationData?.payeeDetails;
6420
- if (payee2) {
6421
- return {
6422
- amount: view.intent.amount.toString(),
6423
- fiatCurrency: view.intent.fiatCurrency,
6424
- conversionRate: view.intent.conversionRate.toString(),
6425
- payeeDetails: payee2,
6426
- intentTimestampMs: (BigInt(view.intent.timestamp) * 1000n).toString(),
6427
- paymentMethodHash: view.intent.paymentMethod
6428
- };
6429
- }
6430
- }
6431
- } catch {
6432
- }
6433
- const query = (
6434
- /* GraphQL */
6435
- `
6436
- query GetIntentMinimal($hash: String!) {
6437
- Intent(where: { intentHash: { _eq: $hash } }, limit: 1) {
6438
- amount
6439
- fiatCurrency
6440
- conversionRate
6441
- paymentMethodHash
6442
- depositId
6443
- signalTimestamp
6444
- verifier
6445
- }
6446
- }
6447
- `
6448
- );
6449
- const res = await this._indexerClient.query({
6450
- query,
6451
- variables: { hash: intentHash.toLowerCase() }
6452
- });
6453
- const rec = res?.Intent?.[0];
6454
- if (!rec) throw new Error("Intent not found on indexer");
6455
- if (!rec.signalTimestamp) throw new Error("Intent signal timestamp not found on indexer");
6456
- const deposit = await this._indexerService.fetchDepositWithRelations(rec.depositId, {
6457
- includeIntents: false
6458
- });
6459
- let payee;
6460
- const pmHashLower = (rec.paymentMethodHash || "").toLowerCase();
6461
- for (const pm of deposit?.paymentMethods || []) {
6462
- if ((pm.paymentMethodHash || "").toLowerCase() === pmHashLower) {
6463
- payee = pm.payeeDetailsHash;
6464
- break;
6465
- }
6466
- }
6467
- if (!payee) throw new Error("Payee details not found for intent");
6468
- return {
6469
- amount: rec.amount,
6470
- fiatCurrency: rec.fiatCurrency,
6471
- conversionRate: rec.conversionRate,
6472
- payeeDetails: payee,
6473
- intentTimestampMs: (BigInt(rec.signalTimestamp) * 1000n).toString(),
6474
- paymentMethodHash: rec.paymentMethodHash || "0x0000000000000000000000000000000000000000000000000000000000000000",
6475
- paymentVerifier: rec.verifier || void 0
6476
- };
7471
+ return this._intentOps.getFulfillIntentInputs(intentHash);
6477
7472
  }
6478
7473
  };
6479
- _Zkp2pClient.EMPTY_ORACLE_RATE_CONFIG = {
6480
- adapter: ZERO_ADDRESS2,
6481
- adapterConfig: "0x",
6482
- spreadBps: 0,
6483
- maxStaleness: 0
6484
- };
6485
- var Zkp2pClient = _Zkp2pClient;
6486
7474
 
6487
7475
  // src/extension.ts
6488
7476
  var PEER_EXTENSION_CHROME_URL = "https://chromewebstore.google.com/detail/peerauth-authenticate-and/ijpgccednehjpeclfcllnjjcmiohdjih";
@@ -6660,7 +7648,6 @@ var buildOnrampQueryString = (params) => {
6660
7648
  "recipientAddress",
6661
7649
  normalizeOptionalString(validated.recipientAddress, "recipientAddress")
6662
7650
  );
6663
- setParam("callbackUrl", normalizeOptionalUrl(validated.callbackUrl, "callbackUrl"));
6664
7651
  setParam("intentHash", normalizeIntentHash(validated.intentHash));
6665
7652
  return searchParams.toString();
6666
7653
  };
@@ -6670,51 +7657,13 @@ var createPeerExtensionSdk = (options = {}) => ({
6670
7657
  checkConnectionStatus: () => requirePeer(options).checkConnectionStatus(),
6671
7658
  openSidebar: (route) => requirePeer(options).openSidebar(route),
6672
7659
  onramp: (params) => requirePeer(options).onramp(buildOnrampQueryString(params)),
6673
- onProofComplete: (callback) => requirePeer(options).onProofComplete(callback),
7660
+ onIntentFulfilled: (callback) => requirePeer(options).onIntentFulfilled(callback),
6674
7661
  getVersion: () => requirePeer(options).getVersion(),
6675
7662
  openInstallPage: () => openPeerExtensionInstallPage(options),
6676
7663
  getState: () => getPeerExtensionState(options)
6677
7664
  });
6678
7665
  var peerExtensionSdk = createPeerExtensionSdk();
6679
7666
 
6680
- // src/utils/logger.ts
6681
- var currentLevel = "info";
6682
- function setLogLevel(level) {
6683
- currentLevel = level;
6684
- }
6685
- function shouldLog(level) {
6686
- switch (currentLevel) {
6687
- case "debug":
6688
- return true;
6689
- case "info":
6690
- return level !== "debug";
6691
- case "error":
6692
- return level === "error";
6693
- default:
6694
- return true;
6695
- }
6696
- }
6697
- var logger = {
6698
- debug: (...args) => {
6699
- if (shouldLog("debug")) {
6700
- console.log("[DEBUG]", ...args);
6701
- }
6702
- },
6703
- info: (...args) => {
6704
- if (shouldLog("info")) {
6705
- console.log("[INFO]", ...args);
6706
- }
6707
- },
6708
- warn: (...args) => {
6709
- if (shouldLog("info")) {
6710
- console.warn("[WARN]", ...args);
6711
- }
6712
- },
6713
- error: (...args) => {
6714
- console.error("[ERROR]", ...args);
6715
- }
6716
- };
6717
-
6718
- export { BASE_BUILDER_CODE, ContractRouter, IndexerClient, IndexerDepositService, IndexerRateManagerService, Zkp2pClient as OfframpClient, PEER_EXTENSION_CHROME_URL, ZKP2P_ANDROID_REFERRER, ZKP2P_IOS_REFERRER, Zkp2pClient, apiGetOwnerDeposits, apiGetPayeeDetails, apiGetTakerTier, apiPostDepositDetails, apiValidatePayeeDetails, appendAttributionToCalldata, convertDepositsForLiquidity, convertIndexerDepositToEscrowView, convertIndexerIntentsToEscrowViews, createCompositeDepositId, createPeerExtensionSdk, defaultIndexerEndpoint, encodeWithAttribution, fetchFulfillmentAndPayment as fetchIndexerFulfillmentAndPayment, getAttributionDataSuffix, getPeerExtensionState, isPeerExtensionAvailable, logger, openPeerExtensionInstallPage, peerExtensionSdk, sendTransactionWithAttribution, setLogLevel };
7667
+ export { BASE_BUILDER_CODE, CHAINLINK_ORACLE_ADAPTER, CHAINLINK_ORACLE_FEEDS, ContractRouter, DEFAULT_ORACLE_MAX_STALENESS_SECONDS, IndexerClient, IndexerDepositService, IndexerRateManagerService, Zkp2pClient as OfframpClient, PAYMENT_PLATFORMS, PEER_EXTENSION_CHROME_URL, PLATFORM_METADATA, PYTH_CONTRACT_BASE, PYTH_ORACLE_ADAPTER, PYTH_ORACLE_FEEDS, SPREAD_ORACLE_FEEDS, SUPPORTED_CHAIN_IDS, TOKEN_METADATA, ZKP2P_ANDROID_REFERRER, ZKP2P_IOS_REFERRER, Zkp2pClient, apiGetOwnerDeposits, apiGetPayeeDetails, apiGetTakerTier, apiPostDepositDetails, apiValidatePayeeDetails, appendAttributionToCalldata, assertValidReferrerFeeConfig, convertDepositsForLiquidity, convertIndexerDepositToEscrowView, convertIndexerIntentsToEscrowViews, createCompositeDepositId, createPeerExtensionSdk, defaultIndexerEndpoint, encodePythAdapterConfig, encodeSpreadOracleAdapterConfig, encodeWithAttribution, fetchFulfillmentAndPayment as fetchIndexerFulfillmentAndPayment, getAttributionDataSuffix, getPeerExtensionState, getSpreadOracleConfig, isPeerExtensionAvailable, isValidReferrerFeeBps, isValidReferrerFeeRecipient, logger, openPeerExtensionInstallPage, parseReferrerFeeConfig, peerExtensionSdk, referrerFeeConfigToPreciseUnits, sendTransactionWithAttribution, setLogLevel, validateOracleFeedsOnChain };
6719
7668
  //# sourceMappingURL=index.mjs.map
6720
7669
  //# sourceMappingURL=index.mjs.map