@zkp2p/sdk 0.6.2 → 0.7.1

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 CHANGED
@@ -211,7 +211,7 @@ const payeeHash = await client.resolvePayeeHash(
211
211
  );
212
212
  ```
213
213
 
214
- `getQuote()` returns available liquidity plus payee details when authenticated. Use `getQuotesBestByPlatform()` to fetch the best quote per supported payment platform in a single call (handy for cross-platform comparison UIs). `getTakerTier()` returns limits and cooldown data for taker UX.
214
+ `getQuote()` returns available liquidity plus payee details when authenticated. Use `getQuotesBestByPlatform()` to fetch the best quote per supported payment platform in a single call (handy for cross-platform comparison UIs). `getTakerTier()` returns limits, cooldown data, Peer Pay volume progression, and `volumeBreakdown` rows for taker UX.
215
215
 
216
216
  ## Seller Credential Status
217
217
 
@@ -270,6 +270,29 @@ await client.releaseFundsToPayer({
270
270
 
271
271
  Use `referralFees[]` for multi-recipient fee distribution on OrchestratorV2.
272
272
 
273
+ ## Referral Account API
274
+
275
+ Authenticated apps can manage Peer referral accounts through the SDK. Configure
276
+ `authorizationToken` or `getAuthorizationToken` on `Zkp2pClient`, or pass an
277
+ override per call.
278
+
279
+ ```ts
280
+ const dashboard = await client.getReferralDashboard();
281
+ // { code, l1FeeBps, l2FeeBps, l1RefereeCount, ... }
282
+
283
+ await client.redeemReferralCode('PEER42');
284
+
285
+ await client.updateReferralCode('MYCODE');
286
+
287
+ const earnings = await client.getReferralEarnings();
288
+ // { totalWei, l1Wei, l2Wei, unattributedWei, ... }
289
+ ```
290
+
291
+ The dashboard call returns the authenticated user's generated referral code.
292
+ `redeemReferralCode()` applies another user's code to the authenticated account;
293
+ `updateReferralCode()` customizes the authenticated user's own code. Codes are
294
+ normalized to uppercase before being sent to curator.
295
+
273
296
  ## Prepared Transactions
274
297
 
275
298
  Most write methods expose `.prepare(params)` and return a `PreparedTransaction` without sending the transaction. `createDeposit()` is the main exception and uses `client.prepareCreateDeposit(params)`, which returns `{ depositDetails, prepared }`. This is the stable pattern for smart accounts, batched user-ops, relayers, gas estimation, and custom senders.
@@ -108,5 +108,5 @@ var prepareSetDelegationTx = async (client, params, referrer) => {
108
108
  };
109
109
 
110
110
  export { TAKER_TIER_CAPS, TAKER_TIER_FEE_DISCOUNT_BPS, TAKER_TIER_ORDER, TAKER_TIER_SCHEDULE, ZERO_ADDRESS, ZERO_RATE_MANAGER_ID, asErrorMessage, assertAtomicDelegationSwitchSupport, assertDelegationMethodSupport, classifyDelegationState, getDelegationRoute, getNextTakerTier, getTakerTierFeeDiscountBps, isZeroRateManagerId, normalizeRateManagerId, normalizeRegistry, prepareClearDelegationTx, prepareSetDelegationTx };
111
- //# sourceMappingURL=chunk-6WAMIVRB.mjs.map
112
- //# sourceMappingURL=chunk-6WAMIVRB.mjs.map
111
+ //# sourceMappingURL=chunk-BQINCOSO.mjs.map
112
+ //# sourceMappingURL=chunk-BQINCOSO.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/takerTiers.ts","../src/react/hooks/vaultUtils.ts"],"names":[],"mappings":"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","file":"chunk-BQINCOSO.mjs","sourcesContent":["import type { TakerTierLevel } from './types';\n\n/**\n * Canonical taker tier schedule — the single client-side source of truth for\n * per-intent caps and volume thresholds. Mirrors the curator's authoritative\n * tier engine (curator `src/common/services/tier/tierConstants.ts`), which is\n * what the backend actually enforces.\n *\n * The live qualification signal is Peer Pay volume. Historical maker tiers\n * earned before July 1, 2026 UTC are preserved; after that cutoff, only Peer\n * Pay volume moves the tier. Curator keeps the response field name\n * `peerPayVolume` for compatibility.\n *\n * A user's *live* tier, cap, and progression always come from the taker-tier\n * API payload (`TakerTier.perIntentCapBaseUnits`, `minVolumeForTier`,\n * `volumeToNextTier`, `peerPayVolume`). Those values are DB-backed and\n * server-authoritative — they vary per environment (e.g. preprod runs\n * different thresholds than these). This static schedule is ONLY a\n * documented-default reference for displays that must show every tier at once\n * (the Fees & Tiers ladder) when no live payload is available; never gate or\n * compute a user's real cap from it.\n *\n * Volume bands track the live tuned qualification thresholds — PEER $1k,\n * PLUS $10k, PRO $50k, PLATINUM $100k. Caps ($100/$250/$1k/$2.5k/$5k) are unchanged.\n * Read the live per-user values from the API: curator can change qualification\n * inputs behind the compatibility fields without changing this reference table.\n *\n * Ordered highest tier → lowest (PLATINUM first) to match UI display order.\n * PEER_PRESIDENT is invite-only and excluded from the volume ladder.\n */\nexport interface TakerTierScheduleEntry {\n tier: TakerTierLevel;\n /** Per-intent order cap in whole USD (base, before platform risk multipliers). */\n perIntentCapUsd: number;\n /** Inclusive lower bound of Peer Pay volume (USD) that qualifies for this tier. */\n minVolumeUsd: number;\n /** Inclusive upper bound of Peer Pay volume (USD); `Infinity` for the top tier. */\n maxVolumeUsd: number;\n}\n\nexport const TAKER_TIER_SCHEDULE: readonly TakerTierScheduleEntry[] = [\n { tier: 'PLATINUM', perIntentCapUsd: 5000, minVolumeUsd: 100000, maxVolumeUsd: Infinity },\n { tier: 'PRO', perIntentCapUsd: 2500, minVolumeUsd: 50000, maxVolumeUsd: 99999 },\n { tier: 'PLUS', perIntentCapUsd: 1000, minVolumeUsd: 10000, maxVolumeUsd: 49999 },\n { tier: 'PEER', perIntentCapUsd: 250, minVolumeUsd: 1000, maxVolumeUsd: 9999 },\n { tier: 'PEASANT', perIntentCapUsd: 100, minVolumeUsd: 0, maxVolumeUsd: 999 },\n];\n\n/** Volume-based tier order, lowest → highest, for next-tier progression. */\nexport const TAKER_TIER_ORDER: readonly TakerTierLevel[] = [\n 'PEASANT',\n 'PEER',\n 'PLUS',\n 'PRO',\n 'PLATINUM',\n];\n\n/** Per-intent caps (whole USD) keyed by tier, derived from the schedule. */\nexport const TAKER_TIER_CAPS: Readonly<Record<string, number>> = Object.fromEntries(\n TAKER_TIER_SCHEDULE.map((entry) => [entry.tier, entry.perIntentCapUsd]),\n);\n\n/**\n * Default take-fee discount (in basis points) applied per tier, mirroring\n * curator `TIER_FEE_DISCOUNT_BPS`. The discount is subtracted from the base\n * service fee server-side at quote and sign time — it is NOT returned by the\n * tier endpoint. These are documented defaults for reference fee displays only;\n * the curator DB control-plane can override them, so prefer the fee shown on a\n * live quote when one is available.\n */\nexport const TAKER_TIER_FEE_DISCOUNT_BPS: Readonly<Record<TakerTierLevel, number>> = {\n PEASANT: 0,\n PEER: 5,\n PLUS: 10,\n PRO: 20,\n PLATINUM: 30,\n PEER_PRESIDENT: 30,\n};\n\n/** The default fee-discount (bps) for a tier, or 0 for unknown tiers. */\nexport function getTakerTierFeeDiscountBps(tier: string | undefined): number {\n if (!tier) return 0;\n return TAKER_TIER_FEE_DISCOUNT_BPS[tier as TakerTierLevel] ?? 0;\n}\n\n/** The next tier up from `currentTier`, or `null` at the top / for unknown tiers. */\nexport function getNextTakerTier(currentTier: string | undefined): TakerTierLevel | null {\n if (!currentTier) return null;\n const index = TAKER_TIER_ORDER.indexOf(currentTier as TakerTierLevel);\n if (index === -1 || index >= TAKER_TIER_ORDER.length - 1) return null;\n return TAKER_TIER_ORDER[index + 1];\n}\n","import type { Address, Hex } from 'viem';\nimport type { PreparedTransaction } from '../../types/prepared';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nexport const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' as const;\nexport const ZERO_RATE_MANAGER_ID =\n '0x0000000000000000000000000000000000000000000000000000000000000000' as const;\n\n// ---------------------------------------------------------------------------\n// Normalizers\n// ---------------------------------------------------------------------------\n\nexport const normalizeRateManagerId = (value?: string | null): string =>\n (value ?? ZERO_RATE_MANAGER_ID).toLowerCase();\n\nexport const normalizeRegistry = (value?: string | null): string =>\n (value ?? ZERO_ADDRESS).toLowerCase();\n\nexport const isZeroRateManagerId = (value?: string | null): boolean => {\n if (!value) return true;\n const normalized = value.toLowerCase();\n return normalized === ZERO_ADDRESS || normalized === ZERO_RATE_MANAGER_ID;\n};\n\n// ---------------------------------------------------------------------------\n// Error helper\n// ---------------------------------------------------------------------------\n\nexport const asErrorMessage = (error: unknown): string => {\n if (!error) return 'Unknown error';\n if (error instanceof Error) return error.message;\n if (typeof error === 'string') return error;\n\n const anyErr = error as Record<string, unknown>;\n if (typeof anyErr.shortMessage === 'string') return anyErr.shortMessage;\n if (typeof anyErr.details === 'string') return anyErr.details;\n if (typeof anyErr.message === 'string') return anyErr.message;\n\n try {\n return JSON.stringify(error);\n } catch {\n return String(error);\n }\n};\n\n// ---------------------------------------------------------------------------\n// Delegation state classification\n// ---------------------------------------------------------------------------\n\nexport type DelegationState = 'delegated_here' | 'delegated_elsewhere' | 'not_delegated';\n\n/**\n * Classify whether a deposit is delegated to the target vault, delegated\n * elsewhere, or not delegated at all.\n *\n * @param currentRateManagerId The deposit's current rateManagerId (from indexer)\n * @param currentRegistry The deposit's current rateManagerAddress / registry (from indexer)\n * @param targetRateManagerId The vault's rateManagerId we're comparing against\n * @param targetRegistry The vault's registry address we're comparing against\n */\nexport const classifyDelegationState = (\n currentRateManagerId: string | null | undefined,\n currentRegistry: string | null | undefined,\n targetRateManagerId: string,\n targetRegistry: string | null | undefined,\n): DelegationState => {\n if (isZeroRateManagerId(currentRateManagerId)) {\n return 'not_delegated';\n }\n\n const normalizedCurrent = normalizeRateManagerId(currentRateManagerId);\n const normalizedTarget = targetRateManagerId.toLowerCase();\n const normalizedCurrentRegistry = normalizeRegistry(currentRegistry);\n const normalizedTargetRegistry = targetRegistry ? targetRegistry.toLowerCase() : '';\n\n const idsMatch = normalizedCurrent === normalizedTarget;\n const registryMatches = normalizedTargetRegistry\n ? normalizedCurrentRegistry === normalizedTargetRegistry\n : true;\n\n if (idsMatch && registryMatches) {\n return 'delegated_here';\n }\n\n return 'delegated_elsewhere';\n};\n\nexport const assertAtomicDelegationSwitchSupport = (\n requiresSwitch: boolean,\n canBatch: boolean,\n): void => {\n if (!requiresSwitch || canBatch) return;\n throw new Error(\n 'Switching delegation targets requires smart-account batching. Clear the existing delegation first.',\n );\n};\n\n// ---------------------------------------------------------------------------\n// Contract routing\n// ---------------------------------------------------------------------------\n\nexport type DelegationRoute = 'v2';\n\nexport const getDelegationRoute = (_client: unknown, _escrow: Address): DelegationRoute => 'v2';\n\ntype DelegationMethodSupportClient = Partial<\n Record<'setRateManager' | 'clearRateManager', { prepare?: unknown }>\n>;\n\nexport const assertDelegationMethodSupport = (\n client: DelegationMethodSupportClient,\n _route: DelegationRoute,\n action: 'set' | 'clear',\n): void => {\n const method = action === 'set' ? 'setRateManager' : 'clearRateManager';\n if (client?.[method]?.prepare) return;\n throw new Error(`Delegation requires SDK ${method} support`);\n};\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface DelegationDepositTarget {\n compositeDepositId: string;\n escrow: Address;\n depositId: bigint;\n currentRateManagerId?: string | null;\n currentRateManagerRegistry?: string | null;\n}\n\nexport interface BatchResult {\n hashes: string[];\n failed: Array<{ compositeDepositId: string; error: string }>;\n}\n\n/**\n * Callback the consumer provides for sending a single prepared transaction.\n * Returns the transaction hash.\n */\nexport type SendTransactionFn = (tx: { to: Address; data: Hex; value?: bigint }) => Promise<string>;\n\n/**\n * Optional callback for batching multiple calls in a single user operation\n * (e.g. via a smart account). If not provided, transactions are sent\n * sequentially via sendTransaction.\n */\nexport type SendBatchFn = (\n txs: Array<{ to: Address; data: Hex; value?: bigint }>,\n) => Promise<string>;\n\n// ---------------------------------------------------------------------------\n// Prepare helpers (used internally by hooks)\n// ---------------------------------------------------------------------------\n\nexport const prepareClearDelegationTx = async (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n client: any,\n params: { escrow: Address; depositId: bigint },\n referrer?: string | string[],\n): Promise<PreparedTransaction> => {\n const route = getDelegationRoute(client, params.escrow);\n assertDelegationMethodSupport(client, route, 'clear');\n return client.clearRateManager.prepare({\n escrowAddress: params.escrow,\n depositId: params.depositId,\n ...(referrer ? { txOverrides: { referrer } } : {}),\n });\n};\n\nexport const prepareSetDelegationTx = async (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n client: any,\n params: {\n escrow: Address;\n depositId: bigint;\n registry: Address;\n rateManagerId: Hex;\n },\n referrer?: string | string[],\n): Promise<PreparedTransaction> => {\n const route = getDelegationRoute(client, params.escrow);\n assertDelegationMethodSupport(client, route, 'set');\n return client.setRateManager.prepare({\n escrowAddress: params.escrow,\n depositId: params.depositId,\n rateManagerAddress: params.registry,\n rateManagerId: params.rateManagerId,\n ...(referrer ? { txOverrides: { referrer } } : {}),\n });\n};\n"]}
package/dist/index.cjs CHANGED
@@ -47157,10 +47157,17 @@ var logger = {
47157
47157
  }
47158
47158
  };
47159
47159
 
47160
+ // src/referral.ts
47161
+ var normalizeReferralCode = (code) => code.trim().toUpperCase();
47162
+ var isValidReferralCode = (code) => /^[A-Z0-9]{6}$/.test(normalizeReferralCode(code));
47163
+
47160
47164
  // src/adapters/api.ts
47161
- function createHeaders(apiKey) {
47165
+ function createHeaders(apiKey, authorizationToken) {
47162
47166
  const headers2 = { "Content-Type": "application/json" };
47163
47167
  if (apiKey) headers2["x-api-key"] = apiKey;
47168
+ if (authorizationToken) {
47169
+ headers2.Authorization = authorizationToken.startsWith("Bearer ") ? authorizationToken : `Bearer ${authorizationToken}`;
47170
+ }
47164
47171
  return headers2;
47165
47172
  }
47166
47173
  function withApiBase(baseApiUrl) {
@@ -47175,6 +47182,7 @@ async function apiFetch({
47175
47182
  method = "GET",
47176
47183
  body,
47177
47184
  apiKey,
47185
+ authorizationToken,
47178
47186
  timeoutMs,
47179
47187
  retryCount = 3,
47180
47188
  retryDelayMs = 1e3
@@ -47186,7 +47194,7 @@ async function apiFetch({
47186
47194
  try {
47187
47195
  const options = {
47188
47196
  method,
47189
- headers: createHeaders(apiKey)
47197
+ headers: createHeaders(apiKey, authorizationToken)
47190
47198
  };
47191
47199
  if (body && method !== "GET") {
47192
47200
  options.body = JSON.stringify(body);
@@ -47206,6 +47214,18 @@ async function apiFetch({
47206
47214
  timeoutMs
47207
47215
  );
47208
47216
  }
47217
+ function unwrapResponseObject(payload) {
47218
+ if (payload && typeof payload === "object" && "responseObject" in payload) {
47219
+ return payload.responseObject;
47220
+ }
47221
+ return payload;
47222
+ }
47223
+ function requireAuthorizationToken(authorizationToken, endpoint) {
47224
+ if (!authorizationToken) {
47225
+ throw new exports.ValidationError(`authorizationToken is required for ${endpoint}`, "authorizationToken");
47226
+ }
47227
+ return authorizationToken;
47228
+ }
47209
47229
  function requireEscrowAddress(escrowAddress, endpoint) {
47210
47230
  if (!escrowAddress) {
47211
47231
  throw new exports.ValidationError(`escrowAddress is required for ${endpoint}`, "escrowAddress");
@@ -47459,6 +47479,52 @@ async function apiGetTakerTier(req, baseApiUrl, timeoutMs) {
47459
47479
  timeoutMs
47460
47480
  });
47461
47481
  }
47482
+ async function apiGetReferralDashboard(opts) {
47483
+ const endpoint = "/v2/referral";
47484
+ const authorizationToken = requireAuthorizationToken(opts.authorizationToken, endpoint);
47485
+ const response = await apiFetch({
47486
+ url: `${withApiBase(opts.baseApiUrl)}${endpoint}`,
47487
+ method: "GET",
47488
+ authorizationToken,
47489
+ timeoutMs: opts.timeoutMs
47490
+ });
47491
+ return unwrapResponseObject(response);
47492
+ }
47493
+ async function apiGetReferralEarnings(opts) {
47494
+ const endpoint = "/v2/referral/earnings";
47495
+ const authorizationToken = requireAuthorizationToken(opts.authorizationToken, endpoint);
47496
+ const response = await apiFetch({
47497
+ url: `${withApiBase(opts.baseApiUrl)}${endpoint}`,
47498
+ method: "GET",
47499
+ authorizationToken,
47500
+ timeoutMs: opts.timeoutMs
47501
+ });
47502
+ return unwrapResponseObject(response);
47503
+ }
47504
+ async function apiRedeemReferralCode(req, opts) {
47505
+ const endpoint = "/v2/referral/redeem";
47506
+ const authorizationToken = requireAuthorizationToken(opts.authorizationToken, endpoint);
47507
+ const response = await apiFetch({
47508
+ url: `${withApiBase(opts.baseApiUrl)}${endpoint}`,
47509
+ method: "POST",
47510
+ body: { code: normalizeReferralCode(req.code) },
47511
+ authorizationToken,
47512
+ timeoutMs: opts.timeoutMs
47513
+ });
47514
+ return unwrapResponseObject(response);
47515
+ }
47516
+ async function apiUpdateReferralCode(req, opts) {
47517
+ const endpoint = "/v2/referral/code";
47518
+ const authorizationToken = requireAuthorizationToken(opts.authorizationToken, endpoint);
47519
+ const response = await apiFetch({
47520
+ url: `${withApiBase(opts.baseApiUrl)}${endpoint}`,
47521
+ method: "PATCH",
47522
+ body: { code: normalizeReferralCode(req.code) },
47523
+ authorizationToken,
47524
+ timeoutMs: opts.timeoutMs
47525
+ });
47526
+ return unwrapResponseObject(response);
47527
+ }
47462
47528
  async function apiUploadSellerCredential(processorName, payeeDetails, bundle, baseApiUrl, timeoutMs) {
47463
47529
  const endpoint = `/v2/makers/${encodeURIComponent(processorName)}/${encodeURIComponent(
47464
47530
  payeeDetails
@@ -47719,6 +47785,9 @@ var appendReferrerFeeDisplayFieldsToBestByPlatform = (quoteResponse, referrerFee
47719
47785
  };
47720
47786
  };
47721
47787
 
47788
+ // src/client/Zkp2pClient.ts
47789
+ init_errors();
47790
+
47722
47791
  // src/utils/erc20.ts
47723
47792
  var ERC20_ABI = [
47724
47793
  {
@@ -48770,6 +48839,7 @@ var Zkp2pClient = class {
48770
48839
  this.baseApiUrl = opts.baseApiUrl;
48771
48840
  this.apiKey = opts.apiKey;
48772
48841
  this.authorizationToken = opts.authorizationToken;
48842
+ this.getAuthorizationToken = opts.getAuthorizationToken;
48773
48843
  this.apiTimeoutMs = opts.timeouts?.api ?? 15e3;
48774
48844
  this._pvReader = new ProtocolViewerReader({
48775
48845
  getPublicClient: () => this.publicClient,
@@ -48865,6 +48935,16 @@ var Zkp2pClient = class {
48865
48935
  `attestationServiceUrl is required when baseApiUrl is not a supported zkp2p API host: ${baseApiUrl}`
48866
48936
  );
48867
48937
  }
48938
+ async resolveAuthorizationToken(opts) {
48939
+ if (opts?.authorizationToken !== void 0) {
48940
+ return opts.authorizationToken;
48941
+ }
48942
+ const provider = opts?.getAuthorizationToken ?? this.getAuthorizationToken;
48943
+ if (provider) {
48944
+ return await provider() ?? void 0;
48945
+ }
48946
+ return this.authorizationToken;
48947
+ }
48868
48948
  normalizeOracleRateConfig(config) {
48869
48949
  return normalizeOracleRateConfig(config);
48870
48950
  }
@@ -50149,6 +50229,51 @@ var Zkp2pClient = class {
50149
50229
  const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
50150
50230
  return apiGetTakerTier(req, baseApiUrl, timeoutMs);
50151
50231
  }
50232
+ /**
50233
+ * Fetch the authenticated user's referral dashboard, including their generated
50234
+ * code, reward rates, referee counts, and lifetime referral fees.
50235
+ */
50236
+ async getReferralDashboard(opts) {
50237
+ const baseApiUrl = this.stripTrailingSlash(
50238
+ opts?.baseApiUrl ?? this.baseApiUrl ?? DEFAULT_BASE_API_URL
50239
+ );
50240
+ const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
50241
+ const authorizationToken = await this.resolveAuthorizationToken(opts);
50242
+ return apiGetReferralDashboard({ baseApiUrl, timeoutMs, authorizationToken });
50243
+ }
50244
+ /**
50245
+ * Fetch the authenticated user's referral earnings totals.
50246
+ */
50247
+ async getReferralEarnings(opts) {
50248
+ const baseApiUrl = this.stripTrailingSlash(
50249
+ opts?.baseApiUrl ?? this.baseApiUrl ?? DEFAULT_BASE_API_URL
50250
+ );
50251
+ const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
50252
+ const authorizationToken = await this.resolveAuthorizationToken(opts);
50253
+ return apiGetReferralEarnings({ baseApiUrl, timeoutMs, authorizationToken });
50254
+ }
50255
+ /**
50256
+ * Apply another user's referral code to the authenticated account.
50257
+ */
50258
+ async redeemReferralCode(code, opts) {
50259
+ const baseApiUrl = this.stripTrailingSlash(
50260
+ opts?.baseApiUrl ?? this.baseApiUrl ?? DEFAULT_BASE_API_URL
50261
+ );
50262
+ const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
50263
+ const authorizationToken = await this.resolveAuthorizationToken(opts);
50264
+ return apiRedeemReferralCode({ code }, { baseApiUrl, timeoutMs, authorizationToken });
50265
+ }
50266
+ /**
50267
+ * Customize the authenticated user's own referral code.
50268
+ */
50269
+ async updateReferralCode(code, opts) {
50270
+ const baseApiUrl = this.stripTrailingSlash(
50271
+ opts?.baseApiUrl ?? this.baseApiUrl ?? DEFAULT_BASE_API_URL
50272
+ );
50273
+ const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
50274
+ const authorizationToken = await this.resolveAuthorizationToken(opts);
50275
+ return apiUpdateReferralCode({ code }, { baseApiUrl, timeoutMs, authorizationToken });
50276
+ }
50152
50277
  /**
50153
50278
  * The signed `credentialValidatedAt` field is an upload-time freshness witness minted by
50154
50279
  * attestation-service. `credentialExpiresAt` carries an upstream session expiry hint when one
@@ -50277,12 +50402,12 @@ var Zkp2pClient = class {
50277
50402
  }
50278
50403
  );
50279
50404
  }
50280
- if (params.platform === "zelle") {
50405
+ if (params.platform === "venmo") {
50281
50406
  return apiUploadGoogleOAuthSellerCredential(
50282
- "zelle",
50407
+ "venmo",
50283
50408
  params.payeeDetails,
50284
50409
  {
50285
- payeeId: params.payeeId,
50410
+ accountId: params.accountId,
50286
50411
  authorizationCode: params.authorizationCode,
50287
50412
  redirectUri: params.redirectUri
50288
50413
  },
@@ -50292,18 +50417,9 @@ var Zkp2pClient = class {
50292
50417
  }
50293
50418
  );
50294
50419
  }
50295
- return apiUploadGoogleOAuthSellerCredential(
50296
- "venmo",
50297
- params.payeeDetails,
50298
- {
50299
- accountId: params.accountId,
50300
- authorizationCode: params.authorizationCode,
50301
- redirectUri: params.redirectUri
50302
- },
50303
- baseApiUrl,
50304
- {
50305
- timeoutMs
50306
- }
50420
+ throw new exports.ValidationError(
50421
+ `Unsupported Google OAuth seller credential platform: ${String(params.platform)}`,
50422
+ "platform"
50307
50423
  );
50308
50424
  }
50309
50425
  /**
@@ -50652,9 +50768,13 @@ exports.apiGetOrderbook = apiGetOrderbook;
50652
50768
  exports.apiGetOwnerDeposits = apiGetOwnerDeposits;
50653
50769
  exports.apiGetPayeeDetails = apiGetPayeeDetails;
50654
50770
  exports.apiGetQuotesBestByPlatform = apiGetQuotesBestByPlatform;
50771
+ exports.apiGetReferralDashboard = apiGetReferralDashboard;
50772
+ exports.apiGetReferralEarnings = apiGetReferralEarnings;
50655
50773
  exports.apiGetTakerTier = apiGetTakerTier;
50656
50774
  exports.apiPostDepositDetails = apiPostDepositDetails;
50775
+ exports.apiRedeemReferralCode = apiRedeemReferralCode;
50657
50776
  exports.apiRequestIdentityAttestation = apiRequestIdentityAttestation;
50777
+ exports.apiUpdateReferralCode = apiUpdateReferralCode;
50658
50778
  exports.apiUploadGoogleOAuthSellerCredential = apiUploadGoogleOAuthSellerCredential;
50659
50779
  exports.apiUploadSellerCredentialBundle = apiUploadSellerCredentialBundle;
50660
50780
  exports.apiValidatePayeeDetails = apiValidatePayeeDetails;
@@ -50693,12 +50813,14 @@ exports.getSpreadOracleConfig = getSpreadOracleConfig;
50693
50813
  exports.getTakerTierFeeDiscountBps = getTakerTierFeeDiscountBps;
50694
50814
  exports.isPeerExtensionAvailable = isPeerExtensionAvailable;
50695
50815
  exports.isSupportedCurrencyHash = isSupportedCurrencyHash;
50816
+ exports.isValidReferralCode = isValidReferralCode;
50696
50817
  exports.isValidReferrerFeeBps = isValidReferrerFeeBps;
50697
50818
  exports.isValidReferrerFeeRecipient = isValidReferrerFeeRecipient;
50698
50819
  exports.isZeroRateManagerId = isZeroRateManagerId;
50699
50820
  exports.logger = logger;
50700
50821
  exports.mapConversionRatesToOnchainMinRate = mapConversionRatesToOnchainMinRate;
50701
50822
  exports.normalizeRateManagerId = normalizeRateManagerId2;
50823
+ exports.normalizeReferralCode = normalizeReferralCode;
50702
50824
  exports.normalizeRegistry = normalizeRegistry;
50703
50825
  exports.openPeerExtensionInstallPage = openPeerExtensionInstallPage;
50704
50826
  exports.parseDepositView = parseDepositView;