@zkp2p/sdk 0.4.0 → 0.4.2

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
@@ -42374,6 +42374,20 @@ init_errors();
42374
42374
  function headers() {
42375
42375
  return { "Content-Type": "application/json" };
42376
42376
  }
42377
+ function normalizeOptionalString(value) {
42378
+ if (typeof value !== "string") {
42379
+ return null;
42380
+ }
42381
+ const normalized = value.trim();
42382
+ return normalized.length > 0 ? normalized : null;
42383
+ }
42384
+ function normalizeBaseUrl(value, label) {
42385
+ const normalized = normalizeOptionalString(value)?.replace(/\/+$/u, "");
42386
+ if (!normalized) {
42387
+ throw new Error(`${label} is required for buyer TEE session encryption.`);
42388
+ }
42389
+ return normalized;
42390
+ }
42377
42391
  function isPayeeBoundSellerCredentialUploadInput(payload) {
42378
42392
  return typeof payload.payeeId === "string";
42379
42393
  }
@@ -42438,6 +42452,51 @@ async function apiCreatePaymentAttestation(payload, attestationServiceUrl, platf
42438
42452
  return res.json();
42439
42453
  });
42440
42454
  }
42455
+ async function apiVerifyBuyerTeePayment(payload, attestationServiceUrl, platform, actionType) {
42456
+ return withRetry(async () => {
42457
+ let res;
42458
+ try {
42459
+ const endpoint = `/buyer/verify/${encodeURIComponent(platform)}/${encodeURIComponent(
42460
+ actionType
42461
+ )}`;
42462
+ res = await fetch(`${attestationServiceUrl}${endpoint}`, {
42463
+ method: "POST",
42464
+ headers: headers(),
42465
+ body: JSON.stringify(payload)
42466
+ });
42467
+ } catch (error) {
42468
+ throw new exports.NetworkError("Failed to connect to Attestation Service", {
42469
+ endpoint: `/buyer/verify/${platform}/${actionType}`,
42470
+ error
42471
+ });
42472
+ }
42473
+ if (!res.ok) {
42474
+ const errorText = await res.text();
42475
+ throw parseAPIError(res, errorText);
42476
+ }
42477
+ return res.json();
42478
+ });
42479
+ }
42480
+ async function createEncryptedBuyerTeeSessionMaterial({
42481
+ actionType,
42482
+ attestationRuntime,
42483
+ attestationServiceUrl,
42484
+ platform,
42485
+ sessionMaterial,
42486
+ timeoutMs
42487
+ }) {
42488
+ const params = {
42489
+ actionType,
42490
+ attestationServiceUrl: normalizeBaseUrl(attestationServiceUrl, "Attestation Service URL"),
42491
+ platform,
42492
+ sessionMaterial,
42493
+ ...timeoutMs == null ? {} : { timeoutMs },
42494
+ ...attestationRuntime?.fetch ? { fetch: attestationRuntime.fetch } : {},
42495
+ ...attestationRuntime?.subtle ? { subtle: attestationRuntime.subtle } : {},
42496
+ ...attestationRuntime?.getRandomValues ? { getRandomValues: attestationRuntime.getRandomValues } : {}
42497
+ };
42498
+ return zkp2pAttestation.createEncryptedBuyerTeeSessionMaterial(params);
42499
+ }
42441
42500
  async function apiCreateSellerCredentialBundle(payload, attestationServiceUrl, platform, timeoutMs, attestationRuntime) {
42442
42501
  return withRetry(
42443
42502
  async () => {
@@ -42492,12 +42551,13 @@ function encodePaymentAttestation(attestation) {
42492
42551
  const dataHash = td.dataHash;
42493
42552
  const signatures = [resp.signature];
42494
42553
  const encodedPaymentDetails = resp.encodedPaymentDetails;
42554
+ const metadata = typeof resp.metadata === "string" && resp.metadata.length > 0 ? resp.metadata : "0x";
42495
42555
  if (!intentHash || !releaseAmount || !dataHash || !encodedPaymentDetails) {
42496
42556
  throw new Error("Attestation response missing required fields");
42497
42557
  }
42498
42558
  return abiCoder.encode(
42499
42559
  ["tuple(bytes32,uint256,bytes32,bytes[],bytes,bytes)"],
42500
- [[intentHash, releaseAmount, dataHash, signatures, encodedPaymentDetails, "0x"]]
42560
+ [[intentHash, releaseAmount, dataHash, signatures, encodedPaymentDetails, metadata]]
42501
42561
  );
42502
42562
  }
42503
42563
 
@@ -42906,6 +42966,7 @@ var PLATFORM_ATTESTATION_CONFIG = {
42906
42966
  chime: { actionType: "transfer_chime", actionPlatform: "chime" },
42907
42967
  luxon: { actionType: "transfer_luxon", actionPlatform: "luxon" },
42908
42968
  n26: { actionType: "transfer_n26", actionPlatform: "n26" },
42969
+ alipay: { actionType: "transfer_alipay", actionPlatform: "alipay" },
42909
42970
  "zelle-chase": { actionType: "transfer_zelle", actionPlatform: "chase" },
42910
42971
  "zelle-bofa": { actionType: "transfer_zelle", actionPlatform: "bankofamerica" },
42911
42972
  "zelle-citi": { actionType: "transfer_zelle", actionPlatform: "citi" }
@@ -43206,6 +43267,8 @@ var IntentOperations = class {
43206
43267
  paymentProof = precomputed.paymentProof;
43207
43268
  verificationData = precomputed.verificationData;
43208
43269
  } else {
43270
+ const { proof } = params;
43271
+ const buyerTeeProof = parseBuyerTeePaymentProofInput(proof);
43209
43272
  const attestationServiceUrl = params.attestationServiceUrl ?? this.defaultAttestationService();
43210
43273
  const inputs = await this.config.host.getFulfillIntentInputs(intentHash, {
43211
43274
  orchestratorAddress: orchestratorContext.address
@@ -43220,24 +43283,33 @@ var IntentOperations = class {
43220
43283
  throw new Error("Unknown paymentMethodHash for this network/env; update SDK catalogs.");
43221
43284
  }
43222
43285
  const platformConfig = resolvePlatformAttestationConfig(platformName);
43223
- const zkTlsProof = typeof params.proof === "string" ? params.proof : serializeProofInput(params.proof);
43224
- const payload = {
43225
- proofType: "reclaim",
43226
- proof: zkTlsProof,
43227
- chainId: this.config.getChainId(),
43228
- intent: {
43229
- intentHash,
43230
- amount: inputs.amount,
43231
- timestampMs: inputs.intentTimestampMs,
43232
- paymentMethod: paymentMethodHash,
43233
- fiatCurrency: inputs.fiatCurrency,
43234
- conversionRate: inputs.conversionRate,
43235
- payeeDetails: inputs.payeeDetails,
43236
- timestampBufferMs: params.timestampBufferMs ?? "300000"
43237
- }
43286
+ const intent = {
43287
+ intentHash,
43288
+ amount: inputs.amount,
43289
+ timestampMs: inputs.intentTimestampMs,
43290
+ paymentMethod: paymentMethodHash,
43291
+ fiatCurrency: inputs.fiatCurrency,
43292
+ conversionRate: inputs.conversionRate,
43293
+ payeeDetails: inputs.payeeDetails,
43294
+ timestampBufferMs: params.timestampBufferMs ?? "300000"
43238
43295
  };
43239
- const attestation = await apiCreatePaymentAttestation(
43240
- payload,
43296
+ const attestation = buyerTeeProof ? await apiVerifyBuyerTeePayment(
43297
+ {
43298
+ encryptedSessionMaterial: buyerTeeProof.encryptedSessionMaterial,
43299
+ params: buyerTeeProof.params,
43300
+ chainId: this.config.getChainId(),
43301
+ intent
43302
+ },
43303
+ attestationServiceUrl,
43304
+ buyerTeeProof.actionPlatform ?? platformConfig.actionPlatform,
43305
+ buyerTeeProof.actionType ?? platformConfig.actionType
43306
+ ) : await apiCreatePaymentAttestation(
43307
+ {
43308
+ proofType: "reclaim",
43309
+ proof: typeof proof === "string" ? proof : serializeProofInput(proof),
43310
+ chainId: this.config.getChainId(),
43311
+ intent
43312
+ },
43241
43313
  attestationServiceUrl,
43242
43314
  platformConfig.actionPlatform,
43243
43315
  platformConfig.actionType
@@ -43355,6 +43427,34 @@ function serializeProofInput(proof) {
43355
43427
  (_key, value) => typeof value === "bigint" ? value.toString() : value
43356
43428
  );
43357
43429
  }
43430
+ function isRecord(value) {
43431
+ return typeof value === "object" && value !== null && !Array.isArray(value);
43432
+ }
43433
+ function isBuyerTeeParams(value) {
43434
+ return isRecord(value) && Object.values(value).every(
43435
+ (entry) => typeof entry === "string" || typeof entry === "number" || typeof entry === "boolean"
43436
+ );
43437
+ }
43438
+ function parseBuyerTeePaymentProofInput(proof) {
43439
+ if (!isRecord(proof) || proof.proofType !== "buyerTee") {
43440
+ return null;
43441
+ }
43442
+ if (typeof proof.encryptedSessionMaterial !== "string" || !isBuyerTeeParams(proof.params)) {
43443
+ throw new Error("Buyer TEE proof requires encryptedSessionMaterial and params.");
43444
+ }
43445
+ const parsed = {
43446
+ proofType: "buyerTee",
43447
+ encryptedSessionMaterial: proof.encryptedSessionMaterial,
43448
+ params: proof.params
43449
+ };
43450
+ if (typeof proof.actionType === "string") {
43451
+ parsed.actionType = proof.actionType;
43452
+ }
43453
+ if (typeof proof.actionPlatform === "string") {
43454
+ parsed.actionPlatform = proof.actionPlatform;
43455
+ }
43456
+ return parsed;
43457
+ }
43358
43458
  function normalizeSignalIntentReferralFees(params) {
43359
43459
  if (params.referralFees) {
43360
43460
  return params.referralFees.map((referralFee) => ({
@@ -47132,6 +47232,32 @@ async function apiUploadSellerCredential(processorName, payeeDetails, bundle, ba
47132
47232
  timeoutMs
47133
47233
  });
47134
47234
  }
47235
+ async function apiConfirmPayPalForwarding(payeeDetails, body, baseApiUrl, opts) {
47236
+ const endpoint = `/v2/makers/paypal/${encodeURIComponent(
47237
+ payeeDetails
47238
+ )}/seller-credential/forwarding-confirmation`;
47239
+ return apiFetch({
47240
+ url: `${withApiBase(baseApiUrl)}${endpoint}`,
47241
+ method: "POST",
47242
+ body,
47243
+ apiKey: opts?.apiKey,
47244
+ authToken: opts?.authToken,
47245
+ timeoutMs: opts?.timeoutMs
47246
+ });
47247
+ }
47248
+ async function apiUploadGoogleOAuthSellerCredential(processorName, payeeDetails, body, baseApiUrl, opts) {
47249
+ const endpoint = `/v2/makers/${encodeURIComponent(processorName)}/${encodeURIComponent(
47250
+ payeeDetails
47251
+ )}/seller-credential/google-oauth`;
47252
+ return apiFetch({
47253
+ url: `${withApiBase(baseApiUrl)}${endpoint}`,
47254
+ method: "POST",
47255
+ body,
47256
+ apiKey: opts?.apiKey,
47257
+ authToken: opts?.authToken,
47258
+ timeoutMs: opts?.timeoutMs
47259
+ });
47260
+ }
47135
47261
  async function apiGetSellerCredentialStatus(processorName, payeeDetails, baseApiUrl, timeoutMs) {
47136
47262
  const endpoint = `/v2/makers/${encodeURIComponent(processorName)}/${encodeURIComponent(
47137
47263
  payeeDetails
@@ -47234,6 +47360,11 @@ var applyReferrerFeeDisplayFieldsToTokenAmount = (tokenAmount, referrerFeeConfig
47234
47360
  }
47235
47361
  };
47236
47362
  var applyReferrerFeeDisplayFieldsToQuote = (quote, referrerFeeConfig, decimals) => {
47363
+ const enrichedQuote = quote;
47364
+ const hasCuratorReferrerFeeFields = enrichedQuote.referrerFeeAmount != null || enrichedQuote.referrerFeeBps != null;
47365
+ if (hasCuratorReferrerFeeFields) {
47366
+ return enrichedQuote;
47367
+ }
47237
47368
  const signalIntentAmount = quote.signalIntentAmount ?? quote.intent?.amount ?? quote.tokenAmount;
47238
47369
  const adjusted = applyReferrerFeeDisplayFieldsToTokenAmount(
47239
47370
  quote.tokenAmount,
@@ -48203,7 +48334,7 @@ var Zkp2pClient = class {
48203
48334
  * ```
48204
48335
  *
48205
48336
  * @param params.intentHash - The intent hash to fulfill (0x-prefixed, 32 bytes)
48206
- * @param params.proof - Payment proof from Reclaim (object or JSON string)
48337
+ * @param params.proof - Payment proof from Reclaim (object or JSON string) or buyer TEE proof input
48207
48338
  * @param params.timestampBufferMs - Allowed timestamp variance (default: 300000ms)
48208
48339
  * @param params.attestationServiceUrl - Override attestation service URL
48209
48340
  * @param params.postIntentHookData - Data to pass to post-intent hook
@@ -49839,6 +49970,76 @@ var Zkp2pClient = class {
49839
49970
  timeoutMs
49840
49971
  );
49841
49972
  }
49973
+ /**
49974
+ * Confirms the PayPal Gmail-forwarding setup for an existing maker payee hash.
49975
+ *
49976
+ * Uses curator's `/forwarding-confirmation` route and forwards both API key and
49977
+ * bearer token so either auth strategy can satisfy the hybrid gate. The endpoint
49978
+ * is rate-limited server-side; callers should surface retry guidance from APIError.
49979
+ */
49980
+ async confirmPayPalForwarding(params, opts) {
49981
+ const baseApiUrl = this.stripTrailingSlash(
49982
+ opts?.baseApiUrl ?? this.baseApiUrl ?? DEFAULT_BASE_API_URL
49983
+ );
49984
+ const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
49985
+ return apiConfirmPayPalForwarding(
49986
+ params.payeeDetails,
49987
+ {
49988
+ payeeEmail: params.payeeEmail,
49989
+ forwardingInitiatorEmail: params.forwardingInitiatorEmail
49990
+ },
49991
+ baseApiUrl,
49992
+ {
49993
+ apiKey: this.apiKey,
49994
+ authToken: this.authorizationToken,
49995
+ timeoutMs
49996
+ }
49997
+ );
49998
+ }
49999
+ /**
50000
+ * Upload a seller Gmail OAuth authorization code through curator.
50001
+ *
50002
+ * Curator owns the encryption hop to attestation-service for this flow, so
50003
+ * callers send the one-time Google code plus the stable seller identity.
50004
+ */
50005
+ async uploadGoogleOAuthSellerCredential(params, opts) {
50006
+ const baseApiUrl = this.stripTrailingSlash(
50007
+ opts?.baseApiUrl ?? this.baseApiUrl ?? DEFAULT_BASE_API_URL
50008
+ );
50009
+ const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
50010
+ if (params.platform === "paypal") {
50011
+ return apiUploadGoogleOAuthSellerCredential(
50012
+ "paypal",
50013
+ params.payeeDetails,
50014
+ {
50015
+ payeeEmail: params.payeeEmail,
50016
+ authorizationCode: params.authorizationCode,
50017
+ redirectUri: params.redirectUri
50018
+ },
50019
+ baseApiUrl,
50020
+ {
50021
+ apiKey: this.apiKey,
50022
+ authToken: this.authorizationToken,
50023
+ timeoutMs
50024
+ }
50025
+ );
50026
+ }
50027
+ return apiUploadGoogleOAuthSellerCredential(
50028
+ "venmo",
50029
+ params.payeeDetails,
50030
+ {
50031
+ accountId: params.accountId,
50032
+ authorizationCode: params.authorizationCode,
50033
+ redirectUri: params.redirectUri
50034
+ },
50035
+ baseApiUrl,
50036
+ {
50037
+ apiKey: this.apiKey,
50038
+ authToken: this.authorizationToken,
50039
+ timeoutMs
50040
+ }
50041
+ );
50042
+ }
49842
50043
  /**
49843
50044
  * Status is a coarse curator-owned signal (`active` / `inactive` / `missing`) and intentionally
49844
50045
  * omits low-level diagnostics. Curator may still re-probe stale credentials during verify, so callers
@@ -50077,7 +50278,7 @@ var assertObjectInput = (params) => {
50077
50278
  }
50078
50279
  return params;
50079
50280
  };
50080
- var normalizeOptionalString = (value, label) => {
50281
+ var normalizeOptionalString2 = (value, label) => {
50081
50282
  if (value === void 0) {
50082
50283
  return void 0;
50083
50284
  }
@@ -50091,7 +50292,7 @@ var normalizeOptionalString = (value, label) => {
50091
50292
  return trimmed;
50092
50293
  };
50093
50294
  var normalizeOptionalUrl = (value, label) => {
50094
- const trimmed = normalizeOptionalString(value, label);
50295
+ const trimmed = normalizeOptionalString2(value, label);
50095
50296
  if (trimmed === void 0) {
50096
50297
  return void 0;
50097
50298
  }
@@ -50218,20 +50419,20 @@ var buildOnrampQueryString = (params) => {
50218
50419
  searchParams.set(key, value);
50219
50420
  }
50220
50421
  };
50221
- setParam("referrer", normalizeOptionalString(validated.referrer, "referrer"));
50422
+ setParam("referrer", normalizeOptionalString2(validated.referrer, "referrer"));
50222
50423
  setParam("referrerLogo", normalizeOptionalUrl(validated.referrerLogo, "referrerLogo"));
50223
- setParam("inputCurrency", normalizeOptionalString(validated.inputCurrency, "inputCurrency"));
50424
+ setParam("inputCurrency", normalizeOptionalString2(validated.inputCurrency, "inputCurrency"));
50224
50425
  setParam("inputAmount", normalizeFiatAmount(validated.inputAmount));
50225
50426
  setParam(
50226
50427
  "paymentPlatform",
50227
- normalizeOptionalString(validated.paymentPlatform, "paymentPlatform")
50428
+ normalizeOptionalString2(validated.paymentPlatform, "paymentPlatform")
50228
50429
  );
50229
50430
  setParam("depositId", normalizeIntegerParam(validated.depositId, "depositId"));
50230
- setParam("toToken", normalizeOptionalString(validated.toToken, "toToken"));
50431
+ setParam("toToken", normalizeOptionalString2(validated.toToken, "toToken"));
50231
50432
  setParam("amountUsdc", normalizeUsdcAmount(validated.amountUsdc));
50232
50433
  setParam(
50233
50434
  "recipientAddress",
50234
- normalizeOptionalString(validated.recipientAddress, "recipientAddress")
50435
+ normalizeOptionalString2(validated.recipientAddress, "recipientAddress")
50235
50436
  );
50236
50437
  setParam("intentHash", normalizeIntentHash(validated.intentHash));
50237
50438
  return searchParams.toString();
@@ -50351,6 +50552,7 @@ exports.ZERO_RATE_MANAGER_ID = ZERO_RATE_MANAGER_ID;
50351
50552
  exports.ZKP2P_ANDROID_REFERRER = ZKP2P_ANDROID_REFERRER;
50352
50553
  exports.ZKP2P_IOS_REFERRER = ZKP2P_IOS_REFERRER;
50353
50554
  exports.Zkp2pClient = Zkp2pClient;
50555
+ exports.apiConfirmPayPalForwarding = apiConfirmPayPalForwarding;
50354
50556
  exports.apiCreateSellerCredentialBundle = apiCreateSellerCredentialBundle;
50355
50557
  exports.apiGetDepositBundle = apiGetDepositBundle;
50356
50558
  exports.apiGetOrderbook = apiGetOrderbook;
@@ -50359,6 +50561,7 @@ exports.apiGetPayeeDetails = apiGetPayeeDetails;
50359
50561
  exports.apiGetQuotesBestByPlatform = apiGetQuotesBestByPlatform;
50360
50562
  exports.apiGetTakerTier = apiGetTakerTier;
50361
50563
  exports.apiPostDepositDetails = apiPostDepositDetails;
50564
+ exports.apiUploadGoogleOAuthSellerCredential = apiUploadGoogleOAuthSellerCredential;
50362
50565
  exports.apiValidatePayeeDetails = apiValidatePayeeDetails;
50363
50566
  exports.appendAttributionToCalldata = appendAttributionToCalldata;
50364
50567
  exports.asciiToBytes32 = asciiToBytes32;
@@ -50369,6 +50572,7 @@ exports.convertDepositsForLiquidity = convertDepositsForLiquidity;
50369
50572
  exports.convertIndexerDepositToEscrowView = convertIndexerDepositToEscrowView;
50370
50573
  exports.convertIndexerIntentsToEscrowViews = convertIndexerIntentsToEscrowViews;
50371
50574
  exports.createCompositeDepositId = createCompositeDepositId;
50575
+ exports.createEncryptedBuyerTeeSessionMaterial = createEncryptedBuyerTeeSessionMaterial;
50372
50576
  exports.createPeerExtensionSdk = createPeerExtensionSdk;
50373
50577
  exports.defaultIndexerEndpoint = defaultIndexerEndpoint;
50374
50578
  exports.encodePythAdapterConfig = encodePythAdapterConfig;