@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.
- package/README.md +73 -14
- package/dist/{chunk-6YLLNF6Q.mjs → chunk-JH74HXTS.mjs} +103 -11
- package/dist/chunk-JH74HXTS.mjs.map +1 -0
- package/dist/{chunk-456CSWDT.mjs → chunk-YLITJ7SI.mjs} +2 -2
- package/dist/{chunk-456CSWDT.mjs.map → chunk-YLITJ7SI.mjs.map} +1 -1
- package/dist/{chunk-PQQWQF3C.mjs → chunk-ZFBH4HD7.mjs} +10 -4
- package/dist/chunk-ZFBH4HD7.mjs.map +1 -0
- package/dist/{currency-5RZ6VCEA.mjs → currency-PKI2EGJD.mjs} +3 -4
- package/dist/{currency-5RZ6VCEA.mjs.map → currency-PKI2EGJD.mjs.map} +1 -1
- package/dist/index.cjs +3152 -5150
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +73 -34
- package/dist/index.d.ts +73 -34
- package/dist/index.mjs +2553 -1604
- package/dist/index.mjs.map +1 -1
- package/dist/protocolViewerParsers-QVG4JP23.mjs +4 -0
- package/dist/{protocolViewerParsers-EUBHHIPL.mjs.map → protocolViewerParsers-QVG4JP23.mjs.map} +1 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.mts +3 -2
- package/dist/react.d.ts +3 -2
- package/dist/react.mjs +2 -2
- package/dist/{vaultUtils-CZKrvm9v.d.mts → vaultUtils-J1WboG1T.d.mts} +123 -228
- package/dist/{vaultUtils-CZKrvm9v.d.ts → vaultUtils-J1WboG1T.d.ts} +123 -228
- package/package.json +10 -3
- package/dist/chunk-37HJPVJE.mjs +0 -11
- package/dist/chunk-37HJPVJE.mjs.map +0 -1
- package/dist/chunk-6YLLNF6Q.mjs.map +0 -1
- package/dist/chunk-E5SYWOUK.mjs +0 -231
- package/dist/chunk-E5SYWOUK.mjs.map +0 -1
- package/dist/chunk-F7USDS7O.mjs +0 -408
- package/dist/chunk-F7USDS7O.mjs.map +0 -1
- package/dist/chunk-PQQWQF3C.mjs.map +0 -1
- package/dist/constants-YK56UVLH.mjs +0 -5
- package/dist/constants-YK56UVLH.mjs.map +0 -1
- package/dist/paymentResolution-3TC4HRHU.mjs +0 -4
- package/dist/paymentResolution-3TC4HRHU.mjs.map +0 -1
- 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-
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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/
|
|
17
|
-
var
|
|
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/
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
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
|
-
|
|
327
|
-
|
|
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
|
-
|
|
330
|
-
|
|
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
|
-
|
|
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
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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
|
-
|
|
371
|
-
|
|
372
|
-
|
|
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
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
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
|
|
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
|
|
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:
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
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 (
|
|
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,
|
|
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
|
|
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.
|
|
3616
|
-
* @param params.
|
|
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
|
-
|
|
4021
|
-
return /^0x[0-9a-fA-F]{40}$/.test(addr);
|
|
6049
|
+
return isValidHexAddress(addr);
|
|
4022
6050
|
}
|
|
4023
6051
|
normalizeAddress(addr) {
|
|
4024
|
-
|
|
4025
|
-
return addr;
|
|
6052
|
+
return normalizeAddress(addr);
|
|
4026
6053
|
}
|
|
4027
6054
|
parseEscrowAddressFromCompositeDepositId(depositId) {
|
|
4028
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
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
|
-
|
|
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
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
routing.escrowAddress
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
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
|
|
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-
|
|
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
|
-
|
|
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
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
7353
|
+
return this._pvReader.isZeroAddressValue(value);
|
|
5891
7354
|
}
|
|
5892
|
-
toBigIntOrZero(value) {
|
|
5893
|
-
|
|
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.
|
|
7359
|
+
return this._pvReader.buildProtocolViewerContexts(options);
|
|
5902
7360
|
}
|
|
5903
7361
|
isProtocolViewerDepositPopulated(view) {
|
|
5904
|
-
return
|
|
7362
|
+
return this._pvReader.isProtocolViewerDepositPopulated(view);
|
|
5905
7363
|
}
|
|
5906
7364
|
isProtocolViewerIntentPopulated(view) {
|
|
5907
|
-
return
|
|
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
|
-
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
|
|
6020
|
-
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|