@usdctofiat/offramp 0.2.1 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -85
- package/dist/{chunk-AGP66RQ5.js → chunk-2UENKRGX.js} +219 -444
- package/dist/chunk-2UENKRGX.js.map +1 -0
- package/dist/errors-A8NBr_Iw.d.cts +101 -0
- package/dist/errors-A8NBr_Iw.d.ts +101 -0
- package/dist/index.cjs +265 -470
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -64
- package/dist/index.d.ts +24 -64
- package/dist/index.js +25 -8
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +254 -398
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +5 -20
- package/dist/react.d.ts +5 -20
- package/dist/react.js +10 -27
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-AGP66RQ5.js.map +0 -1
- package/dist/errors-DQqv1xfX.d.cts +0 -124
- package/dist/errors-DQqv1xfX.d.ts +0 -124
package/dist/react.cjs
CHANGED
|
@@ -27,28 +27,10 @@ module.exports = __toCommonJS(react_exports);
|
|
|
27
27
|
// src/hooks/useOfframp.ts
|
|
28
28
|
var import_react = require("react");
|
|
29
29
|
|
|
30
|
-
// src/client.ts
|
|
31
|
-
var import_viem2 = require("viem");
|
|
32
|
-
var import_sdk4 = require("@zkp2p/sdk");
|
|
33
|
-
|
|
34
|
-
// src/types.ts
|
|
35
|
-
var PLATFORMS = [
|
|
36
|
-
"venmo",
|
|
37
|
-
"cashapp",
|
|
38
|
-
"chime",
|
|
39
|
-
"revolut",
|
|
40
|
-
"wise",
|
|
41
|
-
"mercadopago",
|
|
42
|
-
"zelle",
|
|
43
|
-
"paypal",
|
|
44
|
-
"monzo",
|
|
45
|
-
"n26"
|
|
46
|
-
];
|
|
47
|
-
|
|
48
30
|
// src/deposit.ts
|
|
49
|
-
var
|
|
31
|
+
var import_viem2 = require("viem");
|
|
50
32
|
var import_chains = require("viem/chains");
|
|
51
|
-
var
|
|
33
|
+
var import_sdk4 = require("@zkp2p/sdk");
|
|
52
34
|
|
|
53
35
|
// src/config.ts
|
|
54
36
|
var import_sdk = require("@zkp2p/sdk");
|
|
@@ -75,8 +57,8 @@ var PAYEE_REGISTRATION_TIMEOUT_MS = 8e3;
|
|
|
75
57
|
// src/platforms.ts
|
|
76
58
|
var import_sdk2 = require("@zkp2p/sdk");
|
|
77
59
|
var import_zod = require("zod");
|
|
78
|
-
var ZELLE_HASH_LOOKUP_NAMES = ["zelle", "zelle-bofa", "zelle-chase", "zelle-citi"];
|
|
79
60
|
var PAYMENT_CATALOG = (0, import_sdk2.getPaymentMethodsCatalog)(BASE_CHAIN_ID, RUNTIME_ENV);
|
|
61
|
+
var ZELLE_HASH_LOOKUP_NAMES = ["zelle", "zelle-bofa", "zelle-chase", "zelle-citi"];
|
|
80
62
|
var FALLBACK_CURRENCIES = {
|
|
81
63
|
venmo: ["USD"],
|
|
82
64
|
cashapp: ["USD"],
|
|
@@ -108,142 +90,62 @@ function resolveSupportedCurrencies(platform) {
|
|
|
108
90
|
}
|
|
109
91
|
return Array.from(codes).sort();
|
|
110
92
|
}
|
|
111
|
-
var
|
|
112
|
-
venmo: {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
},
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
placeholder: "cashtag (no $)",
|
|
126
|
-
helperText: "Cashtag without $ (publicly discoverable)",
|
|
127
|
-
validation: import_zod.z.string().min(1).regex(/^[a-zA-Z0-9]+$/),
|
|
128
|
-
transform: (v) => v.replace(/^\$+/, "")
|
|
129
|
-
},
|
|
130
|
-
chime: {
|
|
131
|
-
id: "chime",
|
|
132
|
-
name: "Chime",
|
|
133
|
-
identifierLabel: "ChimeSign",
|
|
134
|
-
placeholder: "$chimesign",
|
|
135
|
-
helperText: "ChimeSign with $ (must be discoverable)",
|
|
136
|
-
validation: import_zod.z.string().min(2).regex(/^\$[a-zA-Z0-9]+$/),
|
|
137
|
-
transform: (v) => {
|
|
138
|
-
const t = v.trim().toLowerCase();
|
|
139
|
-
return t.startsWith("$") ? t : `$${t}`;
|
|
140
|
-
}
|
|
141
|
-
},
|
|
142
|
-
revolut: {
|
|
143
|
-
id: "revolut",
|
|
144
|
-
name: "Revolut",
|
|
145
|
-
identifierLabel: "Revtag",
|
|
146
|
-
placeholder: "revtag (no @)",
|
|
147
|
-
helperText: "Revtag without @ (must be public)",
|
|
148
|
-
validation: import_zod.z.string().min(1).regex(/^[a-zA-Z0-9]+$/),
|
|
149
|
-
transform: (v) => v.replace(/^@+/, "").trim()
|
|
150
|
-
},
|
|
151
|
-
wise: {
|
|
152
|
-
id: "wise",
|
|
153
|
-
name: "Wise",
|
|
154
|
-
identifierLabel: "Wisetag",
|
|
155
|
-
placeholder: "wisetag (no @)",
|
|
156
|
-
helperText: "Your Wise @wisetag (no @)",
|
|
157
|
-
validation: import_zod.z.string().min(1).regex(/^[a-zA-Z0-9_-]+$/),
|
|
158
|
-
transform: (v) => v.replace(/^@+/, "").trim()
|
|
159
|
-
},
|
|
160
|
-
mercadopago: {
|
|
161
|
-
id: "mercadopago",
|
|
162
|
-
name: "Mercado Pago",
|
|
163
|
-
identifierLabel: "CVU",
|
|
164
|
-
placeholder: "22-digit CVU",
|
|
165
|
-
helperText: "CVU must be exactly 22 digits",
|
|
166
|
-
validation: import_zod.z.string().length(22).regex(/^\d{22}$/)
|
|
167
|
-
},
|
|
168
|
-
zelle: {
|
|
169
|
-
id: "zelle",
|
|
170
|
-
name: "Zelle",
|
|
171
|
-
identifierLabel: "Email",
|
|
172
|
-
placeholder: "email",
|
|
173
|
-
helperText: "Registered Zelle email",
|
|
174
|
-
validation: import_zod.z.string().email()
|
|
175
|
-
},
|
|
176
|
-
paypal: {
|
|
177
|
-
id: "paypal",
|
|
178
|
-
name: "PayPal",
|
|
179
|
-
identifierLabel: "Email",
|
|
180
|
-
placeholder: "email",
|
|
181
|
-
helperText: "Email linked to PayPal account",
|
|
182
|
-
validation: import_zod.z.string().email()
|
|
183
|
-
},
|
|
184
|
-
monzo: {
|
|
185
|
-
id: "monzo",
|
|
186
|
-
name: "Monzo",
|
|
187
|
-
identifierLabel: "Username",
|
|
188
|
-
placeholder: "monzo.me username",
|
|
189
|
-
helperText: "Your Monzo.me username",
|
|
190
|
-
validation: import_zod.z.string().min(1).regex(/^[a-zA-Z0-9_-]+$/)
|
|
191
|
-
},
|
|
192
|
-
n26: {
|
|
193
|
-
id: "n26",
|
|
194
|
-
name: "N26",
|
|
195
|
-
identifierLabel: "IBAN",
|
|
196
|
-
placeholder: "IBAN (e.g. DE89...)",
|
|
197
|
-
helperText: "Your IBAN (spaces will be removed)",
|
|
198
|
-
validation: import_zod.z.string().min(15).max(34).regex(/^[A-Z]{2}[0-9]{2}[A-Z0-9]+$/i),
|
|
199
|
-
transform: (v) => v.replace(/\s/g, "").toUpperCase()
|
|
200
|
-
}
|
|
93
|
+
var BLUEPRINTS = {
|
|
94
|
+
venmo: { id: "venmo", name: "Venmo", identifierLabel: "Username", placeholder: "venmo username (no @)", helperText: "Username without @ (publicly discoverable)", validation: import_zod.z.string().min(1).regex(/^[a-zA-Z0-9_-]+$/), transform: (v) => v.replace(/^@+/, "") },
|
|
95
|
+
cashapp: { id: "cashapp", name: "Cash App", identifierLabel: "Cashtag", placeholder: "cashtag (no $)", helperText: "Cashtag without $ (publicly discoverable)", validation: import_zod.z.string().min(1).regex(/^[a-zA-Z0-9]+$/), transform: (v) => v.replace(/^\$+/, "") },
|
|
96
|
+
chime: { id: "chime", name: "Chime", identifierLabel: "ChimeSign", placeholder: "$chimesign", helperText: "ChimeSign with $ (must be discoverable)", validation: import_zod.z.string().min(2).regex(/^\$[a-zA-Z0-9]+$/), transform: (v) => {
|
|
97
|
+
const t = v.trim().toLowerCase();
|
|
98
|
+
return t.startsWith("$") ? t : `$${t}`;
|
|
99
|
+
} },
|
|
100
|
+
revolut: { id: "revolut", name: "Revolut", identifierLabel: "Revtag", placeholder: "revtag (no @)", helperText: "Revtag without @ (must be public)", validation: import_zod.z.string().min(1).regex(/^[a-zA-Z0-9]+$/), transform: (v) => v.replace(/^@+/, "").trim() },
|
|
101
|
+
wise: { id: "wise", name: "Wise", identifierLabel: "Wisetag", placeholder: "wisetag (no @)", helperText: "Your Wise @wisetag (no @)", validation: import_zod.z.string().min(1).regex(/^[a-zA-Z0-9_-]+$/), transform: (v) => v.replace(/^@+/, "").trim() },
|
|
102
|
+
mercadopago: { id: "mercadopago", name: "Mercado Pago", identifierLabel: "CVU", placeholder: "22-digit CVU", helperText: "CVU must be exactly 22 digits", validation: import_zod.z.string().length(22).regex(/^\d{22}$/) },
|
|
103
|
+
zelle: { id: "zelle", name: "Zelle", identifierLabel: "Email", placeholder: "email", helperText: "Registered Zelle email", validation: import_zod.z.string().email() },
|
|
104
|
+
paypal: { id: "paypal", name: "PayPal", identifierLabel: "Email", placeholder: "email", helperText: "Email linked to PayPal account", validation: import_zod.z.string().email() },
|
|
105
|
+
monzo: { id: "monzo", name: "Monzo", identifierLabel: "Username", placeholder: "monzo.me username", helperText: "Your Monzo.me username", validation: import_zod.z.string().min(1).regex(/^[a-zA-Z0-9_-]+$/) },
|
|
106
|
+
n26: { id: "n26", name: "N26", identifierLabel: "IBAN", placeholder: "IBAN (e.g. DE89...)", helperText: "Your IBAN (spaces will be removed)", validation: import_zod.z.string().min(15).max(34).regex(/^[A-Z]{2}[0-9]{2}[A-Z0-9]+$/i), transform: (v) => v.replace(/\s/g, "").toUpperCase() }
|
|
201
107
|
};
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
function getCurrencies(platform) {
|
|
225
|
-
return CONFIGS[platform]?.currencies ?? [];
|
|
226
|
-
}
|
|
227
|
-
function validateIdentifier(platform, value) {
|
|
228
|
-
const cfg = CONFIGS[platform];
|
|
229
|
-
if (!cfg) return { valid: false, normalized: value, error: "Unsupported platform" };
|
|
230
|
-
const transformed = cfg.transform ? cfg.transform(value) : value;
|
|
231
|
-
const result = cfg.validation.safeParse(transformed);
|
|
232
|
-
if (!result.success) {
|
|
233
|
-
return { valid: false, normalized: transformed, error: result.error.issues[0]?.message || "Invalid input" };
|
|
234
|
-
}
|
|
235
|
-
return { valid: true, normalized: transformed };
|
|
236
|
-
}
|
|
237
|
-
function isSupportedCurrency(platform, currency) {
|
|
238
|
-
return CONFIGS[platform]?.currencies.includes(currency) ?? false;
|
|
108
|
+
function buildPlatformEntry(bp) {
|
|
109
|
+
const currencies = resolveSupportedCurrencies(bp.id);
|
|
110
|
+
return {
|
|
111
|
+
id: bp.id,
|
|
112
|
+
name: bp.name,
|
|
113
|
+
currencies,
|
|
114
|
+
identifier: {
|
|
115
|
+
label: bp.identifierLabel,
|
|
116
|
+
placeholder: bp.placeholder,
|
|
117
|
+
help: bp.helperText
|
|
118
|
+
},
|
|
119
|
+
validate(input) {
|
|
120
|
+
const transformed = bp.transform ? bp.transform(input) : input;
|
|
121
|
+
const result = bp.validation.safeParse(transformed);
|
|
122
|
+
if (!result.success) {
|
|
123
|
+
return { valid: false, normalized: transformed, error: result.error.issues[0]?.message || "Invalid input" };
|
|
124
|
+
}
|
|
125
|
+
return { valid: true, normalized: transformed };
|
|
126
|
+
}
|
|
127
|
+
};
|
|
239
128
|
}
|
|
129
|
+
var PLATFORMS = {
|
|
130
|
+
VENMO: buildPlatformEntry(BLUEPRINTS.venmo),
|
|
131
|
+
CASHAPP: buildPlatformEntry(BLUEPRINTS.cashapp),
|
|
132
|
+
CHIME: buildPlatformEntry(BLUEPRINTS.chime),
|
|
133
|
+
REVOLUT: buildPlatformEntry(BLUEPRINTS.revolut),
|
|
134
|
+
WISE: buildPlatformEntry(BLUEPRINTS.wise),
|
|
135
|
+
MERCADO_PAGO: buildPlatformEntry(BLUEPRINTS.mercadopago),
|
|
136
|
+
ZELLE: buildPlatformEntry(BLUEPRINTS.zelle),
|
|
137
|
+
PAYPAL: buildPlatformEntry(BLUEPRINTS.paypal),
|
|
138
|
+
MONZO: buildPlatformEntry(BLUEPRINTS.monzo),
|
|
139
|
+
N26: buildPlatformEntry(BLUEPRINTS.n26)
|
|
140
|
+
};
|
|
240
141
|
function normalizePaymentMethodLookupName(platform) {
|
|
241
142
|
const normalized = platform.trim().toLowerCase();
|
|
242
143
|
if (!normalized) return null;
|
|
243
144
|
if (ZELLE_HASH_LOOKUP_NAMES.includes(normalized)) {
|
|
244
145
|
return normalized;
|
|
245
146
|
}
|
|
246
|
-
|
|
147
|
+
const ids = Object.values(PLATFORMS).map((p) => p.id);
|
|
148
|
+
return ids.includes(normalized) ? normalized : null;
|
|
247
149
|
}
|
|
248
150
|
function resolveCanonicalZelleHash() {
|
|
249
151
|
const direct = PAYMENT_CATALOG.zelle?.paymentMethodHash;
|
|
@@ -329,9 +231,105 @@ function isUserCancellation(error) {
|
|
|
329
231
|
return msg.includes("user rejected") || msg.includes("user denied") || msg.includes("user cancelled") || msg.includes("rejected the request") || msg.includes("action_rejected");
|
|
330
232
|
}
|
|
331
233
|
|
|
234
|
+
// src/queries.ts
|
|
235
|
+
var import_viem = require("viem");
|
|
236
|
+
var import_sdk3 = require("@zkp2p/sdk");
|
|
237
|
+
var indexerService = null;
|
|
238
|
+
function getIndexerService() {
|
|
239
|
+
if (!indexerService) {
|
|
240
|
+
const endpoint = (0, import_sdk3.defaultIndexerEndpoint)("PRODUCTION");
|
|
241
|
+
const client = new import_sdk3.IndexerClient(endpoint);
|
|
242
|
+
indexerService = new import_sdk3.IndexerDepositService(client);
|
|
243
|
+
}
|
|
244
|
+
return indexerService;
|
|
245
|
+
}
|
|
246
|
+
function toBigInt(value) {
|
|
247
|
+
try {
|
|
248
|
+
return BigInt(value || "0");
|
|
249
|
+
} catch {
|
|
250
|
+
return 0n;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
function toUsdc(value) {
|
|
254
|
+
return Number((0, import_viem.formatUnits)(toBigInt(value), 6));
|
|
255
|
+
}
|
|
256
|
+
function resolveStatus(deposit) {
|
|
257
|
+
if (deposit.status === "CLOSED") return "closed";
|
|
258
|
+
if (toBigInt(deposit.remainingDeposits) === 0n) return "empty";
|
|
259
|
+
return "active";
|
|
260
|
+
}
|
|
261
|
+
function resolveMethodNames(hashes) {
|
|
262
|
+
const names = /* @__PURE__ */ new Set();
|
|
263
|
+
for (const { paymentMethodHash } of hashes) {
|
|
264
|
+
const normalized = paymentMethodHash.toLowerCase();
|
|
265
|
+
for (const platform of Object.values(PLATFORMS)) {
|
|
266
|
+
const platformHashes = getPaymentMethodHashes(platform.id);
|
|
267
|
+
if (platformHashes.some((h) => h.toLowerCase() === normalized)) {
|
|
268
|
+
names.add(platform.name);
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return Array.from(names);
|
|
274
|
+
}
|
|
275
|
+
function mapDeposit(d) {
|
|
276
|
+
const delegationState = (0, import_sdk3.classifyDelegationState)(
|
|
277
|
+
d.rateManagerId ?? void 0,
|
|
278
|
+
d.rateManagerAddress ?? void 0,
|
|
279
|
+
DELEGATE_RATE_MANAGER_ID,
|
|
280
|
+
RATE_MANAGER_REGISTRY_ADDRESS
|
|
281
|
+
);
|
|
282
|
+
return {
|
|
283
|
+
depositId: d.depositId,
|
|
284
|
+
compositeId: d.id,
|
|
285
|
+
txHash: d.txHash,
|
|
286
|
+
status: resolveStatus(d),
|
|
287
|
+
remainingUsdc: toUsdc(d.remainingDeposits),
|
|
288
|
+
outstandingUsdc: toUsdc(d.outstandingIntentAmount),
|
|
289
|
+
totalTakenUsdc: toUsdc(d.totalAmountTaken),
|
|
290
|
+
fulfilledIntents: d.fulfilledIntents ?? 0,
|
|
291
|
+
paymentMethods: resolveMethodNames(d.paymentMethods),
|
|
292
|
+
currencies: d.currencies.map((c) => {
|
|
293
|
+
const info = (0, import_sdk3.getCurrencyInfoFromHash)(c.currencyCode);
|
|
294
|
+
return info?.currencyCode ?? c.currencyCode;
|
|
295
|
+
}),
|
|
296
|
+
rateSource: d.currencies[0]?.rateSource || "unknown",
|
|
297
|
+
delegated: delegationState === "delegated_here",
|
|
298
|
+
escrowAddress: d.escrowAddress
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
function extractTxHash(result) {
|
|
302
|
+
if (typeof result === "string") return result;
|
|
303
|
+
if (result && typeof result === "object" && "hash" in result) return result.hash;
|
|
304
|
+
if (result && typeof result === "object" && "transactionHash" in result) return result.transactionHash;
|
|
305
|
+
throw new Error("Unexpected transaction result format");
|
|
306
|
+
}
|
|
307
|
+
async function deposits(walletAddress) {
|
|
308
|
+
const service = getIndexerService();
|
|
309
|
+
const raw = await service.fetchDepositsWithRelations(
|
|
310
|
+
{ depositor: walletAddress },
|
|
311
|
+
{ limit: 100 }
|
|
312
|
+
);
|
|
313
|
+
const statusOrder = { active: 0, empty: 1, closed: 2 };
|
|
314
|
+
return (raw || []).map(mapDeposit).sort((a, b) => {
|
|
315
|
+
const diff = statusOrder[a.status] - statusOrder[b.status];
|
|
316
|
+
if (diff !== 0) return diff;
|
|
317
|
+
return Number(BigInt(b.depositId) - BigInt(a.depositId));
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
async function close(walletClient, depositId, escrowAddress) {
|
|
321
|
+
const client = createSdkClient(walletClient);
|
|
322
|
+
const result = await client.withdrawDeposit({
|
|
323
|
+
depositId: BigInt(depositId),
|
|
324
|
+
escrowAddress: escrowAddress || ESCROW_ADDRESS,
|
|
325
|
+
txOverrides: { referrer: [REFERRER] }
|
|
326
|
+
});
|
|
327
|
+
return extractTxHash(result);
|
|
328
|
+
}
|
|
329
|
+
|
|
332
330
|
// src/deposit.ts
|
|
333
331
|
function usdcToUnits(amount) {
|
|
334
|
-
return (0,
|
|
332
|
+
return (0, import_viem2.parseUnits)(amount, 6);
|
|
335
333
|
}
|
|
336
334
|
var DEPOSIT_RECEIVED_ABI = [
|
|
337
335
|
{
|
|
@@ -355,7 +353,7 @@ function extractDepositIdFromLogs(logs) {
|
|
|
355
353
|
for (const log of logs) {
|
|
356
354
|
if (!log?.topics?.length || !log.data) continue;
|
|
357
355
|
try {
|
|
358
|
-
const decoded = (0,
|
|
356
|
+
const decoded = (0, import_viem2.decodeEventLog)({
|
|
359
357
|
abi: DEPOSIT_RECEIVED_ABI,
|
|
360
358
|
data: log.data,
|
|
361
359
|
topics: log.topics
|
|
@@ -397,7 +395,7 @@ function attachOracleConfig(entries, conversionRates) {
|
|
|
397
395
|
(group, gi) => group.map((entry, ci) => {
|
|
398
396
|
const currency = conversionRates[gi]?.[ci]?.currency;
|
|
399
397
|
if (!currency) return entry;
|
|
400
|
-
const oracleConfig = (0,
|
|
398
|
+
const oracleConfig = (0, import_sdk4.getSpreadOracleConfig)(currency);
|
|
401
399
|
if (!oracleConfig) return entry;
|
|
402
400
|
return {
|
|
403
401
|
...entry,
|
|
@@ -411,8 +409,14 @@ function attachOracleConfig(entries, conversionRates) {
|
|
|
411
409
|
})
|
|
412
410
|
);
|
|
413
411
|
}
|
|
412
|
+
function extractTxHash2(result) {
|
|
413
|
+
if (typeof result === "string") return result;
|
|
414
|
+
if (result && typeof result === "object" && "hash" in result) return result.hash;
|
|
415
|
+
if (result && typeof result === "object" && "transactionHash" in result) return result.transactionHash;
|
|
416
|
+
throw new Error("Unexpected transaction result format");
|
|
417
|
+
}
|
|
414
418
|
function createSdkClient(walletClient) {
|
|
415
|
-
return new
|
|
419
|
+
return new import_sdk4.OfframpClient({
|
|
416
420
|
walletClient,
|
|
417
421
|
chainId: BASE_CHAIN_ID,
|
|
418
422
|
runtimeEnv: RUNTIME_ENV,
|
|
@@ -420,34 +424,90 @@ function createSdkClient(walletClient) {
|
|
|
420
424
|
baseApiUrl: API_BASE_URL
|
|
421
425
|
});
|
|
422
426
|
}
|
|
423
|
-
async function
|
|
427
|
+
async function findUndelegatedDeposit(walletAddress) {
|
|
428
|
+
try {
|
|
429
|
+
const service = getIndexerService();
|
|
430
|
+
const raw = await service.fetchDepositsWithRelations(
|
|
431
|
+
{ depositor: walletAddress },
|
|
432
|
+
{ limit: 50 }
|
|
433
|
+
);
|
|
434
|
+
const escrowLower = ESCROW_ADDRESS.toLowerCase();
|
|
435
|
+
const undelegated = (raw || []).filter((d) => {
|
|
436
|
+
if (d.status === "CLOSED") return false;
|
|
437
|
+
if (d.escrowAddress.toLowerCase() !== escrowLower) return false;
|
|
438
|
+
const remaining = (() => {
|
|
439
|
+
try {
|
|
440
|
+
return BigInt(d.remainingDeposits || "0");
|
|
441
|
+
} catch {
|
|
442
|
+
return 0n;
|
|
443
|
+
}
|
|
444
|
+
})();
|
|
445
|
+
if (remaining === 0n) return false;
|
|
446
|
+
return d.rateManagerId !== DELEGATE_RATE_MANAGER_ID;
|
|
447
|
+
});
|
|
448
|
+
undelegated.sort((a, b) => Number(BigInt(b.depositId) - BigInt(a.depositId)));
|
|
449
|
+
return undelegated[0] ?? null;
|
|
450
|
+
} catch {
|
|
451
|
+
return null;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
async function offramp(walletClient, params, onProgress) {
|
|
424
455
|
const { amount, platform, currency, identifier } = params;
|
|
456
|
+
const platformId = platform.id;
|
|
457
|
+
const currencyCode = currency.code;
|
|
458
|
+
if (!walletClient.account?.address) {
|
|
459
|
+
throw new OfframpError("Wallet client has no account. Connect a wallet first.", "VALIDATION");
|
|
460
|
+
}
|
|
461
|
+
const walletAddress = walletClient.account.address;
|
|
425
462
|
const amt = parseFloat(amount);
|
|
426
463
|
if (!Number.isFinite(amt) || amt < MIN_DEPOSIT_USDC) {
|
|
427
464
|
throw new OfframpError(`Minimum deposit is ${MIN_DEPOSIT_USDC} USDC`, "VALIDATION");
|
|
428
465
|
}
|
|
429
|
-
if (!
|
|
430
|
-
throw new OfframpError(`${
|
|
466
|
+
if (!platform.currencies.includes(currencyCode)) {
|
|
467
|
+
throw new OfframpError(`${currencyCode} is not supported on ${platform.name}`, "UNSUPPORTED");
|
|
431
468
|
}
|
|
432
|
-
const validation =
|
|
469
|
+
const validation = platform.validate(identifier);
|
|
433
470
|
if (!validation.valid) {
|
|
434
471
|
throw new OfframpError(validation.error || "Invalid identifier", "VALIDATION");
|
|
435
472
|
}
|
|
436
473
|
const normalizedIdentifier = validation.normalized;
|
|
437
|
-
const methodHash = getPaymentMethodHash(
|
|
474
|
+
const methodHash = getPaymentMethodHash(platformId);
|
|
438
475
|
if (!methodHash) {
|
|
439
|
-
throw new OfframpError(`${platform} is not currently supported`, "UNSUPPORTED");
|
|
476
|
+
throw new OfframpError(`${platform.name} is not currently supported`, "UNSUPPORTED");
|
|
440
477
|
}
|
|
441
|
-
|
|
442
|
-
|
|
478
|
+
const existing = await findUndelegatedDeposit(walletAddress);
|
|
479
|
+
if (existing) {
|
|
480
|
+
onProgress?.({ step: "resuming", depositId: existing.depositId });
|
|
481
|
+
const client2 = createSdkClient(walletClient);
|
|
482
|
+
const txOverrides2 = { referrer: [REFERRER] };
|
|
483
|
+
try {
|
|
484
|
+
const result = await client2.setRateManager({
|
|
485
|
+
depositId: BigInt(existing.depositId),
|
|
486
|
+
rateManagerAddress: RATE_MANAGER_REGISTRY_ADDRESS,
|
|
487
|
+
rateManagerId: DELEGATE_RATE_MANAGER_ID,
|
|
488
|
+
escrowAddress: existing.escrowAddress,
|
|
489
|
+
txOverrides: txOverrides2
|
|
490
|
+
});
|
|
491
|
+
const txHash = extractTxHash2(result);
|
|
492
|
+
onProgress?.({ step: "done", txHash, depositId: existing.depositId });
|
|
493
|
+
return { depositId: existing.depositId, txHash, resumed: true };
|
|
494
|
+
} catch (err) {
|
|
495
|
+
if (isUserCancellation(err)) throw new OfframpError("User cancelled", "USER_CANCELLED", "resuming", err);
|
|
496
|
+
throw new OfframpError(
|
|
497
|
+
"Found undelegated deposit but delegation failed. Try again.",
|
|
498
|
+
"DELEGATION_FAILED",
|
|
499
|
+
"resuming",
|
|
500
|
+
err,
|
|
501
|
+
{ depositId: existing.depositId, txHash: existing.txHash }
|
|
502
|
+
);
|
|
503
|
+
}
|
|
443
504
|
}
|
|
444
|
-
const walletAddress = walletClient.account.address;
|
|
445
505
|
const truncatedAmount = amt.toFixed(6).replace(/\.?0+$/, "");
|
|
446
506
|
const amountUnits = usdcToUnits(truncatedAmount);
|
|
447
507
|
const minUnits = usdcToUnits(String(MIN_ORDER_USDC));
|
|
448
508
|
const maxUnits = usdcToUnits(String(Math.min(amt, 2500)));
|
|
449
509
|
try {
|
|
450
|
-
const publicClient = (0,
|
|
510
|
+
const publicClient = (0, import_viem2.createPublicClient)({ chain: import_chains.base, transport: (0, import_viem2.http)(BASE_RPC_URL) });
|
|
451
511
|
const balance = await publicClient.readContract({
|
|
452
512
|
address: USDC_ADDRESS,
|
|
453
513
|
abi: [{ name: "balanceOf", type: "function", stateMutability: "view", inputs: [{ name: "account", type: "address" }], outputs: [{ name: "", type: "uint256" }] }],
|
|
@@ -455,11 +515,8 @@ async function createOfframpDeposit(walletClient, params, onProgress) {
|
|
|
455
515
|
args: [walletAddress]
|
|
456
516
|
});
|
|
457
517
|
if (balance < amountUnits) {
|
|
458
|
-
const available = Number((0,
|
|
459
|
-
throw new OfframpError(
|
|
460
|
-
`Insufficient USDC balance. Have ${available.toFixed(2)}, need ${truncatedAmount}.`,
|
|
461
|
-
"VALIDATION"
|
|
462
|
-
);
|
|
518
|
+
const available = Number((0, import_viem2.formatUnits)(balance, 6));
|
|
519
|
+
throw new OfframpError(`Insufficient USDC balance. Have ${available.toFixed(2)}, need ${truncatedAmount}.`, "VALIDATION");
|
|
463
520
|
}
|
|
464
521
|
} catch (err) {
|
|
465
522
|
if (err instanceof OfframpError) throw err;
|
|
@@ -483,17 +540,17 @@ async function createOfframpDeposit(walletClient, params, onProgress) {
|
|
|
483
540
|
onProgress?.({ step: "registering" });
|
|
484
541
|
let hashedOnchainId;
|
|
485
542
|
try {
|
|
486
|
-
const canonicalName =
|
|
487
|
-
const depositData = buildDepositData(
|
|
543
|
+
const canonicalName = platformId.startsWith("zelle") ? "zelle" : platformId;
|
|
544
|
+
const depositData = buildDepositData(platformId, normalizedIdentifier);
|
|
488
545
|
hashedOnchainId = await registerPayeeDetails(canonicalName, depositData);
|
|
489
546
|
} catch (err) {
|
|
490
547
|
throw new OfframpError("Payee registration failed", "REGISTRATION_FAILED", "registering", err);
|
|
491
548
|
}
|
|
492
549
|
onProgress?.({ step: "depositing" });
|
|
493
550
|
const conversionRates = [
|
|
494
|
-
[{ currency, conversionRate: "1" }]
|
|
551
|
+
[{ currency: currencyCode, conversionRate: "1" }]
|
|
495
552
|
];
|
|
496
|
-
const baseCurrenciesOverride = (0,
|
|
553
|
+
const baseCurrenciesOverride = (0, import_sdk4.mapConversionRatesToOnchainMinRate)(conversionRates, 1);
|
|
497
554
|
const currenciesOverride = attachOracleConfig(baseCurrenciesOverride, conversionRates);
|
|
498
555
|
let hash;
|
|
499
556
|
try {
|
|
@@ -502,8 +559,8 @@ async function createOfframpDeposit(walletClient, params, onProgress) {
|
|
|
502
559
|
amount: amountUnits,
|
|
503
560
|
retainOnEmpty: false,
|
|
504
561
|
intentAmountRange: { min: minUnits, max: maxUnits },
|
|
505
|
-
processorNames: [
|
|
506
|
-
depositData: [buildDepositData(
|
|
562
|
+
processorNames: [platformId],
|
|
563
|
+
depositData: [buildDepositData(platformId, normalizedIdentifier)],
|
|
507
564
|
conversionRates,
|
|
508
565
|
paymentMethodsOverride: [methodHash],
|
|
509
566
|
paymentMethodDataOverride: [{
|
|
@@ -533,29 +590,27 @@ async function createOfframpDeposit(walletClient, params, onProgress) {
|
|
|
533
590
|
}
|
|
534
591
|
}
|
|
535
592
|
if (!depositId) {
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
break;
|
|
548
|
-
}
|
|
549
|
-
} catch {
|
|
593
|
+
let delay = INDEXER_INITIAL_DELAY_MS;
|
|
594
|
+
for (let attempt = 0; attempt < INDEXER_MAX_ATTEMPTS && !depositId; attempt++) {
|
|
595
|
+
try {
|
|
596
|
+
const deps = await client.indexer.getDepositsWithRelations(
|
|
597
|
+
{ depositor: walletAddress },
|
|
598
|
+
{ limit: 25 }
|
|
599
|
+
);
|
|
600
|
+
const hit = deps.find((d) => (d?.txHash || "").toLowerCase() === hash.toLowerCase());
|
|
601
|
+
if (hit) {
|
|
602
|
+
depositId = String(hit.depositId);
|
|
603
|
+
break;
|
|
550
604
|
}
|
|
551
|
-
|
|
552
|
-
delay = Math.min(INDEXER_MAX_DELAY_MS, Math.floor(delay * 1.7));
|
|
605
|
+
} catch {
|
|
553
606
|
}
|
|
607
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
608
|
+
delay = Math.min(INDEXER_MAX_DELAY_MS, Math.floor(delay * 1.7));
|
|
554
609
|
}
|
|
555
610
|
}
|
|
556
611
|
if (!depositId) {
|
|
557
612
|
throw new OfframpError(
|
|
558
|
-
"Deposit created on-chain but could not confirm deposit ID. Your funds are safe.
|
|
613
|
+
"Deposit created on-chain but could not confirm deposit ID. Your funds are safe. Call offramp() again to resume delegation.",
|
|
559
614
|
"CONFIRMATION_FAILED",
|
|
560
615
|
"confirming",
|
|
561
616
|
void 0,
|
|
@@ -576,7 +631,7 @@ async function createOfframpDeposit(walletClient, params, onProgress) {
|
|
|
576
631
|
throw new OfframpError("User cancelled delegation", "USER_CANCELLED", "delegating", delegationError, { txHash: hash, depositId });
|
|
577
632
|
}
|
|
578
633
|
throw new OfframpError(
|
|
579
|
-
"Deposit created but delegation failed.
|
|
634
|
+
"Deposit created but delegation failed. Call offramp() again to resume delegation.",
|
|
580
635
|
"DELEGATION_FAILED",
|
|
581
636
|
"delegating",
|
|
582
637
|
delegationError,
|
|
@@ -584,192 +639,8 @@ async function createOfframpDeposit(walletClient, params, onProgress) {
|
|
|
584
639
|
);
|
|
585
640
|
}
|
|
586
641
|
onProgress?.({ step: "done", txHash: hash, depositId });
|
|
587
|
-
return { depositId, txHash: hash };
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
// src/client.ts
|
|
591
|
-
var indexerClient = null;
|
|
592
|
-
function getIndexerService() {
|
|
593
|
-
if (!indexerClient) {
|
|
594
|
-
const endpoint = (0, import_sdk4.defaultIndexerEndpoint)("PRODUCTION");
|
|
595
|
-
const client = new import_sdk4.IndexerClient(endpoint);
|
|
596
|
-
indexerClient = new import_sdk4.IndexerDepositService(client);
|
|
597
|
-
}
|
|
598
|
-
return indexerClient;
|
|
599
|
-
}
|
|
600
|
-
function toBigInt(value) {
|
|
601
|
-
try {
|
|
602
|
-
return BigInt(value || "0");
|
|
603
|
-
} catch {
|
|
604
|
-
return 0n;
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
function toUsdc(value) {
|
|
608
|
-
return Number((0, import_viem2.formatUnits)(toBigInt(value), 6));
|
|
609
|
-
}
|
|
610
|
-
function resolveStatus(deposit) {
|
|
611
|
-
if (deposit.status === "CLOSED") return "closed";
|
|
612
|
-
if (toBigInt(deposit.remainingDeposits) === 0n) return "empty";
|
|
613
|
-
return "active";
|
|
614
|
-
}
|
|
615
|
-
function resolveMethodNames(hashes) {
|
|
616
|
-
const names = /* @__PURE__ */ new Set();
|
|
617
|
-
for (const { paymentMethodHash } of hashes) {
|
|
618
|
-
const normalized = paymentMethodHash.toLowerCase();
|
|
619
|
-
for (const platform of PLATFORMS) {
|
|
620
|
-
const platformHashes = getPaymentMethodHashes(platform);
|
|
621
|
-
if (platformHashes.some((h) => h.toLowerCase() === normalized)) {
|
|
622
|
-
names.add(getPlatformConfig(platform).name);
|
|
623
|
-
break;
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
return Array.from(names);
|
|
628
|
-
}
|
|
629
|
-
function mapDeposit(d) {
|
|
630
|
-
const delegationState = (0, import_sdk4.classifyDelegationState)(
|
|
631
|
-
d.rateManagerId ?? void 0,
|
|
632
|
-
d.rateManagerAddress ?? void 0,
|
|
633
|
-
DELEGATE_RATE_MANAGER_ID,
|
|
634
|
-
RATE_MANAGER_REGISTRY_ADDRESS
|
|
635
|
-
);
|
|
636
|
-
return {
|
|
637
|
-
depositId: d.depositId,
|
|
638
|
-
compositeId: d.id,
|
|
639
|
-
txHash: d.txHash,
|
|
640
|
-
status: resolveStatus(d),
|
|
641
|
-
remainingUsdc: toUsdc(d.remainingDeposits),
|
|
642
|
-
outstandingUsdc: toUsdc(d.outstandingIntentAmount),
|
|
643
|
-
totalTakenUsdc: toUsdc(d.totalAmountTaken),
|
|
644
|
-
fulfilledIntents: d.fulfilledIntents ?? 0,
|
|
645
|
-
paymentMethods: resolveMethodNames(d.paymentMethods),
|
|
646
|
-
currencies: d.currencies.map((c) => {
|
|
647
|
-
const info = (0, import_sdk4.getCurrencyInfoFromHash)(c.currencyCode);
|
|
648
|
-
return info?.currencyCode ?? c.currencyCode;
|
|
649
|
-
}),
|
|
650
|
-
rateSource: d.currencies[0]?.rateSource || "unknown",
|
|
651
|
-
delegated: delegationState === "delegated_here",
|
|
652
|
-
escrowAddress: d.escrowAddress
|
|
653
|
-
};
|
|
654
|
-
}
|
|
655
|
-
function extractTxHash(result) {
|
|
656
|
-
if (typeof result === "string") return result;
|
|
657
|
-
if (result && typeof result === "object" && "hash" in result) return result.hash;
|
|
658
|
-
if (result && typeof result === "object" && "transactionHash" in result) return result.transactionHash;
|
|
659
|
-
throw new Error("Unexpected transaction result format");
|
|
642
|
+
return { depositId, txHash: hash, resumed: false };
|
|
660
643
|
}
|
|
661
|
-
var Offramp = class {
|
|
662
|
-
/**
|
|
663
|
-
* Create an offramp deposit: approve USDC, register payee, create deposit,
|
|
664
|
-
* confirm on-chain, and delegate to the vault. All in one call.
|
|
665
|
-
*
|
|
666
|
-
* @param walletClient - viem WalletClient with an account
|
|
667
|
-
* @param params - Deposit parameters (amount, platform, currency, identifier)
|
|
668
|
-
* @param onProgress - Optional callback for step-by-step progress updates
|
|
669
|
-
*/
|
|
670
|
-
async createDeposit(walletClient, params, onProgress) {
|
|
671
|
-
return createOfframpDeposit(walletClient, params, onProgress);
|
|
672
|
-
}
|
|
673
|
-
/**
|
|
674
|
-
* Fetch all deposits for a wallet address. Read-only, no wallet needed.
|
|
675
|
-
* Returns active, empty, and closed deposits sorted by status then recency.
|
|
676
|
-
*/
|
|
677
|
-
async getDeposits(walletAddress) {
|
|
678
|
-
const service = getIndexerService();
|
|
679
|
-
const raw = await service.fetchDepositsWithRelations(
|
|
680
|
-
{ depositor: walletAddress },
|
|
681
|
-
{ limit: 100 }
|
|
682
|
-
);
|
|
683
|
-
const statusOrder = { active: 0, empty: 1, closed: 2 };
|
|
684
|
-
return (raw || []).map(mapDeposit).sort((a, b) => {
|
|
685
|
-
const diff = statusOrder[a.status] - statusOrder[b.status];
|
|
686
|
-
if (diff !== 0) return diff;
|
|
687
|
-
return Number(BigInt(b.depositId) - BigInt(a.depositId));
|
|
688
|
-
});
|
|
689
|
-
}
|
|
690
|
-
/**
|
|
691
|
-
* Find a deposit by its transaction hash. Useful for recovering from
|
|
692
|
-
* CONFIRMATION_FAILED errors where you have a txHash but no depositId.
|
|
693
|
-
*
|
|
694
|
-
* @param walletAddress - The depositor's wallet address
|
|
695
|
-
* @param txHash - The transaction hash from createDeposit
|
|
696
|
-
*/
|
|
697
|
-
async getDepositByTxHash(walletAddress, txHash) {
|
|
698
|
-
const deposits = await this.getDeposits(walletAddress);
|
|
699
|
-
const normalized = txHash.toLowerCase();
|
|
700
|
-
return deposits.find((d) => d.txHash?.toLowerCase() === normalized) ?? null;
|
|
701
|
-
}
|
|
702
|
-
/**
|
|
703
|
-
* Delegate an existing deposit to the Delegate vault. Use this to:
|
|
704
|
-
* - Retry after a DELEGATION_FAILED error
|
|
705
|
-
* - Delegate a deposit created outside the SDK
|
|
706
|
-
* - Delegate a deposit created via usdctofiat.xyz
|
|
707
|
-
*
|
|
708
|
-
* @param walletClient - viem WalletClient with the deposit owner's account
|
|
709
|
-
* @param depositId - The numeric deposit ID (not the composite escrow_id format)
|
|
710
|
-
*/
|
|
711
|
-
async delegateDeposit(walletClient, depositId, escrowAddress) {
|
|
712
|
-
const client = createSdkClient(walletClient);
|
|
713
|
-
const result = await client.setRateManager({
|
|
714
|
-
depositId: BigInt(depositId),
|
|
715
|
-
rateManagerAddress: RATE_MANAGER_REGISTRY_ADDRESS,
|
|
716
|
-
rateManagerId: DELEGATE_RATE_MANAGER_ID,
|
|
717
|
-
escrowAddress: escrowAddress || ESCROW_ADDRESS,
|
|
718
|
-
txOverrides: { referrer: [REFERRER] }
|
|
719
|
-
});
|
|
720
|
-
return extractTxHash(result);
|
|
721
|
-
}
|
|
722
|
-
/**
|
|
723
|
-
* Withdraw remaining USDC and close a deposit.
|
|
724
|
-
*
|
|
725
|
-
* @param walletClient - viem WalletClient with the deposit owner's account
|
|
726
|
-
* @param depositId - The numeric deposit ID (not the composite escrow_id format)
|
|
727
|
-
*/
|
|
728
|
-
async withdrawDeposit(walletClient, depositId, escrowAddress) {
|
|
729
|
-
const client = createSdkClient(walletClient);
|
|
730
|
-
const result = await client.withdrawDeposit({
|
|
731
|
-
depositId: BigInt(depositId),
|
|
732
|
-
escrowAddress: escrowAddress || ESCROW_ADDRESS,
|
|
733
|
-
txOverrides: { referrer: [REFERRER] }
|
|
734
|
-
});
|
|
735
|
-
return extractTxHash(result);
|
|
736
|
-
}
|
|
737
|
-
/** List available payment platforms with currencies, labels, and format requirements. */
|
|
738
|
-
getPlatforms() {
|
|
739
|
-
return getPlatforms();
|
|
740
|
-
}
|
|
741
|
-
/** Get supported currencies for a specific platform. */
|
|
742
|
-
getCurrencies(platform) {
|
|
743
|
-
return getCurrencies(platform);
|
|
744
|
-
}
|
|
745
|
-
/**
|
|
746
|
-
* Get currency metadata for UI rendering.
|
|
747
|
-
* @returns Symbol (€), full name (Euro), and country code (eu), or null if unsupported.
|
|
748
|
-
*/
|
|
749
|
-
getCurrencyInfo(code) {
|
|
750
|
-
const info = import_sdk4.currencyInfo[code];
|
|
751
|
-
if (!info) return null;
|
|
752
|
-
return {
|
|
753
|
-
code: info.currencyCode ?? code,
|
|
754
|
-
name: info.currencyName ?? code,
|
|
755
|
-
symbol: info.currencySymbol ?? code,
|
|
756
|
-
countryCode: info.countryCode ?? ""
|
|
757
|
-
};
|
|
758
|
-
}
|
|
759
|
-
/** Get all supported currencies with metadata. */
|
|
760
|
-
getAllCurrencies() {
|
|
761
|
-
return Object.keys(import_sdk4.currencyInfo).map((code) => {
|
|
762
|
-
return this.getCurrencyInfo(code);
|
|
763
|
-
}).filter(Boolean);
|
|
764
|
-
}
|
|
765
|
-
/**
|
|
766
|
-
* Validate and normalize a payment identifier for a platform.
|
|
767
|
-
* Strips leading @/$ characters, validates format (email, IBAN, etc).
|
|
768
|
-
*/
|
|
769
|
-
validateIdentifier(platform, identifier) {
|
|
770
|
-
return validateIdentifier(platform, identifier);
|
|
771
|
-
}
|
|
772
|
-
};
|
|
773
644
|
|
|
774
645
|
// src/hooks/useOfframp.ts
|
|
775
646
|
function useOfframp() {
|
|
@@ -779,13 +650,6 @@ function useOfframp() {
|
|
|
779
650
|
const [error, setError] = (0, import_react.useState)(null);
|
|
780
651
|
const [isLoading, setIsLoading] = (0, import_react.useState)(false);
|
|
781
652
|
const lockRef = (0, import_react.useRef)(false);
|
|
782
|
-
const offrampRef = (0, import_react.useRef)(null);
|
|
783
|
-
const getOfframp = () => {
|
|
784
|
-
if (!offrampRef.current) {
|
|
785
|
-
offrampRef.current = new Offramp();
|
|
786
|
-
}
|
|
787
|
-
return offrampRef.current;
|
|
788
|
-
};
|
|
789
653
|
const reset = (0, import_react.useCallback)(() => {
|
|
790
654
|
setStep(null);
|
|
791
655
|
setTxHash(null);
|
|
@@ -794,7 +658,7 @@ function useOfframp() {
|
|
|
794
658
|
setIsLoading(false);
|
|
795
659
|
lockRef.current = false;
|
|
796
660
|
}, []);
|
|
797
|
-
const
|
|
661
|
+
const offramp2 = (0, import_react.useCallback)(
|
|
798
662
|
async (walletClient, params) => {
|
|
799
663
|
if (lockRef.current) throw new OfframpError("Deposit already in progress", "VALIDATION");
|
|
800
664
|
lockRef.current = true;
|
|
@@ -804,7 +668,7 @@ function useOfframp() {
|
|
|
804
668
|
setTxHash(null);
|
|
805
669
|
setDepositId(null);
|
|
806
670
|
try {
|
|
807
|
-
const result = await
|
|
671
|
+
const result = await offramp(walletClient, params, (progress) => {
|
|
808
672
|
setStep(progress.step);
|
|
809
673
|
if (progress.txHash) setTxHash(progress.txHash);
|
|
810
674
|
if (progress.depositId) setDepositId(progress.depositId);
|
|
@@ -823,24 +687,16 @@ function useOfframp() {
|
|
|
823
687
|
},
|
|
824
688
|
[]
|
|
825
689
|
);
|
|
826
|
-
const o = getOfframp();
|
|
827
690
|
return {
|
|
828
691
|
step,
|
|
829
692
|
txHash,
|
|
830
693
|
depositId,
|
|
831
694
|
error,
|
|
832
695
|
isLoading,
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
withdrawDeposit: (0, import_react.useCallback)((wc, id, esc) => o.withdrawDeposit(wc, id, esc), [o]),
|
|
838
|
-
reset,
|
|
839
|
-
getPlatforms,
|
|
840
|
-
getCurrencies,
|
|
841
|
-
getCurrencyInfo: (0, import_react.useCallback)((code) => o.getCurrencyInfo(code), [o]),
|
|
842
|
-
getAllCurrencies: (0, import_react.useCallback)(() => o.getAllCurrencies(), [o]),
|
|
843
|
-
validateIdentifier
|
|
696
|
+
offramp: offramp2,
|
|
697
|
+
deposits,
|
|
698
|
+
close,
|
|
699
|
+
reset
|
|
844
700
|
};
|
|
845
701
|
}
|
|
846
702
|
// Annotate the CommonJS export names for ESM import in node:
|