@usdctofiat/offramp 3.0.3 → 3.1.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 +5 -0
- package/README.md +128 -23
- package/dist/{chunk-4KKKDDES.js → chunk-XQ7HOLLB.js} +292 -96
- package/dist/chunk-XQ7HOLLB.js.map +1 -0
- package/dist/{errors-D9bV_DWE.d.cts → errors-DzTiflBh.d.cts} +161 -6
- package/dist/{errors-D9bV_DWE.d.ts → errors-DzTiflBh.d.ts} +161 -6
- package/dist/index.cjs +297 -92
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -5
- package/dist/index.d.ts +9 -5
- package/dist/index.js +9 -3
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +385 -111
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +23 -13
- package/dist/react.d.ts +23 -13
- package/dist/react.js +106 -27
- package/dist/react.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-4KKKDDES.js.map +0 -1
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
// src/config.ts
|
|
2
2
|
import { getContracts, getGatingServiceAddress } from "@zkp2p/sdk";
|
|
3
|
-
var SDK_VERSION = "3.0
|
|
3
|
+
var SDK_VERSION = "3.1.0";
|
|
4
4
|
var BASE_CHAIN_ID = 8453;
|
|
5
5
|
var RUNTIME_ENV = "production";
|
|
6
6
|
var API_BASE_URL = "https://api.zkp2p.xyz";
|
|
7
7
|
var BASE_RPC_URL = "https://mainnet.base.org";
|
|
8
|
+
function resolveApiBaseUrl(override) {
|
|
9
|
+
const trimmed = override?.trim();
|
|
10
|
+
return (trimmed && trimmed.length > 0 ? trimmed : API_BASE_URL).replace(/\/$/, "");
|
|
11
|
+
}
|
|
8
12
|
var contracts = getContracts(BASE_CHAIN_ID, RUNTIME_ENV);
|
|
9
13
|
var addresses = contracts.addresses;
|
|
10
14
|
var addrs = addresses;
|
|
@@ -21,11 +25,45 @@ var DEFAULT_INTENT_GUARDIAN_ADDRESS = "0xe29a5BD4D0CEbA6C125A0361E7D20ab4eA275C2
|
|
|
21
25
|
var REFERRER = "galleonlabs";
|
|
22
26
|
var MIN_DEPOSIT_USDC = 1;
|
|
23
27
|
var MIN_ORDER_USDC = 1;
|
|
28
|
+
var MAX_ORDER_USDC = 2500;
|
|
24
29
|
var INDEXER_MAX_ATTEMPTS = 12;
|
|
25
30
|
var INDEXER_INITIAL_DELAY_MS = 1e3;
|
|
26
31
|
var INDEXER_MAX_DELAY_MS = 1e4;
|
|
27
32
|
var PAYEE_REGISTRATION_TIMEOUT_MS = 8e3;
|
|
28
33
|
|
|
34
|
+
// src/errors.ts
|
|
35
|
+
var MakersCreateError = class extends Error {
|
|
36
|
+
status;
|
|
37
|
+
body;
|
|
38
|
+
constructor(message, status, body) {
|
|
39
|
+
super(message);
|
|
40
|
+
this.name = "MakersCreateError";
|
|
41
|
+
this.status = status;
|
|
42
|
+
this.body = body;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
var OfframpError = class extends Error {
|
|
46
|
+
code;
|
|
47
|
+
step;
|
|
48
|
+
cause;
|
|
49
|
+
txHash;
|
|
50
|
+
depositId;
|
|
51
|
+
constructor(message, code, step, cause, details) {
|
|
52
|
+
super(message);
|
|
53
|
+
this.name = "OfframpError";
|
|
54
|
+
this.code = code;
|
|
55
|
+
this.step = step;
|
|
56
|
+
this.cause = cause;
|
|
57
|
+
this.txHash = details?.txHash;
|
|
58
|
+
this.depositId = details?.depositId;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
function isUserCancellation(error) {
|
|
62
|
+
if (!(error instanceof Error)) return false;
|
|
63
|
+
const msg = error.message.toLowerCase();
|
|
64
|
+
return msg.includes("user rejected") || msg.includes("user denied") || msg.includes("user cancelled") || msg.includes("rejected the request") || msg.includes("action_rejected");
|
|
65
|
+
}
|
|
66
|
+
|
|
29
67
|
// src/platforms.ts
|
|
30
68
|
import {
|
|
31
69
|
currencyInfo,
|
|
@@ -394,6 +432,146 @@ function getPeerExtensionRegistrationInfo(platform) {
|
|
|
394
432
|
const entry = getPlatformById(platform);
|
|
395
433
|
return entry?.extensionRegistration ?? null;
|
|
396
434
|
}
|
|
435
|
+
function getPeerExtensionRegistrationAuthParams(platform, options = {}) {
|
|
436
|
+
const info = getPeerExtensionRegistrationInfo(platform);
|
|
437
|
+
if (!info) return null;
|
|
438
|
+
const params = {
|
|
439
|
+
actionType: `transfer_${info.providerId}`,
|
|
440
|
+
captureMode: "sellerCredential",
|
|
441
|
+
platform: info.providerId
|
|
442
|
+
};
|
|
443
|
+
if (options.attestationServiceUrl) {
|
|
444
|
+
params.attestationServiceUrl = options.attestationServiceUrl;
|
|
445
|
+
}
|
|
446
|
+
return params;
|
|
447
|
+
}
|
|
448
|
+
function resolveRegistrationProcessor(platform) {
|
|
449
|
+
const info = getPeerExtensionRegistrationInfo(platform.id);
|
|
450
|
+
if (info?.providerId === "paypal" || info?.providerId === "wise") {
|
|
451
|
+
return info.providerId;
|
|
452
|
+
}
|
|
453
|
+
throw new Error(`${platform.name} does not require Peer extension registration.`);
|
|
454
|
+
}
|
|
455
|
+
async function postMakerCreate(processorName, payload, apiBaseUrl = API_BASE_URL) {
|
|
456
|
+
const controller = new AbortController();
|
|
457
|
+
const timeout = setTimeout(() => controller.abort(), PAYEE_REGISTRATION_TIMEOUT_MS);
|
|
458
|
+
try {
|
|
459
|
+
const res = await fetch(`${apiBaseUrl}/v2/makers/create`, {
|
|
460
|
+
method: "POST",
|
|
461
|
+
headers: { "Content-Type": "application/json" },
|
|
462
|
+
body: JSON.stringify({ processorName, ...payload }),
|
|
463
|
+
signal: controller.signal
|
|
464
|
+
});
|
|
465
|
+
if (!res.ok) {
|
|
466
|
+
const txt = await res.text().catch(() => "");
|
|
467
|
+
let detail = txt || res.statusText;
|
|
468
|
+
try {
|
|
469
|
+
const parsed = JSON.parse(txt);
|
|
470
|
+
if (typeof parsed.message === "string" && parsed.message.trim()) {
|
|
471
|
+
detail = parsed.message;
|
|
472
|
+
}
|
|
473
|
+
} catch {
|
|
474
|
+
}
|
|
475
|
+
throw new MakersCreateError(
|
|
476
|
+
`makers/create failed (${res.status}): ${detail}`,
|
|
477
|
+
res.status,
|
|
478
|
+
txt
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
const json = await res.json();
|
|
482
|
+
if (!json.success || !json.responseObject?.hashedOnchainId) {
|
|
483
|
+
throw new MakersCreateError(
|
|
484
|
+
json.message || "makers/create returned no hashedOnchainId",
|
|
485
|
+
json.statusCode ?? null,
|
|
486
|
+
""
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
return json.responseObject.hashedOnchainId;
|
|
490
|
+
} finally {
|
|
491
|
+
clearTimeout(timeout);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
function requireSarCredentialCapture(capturedMetadata) {
|
|
495
|
+
const capture = capturedMetadata.sarCredentialCapture;
|
|
496
|
+
if (!capture?.credentialBundle) {
|
|
497
|
+
throw new Error("Peer metadata did not include a seller credential bundle.");
|
|
498
|
+
}
|
|
499
|
+
if (!capture.offchainId) {
|
|
500
|
+
throw new Error("Peer metadata did not include seller credential offchainId.");
|
|
501
|
+
}
|
|
502
|
+
return capture;
|
|
503
|
+
}
|
|
504
|
+
async function uploadSellerCredentialBundle(processorName, payeeHash, bundle) {
|
|
505
|
+
const controller = new AbortController();
|
|
506
|
+
const timeout = setTimeout(() => controller.abort(), PAYEE_REGISTRATION_TIMEOUT_MS);
|
|
507
|
+
try {
|
|
508
|
+
const res = await fetch(
|
|
509
|
+
`${API_BASE_URL}/v2/makers/${encodeURIComponent(processorName)}/${encodeURIComponent(payeeHash)}/seller-credential`,
|
|
510
|
+
{
|
|
511
|
+
method: "POST",
|
|
512
|
+
headers: { "Content-Type": "application/json" },
|
|
513
|
+
body: JSON.stringify(bundle),
|
|
514
|
+
signal: controller.signal
|
|
515
|
+
}
|
|
516
|
+
);
|
|
517
|
+
if (!res.ok) {
|
|
518
|
+
const txt = await res.text().catch(() => "");
|
|
519
|
+
let detail = txt || res.statusText;
|
|
520
|
+
try {
|
|
521
|
+
const parsed = JSON.parse(txt);
|
|
522
|
+
if (typeof parsed.message === "string" && parsed.message.trim()) {
|
|
523
|
+
detail = parsed.message;
|
|
524
|
+
}
|
|
525
|
+
} catch {
|
|
526
|
+
}
|
|
527
|
+
throw new Error(`seller-credential upload failed (${res.status}): ${detail}`);
|
|
528
|
+
}
|
|
529
|
+
const json = await res.json();
|
|
530
|
+
if (!json.success || !json.responseObject) {
|
|
531
|
+
throw new Error(json.message || "seller-credential upload returned no status.");
|
|
532
|
+
}
|
|
533
|
+
return json;
|
|
534
|
+
} finally {
|
|
535
|
+
clearTimeout(timeout);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
async function completePeerExtensionRegistration(input) {
|
|
539
|
+
const processorName = resolveRegistrationProcessor(input.platform);
|
|
540
|
+
if (input.capturedMetadata.platform !== processorName) {
|
|
541
|
+
throw new Error(
|
|
542
|
+
`Peer metadata is for ${input.capturedMetadata.platform}, not ${processorName}.`
|
|
543
|
+
);
|
|
544
|
+
}
|
|
545
|
+
const sarCredentialCapture = requireSarCredentialCapture(input.capturedMetadata);
|
|
546
|
+
const bundle = sarCredentialCapture.credentialBundle;
|
|
547
|
+
if (bundle.platform.toLowerCase() !== processorName) {
|
|
548
|
+
throw new Error("Seller credential bundle platform does not match registration platform.");
|
|
549
|
+
}
|
|
550
|
+
const validation = input.platform.validate(input.identifier);
|
|
551
|
+
if (!validation.valid) {
|
|
552
|
+
throw new Error(validation.error || "Invalid identifier");
|
|
553
|
+
}
|
|
554
|
+
const payload = buildDepositData(processorName, sarCredentialCapture.offchainId);
|
|
555
|
+
if (payload.offchainId !== validation.normalized) {
|
|
556
|
+
throw new Error("Seller credential offchainId does not match registration identifier.");
|
|
557
|
+
}
|
|
558
|
+
const hashedOnchainId = processorName === "wise" ? bundle.payeeIdHash : await postMakerCreate(processorName, payload);
|
|
559
|
+
if (hashedOnchainId.toLowerCase() !== bundle.payeeIdHash.toLowerCase()) {
|
|
560
|
+
throw new Error("Seller credential payee hash does not match registered payee details.");
|
|
561
|
+
}
|
|
562
|
+
const sellerCredentialResponse = await uploadSellerCredentialBundle(
|
|
563
|
+
processorName,
|
|
564
|
+
hashedOnchainId,
|
|
565
|
+
bundle
|
|
566
|
+
);
|
|
567
|
+
return {
|
|
568
|
+
processorName,
|
|
569
|
+
offchainId: payload.offchainId,
|
|
570
|
+
hashedOnchainId,
|
|
571
|
+
sellerCredentialResponse,
|
|
572
|
+
sellerCredentialStatus: sellerCredentialResponse.responseObject
|
|
573
|
+
};
|
|
574
|
+
}
|
|
397
575
|
var EXTENSION_REGISTRATION_ERROR_PATTERNS = ["creating the maker", "create the maker"];
|
|
398
576
|
function isPeerExtensionRegistrationError(platform, message, statusCode) {
|
|
399
577
|
const info = getPeerExtensionRegistrationInfo(platform);
|
|
@@ -405,39 +583,6 @@ function isPeerExtensionRegistrationError(platform, message, statusCode) {
|
|
|
405
583
|
return EXTENSION_REGISTRATION_ERROR_PATTERNS.some((p) => lower.includes(p));
|
|
406
584
|
}
|
|
407
585
|
|
|
408
|
-
// src/errors.ts
|
|
409
|
-
var MakersCreateError = class extends Error {
|
|
410
|
-
status;
|
|
411
|
-
body;
|
|
412
|
-
constructor(message, status, body) {
|
|
413
|
-
super(message);
|
|
414
|
-
this.name = "MakersCreateError";
|
|
415
|
-
this.status = status;
|
|
416
|
-
this.body = body;
|
|
417
|
-
}
|
|
418
|
-
};
|
|
419
|
-
var OfframpError = class extends Error {
|
|
420
|
-
code;
|
|
421
|
-
step;
|
|
422
|
-
cause;
|
|
423
|
-
txHash;
|
|
424
|
-
depositId;
|
|
425
|
-
constructor(message, code, step, cause, details) {
|
|
426
|
-
super(message);
|
|
427
|
-
this.name = "OfframpError";
|
|
428
|
-
this.code = code;
|
|
429
|
-
this.step = step;
|
|
430
|
-
this.cause = cause;
|
|
431
|
-
this.txHash = details?.txHash;
|
|
432
|
-
this.depositId = details?.depositId;
|
|
433
|
-
}
|
|
434
|
-
};
|
|
435
|
-
function isUserCancellation(error) {
|
|
436
|
-
if (!(error instanceof Error)) return false;
|
|
437
|
-
const msg = error.message.toLowerCase();
|
|
438
|
-
return msg.includes("user rejected") || msg.includes("user denied") || msg.includes("user cancelled") || msg.includes("rejected the request") || msg.includes("action_rejected");
|
|
439
|
-
}
|
|
440
|
-
|
|
441
586
|
// src/otc.ts
|
|
442
587
|
import { createPublicClient, http, isAddress, zeroAddress } from "viem";
|
|
443
588
|
import { base } from "viem/chains";
|
|
@@ -445,13 +590,13 @@ import WhitelistPreIntentHookABI from "@zkp2p/contracts-v2/abis/base/WhitelistPr
|
|
|
445
590
|
|
|
446
591
|
// src/sdk-client.ts
|
|
447
592
|
import { OfframpClient } from "@zkp2p/sdk";
|
|
448
|
-
function createSdkClient(walletClient) {
|
|
593
|
+
function createSdkClient(walletClient, apiBaseUrl = API_BASE_URL) {
|
|
449
594
|
return new OfframpClient({
|
|
450
595
|
walletClient,
|
|
451
596
|
chainId: BASE_CHAIN_ID,
|
|
452
597
|
runtimeEnv: RUNTIME_ENV,
|
|
453
598
|
rpcUrl: BASE_RPC_URL,
|
|
454
|
-
baseApiUrl:
|
|
599
|
+
baseApiUrl: apiBaseUrl
|
|
455
600
|
});
|
|
456
601
|
}
|
|
457
602
|
|
|
@@ -875,50 +1020,11 @@ function extractDepositIdFromLogs(logs) {
|
|
|
875
1020
|
}
|
|
876
1021
|
return null;
|
|
877
1022
|
}
|
|
878
|
-
async function
|
|
879
|
-
const controller = new AbortController();
|
|
880
|
-
const timeout = setTimeout(() => controller.abort(), PAYEE_REGISTRATION_TIMEOUT_MS);
|
|
881
|
-
try {
|
|
882
|
-
const res = await fetch(`${API_BASE_URL}/v2/makers/create`, {
|
|
883
|
-
method: "POST",
|
|
884
|
-
headers: { "Content-Type": "application/json" },
|
|
885
|
-
body: JSON.stringify({ processorName, ...payload }),
|
|
886
|
-
signal: controller.signal
|
|
887
|
-
});
|
|
888
|
-
if (!res.ok) {
|
|
889
|
-
const txt = await res.text().catch(() => "");
|
|
890
|
-
let detail = txt || res.statusText;
|
|
891
|
-
try {
|
|
892
|
-
const parsed = JSON.parse(txt);
|
|
893
|
-
if (typeof parsed.message === "string" && parsed.message.trim()) {
|
|
894
|
-
detail = parsed.message;
|
|
895
|
-
}
|
|
896
|
-
} catch {
|
|
897
|
-
}
|
|
898
|
-
throw new MakersCreateError(
|
|
899
|
-
`makers/create failed (${res.status}): ${detail}`,
|
|
900
|
-
res.status,
|
|
901
|
-
txt
|
|
902
|
-
);
|
|
903
|
-
}
|
|
904
|
-
const json = await res.json();
|
|
905
|
-
if (!json.success || !json.responseObject?.hashedOnchainId) {
|
|
906
|
-
throw new MakersCreateError(
|
|
907
|
-
json.message || "makers/create returned no hashedOnchainId",
|
|
908
|
-
json.statusCode ?? null,
|
|
909
|
-
""
|
|
910
|
-
);
|
|
911
|
-
}
|
|
912
|
-
return json.responseObject.hashedOnchainId;
|
|
913
|
-
} finally {
|
|
914
|
-
clearTimeout(timeout);
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
async function validatePayeeDetails(processorName, offchainId) {
|
|
1023
|
+
async function validatePayeeDetails(processorName, offchainId, apiBaseUrl = API_BASE_URL) {
|
|
918
1024
|
const controller = new AbortController();
|
|
919
1025
|
const timeout = setTimeout(() => controller.abort(), PAYEE_REGISTRATION_TIMEOUT_MS);
|
|
920
1026
|
try {
|
|
921
|
-
const res = await fetch(`${
|
|
1027
|
+
const res = await fetch(`${apiBaseUrl}/v2/makers/validate`, {
|
|
922
1028
|
method: "POST",
|
|
923
1029
|
headers: { "Content-Type": "application/json" },
|
|
924
1030
|
body: JSON.stringify({ processorName, offchainId }),
|
|
@@ -996,10 +1102,11 @@ async function findUndelegatedDeposit(walletAddress) {
|
|
|
996
1102
|
return null;
|
|
997
1103
|
}
|
|
998
1104
|
}
|
|
999
|
-
async function offramp(walletClient, params, onProgress, telemetryContext) {
|
|
1105
|
+
async function offramp(walletClient, params, onProgress, telemetryContext, apiBaseUrl) {
|
|
1000
1106
|
const { amount, platform, currency, identifier } = params;
|
|
1001
1107
|
const platformId = platform.id;
|
|
1002
1108
|
const currencyCode = currency.code;
|
|
1109
|
+
const resolvedApiBaseUrl = resolveApiBaseUrl(apiBaseUrl);
|
|
1003
1110
|
const telemetry = telemetryContext ?? createTelemetryContext({
|
|
1004
1111
|
sdkVersion: SDK_VERSION,
|
|
1005
1112
|
telemetry: true,
|
|
@@ -1044,7 +1151,7 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
|
|
|
1044
1151
|
const existing = await findUndelegatedDeposit(walletAddress);
|
|
1045
1152
|
if (existing) {
|
|
1046
1153
|
emitProgress({ step: "resuming", depositId: existing.depositId });
|
|
1047
|
-
const client2 = createSdkClient(walletClient);
|
|
1154
|
+
const client2 = createSdkClient(walletClient, resolvedApiBaseUrl);
|
|
1048
1155
|
const txOverrides2 = { referrer: [REFERRER] };
|
|
1049
1156
|
try {
|
|
1050
1157
|
const result2 = await client2.setRateManager({
|
|
@@ -1080,7 +1187,7 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
|
|
|
1080
1187
|
const truncatedAmount = amt.toFixed(6).replace(/\.?0+$/, "");
|
|
1081
1188
|
const amountUnits = usdcToUnits(truncatedAmount);
|
|
1082
1189
|
const minUnits = usdcToUnits(String(MIN_ORDER_USDC));
|
|
1083
|
-
const maxUnits = usdcToUnits(String(Math.min(amt,
|
|
1190
|
+
const maxUnits = usdcToUnits(String(Math.min(amt, MAX_ORDER_USDC)));
|
|
1084
1191
|
try {
|
|
1085
1192
|
const publicClient = createPublicClient3({ chain: base3, transport: http3(BASE_RPC_URL) });
|
|
1086
1193
|
const balance = await publicClient.readContract({
|
|
@@ -1109,7 +1216,11 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
|
|
|
1109
1216
|
}
|
|
1110
1217
|
const canonicalName = platformId.startsWith("zelle") ? "zelle" : platformId;
|
|
1111
1218
|
if (!getPeerExtensionRegistrationInfo(platformId)) {
|
|
1112
|
-
const outcome = await validatePayeeDetails(
|
|
1219
|
+
const outcome = await validatePayeeDetails(
|
|
1220
|
+
canonicalName,
|
|
1221
|
+
normalizedIdentifier,
|
|
1222
|
+
resolvedApiBaseUrl
|
|
1223
|
+
);
|
|
1113
1224
|
if (outcome === "invalid") {
|
|
1114
1225
|
throw new OfframpError(
|
|
1115
1226
|
`Couldn't verify that ${platform.name} ${platform.identifier.label.toLowerCase()}. Double-check it and try again.`,
|
|
@@ -1118,7 +1229,7 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
|
|
|
1118
1229
|
);
|
|
1119
1230
|
}
|
|
1120
1231
|
}
|
|
1121
|
-
const client = createSdkClient(walletClient);
|
|
1232
|
+
const client = createSdkClient(walletClient, resolvedApiBaseUrl);
|
|
1122
1233
|
const txOverrides = { referrer: [REFERRER] };
|
|
1123
1234
|
emitProgress({ step: "approving" });
|
|
1124
1235
|
try {
|
|
@@ -1144,13 +1255,13 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
|
|
|
1144
1255
|
let hashedOnchainId;
|
|
1145
1256
|
try {
|
|
1146
1257
|
const payeePayload = buildDepositData(canonicalName, normalizedIdentifier);
|
|
1147
|
-
hashedOnchainId = await
|
|
1258
|
+
hashedOnchainId = await postMakerCreate(canonicalName, payeePayload, resolvedApiBaseUrl);
|
|
1148
1259
|
} catch (err) {
|
|
1149
1260
|
const status = err instanceof MakersCreateError ? err.status : null;
|
|
1150
1261
|
const message = err instanceof Error ? err.message : String(err);
|
|
1151
1262
|
if (isPeerExtensionRegistrationError(canonicalName, message, status)) {
|
|
1152
1263
|
throw new OfframpError(
|
|
1153
|
-
`${platform.name} maker is not yet registered in the Peer extension.
|
|
1264
|
+
`${platform.name} maker is not yet registered in the Peer extension. Register this handle with Peer, then retry.`,
|
|
1154
1265
|
"EXTENSION_REGISTRATION_REQUIRED",
|
|
1155
1266
|
"registering",
|
|
1156
1267
|
err
|
|
@@ -1342,6 +1453,14 @@ var CURRENCIES = buildCurrencies();
|
|
|
1342
1453
|
// src/offramp.ts
|
|
1343
1454
|
var IDEMPOTENCY_TTL_MS = 10 * 60 * 1e3;
|
|
1344
1455
|
var IDEMPOTENCY_STORAGE_PREFIX = "offramp:idempotency:";
|
|
1456
|
+
var warnedIdempotencyUnavailable = false;
|
|
1457
|
+
function warnIdempotencyUnavailableOnce() {
|
|
1458
|
+
if (warnedIdempotencyUnavailable) return;
|
|
1459
|
+
warnedIdempotencyUnavailable = true;
|
|
1460
|
+
console.warn(
|
|
1461
|
+
"[offramp] idempotencyKey was provided but sessionStorage is unavailable (Node/worker runtime). The idempotency cache is browser-only and no-ops here, so retries can create duplicate deposits. For server-side dedup, call deposits(walletAddress) and reuse an existing open deposit before creating one."
|
|
1462
|
+
);
|
|
1463
|
+
}
|
|
1345
1464
|
function getWalletAddress(walletClient) {
|
|
1346
1465
|
const address = walletClient.account?.address;
|
|
1347
1466
|
if (!address) {
|
|
@@ -1412,8 +1531,10 @@ function buildCurrencyGroups() {
|
|
|
1412
1531
|
var Offramp = class {
|
|
1413
1532
|
walletClient;
|
|
1414
1533
|
telemetry;
|
|
1534
|
+
apiBaseUrl;
|
|
1415
1535
|
constructor(options) {
|
|
1416
1536
|
this.walletClient = options.walletClient;
|
|
1537
|
+
this.apiBaseUrl = options.apiBaseUrl;
|
|
1417
1538
|
this.telemetry = createTelemetryContext({
|
|
1418
1539
|
sdkVersion: SDK_VERSION,
|
|
1419
1540
|
telemetry: options.telemetry,
|
|
@@ -1436,6 +1557,9 @@ var Offramp = class {
|
|
|
1436
1557
|
referralId: flowTelemetry.referralId
|
|
1437
1558
|
};
|
|
1438
1559
|
const sanitizedKey = sanitizeAttributionId(params.idempotencyKey);
|
|
1560
|
+
if (sanitizedKey && typeof sessionStorage === "undefined") {
|
|
1561
|
+
warnIdempotencyUnavailableOnce();
|
|
1562
|
+
}
|
|
1439
1563
|
const walletAddress = sanitizedKey ? getWalletAddress(this.walletClient) : null;
|
|
1440
1564
|
const storageKey = walletAddress && sanitizedKey ? getIdempotencyStorageKey(walletAddress, sanitizedKey) : null;
|
|
1441
1565
|
if (storageKey) {
|
|
@@ -1446,7 +1570,8 @@ var Offramp = class {
|
|
|
1446
1570
|
this.walletClient,
|
|
1447
1571
|
sanitizedParams,
|
|
1448
1572
|
onProgress,
|
|
1449
|
-
flowTelemetry
|
|
1573
|
+
flowTelemetry,
|
|
1574
|
+
this.apiBaseUrl
|
|
1450
1575
|
);
|
|
1451
1576
|
if (storageKey) {
|
|
1452
1577
|
writeIdempotencyResult(storageKey, result);
|
|
@@ -1495,24 +1620,94 @@ function createOfframp(options) {
|
|
|
1495
1620
|
// src/extension.ts
|
|
1496
1621
|
import {
|
|
1497
1622
|
PEER_EXTENSION_CHROME_URL,
|
|
1498
|
-
|
|
1499
|
-
createPeerExtensionSdk,
|
|
1500
|
-
isPeerExtensionAvailable,
|
|
1501
|
-
openPeerExtensionInstallPage,
|
|
1502
|
-
getPeerExtensionState
|
|
1623
|
+
createPeerExtensionSdk as createLegacyPeerExtensionSdk
|
|
1503
1624
|
} from "@zkp2p/sdk";
|
|
1625
|
+
var resolveWindow = (options) => {
|
|
1626
|
+
if (options?.window) {
|
|
1627
|
+
return options.window;
|
|
1628
|
+
}
|
|
1629
|
+
if (typeof window === "undefined") {
|
|
1630
|
+
return void 0;
|
|
1631
|
+
}
|
|
1632
|
+
return window;
|
|
1633
|
+
};
|
|
1634
|
+
var requirePeer = (options) => {
|
|
1635
|
+
const resolvedWindow = resolveWindow(options);
|
|
1636
|
+
if (!resolvedWindow) {
|
|
1637
|
+
throw new Error("Peer extension SDK requires a browser window.");
|
|
1638
|
+
}
|
|
1639
|
+
if (!resolvedWindow.peer) {
|
|
1640
|
+
throw new Error("Peer extension not available. Install or enable the Peer extension.");
|
|
1641
|
+
}
|
|
1642
|
+
return resolvedWindow.peer;
|
|
1643
|
+
};
|
|
1644
|
+
var isPeerExtensionAvailable = (options) => {
|
|
1645
|
+
const resolvedWindow = resolveWindow(options);
|
|
1646
|
+
return Boolean(resolvedWindow?.peer);
|
|
1647
|
+
};
|
|
1648
|
+
var hasHeadlessMetadataBridge = (peer) => typeof peer.authenticate === "function" && typeof peer.onMetadataMessage === "function";
|
|
1649
|
+
var requirePeerMetadataBridge = (options) => {
|
|
1650
|
+
const peer = requirePeer(options);
|
|
1651
|
+
if (!hasHeadlessMetadataBridge(peer)) {
|
|
1652
|
+
throw new Error("Peer extension metadata bridge unavailable. Install or update Peer.");
|
|
1653
|
+
}
|
|
1654
|
+
return peer;
|
|
1655
|
+
};
|
|
1656
|
+
var isPeerExtensionMetadataBridgeAvailable = (options) => {
|
|
1657
|
+
const resolvedWindow = resolveWindow(options);
|
|
1658
|
+
return Boolean(resolvedWindow?.peer && hasHeadlessMetadataBridge(resolvedWindow.peer));
|
|
1659
|
+
};
|
|
1660
|
+
var openPeerExtensionInstallPage = (options) => {
|
|
1661
|
+
const resolvedWindow = resolveWindow(options);
|
|
1662
|
+
if (!resolvedWindow) {
|
|
1663
|
+
throw new Error("Peer extension SDK requires a browser window.");
|
|
1664
|
+
}
|
|
1665
|
+
resolvedWindow.open(PEER_EXTENSION_CHROME_URL, "_blank", "noopener,noreferrer");
|
|
1666
|
+
};
|
|
1667
|
+
var getPeerExtensionState = async (options) => {
|
|
1668
|
+
if (!isPeerExtensionAvailable(options)) {
|
|
1669
|
+
return "needs_install";
|
|
1670
|
+
}
|
|
1671
|
+
try {
|
|
1672
|
+
const status = await requirePeer(options).checkConnectionStatus();
|
|
1673
|
+
return status === "connected" ? "ready" : "needs_connection";
|
|
1674
|
+
} catch {
|
|
1675
|
+
return "needs_connection";
|
|
1676
|
+
}
|
|
1677
|
+
};
|
|
1678
|
+
var createPeerExtensionSdk = (options = {}) => {
|
|
1679
|
+
const legacySdk = createLegacyPeerExtensionSdk(
|
|
1680
|
+
options
|
|
1681
|
+
);
|
|
1682
|
+
return {
|
|
1683
|
+
isAvailable: () => isPeerExtensionAvailable(options),
|
|
1684
|
+
requestConnection: () => requirePeer(options).requestConnection(),
|
|
1685
|
+
checkConnectionStatus: () => requirePeer(options).checkConnectionStatus(),
|
|
1686
|
+
getVersion: () => requirePeer(options).getVersion(),
|
|
1687
|
+
authenticate: (params) => requirePeerMetadataBridge(options).authenticate(params),
|
|
1688
|
+
onMetadataMessage: (callback) => requirePeerMetadataBridge(options).onMetadataMessage(callback),
|
|
1689
|
+
openSidebar: (route) => legacySdk.openSidebar(route),
|
|
1690
|
+
onramp: (params, callback) => legacySdk.onramp(params, callback),
|
|
1691
|
+
getOnrampTransaction: (intentHash) => legacySdk.getOnrampTransaction(intentHash),
|
|
1692
|
+
openInstallPage: () => openPeerExtensionInstallPage(options),
|
|
1693
|
+
getState: () => getPeerExtensionState(options)
|
|
1694
|
+
};
|
|
1695
|
+
};
|
|
1696
|
+
var peerExtensionSdk = createPeerExtensionSdk();
|
|
1504
1697
|
|
|
1505
1698
|
export {
|
|
1506
1699
|
ESCROW_ADDRESS,
|
|
1700
|
+
MakersCreateError,
|
|
1701
|
+
OfframpError,
|
|
1507
1702
|
normalizePaypalMeUsername,
|
|
1508
1703
|
isValidIBAN,
|
|
1509
1704
|
PLATFORMS,
|
|
1510
1705
|
PLATFORM_LIMITS,
|
|
1511
1706
|
getPlatformLimits,
|
|
1512
1707
|
getPeerExtensionRegistrationInfo,
|
|
1708
|
+
getPeerExtensionRegistrationAuthParams,
|
|
1709
|
+
completePeerExtensionRegistration,
|
|
1513
1710
|
isPeerExtensionRegistrationError,
|
|
1514
|
-
MakersCreateError,
|
|
1515
|
-
OfframpError,
|
|
1516
1711
|
enableOtc,
|
|
1517
1712
|
disableOtc,
|
|
1518
1713
|
getOtcLink,
|
|
@@ -1529,10 +1724,11 @@ export {
|
|
|
1529
1724
|
Offramp,
|
|
1530
1725
|
createOfframp,
|
|
1531
1726
|
PEER_EXTENSION_CHROME_URL,
|
|
1532
|
-
peerExtensionSdk,
|
|
1533
|
-
createPeerExtensionSdk,
|
|
1534
1727
|
isPeerExtensionAvailable,
|
|
1728
|
+
isPeerExtensionMetadataBridgeAvailable,
|
|
1535
1729
|
openPeerExtensionInstallPage,
|
|
1536
|
-
getPeerExtensionState
|
|
1730
|
+
getPeerExtensionState,
|
|
1731
|
+
createPeerExtensionSdk,
|
|
1732
|
+
peerExtensionSdk
|
|
1537
1733
|
};
|
|
1538
|
-
//# sourceMappingURL=chunk-
|
|
1734
|
+
//# sourceMappingURL=chunk-XQ7HOLLB.js.map
|