@usdctofiat/offramp 1.3.0 → 2.0.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.
@@ -0,0 +1,236 @@
1
+ import { currencyInfo } from '@zkp2p/sdk';
2
+
3
+ type PlatformId = "venmo" | "cashapp" | "chime" | "revolut" | "wise" | "mercadopago" | "zelle" | "paypal" | "monzo" | "n26";
4
+ /**
5
+ * Describes the Peer browser-extension pre-registration requirement for a
6
+ * platform. When present, curator's `/v2/makers/create` will reject the maker
7
+ * until the user has registered their handle inside the Peer (PeerAuth)
8
+ * extension at `/verify/<providerId>`.
9
+ *
10
+ * Drives the {@link isPeerExtensionRegistrationError} check and the React
11
+ * `usePeerExtensionRegistration` hook in `@usdctofiat/offramp/react`.
12
+ */
13
+ interface PeerExtensionRegistrationInfo {
14
+ /**
15
+ * Upstream provider id — matches the Peer extension verify handler. Used
16
+ * to build the sidebar route (`/verify/<providerId>`).
17
+ */
18
+ readonly providerId: string;
19
+ /** Human-readable message surfaced when curator rejects the maker. */
20
+ readonly requiredPrompt: string;
21
+ /** Label for the install / connect / verify CTA. */
22
+ readonly ctaLabel: string;
23
+ /** Optional subtext (e.g. PayPal Business disclaimer). */
24
+ readonly ctaSubtext?: string;
25
+ /** Minimum Peer extension version expected for this provider. */
26
+ readonly minExtensionVersion: string;
27
+ }
28
+ interface PlatformEntry {
29
+ readonly id: PlatformId;
30
+ readonly name: string;
31
+ readonly currencies: readonly string[];
32
+ readonly identifier: {
33
+ readonly label: string;
34
+ readonly placeholder: string;
35
+ readonly help: string;
36
+ };
37
+ /**
38
+ * Present when curator requires the maker to first register this handle in
39
+ * the Peer extension before `/v2/makers/create` will succeed. Today this
40
+ * applies to PayPal and Wise. See `@usdctofiat/offramp/react` for the
41
+ * `usePeerExtensionRegistration` hook that drives the handshake.
42
+ */
43
+ readonly extensionRegistration?: PeerExtensionRegistrationInfo;
44
+ validate(input: string): {
45
+ valid: boolean;
46
+ normalized: string;
47
+ error?: string;
48
+ };
49
+ }
50
+ /**
51
+ * Extracts the bare PayPal.me username from any accepted input shape
52
+ * (`paypal.me/user`, `https://paypal.me/user`, `@user`, `user`). Mirrors the
53
+ * upstream zkp2p-clients normalizer so our offchainId hashes identically.
54
+ */
55
+ declare function normalizePaypalMeUsername(value: string): string;
56
+ /** All supported payment platforms. Access via `PLATFORMS.REVOLUT`, `PLATFORMS.WISE`, etc. */
57
+ declare const PLATFORMS: {
58
+ readonly VENMO: PlatformEntry;
59
+ readonly CASHAPP: PlatformEntry;
60
+ readonly CHIME: PlatformEntry;
61
+ readonly REVOLUT: PlatformEntry;
62
+ readonly WISE: PlatformEntry;
63
+ readonly MERCADO_PAGO: PlatformEntry;
64
+ readonly ZELLE: PlatformEntry;
65
+ readonly PAYPAL: PlatformEntry;
66
+ readonly MONZO: PlatformEntry;
67
+ readonly N26: PlatformEntry;
68
+ };
69
+ /** Platform key type for PLATFORMS constant. */
70
+ type PlatformKey = keyof typeof PLATFORMS;
71
+ /**
72
+ * Shape curator's `/v2/makers/create` expects since the flat-offchainId
73
+ * migration (upstream #580). The endpoint hashes `offchainId + processorName`
74
+ * directly — legacy platform-specific keys (`paypalEmail`, `venmoUsername`,
75
+ * `wisetag`, …) are no longer accepted.
76
+ */
77
+ interface PayeeDepositData {
78
+ offchainId: string;
79
+ telegramUsername?: string;
80
+ metadata?: Record<string, string>;
81
+ }
82
+ /**
83
+ * Returns the extension-registration metadata for a platform, or `null` if
84
+ * the platform does not require Peer-extension pre-registration. Use this to
85
+ * decide whether to surface an "Install / Connect Peer Extension" CTA in
86
+ * your UI before calling `offramp()` for PayPal or Wise.
87
+ */
88
+ declare function getPeerExtensionRegistrationInfo(platform: string): PeerExtensionRegistrationInfo | null;
89
+ /**
90
+ * True when a failed `/v2/makers/create` response should be interpreted as
91
+ * "maker needs to register in the Peer extension first". Platforms without
92
+ * an `extensionRegistration` config always return false.
93
+ *
94
+ * Mirrors upstream `isExtensionRegistrationRequiredPostError`: a 400 status
95
+ * on a registration-required platform is treated as registration required,
96
+ * and so is any response whose message contains the curator phrasing.
97
+ */
98
+ declare function isPeerExtensionRegistrationError(platform: string, message?: string | null, statusCode?: number | null): boolean;
99
+
100
+ interface CurrencyEntry {
101
+ readonly code: string;
102
+ readonly name: string;
103
+ readonly symbol: string;
104
+ readonly countryCode: string;
105
+ }
106
+ type CurrencyMap = {
107
+ readonly [K in keyof typeof currencyInfo]: CurrencyEntry;
108
+ };
109
+ /** All supported currencies with metadata. Access via `CURRENCIES.EUR.symbol` etc. */
110
+ declare const CURRENCIES: CurrencyMap;
111
+
112
+ declare const OFFRAMP_ERROR_CODES: {
113
+ readonly VALIDATION: "VALIDATION";
114
+ readonly APPROVAL_FAILED: "APPROVAL_FAILED";
115
+ readonly REGISTRATION_FAILED: "REGISTRATION_FAILED";
116
+ /**
117
+ * Curator rejected the maker because the user has not registered this
118
+ * handle in the Peer extension yet. Thrown from `offramp()` for PayPal
119
+ * and Wise when `/v2/makers/create` returns 400 or a "creating the maker"
120
+ * message. Recover by prompting the user through the Peer extension via
121
+ * `usePeerExtensionRegistration(platform)` (React) or `peerExtensionSdk`
122
+ * directly, then call `offramp()` again.
123
+ */
124
+ readonly EXTENSION_REGISTRATION_REQUIRED: "EXTENSION_REGISTRATION_REQUIRED";
125
+ readonly DEPOSIT_FAILED: "DEPOSIT_FAILED";
126
+ readonly CONFIRMATION_FAILED: "CONFIRMATION_FAILED";
127
+ readonly DELEGATION_FAILED: "DELEGATION_FAILED";
128
+ readonly USER_CANCELLED: "USER_CANCELLED";
129
+ readonly UNSUPPORTED: "UNSUPPORTED";
130
+ };
131
+ type OfframpErrorCode = (typeof OFFRAMP_ERROR_CODES)[keyof typeof OFFRAMP_ERROR_CODES];
132
+ interface OfframpParams {
133
+ /** USDC amount as decimal string, min 1. */
134
+ amount: string;
135
+ /** Payment platform — use `PLATFORMS.REVOLUT` etc. */
136
+ platform: PlatformEntry;
137
+ /** Fiat currency — use `CURRENCIES.EUR` etc. */
138
+ currency: CurrencyEntry;
139
+ /** Platform-specific identifier (username, email, IBAN). */
140
+ identifier: string;
141
+ /** Optional: restrict the deposit to this taker wallet (OTC private order). */
142
+ otcTaker?: string;
143
+ /** Optional SDK-only referral metadata for telemetry attribution. */
144
+ referralId?: string;
145
+ /** Optional SDK-only integrator metadata for telemetry attribution. */
146
+ integratorId?: string;
147
+ /** Optional per-wallet key to replay the first successful result for 10 minutes. */
148
+ idempotencyKey?: string;
149
+ }
150
+ interface OfframpResult {
151
+ depositId: string;
152
+ txHash: string;
153
+ /** Whether an existing undelegated deposit was resumed. */
154
+ resumed: boolean;
155
+ /** OTC link for the taker, present when `otcTaker` was provided. */
156
+ otcLink?: string;
157
+ }
158
+ type OfframpStep = "approving" | "registering" | "depositing" | "confirming" | "delegating" | "restricting" | "resuming" | "done";
159
+ type OfframpState = "idle" | "approving" | "registering" | "depositing" | "confirming" | "delegating" | "done" | "error";
160
+ interface OfframpProgress {
161
+ step: OfframpStep;
162
+ txHash?: string;
163
+ depositId?: string;
164
+ }
165
+ type OnProgress = (progress: OfframpProgress) => void;
166
+ type DepositStatus = "active" | "empty" | "closed";
167
+ interface OfframpQuoteInput {
168
+ amount: string;
169
+ currency: CurrencyEntry;
170
+ platform: PlatformEntry;
171
+ }
172
+ interface OfframpQuote {
173
+ amountUsdc: number;
174
+ expectedFiat: number;
175
+ effectiveRate: number;
176
+ vaultSpreadBps: number;
177
+ }
178
+ interface OfframpVaultStatus {
179
+ rateManagerId: string;
180
+ rateManagerAddress: string;
181
+ feeRateBps: number;
182
+ escrow: string;
183
+ isActive: boolean;
184
+ }
185
+ interface OfframpCreateOptions {
186
+ integratorId?: string;
187
+ referralId?: string;
188
+ telemetry?: boolean;
189
+ }
190
+ interface DepositInfo {
191
+ /** Numeric deposit ID. Pass this to `close()`. */
192
+ depositId: string;
193
+ /** Composite ID (escrowAddress_depositId). */
194
+ compositeId: string;
195
+ /** Creation transaction hash. */
196
+ txHash?: string;
197
+ status: DepositStatus;
198
+ remainingUsdc: number;
199
+ outstandingUsdc: number;
200
+ totalTakenUsdc: number;
201
+ fulfilledIntents: number;
202
+ paymentMethods: string[];
203
+ currencies: string[];
204
+ rateSource: string;
205
+ delegated: boolean;
206
+ escrowAddress: string;
207
+ }
208
+
209
+ /**
210
+ * Error thrown when curator's `/v2/makers/create` returns a non-success
211
+ * response. Preserves the HTTP status so callers can distinguish a
212
+ * "needs Peer-extension registration" 400 from a transient server error.
213
+ *
214
+ * `offramp()` re-raises this as an {@link OfframpError} with code
215
+ * `EXTENSION_REGISTRATION_REQUIRED` (for PayPal/Wise 400s) or
216
+ * `REGISTRATION_FAILED` (for any other curator error); `MakersCreateError`
217
+ * is attached as the `cause`.
218
+ */
219
+ declare class MakersCreateError extends Error {
220
+ readonly status: number | null;
221
+ readonly body: string;
222
+ constructor(message: string, status: number | null, body: string);
223
+ }
224
+ declare class OfframpError extends Error {
225
+ readonly code: OfframpErrorCode;
226
+ readonly step?: OfframpStep;
227
+ readonly cause?: unknown;
228
+ readonly txHash?: string;
229
+ readonly depositId?: string;
230
+ constructor(message: string, code: OfframpErrorCode, step?: OfframpStep, cause?: unknown, details?: {
231
+ txHash?: string;
232
+ depositId?: string;
233
+ });
234
+ }
235
+
236
+ export { type CurrencyEntry as C, type DepositInfo as D, MakersCreateError as M, type OfframpParams as O, type PlatformEntry as P, type OnProgress as a, type OfframpResult as b, type OfframpCreateOptions as c, type OfframpQuoteInput as d, type OfframpQuote as e, type OfframpVaultStatus as f, CURRENCIES as g, type DepositStatus as h, OFFRAMP_ERROR_CODES as i, OfframpError as j, type OfframpErrorCode as k, type OfframpProgress as l, type OfframpState as m, type OfframpStep as n, PLATFORMS as o, type PayeeDepositData as p, type PeerExtensionRegistrationInfo as q, type PlatformKey as r, getPeerExtensionRegistrationInfo as s, isPeerExtensionRegistrationError as t, normalizePaypalMeUsername as u };
package/dist/index.cjs CHANGED
@@ -22,12 +22,15 @@ var index_exports = {};
22
22
  __export(index_exports, {
23
23
  CURRENCIES: () => CURRENCIES,
24
24
  ESCROW_ADDRESS: () => ESCROW_ADDRESS,
25
+ MakersCreateError: () => MakersCreateError,
25
26
  OFFRAMP_ERROR_CODES: () => OFFRAMP_ERROR_CODES,
26
27
  Offramp: () => Offramp,
27
28
  OfframpError: () => OfframpError,
29
+ PEER_EXTENSION_CHROME_URL: () => import_sdk7.PEER_EXTENSION_CHROME_URL,
28
30
  PLATFORMS: () => PLATFORMS,
29
31
  close: () => close,
30
32
  createOfframp: () => createOfframp,
33
+ createPeerExtensionSdk: () => import_sdk7.createPeerExtensionSdk,
31
34
  createTelemetryContext: () => createTelemetryContext,
32
35
  delegate: () => delegate,
33
36
  deposits: () => deposits,
@@ -35,7 +38,14 @@ __export(index_exports, {
35
38
  emitEvent: () => emitEvent,
36
39
  enableOtc: () => enableOtc,
37
40
  getOtcLink: () => getOtcLink,
41
+ getPeerExtensionRegistrationInfo: () => getPeerExtensionRegistrationInfo,
42
+ getPeerExtensionState: () => import_sdk7.getPeerExtensionState,
43
+ isPeerExtensionAvailable: () => import_sdk7.isPeerExtensionAvailable,
44
+ isPeerExtensionRegistrationError: () => isPeerExtensionRegistrationError,
45
+ normalizePaypalMeUsername: () => normalizePaypalMeUsername,
38
46
  offramp: () => offramp,
47
+ openPeerExtensionInstallPage: () => import_sdk7.openPeerExtensionInstallPage,
48
+ peerExtensionSdk: () => import_sdk7.peerExtensionSdk,
39
49
  sanitizeAttributionId: () => sanitizeAttributionId,
40
50
  sendTelemetryEvent: () => sendTelemetryEvent,
41
51
  undelegate: () => undelegate
@@ -166,6 +176,17 @@ function resolveSupportedCurrencies(platform) {
166
176
  }
167
177
  return Array.from(codes).sort();
168
178
  }
179
+ function normalizePaypalMeUsername(value) {
180
+ const trimmed = value.trim();
181
+ if (!trimmed) return "";
182
+ const withoutProtocol = trimmed.replace(/^https?:\/\//i, "").replace(/^www\./i, "");
183
+ if (/^paypal\.me(?:[?#].*)?$/i.test(withoutProtocol)) return "";
184
+ const withoutDomain = withoutProtocol.replace(/^paypal\.me\//i, "");
185
+ const [pathWithoutQuery] = withoutDomain.split(/[?#]/, 1);
186
+ const sanitizedPath = pathWithoutQuery.replace(/^\/+/, "");
187
+ const [username] = sanitizedPath.split("/", 1);
188
+ return username.replace(/^@+/, "").trim().toLowerCase();
189
+ }
169
190
  var BLUEPRINTS = {
170
191
  venmo: {
171
192
  id: "venmo",
@@ -213,7 +234,13 @@ var BLUEPRINTS = {
213
234
  placeholder: "wisetag (no @)",
214
235
  helperText: "Your Wise @wisetag (no @)",
215
236
  validation: import_zod.z.string().min(1).regex(/^[a-zA-Z0-9_-]+$/),
216
- transform: (v) => v.replace(/^@+/, "").trim()
237
+ transform: (v) => v.replace(/^@+/, "").trim(),
238
+ extensionRegistration: {
239
+ providerId: "wise",
240
+ requiredPrompt: "This Wisetag is not registered yet. Verify it in the Peer extension, then refresh and retry with the same Wisetag.",
241
+ ctaLabel: "Install Peer Extension",
242
+ minExtensionVersion: "0.4.12"
243
+ }
217
244
  },
218
245
  mercadopago: {
219
246
  id: "mercadopago",
@@ -234,10 +261,18 @@ var BLUEPRINTS = {
234
261
  paypal: {
235
262
  id: "paypal",
236
263
  name: "PayPal",
237
- identifierLabel: "Email",
238
- placeholder: "email",
239
- helperText: "Email linked to PayPal account",
240
- validation: import_zod.z.string().email()
264
+ identifierLabel: "PayPal.me Username",
265
+ placeholder: "paypal.me/your-username",
266
+ helperText: "Your PayPal.me username, not your email",
267
+ validation: import_zod.z.string().min(1, "PayPal.me username is required").regex(/^[a-z0-9._-]+$/i, "Use your PayPal.me username (letters, numbers, . _ -)"),
268
+ transform: normalizePaypalMeUsername,
269
+ extensionRegistration: {
270
+ providerId: "paypal",
271
+ requiredPrompt: "This PayPal username is not registered yet. Verify it in the Peer extension, then refresh and retry with the same PayPal username.",
272
+ ctaLabel: "Install Peer Extension",
273
+ ctaSubtext: "PayPal Business accounts are not supported at this time.",
274
+ minExtensionVersion: "0.4.14"
275
+ }
241
276
  },
242
277
  monzo: {
243
278
  id: "monzo",
@@ -268,6 +303,7 @@ function buildPlatformEntry(bp) {
268
303
  placeholder: bp.placeholder,
269
304
  help: bp.helperText
270
305
  },
306
+ ...bp.extensionRegistration ? { extensionRegistration: bp.extensionRegistration } : {},
271
307
  validate(input) {
272
308
  const transformed = bp.transform ? bp.transform(input) : input;
273
309
  const result = bp.validation.safeParse(transformed);
@@ -294,6 +330,9 @@ var PLATFORMS = {
294
330
  MONZO: buildPlatformEntry(BLUEPRINTS.monzo),
295
331
  N26: buildPlatformEntry(BLUEPRINTS.n26)
296
332
  };
333
+ function getPlatformById(id) {
334
+ return Object.values(PLATFORMS).find((p) => p.id === id) ?? null;
335
+ }
297
336
  function normalizePaymentMethodLookupName(platform) {
298
337
  const normalized = platform.trim().toLowerCase();
299
338
  if (!normalized) return null;
@@ -337,34 +376,37 @@ function getPaymentMethodHashes(platform) {
337
376
  }
338
377
  return Array.from(hashes);
339
378
  }
340
- function buildDepositData(platform, identifier) {
341
- switch (platform) {
342
- case "venmo":
343
- return { venmoUsername: identifier, telegramUsername: "" };
344
- case "cashapp":
345
- return { cashtag: identifier, telegramUsername: "" };
346
- case "chime":
347
- return { chimesign: identifier.toLowerCase(), telegramUsername: "" };
348
- case "revolut":
349
- return { revolutUsername: identifier, telegramUsername: "" };
350
- case "wise":
351
- return { wisetag: identifier, telegramUsername: "" };
352
- case "mercadopago":
353
- return { cvu: identifier, telegramUsername: "" };
354
- case "zelle":
355
- return { zelleEmail: identifier, telegramUsername: "" };
356
- case "paypal":
357
- return { paypalEmail: identifier, telegramUsername: "" };
358
- case "monzo":
359
- return { monzoMeUsername: identifier, telegramUsername: "" };
360
- case "n26":
361
- return { iban: identifier, telegramUsername: "" };
362
- default:
363
- return { identifier, telegramUsername: "" };
364
- }
379
+ function buildDepositData(platform, identifier, telegramUsername = "") {
380
+ const offchainId = platform === "chime" ? identifier.toLowerCase() : identifier;
381
+ return telegramUsername ? { offchainId, telegramUsername } : { offchainId };
382
+ }
383
+ function getPeerExtensionRegistrationInfo(platform) {
384
+ const entry = getPlatformById(platform);
385
+ return entry?.extensionRegistration ?? null;
386
+ }
387
+ var EXTENSION_REGISTRATION_ERROR_PATTERNS = ["creating the maker", "create the maker"];
388
+ function isPeerExtensionRegistrationError(platform, message, statusCode) {
389
+ const info = getPeerExtensionRegistrationInfo(platform);
390
+ if (!info) return false;
391
+ const normalized = (message ?? "").trim();
392
+ if (normalized === info.requiredPrompt) return true;
393
+ if (statusCode === 400) return true;
394
+ if (!normalized) return false;
395
+ const lower = normalized.toLowerCase();
396
+ return EXTENSION_REGISTRATION_ERROR_PATTERNS.some((p) => lower.includes(p));
365
397
  }
366
398
 
367
399
  // src/errors.ts
400
+ var MakersCreateError = class extends Error {
401
+ status;
402
+ body;
403
+ constructor(message, status, body) {
404
+ super(message);
405
+ this.name = "MakersCreateError";
406
+ this.status = status;
407
+ this.body = body;
408
+ }
409
+ };
368
410
  var OfframpError = class extends Error {
369
411
  code;
370
412
  step;
@@ -1153,23 +1195,39 @@ function extractDepositIdFromLogs(logs) {
1153
1195
  }
1154
1196
  return null;
1155
1197
  }
1156
- async function registerPayeeDetails(processorName, depositData) {
1198
+ async function registerPayeeDetails(processorName, payload) {
1157
1199
  const controller = new AbortController();
1158
1200
  const timeout = setTimeout(() => controller.abort(), PAYEE_REGISTRATION_TIMEOUT_MS);
1159
1201
  try {
1160
- const res = await fetch(`${API_BASE_URL}/v1/makers/create`, {
1202
+ const res = await fetch(`${API_BASE_URL}/v2/makers/create`, {
1161
1203
  method: "POST",
1162
1204
  headers: { "Content-Type": "application/json" },
1163
- body: JSON.stringify({ processorName, depositData }),
1205
+ body: JSON.stringify({ processorName, ...payload }),
1164
1206
  signal: controller.signal
1165
1207
  });
1166
1208
  if (!res.ok) {
1167
1209
  const txt = await res.text().catch(() => "");
1168
- throw new Error(`makers/create failed (${res.status}): ${txt || res.statusText}`);
1210
+ let detail = txt || res.statusText;
1211
+ try {
1212
+ const parsed = JSON.parse(txt);
1213
+ if (typeof parsed.message === "string" && parsed.message.trim()) {
1214
+ detail = parsed.message;
1215
+ }
1216
+ } catch {
1217
+ }
1218
+ throw new MakersCreateError(
1219
+ `makers/create failed (${res.status}): ${detail}`,
1220
+ res.status,
1221
+ txt
1222
+ );
1169
1223
  }
1170
1224
  const json = await res.json();
1171
1225
  if (!json.success || !json.responseObject?.hashedOnchainId) {
1172
- throw new Error(json.message || "makers/create returned no hashedOnchainId");
1226
+ throw new MakersCreateError(
1227
+ json.message || "makers/create returned no hashedOnchainId",
1228
+ json.statusCode ?? null,
1229
+ ""
1230
+ );
1173
1231
  }
1174
1232
  return json.responseObject.hashedOnchainId;
1175
1233
  } finally {
@@ -1371,11 +1429,21 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
1371
1429
  }
1372
1430
  emitProgress({ step: "registering" });
1373
1431
  let hashedOnchainId;
1432
+ const canonicalName = platformId.startsWith("zelle") ? "zelle" : platformId;
1374
1433
  try {
1375
- const canonicalName = platformId.startsWith("zelle") ? "zelle" : platformId;
1376
- const depositData = buildDepositData(platformId, normalizedIdentifier);
1377
- hashedOnchainId = await registerPayeeDetails(canonicalName, depositData);
1434
+ const payeePayload = buildDepositData(canonicalName, normalizedIdentifier);
1435
+ hashedOnchainId = await registerPayeeDetails(canonicalName, payeePayload);
1378
1436
  } catch (err) {
1437
+ const status = err instanceof MakersCreateError ? err.status : null;
1438
+ const message = err instanceof Error ? err.message : String(err);
1439
+ if (isPeerExtensionRegistrationError(canonicalName, message, status)) {
1440
+ throw new OfframpError(
1441
+ `${platform.name} maker is not yet registered in the Peer extension. Verify this handle in the extension, then retry.`,
1442
+ "EXTENSION_REGISTRATION_REQUIRED",
1443
+ "registering",
1444
+ err
1445
+ );
1446
+ }
1379
1447
  throw new OfframpError(
1380
1448
  "Payee registration failed",
1381
1449
  "REGISTRATION_FAILED",
@@ -1713,22 +1781,37 @@ var OFFRAMP_ERROR_CODES = {
1713
1781
  VALIDATION: "VALIDATION",
1714
1782
  APPROVAL_FAILED: "APPROVAL_FAILED",
1715
1783
  REGISTRATION_FAILED: "REGISTRATION_FAILED",
1784
+ /**
1785
+ * Curator rejected the maker because the user has not registered this
1786
+ * handle in the Peer extension yet. Thrown from `offramp()` for PayPal
1787
+ * and Wise when `/v2/makers/create` returns 400 or a "creating the maker"
1788
+ * message. Recover by prompting the user through the Peer extension via
1789
+ * `usePeerExtensionRegistration(platform)` (React) or `peerExtensionSdk`
1790
+ * directly, then call `offramp()` again.
1791
+ */
1792
+ EXTENSION_REGISTRATION_REQUIRED: "EXTENSION_REGISTRATION_REQUIRED",
1716
1793
  DEPOSIT_FAILED: "DEPOSIT_FAILED",
1717
1794
  CONFIRMATION_FAILED: "CONFIRMATION_FAILED",
1718
1795
  DELEGATION_FAILED: "DELEGATION_FAILED",
1719
1796
  USER_CANCELLED: "USER_CANCELLED",
1720
1797
  UNSUPPORTED: "UNSUPPORTED"
1721
1798
  };
1799
+
1800
+ // src/extension.ts
1801
+ var import_sdk7 = require("@zkp2p/sdk");
1722
1802
  // Annotate the CommonJS export names for ESM import in node:
1723
1803
  0 && (module.exports = {
1724
1804
  CURRENCIES,
1725
1805
  ESCROW_ADDRESS,
1806
+ MakersCreateError,
1726
1807
  OFFRAMP_ERROR_CODES,
1727
1808
  Offramp,
1728
1809
  OfframpError,
1810
+ PEER_EXTENSION_CHROME_URL,
1729
1811
  PLATFORMS,
1730
1812
  close,
1731
1813
  createOfframp,
1814
+ createPeerExtensionSdk,
1732
1815
  createTelemetryContext,
1733
1816
  delegate,
1734
1817
  deposits,
@@ -1736,7 +1819,14 @@ var OFFRAMP_ERROR_CODES = {
1736
1819
  emitEvent,
1737
1820
  enableOtc,
1738
1821
  getOtcLink,
1822
+ getPeerExtensionRegistrationInfo,
1823
+ getPeerExtensionState,
1824
+ isPeerExtensionAvailable,
1825
+ isPeerExtensionRegistrationError,
1826
+ normalizePaypalMeUsername,
1739
1827
  offramp,
1828
+ openPeerExtensionInstallPage,
1829
+ peerExtensionSdk,
1740
1830
  sanitizeAttributionId,
1741
1831
  sendTelemetryEvent,
1742
1832
  undelegate