@rhinestone/deposit-modal 0.17.0 → 0.18.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/README.md +68 -0
- package/dist/{DepositModalReown-6CXXGQ7X.cjs → DepositModalReown-TVO3ZQQK.cjs} +17 -17
- package/dist/{DepositModalReown-ELDSTIME.mjs → DepositModalReown-VCY65DJX.mjs} +4 -4
- package/dist/WithdrawModal-GR3HLYXU.cjs +11 -0
- package/dist/{WithdrawModal-QRMDR5T4.mjs → WithdrawModal-RMCYJJ4S.mjs} +3 -3
- package/dist/bearer-transport-CVHNBgoV.d.cts +14 -0
- package/dist/bearer-transport-CVHNBgoV.d.ts +14 -0
- package/dist/{chunk-2W4BJ5I3.cjs → chunk-34JVJZEZ.cjs} +71 -71
- package/dist/{chunk-XCBDJPBD.mjs → chunk-3TEVMP76.mjs} +1 -1
- package/dist/chunk-ADEWTBSN.cjs +19 -0
- package/dist/{chunk-QMGEK623.mjs → chunk-AIZKGFVA.mjs} +468 -207
- package/dist/{chunk-H66WM5AO.mjs → chunk-EKC2IRQG.mjs} +180 -67
- package/dist/{chunk-XJMDCBHS.cjs → chunk-JV5OGG53.cjs} +629 -516
- package/dist/{chunk-QGNJFDEO.cjs → chunk-N3AAT6BS.cjs} +623 -362
- package/dist/{chunk-JCWJ6HW7.cjs → chunk-N6JJG57R.cjs} +1 -1
- package/dist/chunk-O4JZKKCZ.cjs +41 -0
- package/dist/chunk-PP4QE32S.mjs +19 -0
- package/dist/{chunk-ZHX4QROC.mjs → chunk-R2B6VD4E.mjs} +1 -1
- package/dist/chunk-X4EUXBHJ.mjs +41 -0
- package/dist/compliance.cjs +14 -0
- package/dist/compliance.d.cts +10 -0
- package/dist/compliance.d.ts +10 -0
- package/dist/compliance.mjs +14 -0
- package/dist/constants.cjs +3 -3
- package/dist/constants.d.cts +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.mjs +3 -3
- package/dist/deposit.cjs +4 -4
- package/dist/deposit.d.cts +2 -2
- package/dist/deposit.d.ts +2 -2
- package/dist/deposit.mjs +3 -3
- package/dist/embed.cjs +16 -16
- package/dist/embed.d.cts +1 -1
- package/dist/embed.d.ts +1 -1
- package/dist/embed.mjs +8 -8
- package/dist/index.cjs +5 -5
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +4 -4
- package/dist/offramp.cjs +25 -0
- package/dist/offramp.d.cts +28 -0
- package/dist/offramp.d.ts +28 -0
- package/dist/offramp.mjs +25 -0
- package/dist/onramp.cjs +27 -0
- package/dist/onramp.d.cts +37 -0
- package/dist/onramp.d.ts +37 -0
- package/dist/onramp.mjs +27 -0
- package/dist/ramp-types-C6aUz4SZ.d.cts +43 -0
- package/dist/ramp-types-C6aUz4SZ.d.ts +43 -0
- package/dist/server.cjs +54 -2
- package/dist/server.d.cts +13 -1
- package/dist/server.d.ts +13 -1
- package/dist/server.mjs +52 -0
- package/dist/{types-B9SbZQIG.d.ts → types-CZYypODQ.d.ts} +3 -2
- package/dist/{types-SwGGf0eH.d.cts → types-CbUs4boj.d.cts} +3 -2
- package/dist/withdraw.cjs +4 -4
- package/dist/withdraw.d.cts +2 -2
- package/dist/withdraw.d.ts +2 -2
- package/dist/withdraw.mjs +3 -3
- package/package.json +35 -5
- package/dist/WithdrawModal-QB2U756L.cjs +0 -11
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
MODAL_VERSION,
|
|
3
|
-
serviceHeaders
|
|
4
|
-
} from "./chunk-XCBDJPBD.mjs";
|
|
5
1
|
import {
|
|
6
2
|
CHAIN_DISPLAY_ORDER,
|
|
7
3
|
HYPERCORE_CHAIN_ID,
|
|
@@ -36,6 +32,10 @@ import {
|
|
|
36
32
|
toEvmCaip2,
|
|
37
33
|
tokenIconUrl
|
|
38
34
|
} from "./chunk-EAGMY3QE.mjs";
|
|
35
|
+
import {
|
|
36
|
+
MODAL_VERSION,
|
|
37
|
+
serviceHeaders
|
|
38
|
+
} from "./chunk-3TEVMP76.mjs";
|
|
39
39
|
|
|
40
40
|
// src/components/ui/Modal.tsx
|
|
41
41
|
import {
|
|
@@ -736,6 +736,31 @@ function resolveAppFeeBps(appFees, sourceChainCaip2, sourceToken) {
|
|
|
736
736
|
const bps = override ?? appFees?.feeBps ?? 0;
|
|
737
737
|
return bps > 0 ? bps : 0;
|
|
738
738
|
}
|
|
739
|
+
function isRawAmount(value) {
|
|
740
|
+
return typeof value === "string" && /^\d+$/.test(value);
|
|
741
|
+
}
|
|
742
|
+
function isDepositPolicyRefusal(value) {
|
|
743
|
+
return typeof value === "object" && value !== null && "policyRefusal" in value;
|
|
744
|
+
}
|
|
745
|
+
var DEPOSIT_POLICY_REFUSAL_CODES = [
|
|
746
|
+
"TOKEN-3",
|
|
747
|
+
"BALANCE-3",
|
|
748
|
+
"BALANCE-4"
|
|
749
|
+
];
|
|
750
|
+
var DEPOSIT_PREFLIGHT_TIMEOUT_MS = 1e4;
|
|
751
|
+
async function readPolicyRefusal(response) {
|
|
752
|
+
if (response.status !== 422) return null;
|
|
753
|
+
try {
|
|
754
|
+
const body = await response.json();
|
|
755
|
+
if (!body || typeof body.code !== "string" || !DEPOSIT_POLICY_REFUSAL_CODES.includes(body.code)) {
|
|
756
|
+
return null;
|
|
757
|
+
}
|
|
758
|
+
const message = typeof body.error === "string" && body.error !== "" ? body.error : "This deposit is not accepted.";
|
|
759
|
+
return { policyRefusal: { code: body.code, message } };
|
|
760
|
+
} catch {
|
|
761
|
+
return null;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
739
764
|
var PermitDepositSubmitError = class extends Error {
|
|
740
765
|
constructor(message, safeToTransfer) {
|
|
741
766
|
super(message);
|
|
@@ -762,29 +787,60 @@ function createDepositService(baseUrl, options) {
|
|
|
762
787
|
if (value.length <= 20) return value;
|
|
763
788
|
return `${value.slice(0, 10)}...${value.slice(-8)}`;
|
|
764
789
|
}
|
|
790
|
+
function withPreflightTimeout(label, fallback, run) {
|
|
791
|
+
const controller = new AbortController();
|
|
792
|
+
return new Promise((resolve) => {
|
|
793
|
+
const timer = setTimeout(() => {
|
|
794
|
+
debugLog(debug, scope, `${label}:timeout`, {
|
|
795
|
+
timeoutMs: DEPOSIT_PREFLIGHT_TIMEOUT_MS
|
|
796
|
+
});
|
|
797
|
+
controller.abort();
|
|
798
|
+
resolve(fallback);
|
|
799
|
+
}, DEPOSIT_PREFLIGHT_TIMEOUT_MS);
|
|
800
|
+
run(controller.signal).then(
|
|
801
|
+
(value) => {
|
|
802
|
+
clearTimeout(timer);
|
|
803
|
+
resolve(value);
|
|
804
|
+
},
|
|
805
|
+
() => {
|
|
806
|
+
clearTimeout(timer);
|
|
807
|
+
resolve(fallback);
|
|
808
|
+
}
|
|
809
|
+
);
|
|
810
|
+
});
|
|
811
|
+
}
|
|
765
812
|
const PORTFOLIO_CACHE_TTL_MS = 3e4;
|
|
766
813
|
const portfolioCache = /* @__PURE__ */ new Map();
|
|
767
814
|
let topTokensPromise = null;
|
|
768
815
|
let chainsPromise = null;
|
|
769
|
-
function
|
|
770
|
-
if (typeof value !== "object" || value === null
|
|
816
|
+
function parseDepositOptions(value) {
|
|
817
|
+
if (typeof value !== "object" || value === null) return null;
|
|
818
|
+
const { restricted, tokens: rawTokens } = value;
|
|
819
|
+
if (typeof restricted !== "boolean") return null;
|
|
820
|
+
if (typeof rawTokens !== "object" || rawTokens === null || Array.isArray(rawTokens)) {
|
|
771
821
|
return null;
|
|
772
822
|
}
|
|
773
|
-
const
|
|
774
|
-
for (const [chainKey, list] of Object.entries(
|
|
823
|
+
const tokens = {};
|
|
824
|
+
for (const [chainKey, list] of Object.entries(rawTokens)) {
|
|
775
825
|
if (!Array.isArray(list)) return null;
|
|
776
|
-
const
|
|
826
|
+
const parsed = [];
|
|
777
827
|
for (const entry of list) {
|
|
778
828
|
if (typeof entry !== "object" || entry === null) return null;
|
|
779
|
-
const { symbol, address, decimals } = entry;
|
|
829
|
+
const { symbol, address, decimals, minAmount, maxAmount } = entry;
|
|
780
830
|
if (typeof symbol !== "string" || typeof address !== "string" || typeof decimals !== "number") {
|
|
781
831
|
return null;
|
|
782
832
|
}
|
|
783
|
-
|
|
833
|
+
parsed.push({
|
|
834
|
+
symbol,
|
|
835
|
+
address,
|
|
836
|
+
decimals,
|
|
837
|
+
...isRawAmount(minAmount) && { minAmount },
|
|
838
|
+
...isRawAmount(maxAmount) && { maxAmount }
|
|
839
|
+
});
|
|
784
840
|
}
|
|
785
|
-
|
|
841
|
+
tokens[chainKey] = parsed;
|
|
786
842
|
}
|
|
787
|
-
return
|
|
843
|
+
return { restricted, tokens };
|
|
788
844
|
}
|
|
789
845
|
async function requestTopTokens() {
|
|
790
846
|
try {
|
|
@@ -796,21 +852,21 @@ function createDepositService(baseUrl, options) {
|
|
|
796
852
|
debugLog(debug, scope, "getTopTokens:unavailable", {
|
|
797
853
|
status: response.status
|
|
798
854
|
});
|
|
799
|
-
return
|
|
855
|
+
return { ok: false };
|
|
800
856
|
}
|
|
801
|
-
const
|
|
802
|
-
|
|
803
|
-
if (!tokens) {
|
|
857
|
+
const options2 = parseDepositOptions(await response.json());
|
|
858
|
+
if (!options2) {
|
|
804
859
|
debugLog(debug, scope, "getTopTokens:malformed");
|
|
805
|
-
return
|
|
860
|
+
return { ok: false };
|
|
806
861
|
}
|
|
807
862
|
debugLog(debug, scope, "getTopTokens:success", {
|
|
808
|
-
chains: Object.keys(tokens).length
|
|
863
|
+
chains: Object.keys(options2.tokens).length,
|
|
864
|
+
restricted: options2.restricted
|
|
809
865
|
});
|
|
810
|
-
return
|
|
866
|
+
return { ok: true, options: options2 };
|
|
811
867
|
} catch (error) {
|
|
812
868
|
debugError(debug, scope, "getTopTokens:error", error);
|
|
813
|
-
return
|
|
869
|
+
return { ok: false };
|
|
814
870
|
}
|
|
815
871
|
}
|
|
816
872
|
async function requestChains() {
|
|
@@ -1303,36 +1359,46 @@ function createDepositService(baseUrl, options) {
|
|
|
1303
1359
|
sourceToken: params.sourceToken,
|
|
1304
1360
|
amount: params.amount
|
|
1305
1361
|
});
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
debugLog(debug, scope, "getQuotePreview:unavailable", {
|
|
1315
|
-
status: response.status
|
|
1362
|
+
return withPreflightTimeout("getQuotePreview", null, async (signal) => {
|
|
1363
|
+
try {
|
|
1364
|
+
const response = await fetch(url, {
|
|
1365
|
+
method: "POST",
|
|
1366
|
+
headers: serviceHeaders(),
|
|
1367
|
+
body: JSON.stringify(body),
|
|
1368
|
+
cache: "no-store",
|
|
1369
|
+
signal
|
|
1316
1370
|
});
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1371
|
+
if (!response.ok) {
|
|
1372
|
+
const refusal = await readPolicyRefusal(response);
|
|
1373
|
+
if (refusal) {
|
|
1374
|
+
debugLog(debug, scope, "getQuotePreview:refused", {
|
|
1375
|
+
code: refusal.policyRefusal.code
|
|
1376
|
+
});
|
|
1377
|
+
return refusal;
|
|
1378
|
+
}
|
|
1379
|
+
debugLog(debug, scope, "getQuotePreview:unavailable", {
|
|
1380
|
+
status: response.status
|
|
1381
|
+
});
|
|
1382
|
+
return null;
|
|
1383
|
+
}
|
|
1384
|
+
const quote = parseQuotePreview(await response.json());
|
|
1385
|
+
if (!quote) {
|
|
1386
|
+
debugLog(debug, scope, "getQuotePreview:unavailable", {
|
|
1387
|
+
status: response.status,
|
|
1388
|
+
reason: "malformed"
|
|
1389
|
+
});
|
|
1390
|
+
return null;
|
|
1391
|
+
}
|
|
1392
|
+
debugLog(debug, scope, "getQuotePreview:success", {
|
|
1393
|
+
settlementLayer: quote.settlementLayer,
|
|
1394
|
+
totalUsd: quote.fees.total.usd
|
|
1324
1395
|
});
|
|
1396
|
+
return quote;
|
|
1397
|
+
} catch (error) {
|
|
1398
|
+
debugError(debug, scope, "getQuotePreview:error", error);
|
|
1325
1399
|
return null;
|
|
1326
1400
|
}
|
|
1327
|
-
|
|
1328
|
-
settlementLayer: quote.settlementLayer,
|
|
1329
|
-
totalUsd: quote.fees.total.usd
|
|
1330
|
-
});
|
|
1331
|
-
return quote;
|
|
1332
|
-
} catch (error) {
|
|
1333
|
-
debugError(debug, scope, "getQuotePreview:error", error);
|
|
1334
|
-
return null;
|
|
1335
|
-
}
|
|
1401
|
+
});
|
|
1336
1402
|
},
|
|
1337
1403
|
async preparePermitDeposit(params) {
|
|
1338
1404
|
const url = apiUrl("/deposits/permit/prepare");
|
|
@@ -1343,88 +1409,98 @@ function createDepositService(baseUrl, options) {
|
|
|
1343
1409
|
token: params.token,
|
|
1344
1410
|
amount: params.amount
|
|
1345
1411
|
});
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
debugLog(debug, scope, "preparePermitDeposit:unavailable", {
|
|
1355
|
-
status: response.status
|
|
1356
|
-
});
|
|
1357
|
-
return null;
|
|
1358
|
-
}
|
|
1359
|
-
const data = await response.json();
|
|
1360
|
-
if (!data || typeof data.available !== "boolean") {
|
|
1361
|
-
debugLog(debug, scope, "preparePermitDeposit:unavailable", {
|
|
1362
|
-
status: response.status,
|
|
1363
|
-
reason: "malformed"
|
|
1412
|
+
return withPreflightTimeout("preparePermitDeposit", null, async (signal) => {
|
|
1413
|
+
try {
|
|
1414
|
+
const response = await fetch(url, {
|
|
1415
|
+
method: "POST",
|
|
1416
|
+
headers: serviceHeaders(),
|
|
1417
|
+
body: JSON.stringify({ ...params, kind: "auto" }),
|
|
1418
|
+
cache: "no-store",
|
|
1419
|
+
signal
|
|
1364
1420
|
});
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1421
|
+
if (!response.ok) {
|
|
1422
|
+
const refusal = await readPolicyRefusal(response);
|
|
1423
|
+
if (refusal) {
|
|
1424
|
+
debugLog(debug, scope, "preparePermitDeposit:refused", {
|
|
1425
|
+
code: refusal.policyRefusal.code
|
|
1426
|
+
});
|
|
1427
|
+
return refusal;
|
|
1428
|
+
}
|
|
1429
|
+
debugLog(debug, scope, "preparePermitDeposit:unavailable", {
|
|
1430
|
+
status: response.status
|
|
1431
|
+
});
|
|
1370
1432
|
return null;
|
|
1371
1433
|
}
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
reason,
|
|
1385
|
-
...parsedApproval && { approval: parsedApproval }
|
|
1386
|
-
};
|
|
1387
|
-
}
|
|
1388
|
-
const authorization = data.authorization;
|
|
1389
|
-
if (!authorization || typeof authorization.typedData !== "object" || authorization.typedData === null || typeof authorization.nonce !== "string") {
|
|
1390
|
-
return null;
|
|
1391
|
-
}
|
|
1392
|
-
if (authorization.kind === "erc3009" && typeof authorization.validAfter === "string" && typeof authorization.validBefore === "string") {
|
|
1393
|
-
debugLog(debug, scope, "preparePermitDeposit:success", {
|
|
1394
|
-
kind: authorization.kind,
|
|
1395
|
-
nonce: authorization.nonce
|
|
1396
|
-
});
|
|
1397
|
-
return {
|
|
1398
|
-
available: true,
|
|
1399
|
-
authorization: {
|
|
1400
|
-
kind: "erc3009",
|
|
1401
|
-
typedData: authorization.typedData,
|
|
1402
|
-
nonce: authorization.nonce,
|
|
1403
|
-
validAfter: authorization.validAfter,
|
|
1404
|
-
validBefore: authorization.validBefore
|
|
1434
|
+
const data = await response.json();
|
|
1435
|
+
if (!data || typeof data.available !== "boolean") {
|
|
1436
|
+
debugLog(debug, scope, "preparePermitDeposit:unavailable", {
|
|
1437
|
+
status: response.status,
|
|
1438
|
+
reason: "malformed"
|
|
1439
|
+
});
|
|
1440
|
+
return null;
|
|
1441
|
+
}
|
|
1442
|
+
if (data.available === false) {
|
|
1443
|
+
const reason = data.reason;
|
|
1444
|
+
if (reason !== "permit2-approval-required" && reason !== "unsupported-token" && reason !== "unsupported-owner") {
|
|
1445
|
+
return null;
|
|
1405
1446
|
}
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1447
|
+
debugLog(debug, scope, "preparePermitDeposit:unavailable", {
|
|
1448
|
+
status: response.status,
|
|
1449
|
+
reason
|
|
1450
|
+
});
|
|
1451
|
+
const approval = data.approval;
|
|
1452
|
+
const parsedApproval = approval && typeof approval.token === "string" && typeof approval.spender === "string" && typeof approval.minimumAmount === "string" ? {
|
|
1453
|
+
token: approval.token,
|
|
1454
|
+
spender: approval.spender,
|
|
1455
|
+
minimumAmount: approval.minimumAmount
|
|
1456
|
+
} : void 0;
|
|
1457
|
+
return {
|
|
1458
|
+
available: false,
|
|
1459
|
+
reason,
|
|
1460
|
+
...parsedApproval && { approval: parsedApproval }
|
|
1461
|
+
};
|
|
1462
|
+
}
|
|
1463
|
+
const authorization = data.authorization;
|
|
1464
|
+
if (!authorization || typeof authorization.typedData !== "object" || authorization.typedData === null || typeof authorization.nonce !== "string") {
|
|
1465
|
+
return null;
|
|
1466
|
+
}
|
|
1467
|
+
if (authorization.kind === "erc3009" && typeof authorization.validAfter === "string" && typeof authorization.validBefore === "string") {
|
|
1468
|
+
debugLog(debug, scope, "preparePermitDeposit:success", {
|
|
1416
1469
|
kind: authorization.kind,
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1470
|
+
nonce: authorization.nonce
|
|
1471
|
+
});
|
|
1472
|
+
return {
|
|
1473
|
+
available: true,
|
|
1474
|
+
authorization: {
|
|
1475
|
+
kind: "erc3009",
|
|
1476
|
+
typedData: authorization.typedData,
|
|
1477
|
+
nonce: authorization.nonce,
|
|
1478
|
+
validAfter: authorization.validAfter,
|
|
1479
|
+
validBefore: authorization.validBefore
|
|
1480
|
+
}
|
|
1481
|
+
};
|
|
1482
|
+
}
|
|
1483
|
+
if ((authorization.kind === "erc2612" || authorization.kind === "permit2") && typeof authorization.deadline === "string") {
|
|
1484
|
+
debugLog(debug, scope, "preparePermitDeposit:success", {
|
|
1485
|
+
kind: authorization.kind,
|
|
1486
|
+
nonce: authorization.nonce
|
|
1487
|
+
});
|
|
1488
|
+
return {
|
|
1489
|
+
available: true,
|
|
1490
|
+
authorization: {
|
|
1491
|
+
kind: authorization.kind,
|
|
1492
|
+
typedData: authorization.typedData,
|
|
1493
|
+
nonce: authorization.nonce,
|
|
1494
|
+
deadline: authorization.deadline
|
|
1495
|
+
}
|
|
1496
|
+
};
|
|
1497
|
+
}
|
|
1498
|
+
return null;
|
|
1499
|
+
} catch (error) {
|
|
1500
|
+
debugError(debug, scope, "preparePermitDeposit:error", error);
|
|
1501
|
+
return null;
|
|
1422
1502
|
}
|
|
1423
|
-
|
|
1424
|
-
} catch (error) {
|
|
1425
|
-
debugError(debug, scope, "preparePermitDeposit:error", error);
|
|
1426
|
-
return null;
|
|
1427
|
-
}
|
|
1503
|
+
});
|
|
1428
1504
|
},
|
|
1429
1505
|
async submitPermitDeposit(params) {
|
|
1430
1506
|
const url = apiUrl("/deposits/permit");
|
|
@@ -1733,9 +1809,11 @@ function createDepositService(baseUrl, options) {
|
|
|
1733
1809
|
},
|
|
1734
1810
|
getTopTokens() {
|
|
1735
1811
|
if (!topTokensPromise) {
|
|
1736
|
-
const attempt = requestTopTokens().then((
|
|
1737
|
-
if (!
|
|
1738
|
-
|
|
1812
|
+
const attempt = requestTopTokens().then((result) => {
|
|
1813
|
+
if (!result.ok && topTokensPromise === attempt) {
|
|
1814
|
+
topTokensPromise = null;
|
|
1815
|
+
}
|
|
1816
|
+
return result;
|
|
1739
1817
|
});
|
|
1740
1818
|
topTokensPromise = attempt;
|
|
1741
1819
|
}
|
|
@@ -1964,6 +2042,7 @@ function useStableRpcUrls(rpcUrls) {
|
|
|
1964
2042
|
// src/core/chain-catalog-context.tsx
|
|
1965
2043
|
import {
|
|
1966
2044
|
createContext as createContext2,
|
|
2045
|
+
useCallback as useCallback2,
|
|
1967
2046
|
useContext as useContext2,
|
|
1968
2047
|
useEffect as useEffect2,
|
|
1969
2048
|
useMemo as useMemo2,
|
|
@@ -1971,6 +2050,59 @@ import {
|
|
|
1971
2050
|
useSyncExternalStore
|
|
1972
2051
|
} from "react";
|
|
1973
2052
|
|
|
2053
|
+
// src/core/deposit-bounds.ts
|
|
2054
|
+
import { formatUnits } from "viem";
|
|
2055
|
+
function findListed(options, chain, token) {
|
|
2056
|
+
const normalize2 = (value) => chain === "solana" ? value : value.toLowerCase();
|
|
2057
|
+
return options.tokens[String(chain)]?.find(
|
|
2058
|
+
(listed) => normalize2(listed.address) === normalize2(token)
|
|
2059
|
+
);
|
|
2060
|
+
}
|
|
2061
|
+
function isExcludedByRestrictedList(options, chain, token) {
|
|
2062
|
+
return Boolean(options?.restricted && !findListed(options, chain, token));
|
|
2063
|
+
}
|
|
2064
|
+
function findDepositBounds(options, chain, token) {
|
|
2065
|
+
if (!options?.restricted) return void 0;
|
|
2066
|
+
const entry = findListed(options, chain, token);
|
|
2067
|
+
if (!entry || entry.minAmount === void 0 && entry.maxAmount === void 0) {
|
|
2068
|
+
return void 0;
|
|
2069
|
+
}
|
|
2070
|
+
return {
|
|
2071
|
+
symbol: entry.symbol,
|
|
2072
|
+
decimals: entry.decimals,
|
|
2073
|
+
...entry.minAmount !== void 0 && { minAmount: BigInt(entry.minAmount) },
|
|
2074
|
+
...entry.maxAmount !== void 0 && { maxAmount: BigInt(entry.maxAmount) }
|
|
2075
|
+
};
|
|
2076
|
+
}
|
|
2077
|
+
function boundMessage(bounds, bound) {
|
|
2078
|
+
const raw = bounds?.[bound];
|
|
2079
|
+
if (!bounds || raw === void 0) return null;
|
|
2080
|
+
const amount = new Intl.NumberFormat("en-US", {
|
|
2081
|
+
maximumFractionDigits: Math.min(bounds.decimals, 20)
|
|
2082
|
+
}).format(Number(formatUnits(raw, bounds.decimals)));
|
|
2083
|
+
return `${bound === "minAmount" ? "Minimum" : "Maximum"} deposit is ${amount} ${bounds.symbol}`;
|
|
2084
|
+
}
|
|
2085
|
+
function depositBoundsViolation(bounds, units) {
|
|
2086
|
+
if (!bounds || units === null || units <= 0n) return null;
|
|
2087
|
+
if (bounds.minAmount !== void 0 && units < bounds.minAmount) {
|
|
2088
|
+
return boundMessage(bounds, "minAmount");
|
|
2089
|
+
}
|
|
2090
|
+
if (bounds.maxAmount !== void 0 && units > bounds.maxAmount) {
|
|
2091
|
+
return boundMessage(bounds, "maxAmount");
|
|
2092
|
+
}
|
|
2093
|
+
return null;
|
|
2094
|
+
}
|
|
2095
|
+
function describePolicyRefusal(refusal, bounds) {
|
|
2096
|
+
switch (refusal.code) {
|
|
2097
|
+
case "BALANCE-4":
|
|
2098
|
+
return boundMessage(bounds, "minAmount") ?? "This amount is below the minimum deposit";
|
|
2099
|
+
case "BALANCE-3":
|
|
2100
|
+
return boundMessage(bounds, "maxAmount") ?? "This amount is above the maximum deposit";
|
|
2101
|
+
default:
|
|
2102
|
+
return "This token isn't accepted for deposits";
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
|
|
1974
2106
|
// src/core/public-client.ts
|
|
1975
2107
|
import { createPublicClient, http } from "viem";
|
|
1976
2108
|
var clientCache = /* @__PURE__ */ new Map();
|
|
@@ -2135,6 +2267,9 @@ var EMPTY = {
|
|
|
2135
2267
|
viemChains: null,
|
|
2136
2268
|
isLoading: true,
|
|
2137
2269
|
shortlist: null,
|
|
2270
|
+
depositOptions: { status: "loading" },
|
|
2271
|
+
retryDepositOptions: () => {
|
|
2272
|
+
},
|
|
2138
2273
|
clientCapableChainIds: null
|
|
2139
2274
|
};
|
|
2140
2275
|
var ChainCatalogContext = createContext2(EMPTY);
|
|
@@ -2292,6 +2427,48 @@ function useTargetTokens() {
|
|
|
2292
2427
|
};
|
|
2293
2428
|
}, [catalog, shortlist]);
|
|
2294
2429
|
}
|
|
2430
|
+
function createDepositOffer(state, retry) {
|
|
2431
|
+
const options = state.status === "ready" ? state.options : null;
|
|
2432
|
+
const restricted = options?.restricted ?? false;
|
|
2433
|
+
const listed = (chain) => options?.tokens[String(chain)];
|
|
2434
|
+
const isChainOffered = (chain) => {
|
|
2435
|
+
if (!options) return false;
|
|
2436
|
+
const entry = listed(chain);
|
|
2437
|
+
return restricted ? (entry?.length ?? 0) > 0 : entry?.length !== 0;
|
|
2438
|
+
};
|
|
2439
|
+
return {
|
|
2440
|
+
status: state.status,
|
|
2441
|
+
restricted,
|
|
2442
|
+
retry,
|
|
2443
|
+
tokensFor: (chain) => {
|
|
2444
|
+
if (!options) return [];
|
|
2445
|
+
const entry = listed(chain);
|
|
2446
|
+
return restricted ? entry ?? [] : entry;
|
|
2447
|
+
},
|
|
2448
|
+
isChainOffered
|
|
2449
|
+
};
|
|
2450
|
+
}
|
|
2451
|
+
function useDepositOffer() {
|
|
2452
|
+
const { depositOptions, retryDepositOptions } = useChainCatalog();
|
|
2453
|
+
return useMemo2(
|
|
2454
|
+
() => createDepositOffer(depositOptions, retryDepositOptions),
|
|
2455
|
+
[depositOptions, retryDepositOptions]
|
|
2456
|
+
);
|
|
2457
|
+
}
|
|
2458
|
+
function useDepositBounds() {
|
|
2459
|
+
const { depositOptions } = useChainCatalog();
|
|
2460
|
+
return useMemo2(() => {
|
|
2461
|
+
const options = depositOptions.status === "ready" ? depositOptions.options : null;
|
|
2462
|
+
return (chain, token) => findDepositBounds(options, chain, token);
|
|
2463
|
+
}, [depositOptions]);
|
|
2464
|
+
}
|
|
2465
|
+
function useRestrictedListExclusion() {
|
|
2466
|
+
const { depositOptions } = useChainCatalog();
|
|
2467
|
+
return useMemo2(() => {
|
|
2468
|
+
const options = depositOptions.status === "ready" ? depositOptions.options : null;
|
|
2469
|
+
return (chain, token) => isExcludedByRestrictedList(options, chain, token);
|
|
2470
|
+
}, [depositOptions]);
|
|
2471
|
+
}
|
|
2295
2472
|
function useIsDepositChain() {
|
|
2296
2473
|
const ids = useDepositChainIds();
|
|
2297
2474
|
const { clientCapableChainIds } = useChainCatalog();
|
|
@@ -2384,19 +2561,36 @@ function ChainCatalogProvider({
|
|
|
2384
2561
|
const chains = toViemChains(catalog, overrides, viemChains);
|
|
2385
2562
|
if (chains.length > 0) setRuntimeChains(chains);
|
|
2386
2563
|
}, [catalog, viemChains, overrides]);
|
|
2387
|
-
const [
|
|
2564
|
+
const [depositOptions, setDepositOptions] = useState({
|
|
2565
|
+
status: "loading"
|
|
2566
|
+
});
|
|
2567
|
+
const [depositOptionsAttempt, setDepositOptionsAttempt] = useState(0);
|
|
2388
2568
|
useEffect2(() => {
|
|
2389
2569
|
let active = true;
|
|
2390
|
-
|
|
2391
|
-
service.getTopTokens().then(
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2570
|
+
setDepositOptions({ status: "loading" });
|
|
2571
|
+
service.getTopTokens().then(
|
|
2572
|
+
(result) => {
|
|
2573
|
+
if (!active) return;
|
|
2574
|
+
if (!result?.ok) {
|
|
2575
|
+
setDepositOptions({ status: "error" });
|
|
2576
|
+
return;
|
|
2577
|
+
}
|
|
2578
|
+
publishShortlistTokens(result.options.tokens);
|
|
2579
|
+
setDepositOptions({ status: "ready", options: result.options });
|
|
2580
|
+
},
|
|
2581
|
+
() => {
|
|
2582
|
+
if (active) setDepositOptions({ status: "error" });
|
|
2583
|
+
}
|
|
2584
|
+
);
|
|
2396
2585
|
return () => {
|
|
2397
2586
|
active = false;
|
|
2398
2587
|
};
|
|
2399
|
-
}, [service]);
|
|
2588
|
+
}, [service, depositOptionsAttempt]);
|
|
2589
|
+
const retryDepositOptions = useCallback2(
|
|
2590
|
+
() => setDepositOptionsAttempt((attempt) => attempt + 1),
|
|
2591
|
+
[]
|
|
2592
|
+
);
|
|
2593
|
+
const shortlist = depositOptions.status === "ready" ? depositOptions.options.tokens : null;
|
|
2400
2594
|
const clientCapableChainIds = useMemo2(() => {
|
|
2401
2595
|
if (!catalog) return null;
|
|
2402
2596
|
return new Set(
|
|
@@ -2409,9 +2603,19 @@ function ChainCatalogProvider({
|
|
|
2409
2603
|
viemChains,
|
|
2410
2604
|
isLoading,
|
|
2411
2605
|
shortlist,
|
|
2606
|
+
depositOptions,
|
|
2607
|
+
retryDepositOptions,
|
|
2412
2608
|
clientCapableChainIds
|
|
2413
2609
|
}),
|
|
2414
|
-
[
|
|
2610
|
+
[
|
|
2611
|
+
catalog,
|
|
2612
|
+
viemChains,
|
|
2613
|
+
isLoading,
|
|
2614
|
+
shortlist,
|
|
2615
|
+
depositOptions,
|
|
2616
|
+
retryDepositOptions,
|
|
2617
|
+
clientCapableChainIds
|
|
2618
|
+
]
|
|
2415
2619
|
);
|
|
2416
2620
|
return /* @__PURE__ */ jsx3(ChainCatalogContext.Provider, { value, children });
|
|
2417
2621
|
}
|
|
@@ -2429,7 +2633,7 @@ function useLatestRef(value) {
|
|
|
2429
2633
|
// src/core/analytics.tsx
|
|
2430
2634
|
import {
|
|
2431
2635
|
createContext as createContext3,
|
|
2432
|
-
useCallback as
|
|
2636
|
+
useCallback as useCallback3,
|
|
2433
2637
|
useContext as useContext3,
|
|
2434
2638
|
useEffect as useEffect4,
|
|
2435
2639
|
useMemo as useMemo3,
|
|
@@ -2817,7 +3021,7 @@ function AnalyticsSession(props) {
|
|
|
2817
3021
|
nowRef.current = props.now ?? (() => /* @__PURE__ */ new Date());
|
|
2818
3022
|
const modal = props.modal;
|
|
2819
3023
|
const reportedFailuresRef = useRef3(/* @__PURE__ */ new Set());
|
|
2820
|
-
const emitFailure =
|
|
3024
|
+
const emitFailure = useCallback3(
|
|
2821
3025
|
({ reason, status, droppedEvents }) => {
|
|
2822
3026
|
if (reportedFailuresRef.current.has(reason)) return;
|
|
2823
3027
|
reportedFailuresRef.current.add(reason);
|
|
@@ -2867,7 +3071,7 @@ function AnalyticsSession(props) {
|
|
|
2867
3071
|
ingestRef.current = createIngest();
|
|
2868
3072
|
}
|
|
2869
3073
|
const pendingDisposalRef = useRef3(null);
|
|
2870
|
-
const enqueue =
|
|
3074
|
+
const enqueue = useCallback3(
|
|
2871
3075
|
(event) => {
|
|
2872
3076
|
try {
|
|
2873
3077
|
ingestRef.current?.transport?.enqueue(
|
|
@@ -2902,7 +3106,7 @@ function AnalyticsSession(props) {
|
|
|
2902
3106
|
}, 0);
|
|
2903
3107
|
};
|
|
2904
3108
|
}, [emitFailure]);
|
|
2905
|
-
const emitDeposit =
|
|
3109
|
+
const emitDeposit = useCallback3(
|
|
2906
3110
|
(...[payload, fundingMethod]) => {
|
|
2907
3111
|
if (modal !== "deposit") return;
|
|
2908
3112
|
const event = {
|
|
@@ -2921,7 +3125,7 @@ function AnalyticsSession(props) {
|
|
|
2921
3125
|
},
|
|
2922
3126
|
[enqueue, modal, nowRef, onEventRef]
|
|
2923
3127
|
);
|
|
2924
|
-
const emitWithdraw =
|
|
3128
|
+
const emitWithdraw = useCallback3(
|
|
2925
3129
|
(payload) => {
|
|
2926
3130
|
if (modal !== "withdraw") return;
|
|
2927
3131
|
const event = {
|
|
@@ -2937,7 +3141,7 @@ function AnalyticsSession(props) {
|
|
|
2937
3141
|
},
|
|
2938
3142
|
[enqueue, modal, nowRef, onEventRef]
|
|
2939
3143
|
);
|
|
2940
|
-
const emitClaim =
|
|
3144
|
+
const emitClaim = useCallback3(
|
|
2941
3145
|
(payload) => {
|
|
2942
3146
|
if (modal !== "claim") return;
|
|
2943
3147
|
const event = {
|
|
@@ -3011,17 +3215,38 @@ function recoveryFailureCause(sourceChainName) {
|
|
|
3011
3215
|
}
|
|
3012
3216
|
|
|
3013
3217
|
// src/core/history-status.ts
|
|
3014
|
-
|
|
3218
|
+
var UNKNOWN = ["pending", false, []];
|
|
3219
|
+
var STATUS_FACTS = [
|
|
3220
|
+
// `delayed` is held up but still coming on the corridor's schedule.
|
|
3221
|
+
["pending", true, ["pending", "delayed"]],
|
|
3222
|
+
// Nothing emits `submitted` or `bridging`; they are here so the badge and
|
|
3223
|
+
// the arrival line cannot diverge should a row ever carry them.
|
|
3224
|
+
["processing", true, ["processing", "submitted", "bridging"]],
|
|
3225
|
+
["completed", false, ["completed", "complete", "bridge-complete", "processed"]],
|
|
3226
|
+
// `rejected` is recoverable upstream exactly like `failed`, so it must not
|
|
3227
|
+
// read as Pending — a row offering recovery would otherwise claim to still
|
|
3228
|
+
// be on its way.
|
|
3229
|
+
["failed", false, ["failed", "error", "bridge-failed", "rejected"]],
|
|
3230
|
+
// Where a recovered deposit lands. Terminal and not recoverable again.
|
|
3231
|
+
["refunded", false, ["refunded"]],
|
|
3232
|
+
// These read Pending but are not arriving: the deposit is bound for a refund
|
|
3233
|
+
// or for manual reconciliation rather than for the recipient, so an arrival
|
|
3234
|
+
// expectation would be a claim about a corridor it never enters.
|
|
3235
|
+
["pending", false, ["ignored", "expecting_refund", "reconciliation_required"]]
|
|
3236
|
+
];
|
|
3237
|
+
function lookup(raw) {
|
|
3015
3238
|
const lower = raw.toLowerCase();
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3239
|
+
return STATUS_FACTS.find((facts) => facts[2].includes(lower)) ?? UNKNOWN;
|
|
3240
|
+
}
|
|
3241
|
+
function normalizeStatus(raw, isSpam) {
|
|
3242
|
+
const [badge] = lookup(raw);
|
|
3243
|
+
return isSpam && badge === "failed" ? "spam" : badge;
|
|
3244
|
+
}
|
|
3245
|
+
function isInFlight(status) {
|
|
3246
|
+
return status === "pending" || status === "processing";
|
|
3247
|
+
}
|
|
3248
|
+
function expectsArrival(raw) {
|
|
3249
|
+
return lookup(raw)[1];
|
|
3025
3250
|
}
|
|
3026
3251
|
var STATUS_LABEL = {
|
|
3027
3252
|
pending: "Pending",
|
|
@@ -3041,20 +3266,37 @@ function filterVisibleDeposits(deposits) {
|
|
|
3041
3266
|
}
|
|
3042
3267
|
|
|
3043
3268
|
// src/core/history-badge.ts
|
|
3044
|
-
|
|
3269
|
+
var RECOVERY_INDICATOR_WINDOW_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
3270
|
+
function deriveHistoryBadgeState(deposits, {
|
|
3271
|
+
recipient,
|
|
3272
|
+
canRecover,
|
|
3273
|
+
evaluatedAt = Date.now()
|
|
3274
|
+
}) {
|
|
3045
3275
|
const visible = filterVisibleDeposits(deposits);
|
|
3046
3276
|
if (canRecover) {
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
)
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3277
|
+
let count = 0;
|
|
3278
|
+
let nextExpiryAt = null;
|
|
3279
|
+
for (const row of visible) {
|
|
3280
|
+
if (toRecoverableDeposit(row, { recipient }) === null) continue;
|
|
3281
|
+
const expiryAt = Date.parse(row.createdAt ?? "") + RECOVERY_INDICATOR_WINDOW_MS;
|
|
3282
|
+
if (!(evaluatedAt < expiryAt)) continue;
|
|
3283
|
+
count += 1;
|
|
3284
|
+
nextExpiryAt = nextExpiryAt === null ? expiryAt : Math.min(nextExpiryAt, expiryAt);
|
|
3285
|
+
}
|
|
3286
|
+
if (count > 0) {
|
|
3287
|
+
return {
|
|
3288
|
+
badge: { state: "needs-you", count },
|
|
3289
|
+
nextExpiryAt
|
|
3290
|
+
};
|
|
3291
|
+
}
|
|
3292
|
+
}
|
|
3293
|
+
const inProgress = visible.filter(
|
|
3294
|
+
(row) => isInFlight(normalizeStatus(row.status, row.isSpam))
|
|
3295
|
+
).length;
|
|
3296
|
+
return {
|
|
3297
|
+
badge: inProgress > 0 ? { state: "progress", count: inProgress } : null,
|
|
3298
|
+
nextExpiryAt: null
|
|
3299
|
+
};
|
|
3058
3300
|
}
|
|
3059
3301
|
function historyBadgeAriaLabel(badge) {
|
|
3060
3302
|
if (!badge) return "Deposit history";
|
|
@@ -3094,11 +3336,11 @@ function HistoryEntryButton({
|
|
|
3094
3336
|
}
|
|
3095
3337
|
|
|
3096
3338
|
// src/components/history/HistoryOverlay.tsx
|
|
3097
|
-
import { useCallback as
|
|
3339
|
+
import { useCallback as useCallback7, useEffect as useEffect10, useMemo as useMemo6, useRef as useRef7, useState as useState8 } from "react";
|
|
3098
3340
|
|
|
3099
3341
|
// src/components/history/DepositHistoryPanel.tsx
|
|
3100
3342
|
import {
|
|
3101
|
-
useCallback as
|
|
3343
|
+
useCallback as useCallback4,
|
|
3102
3344
|
useEffect as useEffect5,
|
|
3103
3345
|
useId,
|
|
3104
3346
|
useMemo as useMemo4,
|
|
@@ -3428,14 +3670,13 @@ function advancePendingTimingState(previous, next) {
|
|
|
3428
3670
|
}
|
|
3429
3671
|
|
|
3430
3672
|
// src/core/history-timing.ts
|
|
3431
|
-
var TIMED_HISTORY_STATUSES = /* @__PURE__ */ new Set(["pending", "processing", "delayed"]);
|
|
3432
3673
|
function resolveHistoryTiming({
|
|
3433
3674
|
status,
|
|
3434
3675
|
timing,
|
|
3435
3676
|
createdAt,
|
|
3436
3677
|
nowMs
|
|
3437
3678
|
}) {
|
|
3438
|
-
if (!
|
|
3679
|
+
if (!expectsArrival(status) || !timing || !createdAt) {
|
|
3439
3680
|
return void 0;
|
|
3440
3681
|
}
|
|
3441
3682
|
const createdAtMs = Date.parse(createdAt);
|
|
@@ -3559,7 +3800,7 @@ function DepositHistoryPanel({
|
|
|
3559
3800
|
useEffect5(() => {
|
|
3560
3801
|
rootRef.current?.toggleAttribute("inert", Boolean(obscured));
|
|
3561
3802
|
}, [obscured]);
|
|
3562
|
-
const handleKeyDown =
|
|
3803
|
+
const handleKeyDown = useCallback4(
|
|
3563
3804
|
(e) => {
|
|
3564
3805
|
if (obscured) return;
|
|
3565
3806
|
if (e.key === "Escape") {
|
|
@@ -3860,7 +4101,7 @@ function HistoryCard({
|
|
|
3860
4101
|
DepositHistoryPanel.displayName = "DepositHistoryPanel";
|
|
3861
4102
|
|
|
3862
4103
|
// src/components/history/HistoryFallbackFlow.tsx
|
|
3863
|
-
import { useCallback as
|
|
4104
|
+
import { useCallback as useCallback5, useEffect as useEffect7, useRef as useRef5, useState as useState5 } from "react";
|
|
3864
4105
|
|
|
3865
4106
|
// src/components/ui/ListRow.tsx
|
|
3866
4107
|
import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
@@ -4044,10 +4285,10 @@ function RecoveryLookupScreen({
|
|
|
4044
4285
|
RecoveryLookupScreen.displayName = "RecoveryLookupScreen";
|
|
4045
4286
|
|
|
4046
4287
|
// src/components/recovery/recovery-display.ts
|
|
4047
|
-
import { formatUnits as
|
|
4288
|
+
import { formatUnits as formatUnits3 } from "viem";
|
|
4048
4289
|
|
|
4049
4290
|
// src/core/token-amount.ts
|
|
4050
|
-
import { formatUnits } from "viem";
|
|
4291
|
+
import { formatUnits as formatUnits2 } from "viem";
|
|
4051
4292
|
var STABLECOIN_SYMBOLS = /* @__PURE__ */ new Set([
|
|
4052
4293
|
"USDC",
|
|
4053
4294
|
"USDT",
|
|
@@ -4111,7 +4352,7 @@ function formatTokenAmount(amount, symbol) {
|
|
|
4111
4352
|
function tokenAmountToNumber(rawAmount, decimals) {
|
|
4112
4353
|
if (decimals === void 0) return void 0;
|
|
4113
4354
|
try {
|
|
4114
|
-
const value = Number(
|
|
4355
|
+
const value = Number(formatUnits2(BigInt(rawAmount), decimals));
|
|
4115
4356
|
return Number.isFinite(value) ? value : void 0;
|
|
4116
4357
|
} catch {
|
|
4117
4358
|
return void 0;
|
|
@@ -4198,18 +4439,18 @@ function describeRecoveryDeposit(params) {
|
|
|
4198
4439
|
const decimals = getTokenDecimalsByAddress(token, params.chainId);
|
|
4199
4440
|
const symbol = getTokenSymbol(token, params.chainId);
|
|
4200
4441
|
const raw = toBigInt(params.amountRaw);
|
|
4201
|
-
const human = Number(
|
|
4442
|
+
const human = Number(formatUnits3(raw, decimals));
|
|
4202
4443
|
return {
|
|
4203
4444
|
symbol,
|
|
4204
4445
|
decimals,
|
|
4205
|
-
amount: formatTokenAmount(human, symbol) ??
|
|
4446
|
+
amount: formatTokenAmount(human, symbol) ?? formatUnits3(raw, decimals),
|
|
4206
4447
|
chainName: getChainName(params.chainId),
|
|
4207
4448
|
chainIcon: getChainIcon(params.chainId)
|
|
4208
4449
|
};
|
|
4209
4450
|
}
|
|
4210
4451
|
function formatRecoveryAmount(amountRaw, decimals, symbol) {
|
|
4211
4452
|
const raw = toBigInt(amountRaw);
|
|
4212
|
-
return formatTokenAmount(Number(
|
|
4453
|
+
return formatTokenAmount(Number(formatUnits3(raw, decimals)), symbol) ?? formatUnits3(raw, decimals);
|
|
4213
4454
|
}
|
|
4214
4455
|
function toBigInt(value) {
|
|
4215
4456
|
try {
|
|
@@ -4697,7 +4938,7 @@ function HistoryFallbackFlow({
|
|
|
4697
4938
|
epochRef.current += 1;
|
|
4698
4939
|
};
|
|
4699
4940
|
}, [recipient]);
|
|
4700
|
-
const reportSelection =
|
|
4941
|
+
const reportSelection = useCallback5(
|
|
4701
4942
|
(match, autoSelected) => {
|
|
4702
4943
|
analytics.selectDeposit({
|
|
4703
4944
|
depositId: match.depositId,
|
|
@@ -4707,7 +4948,7 @@ function HistoryFallbackFlow({
|
|
|
4707
4948
|
},
|
|
4708
4949
|
[analytics]
|
|
4709
4950
|
);
|
|
4710
|
-
const
|
|
4951
|
+
const lookup2 = useCallback5(
|
|
4711
4952
|
async (txHash) => {
|
|
4712
4953
|
const epoch = epochRef.current;
|
|
4713
4954
|
const isCurrentLookup = () => epochRef.current === epoch;
|
|
@@ -4750,7 +4991,7 @@ function HistoryFallbackFlow({
|
|
|
4750
4991
|
},
|
|
4751
4992
|
[analytics, service, recipient, onFound, reportSelection]
|
|
4752
4993
|
);
|
|
4753
|
-
const selectMatch =
|
|
4994
|
+
const selectMatch = useCallback5(
|
|
4754
4995
|
(match) => {
|
|
4755
4996
|
analytics.completeStep("select");
|
|
4756
4997
|
reportSelection(match, false);
|
|
@@ -4758,7 +4999,7 @@ function HistoryFallbackFlow({
|
|
|
4758
4999
|
},
|
|
4759
5000
|
[analytics, onFound, reportSelection]
|
|
4760
5001
|
);
|
|
4761
|
-
const handleKeyDown =
|
|
5002
|
+
const handleKeyDown = useCallback5(
|
|
4762
5003
|
(e) => {
|
|
4763
5004
|
if (e.key === "Escape") {
|
|
4764
5005
|
e.stopPropagation();
|
|
@@ -4837,7 +5078,7 @@ function HistoryFallbackFlow({
|
|
|
4837
5078
|
hint: "The transaction hash from the wallet or exchange you sent from.",
|
|
4838
5079
|
loading,
|
|
4839
5080
|
error,
|
|
4840
|
-
onSubmit:
|
|
5081
|
+
onSubmit: lookup2,
|
|
4841
5082
|
onInvalid: () => analytics.friction("lookup_transaction_hash_invalid", "lookup")
|
|
4842
5083
|
}
|
|
4843
5084
|
)
|
|
@@ -4853,7 +5094,7 @@ function newestFirst(rows) {
|
|
|
4853
5094
|
HistoryFallbackFlow.displayName = "HistoryFallbackFlow";
|
|
4854
5095
|
|
|
4855
5096
|
// src/components/history/HistoryRecoveryFlow.tsx
|
|
4856
|
-
import { useCallback as
|
|
5097
|
+
import { useCallback as useCallback6, useEffect as useEffect9, useRef as useRef6, useState as useState7 } from "react";
|
|
4857
5098
|
|
|
4858
5099
|
// src/components/recovery/RecoveryOutcomeScreen.tsx
|
|
4859
5100
|
import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
@@ -5057,7 +5298,7 @@ function HistoryRecoveryFlow({
|
|
|
5057
5298
|
token: deposit.token,
|
|
5058
5299
|
amountRaw: deposit.amountRaw
|
|
5059
5300
|
});
|
|
5060
|
-
const submit =
|
|
5301
|
+
const submit = useCallback6(
|
|
5061
5302
|
async (destination) => {
|
|
5062
5303
|
setPhase("submitting");
|
|
5063
5304
|
onSubmittingChange(true);
|
|
@@ -5129,7 +5370,7 @@ function HistoryRecoveryFlow({
|
|
|
5129
5370
|
symbol
|
|
5130
5371
|
]
|
|
5131
5372
|
);
|
|
5132
|
-
const retry =
|
|
5373
|
+
const retry = useCallback6(() => {
|
|
5133
5374
|
const reason = lastFailureRef.current;
|
|
5134
5375
|
if (reason) {
|
|
5135
5376
|
lastFailureRef.current = null;
|
|
@@ -5226,7 +5467,7 @@ function HistoryOverlay({
|
|
|
5226
5467
|
const [fallbackOpen, setFallbackOpen] = useState8(false);
|
|
5227
5468
|
const [attempt, setAttempt] = useState8(null);
|
|
5228
5469
|
const claimControllerRef = useRef7(null);
|
|
5229
|
-
const beginAttempt =
|
|
5470
|
+
const beginAttempt = useCallback7(
|
|
5230
5471
|
(entrySource) => {
|
|
5231
5472
|
const id = randomUuid();
|
|
5232
5473
|
const started = {
|
|
@@ -5244,7 +5485,7 @@ function HistoryOverlay({
|
|
|
5244
5485
|
},
|
|
5245
5486
|
[analytics]
|
|
5246
5487
|
);
|
|
5247
|
-
const endAttempt =
|
|
5488
|
+
const endAttempt = useCallback7(
|
|
5248
5489
|
(source, reason) => {
|
|
5249
5490
|
const claim = claimControllerRef.current;
|
|
5250
5491
|
claim?.abandon(reason);
|
|
@@ -5254,12 +5495,12 @@ function HistoryOverlay({
|
|
|
5254
5495
|
},
|
|
5255
5496
|
[]
|
|
5256
5497
|
);
|
|
5257
|
-
const openFallback =
|
|
5498
|
+
const openFallback = useCallback7(() => {
|
|
5258
5499
|
const started = beginAttempt("history_fallback");
|
|
5259
5500
|
analytics.fallbackOpened(started.id);
|
|
5260
5501
|
setFallbackOpen(true);
|
|
5261
5502
|
}, [analytics, beginAttempt]);
|
|
5262
|
-
const closeFallback =
|
|
5503
|
+
const closeFallback = useCallback7(
|
|
5263
5504
|
(via) => {
|
|
5264
5505
|
endAttempt(via === "escape" ? "escape" : "history_back", "back");
|
|
5265
5506
|
setFallbackOpen(false);
|
|
@@ -5272,7 +5513,7 @@ function HistoryOverlay({
|
|
|
5272
5513
|
setFallbackOpen(false);
|
|
5273
5514
|
if (fallbackOpen && !recovering) endAttempt("host_controlled", "back");
|
|
5274
5515
|
}, [canLookup, fallbackOpen, recovering, endAttempt]);
|
|
5275
|
-
const startRecoveryFromRow =
|
|
5516
|
+
const startRecoveryFromRow = useCallback7(
|
|
5276
5517
|
(deposit) => {
|
|
5277
5518
|
const started = beginAttempt("history_row");
|
|
5278
5519
|
analytics.recoveryStarted(started.id, "history_row", deposit.depositId);
|
|
@@ -5280,7 +5521,7 @@ function HistoryOverlay({
|
|
|
5280
5521
|
},
|
|
5281
5522
|
[analytics, beginAttempt, controller]
|
|
5282
5523
|
);
|
|
5283
|
-
const startRecoveryFromLookup =
|
|
5524
|
+
const startRecoveryFromLookup = useCallback7(
|
|
5284
5525
|
(deposit) => {
|
|
5285
5526
|
if (attempt) {
|
|
5286
5527
|
analytics.recoveryStarted(
|
|
@@ -5294,11 +5535,11 @@ function HistoryOverlay({
|
|
|
5294
5535
|
},
|
|
5295
5536
|
[analytics, attempt, controller]
|
|
5296
5537
|
);
|
|
5297
|
-
const cancelRecovery =
|
|
5538
|
+
const cancelRecovery = useCallback7(() => {
|
|
5298
5539
|
endAttempt("history_back", "back");
|
|
5299
5540
|
controller.cancelRecovery();
|
|
5300
5541
|
}, [controller, endAttempt]);
|
|
5301
|
-
const closeModal =
|
|
5542
|
+
const closeModal = useCallback7(() => {
|
|
5302
5543
|
endAttempt("header_button", "modal_close");
|
|
5303
5544
|
onCloseModal();
|
|
5304
5545
|
}, [endAttempt, onCloseModal]);
|
|
@@ -5389,7 +5630,8 @@ function HistoryOverlay({
|
|
|
5389
5630
|
}
|
|
5390
5631
|
|
|
5391
5632
|
// src/components/history/useHistoryPanel.ts
|
|
5392
|
-
import { useCallback as
|
|
5633
|
+
import { useCallback as useCallback8, useEffect as useEffect11, useMemo as useMemo7, useRef as useRef8, useState as useState9 } from "react";
|
|
5634
|
+
var MAX_TIMEOUT_MS = 2147483647;
|
|
5393
5635
|
function sortByCreatedAtDesc(items) {
|
|
5394
5636
|
return [...items].sort((a, b) => {
|
|
5395
5637
|
const at = a.createdAt ? Date.parse(a.createdAt) : 0;
|
|
@@ -5417,7 +5659,7 @@ function useHistoryPanel({
|
|
|
5417
5659
|
const requestRef = useRef8(0);
|
|
5418
5660
|
const [recovering, setRecovering] = useState9(null);
|
|
5419
5661
|
const [recoverySubmitting, setRecoverySubmitting] = useState9(false);
|
|
5420
|
-
const fetchHistory =
|
|
5662
|
+
const fetchHistory = useCallback8(
|
|
5421
5663
|
async (mode = "initial") => {
|
|
5422
5664
|
if (!recipient) return;
|
|
5423
5665
|
const isInitial = mode === "initial";
|
|
@@ -5467,27 +5709,40 @@ function useHistoryPanel({
|
|
|
5467
5709
|
},
|
|
5468
5710
|
[recipient, service]
|
|
5469
5711
|
);
|
|
5470
|
-
const
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
);
|
|
5474
|
-
const
|
|
5712
|
+
const badgeState2 = deriveHistoryBadgeState(deposits, {
|
|
5713
|
+
recipient,
|
|
5714
|
+
canRecover
|
|
5715
|
+
});
|
|
5716
|
+
const badge = badgeState2.badge;
|
|
5717
|
+
useEffect11(() => {
|
|
5718
|
+
if (!isOpen || badgeState2.nextExpiryAt === null) return;
|
|
5719
|
+
const delay = Math.min(
|
|
5720
|
+
badgeState2.nextExpiryAt - Date.now(),
|
|
5721
|
+
MAX_TIMEOUT_MS
|
|
5722
|
+
);
|
|
5723
|
+
const timeout = setTimeout(
|
|
5724
|
+
() => setDeposits((current) => current.slice()),
|
|
5725
|
+
delay
|
|
5726
|
+
);
|
|
5727
|
+
return () => clearTimeout(timeout);
|
|
5728
|
+
}, [isOpen, badgeState2.nextExpiryAt]);
|
|
5729
|
+
const openPanel = useCallback8(() => {
|
|
5475
5730
|
setIsPanelOpen(true);
|
|
5476
5731
|
analytics?.visitOpened(badge);
|
|
5477
5732
|
if (!loadedRef.current || staleRef.current) {
|
|
5478
5733
|
fetchHistory("initial");
|
|
5479
5734
|
}
|
|
5480
5735
|
}, [analytics, badge, fetchHistory]);
|
|
5481
|
-
const closePanel =
|
|
5736
|
+
const closePanel = useCallback8(() => {
|
|
5482
5737
|
if (recovering) return;
|
|
5483
5738
|
setIsPanelOpen(false);
|
|
5484
5739
|
analytics?.visitEnded();
|
|
5485
5740
|
}, [analytics, recovering]);
|
|
5486
|
-
const loadMore =
|
|
5741
|
+
const loadMore = useCallback8(() => {
|
|
5487
5742
|
analytics?.loadMore(filterVisibleDeposits(deposits).length);
|
|
5488
5743
|
fetchHistory("more");
|
|
5489
5744
|
}, [analytics, deposits, fetchHistory]);
|
|
5490
|
-
const markStale =
|
|
5745
|
+
const markStale = useCallback8(() => {
|
|
5491
5746
|
staleRef.current = true;
|
|
5492
5747
|
if (isOpen) {
|
|
5493
5748
|
fetchHistory("initial");
|
|
@@ -5523,10 +5778,10 @@ function useHistoryPanel({
|
|
|
5523
5778
|
setRecovering(null);
|
|
5524
5779
|
setRecoverySubmitting(false);
|
|
5525
5780
|
}, [isOpen, analytics]);
|
|
5526
|
-
const invalidate =
|
|
5781
|
+
const invalidate = useCallback8(() => {
|
|
5527
5782
|
staleRef.current = true;
|
|
5528
5783
|
}, []);
|
|
5529
|
-
const cancelRecovery =
|
|
5784
|
+
const cancelRecovery = useCallback8(() => setRecovering(null), []);
|
|
5530
5785
|
return useMemo7(
|
|
5531
5786
|
() => ({
|
|
5532
5787
|
deposits,
|
|
@@ -5960,14 +6215,14 @@ function isSubmissionUncertain(error) {
|
|
|
5960
6215
|
}
|
|
5961
6216
|
|
|
5962
6217
|
// src/components/steps/ProcessingStep.tsx
|
|
5963
|
-
import { useCallback as
|
|
6218
|
+
import { useCallback as useCallback10, useEffect as useEffect14, useRef as useRef10, useState as useState13 } from "react";
|
|
5964
6219
|
|
|
5965
6220
|
// src/components/ui/Tooltip.tsx
|
|
5966
6221
|
import {
|
|
5967
6222
|
useState as useState10,
|
|
5968
6223
|
useRef as useRef9,
|
|
5969
6224
|
useEffect as useEffect12,
|
|
5970
|
-
useCallback as
|
|
6225
|
+
useCallback as useCallback9
|
|
5971
6226
|
} from "react";
|
|
5972
6227
|
import { createPortal as createPortal2 } from "react-dom";
|
|
5973
6228
|
import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
@@ -5976,7 +6231,7 @@ function Tooltip({ content, children, className }) {
|
|
|
5976
6231
|
const [position, setPosition] = useState10(null);
|
|
5977
6232
|
const triggerRef = useRef9(null);
|
|
5978
6233
|
const bubbleRef = useRef9(null);
|
|
5979
|
-
const updatePosition =
|
|
6234
|
+
const updatePosition = useCallback9(() => {
|
|
5980
6235
|
const trigger = triggerRef.current;
|
|
5981
6236
|
if (!trigger) return;
|
|
5982
6237
|
const rect = trigger.getBoundingClientRect();
|
|
@@ -6776,7 +7031,7 @@ function ProcessingStep({
|
|
|
6776
7031
|
}
|
|
6777
7032
|
const timingStateRef = useRef10("expected");
|
|
6778
7033
|
const servedTimingLatchRef = useRef10(false);
|
|
6779
|
-
const updatePhaseTimings =
|
|
7034
|
+
const updatePhaseTimings = useCallback10(
|
|
6780
7035
|
(updater) => {
|
|
6781
7036
|
setPhaseTimings((previous) => {
|
|
6782
7037
|
const next = updater(previous);
|
|
@@ -7709,8 +7964,11 @@ export {
|
|
|
7709
7964
|
SwappedConnectFeeChangedError,
|
|
7710
7965
|
SUPPORTED_CONNECT_EXCHANGE_COUNT,
|
|
7711
7966
|
resolveAppFeeBps,
|
|
7967
|
+
isDepositPolicyRefusal,
|
|
7712
7968
|
PermitDepositSubmitError,
|
|
7713
7969
|
createDepositService,
|
|
7970
|
+
depositBoundsViolation,
|
|
7971
|
+
describePolicyRefusal,
|
|
7714
7972
|
rpcUrlFor,
|
|
7715
7973
|
RpcUrlsProvider,
|
|
7716
7974
|
useRpcUrls,
|
|
@@ -7723,6 +7981,9 @@ export {
|
|
|
7723
7981
|
useDepositChainIds,
|
|
7724
7982
|
useDestinationChains,
|
|
7725
7983
|
useTargetTokens,
|
|
7984
|
+
useDepositOffer,
|
|
7985
|
+
useDepositBounds,
|
|
7986
|
+
useRestrictedListExclusion,
|
|
7726
7987
|
useIsDepositChain,
|
|
7727
7988
|
useChainName,
|
|
7728
7989
|
useReadClient,
|