@usdctofiat/offramp 1.3.0 → 2.0.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/CHANGELOG.md +270 -0
- package/README.md +82 -2
- package/dist/{chunk-JQBKGGI2.js → chunk-747S3WWB.js} +117 -40
- package/dist/chunk-747S3WWB.js.map +1 -0
- package/dist/{errors-CfZrDly0.d.cts → errors-DKQ2N_ih.d.cts} +73 -1
- package/dist/{errors-CfZrDly0.d.ts → errors-DKQ2N_ih.d.ts} +73 -1
- package/dist/index.cjs +127 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +30 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +219 -40
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +86 -2
- package/dist/react.d.ts +86 -2
- package/dist/react.js +122 -3
- package/dist/react.js.map +1 -1
- package/package.json +3 -2
- package/dist/chunk-JQBKGGI2.js.map +0 -1
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: "
|
|
238
|
-
placeholder: "
|
|
239
|
-
helperText: "
|
|
240
|
-
validation: import_zod.z.string().
|
|
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,36 @@ function getPaymentMethodHashes(platform) {
|
|
|
337
376
|
}
|
|
338
377
|
return Array.from(hashes);
|
|
339
378
|
}
|
|
340
|
-
function buildDepositData(platform, identifier) {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
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
|
+
if (statusCode === 400) return true;
|
|
392
|
+
const normalized = (message ?? "").trim();
|
|
393
|
+
if (!normalized) return false;
|
|
394
|
+
const lower = normalized.toLowerCase();
|
|
395
|
+
return EXTENSION_REGISTRATION_ERROR_PATTERNS.some((p) => lower.includes(p));
|
|
365
396
|
}
|
|
366
397
|
|
|
367
398
|
// src/errors.ts
|
|
399
|
+
var MakersCreateError = class extends Error {
|
|
400
|
+
status;
|
|
401
|
+
body;
|
|
402
|
+
constructor(message, status, body) {
|
|
403
|
+
super(message);
|
|
404
|
+
this.name = "MakersCreateError";
|
|
405
|
+
this.status = status;
|
|
406
|
+
this.body = body;
|
|
407
|
+
}
|
|
408
|
+
};
|
|
368
409
|
var OfframpError = class extends Error {
|
|
369
410
|
code;
|
|
370
411
|
step;
|
|
@@ -1153,23 +1194,39 @@ function extractDepositIdFromLogs(logs) {
|
|
|
1153
1194
|
}
|
|
1154
1195
|
return null;
|
|
1155
1196
|
}
|
|
1156
|
-
async function registerPayeeDetails(processorName,
|
|
1197
|
+
async function registerPayeeDetails(processorName, payload) {
|
|
1157
1198
|
const controller = new AbortController();
|
|
1158
1199
|
const timeout = setTimeout(() => controller.abort(), PAYEE_REGISTRATION_TIMEOUT_MS);
|
|
1159
1200
|
try {
|
|
1160
|
-
const res = await fetch(`${API_BASE_URL}/
|
|
1201
|
+
const res = await fetch(`${API_BASE_URL}/v2/makers/create`, {
|
|
1161
1202
|
method: "POST",
|
|
1162
1203
|
headers: { "Content-Type": "application/json" },
|
|
1163
|
-
body: JSON.stringify({ processorName,
|
|
1204
|
+
body: JSON.stringify({ processorName, ...payload }),
|
|
1164
1205
|
signal: controller.signal
|
|
1165
1206
|
});
|
|
1166
1207
|
if (!res.ok) {
|
|
1167
1208
|
const txt = await res.text().catch(() => "");
|
|
1168
|
-
|
|
1209
|
+
let detail = txt || res.statusText;
|
|
1210
|
+
try {
|
|
1211
|
+
const parsed = JSON.parse(txt);
|
|
1212
|
+
if (typeof parsed.message === "string" && parsed.message.trim()) {
|
|
1213
|
+
detail = parsed.message;
|
|
1214
|
+
}
|
|
1215
|
+
} catch {
|
|
1216
|
+
}
|
|
1217
|
+
throw new MakersCreateError(
|
|
1218
|
+
`makers/create failed (${res.status}): ${detail}`,
|
|
1219
|
+
res.status,
|
|
1220
|
+
txt
|
|
1221
|
+
);
|
|
1169
1222
|
}
|
|
1170
1223
|
const json = await res.json();
|
|
1171
1224
|
if (!json.success || !json.responseObject?.hashedOnchainId) {
|
|
1172
|
-
throw new
|
|
1225
|
+
throw new MakersCreateError(
|
|
1226
|
+
json.message || "makers/create returned no hashedOnchainId",
|
|
1227
|
+
json.statusCode ?? null,
|
|
1228
|
+
""
|
|
1229
|
+
);
|
|
1173
1230
|
}
|
|
1174
1231
|
return json.responseObject.hashedOnchainId;
|
|
1175
1232
|
} finally {
|
|
@@ -1371,11 +1428,21 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
|
|
|
1371
1428
|
}
|
|
1372
1429
|
emitProgress({ step: "registering" });
|
|
1373
1430
|
let hashedOnchainId;
|
|
1431
|
+
const canonicalName = platformId.startsWith("zelle") ? "zelle" : platformId;
|
|
1374
1432
|
try {
|
|
1375
|
-
const
|
|
1376
|
-
|
|
1377
|
-
hashedOnchainId = await registerPayeeDetails(canonicalName, depositData);
|
|
1433
|
+
const payeePayload = buildDepositData(canonicalName, normalizedIdentifier);
|
|
1434
|
+
hashedOnchainId = await registerPayeeDetails(canonicalName, payeePayload);
|
|
1378
1435
|
} catch (err) {
|
|
1436
|
+
const status = err instanceof MakersCreateError ? err.status : null;
|
|
1437
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1438
|
+
if (isPeerExtensionRegistrationError(canonicalName, message, status)) {
|
|
1439
|
+
throw new OfframpError(
|
|
1440
|
+
`${platform.name} maker is not yet registered in the Peer extension. Verify this handle in the extension, then retry.`,
|
|
1441
|
+
"EXTENSION_REGISTRATION_REQUIRED",
|
|
1442
|
+
"registering",
|
|
1443
|
+
err
|
|
1444
|
+
);
|
|
1445
|
+
}
|
|
1379
1446
|
throw new OfframpError(
|
|
1380
1447
|
"Payee registration failed",
|
|
1381
1448
|
"REGISTRATION_FAILED",
|
|
@@ -1713,22 +1780,37 @@ var OFFRAMP_ERROR_CODES = {
|
|
|
1713
1780
|
VALIDATION: "VALIDATION",
|
|
1714
1781
|
APPROVAL_FAILED: "APPROVAL_FAILED",
|
|
1715
1782
|
REGISTRATION_FAILED: "REGISTRATION_FAILED",
|
|
1783
|
+
/**
|
|
1784
|
+
* Curator rejected the maker because the user has not registered this
|
|
1785
|
+
* handle in the Peer extension yet. Thrown from `offramp()` for PayPal
|
|
1786
|
+
* and Wise when `/v2/makers/create` returns 400 or a "creating the maker"
|
|
1787
|
+
* message. Recover by prompting the user through the Peer extension via
|
|
1788
|
+
* `usePeerExtensionRegistration(platform)` (React) or `peerExtensionSdk`
|
|
1789
|
+
* directly, then call `offramp()` again.
|
|
1790
|
+
*/
|
|
1791
|
+
EXTENSION_REGISTRATION_REQUIRED: "EXTENSION_REGISTRATION_REQUIRED",
|
|
1716
1792
|
DEPOSIT_FAILED: "DEPOSIT_FAILED",
|
|
1717
1793
|
CONFIRMATION_FAILED: "CONFIRMATION_FAILED",
|
|
1718
1794
|
DELEGATION_FAILED: "DELEGATION_FAILED",
|
|
1719
1795
|
USER_CANCELLED: "USER_CANCELLED",
|
|
1720
1796
|
UNSUPPORTED: "UNSUPPORTED"
|
|
1721
1797
|
};
|
|
1798
|
+
|
|
1799
|
+
// src/extension.ts
|
|
1800
|
+
var import_sdk7 = require("@zkp2p/sdk");
|
|
1722
1801
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1723
1802
|
0 && (module.exports = {
|
|
1724
1803
|
CURRENCIES,
|
|
1725
1804
|
ESCROW_ADDRESS,
|
|
1805
|
+
MakersCreateError,
|
|
1726
1806
|
OFFRAMP_ERROR_CODES,
|
|
1727
1807
|
Offramp,
|
|
1728
1808
|
OfframpError,
|
|
1809
|
+
PEER_EXTENSION_CHROME_URL,
|
|
1729
1810
|
PLATFORMS,
|
|
1730
1811
|
close,
|
|
1731
1812
|
createOfframp,
|
|
1813
|
+
createPeerExtensionSdk,
|
|
1732
1814
|
createTelemetryContext,
|
|
1733
1815
|
delegate,
|
|
1734
1816
|
deposits,
|
|
@@ -1736,7 +1818,14 @@ var OFFRAMP_ERROR_CODES = {
|
|
|
1736
1818
|
emitEvent,
|
|
1737
1819
|
enableOtc,
|
|
1738
1820
|
getOtcLink,
|
|
1821
|
+
getPeerExtensionRegistrationInfo,
|
|
1822
|
+
getPeerExtensionState,
|
|
1823
|
+
isPeerExtensionAvailable,
|
|
1824
|
+
isPeerExtensionRegistrationError,
|
|
1825
|
+
normalizePaypalMeUsername,
|
|
1739
1826
|
offramp,
|
|
1827
|
+
openPeerExtensionInstallPage,
|
|
1828
|
+
peerExtensionSdk,
|
|
1740
1829
|
sanitizeAttributionId,
|
|
1741
1830
|
sendTelemetryEvent,
|
|
1742
1831
|
undelegate
|