@zkp2p/sdk 0.3.0 → 0.3.2-rc.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/dist/index.cjs CHANGED
@@ -254,9 +254,6 @@ function uniqueAddresses(...values) {
254
254
  }
255
255
  return addresses;
256
256
  }
257
- function addressesEqual(left, right) {
258
- return Boolean(left && right && left.toLowerCase() === right.toLowerCase());
259
- }
260
257
  function readRuntimeEnv(key) {
261
258
  try {
262
259
  const meta = ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) });
@@ -288,26 +285,19 @@ function getContracts(chainId, env = "production") {
288
285
  "ProtocolViewerV2"
289
286
  ]);
290
287
  const baseV2ProtocolViewerAddress = pickAddress(baseContracts, ["ProtocolViewerV2"]);
291
- const baseV1ProtocolViewerAddress = pickAddress(baseContracts, ["ProtocolViewer"]);
292
288
  const baseProtocolViewerEntries = (() => {
293
289
  const entries = [];
294
290
  if (baseV2ProtocolViewerAddress && baseV2ProtocolViewerAbi) {
295
291
  entries.push({ address: baseV2ProtocolViewerAddress, abi: baseV2ProtocolViewerAbi });
296
292
  }
297
- if (baseV1ProtocolViewerAddress && !addressesEqual(baseV1ProtocolViewerAddress, baseV2ProtocolViewerAddress)) {
298
- entries.push({ address: baseV1ProtocolViewerAddress, abi: ProtocolViewerBase__default.default });
299
- }
300
293
  return entries.length > 0 ? entries : void 0;
301
294
  })();
302
295
  const addressesByKey = {
303
296
  base: {
304
- escrow: pickAddress(baseContracts, ["EscrowV2", "Escrow_V2"]) ?? pickAddress(baseContracts, ["Escrow"]) ?? "",
297
+ escrow: pickAddress(baseContracts, ["EscrowV2", "Escrow_V2"]) ?? "",
305
298
  escrowV2: pickAddress(baseContracts, ["EscrowV2", "Escrow_V2"]),
306
- escrowAddresses: uniqueAddresses(
307
- pickAddress(baseContracts, ["EscrowV2", "Escrow_V2"]),
308
- pickAddress(baseContracts, ["Escrow"])
309
- ),
310
- orchestrator: pickAddress(baseContracts, ["OrchestratorV2", "Orchestrator_V2"]) ?? pickAddress(baseContracts, ["Orchestrator"]),
299
+ escrowAddresses: uniqueAddresses(pickAddress(baseContracts, ["EscrowV2", "Escrow_V2"])),
300
+ orchestrator: pickAddress(baseContracts, ["OrchestratorV2", "Orchestrator_V2"]),
311
301
  orchestratorV2: pickAddress(baseContracts, ["OrchestratorV2", "Orchestrator_V2"]),
312
302
  orchestratorAddresses: uniqueAddresses(
313
303
  pickAddress(baseContracts, ["OrchestratorV2", "Orchestrator_V2"])
@@ -317,7 +307,7 @@ function getContracts(chainId, env = "production") {
317
307
  "UnifiedPaymentVerifier"
318
308
  ]),
319
309
  unifiedPaymentVerifierV2: pickAddress(baseContracts, ["UnifiedPaymentVerifierV2"]),
320
- protocolViewer: baseProtocolViewerEntries?.[0]?.address ?? baseV1ProtocolViewerAddress ?? baseV2ProtocolViewerAddress,
310
+ protocolViewer: baseProtocolViewerEntries?.[0]?.address ?? baseV2ProtocolViewerAddress,
321
311
  protocolViewerEntries: baseProtocolViewerEntries,
322
312
  usdc: baseConstants.USDC,
323
313
  rateManagerV1: pickAddress(baseContracts, ["RateManagerV1", "DepositRateManagerRegistryV1"]),
@@ -368,13 +358,13 @@ function getContracts(chainId, env = "production") {
368
358
  "VITE_BASE_STAGING_ESCROW_V2_ADDRESS",
369
359
  "VITE_ESCROW_V2_ADDRESS"
370
360
  ]);
371
- const stagingEscrowCurrent = stagingEscrowV2Override ?? pickAddress(sc, ["EscrowV2", "Escrow_V2"]) ?? pickAddress(sc, ["Escrow"]);
361
+ const stagingEscrowCurrent = stagingEscrowV2Override ?? pickAddress(sc, ["EscrowV2", "Escrow_V2"]);
372
362
  const stagingOrchestratorV2Override = resolveRuntimeAddressOverride([
373
363
  "VITE_BASE_STAGING_ORCHESTRATOR_V2_ADDRESS",
374
364
  "VITE_ORCHESTRATOR_V2_ADDRESS",
375
365
  "VITE_ORCHESTRATORV2_ADDRESS"
376
366
  ]);
377
- const stagingOrchestratorCurrent = stagingOrchestratorV2Override ?? pickAddress(sc, ["OrchestratorV2", "Orchestrator_V2"]) ?? pickAddress(sc, ["Orchestrator"]);
367
+ const stagingOrchestratorCurrent = stagingOrchestratorV2Override ?? pickAddress(sc, ["OrchestratorV2", "Orchestrator_V2"]);
378
368
  const stagingRateManagerV1 = pickAddress(sc, ["RateManagerV1", "DepositRateManagerRegistryV1"]);
379
369
  return {
380
370
  addresses: {
@@ -389,7 +379,7 @@ function getContracts(chainId, env = "production") {
389
379
  "UnifiedPaymentVerifier"
390
380
  ]),
391
381
  unifiedPaymentVerifierV2: pickAddress(sc, ["UnifiedPaymentVerifierV2"]),
392
- protocolViewer: pickAddress(sc, ["ProtocolViewerV2", "ProtocolViewer"]),
382
+ protocolViewer: pickAddress(sc, ["ProtocolViewerV2"]),
393
383
  protocolViewerEntries: (() => {
394
384
  const entries = [];
395
385
  const pvV2Address = pickAddress(sc, ["ProtocolViewerV2"]);
@@ -399,11 +389,6 @@ function getContracts(chainId, env = "production") {
399
389
  if (pvV2Address && pvV2Abi) {
400
390
  entries.push({ address: pvV2Address, abi: pvV2Abi });
401
391
  }
402
- const pvV1Address = pickAddress(sc, ["ProtocolViewer"]);
403
- const pvV1Abi = ProtocolViewerBaseStaging__default.default;
404
- if (pvV1Address && !addressesEqual(pvV1Address, pvV2Address) && pvV1Abi) {
405
- entries.push({ address: pvV1Address, abi: pvV1Abi });
406
- }
407
392
  return entries.length > 0 ? entries : void 0;
408
393
  })(),
409
394
  usdc: baseStagingConstants.USDC,
@@ -416,12 +401,11 @@ function getContracts(chainId, env = "production") {
416
401
  },
417
402
  abis: {
418
403
  escrow: EscrowBaseStaging__default.default,
419
- escrowV2: addressesEqual(stagingEscrowCurrent, pickAddress(sc, ["Escrow"])) ? EscrowBaseStaging__default.default : pickAbi(baseStagingAbisRaw__namespace, ["EscrowV2"]) ?? EscrowBaseStaging__default.default,
404
+ escrowV2: pickAbi(baseStagingAbisRaw__namespace, [
405
+ "EscrowV2"
406
+ ]) ?? EscrowBaseStaging__default.default,
420
407
  orchestrator: OrchestratorBaseStaging__default.default,
421
- orchestratorV2: addressesEqual(
422
- stagingOrchestratorCurrent,
423
- pickAddress(sc, ["Orchestrator"])
424
- ) ? OrchestratorBaseStaging__default.default : pickAbi(baseStagingAbisRaw__namespace, [
408
+ orchestratorV2: pickAbi(baseStagingAbisRaw__namespace, [
425
409
  "OrchestratorV2"
426
410
  ]) ?? OrchestratorBaseStaging__default.default,
427
411
  unifiedPaymentVerifier: pickAbi(baseStagingAbisRaw__namespace, [
@@ -1460,7 +1444,7 @@ function createHeaders(apiKey, authorizationToken) {
1460
1444
  return headers2;
1461
1445
  }
1462
1446
  async function apiSignIntentV3(request, opts) {
1463
- const url = `${opts.baseApiUrl.replace(/\/$/, "")}/v3/intent`;
1447
+ const url = `${opts.baseApiUrl.replace(/\/$/, "")}/v3/intent/sign`;
1464
1448
  const json = await withRetry(
1465
1449
  async () => {
1466
1450
  let res;
@@ -1472,7 +1456,7 @@ async function apiSignIntentV3(request, opts) {
1472
1456
  });
1473
1457
  } catch (error) {
1474
1458
  throw new exports.NetworkError("Failed to connect to API server", {
1475
- endpoint: "/v3/intent",
1459
+ endpoint: "/v3/intent/sign",
1476
1460
  error
1477
1461
  });
1478
1462
  }
@@ -1490,7 +1474,7 @@ async function apiSignIntentV3(request, opts) {
1490
1474
  const expStr = json?.responseObject?.intentData?.signatureExpiration ?? json?.responseObject?.signatureExpiration;
1491
1475
  const preIntentHookData = json?.responseObject?.intentData?.preIntentHookData ?? json?.responseObject?.preIntentHookData;
1492
1476
  const referralFees = json?.responseObject?.intentData?.referralFees ?? json?.responseObject?.referralFees;
1493
- if (!sig || !expStr) throw new Error("v3/intent missing signature or expiration");
1477
+ if (!sig || !expStr) throw new Error("v3/intent/sign missing signature or expiration");
1494
1478
  return {
1495
1479
  signature: sig,
1496
1480
  signatureExpiration: BigInt(expStr),
@@ -1527,6 +1511,34 @@ async function apiCreatePaymentAttestation(payload, attestationServiceUrl, platf
1527
1511
  return res.json();
1528
1512
  });
1529
1513
  }
1514
+ async function apiCreateSellerCredentialBundle(payload, attestationServiceUrl, platform, timeoutMs) {
1515
+ return withRetry(
1516
+ async () => {
1517
+ let res;
1518
+ try {
1519
+ const endpoint = `/seller/credentials/${encodeURIComponent(platform)}`;
1520
+ res = await fetch(`${attestationServiceUrl}${endpoint}`, {
1521
+ method: "POST",
1522
+ headers: headers(),
1523
+ body: JSON.stringify(payload)
1524
+ });
1525
+ } catch (error) {
1526
+ throw new exports.NetworkError("Failed to connect to Attestation Service", {
1527
+ endpoint: `/seller/credentials/${platform}`,
1528
+ error
1529
+ });
1530
+ }
1531
+ if (!res.ok) {
1532
+ const errorText = await res.text();
1533
+ throw parseAPIError(res, errorText);
1534
+ }
1535
+ return res.json();
1536
+ },
1537
+ 3,
1538
+ 1e3,
1539
+ timeoutMs
1540
+ );
1541
+ }
1530
1542
  var abiCoder = ethers.AbiCoder.defaultAbiCoder();
1531
1543
  function encodeVerifyPaymentData(params) {
1532
1544
  return abiCoder.encode(
@@ -1670,6 +1682,9 @@ var PAYMENT_PLATFORMS = [
1670
1682
  "n26"
1671
1683
  ];
1672
1684
 
1685
+ // src/utils/constants.ts
1686
+ var DEFAULT_BASE_API_URL = "https://api.zkp2p.xyz";
1687
+
1673
1688
  // src/utils/oracles.ts
1674
1689
  init_currency();
1675
1690
  var ZERO_ADDRESS3 = "0x0000000000000000000000000000000000000000";
@@ -1916,6 +1931,13 @@ var IntentOperations = class {
1916
1931
  orchestratorAddress: params.orchestratorAddress,
1917
1932
  escrowAddress: escrowContext.address
1918
1933
  });
1934
+ const currentEscrow = this.config.getEscrowV2Address();
1935
+ const currentOrchestrator = this.config.getOrchestratorV2Address();
1936
+ if (currentEscrow && escrowContext.address.toLowerCase() !== currentEscrow.toLowerCase() || currentOrchestrator && orchestratorContext.address.toLowerCase() !== currentOrchestrator.toLowerCase()) {
1937
+ throw new Error(
1938
+ "signalIntent is only supported on the current EscrowV2 / OrchestratorV2 deployment"
1939
+ );
1940
+ }
1919
1941
  const catalog = getPaymentMethodsCatalog(this.config.getChainId(), this.config.getRuntimeEnv());
1920
1942
  const paymentMethod = resolvePaymentMethodHashFromCatalog(params.processorName, catalog);
1921
1943
  const fiatCurrency = resolveFiatCurrencyBytes32(params.fiatCurrencyCode);
@@ -1967,13 +1989,13 @@ var IntentOperations = class {
1967
1989
  if (response.referralFees !== void 0) {
1968
1990
  referralFees = response.referralFees.map((referralFee) => {
1969
1991
  if (!isValidReferrerFeeRecipient(referralFee.recipient)) {
1970
- throw new Error("v3/intent returned invalid referral fee recipient");
1992
+ throw new Error("v3/intent/sign returned invalid referral fee recipient");
1971
1993
  }
1972
1994
  let fee;
1973
1995
  try {
1974
1996
  fee = BigInt(referralFee.fee);
1975
1997
  } catch {
1976
- throw new Error("v3/intent returned non-integer referral fee value");
1998
+ throw new Error("v3/intent/sign returned non-integer referral fee value");
1977
1999
  }
1978
2000
  return {
1979
2001
  recipient: referralFee.recipient,
@@ -5950,7 +5972,7 @@ function convertIndexerDepositToLegacyApiDeposit(deposit) {
5950
5972
  }
5951
5973
  async function apiPostDepositDetails(req, baseApiUrl, timeoutMs, _apiKey, _authToken) {
5952
5974
  return apiFetch({
5953
- url: `${withApiBase(baseApiUrl)}/v1/makers/create`,
5975
+ url: `${withApiBase(baseApiUrl)}/v2/makers/create`,
5954
5976
  method: "POST",
5955
5977
  body: req,
5956
5978
  timeoutMs
@@ -5983,7 +6005,8 @@ async function apiGetQuote(req, baseApiUrl, timeoutMs, apiKey, authToken) {
5983
6005
  [isExactFiat ? "exactFiatAmount" : "exactTokenAmount"]: String(req.amount),
5984
6006
  amount: void 0,
5985
6007
  isExactFiat: void 0,
5986
- quotesToReturn: void 0
6008
+ quotesToReturn: void 0,
6009
+ includePrivateOrderbooks: req.includePrivateOrderbooks
5987
6010
  };
5988
6011
  Object.keys(requestBody).forEach((k) => requestBody[k] === void 0 && delete requestBody[k]);
5989
6012
  return apiFetch({
@@ -6020,7 +6043,7 @@ async function apiGetQuotesBestByPlatform(req, baseApiUrl, timeoutMs, apiKey, au
6020
6043
  }
6021
6044
  async function apiGetPayeeDetails(req, apiKey, baseApiUrl, authToken, timeoutMs) {
6022
6045
  return apiFetch({
6023
- url: `${baseApiUrl.replace(/\/$/, "")}/v1/makers/${req.processorName}/${req.hashedOnchainId}`,
6046
+ url: `${baseApiUrl.replace(/\/$/, "")}/v2/makers/${req.processorName}/${req.hashedOnchainId}`,
6024
6047
  method: "GET",
6025
6048
  apiKey,
6026
6049
  authToken,
@@ -6029,7 +6052,7 @@ async function apiGetPayeeDetails(req, apiKey, baseApiUrl, authToken, timeoutMs)
6029
6052
  }
6030
6053
  async function apiValidatePayeeDetails(req, baseApiUrl, timeoutMs) {
6031
6054
  const data = await apiFetch({
6032
- url: `${baseApiUrl.replace(/\/$/, "")}/v1/makers/validate`,
6055
+ url: `${baseApiUrl.replace(/\/$/, "")}/v2/makers/validate`,
6033
6056
  method: "POST",
6034
6057
  body: req,
6035
6058
  timeoutMs
@@ -6087,6 +6110,78 @@ async function apiGetTakerTier(req, apiKey, baseApiUrl, timeoutMs) {
6087
6110
  timeoutMs
6088
6111
  });
6089
6112
  }
6113
+ async function apiUploadSellerCredential(makerId, bundle, baseApiUrl, timeoutMs, apiKey, authToken) {
6114
+ return apiFetch({
6115
+ url: `${withApiBase(baseApiUrl)}/v2/makers/${makerId}/seller-credential`,
6116
+ method: "POST",
6117
+ body: bundle,
6118
+ apiKey,
6119
+ authToken,
6120
+ timeoutMs
6121
+ });
6122
+ }
6123
+ async function apiGetSellerCredentialStatus(makerId, baseApiUrl, timeoutMs, apiKey, authToken) {
6124
+ return apiFetch({
6125
+ url: `${withApiBase(baseApiUrl)}/v2/makers/${makerId}/seller-credential/status`,
6126
+ method: "GET",
6127
+ apiKey,
6128
+ authToken,
6129
+ timeoutMs
6130
+ });
6131
+ }
6132
+ async function apiVerifySellerPayment(platform, req, baseApiUrl, timeoutMs, apiKey, authToken) {
6133
+ return apiFetch({
6134
+ url: `${withApiBase(baseApiUrl)}/v2/verify/seller/${encodeURIComponent(platform)}`,
6135
+ method: "POST",
6136
+ body: req,
6137
+ apiKey,
6138
+ authToken,
6139
+ timeoutMs
6140
+ });
6141
+ }
6142
+ async function apiGetOrderbook(params, optsOrBaseApiUrl, timeoutMs, apiKey) {
6143
+ const opts = typeof optsOrBaseApiUrl === "string" ? {
6144
+ baseApiUrl: optsOrBaseApiUrl,
6145
+ timeoutMs,
6146
+ apiKey
6147
+ } : optsOrBaseApiUrl;
6148
+ const query = new URLSearchParams();
6149
+ Object.entries(params).forEach(([key, value]) => {
6150
+ if (value === void 0 || value === null) return;
6151
+ query.set(key, String(value));
6152
+ });
6153
+ const response = await apiFetch({
6154
+ url: `${withApiBase(opts.baseApiUrl)}/v2/orderbook?${query.toString()}`,
6155
+ method: "GET",
6156
+ apiKey: opts.apiKey,
6157
+ authToken: opts.authToken,
6158
+ timeoutMs: opts.timeoutMs
6159
+ });
6160
+ return response.responseObject;
6161
+ }
6162
+ async function apiGetDepositBundle(params, optsOrBaseApiUrl, timeoutMs, apiKey) {
6163
+ const opts = typeof optsOrBaseApiUrl === "string" ? {
6164
+ baseApiUrl: optsOrBaseApiUrl,
6165
+ timeoutMs,
6166
+ apiKey
6167
+ } : optsOrBaseApiUrl;
6168
+ const escrowAddress = requireEscrowAddress(
6169
+ params.escrowAddress,
6170
+ "apiGetDepositBundle requires escrowAddress"
6171
+ );
6172
+ const query = new URLSearchParams({ escrowAddress });
6173
+ if (params.dailySnapshotLimit !== void 0) {
6174
+ query.set("dailySnapshotLimit", String(params.dailySnapshotLimit));
6175
+ }
6176
+ const response = await apiFetch({
6177
+ url: `${withApiBase(opts.baseApiUrl)}/v2/deposits/${params.depositId}/bundle?${query.toString()}`,
6178
+ method: "GET",
6179
+ apiKey: opts.apiKey,
6180
+ authToken: opts.authToken,
6181
+ timeoutMs: opts.timeoutMs
6182
+ });
6183
+ return response.responseObject;
6184
+ }
6090
6185
 
6091
6186
  // src/client/Zkp2pClient.ts
6092
6187
  init_contracts();
@@ -6228,6 +6323,95 @@ var ERC20_ABI = [
6228
6323
  ];
6229
6324
 
6230
6325
  // src/client/Zkp2pClient.ts
6326
+ function isStringRecord(value) {
6327
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
6328
+ return false;
6329
+ }
6330
+ return Object.values(value).every((entry) => typeof entry === "string");
6331
+ }
6332
+ function normalizeTelegramUsername(value) {
6333
+ if (typeof value !== "string") {
6334
+ return value === null ? null : null;
6335
+ }
6336
+ const normalized = value.trim();
6337
+ return normalized.length > 0 ? normalized : null;
6338
+ }
6339
+ function extractLegacyQuotePayeeData(depositData) {
6340
+ if (!depositData || typeof depositData !== "object" || Array.isArray(depositData)) {
6341
+ return void 0;
6342
+ }
6343
+ const stringEntries = Object.entries(depositData).filter(
6344
+ (entry) => typeof entry[1] === "string" && entry[1].trim().length > 0
6345
+ );
6346
+ const telegramUsername = stringEntries.find(([key]) => key === "telegramUsername")?.[1] ?? null;
6347
+ const identifierEntries = stringEntries.filter(([key]) => key !== "telegramUsername");
6348
+ const [primaryEntry, ...metadataEntries] = identifierEntries;
6349
+ if (!primaryEntry) {
6350
+ return void 0;
6351
+ }
6352
+ return {
6353
+ offchainId: primaryEntry[1],
6354
+ telegramUsername,
6355
+ metadata: metadataEntries.length > 0 ? Object.fromEntries(metadataEntries) : null
6356
+ };
6357
+ }
6358
+ function normalizeQuotePayeeData(maker) {
6359
+ const legacy = extractLegacyQuotePayeeData(maker?.depositData);
6360
+ const offchainId = typeof maker?.offchainId === "string" && maker.offchainId.trim().length > 0 ? maker.offchainId : legacy?.offchainId;
6361
+ if (!offchainId) {
6362
+ return void 0;
6363
+ }
6364
+ return {
6365
+ offchainId,
6366
+ telegramUsername: normalizeTelegramUsername(maker?.telegramUsername) ?? legacy?.telegramUsername ?? null,
6367
+ metadata: isStringRecord(maker?.metadata) ? maker.metadata : legacy?.metadata ?? null
6368
+ };
6369
+ }
6370
+ function normalizePayeeDataInputItem(raw) {
6371
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
6372
+ return null;
6373
+ }
6374
+ const candidate = raw;
6375
+ if (typeof candidate.offchainId === "string" && candidate.offchainId.trim().length > 0) {
6376
+ return candidate;
6377
+ }
6378
+ const legacy = extractLegacyQuotePayeeData(raw);
6379
+ if (!legacy) {
6380
+ return null;
6381
+ }
6382
+ return {
6383
+ offchainId: legacy.offchainId,
6384
+ telegramUsername: legacy.telegramUsername,
6385
+ metadata: legacy.metadata
6386
+ };
6387
+ }
6388
+ function resolvePayeeDataInput(params, methodName) {
6389
+ const payeeData = params.payeeData ?? params.depositData;
6390
+ if (!Array.isArray(payeeData)) {
6391
+ throw new Error(`${methodName} requires payeeData`);
6392
+ }
6393
+ const normalized = payeeData.map((item, index) => {
6394
+ const result = normalizePayeeDataInputItem(item);
6395
+ if (!result) {
6396
+ throw new Error(
6397
+ `${methodName}: payeeData[${index}] must include a non-empty offchainId or a recognizable legacy identifier`
6398
+ );
6399
+ }
6400
+ return result;
6401
+ });
6402
+ return normalized;
6403
+ }
6404
+ function toPostDepositDetailsRequest(processorName, payeeData, index) {
6405
+ if (!payeeData || typeof payeeData.offchainId !== "string" || payeeData.offchainId.length === 0) {
6406
+ throw new Error(`payeeData[${index}] must include a non-empty offchainId`);
6407
+ }
6408
+ return {
6409
+ processorName,
6410
+ offchainId: payeeData.offchainId,
6411
+ telegramUsername: payeeData.telegramUsername,
6412
+ metadata: payeeData.metadata
6413
+ };
6414
+ }
6231
6415
  var Zkp2pClient = class {
6232
6416
  /**
6233
6417
  * Creates a new Zkp2pClient instance.
@@ -6774,7 +6958,7 @@ var Zkp2pClient = class {
6774
6958
  * sending fiat payment to the deposit's payee.
6775
6959
  *
6776
6960
  * If `gatingServiceSignature` is not provided, the SDK will automatically
6777
- * fetch one from curator `/v3/intent` when `apiKey` or `authorizationToken`
6961
+ * fetch one from curator `/v3/intent/sign` when `apiKey` or `authorizationToken`
6778
6962
  * is available. Otherwise you must provide `gatingServiceSignature` and
6779
6963
  * `signatureExpiration` yourself.
6780
6964
  *
@@ -7213,6 +7397,7 @@ var Zkp2pClient = class {
7213
7397
  getProtocolViewerAbi: () => this.protocolViewerAbi,
7214
7398
  getIndexerClient: () => this._indexerClient,
7215
7399
  getIndexerService: () => this._indexerService,
7400
+ getEscrowV2Address: () => this.escrowV2Address,
7216
7401
  getOrchestratorV2Address: () => this.orchestratorV2Address,
7217
7402
  host: {
7218
7403
  resolveEscrowContext: (options) => this.resolveEscrowContext(options),
@@ -7236,6 +7421,30 @@ var Zkp2pClient = class {
7236
7421
  parseRawDepositId(depositId) {
7237
7422
  return parseRawDepositId(depositId);
7238
7423
  }
7424
+ stripTrailingSlash(url) {
7425
+ return url.replace(/\/$/, "");
7426
+ }
7427
+ defaultAttestationServiceForBaseApiUrl(baseApiUrl) {
7428
+ try {
7429
+ const { hostname } = new URL(baseApiUrl);
7430
+ if (hostname === "api-staging.zkp2p.xyz") {
7431
+ return "https://attestation-service-staging.zkp2p.xyz";
7432
+ }
7433
+ if (hostname === "api-preprod.zkp2p.xyz") {
7434
+ return "https://attestation-service.zkp2p.xyz";
7435
+ }
7436
+ if (hostname === "api.zkp2p.xyz") {
7437
+ return "https://attestation-service.zkp2p.xyz";
7438
+ }
7439
+ } catch {
7440
+ }
7441
+ if (baseApiUrl === DEFAULT_BASE_API_URL) {
7442
+ return "https://attestation-service.zkp2p.xyz";
7443
+ }
7444
+ throw new Error(
7445
+ `attestationServiceUrl is required when baseApiUrl is not a supported zkp2p API host: ${baseApiUrl}`
7446
+ );
7447
+ }
7239
7448
  normalizeOracleRateConfig(config) {
7240
7449
  return normalizeOracleRateConfig(config);
7241
7450
  }
@@ -8088,31 +8297,29 @@ var Zkp2pClient = class {
8088
8297
  * register maker payment details with the curator service.
8089
8298
  *
8090
8299
  * @param params.processorNames - Payment platforms (e.g., ['wise', 'revolut'])
8091
- * @param params.depositData - Payee details per processor (e.g., [{ email: '...' }])
8300
+ * @param params.payeeData - Payee details per processor (e.g., [{ offchainId: 'you@example.com' }]). Required when the SDK needs to register payee details with the curator.
8092
8301
  * @returns The posted deposit details and their corresponding hashed on-chain IDs
8093
8302
  *
8094
8303
  * @example
8095
8304
  * ```typescript
8096
8305
  * const { hashedOnchainIds } = await client.registerPayeeDetails({
8097
8306
  * processorNames: ['wise'],
8098
- * depositData: [{ email: 'you@example.com' }],
8307
+ * payeeData: [{ offchainId: 'you@example.com' }],
8099
8308
  * });
8100
8309
  * // Then pass hashedOnchainIds to createDeposit
8101
8310
  * ```
8102
8311
  */
8103
8312
  async registerPayeeDetails(params) {
8313
+ const payeeData = resolvePayeeDataInput(params, "registerPayeeDetails");
8104
8314
  if (!Array.isArray(params.processorNames) || params.processorNames.length === 0) {
8105
8315
  throw new Error("processorNames must be a non-empty array");
8106
8316
  }
8107
- if (params.processorNames.length !== params.depositData.length) {
8108
- throw new Error("processorNames and depositData length mismatch");
8317
+ if (params.processorNames.length !== payeeData.length) {
8318
+ throw new Error("processorNames and payeeData length mismatch");
8109
8319
  }
8110
8320
  const baseApiUrl = (this.baseApiUrl ?? "https://api.zkp2p.xyz").replace(/\/$/, "");
8111
8321
  const depositDetails = params.processorNames.map(
8112
- (processorName, index) => ({
8113
- processorName,
8114
- depositData: params.depositData[index] || {}
8115
- })
8322
+ (processorName, index) => toPostDepositDetailsRequest(processorName, payeeData[index], index)
8116
8323
  );
8117
8324
  const apiResponses = await Promise.all(
8118
8325
  depositDetails.map((req) => apiPostDepositDetails(req, baseApiUrl, this.apiTimeoutMs))
@@ -8139,16 +8346,17 @@ var Zkp2pClient = class {
8139
8346
  * @param params.amount - Total deposit amount in token units (6 decimals for USDC)
8140
8347
  * @param params.intentAmountRange - Min/max amount per intent
8141
8348
  * @param params.processorNames - Payment platforms to accept (e.g., ['wise', 'revolut'])
8142
- * @param params.depositData - Payee details per processor (e.g., [{ email: '...' }])
8349
+ * @param params.payeeData - Payee details per processor (e.g., [{ offchainId: 'you@example.com' }])
8143
8350
  * @param params.conversionRates - Conversion rates per processor, grouped by currency
8144
8351
  * @param params.payeeDetailsHashes - Pre-computed hashed on-chain IDs (from registerPayeeDetails). When provided, skips the curator API call entirely.
8145
8352
  * @param params.delegate - Optional delegate address that can manage the deposit
8146
8353
  * @param params.intentGuardian - Optional guardian for intent approval
8147
8354
  * @param params.retainOnEmpty - Keep deposit active when balance reaches zero
8148
8355
  * @param params.txOverrides - Optional viem transaction overrides
8149
- * @returns The deposit details posted to API and the transaction hash
8356
+ * @returns The deposit details posted to API (empty when payee registration is skipped) and the transaction hash
8150
8357
  *
8151
- * @throws Error if processorNames, depositData, and conversionRates lengths don't match
8358
+ * @throws Error if processorNames, payeeData, and conversionRates lengths don't match
8359
+ * @throws Error if payeeData is missing and neither payeeDetailsHashes nor full payment method overrides are provided
8152
8360
  * @throws Error if a currency is not supported by the specified processor
8153
8361
  *
8154
8362
  * @example
@@ -8159,7 +8367,7 @@ var Zkp2pClient = class {
8159
8367
  * amount: 1000_000000n,
8160
8368
  * intentAmountRange: { min: 10_000000n, max: 500_000000n },
8161
8369
  * processorNames: ['wise'],
8162
- * depositData: [{ email: 'you@example.com' }],
8370
+ * payeeData: [{ offchainId: 'you@example.com' }],
8163
8371
  * conversionRates: [[
8164
8372
  * { currency: 'USD', conversionRate: '1020000000000000000' }, // 1.02
8165
8373
  * { currency: 'EUR', conversionRate: '1100000000000000000' }, // 1.10
@@ -8192,24 +8400,30 @@ var Zkp2pClient = class {
8192
8400
  };
8193
8401
  }
8194
8402
  async prepareCreateDepositInternal(params) {
8403
+ const hasOverrides = Boolean(
8404
+ params.paymentMethodsOverride || params.paymentMethodDataOverride || params.currenciesOverride
8405
+ );
8406
+ const payeeDetailsHashes = params.payeeDetailsHashes;
8407
+ const hasPayeeHashes = payeeDetailsHashes !== void 0;
8408
+ const shouldResolvePayeeData = params.payeeData !== void 0 || params.depositData !== void 0;
8409
+ const payeeData = shouldResolvePayeeData ? resolvePayeeDataInput(params, "createDeposit") : null;
8195
8410
  if (!Array.isArray(params.processorNames) || params.processorNames.length === 0) {
8196
8411
  throw new Error("processorNames must be a non-empty array");
8197
8412
  }
8198
8413
  if (params.processorNames.length !== params.conversionRates.length) {
8199
8414
  throw new Error("processorNames and conversionRates length mismatch");
8200
8415
  }
8201
- if (params.processorNames.length !== params.depositData.length) {
8202
- throw new Error("processorNames and depositData length mismatch");
8416
+ if (payeeData && params.processorNames.length !== payeeData.length) {
8417
+ throw new Error("processorNames and payeeData length mismatch");
8203
8418
  }
8204
- const depositDetails = params.processorNames.map(
8205
- (processorName, index) => ({
8206
- processorName,
8207
- depositData: params.depositData[index] || {}
8208
- })
8209
- );
8210
- const hasOverrides = Boolean(
8211
- params.paymentMethodsOverride || params.paymentMethodDataOverride || params.currenciesOverride
8212
- );
8419
+ if (!hasOverrides && !hasPayeeHashes && !payeeData) {
8420
+ throw new Error(
8421
+ "createDeposit requires payeeData unless payeeDetailsHashes or full payment method overrides are provided"
8422
+ );
8423
+ }
8424
+ const depositDetails = payeeData ? params.processorNames.map(
8425
+ (processorName, index) => toPostDepositDetailsRequest(processorName, payeeData[index], index)
8426
+ ) : [];
8213
8427
  let paymentMethods;
8214
8428
  let paymentMethodData;
8215
8429
  let currencies;
@@ -8234,11 +8448,11 @@ var Zkp2pClient = class {
8234
8448
  );
8235
8449
  const intentGatingService = getGatingServiceAddress(this.chainId, this.runtimeEnv);
8236
8450
  let hashedOnchainIds;
8237
- if (params.payeeDetailsHashes) {
8238
- if (params.payeeDetailsHashes.length !== params.processorNames.length) {
8451
+ if (payeeDetailsHashes !== void 0) {
8452
+ if (payeeDetailsHashes.length !== params.processorNames.length) {
8239
8453
  throw new Error("payeeDetailsHashes length must match processorNames length");
8240
8454
  }
8241
- hashedOnchainIds = params.payeeDetailsHashes;
8455
+ hashedOnchainIds = payeeDetailsHashes;
8242
8456
  } else {
8243
8457
  const baseApiUrl = (this.baseApiUrl ?? "https://api.zkp2p.xyz").replace(/\/$/, "");
8244
8458
  const apiResponses = await Promise.all(
@@ -8424,7 +8638,7 @@ var Zkp2pClient = class {
8424
8638
  const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
8425
8639
  const reqWithEscrow = { ...req };
8426
8640
  if (!reqWithEscrow.escrowAddresses || reqWithEscrow.escrowAddresses.length === 0) {
8427
- const configuredEscrows = this.escrowAddresses.length > 0 ? this.escrowAddresses.map((address) => address) : this.escrowAddress ? [this.escrowAddress] : [];
8641
+ const configuredEscrows = this.escrowV2Address ? [this.escrowV2Address] : this.escrowAddress ? [this.escrowAddress] : [];
8428
8642
  if (configuredEscrows.length > 0) {
8429
8643
  reqWithEscrow.escrowAddresses = configuredEscrows;
8430
8644
  }
@@ -8439,8 +8653,9 @@ var Zkp2pClient = class {
8439
8653
  const quotes = quote?.responseObject?.quotes ?? [];
8440
8654
  for (const q of quotes) {
8441
8655
  const maker = q?.maker;
8442
- if (maker?.depositData && typeof q === "object") {
8443
- q.payeeData = maker.depositData;
8656
+ const payeeData = normalizeQuotePayeeData(maker);
8657
+ if (payeeData && typeof q === "object") {
8658
+ q.payeeData = payeeData;
8444
8659
  }
8445
8660
  }
8446
8661
  return appendReferrerFeeDisplayFields(quote, referrerFeeConfig);
@@ -8467,7 +8682,7 @@ var Zkp2pClient = class {
8467
8682
  const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
8468
8683
  const reqWithEscrow = { ...req };
8469
8684
  if (!reqWithEscrow.escrowAddresses || reqWithEscrow.escrowAddresses.length === 0) {
8470
- const configuredEscrows = this.escrowAddresses.length > 0 ? [...this.escrowAddresses] : this.escrowAddress ? [this.escrowAddress] : [];
8685
+ const configuredEscrows = this.escrowV2Address ? [this.escrowV2Address] : this.escrowAddress ? [this.escrowAddress] : [];
8471
8686
  if (configuredEscrows.length > 0) {
8472
8687
  reqWithEscrow.escrowAddresses = configuredEscrows;
8473
8688
  }
@@ -8485,11 +8700,11 @@ var Zkp2pClient = class {
8485
8700
  ...quote.responseObject,
8486
8701
  platformQuotes: (quote.responseObject?.platformQuotes ?? []).map((platformQuote) => {
8487
8702
  const bestQuote = platformQuote?.bestQuote;
8488
- const makerDepositData = bestQuote?.maker?.depositData;
8489
- if (!bestQuote || !makerDepositData) return platformQuote;
8703
+ const payeeData = normalizeQuotePayeeData(bestQuote?.maker);
8704
+ if (!bestQuote || !payeeData) return platformQuote;
8490
8705
  return {
8491
8706
  ...platformQuote,
8492
- bestQuote: { ...bestQuote, payeeData: makerDepositData }
8707
+ bestQuote: { ...bestQuote, payeeData }
8493
8708
  };
8494
8709
  })
8495
8710
  }
@@ -8517,6 +8732,92 @@ var Zkp2pClient = class {
8517
8732
  const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
8518
8733
  return apiGetTakerTier(req, void 0, baseApiUrl, timeoutMs);
8519
8734
  }
8735
+ /**
8736
+ * The signed `expiresAtMs` field is an upload-time freshness token minted by attestation-service.
8737
+ * Once curator persists the bundle, seller-automated-release availability is governed by curator's
8738
+ * probe/revalidation state rather than this timestamp.
8739
+ *
8740
+ * Curator accepts either a configured API key or bearer token for this endpoint.
8741
+ *
8742
+ * Create a signed seller credential bundle with attestation-service and store it on the maker via curator.
8743
+ */
8744
+ async uploadSellerCredential(params, opts) {
8745
+ const baseApiUrl = this.stripTrailingSlash(
8746
+ opts?.baseApiUrl ?? this.baseApiUrl ?? DEFAULT_BASE_API_URL
8747
+ );
8748
+ const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
8749
+ const attestationServiceUrl = this.stripTrailingSlash(
8750
+ opts?.attestationServiceUrl ?? this.defaultAttestationServiceForBaseApiUrl(baseApiUrl)
8751
+ );
8752
+ const uploadPayload = {
8753
+ payeeId: params.payeeId,
8754
+ sessionMaterial: params.sessionMaterial
8755
+ };
8756
+ const bundleResponse = await apiCreateSellerCredentialBundle(
8757
+ uploadPayload,
8758
+ attestationServiceUrl,
8759
+ params.platform,
8760
+ timeoutMs
8761
+ );
8762
+ if (!bundleResponse.success || !bundleResponse.responseObject) {
8763
+ throw new Error(bundleResponse.message || "Failed to create seller credential bundle");
8764
+ }
8765
+ return apiUploadSellerCredential(
8766
+ params.makerId,
8767
+ bundleResponse.responseObject,
8768
+ baseApiUrl,
8769
+ timeoutMs,
8770
+ this.apiKey,
8771
+ this.authorizationToken
8772
+ );
8773
+ }
8774
+ /**
8775
+ * Status is a coarse curator-owned signal (`active` / `inactive` / `missing`) and intentionally
8776
+ * omits low-level diagnostics. Curator may still re-probe stale credentials during verify, so callers
8777
+ * should continue to handle a 410 from `verifySellerPayment`.
8778
+ *
8779
+ * Curator accepts either a configured API key or bearer token for this endpoint.
8780
+ *
8781
+ * Fetch seller credential status for a maker from curator.
8782
+ */
8783
+ async getSellerCredentialStatus(params, opts) {
8784
+ const baseApiUrl = this.stripTrailingSlash(
8785
+ opts?.baseApiUrl ?? this.baseApiUrl ?? DEFAULT_BASE_API_URL
8786
+ );
8787
+ const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
8788
+ return apiGetSellerCredentialStatus(
8789
+ params.makerId,
8790
+ baseApiUrl,
8791
+ timeoutMs,
8792
+ this.apiKey,
8793
+ this.authorizationToken
8794
+ );
8795
+ }
8796
+ /**
8797
+ * Internal-use endpoint. The curator route requires an internal `x-api-key`; standard SDK consumer
8798
+ * API keys will be rejected with 401. Returns 410 GONE when curator has marked the credential inactive
8799
+ * or a stale credential fails its synchronous re-probe.
8800
+ *
8801
+ * Verify a seller payment via curator's seller-credential proxy.
8802
+ */
8803
+ async verifySellerPayment(params, opts) {
8804
+ const baseApiUrl = this.stripTrailingSlash(
8805
+ opts?.baseApiUrl ?? this.baseApiUrl ?? DEFAULT_BASE_API_URL
8806
+ );
8807
+ const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
8808
+ return apiVerifySellerPayment(
8809
+ params.platform,
8810
+ {
8811
+ txId: params.txId,
8812
+ chainId: params.chainId,
8813
+ intent: params.intent
8814
+ },
8815
+ baseApiUrl,
8816
+ timeoutMs,
8817
+ this.apiKey,
8818
+ this.authorizationToken
8819
+ );
8820
+ }
8520
8821
  // ╔═══════════════════════════════════════════════════════════════════════════╗
8521
8822
  // ║ CORE: ON-CHAIN DEPOSIT VIEWS ║
8522
8823
  // ╚═══════════════════════════════════════════════════════════════════════════╝
@@ -8943,6 +9244,8 @@ exports.ZERO_RATE_MANAGER_ID = ZERO_RATE_MANAGER_ID;
8943
9244
  exports.ZKP2P_ANDROID_REFERRER = ZKP2P_ANDROID_REFERRER;
8944
9245
  exports.ZKP2P_IOS_REFERRER = ZKP2P_IOS_REFERRER;
8945
9246
  exports.Zkp2pClient = Zkp2pClient;
9247
+ exports.apiGetDepositBundle = apiGetDepositBundle;
9248
+ exports.apiGetOrderbook = apiGetOrderbook;
8946
9249
  exports.apiGetOwnerDeposits = apiGetOwnerDeposits;
8947
9250
  exports.apiGetPayeeDetails = apiGetPayeeDetails;
8948
9251
  exports.apiGetQuotesBestByPlatform = apiGetQuotesBestByPlatform;