@zkp2p/sdk 0.14.6 → 0.14.7-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.
@@ -1,4 +1,4 @@
1
1
  export { Currency, currencyInfo, getCurrencyCodeFromHash, getCurrencyInfoFromCountryCode, getCurrencyInfoFromHash, isSupportedCurrencyHash, mapConversionRatesToOnchain, mapConversionRatesToOnchainMinRate } from './chunk-WDEEWFEU.mjs';
2
- import './chunk-BBPE3X6U.mjs';
3
- //# sourceMappingURL=currency-OXHRXRZK.mjs.map
4
- //# sourceMappingURL=currency-OXHRXRZK.mjs.map
2
+ import './chunk-35IHGX4I.mjs';
3
+ //# sourceMappingURL=currency-5JVD64RX.mjs.map
4
+ //# sourceMappingURL=currency-5JVD64RX.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"currency-OXHRXRZK.mjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"currency-5JVD64RX.mjs"}
package/dist/index.cjs CHANGED
@@ -21,7 +21,7 @@ var __export = (target, all) => {
21
21
  var define_ZKP2P_SDK_BUILD_METADATA_default;
22
22
  var init_define_ZKP2P_SDK_BUILD_METADATA = __esm({
23
23
  "<define:__ZKP2P_SDK_BUILD_METADATA__>"() {
24
- define_ZKP2P_SDK_BUILD_METADATA_default = { schemaVersion: 2, source: { repository: "zkp2p/zkp2p-clients", commitSha: "fd02009b2fcfda2e4ee8decaa6bd572181ffdb4a", kind: "github", distributable: true }, sdkPackageVersion: "0.14.6", contractsPackageVersion: "0.4.4-rc.2", indexerSchemaPackageVersion: "0.22.0", activeDisputeStack: { base: { version: 2, selectionHash: "ba40c2954b408d0c658881a8d28e5bfcc9bade5cc3d953fd17eae1eca69d841c" }, baseStaging: { version: 2, selectionHash: "6c49c1ce51eec594a22385c4efcab08aa9926b6b63a725e14a0027ec5d2f4fc9" } } };
24
+ define_ZKP2P_SDK_BUILD_METADATA_default = { schemaVersion: 2, source: { repository: "zkp2p/zkp2p-clients", commitSha: "702186ed22ef1102f2827501e14f12172b5acf9b", kind: "github", distributable: true }, sdkPackageVersion: "0.14.7-rc.0", contractsPackageVersion: "0.4.4-rc.2", indexerSchemaPackageVersion: "0.22.0", activeDisputeStack: { base: { version: 2, selectionHash: "ba40c2954b408d0c658881a8d28e5bfcc9bade5cc3d953fd17eae1eca69d841c" }, baseStaging: { version: 2, selectionHash: "6c49c1ce51eec594a22385c4efcab08aa9926b6b63a725e14a0027ec5d2f4fc9" } } };
25
25
  }
26
26
  });
27
27
 
@@ -107181,7 +107181,7 @@ async function apiUpdateReferralCode(req, opts) {
107181
107181
  });
107182
107182
  return unwrapResponseObject(response);
107183
107183
  }
107184
- async function apiUploadSellerCredential(processorName, payeeDetails, bundle, baseApiUrl, timeoutMs, authorizationToken) {
107184
+ async function apiUploadSellerCredential(processorName, payeeDetails, bundle, baseApiUrl, timeoutMs, authorizationToken, retryCount) {
107185
107185
  const endpoint = `/v2/makers/${encodeURIComponent(processorName)}/${encodeURIComponent(
107186
107186
  payeeDetails
107187
107187
  )}/seller-credential`;
@@ -107190,7 +107190,8 @@ async function apiUploadSellerCredential(processorName, payeeDetails, bundle, ba
107190
107190
  method: "POST",
107191
107191
  body: bundle,
107192
107192
  timeoutMs,
107193
- authorizationToken
107193
+ authorizationToken,
107194
+ retryCount
107194
107195
  });
107195
107196
  }
107196
107197
  async function apiUploadGoogleOAuthSellerCredential(processorName, payeeDetails, body, baseApiUrl, opts) {
@@ -107261,6 +107262,15 @@ async function apiGetSellerCredentialStatus(processorName, payeeDetails, baseApi
107261
107262
  timeoutMs
107262
107263
  });
107263
107264
  }
107265
+ async function apiGetVenmoPayeeId(payeeDetails, baseApiUrl, timeoutMs) {
107266
+ return apiFetch({
107267
+ url: `${withApiBase(baseApiUrl)}/v2/makers/venmo/${encodeURIComponent(payeeDetails)}/payee-id`,
107268
+ method: "GET",
107269
+ timeoutMs,
107270
+ // Shares Curator's seller-credential limit with the upload; a 429 returns to the user.
107271
+ retryCount: 1
107272
+ });
107273
+ }
107264
107274
  async function apiVerifySellerPayment(platform, req, baseApiUrl, timeoutMs, apiKey) {
107265
107275
  const body = {
107266
107276
  txId: req.txId,
@@ -110858,6 +110868,240 @@ async function fetchFulfillmentAndPayment(client, intentHash) {
110858
110868
  // src/client/Zkp2pClient.ts
110859
110869
  init_contracts2();
110860
110870
 
110871
+ // src/icloudMail.ts
110872
+ init_define_ZKP2P_SDK_BUILD_METADATA();
110873
+ init_errors();
110874
+ var ICloudMailCredentialError = class extends Error {
110875
+ constructor(reason, message, options = {}) {
110876
+ super(message);
110877
+ this.reason = reason;
110878
+ this.name = "ICloudMailCredentialError";
110879
+ this.retryAfterMs = options.retryAfterMs;
110880
+ this.cause = options.cause;
110881
+ }
110882
+ };
110883
+ var MAILBOX_SELLER_CREDENTIAL_TYPES = /* @__PURE__ */ new Set([
110884
+ "google_oauth",
110885
+ "microsoft_oauth",
110886
+ "icloud_mail"
110887
+ ]);
110888
+ var isMailboxSellerCredentialType = (credentialType) => typeof credentialType === "string" && MAILBOX_SELLER_CREDENTIAL_TYPES.has(credentialType);
110889
+ var ATTESTOR_ENVIRONMENTS = {
110890
+ "attestation-service.zkp2p.xyz": "production",
110891
+ "attestation-service-staging.zkp2p.xyz": "staging"
110892
+ };
110893
+ var SELLER_CREDENTIAL_SIGNERS = {
110894
+ production: "0xe078d93bfdd87a8c5c5cca5905dcba0dd7a1f0bd",
110895
+ staging: "0x66649f896521b0fb487fe2077b4fbda283d7f19a"
110896
+ };
110897
+ var ATTESTOR_TIMEOUT_MS = 2e4;
110898
+ var DEFAULT_RETRY_AFTER_MS = 6e4;
110899
+ var mailboxesInFlight = /* @__PURE__ */ new Set();
110900
+ var mailboxRetryAt = /* @__PURE__ */ new Map();
110901
+ var asRecord = (value) => typeof value === "object" && value !== null ? value : null;
110902
+ function rateLimited(mailboxEmail, responseObject, cause) {
110903
+ const seconds = responseObject?.retryAfterSeconds;
110904
+ const retryAfterMs = typeof seconds === "string" && /^\d+$/.test(seconds) ? Number(seconds) * 1e3 : DEFAULT_RETRY_AFTER_MS;
110905
+ mailboxRetryAt.set(mailboxEmail, Date.now() + retryAfterMs);
110906
+ return new ICloudMailCredentialError("rate_limited", "iCloud Mail is rate limited", {
110907
+ retryAfterMs,
110908
+ cause
110909
+ });
110910
+ }
110911
+ function toAttestorError(error, platform, mailboxEmail) {
110912
+ if (!(error instanceof zkp2pAttestation.NitroAttestationError)) {
110913
+ return new ICloudMailCredentialError("unavailable", "iCloud Mail upload failed", {
110914
+ cause: error
110915
+ });
110916
+ }
110917
+ if (error.code === "TIMEOUT" || error.code === "ATTESTATION_FETCH_FAILED") {
110918
+ return new ICloudMailCredentialError("unavailable", error.message, { cause: error });
110919
+ }
110920
+ if (error.code !== "SERVICE_RESPONSE_ERROR") {
110921
+ return new ICloudMailCredentialError("bundle_unverified", error.message, {
110922
+ cause: error
110923
+ });
110924
+ }
110925
+ const status = error.details?.status;
110926
+ const responseObject = asRecord(error.details?.responseObject);
110927
+ if (status === 429) return rateLimited(mailboxEmail, responseObject, error);
110928
+ if (status === 400 && responseObject?.code === `${platform.toUpperCase()}_ICLOUD_RECEIPT_NOT_FOUND`) {
110929
+ return new ICloudMailCredentialError("receipt_not_found", error.message, {
110930
+ cause: error
110931
+ });
110932
+ }
110933
+ if (status === 410) {
110934
+ return new ICloudMailCredentialError("app_password_rejected", error.message, {
110935
+ cause: error
110936
+ });
110937
+ }
110938
+ return new ICloudMailCredentialError(
110939
+ typeof status === "number" && status >= 500 ? "unavailable" : "upload_rejected",
110940
+ error.message,
110941
+ { cause: error }
110942
+ );
110943
+ }
110944
+ var curatorResponseBody = (error) => asRecord(asRecord(error.details)?.responseBody);
110945
+ var VENMO_PAYEE_LOOKUP_ERRORS = /* @__PURE__ */ new Map([
110946
+ ["maker_not_found", "maker_not_found"],
110947
+ ["venmo_user_not_found", "payee_not_found"],
110948
+ ["venmo_account_id_mismatch", "payee_mismatch"]
110949
+ ]);
110950
+ function toVenmoPayeeLookupError(error, mailboxEmail) {
110951
+ if (error instanceof exports.APIError) {
110952
+ const responseBody = curatorResponseBody(error);
110953
+ const reason = VENMO_PAYEE_LOOKUP_ERRORS.get(responseBody?.errorCode);
110954
+ if (reason) return new ICloudMailCredentialError(reason, error.message, { cause: error });
110955
+ if (error.status === 429) {
110956
+ return rateLimited(mailboxEmail, asRecord(responseBody?.responseObject), error);
110957
+ }
110958
+ }
110959
+ return new ICloudMailCredentialError("unavailable", "Venmo account lookup failed", {
110960
+ cause: error
110961
+ });
110962
+ }
110963
+ function toCuratorError(error, mailboxEmail) {
110964
+ if (error instanceof exports.APIError) {
110965
+ if (error.status === 404) {
110966
+ return new ICloudMailCredentialError("maker_not_found", error.message, {
110967
+ cause: error
110968
+ });
110969
+ }
110970
+ if (error.status === 401 || error.status === 403) {
110971
+ return new ICloudMailCredentialError("auth_required", error.message, {
110972
+ cause: error
110973
+ });
110974
+ }
110975
+ if (error.status === 429) {
110976
+ const responseObject = asRecord(curatorResponseBody(error)?.responseObject);
110977
+ return rateLimited(mailboxEmail, responseObject, error);
110978
+ }
110979
+ }
110980
+ if (error instanceof exports.NetworkError) {
110981
+ return new ICloudMailCredentialError("unavailable", error.message, { cause: error });
110982
+ }
110983
+ return new ICloudMailCredentialError(
110984
+ "store_failed",
110985
+ "Curator did not store the iCloud credential",
110986
+ {
110987
+ cause: error
110988
+ }
110989
+ );
110990
+ }
110991
+ async function resolveVenmoPayeeId(payeeDetails, mailboxEmail, context) {
110992
+ let payeeId;
110993
+ try {
110994
+ const response = await apiGetVenmoPayeeId(payeeDetails, context.baseApiUrl, context.timeoutMs);
110995
+ payeeId = response.responseObject?.payeeId;
110996
+ } catch (error) {
110997
+ throw toVenmoPayeeLookupError(error, mailboxEmail);
110998
+ }
110999
+ if (typeof payeeId !== "string" || zkp2pAttestation.hashUtf8(payeeId) !== payeeDetails) {
111000
+ throw new ICloudMailCredentialError(
111001
+ "payee_mismatch",
111002
+ "Curator returned a Venmo account that does not match the registered maker"
111003
+ );
111004
+ }
111005
+ return payeeId;
111006
+ }
111007
+ function resolveAttestorEnvironment(attestationServiceUrl) {
111008
+ const environment = ATTESTOR_ENVIRONMENTS[new URL(attestationServiceUrl).hostname];
111009
+ if (!environment) {
111010
+ throw new Error(`Unsupported iCloud Mail attestor: ${attestationServiceUrl}`);
111011
+ }
111012
+ return environment;
111013
+ }
111014
+ async function uploadICloudMailSellerCredential(params, context) {
111015
+ const { appSpecificPassword, platform } = params;
111016
+ const mailboxEmail = params.mailboxEmail.trim().toLowerCase();
111017
+ if (!mailboxEmail) throw new exports.ValidationError("mailboxEmail is required", "mailboxEmail");
111018
+ if (!appSpecificPassword) {
111019
+ throw new exports.ValidationError("appSpecificPassword is required", "appSpecificPassword");
111020
+ }
111021
+ const payeeDetails = params.payeeDetails.toLowerCase();
111022
+ const payeeEmail = params.platform === "paypal" ? params.payeeEmail.trim().toLowerCase() : null;
111023
+ if (payeeEmail !== null && zkp2pAttestation.hashUtf8(payeeEmail) !== payeeDetails) {
111024
+ throw new ICloudMailCredentialError(
111025
+ "payee_mismatch",
111026
+ "The PayPal email does not match the registered maker"
111027
+ );
111028
+ }
111029
+ const retryAt = mailboxRetryAt.get(mailboxEmail);
111030
+ if (retryAt !== void 0 && retryAt > Date.now()) {
111031
+ throw new ICloudMailCredentialError("rate_limited", "iCloud Mail is rate limited", {
111032
+ retryAfterMs: retryAt - Date.now()
111033
+ });
111034
+ }
111035
+ if (mailboxesInFlight.has(mailboxEmail)) {
111036
+ throw new ICloudMailCredentialError("mailbox_busy", "This mailbox is already connecting");
111037
+ }
111038
+ const environment = resolveAttestorEnvironment(context.attestationServiceUrl);
111039
+ mailboxesInFlight.add(mailboxEmail);
111040
+ try {
111041
+ const payeeId = payeeEmail ?? await resolveVenmoPayeeId(payeeDetails, mailboxEmail, context);
111042
+ let bundle;
111043
+ try {
111044
+ const nitro = zkp2pAttestation.createNitroAttestationClient({
111045
+ environment,
111046
+ attestationServiceUrl: context.attestationServiceUrl,
111047
+ timeoutMs: ATTESTOR_TIMEOUT_MS,
111048
+ ...context.attestationRuntime
111049
+ });
111050
+ bundle = await nitro.uploadSellerCredential({
111051
+ platform,
111052
+ payeeId,
111053
+ sessionMaterial: { credentialSource: "icloud_mail", mailboxEmail, appSpecificPassword }
111054
+ });
111055
+ } catch (error) {
111056
+ throw toAttestorError(error, platform, mailboxEmail);
111057
+ }
111058
+ try {
111059
+ zkp2pAttestation.verifySellerCredentialBundle(bundle, {
111060
+ trustedSigners: [SELLER_CREDENTIAL_SIGNERS[environment]],
111061
+ expectedPlatform: platform,
111062
+ expectedPayeeIdHash: payeeDetails
111063
+ });
111064
+ } catch (error) {
111065
+ throw new ICloudMailCredentialError(
111066
+ "bundle_unverified",
111067
+ "Seller credential bundle failed verification",
111068
+ { cause: error }
111069
+ );
111070
+ }
111071
+ if (bundle.credentialType !== "icloud_mail") {
111072
+ throw new ICloudMailCredentialError(
111073
+ "bundle_unverified",
111074
+ `Attestor returned credential type ${bundle.credentialType}`
111075
+ );
111076
+ }
111077
+ let stored;
111078
+ try {
111079
+ const response = await apiUploadSellerCredential(
111080
+ platform,
111081
+ payeeDetails,
111082
+ bundle,
111083
+ context.baseApiUrl,
111084
+ context.timeoutMs,
111085
+ context.authorizationToken,
111086
+ // Send once: a 429 or lost response returns to the user, who retries.
111087
+ 1
111088
+ );
111089
+ stored = response.success ? response.responseObject : null;
111090
+ } catch (error) {
111091
+ throw toCuratorError(error, mailboxEmail);
111092
+ }
111093
+ if (stored?.status !== "active" || stored.credentialType !== "icloud_mail" || stored.platform !== platform || stored.payeeIdHash.toLowerCase() !== payeeDetails) {
111094
+ throw new ICloudMailCredentialError(
111095
+ "store_failed",
111096
+ "Curator did not store an active iCloud credential"
111097
+ );
111098
+ }
111099
+ return stored;
111100
+ } finally {
111101
+ mailboxesInFlight.delete(mailboxEmail);
111102
+ }
111103
+ }
111104
+
110861
111105
  // src/sellerCredentials.ts
110862
111106
  init_define_ZKP2P_SDK_BUILD_METADATA();
110863
111107
  function normalizeBaseApiUrl(value) {
@@ -114152,6 +114396,32 @@ var Zkp2pClient = class {
114152
114396
  uploadOptions
114153
114397
  );
114154
114398
  }
114399
+ /**
114400
+ * Connect an iCloud Mail receipt inbox for PayPal or Venmo seller automated
114401
+ * release. The app-specific password is encrypted to the attested enclave and
114402
+ * posted directly to the attestor (no proxy, no retry). The returned bundle is
114403
+ * verified against the pinned enclave signer, platform and registered maker,
114404
+ * then stored unchanged for that maker; the maker is not re-registered.
114405
+ *
114406
+ * Rejects with `ICloudMailCredentialError` (`reason` names the failure)
114407
+ * before any mailbox work when `payeeId` does not hash to `payeeDetails`,
114408
+ * while another connection for the mailbox runs, or during a rate-limit
114409
+ * delay. The attestor defaults to the one paired with `baseApiUrl`.
114410
+ */
114411
+ async uploadICloudMailSellerCredential(params, opts) {
114412
+ const baseApiUrl = this.stripTrailingSlash(
114413
+ opts?.baseApiUrl ?? this.baseApiUrl ?? DEFAULT_BASE_API_URL
114414
+ );
114415
+ return uploadICloudMailSellerCredential(params, {
114416
+ attestationServiceUrl: this.stripTrailingSlash(
114417
+ opts?.attestationServiceUrl ?? this.defaultAttestationServiceForBaseApiUrl(baseApiUrl)
114418
+ ),
114419
+ attestationRuntime: opts?.attestationRuntime,
114420
+ baseApiUrl,
114421
+ timeoutMs: this.apiTimeoutMs,
114422
+ authorizationToken: await this.resolveAuthorizationToken()
114423
+ });
114424
+ }
114155
114425
  /**
114156
114426
  * Status is a coarse curator-owned signal (`active` / `inactive` / `missing`) and intentionally
114157
114427
  * omits low-level diagnostics. Curator may still re-probe stale credentials during verify, so callers
@@ -114640,6 +114910,7 @@ exports.CHAINLINK_ORACLE_ADAPTER = CHAINLINK_ORACLE_ADAPTER;
114640
114910
  exports.CHAINLINK_ORACLE_FEEDS = CHAINLINK_ORACLE_FEEDS;
114641
114911
  exports.ContractRouter = ContractRouter;
114642
114912
  exports.DEFAULT_ORACLE_MAX_STALENESS_SECONDS = DEFAULT_ORACLE_MAX_STALENESS_SECONDS;
114913
+ exports.ICloudMailCredentialError = ICloudMailCredentialError;
114643
114914
  exports.IndexerClient = IndexerClient;
114644
114915
  exports.IndexerDepositService = IndexerDepositService;
114645
114916
  exports.IndexerRateManagerService = IndexerRateManagerService;
@@ -114727,6 +114998,7 @@ exports.getSpreadOracleConfig = getSpreadOracleConfig;
114727
114998
  exports.getStakeVaultContract = getStakeVaultContract;
114728
114999
  exports.getVenmoGmailConnectUrl = getVenmoGmailConnectUrl;
114729
115000
  exports.hasIntentGuardian = hasIntentGuardian;
115001
+ exports.isMailboxSellerCredentialType = isMailboxSellerCredentialType;
114730
115002
  exports.isPeerExtensionAvailable = isPeerExtensionAvailable;
114731
115003
  exports.isSupportedCurrencyHash = isSupportedCurrencyHash;
114732
115004
  exports.isValidReferralCode = isValidReferralCode;