@usdctofiat/offramp 1.1.4 → 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.
- package/CHANGELOG.md +252 -0
- package/README.md +82 -2
- package/dist/{chunk-OJY6DE3I.js → chunk-HBR3Z6HX.js} +668 -248
- package/dist/chunk-HBR3Z6HX.js.map +1 -0
- package/dist/errors-Deoi_xYZ.d.cts +236 -0
- package/dist/errors-Deoi_xYZ.d.ts +236 -0
- package/dist/index.cjs +681 -248
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -5
- package/dist/index.d.ts +38 -5
- package/dist/index.js +55 -18
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +808 -277
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +90 -3
- package/dist/react.d.ts +90 -3
- package/dist/react.js +152 -14
- package/dist/react.js.map +1 -1
- package/package.json +18 -7
- package/dist/chunk-OJY6DE3I.js.map +0 -1
- package/dist/errors-Dtzrl98J.d.cts +0 -105
- package/dist/errors-Dtzrl98J.d.ts +0 -105
package/dist/react.cjs
CHANGED
|
@@ -20,20 +20,17 @@ 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
|
|
|
27
28
|
// src/hooks/useOfframp.ts
|
|
28
29
|
var import_react = require("react");
|
|
29
30
|
|
|
30
|
-
// src/deposit.ts
|
|
31
|
-
var import_viem3 = require("viem");
|
|
32
|
-
var import_chains3 = require("viem/chains");
|
|
33
|
-
var import_sdk5 = require("@zkp2p/sdk");
|
|
34
|
-
|
|
35
31
|
// src/config.ts
|
|
36
32
|
var import_sdk = require("@zkp2p/sdk");
|
|
33
|
+
var SDK_VERSION = "1.2.0";
|
|
37
34
|
var BASE_CHAIN_ID = 8453;
|
|
38
35
|
var RUNTIME_ENV = "production";
|
|
39
36
|
var API_BASE_URL = "https://api.zkp2p.xyz";
|
|
@@ -49,6 +46,7 @@ var GATING_SERVICE_ADDRESS = (0, import_sdk.getGatingServiceAddress)(
|
|
|
49
46
|
);
|
|
50
47
|
var DELEGATE_RATE_MANAGER_ID = "0x8666d6fb0f6797c56e95339fd7ca82fdd348b9db200e10a4c4aa0a0b879fc41c";
|
|
51
48
|
var RATE_MANAGER_REGISTRY_ADDRESS = "0xeed7db23e724ac4590d6db6f78fda6db203535f3";
|
|
49
|
+
var DELEGATE_MANAGER_FEE_BPS = 10;
|
|
52
50
|
var REFERRER = "galleonlabs";
|
|
53
51
|
var MIN_DEPOSIT_USDC = 1;
|
|
54
52
|
var MIN_ORDER_USDC = 1;
|
|
@@ -57,10 +55,33 @@ var INDEXER_INITIAL_DELAY_MS = 1e3;
|
|
|
57
55
|
var INDEXER_MAX_DELAY_MS = 1e4;
|
|
58
56
|
var PAYEE_REGISTRATION_TIMEOUT_MS = 8e3;
|
|
59
57
|
|
|
60
|
-
// src/
|
|
58
|
+
// src/currencies.ts
|
|
61
59
|
var import_sdk2 = require("@zkp2p/sdk");
|
|
60
|
+
function buildCurrencies() {
|
|
61
|
+
const entries = {};
|
|
62
|
+
for (const [code, info] of Object.entries(
|
|
63
|
+
import_sdk2.currencyInfo
|
|
64
|
+
)) {
|
|
65
|
+
entries[code] = {
|
|
66
|
+
code: info.currencyCode ?? code,
|
|
67
|
+
name: info.currencyName ?? code,
|
|
68
|
+
symbol: info.currencySymbol ?? code,
|
|
69
|
+
countryCode: info.countryCode ?? ""
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return entries;
|
|
73
|
+
}
|
|
74
|
+
var CURRENCIES = buildCurrencies();
|
|
75
|
+
|
|
76
|
+
// src/deposit.ts
|
|
77
|
+
var import_viem3 = require("viem");
|
|
78
|
+
var import_chains3 = require("viem/chains");
|
|
79
|
+
var import_sdk6 = require("@zkp2p/sdk");
|
|
80
|
+
|
|
81
|
+
// src/platforms.ts
|
|
82
|
+
var import_sdk3 = require("@zkp2p/sdk");
|
|
62
83
|
var import_zod = require("zod");
|
|
63
|
-
var PAYMENT_CATALOG = (0,
|
|
84
|
+
var PAYMENT_CATALOG = (0, import_sdk3.getPaymentMethodsCatalog)(BASE_CHAIN_ID, RUNTIME_ENV);
|
|
64
85
|
var ZELLE_HASH_LOOKUP_NAMES = ["zelle", "zelle-bofa", "zelle-chase", "zelle-citi"];
|
|
65
86
|
var FALLBACK_CURRENCIES = {
|
|
66
87
|
venmo: ["USD"],
|
|
@@ -139,8 +160,8 @@ function gatherCatalogHashes(platform) {
|
|
|
139
160
|
function resolveSupportedCurrencies(platform) {
|
|
140
161
|
const codes = /* @__PURE__ */ new Set();
|
|
141
162
|
for (const hash of gatherCatalogHashes(platform)) {
|
|
142
|
-
const info = (0,
|
|
143
|
-
if (info?.currencyCode &&
|
|
163
|
+
const info = (0, import_sdk3.getCurrencyInfoFromHash)(hash);
|
|
164
|
+
if (info?.currencyCode && import_sdk3.currencyInfo[info.currencyCode]) {
|
|
144
165
|
codes.add(info.currencyCode);
|
|
145
166
|
}
|
|
146
167
|
}
|
|
@@ -149,6 +170,17 @@ function resolveSupportedCurrencies(platform) {
|
|
|
149
170
|
}
|
|
150
171
|
return Array.from(codes).sort();
|
|
151
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
|
+
}
|
|
152
184
|
var BLUEPRINTS = {
|
|
153
185
|
venmo: {
|
|
154
186
|
id: "venmo",
|
|
@@ -196,7 +228,13 @@ var BLUEPRINTS = {
|
|
|
196
228
|
placeholder: "wisetag (no @)",
|
|
197
229
|
helperText: "Your Wise @wisetag (no @)",
|
|
198
230
|
validation: import_zod.z.string().min(1).regex(/^[a-zA-Z0-9_-]+$/),
|
|
199
|
-
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
|
+
}
|
|
200
238
|
},
|
|
201
239
|
mercadopago: {
|
|
202
240
|
id: "mercadopago",
|
|
@@ -217,10 +255,18 @@ var BLUEPRINTS = {
|
|
|
217
255
|
paypal: {
|
|
218
256
|
id: "paypal",
|
|
219
257
|
name: "PayPal",
|
|
220
|
-
identifierLabel: "
|
|
221
|
-
placeholder: "
|
|
222
|
-
helperText: "
|
|
223
|
-
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
|
+
}
|
|
224
270
|
},
|
|
225
271
|
monzo: {
|
|
226
272
|
id: "monzo",
|
|
@@ -251,6 +297,7 @@ function buildPlatformEntry(bp) {
|
|
|
251
297
|
placeholder: bp.placeholder,
|
|
252
298
|
help: bp.helperText
|
|
253
299
|
},
|
|
300
|
+
...bp.extensionRegistration ? { extensionRegistration: bp.extensionRegistration } : {},
|
|
254
301
|
validate(input) {
|
|
255
302
|
const transformed = bp.transform ? bp.transform(input) : input;
|
|
256
303
|
const result = bp.validation.safeParse(transformed);
|
|
@@ -277,6 +324,9 @@ var PLATFORMS = {
|
|
|
277
324
|
MONZO: buildPlatformEntry(BLUEPRINTS.monzo),
|
|
278
325
|
N26: buildPlatformEntry(BLUEPRINTS.n26)
|
|
279
326
|
};
|
|
327
|
+
function getPlatformById(id) {
|
|
328
|
+
return Object.values(PLATFORMS).find((p) => p.id === id) ?? null;
|
|
329
|
+
}
|
|
280
330
|
function normalizePaymentMethodLookupName(platform) {
|
|
281
331
|
const normalized = platform.trim().toLowerCase();
|
|
282
332
|
if (!normalized) return null;
|
|
@@ -300,7 +350,7 @@ function getPaymentMethodHash(platform) {
|
|
|
300
350
|
const catalogEntry = PAYMENT_CATALOG[name];
|
|
301
351
|
if (catalogEntry?.paymentMethodHash) return catalogEntry.paymentMethodHash;
|
|
302
352
|
if (name === "zelle" || name.startsWith("zelle-")) return resolveCanonicalZelleHash();
|
|
303
|
-
const sdkHash = (0,
|
|
353
|
+
const sdkHash = (0, import_sdk3.resolvePaymentMethodHash)(name);
|
|
304
354
|
return sdkHash ? sdkHash : null;
|
|
305
355
|
}
|
|
306
356
|
function getPaymentMethodHashes(platform) {
|
|
@@ -309,7 +359,7 @@ function getPaymentMethodHashes(platform) {
|
|
|
309
359
|
return hash ? [hash] : [];
|
|
310
360
|
}
|
|
311
361
|
const hashes = /* @__PURE__ */ new Set();
|
|
312
|
-
const generic = (0,
|
|
362
|
+
const generic = (0, import_sdk3.resolvePaymentMethodHash)("zelle");
|
|
313
363
|
if (generic) hashes.add(generic);
|
|
314
364
|
const canonical = resolveCanonicalZelleHash();
|
|
315
365
|
if (canonical) hashes.add(canonical);
|
|
@@ -320,34 +370,37 @@ function getPaymentMethodHashes(platform) {
|
|
|
320
370
|
}
|
|
321
371
|
return Array.from(hashes);
|
|
322
372
|
}
|
|
323
|
-
function buildDepositData(platform, identifier) {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
case "monzo":
|
|
342
|
-
return { monzoMeUsername: identifier, telegramUsername: "" };
|
|
343
|
-
case "n26":
|
|
344
|
-
return { iban: identifier, telegramUsername: "" };
|
|
345
|
-
default:
|
|
346
|
-
return { identifier, telegramUsername: "" };
|
|
347
|
-
}
|
|
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
|
+
const normalized = (message ?? "").trim();
|
|
386
|
+
if (normalized === info.requiredPrompt) return true;
|
|
387
|
+
if (statusCode === 400) return true;
|
|
388
|
+
if (!normalized) return false;
|
|
389
|
+
const lower = normalized.toLowerCase();
|
|
390
|
+
return EXTENSION_REGISTRATION_ERROR_PATTERNS.some((p) => lower.includes(p));
|
|
348
391
|
}
|
|
349
392
|
|
|
350
393
|
// src/errors.ts
|
|
394
|
+
var MakersCreateError = class extends Error {
|
|
395
|
+
status;
|
|
396
|
+
body;
|
|
397
|
+
constructor(message, status, body) {
|
|
398
|
+
super(message);
|
|
399
|
+
this.name = "MakersCreateError";
|
|
400
|
+
this.status = status;
|
|
401
|
+
this.body = body;
|
|
402
|
+
}
|
|
403
|
+
};
|
|
351
404
|
var OfframpError = class extends Error {
|
|
352
405
|
code;
|
|
353
406
|
step;
|
|
@@ -718,9 +771,9 @@ var WhitelistPreIntentHook_default = [
|
|
|
718
771
|
];
|
|
719
772
|
|
|
720
773
|
// src/sdk-client.ts
|
|
721
|
-
var
|
|
774
|
+
var import_sdk4 = require("@zkp2p/sdk");
|
|
722
775
|
function createSdkClient(walletClient) {
|
|
723
|
-
return new
|
|
776
|
+
return new import_sdk4.OfframpClient({
|
|
724
777
|
walletClient,
|
|
725
778
|
chainId: BASE_CHAIN_ID,
|
|
726
779
|
runtimeEnv: RUNTIME_ENV,
|
|
@@ -809,13 +862,13 @@ async function readIsWhitelisted(escrow, depositId, taker) {
|
|
|
809
862
|
// src/queries.ts
|
|
810
863
|
var import_viem2 = require("viem");
|
|
811
864
|
var import_chains2 = require("viem/chains");
|
|
812
|
-
var
|
|
865
|
+
var import_sdk5 = require("@zkp2p/sdk");
|
|
813
866
|
var indexerService = null;
|
|
814
867
|
function getIndexerService() {
|
|
815
868
|
if (!indexerService) {
|
|
816
|
-
const endpoint = (0,
|
|
817
|
-
const client = new
|
|
818
|
-
indexerService = new
|
|
869
|
+
const endpoint = (0, import_sdk5.defaultIndexerEndpoint)("PRODUCTION");
|
|
870
|
+
const client = new import_sdk5.IndexerClient(endpoint);
|
|
871
|
+
indexerService = new import_sdk5.IndexerDepositService(client);
|
|
819
872
|
}
|
|
820
873
|
return indexerService;
|
|
821
874
|
}
|
|
@@ -849,7 +902,7 @@ function resolveMethodNames(hashes) {
|
|
|
849
902
|
return Array.from(names);
|
|
850
903
|
}
|
|
851
904
|
function mapDeposit(d) {
|
|
852
|
-
const delegationState = (0,
|
|
905
|
+
const delegationState = (0, import_sdk5.classifyDelegationState)(
|
|
853
906
|
d.rateManagerId ?? void 0,
|
|
854
907
|
d.rateManagerAddress ?? void 0,
|
|
855
908
|
DELEGATE_RATE_MANAGER_ID,
|
|
@@ -866,7 +919,7 @@ function mapDeposit(d) {
|
|
|
866
919
|
fulfilledIntents: d.fulfilledIntents ?? 0,
|
|
867
920
|
paymentMethods: resolveMethodNames(d.paymentMethods),
|
|
868
921
|
currencies: d.currencies.map((c) => {
|
|
869
|
-
const info = (0,
|
|
922
|
+
const info = (0, import_sdk5.getCurrencyInfoFromHash)(c.currencyCode);
|
|
870
923
|
return info?.currencyCode ?? c.currencyCode;
|
|
871
924
|
}),
|
|
872
925
|
rateSource: d.currencies[0]?.rateSource || "unknown",
|
|
@@ -905,6 +958,105 @@ async function close(walletClient, depositId, escrowAddress) {
|
|
|
905
958
|
return extractTxHash(result);
|
|
906
959
|
}
|
|
907
960
|
|
|
961
|
+
// src/telemetry.ts
|
|
962
|
+
var SDK_EVENTS_ENDPOINT = "https://usdctofiat.xyz/api/sdk-events";
|
|
963
|
+
var MAX_BATCH_SIZE = 50;
|
|
964
|
+
var FLUSH_DELAY_MS = 180;
|
|
965
|
+
var TELEMETRY_TIMEOUT_MS = 2e3;
|
|
966
|
+
var queuedEvents = [];
|
|
967
|
+
var flushTimer = null;
|
|
968
|
+
var flushInFlight = false;
|
|
969
|
+
function sanitizeAttributionId(raw) {
|
|
970
|
+
if (typeof raw !== "string") return void 0;
|
|
971
|
+
const stripped = raw.trim().replace(/[^a-zA-Z0-9_-]/g, "");
|
|
972
|
+
if (!stripped) return void 0;
|
|
973
|
+
if (stripped.length > 64) return void 0;
|
|
974
|
+
return stripped;
|
|
975
|
+
}
|
|
976
|
+
function scheduleFlush() {
|
|
977
|
+
if (flushTimer != null) return;
|
|
978
|
+
flushTimer = setTimeout(() => {
|
|
979
|
+
flushTimer = null;
|
|
980
|
+
void flushQueue();
|
|
981
|
+
}, FLUSH_DELAY_MS);
|
|
982
|
+
}
|
|
983
|
+
async function postBatch(batch) {
|
|
984
|
+
if (!batch.length) return;
|
|
985
|
+
const body = JSON.stringify(batch);
|
|
986
|
+
try {
|
|
987
|
+
if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
|
|
988
|
+
const blob = new Blob([body], { type: "application/json" });
|
|
989
|
+
const accepted = navigator.sendBeacon(SDK_EVENTS_ENDPOINT, blob);
|
|
990
|
+
if (accepted) return;
|
|
991
|
+
}
|
|
992
|
+
} catch {
|
|
993
|
+
}
|
|
994
|
+
try {
|
|
995
|
+
const controller = typeof AbortController !== "undefined" ? new AbortController() : null;
|
|
996
|
+
const timeout = controller ? setTimeout(() => controller.abort(), TELEMETRY_TIMEOUT_MS) : null;
|
|
997
|
+
await fetch(SDK_EVENTS_ENDPOINT, {
|
|
998
|
+
method: "POST",
|
|
999
|
+
headers: { "Content-Type": "application/json" },
|
|
1000
|
+
body,
|
|
1001
|
+
keepalive: true,
|
|
1002
|
+
signal: controller?.signal
|
|
1003
|
+
}).catch(() => {
|
|
1004
|
+
});
|
|
1005
|
+
if (timeout) clearTimeout(timeout);
|
|
1006
|
+
} catch {
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
async function flushQueue() {
|
|
1010
|
+
if (flushInFlight) return;
|
|
1011
|
+
if (!queuedEvents.length) return;
|
|
1012
|
+
flushInFlight = true;
|
|
1013
|
+
try {
|
|
1014
|
+
while (queuedEvents.length > 0) {
|
|
1015
|
+
const batch = queuedEvents.slice(0, MAX_BATCH_SIZE);
|
|
1016
|
+
queuedEvents = queuedEvents.slice(batch.length);
|
|
1017
|
+
await postBatch(batch);
|
|
1018
|
+
}
|
|
1019
|
+
} finally {
|
|
1020
|
+
flushInFlight = false;
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
function emitEvent(name, payload) {
|
|
1024
|
+
try {
|
|
1025
|
+
queuedEvents.push({
|
|
1026
|
+
name,
|
|
1027
|
+
payload,
|
|
1028
|
+
ts: Date.now()
|
|
1029
|
+
});
|
|
1030
|
+
if (queuedEvents.length >= MAX_BATCH_SIZE) {
|
|
1031
|
+
void flushQueue();
|
|
1032
|
+
return;
|
|
1033
|
+
}
|
|
1034
|
+
scheduleFlush();
|
|
1035
|
+
} catch {
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
function createTelemetryContext(options) {
|
|
1039
|
+
const integratorId = sanitizeAttributionId(options.integratorId);
|
|
1040
|
+
const referralId = sanitizeAttributionId(options.referralId);
|
|
1041
|
+
const enabled = options.telemetry !== false;
|
|
1042
|
+
const sdkVersion = options.sdkVersion;
|
|
1043
|
+
return {
|
|
1044
|
+
enabled,
|
|
1045
|
+
sdkVersion,
|
|
1046
|
+
integratorId,
|
|
1047
|
+
referralId,
|
|
1048
|
+
emit(name, payload = {}) {
|
|
1049
|
+
if (!enabled) return;
|
|
1050
|
+
emitEvent(name, {
|
|
1051
|
+
sdkVersion,
|
|
1052
|
+
integratorId,
|
|
1053
|
+
referralId,
|
|
1054
|
+
...payload
|
|
1055
|
+
});
|
|
1056
|
+
}
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
|
|
908
1060
|
// src/deposit.ts
|
|
909
1061
|
function usdcToUnits(amount) {
|
|
910
1062
|
return (0, import_viem3.parseUnits)(amount, 6);
|
|
@@ -950,23 +1102,39 @@ function extractDepositIdFromLogs(logs) {
|
|
|
950
1102
|
}
|
|
951
1103
|
return null;
|
|
952
1104
|
}
|
|
953
|
-
async function registerPayeeDetails(processorName,
|
|
1105
|
+
async function registerPayeeDetails(processorName, payload) {
|
|
954
1106
|
const controller = new AbortController();
|
|
955
1107
|
const timeout = setTimeout(() => controller.abort(), PAYEE_REGISTRATION_TIMEOUT_MS);
|
|
956
1108
|
try {
|
|
957
|
-
const res = await fetch(`${API_BASE_URL}/
|
|
1109
|
+
const res = await fetch(`${API_BASE_URL}/v2/makers/create`, {
|
|
958
1110
|
method: "POST",
|
|
959
1111
|
headers: { "Content-Type": "application/json" },
|
|
960
|
-
body: JSON.stringify({ processorName,
|
|
1112
|
+
body: JSON.stringify({ processorName, ...payload }),
|
|
961
1113
|
signal: controller.signal
|
|
962
1114
|
});
|
|
963
1115
|
if (!res.ok) {
|
|
964
1116
|
const txt = await res.text().catch(() => "");
|
|
965
|
-
|
|
1117
|
+
let detail = txt || res.statusText;
|
|
1118
|
+
try {
|
|
1119
|
+
const parsed = JSON.parse(txt);
|
|
1120
|
+
if (typeof parsed.message === "string" && parsed.message.trim()) {
|
|
1121
|
+
detail = parsed.message;
|
|
1122
|
+
}
|
|
1123
|
+
} catch {
|
|
1124
|
+
}
|
|
1125
|
+
throw new MakersCreateError(
|
|
1126
|
+
`makers/create failed (${res.status}): ${detail}`,
|
|
1127
|
+
res.status,
|
|
1128
|
+
txt
|
|
1129
|
+
);
|
|
966
1130
|
}
|
|
967
1131
|
const json = await res.json();
|
|
968
1132
|
if (!json.success || !json.responseObject?.hashedOnchainId) {
|
|
969
|
-
throw new
|
|
1133
|
+
throw new MakersCreateError(
|
|
1134
|
+
json.message || "makers/create returned no hashedOnchainId",
|
|
1135
|
+
json.statusCode ?? null,
|
|
1136
|
+
""
|
|
1137
|
+
);
|
|
970
1138
|
}
|
|
971
1139
|
return json.responseObject.hashedOnchainId;
|
|
972
1140
|
} finally {
|
|
@@ -978,7 +1146,7 @@ function attachOracleConfig(entries, conversionRates) {
|
|
|
978
1146
|
(group, gi) => group.map((entry, ci) => {
|
|
979
1147
|
const currency = conversionRates[gi]?.[ci]?.currency;
|
|
980
1148
|
if (!currency) return entry;
|
|
981
|
-
const oracleConfig = (0,
|
|
1149
|
+
const oracleConfig = (0, import_sdk6.getSpreadOracleConfig)(currency);
|
|
982
1150
|
if (!oracleConfig) return entry;
|
|
983
1151
|
return {
|
|
984
1152
|
...entry,
|
|
@@ -1022,271 +1190,501 @@ async function findUndelegatedDeposit(walletAddress) {
|
|
|
1022
1190
|
if (remaining === 0n) return false;
|
|
1023
1191
|
return (d.rateManagerId ?? "").toLowerCase() !== delegateIdLower;
|
|
1024
1192
|
});
|
|
1025
|
-
undelegated.sort((a, b) =>
|
|
1193
|
+
undelegated.sort((a, b) => {
|
|
1194
|
+
const left = BigInt(a.depositId);
|
|
1195
|
+
const right = BigInt(b.depositId);
|
|
1196
|
+
if (left === right) return 0;
|
|
1197
|
+
return left > right ? -1 : 1;
|
|
1198
|
+
});
|
|
1026
1199
|
return undelegated[0] ?? null;
|
|
1027
1200
|
} catch {
|
|
1028
1201
|
return null;
|
|
1029
1202
|
}
|
|
1030
1203
|
}
|
|
1031
|
-
async function offramp(walletClient, params, onProgress) {
|
|
1204
|
+
async function offramp(walletClient, params, onProgress, telemetryContext) {
|
|
1032
1205
|
const { amount, platform, currency, identifier } = params;
|
|
1033
1206
|
const platformId = platform.id;
|
|
1034
1207
|
const currencyCode = currency.code;
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1208
|
+
const telemetry = telemetryContext ?? createTelemetryContext({
|
|
1209
|
+
sdkVersion: SDK_VERSION,
|
|
1210
|
+
telemetry: true,
|
|
1211
|
+
integratorId: params.integratorId,
|
|
1212
|
+
referralId: params.referralId
|
|
1213
|
+
});
|
|
1214
|
+
const flowStartMs = Date.now();
|
|
1215
|
+
const emitProgress = (progress) => {
|
|
1216
|
+
onProgress?.(progress);
|
|
1217
|
+
telemetry.emit("sdk.createDeposit.progress", {
|
|
1218
|
+
step: progress.step,
|
|
1219
|
+
txHash: progress.txHash
|
|
1220
|
+
});
|
|
1221
|
+
};
|
|
1222
|
+
try {
|
|
1223
|
+
if (!walletClient.account?.address) {
|
|
1224
|
+
throw new OfframpError("Wallet client has no account. Connect a wallet first.", "VALIDATION");
|
|
1225
|
+
}
|
|
1226
|
+
const walletAddress = walletClient.account.address.toLowerCase();
|
|
1227
|
+
telemetry.emit("sdk.createDeposit.start", {
|
|
1228
|
+
platform: platformId,
|
|
1229
|
+
currency: currencyCode,
|
|
1230
|
+
amount,
|
|
1231
|
+
wallet: walletAddress
|
|
1232
|
+
});
|
|
1233
|
+
const amt = parseFloat(amount);
|
|
1234
|
+
if (!Number.isFinite(amt) || amt < MIN_DEPOSIT_USDC) {
|
|
1235
|
+
throw new OfframpError(`Minimum deposit is ${MIN_DEPOSIT_USDC} USDC`, "VALIDATION");
|
|
1236
|
+
}
|
|
1237
|
+
if (!platform.currencies.includes(currencyCode)) {
|
|
1238
|
+
throw new OfframpError(`${currencyCode} is not supported on ${platform.name}`, "UNSUPPORTED");
|
|
1239
|
+
}
|
|
1240
|
+
const validation = platform.validate(identifier);
|
|
1241
|
+
if (!validation.valid) {
|
|
1242
|
+
throw new OfframpError(validation.error || "Invalid identifier", "VALIDATION");
|
|
1243
|
+
}
|
|
1244
|
+
const normalizedIdentifier = validation.normalized;
|
|
1245
|
+
const methodHash = getPaymentMethodHash(platformId);
|
|
1246
|
+
if (!methodHash) {
|
|
1247
|
+
throw new OfframpError(`${platform.name} is not currently supported`, "UNSUPPORTED");
|
|
1248
|
+
}
|
|
1249
|
+
const existing = await findUndelegatedDeposit(walletAddress);
|
|
1250
|
+
if (existing) {
|
|
1251
|
+
emitProgress({ step: "resuming", depositId: existing.depositId });
|
|
1252
|
+
const client2 = createSdkClient(walletClient);
|
|
1253
|
+
const txOverrides2 = { referrer: [REFERRER] };
|
|
1254
|
+
try {
|
|
1255
|
+
const result2 = await client2.setRateManager({
|
|
1256
|
+
depositId: BigInt(existing.depositId),
|
|
1257
|
+
rateManagerAddress: RATE_MANAGER_REGISTRY_ADDRESS,
|
|
1258
|
+
rateManagerId: DELEGATE_RATE_MANAGER_ID,
|
|
1259
|
+
escrowAddress: existing.escrowAddress,
|
|
1260
|
+
txOverrides: txOverrides2
|
|
1261
|
+
});
|
|
1262
|
+
const txHash = extractTxHash2(result2);
|
|
1263
|
+
emitProgress({ step: "done", txHash, depositId: existing.depositId });
|
|
1264
|
+
const resumedResult = { depositId: existing.depositId, txHash, resumed: true };
|
|
1265
|
+
telemetry.emit("sdk.createDeposit.success", {
|
|
1266
|
+
depositId: resumedResult.depositId,
|
|
1267
|
+
txHash: resumedResult.txHash,
|
|
1268
|
+
wallet: walletAddress,
|
|
1269
|
+
resumed: true,
|
|
1270
|
+
wallDurationMs: Date.now() - flowStartMs
|
|
1271
|
+
});
|
|
1272
|
+
return resumedResult;
|
|
1273
|
+
} catch (err) {
|
|
1274
|
+
if (isUserCancellation(err))
|
|
1275
|
+
throw new OfframpError("User cancelled", "USER_CANCELLED", "resuming", err);
|
|
1276
|
+
throw new OfframpError(
|
|
1277
|
+
"Found undelegated deposit but delegation failed. Try again.",
|
|
1278
|
+
"DELEGATION_FAILED",
|
|
1279
|
+
"resuming",
|
|
1280
|
+
err,
|
|
1281
|
+
{ depositId: existing.depositId, txHash: existing.txHash }
|
|
1282
|
+
);
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
const truncatedAmount = amt.toFixed(6).replace(/\.?0+$/, "");
|
|
1286
|
+
const amountUnits = usdcToUnits(truncatedAmount);
|
|
1287
|
+
const minUnits = usdcToUnits(String(MIN_ORDER_USDC));
|
|
1288
|
+
const maxUnits = usdcToUnits(String(Math.min(amt, 2500)));
|
|
1060
1289
|
try {
|
|
1061
|
-
const
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1290
|
+
const publicClient = (0, import_viem3.createPublicClient)({ chain: import_chains3.base, transport: (0, import_viem3.http)(BASE_RPC_URL) });
|
|
1291
|
+
const balance = await publicClient.readContract({
|
|
1292
|
+
address: USDC_ADDRESS,
|
|
1293
|
+
abi: [
|
|
1294
|
+
{
|
|
1295
|
+
name: "balanceOf",
|
|
1296
|
+
type: "function",
|
|
1297
|
+
stateMutability: "view",
|
|
1298
|
+
inputs: [{ name: "account", type: "address" }],
|
|
1299
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
1300
|
+
}
|
|
1301
|
+
],
|
|
1302
|
+
functionName: "balanceOf",
|
|
1303
|
+
args: [walletAddress]
|
|
1304
|
+
});
|
|
1305
|
+
if (balance < amountUnits) {
|
|
1306
|
+
const available = Number((0, import_viem3.formatUnits)(balance, 6));
|
|
1307
|
+
throw new OfframpError(
|
|
1308
|
+
`Insufficient USDC balance. Have ${available.toFixed(2)}, need ${truncatedAmount}.`,
|
|
1309
|
+
"VALIDATION"
|
|
1310
|
+
);
|
|
1311
|
+
}
|
|
1312
|
+
} catch (err) {
|
|
1313
|
+
if (err instanceof OfframpError) throw err;
|
|
1314
|
+
}
|
|
1315
|
+
const client = createSdkClient(walletClient);
|
|
1316
|
+
const txOverrides = { referrer: [REFERRER] };
|
|
1317
|
+
emitProgress({ step: "approving" });
|
|
1318
|
+
try {
|
|
1319
|
+
await client.ensureAllowance({
|
|
1320
|
+
token: USDC_ADDRESS,
|
|
1321
|
+
amount: amountUnits,
|
|
1322
|
+
escrowAddress: ESCROW_ADDRESS,
|
|
1323
|
+
maxApprove: false,
|
|
1324
|
+
txOverrides
|
|
1067
1325
|
});
|
|
1068
|
-
const txHash = extractTxHash2(result);
|
|
1069
|
-
onProgress?.({ step: "done", txHash, depositId: existing.depositId });
|
|
1070
|
-
return { depositId: existing.depositId, txHash, resumed: true };
|
|
1071
1326
|
} catch (err) {
|
|
1072
1327
|
if (isUserCancellation(err))
|
|
1073
|
-
throw new OfframpError("User cancelled", "USER_CANCELLED", "
|
|
1328
|
+
throw new OfframpError("User cancelled", "USER_CANCELLED", "approving", err);
|
|
1329
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
1074
1330
|
throw new OfframpError(
|
|
1075
|
-
|
|
1076
|
-
"
|
|
1077
|
-
"
|
|
1078
|
-
err
|
|
1079
|
-
{ depositId: existing.depositId, txHash: existing.txHash }
|
|
1331
|
+
`USDC approval failed: ${detail}`,
|
|
1332
|
+
"APPROVAL_FAILED",
|
|
1333
|
+
"approving",
|
|
1334
|
+
err
|
|
1080
1335
|
);
|
|
1081
1336
|
}
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
name
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
],
|
|
1100
|
-
functionName: "balanceOf",
|
|
1101
|
-
args: [walletAddress]
|
|
1102
|
-
});
|
|
1103
|
-
if (balance < amountUnits) {
|
|
1104
|
-
const available = Number((0, import_viem3.formatUnits)(balance, 6));
|
|
1337
|
+
emitProgress({ step: "registering" });
|
|
1338
|
+
let hashedOnchainId;
|
|
1339
|
+
const canonicalName = platformId.startsWith("zelle") ? "zelle" : platformId;
|
|
1340
|
+
try {
|
|
1341
|
+
const payeePayload = buildDepositData(canonicalName, normalizedIdentifier);
|
|
1342
|
+
hashedOnchainId = await registerPayeeDetails(canonicalName, payeePayload);
|
|
1343
|
+
} catch (err) {
|
|
1344
|
+
const status = err instanceof MakersCreateError ? err.status : null;
|
|
1345
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1346
|
+
if (isPeerExtensionRegistrationError(canonicalName, message, status)) {
|
|
1347
|
+
throw new OfframpError(
|
|
1348
|
+
`${platform.name} maker is not yet registered in the Peer extension. Verify this handle in the extension, then retry.`,
|
|
1349
|
+
"EXTENSION_REGISTRATION_REQUIRED",
|
|
1350
|
+
"registering",
|
|
1351
|
+
err
|
|
1352
|
+
);
|
|
1353
|
+
}
|
|
1105
1354
|
throw new OfframpError(
|
|
1106
|
-
|
|
1107
|
-
"
|
|
1355
|
+
"Payee registration failed",
|
|
1356
|
+
"REGISTRATION_FAILED",
|
|
1357
|
+
"registering",
|
|
1358
|
+
err
|
|
1108
1359
|
);
|
|
1109
1360
|
}
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
await client.ensureAllowance({
|
|
1118
|
-
token: USDC_ADDRESS,
|
|
1119
|
-
amount: amountUnits,
|
|
1120
|
-
escrowAddress: ESCROW_ADDRESS,
|
|
1121
|
-
maxApprove: false,
|
|
1122
|
-
txOverrides
|
|
1123
|
-
});
|
|
1124
|
-
} catch (err) {
|
|
1125
|
-
if (isUserCancellation(err))
|
|
1126
|
-
throw new OfframpError("User cancelled", "USER_CANCELLED", "approving", err);
|
|
1127
|
-
const detail = err instanceof Error ? err.message : String(err);
|
|
1128
|
-
throw new OfframpError(`USDC approval failed: ${detail}`, "APPROVAL_FAILED", "approving", err);
|
|
1129
|
-
}
|
|
1130
|
-
onProgress?.({ step: "registering" });
|
|
1131
|
-
let hashedOnchainId;
|
|
1132
|
-
try {
|
|
1133
|
-
const canonicalName = platformId.startsWith("zelle") ? "zelle" : platformId;
|
|
1134
|
-
const depositData = buildDepositData(platformId, normalizedIdentifier);
|
|
1135
|
-
hashedOnchainId = await registerPayeeDetails(canonicalName, depositData);
|
|
1136
|
-
} catch (err) {
|
|
1137
|
-
throw new OfframpError("Payee registration failed", "REGISTRATION_FAILED", "registering", err);
|
|
1138
|
-
}
|
|
1139
|
-
onProgress?.({ step: "depositing" });
|
|
1140
|
-
const conversionRates = [
|
|
1141
|
-
[{ currency: currencyCode, conversionRate: "1" }]
|
|
1142
|
-
];
|
|
1143
|
-
const baseCurrenciesOverride = (0, import_sdk5.mapConversionRatesToOnchainMinRate)(conversionRates, 1);
|
|
1144
|
-
const currenciesOverride = attachOracleConfig(baseCurrenciesOverride, conversionRates);
|
|
1145
|
-
let hash;
|
|
1146
|
-
try {
|
|
1147
|
-
const result = await client.createDeposit({
|
|
1148
|
-
token: USDC_ADDRESS,
|
|
1149
|
-
amount: amountUnits,
|
|
1150
|
-
retainOnEmpty: false,
|
|
1151
|
-
intentAmountRange: { min: minUnits, max: maxUnits },
|
|
1152
|
-
processorNames: [platformId],
|
|
1153
|
-
conversionRates,
|
|
1154
|
-
payeeDetailsHashes: [hashedOnchainId],
|
|
1155
|
-
paymentMethodsOverride: [methodHash],
|
|
1156
|
-
paymentMethodDataOverride: [
|
|
1157
|
-
{
|
|
1158
|
-
intentGatingService: GATING_SERVICE_ADDRESS,
|
|
1159
|
-
payeeDetails: hashedOnchainId,
|
|
1160
|
-
data: "0x"
|
|
1161
|
-
}
|
|
1162
|
-
],
|
|
1163
|
-
currenciesOverride,
|
|
1164
|
-
escrowAddress: ESCROW_ADDRESS,
|
|
1165
|
-
txOverrides
|
|
1166
|
-
});
|
|
1167
|
-
if (!result?.hash) throw new Error("No transaction hash returned");
|
|
1168
|
-
hash = result.hash;
|
|
1169
|
-
} catch (err) {
|
|
1170
|
-
if (isUserCancellation(err))
|
|
1171
|
-
throw new OfframpError("User cancelled", "USER_CANCELLED", "depositing", err);
|
|
1172
|
-
const detail = err instanceof Error ? err.message : String(err);
|
|
1173
|
-
throw new OfframpError(
|
|
1174
|
-
`Deposit transaction failed: ${detail}`,
|
|
1175
|
-
"DEPOSIT_FAILED",
|
|
1176
|
-
"depositing",
|
|
1177
|
-
err
|
|
1178
|
-
);
|
|
1179
|
-
}
|
|
1180
|
-
onProgress?.({ step: "confirming", txHash: hash });
|
|
1181
|
-
let depositId = "";
|
|
1182
|
-
const receiptClient = client;
|
|
1183
|
-
if (typeof receiptClient.waitForTransactionReceipt === "function") {
|
|
1361
|
+
emitProgress({ step: "depositing" });
|
|
1362
|
+
const conversionRates = [
|
|
1363
|
+
[{ currency: currencyCode, conversionRate: "1" }]
|
|
1364
|
+
];
|
|
1365
|
+
const baseCurrenciesOverride = (0, import_sdk6.mapConversionRatesToOnchainMinRate)(conversionRates, 1);
|
|
1366
|
+
const currenciesOverride = attachOracleConfig(baseCurrenciesOverride, conversionRates);
|
|
1367
|
+
let hash;
|
|
1184
1368
|
try {
|
|
1185
|
-
const
|
|
1186
|
-
|
|
1187
|
-
|
|
1369
|
+
const result2 = await client.createDeposit({
|
|
1370
|
+
token: USDC_ADDRESS,
|
|
1371
|
+
amount: amountUnits,
|
|
1372
|
+
retainOnEmpty: false,
|
|
1373
|
+
intentAmountRange: { min: minUnits, max: maxUnits },
|
|
1374
|
+
processorNames: [platformId],
|
|
1375
|
+
conversionRates,
|
|
1376
|
+
payeeDetailsHashes: [hashedOnchainId],
|
|
1377
|
+
paymentMethodsOverride: [methodHash],
|
|
1378
|
+
paymentMethodDataOverride: [
|
|
1379
|
+
{
|
|
1380
|
+
intentGatingService: GATING_SERVICE_ADDRESS,
|
|
1381
|
+
payeeDetails: hashedOnchainId,
|
|
1382
|
+
data: "0x"
|
|
1383
|
+
}
|
|
1384
|
+
],
|
|
1385
|
+
currenciesOverride,
|
|
1386
|
+
escrowAddress: ESCROW_ADDRESS,
|
|
1387
|
+
txOverrides
|
|
1388
|
+
});
|
|
1389
|
+
if (!result2?.hash) throw new Error("No transaction hash returned");
|
|
1390
|
+
hash = result2.hash;
|
|
1391
|
+
} catch (err) {
|
|
1392
|
+
if (isUserCancellation(err))
|
|
1393
|
+
throw new OfframpError("User cancelled", "USER_CANCELLED", "depositing", err);
|
|
1394
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
1395
|
+
throw new OfframpError(
|
|
1396
|
+
`Deposit transaction failed: ${detail}`,
|
|
1397
|
+
"DEPOSIT_FAILED",
|
|
1398
|
+
"depositing",
|
|
1399
|
+
err
|
|
1400
|
+
);
|
|
1188
1401
|
}
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1402
|
+
emitProgress({ step: "confirming", txHash: hash });
|
|
1403
|
+
let depositId = "";
|
|
1404
|
+
const receiptClient = client;
|
|
1405
|
+
if (typeof receiptClient.waitForTransactionReceipt === "function") {
|
|
1193
1406
|
try {
|
|
1194
|
-
const
|
|
1195
|
-
|
|
1196
|
-
{ limit: 25 }
|
|
1197
|
-
);
|
|
1198
|
-
const hit = deps.find((d) => (d?.txHash || "").toLowerCase() === hash.toLowerCase());
|
|
1199
|
-
if (hit) {
|
|
1200
|
-
depositId = String(hit.depositId);
|
|
1201
|
-
break;
|
|
1202
|
-
}
|
|
1407
|
+
const receipt = await receiptClient.waitForTransactionReceipt({ hash, confirmations: 1 });
|
|
1408
|
+
depositId = extractDepositIdFromLogs(receipt.logs) || "";
|
|
1203
1409
|
} catch {
|
|
1204
1410
|
}
|
|
1205
|
-
await new Promise((r) => setTimeout(r, delay));
|
|
1206
|
-
delay = Math.min(INDEXER_MAX_DELAY_MS, Math.floor(delay * 1.7));
|
|
1207
1411
|
}
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
}
|
|
1227
|
-
|
|
1228
|
-
if (isUserCancellation(delegationError)) {
|
|
1412
|
+
if (!depositId) {
|
|
1413
|
+
let delay = INDEXER_INITIAL_DELAY_MS;
|
|
1414
|
+
for (let attempt = 0; attempt < INDEXER_MAX_ATTEMPTS && !depositId; attempt++) {
|
|
1415
|
+
try {
|
|
1416
|
+
const deps = await client.indexer.getDepositsWithRelations(
|
|
1417
|
+
{ depositor: walletAddress },
|
|
1418
|
+
{ limit: 25 }
|
|
1419
|
+
);
|
|
1420
|
+
const hit = deps.find((d) => (d?.txHash || "").toLowerCase() === hash.toLowerCase());
|
|
1421
|
+
if (hit) {
|
|
1422
|
+
depositId = String(hit.depositId);
|
|
1423
|
+
break;
|
|
1424
|
+
}
|
|
1425
|
+
} catch {
|
|
1426
|
+
}
|
|
1427
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
1428
|
+
delay = Math.min(INDEXER_MAX_DELAY_MS, Math.floor(delay * 1.7));
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
if (!depositId) {
|
|
1229
1432
|
throw new OfframpError(
|
|
1230
|
-
"
|
|
1231
|
-
"
|
|
1433
|
+
"Deposit created on-chain but could not confirm deposit ID. Your funds are safe. Call offramp() again to resume delegation.",
|
|
1434
|
+
"CONFIRMATION_FAILED",
|
|
1435
|
+
"confirming",
|
|
1436
|
+
void 0,
|
|
1437
|
+
{ txHash: hash }
|
|
1438
|
+
);
|
|
1439
|
+
}
|
|
1440
|
+
emitProgress({ step: "delegating", txHash: hash, depositId });
|
|
1441
|
+
try {
|
|
1442
|
+
await client.setRateManager({
|
|
1443
|
+
depositId: BigInt(depositId),
|
|
1444
|
+
rateManagerAddress: RATE_MANAGER_REGISTRY_ADDRESS,
|
|
1445
|
+
rateManagerId: DELEGATE_RATE_MANAGER_ID,
|
|
1446
|
+
escrowAddress: ESCROW_ADDRESS,
|
|
1447
|
+
txOverrides
|
|
1448
|
+
});
|
|
1449
|
+
} catch (delegationError) {
|
|
1450
|
+
if (isUserCancellation(delegationError)) {
|
|
1451
|
+
throw new OfframpError(
|
|
1452
|
+
"User cancelled delegation",
|
|
1453
|
+
"USER_CANCELLED",
|
|
1454
|
+
"delegating",
|
|
1455
|
+
delegationError,
|
|
1456
|
+
{ txHash: hash, depositId }
|
|
1457
|
+
);
|
|
1458
|
+
}
|
|
1459
|
+
throw new OfframpError(
|
|
1460
|
+
"Deposit created but delegation failed. Call offramp() again to resume delegation.",
|
|
1461
|
+
"DELEGATION_FAILED",
|
|
1232
1462
|
"delegating",
|
|
1233
1463
|
delegationError,
|
|
1234
1464
|
{ txHash: hash, depositId }
|
|
1235
1465
|
);
|
|
1236
1466
|
}
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
"
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1467
|
+
let otcLink;
|
|
1468
|
+
if (params.otcTaker) {
|
|
1469
|
+
emitProgress({ step: "restricting", txHash: hash, depositId });
|
|
1470
|
+
try {
|
|
1471
|
+
const otcResult = await enableOtc(walletClient, depositId, params.otcTaker);
|
|
1472
|
+
otcLink = otcResult.otcLink;
|
|
1473
|
+
} catch (otcError) {
|
|
1474
|
+
if (isUserCancellation(otcError)) {
|
|
1475
|
+
throw new OfframpError(
|
|
1476
|
+
"User cancelled OTC restriction",
|
|
1477
|
+
"USER_CANCELLED",
|
|
1478
|
+
"restricting",
|
|
1479
|
+
otcError,
|
|
1480
|
+
{
|
|
1481
|
+
txHash: hash,
|
|
1482
|
+
depositId
|
|
1483
|
+
}
|
|
1484
|
+
);
|
|
1485
|
+
}
|
|
1253
1486
|
throw new OfframpError(
|
|
1254
|
-
"
|
|
1255
|
-
"
|
|
1487
|
+
"Deposit created and delegated but OTC restriction failed. Use enableOtc() to retry.",
|
|
1488
|
+
"DEPOSIT_FAILED",
|
|
1256
1489
|
"restricting",
|
|
1257
1490
|
otcError,
|
|
1258
|
-
{
|
|
1259
|
-
txHash: hash,
|
|
1260
|
-
depositId
|
|
1261
|
-
}
|
|
1491
|
+
{ txHash: hash, depositId }
|
|
1262
1492
|
);
|
|
1263
1493
|
}
|
|
1494
|
+
}
|
|
1495
|
+
emitProgress({ step: "done", txHash: hash, depositId });
|
|
1496
|
+
const result = { depositId, txHash: hash, resumed: false, otcLink };
|
|
1497
|
+
telemetry.emit("sdk.createDeposit.success", {
|
|
1498
|
+
depositId: result.depositId,
|
|
1499
|
+
txHash: result.txHash,
|
|
1500
|
+
wallet: walletAddress,
|
|
1501
|
+
resumed: false,
|
|
1502
|
+
wallDurationMs: Date.now() - flowStartMs
|
|
1503
|
+
});
|
|
1504
|
+
return result;
|
|
1505
|
+
} catch (error) {
|
|
1506
|
+
const known = error instanceof OfframpError ? error : null;
|
|
1507
|
+
telemetry.emit("sdk.createDeposit.error", {
|
|
1508
|
+
code: known?.code ?? "DEPOSIT_FAILED",
|
|
1509
|
+
step: known?.step ?? "unknown"
|
|
1510
|
+
});
|
|
1511
|
+
throw error;
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
// src/offramp.ts
|
|
1516
|
+
var IDEMPOTENCY_TTL_MS = 10 * 60 * 1e3;
|
|
1517
|
+
var IDEMPOTENCY_STORAGE_PREFIX = "offramp:idempotency:";
|
|
1518
|
+
function getWalletAddress(walletClient) {
|
|
1519
|
+
const address = walletClient.account?.address;
|
|
1520
|
+
if (!address) {
|
|
1521
|
+
throw new OfframpError("Wallet client has no account. Connect a wallet first.", "VALIDATION");
|
|
1522
|
+
}
|
|
1523
|
+
return address.toLowerCase();
|
|
1524
|
+
}
|
|
1525
|
+
function getIdempotencyStorageKey(walletAddress, idempotencyKey) {
|
|
1526
|
+
return `${IDEMPOTENCY_STORAGE_PREFIX}${walletAddress}:${idempotencyKey}`;
|
|
1527
|
+
}
|
|
1528
|
+
function readIdempotencyResult(storageKey) {
|
|
1529
|
+
if (typeof sessionStorage === "undefined") return null;
|
|
1530
|
+
try {
|
|
1531
|
+
const raw = sessionStorage.getItem(storageKey);
|
|
1532
|
+
if (!raw) return null;
|
|
1533
|
+
const parsed = JSON.parse(raw);
|
|
1534
|
+
const expiresAt = typeof parsed.expiresAt === "number" && Number.isFinite(parsed.expiresAt) ? parsed.expiresAt : 0;
|
|
1535
|
+
if (expiresAt <= Date.now()) {
|
|
1536
|
+
sessionStorage.removeItem(storageKey);
|
|
1537
|
+
return null;
|
|
1538
|
+
}
|
|
1539
|
+
const result = parsed.result;
|
|
1540
|
+
if (!result?.depositId || !result.txHash) {
|
|
1541
|
+
sessionStorage.removeItem(storageKey);
|
|
1542
|
+
return null;
|
|
1543
|
+
}
|
|
1544
|
+
return result;
|
|
1545
|
+
} catch {
|
|
1546
|
+
return null;
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
function writeIdempotencyResult(storageKey, result) {
|
|
1550
|
+
if (typeof sessionStorage === "undefined") return;
|
|
1551
|
+
try {
|
|
1552
|
+
const record = {
|
|
1553
|
+
result,
|
|
1554
|
+
expiresAt: Date.now() + IDEMPOTENCY_TTL_MS
|
|
1555
|
+
};
|
|
1556
|
+
sessionStorage.setItem(storageKey, JSON.stringify(record));
|
|
1557
|
+
} catch {
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
function createPerFlowTelemetry(base4, integratorId, referralId) {
|
|
1561
|
+
return createTelemetryContext({
|
|
1562
|
+
sdkVersion: base4.sdkVersion,
|
|
1563
|
+
telemetry: base4.enabled,
|
|
1564
|
+
integratorId: sanitizeAttributionId(integratorId) ?? base4.integratorId,
|
|
1565
|
+
referralId: sanitizeAttributionId(referralId) ?? base4.referralId
|
|
1566
|
+
});
|
|
1567
|
+
}
|
|
1568
|
+
function normalizeCurrencyEntry(code) {
|
|
1569
|
+
const fromCatalog = CURRENCIES[code];
|
|
1570
|
+
if (fromCatalog) return fromCatalog;
|
|
1571
|
+
return {
|
|
1572
|
+
code,
|
|
1573
|
+
name: code,
|
|
1574
|
+
symbol: code,
|
|
1575
|
+
countryCode: ""
|
|
1576
|
+
};
|
|
1577
|
+
}
|
|
1578
|
+
function buildCurrencyGroups() {
|
|
1579
|
+
const grouped = {};
|
|
1580
|
+
for (const platform of Object.values(PLATFORMS)) {
|
|
1581
|
+
grouped[platform.id] = platform.currencies.map(normalizeCurrencyEntry);
|
|
1582
|
+
}
|
|
1583
|
+
return grouped;
|
|
1584
|
+
}
|
|
1585
|
+
var Offramp = class {
|
|
1586
|
+
walletClient;
|
|
1587
|
+
telemetry;
|
|
1588
|
+
constructor(options) {
|
|
1589
|
+
this.walletClient = options.walletClient;
|
|
1590
|
+
this.telemetry = createTelemetryContext({
|
|
1591
|
+
sdkVersion: SDK_VERSION,
|
|
1592
|
+
telemetry: options.telemetry,
|
|
1593
|
+
integratorId: options.integratorId,
|
|
1594
|
+
referralId: options.referralId
|
|
1595
|
+
});
|
|
1596
|
+
this.telemetry.emit("sdk.init", {
|
|
1597
|
+
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "unknown"
|
|
1598
|
+
});
|
|
1599
|
+
}
|
|
1600
|
+
async createDeposit(params, onProgress) {
|
|
1601
|
+
const flowTelemetry = createPerFlowTelemetry(
|
|
1602
|
+
this.telemetry,
|
|
1603
|
+
params.integratorId,
|
|
1604
|
+
params.referralId
|
|
1605
|
+
);
|
|
1606
|
+
const sanitizedParams = {
|
|
1607
|
+
...params,
|
|
1608
|
+
integratorId: flowTelemetry.integratorId,
|
|
1609
|
+
referralId: flowTelemetry.referralId
|
|
1610
|
+
};
|
|
1611
|
+
const sanitizedKey = sanitizeAttributionId(params.idempotencyKey);
|
|
1612
|
+
const walletAddress = sanitizedKey ? getWalletAddress(this.walletClient) : null;
|
|
1613
|
+
const storageKey = walletAddress && sanitizedKey ? getIdempotencyStorageKey(walletAddress, sanitizedKey) : null;
|
|
1614
|
+
if (storageKey) {
|
|
1615
|
+
const existing = readIdempotencyResult(storageKey);
|
|
1616
|
+
if (existing) return existing;
|
|
1617
|
+
}
|
|
1618
|
+
const result = await offramp(
|
|
1619
|
+
this.walletClient,
|
|
1620
|
+
sanitizedParams,
|
|
1621
|
+
onProgress,
|
|
1622
|
+
flowTelemetry
|
|
1623
|
+
);
|
|
1624
|
+
if (storageKey) {
|
|
1625
|
+
writeIdempotencyResult(storageKey, result);
|
|
1626
|
+
}
|
|
1627
|
+
return result;
|
|
1628
|
+
}
|
|
1629
|
+
getQuote(input) {
|
|
1630
|
+
const amountUsdc = Number(input.amount);
|
|
1631
|
+
if (!Number.isFinite(amountUsdc) || amountUsdc <= 0) {
|
|
1632
|
+
throw new OfframpError("Amount must be a positive number", "VALIDATION");
|
|
1633
|
+
}
|
|
1634
|
+
if (!input.platform.currencies.includes(input.currency.code)) {
|
|
1264
1635
|
throw new OfframpError(
|
|
1265
|
-
|
|
1266
|
-
"
|
|
1267
|
-
"restricting",
|
|
1268
|
-
otcError,
|
|
1269
|
-
{ txHash: hash, depositId }
|
|
1636
|
+
`${input.currency.code} is not supported on ${input.platform.name}`,
|
|
1637
|
+
"UNSUPPORTED"
|
|
1270
1638
|
);
|
|
1271
1639
|
}
|
|
1640
|
+
const vaultSpreadBps = 0;
|
|
1641
|
+
const spreadFactor = Math.max(0, 1 - vaultSpreadBps / 1e4);
|
|
1642
|
+
const expectedFiat = amountUsdc * spreadFactor;
|
|
1643
|
+
const effectiveRate = amountUsdc === 0 ? 0 : expectedFiat / amountUsdc;
|
|
1644
|
+
return {
|
|
1645
|
+
amountUsdc,
|
|
1646
|
+
expectedFiat,
|
|
1647
|
+
effectiveRate,
|
|
1648
|
+
vaultSpreadBps
|
|
1649
|
+
};
|
|
1272
1650
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1651
|
+
getVaultStatus() {
|
|
1652
|
+
return {
|
|
1653
|
+
rateManagerId: DELEGATE_RATE_MANAGER_ID,
|
|
1654
|
+
rateManagerAddress: RATE_MANAGER_REGISTRY_ADDRESS,
|
|
1655
|
+
feeRateBps: DELEGATE_MANAGER_FEE_BPS,
|
|
1656
|
+
escrow: ESCROW_ADDRESS,
|
|
1657
|
+
isActive: true
|
|
1658
|
+
};
|
|
1659
|
+
}
|
|
1660
|
+
listCurrencies() {
|
|
1661
|
+
return buildCurrencyGroups();
|
|
1662
|
+
}
|
|
1663
|
+
};
|
|
1664
|
+
function createOfframp(options) {
|
|
1665
|
+
return new Offramp(options);
|
|
1275
1666
|
}
|
|
1276
1667
|
|
|
1277
1668
|
// src/hooks/useOfframp.ts
|
|
1278
|
-
function
|
|
1669
|
+
function mapStepToState(step) {
|
|
1670
|
+
if (step === "resuming" || step === "restricting") return "delegating";
|
|
1671
|
+
if (step === "done") return "done";
|
|
1672
|
+
return step;
|
|
1673
|
+
}
|
|
1674
|
+
function useOfframp(defaultOptions = {}) {
|
|
1675
|
+
const [state, setState] = (0, import_react.useState)("idle");
|
|
1279
1676
|
const [step, setStep] = (0, import_react.useState)(null);
|
|
1280
1677
|
const [txHash, setTxHash] = (0, import_react.useState)(null);
|
|
1281
1678
|
const [depositId, setDepositId] = (0, import_react.useState)(null);
|
|
1282
|
-
const [
|
|
1679
|
+
const [lastError, setLastError] = (0, import_react.useState)(null);
|
|
1283
1680
|
const [isLoading, setIsLoading] = (0, import_react.useState)(false);
|
|
1284
1681
|
const lockRef = (0, import_react.useRef)(false);
|
|
1285
1682
|
const reset = (0, import_react.useCallback)(() => {
|
|
1683
|
+
setState("idle");
|
|
1286
1684
|
setStep(null);
|
|
1287
1685
|
setTxHash(null);
|
|
1288
1686
|
setDepositId(null);
|
|
1289
|
-
|
|
1687
|
+
setLastError(null);
|
|
1290
1688
|
setIsLoading(false);
|
|
1291
1689
|
lockRef.current = false;
|
|
1292
1690
|
}, []);
|
|
@@ -1295,16 +1693,25 @@ function useOfframp() {
|
|
|
1295
1693
|
if (lockRef.current) throw new OfframpError("Deposit already in progress", "VALIDATION");
|
|
1296
1694
|
lockRef.current = true;
|
|
1297
1695
|
setIsLoading(true);
|
|
1298
|
-
|
|
1696
|
+
setState("idle");
|
|
1697
|
+
setLastError(null);
|
|
1299
1698
|
setStep(null);
|
|
1300
1699
|
setTxHash(null);
|
|
1301
1700
|
setDepositId(null);
|
|
1302
1701
|
try {
|
|
1303
|
-
const
|
|
1702
|
+
const sdk = createOfframp({
|
|
1703
|
+
walletClient,
|
|
1704
|
+
integratorId: params.integratorId ?? defaultOptions.integratorId,
|
|
1705
|
+
referralId: params.referralId ?? defaultOptions.referralId,
|
|
1706
|
+
telemetry: defaultOptions.telemetry
|
|
1707
|
+
});
|
|
1708
|
+
const result = await sdk.createDeposit(params, (progress) => {
|
|
1304
1709
|
setStep(progress.step);
|
|
1710
|
+
setState(mapStepToState(progress.step));
|
|
1305
1711
|
if (progress.txHash) setTxHash(progress.txHash);
|
|
1306
1712
|
if (progress.depositId) setDepositId(progress.depositId);
|
|
1307
1713
|
});
|
|
1714
|
+
setState("done");
|
|
1308
1715
|
setDepositId(result.depositId);
|
|
1309
1716
|
setTxHash(result.txHash);
|
|
1310
1717
|
return result;
|
|
@@ -1313,20 +1720,23 @@ function useOfframp() {
|
|
|
1313
1720
|
err instanceof Error ? err.message : "Offramp failed",
|
|
1314
1721
|
"DEPOSIT_FAILED"
|
|
1315
1722
|
);
|
|
1316
|
-
|
|
1317
|
-
|
|
1723
|
+
setLastError(offrampError);
|
|
1724
|
+
setState("error");
|
|
1725
|
+
throw offrampError;
|
|
1318
1726
|
} finally {
|
|
1319
1727
|
setIsLoading(false);
|
|
1320
1728
|
lockRef.current = false;
|
|
1321
1729
|
}
|
|
1322
1730
|
},
|
|
1323
|
-
[]
|
|
1731
|
+
[defaultOptions.integratorId, defaultOptions.referralId, defaultOptions.telemetry]
|
|
1324
1732
|
);
|
|
1325
1733
|
return {
|
|
1734
|
+
state,
|
|
1326
1735
|
step,
|
|
1327
1736
|
txHash,
|
|
1328
1737
|
depositId,
|
|
1329
|
-
|
|
1738
|
+
lastError,
|
|
1739
|
+
error: lastError,
|
|
1330
1740
|
isLoading,
|
|
1331
1741
|
offramp: offramp2,
|
|
1332
1742
|
deposits,
|
|
@@ -1334,8 +1744,129 @@ function useOfframp() {
|
|
|
1334
1744
|
reset
|
|
1335
1745
|
};
|
|
1336
1746
|
}
|
|
1747
|
+
|
|
1748
|
+
// src/hooks/usePeerExtensionRegistration.ts
|
|
1749
|
+
var import_react2 = require("react");
|
|
1750
|
+
|
|
1751
|
+
// src/extension.ts
|
|
1752
|
+
var import_sdk7 = require("@zkp2p/sdk");
|
|
1753
|
+
|
|
1754
|
+
// src/hooks/usePeerExtensionRegistration.ts
|
|
1755
|
+
function usePeerExtensionRegistration(platform) {
|
|
1756
|
+
const info = platform ? getPeerExtensionRegistrationInfo(platform.id) : null;
|
|
1757
|
+
const [phase, setPhase] = (0, import_react2.useState)(
|
|
1758
|
+
info ? "checking" : "unsupported"
|
|
1759
|
+
);
|
|
1760
|
+
const [busy, setBusy] = (0, import_react2.useState)(false);
|
|
1761
|
+
const [error, setError] = (0, import_react2.useState)(null);
|
|
1762
|
+
const mountedRef = (0, import_react2.useRef)(true);
|
|
1763
|
+
const providerId = info?.providerId ?? null;
|
|
1764
|
+
const refresh = (0, import_react2.useCallback)(async () => {
|
|
1765
|
+
if (!providerId) {
|
|
1766
|
+
setPhase("unsupported");
|
|
1767
|
+
return;
|
|
1768
|
+
}
|
|
1769
|
+
try {
|
|
1770
|
+
const state = await import_sdk7.peerExtensionSdk.getState();
|
|
1771
|
+
if (!mountedRef.current) return;
|
|
1772
|
+
setPhase(mapSdkState(state));
|
|
1773
|
+
} catch {
|
|
1774
|
+
if (!mountedRef.current) return;
|
|
1775
|
+
setPhase("needs_install");
|
|
1776
|
+
}
|
|
1777
|
+
}, [providerId]);
|
|
1778
|
+
(0, import_react2.useEffect)(() => {
|
|
1779
|
+
mountedRef.current = true;
|
|
1780
|
+
setError(null);
|
|
1781
|
+
setBusy(false);
|
|
1782
|
+
if (!providerId) {
|
|
1783
|
+
setPhase("unsupported");
|
|
1784
|
+
} else {
|
|
1785
|
+
setPhase("checking");
|
|
1786
|
+
refresh();
|
|
1787
|
+
}
|
|
1788
|
+
return () => {
|
|
1789
|
+
mountedRef.current = false;
|
|
1790
|
+
};
|
|
1791
|
+
}, [providerId, refresh]);
|
|
1792
|
+
const installExtension = (0, import_react2.useCallback)(() => {
|
|
1793
|
+
setError(null);
|
|
1794
|
+
try {
|
|
1795
|
+
import_sdk7.peerExtensionSdk.openInstallPage();
|
|
1796
|
+
} catch {
|
|
1797
|
+
if (typeof window !== "undefined") {
|
|
1798
|
+
window.open(import_sdk7.PEER_EXTENSION_CHROME_URL, "_blank", "noopener,noreferrer");
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
}, []);
|
|
1802
|
+
const connectExtension = (0, import_react2.useCallback)(async () => {
|
|
1803
|
+
if (!providerId) return false;
|
|
1804
|
+
setError(null);
|
|
1805
|
+
setBusy(true);
|
|
1806
|
+
try {
|
|
1807
|
+
const approved = await import_sdk7.peerExtensionSdk.requestConnection();
|
|
1808
|
+
if (!mountedRef.current) return approved;
|
|
1809
|
+
if (approved) {
|
|
1810
|
+
setPhase("ready");
|
|
1811
|
+
import_sdk7.peerExtensionSdk.openSidebar(`/verify/${providerId}`);
|
|
1812
|
+
} else {
|
|
1813
|
+
setError("Connection was not approved. Try again once you've approved Peer.");
|
|
1814
|
+
}
|
|
1815
|
+
return approved;
|
|
1816
|
+
} catch (err) {
|
|
1817
|
+
if (!mountedRef.current) return false;
|
|
1818
|
+
setError(
|
|
1819
|
+
err instanceof Error ? err.message : "Couldn't request a Peer extension connection. Make sure Peer is installed and enabled."
|
|
1820
|
+
);
|
|
1821
|
+
refresh();
|
|
1822
|
+
return false;
|
|
1823
|
+
} finally {
|
|
1824
|
+
if (mountedRef.current) setBusy(false);
|
|
1825
|
+
}
|
|
1826
|
+
}, [providerId, refresh]);
|
|
1827
|
+
const openVerifySidebar = (0, import_react2.useCallback)(async () => {
|
|
1828
|
+
if (!providerId) return;
|
|
1829
|
+
setError(null);
|
|
1830
|
+
const state = await import_sdk7.peerExtensionSdk.getState().catch(() => "needs_install");
|
|
1831
|
+
if (!mountedRef.current) return;
|
|
1832
|
+
const nextPhase = mapSdkState(state);
|
|
1833
|
+
setPhase(nextPhase);
|
|
1834
|
+
if (nextPhase === "needs_install") {
|
|
1835
|
+
installExtension();
|
|
1836
|
+
return;
|
|
1837
|
+
}
|
|
1838
|
+
if (nextPhase === "needs_connection") {
|
|
1839
|
+
await connectExtension();
|
|
1840
|
+
return;
|
|
1841
|
+
}
|
|
1842
|
+
try {
|
|
1843
|
+
import_sdk7.peerExtensionSdk.openSidebar(`/verify/${providerId}`);
|
|
1844
|
+
} catch (err) {
|
|
1845
|
+
setError(
|
|
1846
|
+
err instanceof Error ? err.message : "Couldn't open the Peer extension. Make sure it's enabled."
|
|
1847
|
+
);
|
|
1848
|
+
refresh();
|
|
1849
|
+
}
|
|
1850
|
+
}, [connectExtension, installExtension, providerId, refresh]);
|
|
1851
|
+
return {
|
|
1852
|
+
phase,
|
|
1853
|
+
info,
|
|
1854
|
+
busy,
|
|
1855
|
+
error,
|
|
1856
|
+
refresh,
|
|
1857
|
+
installExtension,
|
|
1858
|
+
connectExtension,
|
|
1859
|
+
openVerifySidebar
|
|
1860
|
+
};
|
|
1861
|
+
}
|
|
1862
|
+
function mapSdkState(state) {
|
|
1863
|
+
if (state === "needs_install") return "needs_install";
|
|
1864
|
+
if (state === "needs_connection") return "needs_connection";
|
|
1865
|
+
return "ready";
|
|
1866
|
+
}
|
|
1337
1867
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1338
1868
|
0 && (module.exports = {
|
|
1339
|
-
useOfframp
|
|
1869
|
+
useOfframp,
|
|
1870
|
+
usePeerExtensionRegistration
|
|
1340
1871
|
});
|
|
1341
1872
|
//# sourceMappingURL=react.cjs.map
|