@usdctofiat/offramp 4.3.0 → 4.4.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,6 +1,7 @@
1
1
  import { PeerMetadataMessage, CuratorSellerCredentialUploadResponse, PeerAuthenticateParams, currencyInfo } from '@zkp2p/sdk';
2
2
 
3
- type PlatformId = "venmo" | "cashapp" | "chime" | "revolut" | "wise" | "mercadopago" | "zelle" | "paypal" | "monzo" | "n26" | "luxon";
3
+ type PlatformId = "venmo" | "cashapp" | "chime" | "revolut" | "wise" | "mercadopago" | "zelle" | "paypal" | "monzo";
4
+ type SellerCredentialProcessor = "paypal" | "wise" | "venmo" | "cashapp";
4
5
  /**
5
6
  * Extension pre-registration requirement for a platform. When present,
6
7
  * curator's `/v2/makers/create` rejects the maker until the user has
@@ -39,13 +40,6 @@ interface PlatformEntry {
39
40
  * upstream zkp2p-clients normalizer so our offchainId hashes identically.
40
41
  */
41
42
  declare function normalizePaypalMeUsername(value: string): string;
42
- /**
43
- * Validates an IBAN using the MOD-97 algorithm (ISO 13616), mirroring
44
- * curator's N26 processor so a malformed-but-well-formed IBAN is rejected
45
- * client-side before the maker approves USDC + pays gas. Expects no spaces
46
- * (the n26 transform strips them and uppercases first).
47
- */
48
- declare function isValidIBAN(iban: string): boolean;
49
43
  /** All supported payment platforms. Access via `PLATFORMS.REVOLUT`, `PLATFORMS.WISE`, etc. */
50
44
  declare const PLATFORMS: {
51
45
  readonly VENMO: PlatformEntry;
@@ -57,8 +51,6 @@ declare const PLATFORMS: {
57
51
  readonly ZELLE: PlatformEntry;
58
52
  readonly PAYPAL: PlatformEntry;
59
53
  readonly MONZO: PlatformEntry;
60
- readonly N26: PlatformEntry;
61
- readonly LUXON: PlatformEntry;
62
54
  };
63
55
  /** Platform key type for PLATFORMS constant. */
64
56
  type PlatformKey = keyof typeof PLATFORMS;
@@ -81,7 +73,7 @@ interface PlatformLimits {
81
73
  /**
82
74
  * Per-platform constraints mirrored from curator's `PLATFORM_RISK_CONFIG`
83
75
  * (curator `platformRisk.ts`). ONLY the absolute, tier-independent rules are
84
- * mirrored: PayPal's PLUS-tier gate and the hard Venmo / N26 caps. Per-tier
76
+ * mirrored: PayPal's PLUS-tier gate and the hard Venmo cap. Per-tier
85
77
  * effective caps are intentionally excluded — they're `capMultiplier × tierCap`
86
78
  * and depend on the taker, not the maker. Curator exposes no public "list
87
79
  * limits" endpoint, so this static mirror can drift if a PeerHQ admin changes
@@ -103,7 +95,7 @@ interface CompletePeerExtensionRegistrationInput {
103
95
  readonly capturedMetadata: PeerMetadataMessage;
104
96
  }
105
97
  interface CompletePeerExtensionRegistrationResult {
106
- readonly processorName: "paypal" | "wise";
98
+ readonly processorName: SellerCredentialProcessor;
107
99
  readonly offchainId: string;
108
100
  readonly hashedOnchainId: string;
109
101
  readonly sellerCredentialResponse: CuratorSellerCredentialUploadResponse;
@@ -287,4 +279,4 @@ declare class OfframpError extends Error {
287
279
  });
288
280
  }
289
281
 
290
- export { getPlatformLimits as A, isPeerExtensionRegistrationError as B, CURRENCIES as C, type DepositInfo as D, isValidIBAN as E, normalizePaypalMeUsername as F, MakersCreateError as M, OFFRAMP_ERROR_CODES as O, PLATFORMS as P, type CompletePeerExtensionRegistrationInput as a, type CompletePeerExtensionRegistrationResult as b, type CurrencyEntry as c, type DepositStatus as d, type OfframpCreateOptions as e, OfframpError as f, type OfframpErrorCode as g, type OfframpParams as h, type OfframpProgress as i, type OfframpQuote as j, type OfframpQuoteInput as k, type OfframpResult as l, type OfframpState as m, type OfframpStep as n, type OfframpVaultStatus as o, type OnProgress as p, PLATFORM_LIMITS as q, type PayeeDepositData as r, type PeerExtensionRegistrationInfo as s, type PlatformEntry as t, type PlatformKey as u, type PlatformLimits as v, type PlatformTier as w, completePeerExtensionRegistration as x, getPeerExtensionRegistrationAuthParams as y, getPeerExtensionRegistrationInfo as z };
282
+ export { getPlatformLimits as A, isPeerExtensionRegistrationError as B, CURRENCIES as C, type DepositInfo as D, normalizePaypalMeUsername as E, MakersCreateError as M, OFFRAMP_ERROR_CODES as O, PLATFORMS as P, type CompletePeerExtensionRegistrationInput as a, type CompletePeerExtensionRegistrationResult as b, type CurrencyEntry as c, type DepositStatus as d, type OfframpCreateOptions as e, OfframpError as f, type OfframpErrorCode as g, type OfframpParams as h, type OfframpProgress as i, type OfframpQuote as j, type OfframpQuoteInput as k, type OfframpResult as l, type OfframpState as m, type OfframpStep as n, type OfframpVaultStatus as o, type OnProgress as p, PLATFORM_LIMITS as q, type PayeeDepositData as r, type PeerExtensionRegistrationInfo as s, type PlatformEntry as t, type PlatformKey as u, type PlatformLimits as v, type PlatformTier as w, completePeerExtensionRegistration as x, getPeerExtensionRegistrationAuthParams as y, getPeerExtensionRegistrationInfo as z };
@@ -1,6 +1,7 @@
1
1
  import { PeerMetadataMessage, CuratorSellerCredentialUploadResponse, PeerAuthenticateParams, currencyInfo } from '@zkp2p/sdk';
2
2
 
3
- type PlatformId = "venmo" | "cashapp" | "chime" | "revolut" | "wise" | "mercadopago" | "zelle" | "paypal" | "monzo" | "n26" | "luxon";
3
+ type PlatformId = "venmo" | "cashapp" | "chime" | "revolut" | "wise" | "mercadopago" | "zelle" | "paypal" | "monzo";
4
+ type SellerCredentialProcessor = "paypal" | "wise" | "venmo" | "cashapp";
4
5
  /**
5
6
  * Extension pre-registration requirement for a platform. When present,
6
7
  * curator's `/v2/makers/create` rejects the maker until the user has
@@ -39,13 +40,6 @@ interface PlatformEntry {
39
40
  * upstream zkp2p-clients normalizer so our offchainId hashes identically.
40
41
  */
41
42
  declare function normalizePaypalMeUsername(value: string): string;
42
- /**
43
- * Validates an IBAN using the MOD-97 algorithm (ISO 13616), mirroring
44
- * curator's N26 processor so a malformed-but-well-formed IBAN is rejected
45
- * client-side before the maker approves USDC + pays gas. Expects no spaces
46
- * (the n26 transform strips them and uppercases first).
47
- */
48
- declare function isValidIBAN(iban: string): boolean;
49
43
  /** All supported payment platforms. Access via `PLATFORMS.REVOLUT`, `PLATFORMS.WISE`, etc. */
50
44
  declare const PLATFORMS: {
51
45
  readonly VENMO: PlatformEntry;
@@ -57,8 +51,6 @@ declare const PLATFORMS: {
57
51
  readonly ZELLE: PlatformEntry;
58
52
  readonly PAYPAL: PlatformEntry;
59
53
  readonly MONZO: PlatformEntry;
60
- readonly N26: PlatformEntry;
61
- readonly LUXON: PlatformEntry;
62
54
  };
63
55
  /** Platform key type for PLATFORMS constant. */
64
56
  type PlatformKey = keyof typeof PLATFORMS;
@@ -81,7 +73,7 @@ interface PlatformLimits {
81
73
  /**
82
74
  * Per-platform constraints mirrored from curator's `PLATFORM_RISK_CONFIG`
83
75
  * (curator `platformRisk.ts`). ONLY the absolute, tier-independent rules are
84
- * mirrored: PayPal's PLUS-tier gate and the hard Venmo / N26 caps. Per-tier
76
+ * mirrored: PayPal's PLUS-tier gate and the hard Venmo cap. Per-tier
85
77
  * effective caps are intentionally excluded — they're `capMultiplier × tierCap`
86
78
  * and depend on the taker, not the maker. Curator exposes no public "list
87
79
  * limits" endpoint, so this static mirror can drift if a PeerHQ admin changes
@@ -103,7 +95,7 @@ interface CompletePeerExtensionRegistrationInput {
103
95
  readonly capturedMetadata: PeerMetadataMessage;
104
96
  }
105
97
  interface CompletePeerExtensionRegistrationResult {
106
- readonly processorName: "paypal" | "wise";
98
+ readonly processorName: SellerCredentialProcessor;
107
99
  readonly offchainId: string;
108
100
  readonly hashedOnchainId: string;
109
101
  readonly sellerCredentialResponse: CuratorSellerCredentialUploadResponse;
@@ -287,4 +279,4 @@ declare class OfframpError extends Error {
287
279
  });
288
280
  }
289
281
 
290
- export { getPlatformLimits as A, isPeerExtensionRegistrationError as B, CURRENCIES as C, type DepositInfo as D, isValidIBAN as E, normalizePaypalMeUsername as F, MakersCreateError as M, OFFRAMP_ERROR_CODES as O, PLATFORMS as P, type CompletePeerExtensionRegistrationInput as a, type CompletePeerExtensionRegistrationResult as b, type CurrencyEntry as c, type DepositStatus as d, type OfframpCreateOptions as e, OfframpError as f, type OfframpErrorCode as g, type OfframpParams as h, type OfframpProgress as i, type OfframpQuote as j, type OfframpQuoteInput as k, type OfframpResult as l, type OfframpState as m, type OfframpStep as n, type OfframpVaultStatus as o, type OnProgress as p, PLATFORM_LIMITS as q, type PayeeDepositData as r, type PeerExtensionRegistrationInfo as s, type PlatformEntry as t, type PlatformKey as u, type PlatformLimits as v, type PlatformTier as w, completePeerExtensionRegistration as x, getPeerExtensionRegistrationAuthParams as y, getPeerExtensionRegistrationInfo as z };
282
+ export { getPlatformLimits as A, isPeerExtensionRegistrationError as B, CURRENCIES as C, type DepositInfo as D, normalizePaypalMeUsername as E, MakersCreateError as M, OFFRAMP_ERROR_CODES as O, PLATFORMS as P, type CompletePeerExtensionRegistrationInput as a, type CompletePeerExtensionRegistrationResult as b, type CurrencyEntry as c, type DepositStatus as d, type OfframpCreateOptions as e, OfframpError as f, type OfframpErrorCode as g, type OfframpParams as h, type OfframpProgress as i, type OfframpQuote as j, type OfframpQuoteInput as k, type OfframpResult as l, type OfframpState as m, type OfframpStep as n, type OfframpVaultStatus as o, type OnProgress as p, PLATFORM_LIMITS as q, type PayeeDepositData as r, type PeerExtensionRegistrationInfo as s, type PlatformEntry as t, type PlatformKey as u, type PlatformLimits as v, type PlatformTier as w, completePeerExtensionRegistration as x, getPeerExtensionRegistrationAuthParams as y, getPeerExtensionRegistrationInfo as z };
package/dist/index.cjs CHANGED
@@ -36,11 +36,12 @@ __export(index_exports, {
36
36
  MakersCreateError: () => MakersCreateError,
37
37
  OFFRAMP_DEVELOPER_RESOURCES: () => OFFRAMP_DEVELOPER_RESOURCES,
38
38
  OFFRAMP_ERROR_CODES: () => OFFRAMP_ERROR_CODES,
39
+ OFFRAMP_INTEGRATION_CHECKLIST: () => OFFRAMP_INTEGRATION_CHECKLIST,
39
40
  OFFRAMP_INTEGRATION_PLAYBOOKS: () => OFFRAMP_INTEGRATION_PLAYBOOKS,
40
41
  OFFRAMP_RESOURCE_LINKS: () => OFFRAMP_RESOURCE_LINKS,
41
42
  Offramp: () => Offramp,
42
43
  OfframpError: () => OfframpError,
43
- PEER_EXTENSION_CHROME_URL: () => import_sdk7.PEER_EXTENSION_CHROME_URL,
44
+ PEER_EXTENSION_CHROME_URL: () => import_sdk8.PEER_EXTENSION_CHROME_URL,
44
45
  PLATFORMS: () => PLATFORMS,
45
46
  PLATFORM_LIMITS: () => PLATFORM_LIMITS,
46
47
  close: () => close,
@@ -53,20 +54,23 @@ __export(index_exports, {
53
54
  disableOtc: () => disableOtc,
54
55
  emitEvent: () => emitEvent,
55
56
  enableOtc: () => enableOtc,
57
+ findTakerPlatformLimit: () => findTakerPlatformLimit,
58
+ getOfframpAgentPrompt: () => getOfframpAgentPrompt,
56
59
  getOfframpDeveloperResources: () => getOfframpDeveloperResources,
57
60
  getOtcLink: () => getOtcLink,
58
61
  getPeerExtensionRegistrationAuthParams: () => getPeerExtensionRegistrationAuthParams,
59
62
  getPeerExtensionRegistrationInfo: () => getPeerExtensionRegistrationInfo,
60
63
  getPeerExtensionState: () => getPeerExtensionState,
61
64
  getPlatformLimits: () => getPlatformLimits,
65
+ getTakerTier: () => getTakerTier,
62
66
  isPeerExtensionAvailable: () => isPeerExtensionAvailable,
63
67
  isPeerExtensionMetadataBridgeAvailable: () => isPeerExtensionMetadataBridgeAvailable,
64
68
  isPeerExtensionRegistrationError: () => isPeerExtensionRegistrationError,
65
- isValidIBAN: () => isValidIBAN,
66
69
  normalizePaypalMeUsername: () => normalizePaypalMeUsername,
67
70
  offramp: () => offramp,
68
71
  openPeerExtensionInstallPage: () => openPeerExtensionInstallPage,
69
72
  peerExtensionSdk: () => peerExtensionSdk,
73
+ resolveTakerPlatformLimit: () => resolveTakerPlatformLimit,
70
74
  sanitizeAttributionId: () => sanitizeAttributionId,
71
75
  sendTelemetryEvent: () => sendTelemetryEvent,
72
76
  undelegate: () => undelegate
@@ -80,7 +84,7 @@ var import_sdk5 = require("@zkp2p/sdk");
80
84
 
81
85
  // src/config.ts
82
86
  var import_sdk = require("@zkp2p/sdk");
83
- var SDK_VERSION = "4.3.0";
87
+ var SDK_VERSION = "4.4.0";
84
88
  var BASE_CHAIN_ID = 8453;
85
89
  var RUNTIME_ENV = "production";
86
90
  var API_BASE_URL = "https://api.zkp2p.xyz";
@@ -216,9 +220,7 @@ var FALLBACK_CURRENCIES = {
216
220
  mercadopago: ["ARS"],
217
221
  zelle: ["USD"],
218
222
  paypal: ["USD", "EUR", "GBP", "SGD", "NZD", "AUD", "CAD"],
219
- monzo: ["GBP"],
220
- n26: ["EUR"],
221
- luxon: ["USD", "EUR", "GBP"]
223
+ monzo: ["GBP"]
222
224
  };
223
225
  function gatherCatalogHashes(platform) {
224
226
  if (platform === "zelle") {
@@ -261,21 +263,6 @@ function normalizePaypalMeUsername(value) {
261
263
  }
262
264
  return trimmed.replace(/^@+/, "").toLowerCase();
263
265
  }
264
- function isValidIBAN(iban) {
265
- const upper = iban.toUpperCase();
266
- if (!/^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$/.test(upper)) return false;
267
- const rearranged = upper.slice(4) + upper.slice(0, 4);
268
- const numeric = rearranged.split("").map((ch) => {
269
- const code = ch.charCodeAt(0);
270
- return code >= 65 && code <= 90 ? (code - 55).toString() : ch;
271
- }).join("");
272
- let remainder = numeric;
273
- while (remainder.length > 2) {
274
- const block = remainder.slice(0, 9);
275
- remainder = (parseInt(block, 10) % 97).toString() + remainder.slice(block.length);
276
- }
277
- return parseInt(remainder, 10) % 97 === 1;
278
- }
279
266
  var BLUEPRINTS = {
280
267
  venmo: {
281
268
  id: "venmo",
@@ -284,7 +271,12 @@ var BLUEPRINTS = {
284
271
  placeholder: "venmo username (no @)",
285
272
  helperText: "Username without @ (publicly discoverable)",
286
273
  validation: import_zod.z.string().min(1).regex(/^[a-zA-Z0-9_-]+$/),
287
- transform: (v) => v.replace(/^@+/, "")
274
+ transform: (v) => v.replace(/^@+/, ""),
275
+ extensionRegistration: {
276
+ providerId: "venmo",
277
+ requiredPrompt: "This Venmo username is not registered yet. Register it with PeerAuth, then retry with the same Venmo username.",
278
+ ctaLabel: "Register Venmo Username"
279
+ }
288
280
  },
289
281
  cashapp: {
290
282
  id: "cashapp",
@@ -293,7 +285,12 @@ var BLUEPRINTS = {
293
285
  placeholder: "cashtag (no $)",
294
286
  helperText: "Cashtag without $ (publicly discoverable)",
295
287
  validation: import_zod.z.string().min(1).regex(/^[a-zA-Z0-9]+$/),
296
- transform: (v) => v.replace(/^\$+/, "")
288
+ transform: (v) => v.replace(/^\$+/, ""),
289
+ extensionRegistration: {
290
+ providerId: "cashapp",
291
+ requiredPrompt: "This Cash App cashtag is not registered yet. Register it with PeerAuth, then retry with the same cashtag.",
292
+ ctaLabel: "Register Cash App Cashtag"
293
+ }
297
294
  },
298
295
  chime: {
299
296
  id: "chime",
@@ -375,27 +372,6 @@ var BLUEPRINTS = {
375
372
  placeholder: "monzo.me username",
376
373
  helperText: "Your Monzo.me username",
377
374
  validation: import_zod.z.string().min(1).regex(/^[a-zA-Z0-9_-]+$/)
378
- },
379
- n26: {
380
- id: "n26",
381
- name: "N26",
382
- identifierLabel: "IBAN",
383
- placeholder: "IBAN (e.g. DE89...)",
384
- helperText: "Your IBAN (spaces will be removed)",
385
- // transform runs before validation, so the schema sees a spaceless,
386
- // uppercased IBAN. The MOD-97 refine mirrors curator's N26Processor so a
387
- // typo'd-but-well-formed IBAN fails here, not after USDC approval + gas.
388
- validation: import_zod.z.string().regex(/^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$/, "Enter a valid IBAN").refine(isValidIBAN, "That IBAN looks wrong \u2014 its checksum doesn't match"),
389
- transform: (v) => v.replace(/\s/g, "").toUpperCase()
390
- },
391
- luxon: {
392
- id: "luxon",
393
- name: "Luxon",
394
- identifierLabel: "Email",
395
- placeholder: "your-luxon-email@example.com",
396
- helperText: "Email address registered with Luxon",
397
- validation: import_zod.z.string().email(),
398
- transform: (v) => v.trim()
399
375
  }
400
376
  };
401
377
  function buildPlatformEntry(bp) {
@@ -433,13 +409,10 @@ var PLATFORMS = {
433
409
  MERCADO_PAGO: buildPlatformEntry(BLUEPRINTS.mercadopago),
434
410
  ZELLE: buildPlatformEntry(BLUEPRINTS.zelle),
435
411
  PAYPAL: buildPlatformEntry(BLUEPRINTS.paypal),
436
- MONZO: buildPlatformEntry(BLUEPRINTS.monzo),
437
- N26: buildPlatformEntry(BLUEPRINTS.n26),
438
- LUXON: buildPlatformEntry(BLUEPRINTS.luxon)
412
+ MONZO: buildPlatformEntry(BLUEPRINTS.monzo)
439
413
  };
440
414
  var PLATFORM_LIMITS = {
441
415
  venmo: { platformCapUsd: 5e3 },
442
- n26: { platformCapUsd: 1e4 },
443
416
  paypal: { minTier: "PLUS" }
444
417
  };
445
418
  function getPlatformLimits(platform) {
@@ -458,16 +431,26 @@ function normalizePaymentMethodLookupName(platform) {
458
431
  const ids = Object.values(PLATFORMS).map((p) => p.id);
459
432
  return ids.includes(normalized) ? normalized : null;
460
433
  }
434
+ var ZELLE_CREATE_LOOKUP_NAMES = ["zelle-chase", "zelle-bofa", "zelle-citi"];
461
435
  var GENERIC_ZELLE_METHOD_HASH = (0, import_sdk2.resolvePaymentMethodHash)("zelle") ?? null;
462
- function resolveCanonicalZelleHash() {
436
+ function resolveGenericZelleHash() {
463
437
  return GENERIC_ZELLE_METHOD_HASH;
464
438
  }
439
+ function getZelleCreateEntries() {
440
+ const entries = [];
441
+ for (const name of ZELLE_CREATE_LOOKUP_NAMES) {
442
+ const hash = getPaymentMethodHash(name);
443
+ if (hash) entries.push({ name, hash });
444
+ }
445
+ return entries;
446
+ }
465
447
  function getPaymentMethodHash(platform) {
466
448
  const name = normalizePaymentMethodLookupName(platform);
467
449
  if (!name) return null;
468
450
  const catalogEntry = PAYMENT_CATALOG[name];
469
451
  if (catalogEntry?.paymentMethodHash) return catalogEntry.paymentMethodHash;
470
- if (name === "zelle" || name.startsWith("zelle-")) return resolveCanonicalZelleHash();
452
+ if (name === "zelle") return resolveGenericZelleHash();
453
+ if (name.startsWith("zelle-")) return (0, import_sdk2.resolvePaymentMethodHash)(name);
471
454
  const sdkHash = (0, import_sdk2.resolvePaymentMethodHash)(name);
472
455
  return sdkHash ? sdkHash : null;
473
456
  }
@@ -476,16 +459,16 @@ function getPaymentMethodHashes(platform) {
476
459
  const hash = getPaymentMethodHash(platform);
477
460
  return hash ? [hash] : [];
478
461
  }
479
- const generic = resolveCanonicalZelleHash();
480
- return generic ? [generic] : [];
462
+ const hashes = getZelleCreateEntries().map((entry) => entry.hash);
463
+ const generic = resolveGenericZelleHash();
464
+ return generic ? [...hashes, generic] : hashes;
481
465
  }
482
466
  function getPaymentMethodCreateEntries(platform) {
483
467
  if (platform !== "zelle") {
484
468
  const hash = getPaymentMethodHash(platform);
485
469
  return hash ? [{ name: platform, hash }] : [];
486
470
  }
487
- const generic = resolveCanonicalZelleHash();
488
- return generic ? [{ name: "zelle", hash: generic }] : [];
471
+ return getZelleCreateEntries();
489
472
  }
490
473
  function buildDepositData(platform, identifier, telegramUsername = "") {
491
474
  const offchainId = platform === "chime" ? identifier.toLowerCase() : identifier;
@@ -510,7 +493,7 @@ function getPeerExtensionRegistrationAuthParams(platform, options = {}) {
510
493
  }
511
494
  function resolveRegistrationProcessor(platform) {
512
495
  const info = getPeerExtensionRegistrationInfo(platform.id);
513
- if (info?.providerId === "paypal" || info?.providerId === "wise") {
496
+ if (info?.providerId === "paypal" || info?.providerId === "wise" || info?.providerId === "venmo" || info?.providerId === "cashapp") {
514
497
  return info.providerId;
515
498
  }
516
499
  throw new Error(`${platform.name} does not require Peer extension registration.`);
@@ -1638,6 +1621,42 @@ function createOfframp(options) {
1638
1621
  return new Offramp(options);
1639
1622
  }
1640
1623
 
1624
+ // src/taker-tier.ts
1625
+ var import_sdk7 = require("@zkp2p/sdk");
1626
+ async function getTakerTier({
1627
+ owner,
1628
+ chainId = BASE_CHAIN_ID,
1629
+ apiBaseUrl = API_BASE_URL,
1630
+ timeoutMs = PAYEE_REGISTRATION_TIMEOUT_MS
1631
+ }) {
1632
+ const response = await (0, import_sdk7.apiGetTakerTier)({ owner, chainId }, apiBaseUrl, timeoutMs);
1633
+ if (!response.success || !response.responseObject) {
1634
+ throw new Error(response.message || "Failed to load taker tier.");
1635
+ }
1636
+ return response.responseObject;
1637
+ }
1638
+ function findTakerPlatformLimit(tier, lookup) {
1639
+ const limits = tier?.platformLimits ?? [];
1640
+ const platform = lookup.platform?.trim().toLowerCase() || null;
1641
+ const paymentMethodHash = lookup.paymentMethodHash?.trim().toLowerCase() || null;
1642
+ if (!platform && !paymentMethodHash) return null;
1643
+ return limits.find((limit) => {
1644
+ const limitHash = limit.paymentMethodHash?.trim().toLowerCase();
1645
+ if (paymentMethodHash && limitHash === paymentMethodHash) return true;
1646
+ const limitPlatform = limit.platformName?.trim().toLowerCase();
1647
+ if (!platform || !limitPlatform) return false;
1648
+ if (limitPlatform === platform) return true;
1649
+ return platform.startsWith("zelle") && limitPlatform.startsWith("zelle");
1650
+ }) ?? null;
1651
+ }
1652
+ function resolveTakerPlatformLimit(tier, lookup) {
1653
+ if (!tier) return null;
1654
+ return {
1655
+ tier: tier.tier,
1656
+ limit: findTakerPlatformLimit(tier, lookup)
1657
+ };
1658
+ }
1659
+
1641
1660
  // src/types.ts
1642
1661
  var OFFRAMP_ERROR_CODES = {
1643
1662
  VALIDATION: "VALIDATION",
@@ -1660,7 +1679,7 @@ var OFFRAMP_ERROR_CODES = {
1660
1679
  };
1661
1680
 
1662
1681
  // src/extension.ts
1663
- var import_sdk7 = require("@zkp2p/sdk");
1682
+ var import_sdk8 = require("@zkp2p/sdk");
1664
1683
  var DEFAULT_EXTENSION_INSTALL_URL = "https://chromewebstore.google.com/detail/usdctofiat-verify/lfkmdfifolhcfjmhklmckigfngghmpdf";
1665
1684
  var resolveWindow = (options) => {
1666
1685
  if (options?.window) {
@@ -1717,7 +1736,7 @@ var getPeerExtensionState = async (options) => {
1717
1736
  }
1718
1737
  };
1719
1738
  var createPeerExtensionSdk = (options = {}) => {
1720
- const sdk = (0, import_sdk7.createPeerExtensionSdk)(options);
1739
+ const sdk = (0, import_sdk8.createPeerExtensionSdk)(options);
1721
1740
  return {
1722
1741
  isAvailable: () => isPeerExtensionAvailable(options),
1723
1742
  requestConnection: () => requirePeer(options).requestConnection(),
@@ -1781,7 +1800,7 @@ var OFFRAMP_INTEGRATION_PLAYBOOKS = [
1781
1800
  detail: "Pass the user's viem WalletClient so the user signs approval, deposit, and delegation."
1782
1801
  },
1783
1802
  {
1784
- title: "Handle PayPal and Wise registration",
1803
+ title: "Handle SAR registration",
1785
1804
  detail: "Catch EXTENSION_REGISTRATION_REQUIRED and drive usePeerExtensionRegistration."
1786
1805
  },
1787
1806
  {
@@ -1971,6 +1990,33 @@ var OFFRAMP_INTEGRATION_PLAYBOOKS = [
1971
1990
  ]
1972
1991
  }
1973
1992
  ];
1993
+ var OFFRAMP_INTEGRATION_CHECKLIST = [
1994
+ {
1995
+ title: "Base mainnet wallet client",
1996
+ detail: "Use a viem WalletClient on chain 8453. The SDK has no public sandbox mode.",
1997
+ required: true
1998
+ },
1999
+ {
2000
+ title: "Delegate-vault pricing",
2001
+ detail: "Every SDK-created deposit must delegate pricing to the managed Delegate vault.",
2002
+ required: true
2003
+ },
2004
+ {
2005
+ title: "PayPal/Wise recovery path",
2006
+ detail: "Catch EXTENSION_REGISTRATION_REQUIRED and drive Peer extension seller registration.",
2007
+ required: true
2008
+ },
2009
+ {
2010
+ title: "Server-side duplicate prevention",
2011
+ detail: "Bots and workers must call deposits(address) and use their own order database; idempotencyKey is browser-session scoped and the standalone offramp() helper ignores it.",
2012
+ required: true
2013
+ },
2014
+ {
2015
+ title: "Raw-body webhook verification",
2016
+ detail: "Verify timestamp.rawBody with HMAC-SHA256 before parsing JSON.",
2017
+ required: true
2018
+ }
2019
+ ];
1974
2020
  var OFFRAMP_DEVELOPER_RESOURCES = {
1975
2021
  packageName: "@usdctofiat/offramp",
1976
2022
  sdkVersion: SDK_VERSION,
@@ -2001,7 +2047,8 @@ var OFFRAMP_DEVELOPER_RESOURCES = {
2001
2047
  peerlyticsPricing: OFFRAMP_RESOURCE_LINKS.peerlyticsPricing,
2002
2048
  npm: OFFRAMP_RESOURCE_LINKS.npm
2003
2049
  },
2004
- playbooks: OFFRAMP_INTEGRATION_PLAYBOOKS
2050
+ playbooks: OFFRAMP_INTEGRATION_PLAYBOOKS,
2051
+ checklist: OFFRAMP_INTEGRATION_CHECKLIST
2005
2052
  };
2006
2053
  function getOfframpDeveloperResources(profile) {
2007
2054
  if (!profile) return OFFRAMP_DEVELOPER_RESOURCES;
@@ -2009,6 +2056,22 @@ function getOfframpDeveloperResources(profile) {
2009
2056
  if (!playbook) return OFFRAMP_DEVELOPER_RESOURCES;
2010
2057
  return playbook;
2011
2058
  }
2059
+ function getOfframpAgentPrompt(profile = "app") {
2060
+ const playbook = getOfframpDeveloperResources(profile);
2061
+ const resource = "profile" in playbook ? playbook : OFFRAMP_INTEGRATION_PLAYBOOKS.find((entry) => entry.profile === "app");
2062
+ const steps = resource?.steps.map((step, index) => `${index + 1}. ${step.title}: ${step.detail}`);
2063
+ return [
2064
+ "Build a USDC-to-fiat integration with @usdctofiat/offramp.",
2065
+ `Profile: ${profile}.`,
2066
+ "Before coding, read https://usdctofiat.xyz/skills/usdctofiat.md and https://usdctofiat.xyz/llms.txt.",
2067
+ "Use Base mainnet chainId 8453 and a viem WalletClient; do not invent a sandbox.",
2068
+ "Do not add manual rate controls; SDK-created deposits must delegate to the Delegate vault.",
2069
+ "For PayPal, Wise, Venmo, and Cash App, recover EXTENSION_REGISTRATION_REQUIRED through the Peer extension registration flow.",
2070
+ "For bots/workers, deduplicate with deposits(address) plus your own order database; do not rely on idempotencyKey.",
2071
+ "For webhooks, verify the raw request body before parsing JSON.",
2072
+ ...steps ?? []
2073
+ ].join("\n");
2074
+ }
2012
2075
  // Annotate the CommonJS export names for ESM import in node:
2013
2076
  0 && (module.exports = {
2014
2077
  CURRENCIES,
@@ -2017,6 +2080,7 @@ function getOfframpDeveloperResources(profile) {
2017
2080
  MakersCreateError,
2018
2081
  OFFRAMP_DEVELOPER_RESOURCES,
2019
2082
  OFFRAMP_ERROR_CODES,
2083
+ OFFRAMP_INTEGRATION_CHECKLIST,
2020
2084
  OFFRAMP_INTEGRATION_PLAYBOOKS,
2021
2085
  OFFRAMP_RESOURCE_LINKS,
2022
2086
  Offramp,
@@ -2034,20 +2098,23 @@ function getOfframpDeveloperResources(profile) {
2034
2098
  disableOtc,
2035
2099
  emitEvent,
2036
2100
  enableOtc,
2101
+ findTakerPlatformLimit,
2102
+ getOfframpAgentPrompt,
2037
2103
  getOfframpDeveloperResources,
2038
2104
  getOtcLink,
2039
2105
  getPeerExtensionRegistrationAuthParams,
2040
2106
  getPeerExtensionRegistrationInfo,
2041
2107
  getPeerExtensionState,
2042
2108
  getPlatformLimits,
2109
+ getTakerTier,
2043
2110
  isPeerExtensionAvailable,
2044
2111
  isPeerExtensionMetadataBridgeAvailable,
2045
2112
  isPeerExtensionRegistrationError,
2046
- isValidIBAN,
2047
2113
  normalizePaypalMeUsername,
2048
2114
  offramp,
2049
2115
  openPeerExtensionInstallPage,
2050
2116
  peerExtensionSdk,
2117
+ resolveTakerPlatformLimit,
2051
2118
  sanitizeAttributionId,
2052
2119
  sendTelemetryEvent,
2053
2120
  undelegate