@usdctofiat/offramp 1.1.3 → 1.3.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
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,38 +15,41 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // src/index.ts
31
21
  var index_exports = {};
32
22
  __export(index_exports, {
33
23
  CURRENCIES: () => CURRENCIES,
24
+ ESCROW_ADDRESS: () => ESCROW_ADDRESS,
25
+ OFFRAMP_ERROR_CODES: () => OFFRAMP_ERROR_CODES,
26
+ Offramp: () => Offramp,
34
27
  OfframpError: () => OfframpError,
35
28
  PLATFORMS: () => PLATFORMS,
36
29
  close: () => close,
30
+ createOfframp: () => createOfframp,
31
+ createTelemetryContext: () => createTelemetryContext,
32
+ delegate: () => delegate,
37
33
  deposits: () => deposits,
38
34
  disableOtc: () => disableOtc,
35
+ emitEvent: () => emitEvent,
39
36
  enableOtc: () => enableOtc,
40
37
  getOtcLink: () => getOtcLink,
41
- offramp: () => offramp
38
+ offramp: () => offramp,
39
+ sanitizeAttributionId: () => sanitizeAttributionId,
40
+ sendTelemetryEvent: () => sendTelemetryEvent,
41
+ undelegate: () => undelegate
42
42
  });
43
43
  module.exports = __toCommonJS(index_exports);
44
44
 
45
45
  // src/deposit.ts
46
46
  var import_viem3 = require("viem");
47
- var import_chains = require("viem/chains");
48
- var import_sdk4 = require("@zkp2p/sdk");
47
+ var import_chains3 = require("viem/chains");
48
+ var import_sdk5 = require("@zkp2p/sdk");
49
49
 
50
50
  // src/config.ts
51
51
  var import_sdk = require("@zkp2p/sdk");
52
+ var SDK_VERSION = "1.2.0";
52
53
  var BASE_CHAIN_ID = 8453;
53
54
  var RUNTIME_ENV = "production";
54
55
  var API_BASE_URL = "https://api.zkp2p.xyz";
@@ -64,6 +65,7 @@ var GATING_SERVICE_ADDRESS = (0, import_sdk.getGatingServiceAddress)(
64
65
  );
65
66
  var DELEGATE_RATE_MANAGER_ID = "0x8666d6fb0f6797c56e95339fd7ca82fdd348b9db200e10a4c4aa0a0b879fc41c";
66
67
  var RATE_MANAGER_REGISTRY_ADDRESS = "0xeed7db23e724ac4590d6db6f78fda6db203535f3";
68
+ var DELEGATE_MANAGER_FEE_BPS = 10;
67
69
  var REFERRER = "galleonlabs";
68
70
  var MIN_DEPOSIT_USDC = 1;
69
71
  var MIN_ORDER_USDC = 1;
@@ -387,6 +389,7 @@ function isUserCancellation(error) {
387
389
 
388
390
  // src/otc.ts
389
391
  var import_viem = require("viem");
392
+ var import_chains = require("viem/chains");
390
393
 
391
394
  // ../../node_modules/@zkp2p/contracts-v2/abis/base/WhitelistPreIntentHook.json
392
395
  var WhitelistPreIntentHook_default = [
@@ -731,6 +734,18 @@ var WhitelistPreIntentHook_default = [
731
734
  }
732
735
  ];
733
736
 
737
+ // src/sdk-client.ts
738
+ var import_sdk3 = require("@zkp2p/sdk");
739
+ function createSdkClient(walletClient) {
740
+ return new import_sdk3.OfframpClient({
741
+ walletClient,
742
+ chainId: BASE_CHAIN_ID,
743
+ runtimeEnv: RUNTIME_ENV,
744
+ rpcUrl: BASE_RPC_URL,
745
+ baseApiUrl: API_BASE_URL
746
+ });
747
+ }
748
+
734
749
  // src/otc.ts
735
750
  var WHITELIST_HOOK_ADDRESS = "0xda023Ea0d789A41BcF5866F7B6BBd2CaDF9b79B8";
736
751
  var OTC_BASE_URL = "https://usdctofiat.xyz";
@@ -748,12 +763,7 @@ async function enableOtc(walletClient, depositId, takerAddress, escrowAddress) {
748
763
  escrowAddress: escrow
749
764
  });
750
765
  if (currentHook !== import_viem.zeroAddress) {
751
- const isAlready = await readIsWhitelisted(
752
- walletClient,
753
- escrow,
754
- depositIdBig,
755
- taker
756
- );
766
+ const isAlready = await readIsWhitelisted(escrow, depositIdBig, taker);
757
767
  if (isAlready) {
758
768
  return {
759
769
  depositId,
@@ -824,13 +834,8 @@ async function writeContract(walletClient, functionName, args) {
824
834
  args
825
835
  });
826
836
  }
827
- async function readIsWhitelisted(walletClient, escrow, depositId, taker) {
828
- const { createPublicClient: createPublicClient2, http: http2 } = await import("viem");
829
- const { base: base2 } = await import("viem/chains");
830
- const publicClient = createPublicClient2({
831
- chain: base2,
832
- transport: http2("https://mainnet.base.org")
833
- });
837
+ async function readIsWhitelisted(escrow, depositId, taker) {
838
+ const publicClient = (0, import_viem.createPublicClient)({ chain: import_chains.base, transport: (0, import_viem.http)(BASE_RPC_URL) });
834
839
  return publicClient.readContract({
835
840
  address: WHITELIST_HOOK_ADDRESS,
836
841
  abi: WhitelistPreIntentHook_default,
@@ -841,13 +846,14 @@ async function readIsWhitelisted(walletClient, escrow, depositId, taker) {
841
846
 
842
847
  // src/queries.ts
843
848
  var import_viem2 = require("viem");
844
- var import_sdk3 = require("@zkp2p/sdk");
849
+ var import_chains2 = require("viem/chains");
850
+ var import_sdk4 = require("@zkp2p/sdk");
845
851
  var indexerService = null;
846
852
  function getIndexerService() {
847
853
  if (!indexerService) {
848
- const endpoint = (0, import_sdk3.defaultIndexerEndpoint)("PRODUCTION");
849
- const client = new import_sdk3.IndexerClient(endpoint);
850
- indexerService = new import_sdk3.IndexerDepositService(client);
854
+ const endpoint = (0, import_sdk4.defaultIndexerEndpoint)("PRODUCTION");
855
+ const client = new import_sdk4.IndexerClient(endpoint);
856
+ indexerService = new import_sdk4.IndexerDepositService(client);
851
857
  }
852
858
  return indexerService;
853
859
  }
@@ -881,7 +887,7 @@ function resolveMethodNames(hashes) {
881
887
  return Array.from(names);
882
888
  }
883
889
  function mapDeposit(d) {
884
- const delegationState = (0, import_sdk3.classifyDelegationState)(
890
+ const delegationState = (0, import_sdk4.classifyDelegationState)(
885
891
  d.rateManagerId ?? void 0,
886
892
  d.rateManagerAddress ?? void 0,
887
893
  DELEGATE_RATE_MANAGER_ID,
@@ -898,7 +904,7 @@ function mapDeposit(d) {
898
904
  fulfilledIntents: d.fulfilledIntents ?? 0,
899
905
  paymentMethods: resolveMethodNames(d.paymentMethods),
900
906
  currencies: d.currencies.map((c) => {
901
- const info = (0, import_sdk3.getCurrencyInfoFromHash)(c.currencyCode);
907
+ const info = (0, import_sdk4.getCurrencyInfoFromHash)(c.currencyCode);
902
908
  return info?.currencyCode ?? c.currencyCode;
903
909
  }),
904
910
  rateSource: d.currencies[0]?.rateSource || "unknown",
@@ -914,6 +920,18 @@ function extractTxHash(result) {
914
920
  return result.transactionHash;
915
921
  throw new Error("Unexpected transaction result format");
916
922
  }
923
+ var ESCROW_V2_ABI = [
924
+ {
925
+ name: "clearRateManager",
926
+ type: "function",
927
+ stateMutability: "nonpayable",
928
+ inputs: [{ name: "depositId", type: "uint256" }],
929
+ outputs: []
930
+ }
931
+ ];
932
+ function appendReferrerAttribution(calldata) {
933
+ return (0, import_viem2.concatHex)([calldata, (0, import_sdk4.getAttributionDataSuffix)([REFERRER])]);
934
+ }
917
935
  async function deposits(walletAddress) {
918
936
  const service = getIndexerService();
919
937
  const raw = await service.fetchDepositsWithRelations(
@@ -936,6 +954,159 @@ async function close(walletClient, depositId, escrowAddress) {
936
954
  });
937
955
  return extractTxHash(result);
938
956
  }
957
+ async function delegate(walletClient, depositId, escrowAddress) {
958
+ const client = createSdkClient(walletClient);
959
+ const result = await client.setRateManager({
960
+ depositId: BigInt(depositId),
961
+ rateManagerAddress: RATE_MANAGER_REGISTRY_ADDRESS,
962
+ rateManagerId: DELEGATE_RATE_MANAGER_ID,
963
+ escrowAddress: escrowAddress || ESCROW_ADDRESS,
964
+ txOverrides: { referrer: [REFERRER] }
965
+ });
966
+ return extractTxHash(result);
967
+ }
968
+ async function undelegate(walletClient, depositId, escrowAddress) {
969
+ const account = walletClient.account;
970
+ if (!account) {
971
+ throw new Error("Wallet client has no account. Connect a wallet first.");
972
+ }
973
+ const data = appendReferrerAttribution(
974
+ (0, import_viem2.encodeFunctionData)({
975
+ abi: ESCROW_V2_ABI,
976
+ functionName: "clearRateManager",
977
+ args: [BigInt(depositId)]
978
+ })
979
+ );
980
+ const hash = await walletClient.sendTransaction({
981
+ account,
982
+ chain: import_chains2.base,
983
+ data,
984
+ to: escrowAddress || ESCROW_ADDRESS
985
+ });
986
+ const publicClient = (0, import_viem2.createPublicClient)({
987
+ chain: import_chains2.base,
988
+ transport: (0, import_viem2.http)(BASE_RPC_URL)
989
+ });
990
+ try {
991
+ const receipt = await publicClient.waitForTransactionReceipt({
992
+ hash,
993
+ confirmations: 1,
994
+ timeout: 12e4,
995
+ pollingInterval: 4e3
996
+ });
997
+ if (receipt.status !== "success") {
998
+ throw new Error("Undelegation transaction failed");
999
+ }
1000
+ } catch (err) {
1001
+ const isTimeout = err instanceof Error && err.message.toLowerCase().includes("timed out");
1002
+ if (!isTimeout) {
1003
+ throw err;
1004
+ }
1005
+ }
1006
+ return hash;
1007
+ }
1008
+
1009
+ // src/telemetry.ts
1010
+ var SDK_EVENTS_ENDPOINT = "https://usdctofiat.xyz/api/sdk-events";
1011
+ var MAX_BATCH_SIZE = 50;
1012
+ var FLUSH_DELAY_MS = 180;
1013
+ var TELEMETRY_TIMEOUT_MS = 2e3;
1014
+ var queuedEvents = [];
1015
+ var flushTimer = null;
1016
+ var flushInFlight = false;
1017
+ function sanitizeAttributionId(raw) {
1018
+ if (typeof raw !== "string") return void 0;
1019
+ const stripped = raw.trim().replace(/[^a-zA-Z0-9_-]/g, "");
1020
+ if (!stripped) return void 0;
1021
+ if (stripped.length > 64) return void 0;
1022
+ return stripped;
1023
+ }
1024
+ function scheduleFlush() {
1025
+ if (flushTimer != null) return;
1026
+ flushTimer = setTimeout(() => {
1027
+ flushTimer = null;
1028
+ void flushQueue();
1029
+ }, FLUSH_DELAY_MS);
1030
+ }
1031
+ async function postBatch(batch) {
1032
+ if (!batch.length) return;
1033
+ const body = JSON.stringify(batch);
1034
+ try {
1035
+ if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
1036
+ const blob = new Blob([body], { type: "application/json" });
1037
+ const accepted = navigator.sendBeacon(SDK_EVENTS_ENDPOINT, blob);
1038
+ if (accepted) return;
1039
+ }
1040
+ } catch {
1041
+ }
1042
+ try {
1043
+ const controller = typeof AbortController !== "undefined" ? new AbortController() : null;
1044
+ const timeout = controller ? setTimeout(() => controller.abort(), TELEMETRY_TIMEOUT_MS) : null;
1045
+ await fetch(SDK_EVENTS_ENDPOINT, {
1046
+ method: "POST",
1047
+ headers: { "Content-Type": "application/json" },
1048
+ body,
1049
+ keepalive: true,
1050
+ signal: controller?.signal
1051
+ }).catch(() => {
1052
+ });
1053
+ if (timeout) clearTimeout(timeout);
1054
+ } catch {
1055
+ }
1056
+ }
1057
+ async function flushQueue() {
1058
+ if (flushInFlight) return;
1059
+ if (!queuedEvents.length) return;
1060
+ flushInFlight = true;
1061
+ try {
1062
+ while (queuedEvents.length > 0) {
1063
+ const batch = queuedEvents.slice(0, MAX_BATCH_SIZE);
1064
+ queuedEvents = queuedEvents.slice(batch.length);
1065
+ await postBatch(batch);
1066
+ }
1067
+ } finally {
1068
+ flushInFlight = false;
1069
+ }
1070
+ }
1071
+ function emitEvent(name, payload) {
1072
+ try {
1073
+ queuedEvents.push({
1074
+ name,
1075
+ payload,
1076
+ ts: Date.now()
1077
+ });
1078
+ if (queuedEvents.length >= MAX_BATCH_SIZE) {
1079
+ void flushQueue();
1080
+ return;
1081
+ }
1082
+ scheduleFlush();
1083
+ } catch {
1084
+ }
1085
+ }
1086
+ function sendTelemetryEvent(name, payload) {
1087
+ emitEvent(name, payload);
1088
+ }
1089
+ function createTelemetryContext(options) {
1090
+ const integratorId = sanitizeAttributionId(options.integratorId);
1091
+ const referralId = sanitizeAttributionId(options.referralId);
1092
+ const enabled = options.telemetry !== false;
1093
+ const sdkVersion = options.sdkVersion;
1094
+ return {
1095
+ enabled,
1096
+ sdkVersion,
1097
+ integratorId,
1098
+ referralId,
1099
+ emit(name, payload = {}) {
1100
+ if (!enabled) return;
1101
+ emitEvent(name, {
1102
+ sdkVersion,
1103
+ integratorId,
1104
+ referralId,
1105
+ ...payload
1106
+ });
1107
+ }
1108
+ };
1109
+ }
939
1110
 
940
1111
  // src/deposit.ts
941
1112
  function usdcToUnits(amount) {
@@ -1010,7 +1181,7 @@ function attachOracleConfig(entries, conversionRates) {
1010
1181
  (group, gi) => group.map((entry, ci) => {
1011
1182
  const currency = conversionRates[gi]?.[ci]?.currency;
1012
1183
  if (!currency) return entry;
1013
- const oracleConfig = (0, import_sdk4.getSpreadOracleConfig)(currency);
1184
+ const oracleConfig = (0, import_sdk5.getSpreadOracleConfig)(currency);
1014
1185
  if (!oracleConfig) return entry;
1015
1186
  return {
1016
1187
  ...entry,
@@ -1032,15 +1203,6 @@ function extractTxHash2(result) {
1032
1203
  return result.transactionHash;
1033
1204
  throw new Error("Unexpected transaction result format");
1034
1205
  }
1035
- function createSdkClient(walletClient) {
1036
- return new import_sdk4.OfframpClient({
1037
- walletClient,
1038
- chainId: BASE_CHAIN_ID,
1039
- runtimeEnv: RUNTIME_ENV,
1040
- rpcUrl: BASE_RPC_URL,
1041
- baseApiUrl: API_BASE_URL
1042
- });
1043
- }
1044
1206
  async function findUndelegatedDeposit(walletAddress) {
1045
1207
  try {
1046
1208
  const service = getIndexerService();
@@ -1049,6 +1211,7 @@ async function findUndelegatedDeposit(walletAddress) {
1049
1211
  { limit: 50 }
1050
1212
  );
1051
1213
  const escrowLower = ESCROW_ADDRESS.toLowerCase();
1214
+ const delegateIdLower = DELEGATE_RATE_MANAGER_ID.toLowerCase();
1052
1215
  const undelegated = (raw || []).filter((d) => {
1053
1216
  if (d.status === "CLOSED") return false;
1054
1217
  if (d.escrowAddress.toLowerCase() !== escrowLower) return false;
@@ -1060,266 +1223,326 @@ async function findUndelegatedDeposit(walletAddress) {
1060
1223
  }
1061
1224
  })();
1062
1225
  if (remaining === 0n) return false;
1063
- return d.rateManagerId !== DELEGATE_RATE_MANAGER_ID;
1226
+ return (d.rateManagerId ?? "").toLowerCase() !== delegateIdLower;
1227
+ });
1228
+ undelegated.sort((a, b) => {
1229
+ const left = BigInt(a.depositId);
1230
+ const right = BigInt(b.depositId);
1231
+ if (left === right) return 0;
1232
+ return left > right ? -1 : 1;
1064
1233
  });
1065
- undelegated.sort((a, b) => Number(BigInt(b.depositId) - BigInt(a.depositId)));
1066
1234
  return undelegated[0] ?? null;
1067
1235
  } catch {
1068
1236
  return null;
1069
1237
  }
1070
1238
  }
1071
- async function offramp(walletClient, params, onProgress) {
1239
+ async function offramp(walletClient, params, onProgress, telemetryContext) {
1072
1240
  const { amount, platform, currency, identifier } = params;
1073
1241
  const platformId = platform.id;
1074
1242
  const currencyCode = currency.code;
1075
- if (!walletClient.account?.address) {
1076
- throw new OfframpError("Wallet client has no account. Connect a wallet first.", "VALIDATION");
1077
- }
1078
- const walletAddress = walletClient.account.address;
1079
- const amt = parseFloat(amount);
1080
- if (!Number.isFinite(amt) || amt < MIN_DEPOSIT_USDC) {
1081
- throw new OfframpError(`Minimum deposit is ${MIN_DEPOSIT_USDC} USDC`, "VALIDATION");
1082
- }
1083
- if (!platform.currencies.includes(currencyCode)) {
1084
- throw new OfframpError(`${currencyCode} is not supported on ${platform.name}`, "UNSUPPORTED");
1085
- }
1086
- const validation = platform.validate(identifier);
1087
- if (!validation.valid) {
1088
- throw new OfframpError(validation.error || "Invalid identifier", "VALIDATION");
1089
- }
1090
- const normalizedIdentifier = validation.normalized;
1091
- const methodHash = getPaymentMethodHash(platformId);
1092
- if (!methodHash) {
1093
- throw new OfframpError(`${platform.name} is not currently supported`, "UNSUPPORTED");
1094
- }
1095
- const existing = await findUndelegatedDeposit(walletAddress);
1096
- if (existing) {
1097
- onProgress?.({ step: "resuming", depositId: existing.depositId });
1098
- const client2 = createSdkClient(walletClient);
1099
- const txOverrides2 = { referrer: [REFERRER] };
1243
+ const telemetry = telemetryContext ?? createTelemetryContext({
1244
+ sdkVersion: SDK_VERSION,
1245
+ telemetry: true,
1246
+ integratorId: params.integratorId,
1247
+ referralId: params.referralId
1248
+ });
1249
+ const flowStartMs = Date.now();
1250
+ const emitProgress = (progress) => {
1251
+ onProgress?.(progress);
1252
+ telemetry.emit("sdk.createDeposit.progress", {
1253
+ step: progress.step,
1254
+ txHash: progress.txHash
1255
+ });
1256
+ };
1257
+ try {
1258
+ if (!walletClient.account?.address) {
1259
+ throw new OfframpError("Wallet client has no account. Connect a wallet first.", "VALIDATION");
1260
+ }
1261
+ const walletAddress = walletClient.account.address.toLowerCase();
1262
+ telemetry.emit("sdk.createDeposit.start", {
1263
+ platform: platformId,
1264
+ currency: currencyCode,
1265
+ amount,
1266
+ wallet: walletAddress
1267
+ });
1268
+ const amt = parseFloat(amount);
1269
+ if (!Number.isFinite(amt) || amt < MIN_DEPOSIT_USDC) {
1270
+ throw new OfframpError(`Minimum deposit is ${MIN_DEPOSIT_USDC} USDC`, "VALIDATION");
1271
+ }
1272
+ if (!platform.currencies.includes(currencyCode)) {
1273
+ throw new OfframpError(`${currencyCode} is not supported on ${platform.name}`, "UNSUPPORTED");
1274
+ }
1275
+ const validation = platform.validate(identifier);
1276
+ if (!validation.valid) {
1277
+ throw new OfframpError(validation.error || "Invalid identifier", "VALIDATION");
1278
+ }
1279
+ const normalizedIdentifier = validation.normalized;
1280
+ const methodHash = getPaymentMethodHash(platformId);
1281
+ if (!methodHash) {
1282
+ throw new OfframpError(`${platform.name} is not currently supported`, "UNSUPPORTED");
1283
+ }
1284
+ const existing = await findUndelegatedDeposit(walletAddress);
1285
+ if (existing) {
1286
+ emitProgress({ step: "resuming", depositId: existing.depositId });
1287
+ const client2 = createSdkClient(walletClient);
1288
+ const txOverrides2 = { referrer: [REFERRER] };
1289
+ try {
1290
+ const result2 = await client2.setRateManager({
1291
+ depositId: BigInt(existing.depositId),
1292
+ rateManagerAddress: RATE_MANAGER_REGISTRY_ADDRESS,
1293
+ rateManagerId: DELEGATE_RATE_MANAGER_ID,
1294
+ escrowAddress: existing.escrowAddress,
1295
+ txOverrides: txOverrides2
1296
+ });
1297
+ const txHash = extractTxHash2(result2);
1298
+ emitProgress({ step: "done", txHash, depositId: existing.depositId });
1299
+ const resumedResult = { depositId: existing.depositId, txHash, resumed: true };
1300
+ telemetry.emit("sdk.createDeposit.success", {
1301
+ depositId: resumedResult.depositId,
1302
+ txHash: resumedResult.txHash,
1303
+ wallet: walletAddress,
1304
+ resumed: true,
1305
+ wallDurationMs: Date.now() - flowStartMs
1306
+ });
1307
+ return resumedResult;
1308
+ } catch (err) {
1309
+ if (isUserCancellation(err))
1310
+ throw new OfframpError("User cancelled", "USER_CANCELLED", "resuming", err);
1311
+ throw new OfframpError(
1312
+ "Found undelegated deposit but delegation failed. Try again.",
1313
+ "DELEGATION_FAILED",
1314
+ "resuming",
1315
+ err,
1316
+ { depositId: existing.depositId, txHash: existing.txHash }
1317
+ );
1318
+ }
1319
+ }
1320
+ const truncatedAmount = amt.toFixed(6).replace(/\.?0+$/, "");
1321
+ const amountUnits = usdcToUnits(truncatedAmount);
1322
+ const minUnits = usdcToUnits(String(MIN_ORDER_USDC));
1323
+ const maxUnits = usdcToUnits(String(Math.min(amt, 2500)));
1100
1324
  try {
1101
- const result = await client2.setRateManager({
1102
- depositId: BigInt(existing.depositId),
1103
- rateManagerAddress: RATE_MANAGER_REGISTRY_ADDRESS,
1104
- rateManagerId: DELEGATE_RATE_MANAGER_ID,
1105
- escrowAddress: existing.escrowAddress,
1106
- txOverrides: txOverrides2
1325
+ const publicClient = (0, import_viem3.createPublicClient)({ chain: import_chains3.base, transport: (0, import_viem3.http)(BASE_RPC_URL) });
1326
+ const balance = await publicClient.readContract({
1327
+ address: USDC_ADDRESS,
1328
+ abi: [
1329
+ {
1330
+ name: "balanceOf",
1331
+ type: "function",
1332
+ stateMutability: "view",
1333
+ inputs: [{ name: "account", type: "address" }],
1334
+ outputs: [{ name: "", type: "uint256" }]
1335
+ }
1336
+ ],
1337
+ functionName: "balanceOf",
1338
+ args: [walletAddress]
1339
+ });
1340
+ if (balance < amountUnits) {
1341
+ const available = Number((0, import_viem3.formatUnits)(balance, 6));
1342
+ throw new OfframpError(
1343
+ `Insufficient USDC balance. Have ${available.toFixed(2)}, need ${truncatedAmount}.`,
1344
+ "VALIDATION"
1345
+ );
1346
+ }
1347
+ } catch (err) {
1348
+ if (err instanceof OfframpError) throw err;
1349
+ }
1350
+ const client = createSdkClient(walletClient);
1351
+ const txOverrides = { referrer: [REFERRER] };
1352
+ emitProgress({ step: "approving" });
1353
+ try {
1354
+ await client.ensureAllowance({
1355
+ token: USDC_ADDRESS,
1356
+ amount: amountUnits,
1357
+ escrowAddress: ESCROW_ADDRESS,
1358
+ maxApprove: false,
1359
+ txOverrides
1107
1360
  });
1108
- const txHash = extractTxHash2(result);
1109
- onProgress?.({ step: "done", txHash, depositId: existing.depositId });
1110
- return { depositId: existing.depositId, txHash, resumed: true };
1111
1361
  } catch (err) {
1112
1362
  if (isUserCancellation(err))
1113
- throw new OfframpError("User cancelled", "USER_CANCELLED", "resuming", err);
1363
+ throw new OfframpError("User cancelled", "USER_CANCELLED", "approving", err);
1364
+ const detail = err instanceof Error ? err.message : String(err);
1114
1365
  throw new OfframpError(
1115
- "Found undelegated deposit but delegation failed. Try again.",
1116
- "DELEGATION_FAILED",
1117
- "resuming",
1118
- err,
1119
- { depositId: existing.depositId, txHash: existing.txHash }
1366
+ `USDC approval failed: ${detail}`,
1367
+ "APPROVAL_FAILED",
1368
+ "approving",
1369
+ err
1120
1370
  );
1121
1371
  }
1122
- }
1123
- const truncatedAmount = amt.toFixed(6).replace(/\.?0+$/, "");
1124
- const amountUnits = usdcToUnits(truncatedAmount);
1125
- const minUnits = usdcToUnits(String(MIN_ORDER_USDC));
1126
- const maxUnits = usdcToUnits(String(Math.min(amt, 2500)));
1127
- try {
1128
- const publicClient = (0, import_viem3.createPublicClient)({ chain: import_chains.base, transport: (0, import_viem3.http)(BASE_RPC_URL) });
1129
- const balance = await publicClient.readContract({
1130
- address: USDC_ADDRESS,
1131
- abi: [
1132
- {
1133
- name: "balanceOf",
1134
- type: "function",
1135
- stateMutability: "view",
1136
- inputs: [{ name: "account", type: "address" }],
1137
- outputs: [{ name: "", type: "uint256" }]
1138
- }
1139
- ],
1140
- functionName: "balanceOf",
1141
- args: [walletAddress]
1142
- });
1143
- if (balance < amountUnits) {
1144
- const available = Number((0, import_viem3.formatUnits)(balance, 6));
1372
+ emitProgress({ step: "registering" });
1373
+ let hashedOnchainId;
1374
+ try {
1375
+ const canonicalName = platformId.startsWith("zelle") ? "zelle" : platformId;
1376
+ const depositData = buildDepositData(platformId, normalizedIdentifier);
1377
+ hashedOnchainId = await registerPayeeDetails(canonicalName, depositData);
1378
+ } catch (err) {
1145
1379
  throw new OfframpError(
1146
- `Insufficient USDC balance. Have ${available.toFixed(2)}, need ${truncatedAmount}.`,
1147
- "VALIDATION"
1380
+ "Payee registration failed",
1381
+ "REGISTRATION_FAILED",
1382
+ "registering",
1383
+ err
1148
1384
  );
1149
1385
  }
1150
- } catch (err) {
1151
- if (err instanceof OfframpError) throw err;
1152
- }
1153
- const client = createSdkClient(walletClient);
1154
- const txOverrides = { referrer: [REFERRER] };
1155
- onProgress?.({ step: "approving" });
1156
- try {
1157
- await client.ensureAllowance({
1158
- token: USDC_ADDRESS,
1159
- amount: amountUnits,
1160
- escrowAddress: ESCROW_ADDRESS,
1161
- maxApprove: false,
1162
- txOverrides
1163
- });
1164
- } catch (err) {
1165
- if (isUserCancellation(err))
1166
- throw new OfframpError("User cancelled", "USER_CANCELLED", "approving", err);
1167
- const detail = err instanceof Error ? err.message : String(err);
1168
- throw new OfframpError(`USDC approval failed: ${detail}`, "APPROVAL_FAILED", "approving", err);
1169
- }
1170
- onProgress?.({ step: "registering" });
1171
- let hashedOnchainId;
1172
- try {
1173
- const canonicalName = platformId.startsWith("zelle") ? "zelle" : platformId;
1174
- const depositData = buildDepositData(platformId, normalizedIdentifier);
1175
- hashedOnchainId = await registerPayeeDetails(canonicalName, depositData);
1176
- } catch (err) {
1177
- throw new OfframpError("Payee registration failed", "REGISTRATION_FAILED", "registering", err);
1178
- }
1179
- onProgress?.({ step: "depositing" });
1180
- const conversionRates = [
1181
- [{ currency: currencyCode, conversionRate: "1" }]
1182
- ];
1183
- const baseCurrenciesOverride = (0, import_sdk4.mapConversionRatesToOnchainMinRate)(conversionRates, 1);
1184
- const currenciesOverride = attachOracleConfig(baseCurrenciesOverride, conversionRates);
1185
- let hash;
1186
- try {
1187
- const result = await client.createDeposit({
1188
- token: USDC_ADDRESS,
1189
- amount: amountUnits,
1190
- retainOnEmpty: false,
1191
- intentAmountRange: { min: minUnits, max: maxUnits },
1192
- processorNames: [platformId],
1193
- conversionRates,
1194
- payeeDetailsHashes: [hashedOnchainId],
1195
- paymentMethodsOverride: [methodHash],
1196
- paymentMethodDataOverride: [
1197
- {
1198
- intentGatingService: GATING_SERVICE_ADDRESS,
1199
- payeeDetails: hashedOnchainId,
1200
- data: "0x"
1201
- }
1202
- ],
1203
- currenciesOverride,
1204
- escrowAddress: ESCROW_ADDRESS,
1205
- txOverrides
1206
- });
1207
- if (!result?.hash) throw new Error("No transaction hash returned");
1208
- hash = result.hash;
1209
- } catch (err) {
1210
- if (isUserCancellation(err))
1211
- throw new OfframpError("User cancelled", "USER_CANCELLED", "depositing", err);
1212
- const detail = err instanceof Error ? err.message : String(err);
1213
- throw new OfframpError(
1214
- `Deposit transaction failed: ${detail}`,
1215
- "DEPOSIT_FAILED",
1216
- "depositing",
1217
- err
1218
- );
1219
- }
1220
- onProgress?.({ step: "confirming", txHash: hash });
1221
- let depositId = "";
1222
- const receiptClient = client;
1223
- if (typeof receiptClient.waitForTransactionReceipt === "function") {
1386
+ emitProgress({ step: "depositing" });
1387
+ const conversionRates = [
1388
+ [{ currency: currencyCode, conversionRate: "1" }]
1389
+ ];
1390
+ const baseCurrenciesOverride = (0, import_sdk5.mapConversionRatesToOnchainMinRate)(conversionRates, 1);
1391
+ const currenciesOverride = attachOracleConfig(baseCurrenciesOverride, conversionRates);
1392
+ let hash;
1224
1393
  try {
1225
- const receipt = await receiptClient.waitForTransactionReceipt({ hash, confirmations: 1 });
1226
- depositId = extractDepositIdFromLogs(receipt.logs) || "";
1227
- } catch {
1394
+ const result2 = await client.createDeposit({
1395
+ token: USDC_ADDRESS,
1396
+ amount: amountUnits,
1397
+ retainOnEmpty: false,
1398
+ intentAmountRange: { min: minUnits, max: maxUnits },
1399
+ processorNames: [platformId],
1400
+ conversionRates,
1401
+ payeeDetailsHashes: [hashedOnchainId],
1402
+ paymentMethodsOverride: [methodHash],
1403
+ paymentMethodDataOverride: [
1404
+ {
1405
+ intentGatingService: GATING_SERVICE_ADDRESS,
1406
+ payeeDetails: hashedOnchainId,
1407
+ data: "0x"
1408
+ }
1409
+ ],
1410
+ currenciesOverride,
1411
+ escrowAddress: ESCROW_ADDRESS,
1412
+ txOverrides
1413
+ });
1414
+ if (!result2?.hash) throw new Error("No transaction hash returned");
1415
+ hash = result2.hash;
1416
+ } catch (err) {
1417
+ if (isUserCancellation(err))
1418
+ throw new OfframpError("User cancelled", "USER_CANCELLED", "depositing", err);
1419
+ const detail = err instanceof Error ? err.message : String(err);
1420
+ throw new OfframpError(
1421
+ `Deposit transaction failed: ${detail}`,
1422
+ "DEPOSIT_FAILED",
1423
+ "depositing",
1424
+ err
1425
+ );
1228
1426
  }
1229
- }
1230
- if (!depositId) {
1231
- let delay = INDEXER_INITIAL_DELAY_MS;
1232
- for (let attempt = 0; attempt < INDEXER_MAX_ATTEMPTS && !depositId; attempt++) {
1427
+ emitProgress({ step: "confirming", txHash: hash });
1428
+ let depositId = "";
1429
+ const receiptClient = client;
1430
+ if (typeof receiptClient.waitForTransactionReceipt === "function") {
1233
1431
  try {
1234
- const deps = await client.indexer.getDepositsWithRelations(
1235
- { depositor: walletAddress },
1236
- { limit: 25 }
1237
- );
1238
- const hit = deps.find((d) => (d?.txHash || "").toLowerCase() === hash.toLowerCase());
1239
- if (hit) {
1240
- depositId = String(hit.depositId);
1241
- break;
1242
- }
1432
+ const receipt = await receiptClient.waitForTransactionReceipt({ hash, confirmations: 1 });
1433
+ depositId = extractDepositIdFromLogs(receipt.logs) || "";
1243
1434
  } catch {
1244
1435
  }
1245
- await new Promise((r) => setTimeout(r, delay));
1246
- delay = Math.min(INDEXER_MAX_DELAY_MS, Math.floor(delay * 1.7));
1247
1436
  }
1248
- }
1249
- if (!depositId) {
1250
- throw new OfframpError(
1251
- "Deposit created on-chain but could not confirm deposit ID. Your funds are safe. Call offramp() again to resume delegation.",
1252
- "CONFIRMATION_FAILED",
1253
- "confirming",
1254
- void 0,
1255
- { txHash: hash }
1256
- );
1257
- }
1258
- onProgress?.({ step: "delegating", txHash: hash, depositId });
1259
- try {
1260
- await client.setRateManager({
1261
- depositId: BigInt(depositId),
1262
- rateManagerAddress: RATE_MANAGER_REGISTRY_ADDRESS,
1263
- rateManagerId: DELEGATE_RATE_MANAGER_ID,
1264
- escrowAddress: ESCROW_ADDRESS,
1265
- txOverrides
1266
- });
1267
- } catch (delegationError) {
1268
- if (isUserCancellation(delegationError)) {
1437
+ if (!depositId) {
1438
+ let delay = INDEXER_INITIAL_DELAY_MS;
1439
+ for (let attempt = 0; attempt < INDEXER_MAX_ATTEMPTS && !depositId; attempt++) {
1440
+ try {
1441
+ const deps = await client.indexer.getDepositsWithRelations(
1442
+ { depositor: walletAddress },
1443
+ { limit: 25 }
1444
+ );
1445
+ const hit = deps.find((d) => (d?.txHash || "").toLowerCase() === hash.toLowerCase());
1446
+ if (hit) {
1447
+ depositId = String(hit.depositId);
1448
+ break;
1449
+ }
1450
+ } catch {
1451
+ }
1452
+ await new Promise((r) => setTimeout(r, delay));
1453
+ delay = Math.min(INDEXER_MAX_DELAY_MS, Math.floor(delay * 1.7));
1454
+ }
1455
+ }
1456
+ if (!depositId) {
1269
1457
  throw new OfframpError(
1270
- "User cancelled delegation",
1271
- "USER_CANCELLED",
1272
- "delegating",
1273
- delegationError,
1274
- { txHash: hash, depositId }
1458
+ "Deposit created on-chain but could not confirm deposit ID. Your funds are safe. Call offramp() again to resume delegation.",
1459
+ "CONFIRMATION_FAILED",
1460
+ "confirming",
1461
+ void 0,
1462
+ { txHash: hash }
1275
1463
  );
1276
1464
  }
1277
- throw new OfframpError(
1278
- "Deposit created but delegation failed. Call offramp() again to resume delegation.",
1279
- "DELEGATION_FAILED",
1280
- "delegating",
1281
- delegationError,
1282
- { txHash: hash, depositId }
1283
- );
1284
- }
1285
- let otcLink;
1286
- if (params.otcTaker) {
1287
- onProgress?.({ step: "restricting", txHash: hash, depositId });
1465
+ emitProgress({ step: "delegating", txHash: hash, depositId });
1288
1466
  try {
1289
- const otcResult = await enableOtc(walletClient, depositId, params.otcTaker);
1290
- otcLink = otcResult.otcLink;
1291
- } catch (otcError) {
1292
- if (isUserCancellation(otcError)) {
1467
+ await client.setRateManager({
1468
+ depositId: BigInt(depositId),
1469
+ rateManagerAddress: RATE_MANAGER_REGISTRY_ADDRESS,
1470
+ rateManagerId: DELEGATE_RATE_MANAGER_ID,
1471
+ escrowAddress: ESCROW_ADDRESS,
1472
+ txOverrides
1473
+ });
1474
+ } catch (delegationError) {
1475
+ if (isUserCancellation(delegationError)) {
1293
1476
  throw new OfframpError(
1294
- "User cancelled OTC restriction",
1477
+ "User cancelled delegation",
1295
1478
  "USER_CANCELLED",
1296
- "restricting",
1297
- otcError,
1298
- {
1299
- txHash: hash,
1300
- depositId
1301
- }
1479
+ "delegating",
1480
+ delegationError,
1481
+ { txHash: hash, depositId }
1302
1482
  );
1303
1483
  }
1304
1484
  throw new OfframpError(
1305
- "Deposit created and delegated but OTC restriction failed. Use enableOtc() to retry.",
1306
- "DEPOSIT_FAILED",
1307
- "restricting",
1308
- otcError,
1485
+ "Deposit created but delegation failed. Call offramp() again to resume delegation.",
1486
+ "DELEGATION_FAILED",
1487
+ "delegating",
1488
+ delegationError,
1309
1489
  { txHash: hash, depositId }
1310
1490
  );
1311
1491
  }
1492
+ let otcLink;
1493
+ if (params.otcTaker) {
1494
+ emitProgress({ step: "restricting", txHash: hash, depositId });
1495
+ try {
1496
+ const otcResult = await enableOtc(walletClient, depositId, params.otcTaker);
1497
+ otcLink = otcResult.otcLink;
1498
+ } catch (otcError) {
1499
+ if (isUserCancellation(otcError)) {
1500
+ throw new OfframpError(
1501
+ "User cancelled OTC restriction",
1502
+ "USER_CANCELLED",
1503
+ "restricting",
1504
+ otcError,
1505
+ {
1506
+ txHash: hash,
1507
+ depositId
1508
+ }
1509
+ );
1510
+ }
1511
+ throw new OfframpError(
1512
+ "Deposit created and delegated but OTC restriction failed. Use enableOtc() to retry.",
1513
+ "DEPOSIT_FAILED",
1514
+ "restricting",
1515
+ otcError,
1516
+ { txHash: hash, depositId }
1517
+ );
1518
+ }
1519
+ }
1520
+ emitProgress({ step: "done", txHash: hash, depositId });
1521
+ const result = { depositId, txHash: hash, resumed: false, otcLink };
1522
+ telemetry.emit("sdk.createDeposit.success", {
1523
+ depositId: result.depositId,
1524
+ txHash: result.txHash,
1525
+ wallet: walletAddress,
1526
+ resumed: false,
1527
+ wallDurationMs: Date.now() - flowStartMs
1528
+ });
1529
+ return result;
1530
+ } catch (error) {
1531
+ const known = error instanceof OfframpError ? error : null;
1532
+ telemetry.emit("sdk.createDeposit.error", {
1533
+ code: known?.code ?? "DEPOSIT_FAILED",
1534
+ step: known?.step ?? "unknown"
1535
+ });
1536
+ throw error;
1312
1537
  }
1313
- onProgress?.({ step: "done", txHash: hash, depositId });
1314
- return { depositId, txHash: hash, resumed: false, otcLink };
1315
1538
  }
1316
1539
 
1317
1540
  // src/currencies.ts
1318
- var import_sdk5 = require("@zkp2p/sdk");
1541
+ var import_sdk6 = require("@zkp2p/sdk");
1319
1542
  function buildCurrencies() {
1320
1543
  const entries = {};
1321
1544
  for (const [code, info] of Object.entries(
1322
- import_sdk5.currencyInfo
1545
+ import_sdk6.currencyInfo
1323
1546
  )) {
1324
1547
  entries[code] = {
1325
1548
  code: info.currencyCode ?? code,
@@ -1331,16 +1554,191 @@ function buildCurrencies() {
1331
1554
  return entries;
1332
1555
  }
1333
1556
  var CURRENCIES = buildCurrencies();
1557
+
1558
+ // src/offramp.ts
1559
+ var IDEMPOTENCY_TTL_MS = 10 * 60 * 1e3;
1560
+ var IDEMPOTENCY_STORAGE_PREFIX = "offramp:idempotency:";
1561
+ function getWalletAddress(walletClient) {
1562
+ const address = walletClient.account?.address;
1563
+ if (!address) {
1564
+ throw new OfframpError("Wallet client has no account. Connect a wallet first.", "VALIDATION");
1565
+ }
1566
+ return address.toLowerCase();
1567
+ }
1568
+ function getIdempotencyStorageKey(walletAddress, idempotencyKey) {
1569
+ return `${IDEMPOTENCY_STORAGE_PREFIX}${walletAddress}:${idempotencyKey}`;
1570
+ }
1571
+ function readIdempotencyResult(storageKey) {
1572
+ if (typeof sessionStorage === "undefined") return null;
1573
+ try {
1574
+ const raw = sessionStorage.getItem(storageKey);
1575
+ if (!raw) return null;
1576
+ const parsed = JSON.parse(raw);
1577
+ const expiresAt = typeof parsed.expiresAt === "number" && Number.isFinite(parsed.expiresAt) ? parsed.expiresAt : 0;
1578
+ if (expiresAt <= Date.now()) {
1579
+ sessionStorage.removeItem(storageKey);
1580
+ return null;
1581
+ }
1582
+ const result = parsed.result;
1583
+ if (!result?.depositId || !result.txHash) {
1584
+ sessionStorage.removeItem(storageKey);
1585
+ return null;
1586
+ }
1587
+ return result;
1588
+ } catch {
1589
+ return null;
1590
+ }
1591
+ }
1592
+ function writeIdempotencyResult(storageKey, result) {
1593
+ if (typeof sessionStorage === "undefined") return;
1594
+ try {
1595
+ const record = {
1596
+ result,
1597
+ expiresAt: Date.now() + IDEMPOTENCY_TTL_MS
1598
+ };
1599
+ sessionStorage.setItem(storageKey, JSON.stringify(record));
1600
+ } catch {
1601
+ }
1602
+ }
1603
+ function createPerFlowTelemetry(base4, integratorId, referralId) {
1604
+ return createTelemetryContext({
1605
+ sdkVersion: base4.sdkVersion,
1606
+ telemetry: base4.enabled,
1607
+ integratorId: sanitizeAttributionId(integratorId) ?? base4.integratorId,
1608
+ referralId: sanitizeAttributionId(referralId) ?? base4.referralId
1609
+ });
1610
+ }
1611
+ function normalizeCurrencyEntry(code) {
1612
+ const fromCatalog = CURRENCIES[code];
1613
+ if (fromCatalog) return fromCatalog;
1614
+ return {
1615
+ code,
1616
+ name: code,
1617
+ symbol: code,
1618
+ countryCode: ""
1619
+ };
1620
+ }
1621
+ function buildCurrencyGroups() {
1622
+ const grouped = {};
1623
+ for (const platform of Object.values(PLATFORMS)) {
1624
+ grouped[platform.id] = platform.currencies.map(normalizeCurrencyEntry);
1625
+ }
1626
+ return grouped;
1627
+ }
1628
+ var Offramp = class {
1629
+ walletClient;
1630
+ telemetry;
1631
+ constructor(options) {
1632
+ this.walletClient = options.walletClient;
1633
+ this.telemetry = createTelemetryContext({
1634
+ sdkVersion: SDK_VERSION,
1635
+ telemetry: options.telemetry,
1636
+ integratorId: options.integratorId,
1637
+ referralId: options.referralId
1638
+ });
1639
+ this.telemetry.emit("sdk.init", {
1640
+ userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "unknown"
1641
+ });
1642
+ }
1643
+ async createDeposit(params, onProgress) {
1644
+ const flowTelemetry = createPerFlowTelemetry(
1645
+ this.telemetry,
1646
+ params.integratorId,
1647
+ params.referralId
1648
+ );
1649
+ const sanitizedParams = {
1650
+ ...params,
1651
+ integratorId: flowTelemetry.integratorId,
1652
+ referralId: flowTelemetry.referralId
1653
+ };
1654
+ const sanitizedKey = sanitizeAttributionId(params.idempotencyKey);
1655
+ const walletAddress = sanitizedKey ? getWalletAddress(this.walletClient) : null;
1656
+ const storageKey = walletAddress && sanitizedKey ? getIdempotencyStorageKey(walletAddress, sanitizedKey) : null;
1657
+ if (storageKey) {
1658
+ const existing = readIdempotencyResult(storageKey);
1659
+ if (existing) return existing;
1660
+ }
1661
+ const result = await offramp(
1662
+ this.walletClient,
1663
+ sanitizedParams,
1664
+ onProgress,
1665
+ flowTelemetry
1666
+ );
1667
+ if (storageKey) {
1668
+ writeIdempotencyResult(storageKey, result);
1669
+ }
1670
+ return result;
1671
+ }
1672
+ getQuote(input) {
1673
+ const amountUsdc = Number(input.amount);
1674
+ if (!Number.isFinite(amountUsdc) || amountUsdc <= 0) {
1675
+ throw new OfframpError("Amount must be a positive number", "VALIDATION");
1676
+ }
1677
+ if (!input.platform.currencies.includes(input.currency.code)) {
1678
+ throw new OfframpError(
1679
+ `${input.currency.code} is not supported on ${input.platform.name}`,
1680
+ "UNSUPPORTED"
1681
+ );
1682
+ }
1683
+ const vaultSpreadBps = 0;
1684
+ const spreadFactor = Math.max(0, 1 - vaultSpreadBps / 1e4);
1685
+ const expectedFiat = amountUsdc * spreadFactor;
1686
+ const effectiveRate = amountUsdc === 0 ? 0 : expectedFiat / amountUsdc;
1687
+ return {
1688
+ amountUsdc,
1689
+ expectedFiat,
1690
+ effectiveRate,
1691
+ vaultSpreadBps
1692
+ };
1693
+ }
1694
+ getVaultStatus() {
1695
+ return {
1696
+ rateManagerId: DELEGATE_RATE_MANAGER_ID,
1697
+ rateManagerAddress: RATE_MANAGER_REGISTRY_ADDRESS,
1698
+ feeRateBps: DELEGATE_MANAGER_FEE_BPS,
1699
+ escrow: ESCROW_ADDRESS,
1700
+ isActive: true
1701
+ };
1702
+ }
1703
+ listCurrencies() {
1704
+ return buildCurrencyGroups();
1705
+ }
1706
+ };
1707
+ function createOfframp(options) {
1708
+ return new Offramp(options);
1709
+ }
1710
+
1711
+ // src/types.ts
1712
+ var OFFRAMP_ERROR_CODES = {
1713
+ VALIDATION: "VALIDATION",
1714
+ APPROVAL_FAILED: "APPROVAL_FAILED",
1715
+ REGISTRATION_FAILED: "REGISTRATION_FAILED",
1716
+ DEPOSIT_FAILED: "DEPOSIT_FAILED",
1717
+ CONFIRMATION_FAILED: "CONFIRMATION_FAILED",
1718
+ DELEGATION_FAILED: "DELEGATION_FAILED",
1719
+ USER_CANCELLED: "USER_CANCELLED",
1720
+ UNSUPPORTED: "UNSUPPORTED"
1721
+ };
1334
1722
  // Annotate the CommonJS export names for ESM import in node:
1335
1723
  0 && (module.exports = {
1336
1724
  CURRENCIES,
1725
+ ESCROW_ADDRESS,
1726
+ OFFRAMP_ERROR_CODES,
1727
+ Offramp,
1337
1728
  OfframpError,
1338
1729
  PLATFORMS,
1339
1730
  close,
1731
+ createOfframp,
1732
+ createTelemetryContext,
1733
+ delegate,
1340
1734
  deposits,
1341
1735
  disableOtc,
1736
+ emitEvent,
1342
1737
  enableOtc,
1343
1738
  getOtcLink,
1344
- offramp
1739
+ offramp,
1740
+ sanitizeAttributionId,
1741
+ sendTelemetryEvent,
1742
+ undelegate
1345
1743
  });
1346
1744
  //# sourceMappingURL=index.cjs.map