@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.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CURRENCIES,
|
|
3
3
|
ESCROW_ADDRESS,
|
|
4
|
+
MakersCreateError,
|
|
4
5
|
Offramp,
|
|
5
6
|
OfframpError,
|
|
7
|
+
PEER_EXTENSION_CHROME_URL,
|
|
6
8
|
PLATFORMS,
|
|
7
9
|
close,
|
|
8
10
|
createOfframp,
|
|
11
|
+
createPeerExtensionSdk,
|
|
9
12
|
createTelemetryContext,
|
|
10
13
|
delegate,
|
|
11
14
|
deposits,
|
|
@@ -13,17 +16,33 @@ import {
|
|
|
13
16
|
emitEvent,
|
|
14
17
|
enableOtc,
|
|
15
18
|
getOtcLink,
|
|
19
|
+
getPeerExtensionRegistrationInfo,
|
|
20
|
+
getPeerExtensionState,
|
|
21
|
+
isPeerExtensionAvailable,
|
|
22
|
+
isPeerExtensionRegistrationError,
|
|
23
|
+
normalizePaypalMeUsername,
|
|
16
24
|
offramp,
|
|
25
|
+
openPeerExtensionInstallPage,
|
|
26
|
+
peerExtensionSdk,
|
|
17
27
|
sanitizeAttributionId,
|
|
18
28
|
sendTelemetryEvent,
|
|
19
29
|
undelegate
|
|
20
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-747S3WWB.js";
|
|
21
31
|
|
|
22
32
|
// src/types.ts
|
|
23
33
|
var OFFRAMP_ERROR_CODES = {
|
|
24
34
|
VALIDATION: "VALIDATION",
|
|
25
35
|
APPROVAL_FAILED: "APPROVAL_FAILED",
|
|
26
36
|
REGISTRATION_FAILED: "REGISTRATION_FAILED",
|
|
37
|
+
/**
|
|
38
|
+
* Curator rejected the maker because the user has not registered this
|
|
39
|
+
* handle in the Peer extension yet. Thrown from `offramp()` for PayPal
|
|
40
|
+
* and Wise when `/v2/makers/create` returns 400 or a "creating the maker"
|
|
41
|
+
* message. Recover by prompting the user through the Peer extension via
|
|
42
|
+
* `usePeerExtensionRegistration(platform)` (React) or `peerExtensionSdk`
|
|
43
|
+
* directly, then call `offramp()` again.
|
|
44
|
+
*/
|
|
45
|
+
EXTENSION_REGISTRATION_REQUIRED: "EXTENSION_REGISTRATION_REQUIRED",
|
|
27
46
|
DEPOSIT_FAILED: "DEPOSIT_FAILED",
|
|
28
47
|
CONFIRMATION_FAILED: "CONFIRMATION_FAILED",
|
|
29
48
|
DELEGATION_FAILED: "DELEGATION_FAILED",
|
|
@@ -33,12 +52,15 @@ var OFFRAMP_ERROR_CODES = {
|
|
|
33
52
|
export {
|
|
34
53
|
CURRENCIES,
|
|
35
54
|
ESCROW_ADDRESS,
|
|
55
|
+
MakersCreateError,
|
|
36
56
|
OFFRAMP_ERROR_CODES,
|
|
37
57
|
Offramp,
|
|
38
58
|
OfframpError,
|
|
59
|
+
PEER_EXTENSION_CHROME_URL,
|
|
39
60
|
PLATFORMS,
|
|
40
61
|
close,
|
|
41
62
|
createOfframp,
|
|
63
|
+
createPeerExtensionSdk,
|
|
42
64
|
createTelemetryContext,
|
|
43
65
|
delegate,
|
|
44
66
|
deposits,
|
|
@@ -46,7 +68,14 @@ export {
|
|
|
46
68
|
emitEvent,
|
|
47
69
|
enableOtc,
|
|
48
70
|
getOtcLink,
|
|
71
|
+
getPeerExtensionRegistrationInfo,
|
|
72
|
+
getPeerExtensionState,
|
|
73
|
+
isPeerExtensionAvailable,
|
|
74
|
+
isPeerExtensionRegistrationError,
|
|
75
|
+
normalizePaypalMeUsername,
|
|
49
76
|
offramp,
|
|
77
|
+
openPeerExtensionInstallPage,
|
|
78
|
+
peerExtensionSdk,
|
|
50
79
|
sanitizeAttributionId,
|
|
51
80
|
sendTelemetryEvent,
|
|
52
81
|
undelegate
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { PlatformEntry } from \"./platforms\";\nimport type { CurrencyEntry } from \"./currencies\";\n\nexport const OFFRAMP_ERROR_CODES = {\n VALIDATION: \"VALIDATION\",\n APPROVAL_FAILED: \"APPROVAL_FAILED\",\n REGISTRATION_FAILED: \"REGISTRATION_FAILED\",\n DEPOSIT_FAILED: \"DEPOSIT_FAILED\",\n CONFIRMATION_FAILED: \"CONFIRMATION_FAILED\",\n DELEGATION_FAILED: \"DELEGATION_FAILED\",\n USER_CANCELLED: \"USER_CANCELLED\",\n UNSUPPORTED: \"UNSUPPORTED\",\n} as const;\n\nexport type OfframpErrorCode = (typeof OFFRAMP_ERROR_CODES)[keyof typeof OFFRAMP_ERROR_CODES];\n\nexport interface OfframpParams {\n /** USDC amount as decimal string, min 1. */\n amount: string;\n /** Payment platform — use `PLATFORMS.REVOLUT` etc. */\n platform: PlatformEntry;\n /** Fiat currency — use `CURRENCIES.EUR` etc. */\n currency: CurrencyEntry;\n /** Platform-specific identifier (username, email, IBAN). */\n identifier: string;\n /** Optional: restrict the deposit to this taker wallet (OTC private order). */\n otcTaker?: string;\n /** Optional SDK-only referral metadata for telemetry attribution. */\n referralId?: string;\n /** Optional SDK-only integrator metadata for telemetry attribution. */\n integratorId?: string;\n /** Optional per-wallet key to replay the first successful result for 10 minutes. */\n idempotencyKey?: string;\n}\n\nexport interface OfframpResult {\n depositId: string;\n txHash: string;\n /** Whether an existing undelegated deposit was resumed. */\n resumed: boolean;\n /** OTC link for the taker, present when `otcTaker` was provided. */\n otcLink?: string;\n}\n\nexport type OfframpStep =\n | \"approving\"\n | \"registering\"\n | \"depositing\"\n | \"confirming\"\n | \"delegating\"\n | \"restricting\"\n | \"resuming\"\n | \"done\";\n\nexport type OfframpState =\n | \"idle\"\n | \"approving\"\n | \"registering\"\n | \"depositing\"\n | \"confirming\"\n | \"delegating\"\n | \"done\"\n | \"error\";\n\nexport interface OfframpProgress {\n step: OfframpStep;\n txHash?: string;\n depositId?: string;\n}\n\nexport type OnProgress = (progress: OfframpProgress) => void;\n\nexport type DepositStatus = \"active\" | \"empty\" | \"closed\";\n\nexport interface OfframpQuoteInput {\n amount: string;\n currency: CurrencyEntry;\n platform: PlatformEntry;\n}\n\nexport interface OfframpQuote {\n amountUsdc: number;\n expectedFiat: number;\n effectiveRate: number;\n vaultSpreadBps: number;\n}\n\nexport interface OfframpVaultStatus {\n rateManagerId: string;\n rateManagerAddress: string;\n feeRateBps: number;\n escrow: string;\n isActive: boolean;\n}\n\nexport interface OfframpCreateOptions {\n integratorId?: string;\n referralId?: string;\n telemetry?: boolean;\n}\n\nexport interface DepositInfo {\n /** Numeric deposit ID. Pass this to `close()`. */\n depositId: string;\n /** Composite ID (escrowAddress_depositId). */\n compositeId: string;\n /** Creation transaction hash. */\n txHash?: string;\n status: DepositStatus;\n remainingUsdc: number;\n outstandingUsdc: number;\n totalTakenUsdc: number;\n fulfilledIntents: number;\n paymentMethods: string[];\n currencies: string[];\n rateSource: string;\n delegated: boolean;\n escrowAddress: string;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { PlatformEntry } from \"./platforms\";\nimport type { CurrencyEntry } from \"./currencies\";\n\nexport const OFFRAMP_ERROR_CODES = {\n VALIDATION: \"VALIDATION\",\n APPROVAL_FAILED: \"APPROVAL_FAILED\",\n REGISTRATION_FAILED: \"REGISTRATION_FAILED\",\n /**\n * Curator rejected the maker because the user has not registered this\n * handle in the Peer extension yet. Thrown from `offramp()` for PayPal\n * and Wise when `/v2/makers/create` returns 400 or a \"creating the maker\"\n * message. Recover by prompting the user through the Peer extension via\n * `usePeerExtensionRegistration(platform)` (React) or `peerExtensionSdk`\n * directly, then call `offramp()` again.\n */\n EXTENSION_REGISTRATION_REQUIRED: \"EXTENSION_REGISTRATION_REQUIRED\",\n DEPOSIT_FAILED: \"DEPOSIT_FAILED\",\n CONFIRMATION_FAILED: \"CONFIRMATION_FAILED\",\n DELEGATION_FAILED: \"DELEGATION_FAILED\",\n USER_CANCELLED: \"USER_CANCELLED\",\n UNSUPPORTED: \"UNSUPPORTED\",\n} as const;\n\nexport type OfframpErrorCode = (typeof OFFRAMP_ERROR_CODES)[keyof typeof OFFRAMP_ERROR_CODES];\n\nexport interface OfframpParams {\n /** USDC amount as decimal string, min 1. */\n amount: string;\n /** Payment platform — use `PLATFORMS.REVOLUT` etc. */\n platform: PlatformEntry;\n /** Fiat currency — use `CURRENCIES.EUR` etc. */\n currency: CurrencyEntry;\n /** Platform-specific identifier (username, email, IBAN). */\n identifier: string;\n /** Optional: restrict the deposit to this taker wallet (OTC private order). */\n otcTaker?: string;\n /** Optional SDK-only referral metadata for telemetry attribution. */\n referralId?: string;\n /** Optional SDK-only integrator metadata for telemetry attribution. */\n integratorId?: string;\n /** Optional per-wallet key to replay the first successful result for 10 minutes. */\n idempotencyKey?: string;\n}\n\nexport interface OfframpResult {\n depositId: string;\n txHash: string;\n /** Whether an existing undelegated deposit was resumed. */\n resumed: boolean;\n /** OTC link for the taker, present when `otcTaker` was provided. */\n otcLink?: string;\n}\n\nexport type OfframpStep =\n | \"approving\"\n | \"registering\"\n | \"depositing\"\n | \"confirming\"\n | \"delegating\"\n | \"restricting\"\n | \"resuming\"\n | \"done\";\n\nexport type OfframpState =\n | \"idle\"\n | \"approving\"\n | \"registering\"\n | \"depositing\"\n | \"confirming\"\n | \"delegating\"\n | \"done\"\n | \"error\";\n\nexport interface OfframpProgress {\n step: OfframpStep;\n txHash?: string;\n depositId?: string;\n}\n\nexport type OnProgress = (progress: OfframpProgress) => void;\n\nexport type DepositStatus = \"active\" | \"empty\" | \"closed\";\n\nexport interface OfframpQuoteInput {\n amount: string;\n currency: CurrencyEntry;\n platform: PlatformEntry;\n}\n\nexport interface OfframpQuote {\n amountUsdc: number;\n expectedFiat: number;\n effectiveRate: number;\n vaultSpreadBps: number;\n}\n\nexport interface OfframpVaultStatus {\n rateManagerId: string;\n rateManagerAddress: string;\n feeRateBps: number;\n escrow: string;\n isActive: boolean;\n}\n\nexport interface OfframpCreateOptions {\n integratorId?: string;\n referralId?: string;\n telemetry?: boolean;\n}\n\nexport interface DepositInfo {\n /** Numeric deposit ID. Pass this to `close()`. */\n depositId: string;\n /** Composite ID (escrowAddress_depositId). */\n compositeId: string;\n /** Creation transaction hash. */\n txHash?: string;\n status: DepositStatus;\n remainingUsdc: number;\n outstandingUsdc: number;\n totalTakenUsdc: number;\n fulfilledIntents: number;\n paymentMethods: string[];\n currencies: string[];\n rateSource: string;\n delegated: boolean;\n escrowAddress: string;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGO,IAAM,sBAAsB;AAAA,EACjC,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASrB,iCAAiC;AAAA,EACjC,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,aAAa;AACf;","names":[]}
|
package/dist/react.cjs
CHANGED
|
@@ -20,7 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/react.ts
|
|
21
21
|
var react_exports = {};
|
|
22
22
|
__export(react_exports, {
|
|
23
|
-
useOfframp: () => useOfframp
|
|
23
|
+
useOfframp: () => useOfframp,
|
|
24
|
+
usePeerExtensionRegistration: () => usePeerExtensionRegistration
|
|
24
25
|
});
|
|
25
26
|
module.exports = __toCommonJS(react_exports);
|
|
26
27
|
|
|
@@ -169,6 +170,17 @@ function resolveSupportedCurrencies(platform) {
|
|
|
169
170
|
}
|
|
170
171
|
return Array.from(codes).sort();
|
|
171
172
|
}
|
|
173
|
+
function normalizePaypalMeUsername(value) {
|
|
174
|
+
const trimmed = value.trim();
|
|
175
|
+
if (!trimmed) return "";
|
|
176
|
+
const withoutProtocol = trimmed.replace(/^https?:\/\//i, "").replace(/^www\./i, "");
|
|
177
|
+
if (/^paypal\.me(?:[?#].*)?$/i.test(withoutProtocol)) return "";
|
|
178
|
+
const withoutDomain = withoutProtocol.replace(/^paypal\.me\//i, "");
|
|
179
|
+
const [pathWithoutQuery] = withoutDomain.split(/[?#]/, 1);
|
|
180
|
+
const sanitizedPath = pathWithoutQuery.replace(/^\/+/, "");
|
|
181
|
+
const [username] = sanitizedPath.split("/", 1);
|
|
182
|
+
return username.replace(/^@+/, "").trim().toLowerCase();
|
|
183
|
+
}
|
|
172
184
|
var BLUEPRINTS = {
|
|
173
185
|
venmo: {
|
|
174
186
|
id: "venmo",
|
|
@@ -216,7 +228,13 @@ var BLUEPRINTS = {
|
|
|
216
228
|
placeholder: "wisetag (no @)",
|
|
217
229
|
helperText: "Your Wise @wisetag (no @)",
|
|
218
230
|
validation: import_zod.z.string().min(1).regex(/^[a-zA-Z0-9_-]+$/),
|
|
219
|
-
transform: (v) => v.replace(/^@+/, "").trim()
|
|
231
|
+
transform: (v) => v.replace(/^@+/, "").trim(),
|
|
232
|
+
extensionRegistration: {
|
|
233
|
+
providerId: "wise",
|
|
234
|
+
requiredPrompt: "This Wisetag is not registered yet. Verify it in the Peer extension, then refresh and retry with the same Wisetag.",
|
|
235
|
+
ctaLabel: "Install Peer Extension",
|
|
236
|
+
minExtensionVersion: "0.4.12"
|
|
237
|
+
}
|
|
220
238
|
},
|
|
221
239
|
mercadopago: {
|
|
222
240
|
id: "mercadopago",
|
|
@@ -237,10 +255,18 @@ var BLUEPRINTS = {
|
|
|
237
255
|
paypal: {
|
|
238
256
|
id: "paypal",
|
|
239
257
|
name: "PayPal",
|
|
240
|
-
identifierLabel: "
|
|
241
|
-
placeholder: "
|
|
242
|
-
helperText: "
|
|
243
|
-
validation: import_zod.z.string().
|
|
258
|
+
identifierLabel: "PayPal.me Username",
|
|
259
|
+
placeholder: "paypal.me/your-username",
|
|
260
|
+
helperText: "Your PayPal.me username, not your email",
|
|
261
|
+
validation: import_zod.z.string().min(1, "PayPal.me username is required").regex(/^[a-z0-9._-]+$/i, "Use your PayPal.me username (letters, numbers, . _ -)"),
|
|
262
|
+
transform: normalizePaypalMeUsername,
|
|
263
|
+
extensionRegistration: {
|
|
264
|
+
providerId: "paypal",
|
|
265
|
+
requiredPrompt: "This PayPal username is not registered yet. Verify it in the Peer extension, then refresh and retry with the same PayPal username.",
|
|
266
|
+
ctaLabel: "Install Peer Extension",
|
|
267
|
+
ctaSubtext: "PayPal Business accounts are not supported at this time.",
|
|
268
|
+
minExtensionVersion: "0.4.14"
|
|
269
|
+
}
|
|
244
270
|
},
|
|
245
271
|
monzo: {
|
|
246
272
|
id: "monzo",
|
|
@@ -271,6 +297,7 @@ function buildPlatformEntry(bp) {
|
|
|
271
297
|
placeholder: bp.placeholder,
|
|
272
298
|
help: bp.helperText
|
|
273
299
|
},
|
|
300
|
+
...bp.extensionRegistration ? { extensionRegistration: bp.extensionRegistration } : {},
|
|
274
301
|
validate(input) {
|
|
275
302
|
const transformed = bp.transform ? bp.transform(input) : input;
|
|
276
303
|
const result = bp.validation.safeParse(transformed);
|
|
@@ -297,6 +324,9 @@ var PLATFORMS = {
|
|
|
297
324
|
MONZO: buildPlatformEntry(BLUEPRINTS.monzo),
|
|
298
325
|
N26: buildPlatformEntry(BLUEPRINTS.n26)
|
|
299
326
|
};
|
|
327
|
+
function getPlatformById(id) {
|
|
328
|
+
return Object.values(PLATFORMS).find((p) => p.id === id) ?? null;
|
|
329
|
+
}
|
|
300
330
|
function normalizePaymentMethodLookupName(platform) {
|
|
301
331
|
const normalized = platform.trim().toLowerCase();
|
|
302
332
|
if (!normalized) return null;
|
|
@@ -340,34 +370,36 @@ function getPaymentMethodHashes(platform) {
|
|
|
340
370
|
}
|
|
341
371
|
return Array.from(hashes);
|
|
342
372
|
}
|
|
343
|
-
function buildDepositData(platform, identifier) {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
return { paypalEmail: identifier, telegramUsername: "" };
|
|
361
|
-
case "monzo":
|
|
362
|
-
return { monzoMeUsername: identifier, telegramUsername: "" };
|
|
363
|
-
case "n26":
|
|
364
|
-
return { iban: identifier, telegramUsername: "" };
|
|
365
|
-
default:
|
|
366
|
-
return { identifier, telegramUsername: "" };
|
|
367
|
-
}
|
|
373
|
+
function buildDepositData(platform, identifier, telegramUsername = "") {
|
|
374
|
+
const offchainId = platform === "chime" ? identifier.toLowerCase() : identifier;
|
|
375
|
+
return telegramUsername ? { offchainId, telegramUsername } : { offchainId };
|
|
376
|
+
}
|
|
377
|
+
function getPeerExtensionRegistrationInfo(platform) {
|
|
378
|
+
const entry = getPlatformById(platform);
|
|
379
|
+
return entry?.extensionRegistration ?? null;
|
|
380
|
+
}
|
|
381
|
+
var EXTENSION_REGISTRATION_ERROR_PATTERNS = ["creating the maker", "create the maker"];
|
|
382
|
+
function isPeerExtensionRegistrationError(platform, message, statusCode) {
|
|
383
|
+
const info = getPeerExtensionRegistrationInfo(platform);
|
|
384
|
+
if (!info) return false;
|
|
385
|
+
if (statusCode === 400) return true;
|
|
386
|
+
const normalized = (message ?? "").trim();
|
|
387
|
+
if (!normalized) return false;
|
|
388
|
+
const lower = normalized.toLowerCase();
|
|
389
|
+
return EXTENSION_REGISTRATION_ERROR_PATTERNS.some((p) => lower.includes(p));
|
|
368
390
|
}
|
|
369
391
|
|
|
370
392
|
// src/errors.ts
|
|
393
|
+
var MakersCreateError = class extends Error {
|
|
394
|
+
status;
|
|
395
|
+
body;
|
|
396
|
+
constructor(message, status, body) {
|
|
397
|
+
super(message);
|
|
398
|
+
this.name = "MakersCreateError";
|
|
399
|
+
this.status = status;
|
|
400
|
+
this.body = body;
|
|
401
|
+
}
|
|
402
|
+
};
|
|
371
403
|
var OfframpError = class extends Error {
|
|
372
404
|
code;
|
|
373
405
|
step;
|
|
@@ -1069,23 +1101,39 @@ function extractDepositIdFromLogs(logs) {
|
|
|
1069
1101
|
}
|
|
1070
1102
|
return null;
|
|
1071
1103
|
}
|
|
1072
|
-
async function registerPayeeDetails(processorName,
|
|
1104
|
+
async function registerPayeeDetails(processorName, payload) {
|
|
1073
1105
|
const controller = new AbortController();
|
|
1074
1106
|
const timeout = setTimeout(() => controller.abort(), PAYEE_REGISTRATION_TIMEOUT_MS);
|
|
1075
1107
|
try {
|
|
1076
|
-
const res = await fetch(`${API_BASE_URL}/
|
|
1108
|
+
const res = await fetch(`${API_BASE_URL}/v2/makers/create`, {
|
|
1077
1109
|
method: "POST",
|
|
1078
1110
|
headers: { "Content-Type": "application/json" },
|
|
1079
|
-
body: JSON.stringify({ processorName,
|
|
1111
|
+
body: JSON.stringify({ processorName, ...payload }),
|
|
1080
1112
|
signal: controller.signal
|
|
1081
1113
|
});
|
|
1082
1114
|
if (!res.ok) {
|
|
1083
1115
|
const txt = await res.text().catch(() => "");
|
|
1084
|
-
|
|
1116
|
+
let detail = txt || res.statusText;
|
|
1117
|
+
try {
|
|
1118
|
+
const parsed = JSON.parse(txt);
|
|
1119
|
+
if (typeof parsed.message === "string" && parsed.message.trim()) {
|
|
1120
|
+
detail = parsed.message;
|
|
1121
|
+
}
|
|
1122
|
+
} catch {
|
|
1123
|
+
}
|
|
1124
|
+
throw new MakersCreateError(
|
|
1125
|
+
`makers/create failed (${res.status}): ${detail}`,
|
|
1126
|
+
res.status,
|
|
1127
|
+
txt
|
|
1128
|
+
);
|
|
1085
1129
|
}
|
|
1086
1130
|
const json = await res.json();
|
|
1087
1131
|
if (!json.success || !json.responseObject?.hashedOnchainId) {
|
|
1088
|
-
throw new
|
|
1132
|
+
throw new MakersCreateError(
|
|
1133
|
+
json.message || "makers/create returned no hashedOnchainId",
|
|
1134
|
+
json.statusCode ?? null,
|
|
1135
|
+
""
|
|
1136
|
+
);
|
|
1089
1137
|
}
|
|
1090
1138
|
return json.responseObject.hashedOnchainId;
|
|
1091
1139
|
} finally {
|
|
@@ -1287,11 +1335,21 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
|
|
|
1287
1335
|
}
|
|
1288
1336
|
emitProgress({ step: "registering" });
|
|
1289
1337
|
let hashedOnchainId;
|
|
1338
|
+
const canonicalName = platformId.startsWith("zelle") ? "zelle" : platformId;
|
|
1290
1339
|
try {
|
|
1291
|
-
const
|
|
1292
|
-
|
|
1293
|
-
hashedOnchainId = await registerPayeeDetails(canonicalName, depositData);
|
|
1340
|
+
const payeePayload = buildDepositData(canonicalName, normalizedIdentifier);
|
|
1341
|
+
hashedOnchainId = await registerPayeeDetails(canonicalName, payeePayload);
|
|
1294
1342
|
} catch (err) {
|
|
1343
|
+
const status = err instanceof MakersCreateError ? err.status : null;
|
|
1344
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1345
|
+
if (isPeerExtensionRegistrationError(canonicalName, message, status)) {
|
|
1346
|
+
throw new OfframpError(
|
|
1347
|
+
`${platform.name} maker is not yet registered in the Peer extension. Verify this handle in the extension, then retry.`,
|
|
1348
|
+
"EXTENSION_REGISTRATION_REQUIRED",
|
|
1349
|
+
"registering",
|
|
1350
|
+
err
|
|
1351
|
+
);
|
|
1352
|
+
}
|
|
1295
1353
|
throw new OfframpError(
|
|
1296
1354
|
"Payee registration failed",
|
|
1297
1355
|
"REGISTRATION_FAILED",
|
|
@@ -1685,8 +1743,129 @@ function useOfframp(defaultOptions = {}) {
|
|
|
1685
1743
|
reset
|
|
1686
1744
|
};
|
|
1687
1745
|
}
|
|
1746
|
+
|
|
1747
|
+
// src/hooks/usePeerExtensionRegistration.ts
|
|
1748
|
+
var import_react2 = require("react");
|
|
1749
|
+
|
|
1750
|
+
// src/extension.ts
|
|
1751
|
+
var import_sdk7 = require("@zkp2p/sdk");
|
|
1752
|
+
|
|
1753
|
+
// src/hooks/usePeerExtensionRegistration.ts
|
|
1754
|
+
function usePeerExtensionRegistration(platform) {
|
|
1755
|
+
const info = platform ? getPeerExtensionRegistrationInfo(platform.id) : null;
|
|
1756
|
+
const [phase, setPhase] = (0, import_react2.useState)(
|
|
1757
|
+
info ? "checking" : "unsupported"
|
|
1758
|
+
);
|
|
1759
|
+
const [busy, setBusy] = (0, import_react2.useState)(false);
|
|
1760
|
+
const [error, setError] = (0, import_react2.useState)(null);
|
|
1761
|
+
const mountedRef = (0, import_react2.useRef)(true);
|
|
1762
|
+
const providerId = info?.providerId ?? null;
|
|
1763
|
+
const refresh = (0, import_react2.useCallback)(async () => {
|
|
1764
|
+
if (!providerId) {
|
|
1765
|
+
setPhase("unsupported");
|
|
1766
|
+
return;
|
|
1767
|
+
}
|
|
1768
|
+
try {
|
|
1769
|
+
const state = await import_sdk7.peerExtensionSdk.getState();
|
|
1770
|
+
if (!mountedRef.current) return;
|
|
1771
|
+
setPhase(mapSdkState(state));
|
|
1772
|
+
} catch {
|
|
1773
|
+
if (!mountedRef.current) return;
|
|
1774
|
+
setPhase("needs_install");
|
|
1775
|
+
}
|
|
1776
|
+
}, [providerId]);
|
|
1777
|
+
(0, import_react2.useEffect)(() => {
|
|
1778
|
+
mountedRef.current = true;
|
|
1779
|
+
setError(null);
|
|
1780
|
+
setBusy(false);
|
|
1781
|
+
if (!providerId) {
|
|
1782
|
+
setPhase("unsupported");
|
|
1783
|
+
} else {
|
|
1784
|
+
setPhase("checking");
|
|
1785
|
+
refresh();
|
|
1786
|
+
}
|
|
1787
|
+
return () => {
|
|
1788
|
+
mountedRef.current = false;
|
|
1789
|
+
};
|
|
1790
|
+
}, [providerId, refresh]);
|
|
1791
|
+
const installExtension = (0, import_react2.useCallback)(() => {
|
|
1792
|
+
setError(null);
|
|
1793
|
+
try {
|
|
1794
|
+
import_sdk7.peerExtensionSdk.openInstallPage();
|
|
1795
|
+
} catch {
|
|
1796
|
+
if (typeof window !== "undefined") {
|
|
1797
|
+
window.open(import_sdk7.PEER_EXTENSION_CHROME_URL, "_blank", "noopener,noreferrer");
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
}, []);
|
|
1801
|
+
const connectExtension = (0, import_react2.useCallback)(async () => {
|
|
1802
|
+
if (!providerId) return false;
|
|
1803
|
+
setError(null);
|
|
1804
|
+
setBusy(true);
|
|
1805
|
+
try {
|
|
1806
|
+
const approved = await import_sdk7.peerExtensionSdk.requestConnection();
|
|
1807
|
+
if (!mountedRef.current) return approved;
|
|
1808
|
+
if (approved) {
|
|
1809
|
+
setPhase("ready");
|
|
1810
|
+
import_sdk7.peerExtensionSdk.openSidebar(`/verify/${providerId}`);
|
|
1811
|
+
} else {
|
|
1812
|
+
setError("Connection was not approved. Try again once you've approved Peer.");
|
|
1813
|
+
}
|
|
1814
|
+
return approved;
|
|
1815
|
+
} catch (err) {
|
|
1816
|
+
if (!mountedRef.current) return false;
|
|
1817
|
+
setError(
|
|
1818
|
+
err instanceof Error ? err.message : "Couldn't request a Peer extension connection. Make sure Peer is installed and enabled."
|
|
1819
|
+
);
|
|
1820
|
+
refresh();
|
|
1821
|
+
return false;
|
|
1822
|
+
} finally {
|
|
1823
|
+
if (mountedRef.current) setBusy(false);
|
|
1824
|
+
}
|
|
1825
|
+
}, [providerId, refresh]);
|
|
1826
|
+
const openVerifySidebar = (0, import_react2.useCallback)(async () => {
|
|
1827
|
+
if (!providerId) return;
|
|
1828
|
+
setError(null);
|
|
1829
|
+
const state = await import_sdk7.peerExtensionSdk.getState().catch(() => "needs_install");
|
|
1830
|
+
if (!mountedRef.current) return;
|
|
1831
|
+
const nextPhase = mapSdkState(state);
|
|
1832
|
+
setPhase(nextPhase);
|
|
1833
|
+
if (nextPhase === "needs_install") {
|
|
1834
|
+
installExtension();
|
|
1835
|
+
return;
|
|
1836
|
+
}
|
|
1837
|
+
if (nextPhase === "needs_connection") {
|
|
1838
|
+
await connectExtension();
|
|
1839
|
+
return;
|
|
1840
|
+
}
|
|
1841
|
+
try {
|
|
1842
|
+
import_sdk7.peerExtensionSdk.openSidebar(`/verify/${providerId}`);
|
|
1843
|
+
} catch (err) {
|
|
1844
|
+
setError(
|
|
1845
|
+
err instanceof Error ? err.message : "Couldn't open the Peer extension. Make sure it's enabled."
|
|
1846
|
+
);
|
|
1847
|
+
refresh();
|
|
1848
|
+
}
|
|
1849
|
+
}, [connectExtension, installExtension, providerId, refresh]);
|
|
1850
|
+
return {
|
|
1851
|
+
phase,
|
|
1852
|
+
info,
|
|
1853
|
+
busy,
|
|
1854
|
+
error,
|
|
1855
|
+
refresh,
|
|
1856
|
+
installExtension,
|
|
1857
|
+
connectExtension,
|
|
1858
|
+
openVerifySidebar
|
|
1859
|
+
};
|
|
1860
|
+
}
|
|
1861
|
+
function mapSdkState(state) {
|
|
1862
|
+
if (state === "needs_install") return "needs_install";
|
|
1863
|
+
if (state === "needs_connection") return "needs_connection";
|
|
1864
|
+
return "ready";
|
|
1865
|
+
}
|
|
1688
1866
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1689
1867
|
0 && (module.exports = {
|
|
1690
|
-
useOfframp
|
|
1868
|
+
useOfframp,
|
|
1869
|
+
usePeerExtensionRegistration
|
|
1691
1870
|
});
|
|
1692
1871
|
//# sourceMappingURL=react.cjs.map
|