@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/dist/index.cjs CHANGED
@@ -40,8 +40,9 @@ __export(index_exports, {
40
40
  PLATFORMS: () => PLATFORMS,
41
41
  PLATFORM_LIMITS: () => PLATFORM_LIMITS,
42
42
  close: () => close,
43
+ completePeerExtensionRegistration: () => completePeerExtensionRegistration,
43
44
  createOfframp: () => createOfframp,
44
- createPeerExtensionSdk: () => import_sdk7.createPeerExtensionSdk,
45
+ createPeerExtensionSdk: () => createPeerExtensionSdk,
45
46
  createTelemetryContext: () => createTelemetryContext,
46
47
  delegate: () => delegate,
47
48
  deposits: () => deposits,
@@ -49,16 +50,18 @@ __export(index_exports, {
49
50
  emitEvent: () => emitEvent,
50
51
  enableOtc: () => enableOtc,
51
52
  getOtcLink: () => getOtcLink,
53
+ getPeerExtensionRegistrationAuthParams: () => getPeerExtensionRegistrationAuthParams,
52
54
  getPeerExtensionRegistrationInfo: () => getPeerExtensionRegistrationInfo,
53
- getPeerExtensionState: () => import_sdk7.getPeerExtensionState,
55
+ getPeerExtensionState: () => getPeerExtensionState,
54
56
  getPlatformLimits: () => getPlatformLimits,
55
- isPeerExtensionAvailable: () => import_sdk7.isPeerExtensionAvailable,
57
+ isPeerExtensionAvailable: () => isPeerExtensionAvailable,
58
+ isPeerExtensionMetadataBridgeAvailable: () => isPeerExtensionMetadataBridgeAvailable,
56
59
  isPeerExtensionRegistrationError: () => isPeerExtensionRegistrationError,
57
60
  isValidIBAN: () => isValidIBAN,
58
61
  normalizePaypalMeUsername: () => normalizePaypalMeUsername,
59
62
  offramp: () => offramp,
60
- openPeerExtensionInstallPage: () => import_sdk7.openPeerExtensionInstallPage,
61
- peerExtensionSdk: () => import_sdk7.peerExtensionSdk,
63
+ openPeerExtensionInstallPage: () => openPeerExtensionInstallPage,
64
+ peerExtensionSdk: () => peerExtensionSdk,
62
65
  sanitizeAttributionId: () => sanitizeAttributionId,
63
66
  sendTelemetryEvent: () => sendTelemetryEvent,
64
67
  undelegate: () => undelegate
@@ -72,11 +75,15 @@ var import_sdk5 = require("@zkp2p/sdk");
72
75
 
73
76
  // src/config.ts
74
77
  var import_sdk = require("@zkp2p/sdk");
75
- var SDK_VERSION = "3.0.3";
78
+ var SDK_VERSION = "3.1.0";
76
79
  var BASE_CHAIN_ID = 8453;
77
80
  var RUNTIME_ENV = "production";
78
81
  var API_BASE_URL = "https://api.zkp2p.xyz";
79
82
  var BASE_RPC_URL = "https://mainnet.base.org";
83
+ function resolveApiBaseUrl(override) {
84
+ const trimmed = override?.trim();
85
+ return (trimmed && trimmed.length > 0 ? trimmed : API_BASE_URL).replace(/\/$/, "");
86
+ }
80
87
  var contracts = (0, import_sdk.getContracts)(BASE_CHAIN_ID, RUNTIME_ENV);
81
88
  var addresses = contracts.addresses;
82
89
  var addrs = addresses;
@@ -93,6 +100,7 @@ var DEFAULT_INTENT_GUARDIAN_ADDRESS = "0xe29a5BD4D0CEbA6C125A0361E7D20ab4eA275C2
93
100
  var REFERRER = "galleonlabs";
94
101
  var MIN_DEPOSIT_USDC = 1;
95
102
  var MIN_ORDER_USDC = 1;
103
+ var MAX_ORDER_USDC = 2500;
96
104
  var INDEXER_MAX_ATTEMPTS = 12;
97
105
  var INDEXER_INITIAL_DELAY_MS = 1e3;
98
106
  var INDEXER_MAX_DELAY_MS = 1e4;
@@ -101,6 +109,41 @@ var PAYEE_REGISTRATION_TIMEOUT_MS = 8e3;
101
109
  // src/platforms.ts
102
110
  var import_sdk2 = require("@zkp2p/sdk");
103
111
  var import_zod = require("zod");
112
+
113
+ // src/errors.ts
114
+ var MakersCreateError = class extends Error {
115
+ status;
116
+ body;
117
+ constructor(message, status, body) {
118
+ super(message);
119
+ this.name = "MakersCreateError";
120
+ this.status = status;
121
+ this.body = body;
122
+ }
123
+ };
124
+ var OfframpError = class extends Error {
125
+ code;
126
+ step;
127
+ cause;
128
+ txHash;
129
+ depositId;
130
+ constructor(message, code, step, cause, details) {
131
+ super(message);
132
+ this.name = "OfframpError";
133
+ this.code = code;
134
+ this.step = step;
135
+ this.cause = cause;
136
+ this.txHash = details?.txHash;
137
+ this.depositId = details?.depositId;
138
+ }
139
+ };
140
+ function isUserCancellation(error) {
141
+ if (!(error instanceof Error)) return false;
142
+ const msg = error.message.toLowerCase();
143
+ return msg.includes("user rejected") || msg.includes("user denied") || msg.includes("user cancelled") || msg.includes("rejected the request") || msg.includes("action_rejected");
144
+ }
145
+
146
+ // src/platforms.ts
104
147
  var PAYMENT_CATALOG = (0, import_sdk2.getPaymentMethodsCatalog)(BASE_CHAIN_ID, RUNTIME_ENV);
105
148
  var ZELLE_HASH_LOOKUP_NAMES = ["zelle", "zelle-bofa", "zelle-chase", "zelle-citi"];
106
149
  var FALLBACK_CURRENCIES = {
@@ -461,6 +504,146 @@ function getPeerExtensionRegistrationInfo(platform) {
461
504
  const entry = getPlatformById(platform);
462
505
  return entry?.extensionRegistration ?? null;
463
506
  }
507
+ function getPeerExtensionRegistrationAuthParams(platform, options = {}) {
508
+ const info = getPeerExtensionRegistrationInfo(platform);
509
+ if (!info) return null;
510
+ const params = {
511
+ actionType: `transfer_${info.providerId}`,
512
+ captureMode: "sellerCredential",
513
+ platform: info.providerId
514
+ };
515
+ if (options.attestationServiceUrl) {
516
+ params.attestationServiceUrl = options.attestationServiceUrl;
517
+ }
518
+ return params;
519
+ }
520
+ function resolveRegistrationProcessor(platform) {
521
+ const info = getPeerExtensionRegistrationInfo(platform.id);
522
+ if (info?.providerId === "paypal" || info?.providerId === "wise") {
523
+ return info.providerId;
524
+ }
525
+ throw new Error(`${platform.name} does not require Peer extension registration.`);
526
+ }
527
+ async function postMakerCreate(processorName, payload, apiBaseUrl = API_BASE_URL) {
528
+ const controller = new AbortController();
529
+ const timeout = setTimeout(() => controller.abort(), PAYEE_REGISTRATION_TIMEOUT_MS);
530
+ try {
531
+ const res = await fetch(`${apiBaseUrl}/v2/makers/create`, {
532
+ method: "POST",
533
+ headers: { "Content-Type": "application/json" },
534
+ body: JSON.stringify({ processorName, ...payload }),
535
+ signal: controller.signal
536
+ });
537
+ if (!res.ok) {
538
+ const txt = await res.text().catch(() => "");
539
+ let detail = txt || res.statusText;
540
+ try {
541
+ const parsed = JSON.parse(txt);
542
+ if (typeof parsed.message === "string" && parsed.message.trim()) {
543
+ detail = parsed.message;
544
+ }
545
+ } catch {
546
+ }
547
+ throw new MakersCreateError(
548
+ `makers/create failed (${res.status}): ${detail}`,
549
+ res.status,
550
+ txt
551
+ );
552
+ }
553
+ const json = await res.json();
554
+ if (!json.success || !json.responseObject?.hashedOnchainId) {
555
+ throw new MakersCreateError(
556
+ json.message || "makers/create returned no hashedOnchainId",
557
+ json.statusCode ?? null,
558
+ ""
559
+ );
560
+ }
561
+ return json.responseObject.hashedOnchainId;
562
+ } finally {
563
+ clearTimeout(timeout);
564
+ }
565
+ }
566
+ function requireSarCredentialCapture(capturedMetadata) {
567
+ const capture = capturedMetadata.sarCredentialCapture;
568
+ if (!capture?.credentialBundle) {
569
+ throw new Error("Peer metadata did not include a seller credential bundle.");
570
+ }
571
+ if (!capture.offchainId) {
572
+ throw new Error("Peer metadata did not include seller credential offchainId.");
573
+ }
574
+ return capture;
575
+ }
576
+ async function uploadSellerCredentialBundle(processorName, payeeHash, bundle) {
577
+ const controller = new AbortController();
578
+ const timeout = setTimeout(() => controller.abort(), PAYEE_REGISTRATION_TIMEOUT_MS);
579
+ try {
580
+ const res = await fetch(
581
+ `${API_BASE_URL}/v2/makers/${encodeURIComponent(processorName)}/${encodeURIComponent(payeeHash)}/seller-credential`,
582
+ {
583
+ method: "POST",
584
+ headers: { "Content-Type": "application/json" },
585
+ body: JSON.stringify(bundle),
586
+ signal: controller.signal
587
+ }
588
+ );
589
+ if (!res.ok) {
590
+ const txt = await res.text().catch(() => "");
591
+ let detail = txt || res.statusText;
592
+ try {
593
+ const parsed = JSON.parse(txt);
594
+ if (typeof parsed.message === "string" && parsed.message.trim()) {
595
+ detail = parsed.message;
596
+ }
597
+ } catch {
598
+ }
599
+ throw new Error(`seller-credential upload failed (${res.status}): ${detail}`);
600
+ }
601
+ const json = await res.json();
602
+ if (!json.success || !json.responseObject) {
603
+ throw new Error(json.message || "seller-credential upload returned no status.");
604
+ }
605
+ return json;
606
+ } finally {
607
+ clearTimeout(timeout);
608
+ }
609
+ }
610
+ async function completePeerExtensionRegistration(input) {
611
+ const processorName = resolveRegistrationProcessor(input.platform);
612
+ if (input.capturedMetadata.platform !== processorName) {
613
+ throw new Error(
614
+ `Peer metadata is for ${input.capturedMetadata.platform}, not ${processorName}.`
615
+ );
616
+ }
617
+ const sarCredentialCapture = requireSarCredentialCapture(input.capturedMetadata);
618
+ const bundle = sarCredentialCapture.credentialBundle;
619
+ if (bundle.platform.toLowerCase() !== processorName) {
620
+ throw new Error("Seller credential bundle platform does not match registration platform.");
621
+ }
622
+ const validation = input.platform.validate(input.identifier);
623
+ if (!validation.valid) {
624
+ throw new Error(validation.error || "Invalid identifier");
625
+ }
626
+ const payload = buildDepositData(processorName, sarCredentialCapture.offchainId);
627
+ if (payload.offchainId !== validation.normalized) {
628
+ throw new Error("Seller credential offchainId does not match registration identifier.");
629
+ }
630
+ const hashedOnchainId = processorName === "wise" ? bundle.payeeIdHash : await postMakerCreate(processorName, payload);
631
+ if (hashedOnchainId.toLowerCase() !== bundle.payeeIdHash.toLowerCase()) {
632
+ throw new Error("Seller credential payee hash does not match registered payee details.");
633
+ }
634
+ const sellerCredentialResponse = await uploadSellerCredentialBundle(
635
+ processorName,
636
+ hashedOnchainId,
637
+ bundle
638
+ );
639
+ return {
640
+ processorName,
641
+ offchainId: payload.offchainId,
642
+ hashedOnchainId,
643
+ sellerCredentialResponse,
644
+ sellerCredentialStatus: sellerCredentialResponse.responseObject
645
+ };
646
+ }
464
647
  var EXTENSION_REGISTRATION_ERROR_PATTERNS = ["creating the maker", "create the maker"];
465
648
  function isPeerExtensionRegistrationError(platform, message, statusCode) {
466
649
  const info = getPeerExtensionRegistrationInfo(platform);
@@ -472,39 +655,6 @@ function isPeerExtensionRegistrationError(platform, message, statusCode) {
472
655
  return EXTENSION_REGISTRATION_ERROR_PATTERNS.some((p) => lower.includes(p));
473
656
  }
474
657
 
475
- // src/errors.ts
476
- var MakersCreateError = class extends Error {
477
- status;
478
- body;
479
- constructor(message, status, body) {
480
- super(message);
481
- this.name = "MakersCreateError";
482
- this.status = status;
483
- this.body = body;
484
- }
485
- };
486
- var OfframpError = class extends Error {
487
- code;
488
- step;
489
- cause;
490
- txHash;
491
- depositId;
492
- constructor(message, code, step, cause, details) {
493
- super(message);
494
- this.name = "OfframpError";
495
- this.code = code;
496
- this.step = step;
497
- this.cause = cause;
498
- this.txHash = details?.txHash;
499
- this.depositId = details?.depositId;
500
- }
501
- };
502
- function isUserCancellation(error) {
503
- if (!(error instanceof Error)) return false;
504
- const msg = error.message.toLowerCase();
505
- return msg.includes("user rejected") || msg.includes("user denied") || msg.includes("user cancelled") || msg.includes("rejected the request") || msg.includes("action_rejected");
506
- }
507
-
508
658
  // src/otc.ts
509
659
  var import_viem = require("viem");
510
660
  var import_chains = require("viem/chains");
@@ -512,13 +662,13 @@ var import_WhitelistPreIntentHook = __toESM(require("@zkp2p/contracts-v2/abis/ba
512
662
 
513
663
  // src/sdk-client.ts
514
664
  var import_sdk3 = require("@zkp2p/sdk");
515
- function createSdkClient(walletClient) {
665
+ function createSdkClient(walletClient, apiBaseUrl = API_BASE_URL) {
516
666
  return new import_sdk3.OfframpClient({
517
667
  walletClient,
518
668
  chainId: BASE_CHAIN_ID,
519
669
  runtimeEnv: RUNTIME_ENV,
520
670
  rpcUrl: BASE_RPC_URL,
521
- baseApiUrl: API_BASE_URL
671
+ baseApiUrl: apiBaseUrl
522
672
  });
523
673
  }
524
674
 
@@ -929,50 +1079,11 @@ function extractDepositIdFromLogs(logs) {
929
1079
  }
930
1080
  return null;
931
1081
  }
932
- async function registerPayeeDetails(processorName, payload) {
1082
+ async function validatePayeeDetails(processorName, offchainId, apiBaseUrl = API_BASE_URL) {
933
1083
  const controller = new AbortController();
934
1084
  const timeout = setTimeout(() => controller.abort(), PAYEE_REGISTRATION_TIMEOUT_MS);
935
1085
  try {
936
- const res = await fetch(`${API_BASE_URL}/v2/makers/create`, {
937
- method: "POST",
938
- headers: { "Content-Type": "application/json" },
939
- body: JSON.stringify({ processorName, ...payload }),
940
- signal: controller.signal
941
- });
942
- if (!res.ok) {
943
- const txt = await res.text().catch(() => "");
944
- let detail = txt || res.statusText;
945
- try {
946
- const parsed = JSON.parse(txt);
947
- if (typeof parsed.message === "string" && parsed.message.trim()) {
948
- detail = parsed.message;
949
- }
950
- } catch {
951
- }
952
- throw new MakersCreateError(
953
- `makers/create failed (${res.status}): ${detail}`,
954
- res.status,
955
- txt
956
- );
957
- }
958
- const json = await res.json();
959
- if (!json.success || !json.responseObject?.hashedOnchainId) {
960
- throw new MakersCreateError(
961
- json.message || "makers/create returned no hashedOnchainId",
962
- json.statusCode ?? null,
963
- ""
964
- );
965
- }
966
- return json.responseObject.hashedOnchainId;
967
- } finally {
968
- clearTimeout(timeout);
969
- }
970
- }
971
- async function validatePayeeDetails(processorName, offchainId) {
972
- const controller = new AbortController();
973
- const timeout = setTimeout(() => controller.abort(), PAYEE_REGISTRATION_TIMEOUT_MS);
974
- try {
975
- const res = await fetch(`${API_BASE_URL}/v2/makers/validate`, {
1086
+ const res = await fetch(`${apiBaseUrl}/v2/makers/validate`, {
976
1087
  method: "POST",
977
1088
  headers: { "Content-Type": "application/json" },
978
1089
  body: JSON.stringify({ processorName, offchainId }),
@@ -1050,10 +1161,11 @@ async function findUndelegatedDeposit(walletAddress) {
1050
1161
  return null;
1051
1162
  }
1052
1163
  }
1053
- async function offramp(walletClient, params, onProgress, telemetryContext) {
1164
+ async function offramp(walletClient, params, onProgress, telemetryContext, apiBaseUrl) {
1054
1165
  const { amount, platform, currency, identifier } = params;
1055
1166
  const platformId = platform.id;
1056
1167
  const currencyCode = currency.code;
1168
+ const resolvedApiBaseUrl = resolveApiBaseUrl(apiBaseUrl);
1057
1169
  const telemetry = telemetryContext ?? createTelemetryContext({
1058
1170
  sdkVersion: SDK_VERSION,
1059
1171
  telemetry: true,
@@ -1098,7 +1210,7 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
1098
1210
  const existing = await findUndelegatedDeposit(walletAddress);
1099
1211
  if (existing) {
1100
1212
  emitProgress({ step: "resuming", depositId: existing.depositId });
1101
- const client2 = createSdkClient(walletClient);
1213
+ const client2 = createSdkClient(walletClient, resolvedApiBaseUrl);
1102
1214
  const txOverrides2 = { referrer: [REFERRER] };
1103
1215
  try {
1104
1216
  const result2 = await client2.setRateManager({
@@ -1134,7 +1246,7 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
1134
1246
  const truncatedAmount = amt.toFixed(6).replace(/\.?0+$/, "");
1135
1247
  const amountUnits = usdcToUnits(truncatedAmount);
1136
1248
  const minUnits = usdcToUnits(String(MIN_ORDER_USDC));
1137
- const maxUnits = usdcToUnits(String(Math.min(amt, 2500)));
1249
+ const maxUnits = usdcToUnits(String(Math.min(amt, MAX_ORDER_USDC)));
1138
1250
  try {
1139
1251
  const publicClient = (0, import_viem3.createPublicClient)({ chain: import_chains3.base, transport: (0, import_viem3.http)(BASE_RPC_URL) });
1140
1252
  const balance = await publicClient.readContract({
@@ -1163,7 +1275,11 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
1163
1275
  }
1164
1276
  const canonicalName = platformId.startsWith("zelle") ? "zelle" : platformId;
1165
1277
  if (!getPeerExtensionRegistrationInfo(platformId)) {
1166
- const outcome = await validatePayeeDetails(canonicalName, normalizedIdentifier);
1278
+ const outcome = await validatePayeeDetails(
1279
+ canonicalName,
1280
+ normalizedIdentifier,
1281
+ resolvedApiBaseUrl
1282
+ );
1167
1283
  if (outcome === "invalid") {
1168
1284
  throw new OfframpError(
1169
1285
  `Couldn't verify that ${platform.name} ${platform.identifier.label.toLowerCase()}. Double-check it and try again.`,
@@ -1172,7 +1288,7 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
1172
1288
  );
1173
1289
  }
1174
1290
  }
1175
- const client = createSdkClient(walletClient);
1291
+ const client = createSdkClient(walletClient, resolvedApiBaseUrl);
1176
1292
  const txOverrides = { referrer: [REFERRER] };
1177
1293
  emitProgress({ step: "approving" });
1178
1294
  try {
@@ -1198,13 +1314,13 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
1198
1314
  let hashedOnchainId;
1199
1315
  try {
1200
1316
  const payeePayload = buildDepositData(canonicalName, normalizedIdentifier);
1201
- hashedOnchainId = await registerPayeeDetails(canonicalName, payeePayload);
1317
+ hashedOnchainId = await postMakerCreate(canonicalName, payeePayload, resolvedApiBaseUrl);
1202
1318
  } catch (err) {
1203
1319
  const status = err instanceof MakersCreateError ? err.status : null;
1204
1320
  const message = err instanceof Error ? err.message : String(err);
1205
1321
  if (isPeerExtensionRegistrationError(canonicalName, message, status)) {
1206
1322
  throw new OfframpError(
1207
- `${platform.name} maker is not yet registered in the Peer extension. Verify this handle in the extension, then retry.`,
1323
+ `${platform.name} maker is not yet registered in the Peer extension. Register this handle with Peer, then retry.`,
1208
1324
  "EXTENSION_REGISTRATION_REQUIRED",
1209
1325
  "registering",
1210
1326
  err
@@ -1396,6 +1512,14 @@ var CURRENCIES = buildCurrencies();
1396
1512
  // src/offramp.ts
1397
1513
  var IDEMPOTENCY_TTL_MS = 10 * 60 * 1e3;
1398
1514
  var IDEMPOTENCY_STORAGE_PREFIX = "offramp:idempotency:";
1515
+ var warnedIdempotencyUnavailable = false;
1516
+ function warnIdempotencyUnavailableOnce() {
1517
+ if (warnedIdempotencyUnavailable) return;
1518
+ warnedIdempotencyUnavailable = true;
1519
+ console.warn(
1520
+ "[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."
1521
+ );
1522
+ }
1399
1523
  function getWalletAddress(walletClient) {
1400
1524
  const address = walletClient.account?.address;
1401
1525
  if (!address) {
@@ -1466,8 +1590,10 @@ function buildCurrencyGroups() {
1466
1590
  var Offramp = class {
1467
1591
  walletClient;
1468
1592
  telemetry;
1593
+ apiBaseUrl;
1469
1594
  constructor(options) {
1470
1595
  this.walletClient = options.walletClient;
1596
+ this.apiBaseUrl = options.apiBaseUrl;
1471
1597
  this.telemetry = createTelemetryContext({
1472
1598
  sdkVersion: SDK_VERSION,
1473
1599
  telemetry: options.telemetry,
@@ -1490,6 +1616,9 @@ var Offramp = class {
1490
1616
  referralId: flowTelemetry.referralId
1491
1617
  };
1492
1618
  const sanitizedKey = sanitizeAttributionId(params.idempotencyKey);
1619
+ if (sanitizedKey && typeof sessionStorage === "undefined") {
1620
+ warnIdempotencyUnavailableOnce();
1621
+ }
1493
1622
  const walletAddress = sanitizedKey ? getWalletAddress(this.walletClient) : null;
1494
1623
  const storageKey = walletAddress && sanitizedKey ? getIdempotencyStorageKey(walletAddress, sanitizedKey) : null;
1495
1624
  if (storageKey) {
@@ -1500,7 +1629,8 @@ var Offramp = class {
1500
1629
  this.walletClient,
1501
1630
  sanitizedParams,
1502
1631
  onProgress,
1503
- flowTelemetry
1632
+ flowTelemetry,
1633
+ this.apiBaseUrl
1504
1634
  );
1505
1635
  if (storageKey) {
1506
1636
  writeIdempotencyResult(storageKey, result);
@@ -1556,8 +1686,8 @@ var OFFRAMP_ERROR_CODES = {
1556
1686
  * handle in the Peer extension yet. Thrown from `offramp()` for PayPal
1557
1687
  * and Wise when `/v2/makers/create` returns 400 or a "creating the maker"
1558
1688
  * message. Recover by prompting the user through the Peer extension via
1559
- * `usePeerExtensionRegistration(platform)` (React) or `peerExtensionSdk`
1560
- * directly, then call `offramp()` again.
1689
+ * `usePeerExtensionRegistration(platform)` (React) or
1690
+ * `completePeerExtensionRegistration(...)`, then retrying `offramp()`.
1561
1691
  */
1562
1692
  EXTENSION_REGISTRATION_REQUIRED: "EXTENSION_REGISTRATION_REQUIRED",
1563
1693
  DEPOSIT_FAILED: "DEPOSIT_FAILED",
@@ -1569,6 +1699,78 @@ var OFFRAMP_ERROR_CODES = {
1569
1699
 
1570
1700
  // src/extension.ts
1571
1701
  var import_sdk7 = require("@zkp2p/sdk");
1702
+ var resolveWindow = (options) => {
1703
+ if (options?.window) {
1704
+ return options.window;
1705
+ }
1706
+ if (typeof window === "undefined") {
1707
+ return void 0;
1708
+ }
1709
+ return window;
1710
+ };
1711
+ var requirePeer = (options) => {
1712
+ const resolvedWindow = resolveWindow(options);
1713
+ if (!resolvedWindow) {
1714
+ throw new Error("Peer extension SDK requires a browser window.");
1715
+ }
1716
+ if (!resolvedWindow.peer) {
1717
+ throw new Error("Peer extension not available. Install or enable the Peer extension.");
1718
+ }
1719
+ return resolvedWindow.peer;
1720
+ };
1721
+ var isPeerExtensionAvailable = (options) => {
1722
+ const resolvedWindow = resolveWindow(options);
1723
+ return Boolean(resolvedWindow?.peer);
1724
+ };
1725
+ var hasHeadlessMetadataBridge = (peer) => typeof peer.authenticate === "function" && typeof peer.onMetadataMessage === "function";
1726
+ var requirePeerMetadataBridge = (options) => {
1727
+ const peer = requirePeer(options);
1728
+ if (!hasHeadlessMetadataBridge(peer)) {
1729
+ throw new Error("Peer extension metadata bridge unavailable. Install or update Peer.");
1730
+ }
1731
+ return peer;
1732
+ };
1733
+ var isPeerExtensionMetadataBridgeAvailable = (options) => {
1734
+ const resolvedWindow = resolveWindow(options);
1735
+ return Boolean(resolvedWindow?.peer && hasHeadlessMetadataBridge(resolvedWindow.peer));
1736
+ };
1737
+ var openPeerExtensionInstallPage = (options) => {
1738
+ const resolvedWindow = resolveWindow(options);
1739
+ if (!resolvedWindow) {
1740
+ throw new Error("Peer extension SDK requires a browser window.");
1741
+ }
1742
+ resolvedWindow.open(import_sdk7.PEER_EXTENSION_CHROME_URL, "_blank", "noopener,noreferrer");
1743
+ };
1744
+ var getPeerExtensionState = async (options) => {
1745
+ if (!isPeerExtensionAvailable(options)) {
1746
+ return "needs_install";
1747
+ }
1748
+ try {
1749
+ const status = await requirePeer(options).checkConnectionStatus();
1750
+ return status === "connected" ? "ready" : "needs_connection";
1751
+ } catch {
1752
+ return "needs_connection";
1753
+ }
1754
+ };
1755
+ var createPeerExtensionSdk = (options = {}) => {
1756
+ const legacySdk = (0, import_sdk7.createPeerExtensionSdk)(
1757
+ options
1758
+ );
1759
+ return {
1760
+ isAvailable: () => isPeerExtensionAvailable(options),
1761
+ requestConnection: () => requirePeer(options).requestConnection(),
1762
+ checkConnectionStatus: () => requirePeer(options).checkConnectionStatus(),
1763
+ getVersion: () => requirePeer(options).getVersion(),
1764
+ authenticate: (params) => requirePeerMetadataBridge(options).authenticate(params),
1765
+ onMetadataMessage: (callback) => requirePeerMetadataBridge(options).onMetadataMessage(callback),
1766
+ openSidebar: (route) => legacySdk.openSidebar(route),
1767
+ onramp: (params, callback) => legacySdk.onramp(params, callback),
1768
+ getOnrampTransaction: (intentHash) => legacySdk.getOnrampTransaction(intentHash),
1769
+ openInstallPage: () => openPeerExtensionInstallPage(options),
1770
+ getState: () => getPeerExtensionState(options)
1771
+ };
1772
+ };
1773
+ var peerExtensionSdk = createPeerExtensionSdk();
1572
1774
  // Annotate the CommonJS export names for ESM import in node:
1573
1775
  0 && (module.exports = {
1574
1776
  CURRENCIES,
@@ -1581,6 +1783,7 @@ var import_sdk7 = require("@zkp2p/sdk");
1581
1783
  PLATFORMS,
1582
1784
  PLATFORM_LIMITS,
1583
1785
  close,
1786
+ completePeerExtensionRegistration,
1584
1787
  createOfframp,
1585
1788
  createPeerExtensionSdk,
1586
1789
  createTelemetryContext,
@@ -1590,10 +1793,12 @@ var import_sdk7 = require("@zkp2p/sdk");
1590
1793
  emitEvent,
1591
1794
  enableOtc,
1592
1795
  getOtcLink,
1796
+ getPeerExtensionRegistrationAuthParams,
1593
1797
  getPeerExtensionRegistrationInfo,
1594
1798
  getPeerExtensionState,
1595
1799
  getPlatformLimits,
1596
1800
  isPeerExtensionAvailable,
1801
+ isPeerExtensionMetadataBridgeAvailable,
1597
1802
  isPeerExtensionRegistrationError,
1598
1803
  isValidIBAN,
1599
1804
  normalizePaypalMeUsername,