@rhinestone/deposit-modal 0.1.40 → 0.1.42
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 +1 -0
- package/dist/{DepositModalReown-3HNOCOOO.mjs → DepositModalReown-3GPEVG26.mjs} +15 -6
- package/dist/{DepositModalReown-ZZKRN6J3.cjs → DepositModalReown-EEXNSXI4.cjs} +17 -8
- package/dist/{WithdrawModalReown-XXCOZYVU.mjs → WithdrawModalReown-7CSCY55U.mjs} +4 -4
- package/dist/{WithdrawModalReown-2CWNDVJD.cjs → WithdrawModalReown-GCOVYZN2.cjs} +7 -7
- package/dist/{chunk-K7BHCDJQ.cjs → chunk-37CTMJMO.cjs} +181 -96
- package/dist/{chunk-3O37UPSC.cjs → chunk-CDHUGROM.cjs} +1630 -362
- package/dist/{chunk-CFLZYWX7.mjs → chunk-KWAFKVV6.mjs} +120 -35
- package/dist/{chunk-AHOFT42H.cjs → chunk-LT3QKJI2.cjs} +458 -115
- package/dist/{chunk-SJEIKMVO.mjs → chunk-MBOH6XW3.mjs} +26 -13
- package/dist/{chunk-FLXTBFMZ.cjs → chunk-NELAYNA3.cjs} +11 -0
- package/dist/{chunk-F5S6RHUI.mjs → chunk-NLL42V7D.mjs} +1568 -300
- package/dist/{chunk-V7I5T4SW.cjs → chunk-PWPW7GFB.cjs} +25 -12
- package/dist/{chunk-IC2M2DZ7.mjs → chunk-QIK6ONMQ.mjs} +392 -49
- package/dist/{chunk-I7RYTI4G.mjs → chunk-ZJQZEIHA.mjs} +11 -0
- package/dist/constants.cjs +2 -2
- package/dist/constants.d.cts +6 -6
- package/dist/constants.d.ts +6 -6
- package/dist/constants.mjs +1 -1
- 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/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/reown.cjs +5 -5
- package/dist/reown.d.cts +1 -1
- package/dist/reown.d.ts +1 -1
- package/dist/reown.mjs +4 -4
- package/dist/styles.css +66 -0
- package/dist/{types-CIaQPR6F.d.cts → types-CyUiKQ4H.d.cts} +10 -7
- package/dist/{types-Bp2n2RQ3.d.ts → types-DQG7NEBI.d.ts} +10 -7
- 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 +25 -5
|
@@ -11,9 +11,10 @@ import {
|
|
|
11
11
|
createDepositService,
|
|
12
12
|
createSessionOwnerKey,
|
|
13
13
|
currencyFormatter,
|
|
14
|
+
debugError,
|
|
15
|
+
debugLog,
|
|
14
16
|
formatUserError,
|
|
15
17
|
getAssetId,
|
|
16
|
-
getEventSourceDetails,
|
|
17
18
|
getEventTxHash,
|
|
18
19
|
getPublicClient,
|
|
19
20
|
isDepositEvent,
|
|
@@ -21,8 +22,10 @@ import {
|
|
|
21
22
|
loadSessionOwnerFromStorage,
|
|
22
23
|
portfolioToAssets,
|
|
23
24
|
saveSessionOwnerToStorage,
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
toEvmCaip2,
|
|
26
|
+
tokenFormatter,
|
|
27
|
+
txRefsMatch
|
|
28
|
+
} from "./chunk-QIK6ONMQ.mjs";
|
|
26
29
|
import {
|
|
27
30
|
DEFAULT_BACKEND_URL,
|
|
28
31
|
DEFAULT_SIGNER_ADDRESS,
|
|
@@ -38,21 +41,22 @@ import {
|
|
|
38
41
|
getTokenIcon,
|
|
39
42
|
getTokenSymbol,
|
|
40
43
|
isStablecoinSymbol
|
|
41
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-ZJQZEIHA.mjs";
|
|
42
45
|
|
|
43
46
|
// src/DepositModal.tsx
|
|
44
47
|
import {
|
|
45
|
-
useMemo as
|
|
46
|
-
useEffect as
|
|
48
|
+
useMemo as useMemo8,
|
|
49
|
+
useEffect as useEffect9,
|
|
47
50
|
useRef as useRef6,
|
|
48
|
-
useState as
|
|
51
|
+
useState as useState11,
|
|
49
52
|
useCallback as useCallback4,
|
|
50
53
|
lazy,
|
|
51
54
|
Suspense
|
|
52
55
|
} from "react";
|
|
53
56
|
|
|
54
57
|
// src/DepositFlow.tsx
|
|
55
|
-
import { useState as
|
|
58
|
+
import { useState as useState10, useCallback as useCallback3, useMemo as useMemo7, useEffect as useEffect8, useRef as useRef5 } from "react";
|
|
59
|
+
import { formatUnits as formatUnits5 } from "viem";
|
|
56
60
|
|
|
57
61
|
// src/components/steps/SetupStep.tsx
|
|
58
62
|
import { useState, useEffect, useRef, useCallback } from "react";
|
|
@@ -101,7 +105,7 @@ function SetupStep({
|
|
|
101
105
|
const setup = await service.setupAccount({
|
|
102
106
|
ownerAddress: address,
|
|
103
107
|
sessionOwnerAddress: sessionOwner.address,
|
|
104
|
-
targetChain,
|
|
108
|
+
targetChain: toEvmCaip2(targetChain),
|
|
105
109
|
targetToken,
|
|
106
110
|
signerAddress,
|
|
107
111
|
sessionChainIds,
|
|
@@ -111,7 +115,7 @@ function SetupStep({
|
|
|
111
115
|
if (!setup.needsRegistration) {
|
|
112
116
|
setState({ type: "ready", smartAccount });
|
|
113
117
|
onConnected?.(address, smartAccount);
|
|
114
|
-
onSetupComplete(smartAccount);
|
|
118
|
+
onSetupComplete(smartAccount, setup.solanaDepositAddress);
|
|
115
119
|
return;
|
|
116
120
|
}
|
|
117
121
|
setState({ type: "signing-session" });
|
|
@@ -130,7 +134,7 @@ function SetupStep({
|
|
|
130
134
|
});
|
|
131
135
|
const sessionDetails = buildSessionDetails(setup.sessionDetailsUnsigned, signature);
|
|
132
136
|
setState({ type: "registering" });
|
|
133
|
-
await service.registerAccount({
|
|
137
|
+
const registerResult = await service.registerAccount({
|
|
134
138
|
address: smartAccount,
|
|
135
139
|
accountParams: {
|
|
136
140
|
factory: setup.accountParams.factory,
|
|
@@ -140,14 +144,14 @@ function SetupStep({
|
|
|
140
144
|
eoaAddress: address,
|
|
141
145
|
sessionOwner: sessionOwner.address,
|
|
142
146
|
target: {
|
|
143
|
-
chain: targetChain,
|
|
147
|
+
chain: toEvmCaip2(targetChain),
|
|
144
148
|
token: targetToken,
|
|
145
149
|
...recipient && { recipient }
|
|
146
150
|
}
|
|
147
151
|
});
|
|
148
152
|
setState({ type: "ready", smartAccount });
|
|
149
153
|
onConnected?.(address, smartAccount);
|
|
150
|
-
onSetupComplete(smartAccount);
|
|
154
|
+
onSetupComplete(smartAccount, registerResult.solanaDepositAddress);
|
|
151
155
|
} catch (error) {
|
|
152
156
|
const message = error instanceof Error ? error.message : "Setup failed";
|
|
153
157
|
setState({ type: "error", message });
|
|
@@ -1234,28 +1238,223 @@ function QRCode({ value, size = 200, iconSrc, className }) {
|
|
|
1234
1238
|
}
|
|
1235
1239
|
QRCode.displayName = "QRCode";
|
|
1236
1240
|
|
|
1241
|
+
// src/core/solana.ts
|
|
1242
|
+
import {
|
|
1243
|
+
Connection,
|
|
1244
|
+
PublicKey,
|
|
1245
|
+
SystemProgram,
|
|
1246
|
+
Transaction
|
|
1247
|
+
} from "@solana/web3.js";
|
|
1248
|
+
import {
|
|
1249
|
+
getAssociatedTokenAddress,
|
|
1250
|
+
createAssociatedTokenAccountInstruction,
|
|
1251
|
+
createTransferInstruction
|
|
1252
|
+
} from "@solana/spl-token";
|
|
1253
|
+
var SOLANA_TOKENS = [
|
|
1254
|
+
{ symbol: "SOL", mint: "native", decimals: 9 },
|
|
1255
|
+
{
|
|
1256
|
+
symbol: "USDC",
|
|
1257
|
+
mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
|
1258
|
+
decimals: 6
|
|
1259
|
+
},
|
|
1260
|
+
{
|
|
1261
|
+
symbol: "USDT",
|
|
1262
|
+
mint: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
|
|
1263
|
+
decimals: 6
|
|
1264
|
+
}
|
|
1265
|
+
];
|
|
1266
|
+
var DEFAULT_SOLANA_RPC_URL = "https://api.mainnet.solana.com";
|
|
1267
|
+
var configuredSolanaRpcUrl = null;
|
|
1268
|
+
var cachedConnections = /* @__PURE__ */ new Map();
|
|
1269
|
+
function configureSolanaRpcUrl(rpcUrl) {
|
|
1270
|
+
const normalized = rpcUrl?.trim();
|
|
1271
|
+
configuredSolanaRpcUrl = normalized ? normalized : null;
|
|
1272
|
+
cachedConnections.clear();
|
|
1273
|
+
}
|
|
1274
|
+
function getSolanaRpcUrl() {
|
|
1275
|
+
return configuredSolanaRpcUrl ?? DEFAULT_SOLANA_RPC_URL;
|
|
1276
|
+
}
|
|
1277
|
+
function getSolanaConnection() {
|
|
1278
|
+
const rpcUrl = getSolanaRpcUrl();
|
|
1279
|
+
const cached = cachedConnections.get(rpcUrl);
|
|
1280
|
+
if (cached) {
|
|
1281
|
+
return cached;
|
|
1282
|
+
}
|
|
1283
|
+
const next = new Connection(rpcUrl, "confirmed");
|
|
1284
|
+
cachedConnections.set(rpcUrl, next);
|
|
1285
|
+
return next;
|
|
1286
|
+
}
|
|
1287
|
+
function isNativeSol(token) {
|
|
1288
|
+
return token.mint === "native";
|
|
1289
|
+
}
|
|
1290
|
+
async function buildSolTransferTransaction(connection, from, to, lamports) {
|
|
1291
|
+
const fromPubkey = new PublicKey(from);
|
|
1292
|
+
const toPubkey = new PublicKey(to);
|
|
1293
|
+
const tx = new Transaction().add(
|
|
1294
|
+
SystemProgram.transfer({
|
|
1295
|
+
fromPubkey,
|
|
1296
|
+
toPubkey,
|
|
1297
|
+
lamports
|
|
1298
|
+
})
|
|
1299
|
+
);
|
|
1300
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
|
|
1301
|
+
tx.recentBlockhash = blockhash;
|
|
1302
|
+
tx.lastValidBlockHeight = lastValidBlockHeight;
|
|
1303
|
+
tx.feePayer = fromPubkey;
|
|
1304
|
+
return tx;
|
|
1305
|
+
}
|
|
1306
|
+
async function buildSplTransferTransaction(connection, from, to, mint, amount) {
|
|
1307
|
+
const fromPubkey = new PublicKey(from);
|
|
1308
|
+
const toPubkey = new PublicKey(to);
|
|
1309
|
+
const mintPubkey = new PublicKey(mint);
|
|
1310
|
+
const fromAta = await getAssociatedTokenAddress(mintPubkey, fromPubkey);
|
|
1311
|
+
const toAta = await getAssociatedTokenAddress(mintPubkey, toPubkey, true);
|
|
1312
|
+
const tx = new Transaction();
|
|
1313
|
+
const toAtaInfo = await connection.getAccountInfo(toAta);
|
|
1314
|
+
if (!toAtaInfo) {
|
|
1315
|
+
tx.add(
|
|
1316
|
+
createAssociatedTokenAccountInstruction(
|
|
1317
|
+
fromPubkey,
|
|
1318
|
+
toAta,
|
|
1319
|
+
toPubkey,
|
|
1320
|
+
mintPubkey
|
|
1321
|
+
)
|
|
1322
|
+
);
|
|
1323
|
+
}
|
|
1324
|
+
tx.add(createTransferInstruction(fromAta, toAta, fromPubkey, amount));
|
|
1325
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
|
|
1326
|
+
tx.recentBlockhash = blockhash;
|
|
1327
|
+
tx.lastValidBlockHeight = lastValidBlockHeight;
|
|
1328
|
+
tx.feePayer = fromPubkey;
|
|
1329
|
+
return tx;
|
|
1330
|
+
}
|
|
1331
|
+
function extractSignature(value) {
|
|
1332
|
+
if (typeof value === "string") {
|
|
1333
|
+
return value.length > 0 ? value : null;
|
|
1334
|
+
}
|
|
1335
|
+
if (typeof value.signature === "string" && value.signature.length > 0) {
|
|
1336
|
+
return value.signature;
|
|
1337
|
+
}
|
|
1338
|
+
if (typeof value.hash === "string" && value.hash.length > 0) {
|
|
1339
|
+
return value.hash;
|
|
1340
|
+
}
|
|
1341
|
+
if (typeof value.txid === "string" && value.txid.length > 0) {
|
|
1342
|
+
return value.txid;
|
|
1343
|
+
}
|
|
1344
|
+
if (typeof value.transactionId === "string" && value.transactionId.length > 0) {
|
|
1345
|
+
return value.transactionId;
|
|
1346
|
+
}
|
|
1347
|
+
return null;
|
|
1348
|
+
}
|
|
1349
|
+
async function sendSolanaTransaction(provider, _connection, transaction) {
|
|
1350
|
+
const result = await provider.signAndSendTransaction(transaction);
|
|
1351
|
+
const signature = extractSignature(result);
|
|
1352
|
+
if (!signature) {
|
|
1353
|
+
throw new Error("Transaction sent but wallet did not return a signature");
|
|
1354
|
+
}
|
|
1355
|
+
return signature;
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1237
1358
|
// src/components/steps/DepositAddressStep.tsx
|
|
1238
1359
|
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1239
1360
|
var POLL_INTERVAL_MS = 4e3;
|
|
1361
|
+
function isRecord(value) {
|
|
1362
|
+
return typeof value === "object" && value !== null;
|
|
1363
|
+
}
|
|
1364
|
+
function asNumber(value) {
|
|
1365
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
1366
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
1367
|
+
const parsed = Number(value);
|
|
1368
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
1369
|
+
}
|
|
1370
|
+
return void 0;
|
|
1371
|
+
}
|
|
1372
|
+
function asChainId(value) {
|
|
1373
|
+
if (typeof value === "string") {
|
|
1374
|
+
if (value.startsWith("solana")) return "solana";
|
|
1375
|
+
const eip155Match = value.match(/^eip155:(\d+)$/);
|
|
1376
|
+
if (eip155Match) return Number(eip155Match[1]);
|
|
1377
|
+
}
|
|
1378
|
+
return asNumber(value);
|
|
1379
|
+
}
|
|
1380
|
+
function asAmount(value) {
|
|
1381
|
+
if (typeof value === "string") return value;
|
|
1382
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
1383
|
+
return value.toString();
|
|
1384
|
+
}
|
|
1385
|
+
return void 0;
|
|
1386
|
+
}
|
|
1387
|
+
function asString(value) {
|
|
1388
|
+
return typeof value === "string" ? value : void 0;
|
|
1389
|
+
}
|
|
1390
|
+
function resolveSolanaTokenMeta(token) {
|
|
1391
|
+
if (!token) return {};
|
|
1392
|
+
const normalized = token.toLowerCase();
|
|
1393
|
+
const matched = SOLANA_TOKENS.find(
|
|
1394
|
+
(entry) => entry.mint.toLowerCase() === normalized
|
|
1395
|
+
);
|
|
1396
|
+
if (matched) {
|
|
1397
|
+
return { sourceSymbol: matched.symbol, sourceDecimals: matched.decimals };
|
|
1398
|
+
}
|
|
1399
|
+
if (normalized === "native" || normalized === "11111111111111111111111111111111" || normalized === "so11111111111111111111111111111111111111112") {
|
|
1400
|
+
return { sourceSymbol: "SOL", sourceDecimals: 9 };
|
|
1401
|
+
}
|
|
1402
|
+
return {};
|
|
1403
|
+
}
|
|
1404
|
+
function getDepositEventDetails(event) {
|
|
1405
|
+
if (!event?.type || !isRecord(event.data)) return {};
|
|
1406
|
+
if (event.type === "deposit-received") {
|
|
1407
|
+
const chainId = asChainId(event.data.chain);
|
|
1408
|
+
const token = asString(event.data.token);
|
|
1409
|
+
const solanaMeta = chainId === "solana" ? resolveSolanaTokenMeta(token) : {};
|
|
1410
|
+
return {
|
|
1411
|
+
chainId,
|
|
1412
|
+
amount: asAmount(event.data.amount),
|
|
1413
|
+
token,
|
|
1414
|
+
...solanaMeta
|
|
1415
|
+
};
|
|
1416
|
+
}
|
|
1417
|
+
if (event.type === "bridge-started") {
|
|
1418
|
+
const source = isRecord(event.data.source) ? event.data.source : void 0;
|
|
1419
|
+
const chainId = asChainId(source?.chain);
|
|
1420
|
+
const token = asString(source?.asset);
|
|
1421
|
+
const solanaMeta = chainId === "solana" ? resolveSolanaTokenMeta(token) : {};
|
|
1422
|
+
return {
|
|
1423
|
+
chainId,
|
|
1424
|
+
amount: asAmount(source?.amount),
|
|
1425
|
+
token,
|
|
1426
|
+
...solanaMeta
|
|
1427
|
+
};
|
|
1428
|
+
}
|
|
1429
|
+
return {};
|
|
1430
|
+
}
|
|
1240
1431
|
function DepositAddressStep({
|
|
1241
1432
|
smartAccount,
|
|
1433
|
+
solanaDepositAddress,
|
|
1242
1434
|
service,
|
|
1243
1435
|
onDepositDetected,
|
|
1244
1436
|
onError
|
|
1245
1437
|
}) {
|
|
1246
|
-
const
|
|
1438
|
+
const hasSolana = Boolean(solanaDepositAddress);
|
|
1439
|
+
const evmChainIds = useMemo4(() => getSupportedChainIds(), []);
|
|
1440
|
+
const chainOptions = useMemo4(
|
|
1441
|
+
() => hasSolana ? [...evmChainIds, "solana"] : evmChainIds,
|
|
1442
|
+
[evmChainIds, hasSolana]
|
|
1443
|
+
);
|
|
1247
1444
|
const BASE_CHAIN_ID = 8453;
|
|
1248
|
-
const defaultChainId =
|
|
1445
|
+
const defaultChainId = evmChainIds.includes(BASE_CHAIN_ID) ? BASE_CHAIN_ID : evmChainIds[0];
|
|
1249
1446
|
const [sourceChainId, setSourceChainId] = useState6(defaultChainId);
|
|
1447
|
+
const isSolana = sourceChainId === "solana";
|
|
1250
1448
|
const tokensForChain = useMemo4(
|
|
1251
|
-
() => getTargetTokenSymbolsForChain(sourceChainId),
|
|
1252
|
-
[sourceChainId]
|
|
1449
|
+
() => isSolana ? SOLANA_TOKENS.map((t) => t.symbol) : getTargetTokenSymbolsForChain(sourceChainId),
|
|
1450
|
+
[sourceChainId, isSolana]
|
|
1253
1451
|
);
|
|
1254
1452
|
const defaultToken = tokensForChain.includes("USDC") ? "USDC" : tokensForChain[0] ?? "USDC";
|
|
1255
1453
|
const [sourceTokenSymbol, setSourceTokenSymbol] = useState6(defaultToken);
|
|
1256
1454
|
useEffect6(() => {
|
|
1257
1455
|
if (!tokensForChain.includes(sourceTokenSymbol)) {
|
|
1258
|
-
|
|
1456
|
+
const fallback = tokensForChain.includes("USDC") ? "USDC" : tokensForChain[0] ?? "USDC";
|
|
1457
|
+
setSourceTokenSymbol(fallback);
|
|
1259
1458
|
}
|
|
1260
1459
|
}, [tokensForChain, sourceTokenSymbol]);
|
|
1261
1460
|
const [copied, setCopied] = useState6(false);
|
|
@@ -1267,14 +1466,27 @@ function DepositAddressStep({
|
|
|
1267
1466
|
const depositHandledRef = useRef4(false);
|
|
1268
1467
|
const sourceSelectionRef = useRef4({
|
|
1269
1468
|
chainId: defaultChainId,
|
|
1270
|
-
|
|
1469
|
+
token: typeof defaultChainId === "number" ? getTokenAddress(defaultToken, defaultChainId) : void 0,
|
|
1470
|
+
sourceSymbol: defaultToken
|
|
1271
1471
|
});
|
|
1272
1472
|
useEffect6(() => {
|
|
1473
|
+
if (isSolana) {
|
|
1474
|
+
const matched = SOLANA_TOKENS.find((t) => t.symbol === sourceTokenSymbol) ?? SOLANA_TOKENS[0];
|
|
1475
|
+
sourceSelectionRef.current = {
|
|
1476
|
+
chainId: "solana",
|
|
1477
|
+
token: matched?.mint,
|
|
1478
|
+
sourceSymbol: matched?.symbol,
|
|
1479
|
+
sourceDecimals: matched?.decimals
|
|
1480
|
+
};
|
|
1481
|
+
return;
|
|
1482
|
+
}
|
|
1273
1483
|
sourceSelectionRef.current = {
|
|
1274
1484
|
chainId: sourceChainId,
|
|
1275
|
-
|
|
1485
|
+
token: getTokenAddress(sourceTokenSymbol, sourceChainId),
|
|
1486
|
+
sourceSymbol: sourceTokenSymbol
|
|
1276
1487
|
};
|
|
1277
|
-
}, [sourceChainId, sourceTokenSymbol]);
|
|
1488
|
+
}, [sourceChainId, sourceTokenSymbol, isSolana]);
|
|
1489
|
+
const displayAddress = isSolana && solanaDepositAddress ? solanaDepositAddress : smartAccount;
|
|
1278
1490
|
useEffect6(() => {
|
|
1279
1491
|
if (!chainDropdownOpen && !tokenDropdownOpen) return;
|
|
1280
1492
|
function handlePointerDown(event) {
|
|
@@ -1295,12 +1507,12 @@ function DepositAddressStep({
|
|
|
1295
1507
|
}, [chainDropdownOpen, tokenDropdownOpen]);
|
|
1296
1508
|
const handleCopy = useCallback2(async () => {
|
|
1297
1509
|
try {
|
|
1298
|
-
await navigator.clipboard.writeText(
|
|
1510
|
+
await navigator.clipboard.writeText(displayAddress);
|
|
1299
1511
|
setCopied(true);
|
|
1300
1512
|
setTimeout(() => setCopied(false), 2e3);
|
|
1301
1513
|
} catch {
|
|
1302
1514
|
const textarea = document.createElement("textarea");
|
|
1303
|
-
textarea.value =
|
|
1515
|
+
textarea.value = displayAddress;
|
|
1304
1516
|
textarea.style.position = "fixed";
|
|
1305
1517
|
textarea.style.opacity = "0";
|
|
1306
1518
|
document.body.appendChild(textarea);
|
|
@@ -1310,7 +1522,12 @@ function DepositAddressStep({
|
|
|
1310
1522
|
setCopied(true);
|
|
1311
1523
|
setTimeout(() => setCopied(false), 2e3);
|
|
1312
1524
|
}
|
|
1313
|
-
}, [
|
|
1525
|
+
}, [displayAddress]);
|
|
1526
|
+
useEffect6(() => {
|
|
1527
|
+
setCopied(false);
|
|
1528
|
+
setChainDropdownOpen(false);
|
|
1529
|
+
setTokenDropdownOpen(false);
|
|
1530
|
+
}, [sourceChainId]);
|
|
1314
1531
|
useEffect6(() => {
|
|
1315
1532
|
depositHandledRef.current = false;
|
|
1316
1533
|
setPollingError(null);
|
|
@@ -1323,18 +1540,27 @@ function DepositAddressStep({
|
|
|
1323
1540
|
const status = await service.fetchLatestStatus(smartAccount);
|
|
1324
1541
|
if (cancelled || depositHandledRef.current) return;
|
|
1325
1542
|
const event = status.lastEvent;
|
|
1326
|
-
const eventTxHash = isDepositEvent(event) ? getEventTxHash(event)
|
|
1543
|
+
const eventTxHash = isDepositEvent(event) ? getEventTxHash(event) ?? null : null;
|
|
1327
1544
|
if (baselineTxHash === void 0) {
|
|
1328
1545
|
baselineTxHash = eventTxHash;
|
|
1329
|
-
} else if (eventTxHash && eventTxHash
|
|
1330
|
-
const details =
|
|
1546
|
+
} else if (eventTxHash && (!baselineTxHash || !txRefsMatch(eventTxHash, baselineTxHash))) {
|
|
1547
|
+
const details = getDepositEventDetails(event);
|
|
1331
1548
|
const fallback = sourceSelectionRef.current;
|
|
1332
1549
|
const chainId = details.chainId ?? fallback.chainId;
|
|
1333
1550
|
const amount = details.amount ?? "0";
|
|
1334
|
-
const token = details.token ??
|
|
1551
|
+
const token = details.token ?? fallback.token;
|
|
1552
|
+
const sourceSymbol = details.sourceSymbol ?? fallback.sourceSymbol;
|
|
1553
|
+
const sourceDecimals = details.sourceDecimals ?? fallback.sourceDecimals;
|
|
1335
1554
|
if (token) {
|
|
1336
1555
|
depositHandledRef.current = true;
|
|
1337
|
-
onDepositDetected(
|
|
1556
|
+
onDepositDetected(
|
|
1557
|
+
eventTxHash,
|
|
1558
|
+
chainId,
|
|
1559
|
+
amount,
|
|
1560
|
+
token,
|
|
1561
|
+
sourceSymbol,
|
|
1562
|
+
sourceDecimals
|
|
1563
|
+
);
|
|
1338
1564
|
return;
|
|
1339
1565
|
}
|
|
1340
1566
|
}
|
|
@@ -1356,31 +1582,31 @@ function DepositAddressStep({
|
|
|
1356
1582
|
clearTimeout(timeoutId);
|
|
1357
1583
|
};
|
|
1358
1584
|
}, [smartAccount, service, onDepositDetected, onError]);
|
|
1359
|
-
const
|
|
1585
|
+
const qrIconSrc = getChainIcon(sourceChainId);
|
|
1360
1586
|
return /* @__PURE__ */ jsxs6("div", { className: "rs-step", children: [
|
|
1361
1587
|
/* @__PURE__ */ jsx6("div", { className: "rs-step-body", children: /* @__PURE__ */ jsxs6("div", { className: "rs-deposit-address", children: [
|
|
1362
1588
|
/* @__PURE__ */ jsxs6("div", { className: "rs-deposit-address-selectors", children: [
|
|
1363
|
-
/* @__PURE__ */ jsxs6("div", { className: "rs-deposit-address-dropdown", ref:
|
|
1364
|
-
/* @__PURE__ */ jsx6("div", { className: "rs-deposit-address-dropdown-label", children: "
|
|
1589
|
+
/* @__PURE__ */ jsxs6("div", { className: "rs-deposit-address-dropdown", ref: chainDropdownRef, children: [
|
|
1590
|
+
/* @__PURE__ */ jsx6("div", { className: "rs-deposit-address-dropdown-label", children: "Chain" }),
|
|
1365
1591
|
/* @__PURE__ */ jsxs6(
|
|
1366
1592
|
"button",
|
|
1367
1593
|
{
|
|
1368
1594
|
type: "button",
|
|
1369
1595
|
className: "rs-deposit-address-dropdown-trigger",
|
|
1370
1596
|
onClick: () => {
|
|
1371
|
-
|
|
1372
|
-
|
|
1597
|
+
setChainDropdownOpen(!chainDropdownOpen);
|
|
1598
|
+
setTokenDropdownOpen(false);
|
|
1373
1599
|
},
|
|
1374
1600
|
children: [
|
|
1375
|
-
|
|
1601
|
+
getChainIcon(sourceChainId) && /* @__PURE__ */ jsx6(
|
|
1376
1602
|
"img",
|
|
1377
1603
|
{
|
|
1378
|
-
src:
|
|
1604
|
+
src: getChainIcon(sourceChainId),
|
|
1379
1605
|
alt: "",
|
|
1380
1606
|
className: "rs-deposit-address-dropdown-icon"
|
|
1381
1607
|
}
|
|
1382
1608
|
),
|
|
1383
|
-
/* @__PURE__ */ jsx6("span", { children:
|
|
1609
|
+
/* @__PURE__ */ jsx6("span", { children: getChainName(sourceChainId) }),
|
|
1384
1610
|
/* @__PURE__ */ jsx6(
|
|
1385
1611
|
"svg",
|
|
1386
1612
|
{
|
|
@@ -1402,51 +1628,51 @@ function DepositAddressStep({
|
|
|
1402
1628
|
]
|
|
1403
1629
|
}
|
|
1404
1630
|
),
|
|
1405
|
-
|
|
1631
|
+
chainDropdownOpen && /* @__PURE__ */ jsx6("div", { className: "rs-deposit-address-dropdown-menu", children: chainOptions.map((chainId) => /* @__PURE__ */ jsxs6(
|
|
1406
1632
|
"button",
|
|
1407
1633
|
{
|
|
1408
1634
|
type: "button",
|
|
1409
|
-
className: `rs-deposit-address-dropdown-item ${
|
|
1635
|
+
className: `rs-deposit-address-dropdown-item ${chainId === sourceChainId ? "rs-deposit-address-dropdown-item--active" : ""}`,
|
|
1410
1636
|
onClick: () => {
|
|
1411
|
-
|
|
1412
|
-
|
|
1637
|
+
setSourceChainId(chainId);
|
|
1638
|
+
setChainDropdownOpen(false);
|
|
1413
1639
|
},
|
|
1414
1640
|
children: [
|
|
1415
|
-
|
|
1641
|
+
getChainIcon(chainId) && /* @__PURE__ */ jsx6(
|
|
1416
1642
|
"img",
|
|
1417
1643
|
{
|
|
1418
|
-
src:
|
|
1644
|
+
src: getChainIcon(chainId),
|
|
1419
1645
|
alt: "",
|
|
1420
1646
|
className: "rs-deposit-address-dropdown-icon"
|
|
1421
1647
|
}
|
|
1422
1648
|
),
|
|
1423
|
-
/* @__PURE__ */ jsx6("span", { children:
|
|
1649
|
+
/* @__PURE__ */ jsx6("span", { children: getChainName(chainId) })
|
|
1424
1650
|
]
|
|
1425
1651
|
},
|
|
1426
|
-
|
|
1652
|
+
String(chainId)
|
|
1427
1653
|
)) })
|
|
1428
1654
|
] }),
|
|
1429
|
-
/* @__PURE__ */ jsxs6("div", { className: "rs-deposit-address-dropdown", ref:
|
|
1430
|
-
/* @__PURE__ */ jsx6("div", { className: "rs-deposit-address-dropdown-label", children: "
|
|
1655
|
+
/* @__PURE__ */ jsxs6("div", { className: "rs-deposit-address-dropdown", ref: tokenDropdownRef, children: [
|
|
1656
|
+
/* @__PURE__ */ jsx6("div", { className: "rs-deposit-address-dropdown-label", children: "Token" }),
|
|
1431
1657
|
/* @__PURE__ */ jsxs6(
|
|
1432
1658
|
"button",
|
|
1433
1659
|
{
|
|
1434
1660
|
type: "button",
|
|
1435
1661
|
className: "rs-deposit-address-dropdown-trigger",
|
|
1436
1662
|
onClick: () => {
|
|
1437
|
-
|
|
1438
|
-
|
|
1663
|
+
setTokenDropdownOpen(!tokenDropdownOpen);
|
|
1664
|
+
setChainDropdownOpen(false);
|
|
1439
1665
|
},
|
|
1440
1666
|
children: [
|
|
1441
|
-
|
|
1667
|
+
getTokenIcon(sourceTokenSymbol) && /* @__PURE__ */ jsx6(
|
|
1442
1668
|
"img",
|
|
1443
1669
|
{
|
|
1444
|
-
src:
|
|
1670
|
+
src: getTokenIcon(sourceTokenSymbol),
|
|
1445
1671
|
alt: "",
|
|
1446
1672
|
className: "rs-deposit-address-dropdown-icon"
|
|
1447
1673
|
}
|
|
1448
1674
|
),
|
|
1449
|
-
/* @__PURE__ */ jsx6("span", { children:
|
|
1675
|
+
/* @__PURE__ */ jsx6("span", { children: sourceTokenSymbol }),
|
|
1450
1676
|
/* @__PURE__ */ jsx6(
|
|
1451
1677
|
"svg",
|
|
1452
1678
|
{
|
|
@@ -1468,35 +1694,39 @@ function DepositAddressStep({
|
|
|
1468
1694
|
]
|
|
1469
1695
|
}
|
|
1470
1696
|
),
|
|
1471
|
-
|
|
1697
|
+
tokenDropdownOpen && /* @__PURE__ */ jsx6("div", { className: "rs-deposit-address-dropdown-menu", children: tokensForChain.map((symbol) => /* @__PURE__ */ jsxs6(
|
|
1472
1698
|
"button",
|
|
1473
1699
|
{
|
|
1474
1700
|
type: "button",
|
|
1475
|
-
className: `rs-deposit-address-dropdown-item ${
|
|
1701
|
+
className: `rs-deposit-address-dropdown-item ${symbol === sourceTokenSymbol ? "rs-deposit-address-dropdown-item--active" : ""}`,
|
|
1476
1702
|
onClick: () => {
|
|
1477
|
-
|
|
1478
|
-
|
|
1703
|
+
setSourceTokenSymbol(symbol);
|
|
1704
|
+
setTokenDropdownOpen(false);
|
|
1479
1705
|
},
|
|
1480
1706
|
children: [
|
|
1481
|
-
|
|
1707
|
+
getTokenIcon(symbol) && /* @__PURE__ */ jsx6(
|
|
1482
1708
|
"img",
|
|
1483
1709
|
{
|
|
1484
|
-
src:
|
|
1710
|
+
src: getTokenIcon(symbol),
|
|
1485
1711
|
alt: "",
|
|
1486
1712
|
className: "rs-deposit-address-dropdown-icon"
|
|
1487
1713
|
}
|
|
1488
1714
|
),
|
|
1489
|
-
/* @__PURE__ */ jsx6("span", { children:
|
|
1715
|
+
/* @__PURE__ */ jsx6("span", { children: symbol })
|
|
1490
1716
|
]
|
|
1491
1717
|
},
|
|
1492
|
-
|
|
1718
|
+
symbol
|
|
1493
1719
|
)) })
|
|
1494
1720
|
] })
|
|
1495
1721
|
] }),
|
|
1496
|
-
/* @__PURE__ */ jsx6("div", { className: "rs-deposit-address-qr", children: /* @__PURE__ */ jsx6(QRCode, { value:
|
|
1722
|
+
/* @__PURE__ */ jsx6("div", { className: "rs-deposit-address-qr", children: /* @__PURE__ */ jsx6(QRCode, { value: displayAddress, size: 200, iconSrc: qrIconSrc }) }),
|
|
1497
1723
|
/* @__PURE__ */ jsxs6("div", { className: "rs-deposit-address-info", children: [
|
|
1498
|
-
/* @__PURE__ */
|
|
1499
|
-
|
|
1724
|
+
/* @__PURE__ */ jsxs6("div", { className: "rs-deposit-address-label", children: [
|
|
1725
|
+
"Your ",
|
|
1726
|
+
isSolana ? "Solana" : "EVM",
|
|
1727
|
+
" deposit address"
|
|
1728
|
+
] }),
|
|
1729
|
+
/* @__PURE__ */ jsx6("div", { className: "rs-deposit-address-value", children: displayAddress }),
|
|
1500
1730
|
/* @__PURE__ */ jsxs6(
|
|
1501
1731
|
"button",
|
|
1502
1732
|
{
|
|
@@ -1541,170 +1771,890 @@ function DepositAddressStep({
|
|
|
1541
1771
|
}
|
|
1542
1772
|
DepositAddressStep.displayName = "DepositAddressStep";
|
|
1543
1773
|
|
|
1544
|
-
// src/
|
|
1774
|
+
// src/components/steps/SolanaTokenSelectStep.tsx
|
|
1775
|
+
import { useState as useState7, useEffect as useEffect7, useMemo as useMemo5 } from "react";
|
|
1776
|
+
import { formatUnits as formatUnits3 } from "viem";
|
|
1545
1777
|
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1546
|
-
function
|
|
1547
|
-
|
|
1548
|
-
}
|
|
1549
|
-
function getAddressKey(address) {
|
|
1550
|
-
return address ? address.toLowerCase() : null;
|
|
1551
|
-
}
|
|
1552
|
-
function DepositFlow({
|
|
1553
|
-
dappWalletClient,
|
|
1554
|
-
dappPublicClient,
|
|
1555
|
-
dappAddress,
|
|
1556
|
-
targetChain,
|
|
1557
|
-
targetToken,
|
|
1778
|
+
function SolanaTokenSelectStep({
|
|
1779
|
+
solanaAddress,
|
|
1558
1780
|
service,
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
amount: defaultAmount,
|
|
1562
|
-
recipient,
|
|
1563
|
-
signerAddress = DEFAULT_SIGNER_ADDRESS,
|
|
1564
|
-
sessionChainIds,
|
|
1565
|
-
forceRegister = false,
|
|
1566
|
-
waitForFinalTx = true,
|
|
1567
|
-
reownWallet,
|
|
1568
|
-
onConnect,
|
|
1569
|
-
onDisconnect,
|
|
1570
|
-
onRequestConnect,
|
|
1571
|
-
connectButtonLabel,
|
|
1572
|
-
uiConfig,
|
|
1573
|
-
onStepChange,
|
|
1574
|
-
onTotalBalanceChange,
|
|
1575
|
-
onClose,
|
|
1576
|
-
onConnected,
|
|
1577
|
-
onDepositSubmitted,
|
|
1578
|
-
onDepositComplete,
|
|
1579
|
-
onDepositFailed,
|
|
1580
|
-
onError,
|
|
1781
|
+
onContinue,
|
|
1782
|
+
onTotalBalanceComputed,
|
|
1581
1783
|
debug
|
|
1582
1784
|
}) {
|
|
1583
|
-
const [
|
|
1584
|
-
const [
|
|
1585
|
-
const [
|
|
1586
|
-
const [
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1785
|
+
const [tokenBalances, setTokenBalances] = useState7([]);
|
|
1786
|
+
const [selectedSymbol, setSelectedSymbol] = useState7(null);
|
|
1787
|
+
const [loading, setLoading] = useState7(true);
|
|
1788
|
+
const [error, setError] = useState7(null);
|
|
1789
|
+
useEffect7(() => {
|
|
1790
|
+
let active = true;
|
|
1791
|
+
async function loadBalances() {
|
|
1792
|
+
if (!solanaAddress) {
|
|
1793
|
+
setLoading(false);
|
|
1794
|
+
return;
|
|
1795
|
+
}
|
|
1796
|
+
setLoading(true);
|
|
1797
|
+
setError(null);
|
|
1798
|
+
const portfolioBySymbol = {};
|
|
1799
|
+
try {
|
|
1800
|
+
debugLog(debug, "solana-token-select", "portfolio:request", {
|
|
1801
|
+
solanaAddress
|
|
1802
|
+
});
|
|
1803
|
+
const portfolio = await service.fetchSolanaPortfolio(solanaAddress);
|
|
1804
|
+
if (!active) return;
|
|
1805
|
+
for (const t of portfolio.tokens) {
|
|
1806
|
+
const symbol = t.symbol.toUpperCase();
|
|
1807
|
+
if (!SOLANA_TOKENS.some((st) => st.symbol === symbol)) continue;
|
|
1808
|
+
let parsed = 0n;
|
|
1809
|
+
try {
|
|
1810
|
+
parsed = BigInt(t.balance || "0");
|
|
1811
|
+
} catch {
|
|
1812
|
+
parsed = 0n;
|
|
1813
|
+
}
|
|
1814
|
+
if (parsed <= 0n) continue;
|
|
1815
|
+
const existing = portfolioBySymbol[symbol];
|
|
1816
|
+
if (!existing || (t.balanceUsd ?? 0) > existing.balanceUsd) {
|
|
1817
|
+
portfolioBySymbol[symbol] = {
|
|
1818
|
+
balance: parsed,
|
|
1819
|
+
balanceUsd: t.balanceUsd ?? 0
|
|
1820
|
+
};
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
debugLog(debug, "solana-token-select", "portfolio:success", {
|
|
1824
|
+
symbols: Object.keys(portfolioBySymbol)
|
|
1825
|
+
});
|
|
1826
|
+
} catch (err) {
|
|
1827
|
+
if (!active) return;
|
|
1828
|
+
debugError(debug, "solana-token-select", "portfolio:failure", err, {
|
|
1829
|
+
solanaAddress
|
|
1830
|
+
});
|
|
1831
|
+
setError(
|
|
1832
|
+
err instanceof Error ? err.message : "Failed to load balances"
|
|
1833
|
+
);
|
|
1834
|
+
setTokenBalances([]);
|
|
1835
|
+
setLoading(false);
|
|
1836
|
+
return;
|
|
1837
|
+
}
|
|
1838
|
+
const results = [];
|
|
1839
|
+
for (const token of SOLANA_TOKENS) {
|
|
1840
|
+
const fromPortfolio = portfolioBySymbol[token.symbol];
|
|
1841
|
+
if (fromPortfolio && fromPortfolio.balance > 0n) {
|
|
1842
|
+
results.push({
|
|
1843
|
+
token,
|
|
1844
|
+
balance: fromPortfolio.balance,
|
|
1845
|
+
balanceUsd: fromPortfolio.balanceUsd
|
|
1846
|
+
});
|
|
1603
1847
|
}
|
|
1604
1848
|
}
|
|
1849
|
+
if (!active) return;
|
|
1850
|
+
setTokenBalances(results);
|
|
1851
|
+
setLoading(false);
|
|
1852
|
+
const totalUsd = results.reduce((sum, r) => sum + r.balanceUsd, 0);
|
|
1853
|
+
onTotalBalanceComputed?.(totalUsd);
|
|
1605
1854
|
}
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
if (!dappWalletClient?.switchChain) return void 0;
|
|
1610
|
-
return async (chainId) => {
|
|
1611
|
-
await dappWalletClient.switchChain?.({ id: chainId });
|
|
1855
|
+
void loadBalances();
|
|
1856
|
+
return () => {
|
|
1857
|
+
active = false;
|
|
1612
1858
|
};
|
|
1613
|
-
}, [
|
|
1614
|
-
const
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
kind: "connected"
|
|
1623
|
-
});
|
|
1624
|
-
seen.add(connectedWalletAddress.toLowerCase());
|
|
1625
|
-
}
|
|
1626
|
-
if (reownWallet?.address && reownWallet.isConnected && reownWallet.walletClient && reownWallet.publicClient && !seen.has(reownWallet.address.toLowerCase())) {
|
|
1627
|
-
options.push({
|
|
1628
|
-
address: reownWallet.address,
|
|
1629
|
-
label: "External Wallet",
|
|
1630
|
-
kind: "external",
|
|
1631
|
-
icon: reownWallet.icon
|
|
1632
|
-
});
|
|
1633
|
-
}
|
|
1634
|
-
return options;
|
|
1635
|
-
}, [
|
|
1636
|
-
connectedWalletAddress,
|
|
1637
|
-
dappAddress,
|
|
1638
|
-
reownWallet?.address,
|
|
1639
|
-
reownWallet?.isConnected,
|
|
1640
|
-
reownWallet?.walletClient,
|
|
1641
|
-
reownWallet?.publicClient,
|
|
1642
|
-
reownWallet?.icon
|
|
1643
|
-
]);
|
|
1644
|
-
const canAutoLock = dappWalletClient?.account && dappAddress && !reownWallet;
|
|
1645
|
-
const hasWalletOptions = walletOptions.length > 0;
|
|
1646
|
-
const hasReownSession = Boolean(
|
|
1647
|
-
reownWallet?.isConnected || reownWallet?.address
|
|
1859
|
+
}, [debug, solanaAddress, service, onTotalBalanceComputed]);
|
|
1860
|
+
const rows = useMemo5(
|
|
1861
|
+
() => [...tokenBalances].sort((a, b) => {
|
|
1862
|
+
if (a.balanceUsd !== b.balanceUsd) return b.balanceUsd - a.balanceUsd;
|
|
1863
|
+
if (b.balance > a.balance) return 1;
|
|
1864
|
+
if (b.balance < a.balance) return -1;
|
|
1865
|
+
return 0;
|
|
1866
|
+
}),
|
|
1867
|
+
[tokenBalances]
|
|
1648
1868
|
);
|
|
1649
|
-
const
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
}
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1869
|
+
const selectedEntry = selectedSymbol ? rows.find((r) => r.token.symbol === selectedSymbol) : null;
|
|
1870
|
+
if (error) {
|
|
1871
|
+
return /* @__PURE__ */ jsx7("div", { className: "rs-step", children: /* @__PURE__ */ jsx7("div", { className: "rs-step-body", children: /* @__PURE__ */ jsx7("div", { className: "rs-alert rs-alert--error", children: /* @__PURE__ */ jsx7("span", { className: "rs-alert-text", children: error }) }) }) });
|
|
1872
|
+
}
|
|
1873
|
+
return /* @__PURE__ */ jsxs7("div", { className: "rs-step", children: [
|
|
1874
|
+
/* @__PURE__ */ jsx7("div", { style: { padding: "12px 12px 4px" }, children: /* @__PURE__ */ jsx7("div", { className: "rs-step-title", children: "Select source asset" }) }),
|
|
1875
|
+
/* @__PURE__ */ jsxs7(
|
|
1876
|
+
"div",
|
|
1877
|
+
{
|
|
1878
|
+
className: "rs-step-body",
|
|
1879
|
+
style: { paddingTop: 4, overflow: "auto", maxHeight: 340 },
|
|
1880
|
+
children: [
|
|
1881
|
+
loading && /* @__PURE__ */ jsxs7("div", { className: "rs-loading-state", style: { padding: "40px 12px" }, children: [
|
|
1882
|
+
/* @__PURE__ */ jsx7(Spinner, { className: "rs-text-tertiary" }),
|
|
1883
|
+
/* @__PURE__ */ jsx7("span", { className: "rs-text-sm rs-text-tertiary", children: "Loading balances" })
|
|
1884
|
+
] }),
|
|
1885
|
+
!loading && rows.length === 0 && /* @__PURE__ */ jsxs7("div", { className: "rs-empty-state", children: [
|
|
1886
|
+
/* @__PURE__ */ jsx7(
|
|
1887
|
+
"svg",
|
|
1888
|
+
{
|
|
1889
|
+
className: "rs-empty-icon",
|
|
1890
|
+
viewBox: "0 0 24 24",
|
|
1891
|
+
fill: "none",
|
|
1892
|
+
stroke: "currentColor",
|
|
1893
|
+
strokeWidth: "1.5",
|
|
1894
|
+
children: /* @__PURE__ */ jsx7(
|
|
1895
|
+
"path",
|
|
1896
|
+
{
|
|
1897
|
+
strokeLinecap: "round",
|
|
1898
|
+
strokeLinejoin: "round",
|
|
1899
|
+
d: "M21 12a2.25 2.25 0 00-2.25-2.25H15a3 3 0 11-6 0H5.25A2.25 2.25 0 003 12m18 0v6a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 18v-6m18 0V9M3 12V9m18 0a2.25 2.25 0 00-2.25-2.25H5.25A2.25 2.25 0 003 9m18 0V6a2.25 2.25 0 00-2.25-2.25H5.25A2.25 2.25 0 003 6v3"
|
|
1900
|
+
}
|
|
1901
|
+
)
|
|
1902
|
+
}
|
|
1903
|
+
),
|
|
1904
|
+
/* @__PURE__ */ jsx7("div", { className: "rs-empty-text", children: "No funds in connected wallet" }),
|
|
1905
|
+
/* @__PURE__ */ jsxs7("div", { className: "rs-empty-address", children: [
|
|
1906
|
+
solanaAddress.slice(0, 6),
|
|
1907
|
+
"...",
|
|
1908
|
+
solanaAddress.slice(-4)
|
|
1909
|
+
] })
|
|
1910
|
+
] }),
|
|
1911
|
+
!loading && rows.length > 0 && /* @__PURE__ */ jsx7("div", { className: "rs-asset-list", children: rows.map((entry) => {
|
|
1912
|
+
const isSelected = selectedSymbol === entry.token.symbol;
|
|
1913
|
+
const tokenIcon = getTokenIcon(entry.token.symbol);
|
|
1914
|
+
const chainIcon = getChainIcon("solana");
|
|
1915
|
+
let formattedBalance;
|
|
1916
|
+
try {
|
|
1917
|
+
const raw = formatUnits3(entry.balance, entry.token.decimals);
|
|
1918
|
+
const numeric = Number(raw);
|
|
1919
|
+
formattedBalance = Number.isFinite(numeric) ? tokenFormatter.format(numeric) : raw;
|
|
1920
|
+
} catch {
|
|
1921
|
+
formattedBalance = "...";
|
|
1922
|
+
}
|
|
1923
|
+
return /* @__PURE__ */ jsxs7(
|
|
1924
|
+
"button",
|
|
1925
|
+
{
|
|
1926
|
+
type: "button",
|
|
1927
|
+
onClick: () => setSelectedSymbol(entry.token.symbol),
|
|
1928
|
+
className: `rs-asset-row ${isSelected ? "rs-asset-row--selected" : ""}`,
|
|
1929
|
+
style: { textAlign: "left" },
|
|
1930
|
+
children: [
|
|
1931
|
+
/* @__PURE__ */ jsxs7("div", { className: "rs-asset-info", children: [
|
|
1932
|
+
/* @__PURE__ */ jsxs7("div", { className: "rs-asset-icon-wrapper", children: [
|
|
1933
|
+
tokenIcon ? /* @__PURE__ */ jsx7(
|
|
1934
|
+
"img",
|
|
1935
|
+
{
|
|
1936
|
+
src: tokenIcon,
|
|
1937
|
+
alt: entry.token.symbol,
|
|
1938
|
+
className: "rs-asset-icon",
|
|
1939
|
+
style: { background: "transparent" }
|
|
1940
|
+
}
|
|
1941
|
+
) : /* @__PURE__ */ jsx7("div", { className: "rs-asset-icon", children: entry.token.symbol.slice(0, 4) }),
|
|
1942
|
+
chainIcon && /* @__PURE__ */ jsx7(
|
|
1943
|
+
"img",
|
|
1944
|
+
{
|
|
1945
|
+
src: chainIcon,
|
|
1946
|
+
alt: "Solana",
|
|
1947
|
+
className: "rs-asset-chain-badge"
|
|
1948
|
+
}
|
|
1949
|
+
)
|
|
1950
|
+
] }),
|
|
1951
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1952
|
+
/* @__PURE__ */ jsxs7("div", { className: "rs-asset-name", children: [
|
|
1953
|
+
entry.token.symbol,
|
|
1954
|
+
/* @__PURE__ */ jsx7("span", { className: "rs-asset-chain", children: " on Solana" })
|
|
1955
|
+
] }),
|
|
1956
|
+
/* @__PURE__ */ jsxs7("div", { className: "rs-asset-balance-small", children: [
|
|
1957
|
+
formattedBalance,
|
|
1958
|
+
" ",
|
|
1959
|
+
entry.token.symbol
|
|
1960
|
+
] })
|
|
1961
|
+
] })
|
|
1962
|
+
] }),
|
|
1963
|
+
/* @__PURE__ */ jsx7("div", { className: "rs-asset-balance", children: entry.balanceUsd > 0 ? currencyFormatter.format(entry.balanceUsd) : `${formattedBalance} ${entry.token.symbol}` })
|
|
1964
|
+
]
|
|
1965
|
+
},
|
|
1966
|
+
entry.token.symbol
|
|
1967
|
+
);
|
|
1968
|
+
}) })
|
|
1969
|
+
]
|
|
1970
|
+
}
|
|
1971
|
+
),
|
|
1972
|
+
/* @__PURE__ */ jsx7("div", { className: "rs-step-footer", children: /* @__PURE__ */ jsx7(
|
|
1973
|
+
Button,
|
|
1974
|
+
{
|
|
1975
|
+
onClick: () => selectedEntry && onContinue(
|
|
1976
|
+
selectedEntry.token,
|
|
1977
|
+
selectedEntry.balance,
|
|
1978
|
+
selectedEntry.balanceUsd
|
|
1979
|
+
),
|
|
1980
|
+
disabled: !selectedEntry,
|
|
1981
|
+
fullWidth: true,
|
|
1982
|
+
children: "Continue"
|
|
1983
|
+
}
|
|
1984
|
+
) }),
|
|
1985
|
+
/* @__PURE__ */ jsx7(PoweredBy, {})
|
|
1986
|
+
] });
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
// src/components/steps/SolanaAmountStep.tsx
|
|
1990
|
+
import { useState as useState8, useMemo as useMemo6 } from "react";
|
|
1991
|
+
import { formatUnits as formatUnits4, parseUnits as parseUnits3 } from "viem";
|
|
1992
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1993
|
+
var SOL_FEE_RESERVE_LAMPORTS = 1000000n;
|
|
1994
|
+
function SolanaAmountStep({
|
|
1995
|
+
token,
|
|
1996
|
+
balance,
|
|
1997
|
+
balanceUsd,
|
|
1998
|
+
onContinue,
|
|
1999
|
+
debug
|
|
2000
|
+
}) {
|
|
2001
|
+
const [amount, setAmount] = useState8("");
|
|
2002
|
+
const [error, setError] = useState8(null);
|
|
2003
|
+
const formattedBalance = useMemo6(() => {
|
|
2004
|
+
try {
|
|
2005
|
+
const raw = formatUnits4(balance, token.decimals);
|
|
2006
|
+
const numeric = Number(raw);
|
|
2007
|
+
if (!Number.isFinite(numeric)) return raw;
|
|
2008
|
+
return tokenFormatter.format(numeric);
|
|
2009
|
+
} catch {
|
|
2010
|
+
return "...";
|
|
2011
|
+
}
|
|
2012
|
+
}, [balance, token.decimals]);
|
|
2013
|
+
const formattedBalanceUsd = useMemo6(() => {
|
|
2014
|
+
if (!Number.isFinite(balanceUsd) || balanceUsd <= 0) return null;
|
|
2015
|
+
return currencyFormatter.format(balanceUsd);
|
|
2016
|
+
}, [balanceUsd]);
|
|
2017
|
+
const spendableBalance = useMemo6(() => {
|
|
2018
|
+
if (!isNativeSol(token)) return balance;
|
|
2019
|
+
return balance > SOL_FEE_RESERVE_LAMPORTS ? balance - SOL_FEE_RESERVE_LAMPORTS : 0n;
|
|
2020
|
+
}, [balance, token]);
|
|
2021
|
+
const handlePresetClick = (percentage) => {
|
|
2022
|
+
try {
|
|
2023
|
+
const spendableUnits = Number(formatUnits4(spendableBalance, token.decimals));
|
|
2024
|
+
if (!Number.isFinite(spendableUnits) || spendableUnits <= 0) return;
|
|
2025
|
+
const value = spendableUnits * percentage / 100;
|
|
2026
|
+
const maxDecimals = token.decimals > 6 ? 6 : token.decimals;
|
|
2027
|
+
const factor = 10 ** maxDecimals;
|
|
2028
|
+
const truncated = Math.floor(value * factor) / factor;
|
|
2029
|
+
const formatted = truncated.toFixed(maxDecimals).replace(/\.?0+$/, "");
|
|
2030
|
+
debugLog(debug, "solana-amount", "amount:preset", {
|
|
2031
|
+
percentage,
|
|
2032
|
+
symbol: token.symbol,
|
|
2033
|
+
formatted
|
|
2034
|
+
});
|
|
2035
|
+
setAmount(formatted);
|
|
2036
|
+
} catch {
|
|
2037
|
+
return;
|
|
2038
|
+
}
|
|
2039
|
+
if (error) setError(null);
|
|
2040
|
+
};
|
|
2041
|
+
const handleContinue = () => {
|
|
2042
|
+
const numericAmount = parseFloat(amount);
|
|
2043
|
+
if (isNaN(numericAmount) || numericAmount <= 0) {
|
|
2044
|
+
debugLog(debug, "solana-amount", "amount:invalid", {
|
|
2045
|
+
amount,
|
|
2046
|
+
reason: "nan-or-non-positive"
|
|
2047
|
+
});
|
|
2048
|
+
setError("Please enter a valid amount");
|
|
2049
|
+
return;
|
|
2050
|
+
}
|
|
2051
|
+
let amountInUnits;
|
|
2052
|
+
try {
|
|
2053
|
+
amountInUnits = parseUnits3(amount, token.decimals);
|
|
2054
|
+
} catch {
|
|
2055
|
+
debugLog(debug, "solana-amount", "amount:invalid", {
|
|
2056
|
+
amount,
|
|
2057
|
+
reason: "parse-units-failed"
|
|
2058
|
+
});
|
|
2059
|
+
setError("Please enter a valid amount");
|
|
2060
|
+
return;
|
|
2061
|
+
}
|
|
2062
|
+
if (amountInUnits > spendableBalance) {
|
|
2063
|
+
const isReserveIssue = isNativeSol(token) && amountInUnits <= balance;
|
|
2064
|
+
debugLog(debug, "solana-amount", "amount:invalid", {
|
|
2065
|
+
amount,
|
|
2066
|
+
balance: balance.toString(),
|
|
2067
|
+
spendableBalance: spendableBalance.toString(),
|
|
2068
|
+
amountInUnits: amountInUnits.toString(),
|
|
2069
|
+
reason: isReserveIssue ? "native-buffer" : "insufficient-balance"
|
|
2070
|
+
});
|
|
2071
|
+
setError(
|
|
2072
|
+
isReserveIssue ? "Use a bit less than your full SOL balance" : "Insufficient balance"
|
|
2073
|
+
);
|
|
2074
|
+
return;
|
|
2075
|
+
}
|
|
2076
|
+
debugLog(debug, "solana-amount", "amount:continue", {
|
|
2077
|
+
symbol: token.symbol,
|
|
2078
|
+
amount,
|
|
2079
|
+
amountInUnits: amountInUnits.toString()
|
|
2080
|
+
});
|
|
2081
|
+
setError(null);
|
|
2082
|
+
onContinue(token, amount);
|
|
2083
|
+
};
|
|
2084
|
+
return /* @__PURE__ */ jsxs8("div", { className: "rs-step", children: [
|
|
2085
|
+
/* @__PURE__ */ jsx8("div", { style: { padding: "12px 12px 4px" }, children: /* @__PURE__ */ jsx8("div", { className: "rs-step-title", children: "Enter amount" }) }),
|
|
2086
|
+
/* @__PURE__ */ jsxs8("div", { className: "rs-step-body", style: { paddingTop: 0 }, children: [
|
|
2087
|
+
/* @__PURE__ */ jsxs8("div", { className: "rs-amount-display", children: [
|
|
2088
|
+
/* @__PURE__ */ jsxs8("div", { className: "rs-amount-input-wrapper", children: [
|
|
2089
|
+
/* @__PURE__ */ jsx8(
|
|
2090
|
+
"input",
|
|
2091
|
+
{
|
|
2092
|
+
type: "text",
|
|
2093
|
+
inputMode: "decimal",
|
|
2094
|
+
className: "rs-amount-input-large",
|
|
2095
|
+
placeholder: "0.00",
|
|
2096
|
+
value: amount,
|
|
2097
|
+
onChange: (e) => {
|
|
2098
|
+
const raw = e.target.value.replace(/[^0-9.]/g, "");
|
|
2099
|
+
const parts = raw.split(".");
|
|
2100
|
+
if (parts.length > 2) return;
|
|
2101
|
+
setAmount(raw);
|
|
2102
|
+
if (error) setError(null);
|
|
2103
|
+
},
|
|
2104
|
+
autoFocus: true
|
|
2105
|
+
}
|
|
2106
|
+
),
|
|
2107
|
+
/* @__PURE__ */ jsx8("div", { className: "rs-amount-token-value", children: token.symbol })
|
|
2108
|
+
] }),
|
|
2109
|
+
/* @__PURE__ */ jsxs8("div", { className: "rs-amount-available", children: [
|
|
2110
|
+
/* @__PURE__ */ jsxs8("span", { className: "rs-amount-available-value", children: [
|
|
2111
|
+
formattedBalance,
|
|
2112
|
+
" ",
|
|
2113
|
+
token.symbol,
|
|
2114
|
+
" available"
|
|
2115
|
+
] }),
|
|
2116
|
+
formattedBalanceUsd && /* @__PURE__ */ jsx8("span", { className: "rs-amount-available-value", children: formattedBalanceUsd })
|
|
2117
|
+
] })
|
|
2118
|
+
] }),
|
|
2119
|
+
/* @__PURE__ */ jsxs8("div", { className: "rs-amount-presets", children: [
|
|
2120
|
+
[25, 50, 75].map((pct) => /* @__PURE__ */ jsxs8(
|
|
2121
|
+
"button",
|
|
2122
|
+
{
|
|
2123
|
+
type: "button",
|
|
2124
|
+
className: "rs-amount-preset-btn",
|
|
2125
|
+
onClick: () => handlePresetClick(pct),
|
|
2126
|
+
children: [
|
|
2127
|
+
pct,
|
|
2128
|
+
"%"
|
|
2129
|
+
]
|
|
2130
|
+
},
|
|
2131
|
+
pct
|
|
2132
|
+
)),
|
|
2133
|
+
/* @__PURE__ */ jsx8(
|
|
2134
|
+
"button",
|
|
2135
|
+
{
|
|
2136
|
+
type: "button",
|
|
2137
|
+
className: "rs-amount-preset-btn",
|
|
2138
|
+
onClick: () => handlePresetClick(100),
|
|
2139
|
+
children: "Max"
|
|
2140
|
+
}
|
|
2141
|
+
)
|
|
2142
|
+
] }),
|
|
2143
|
+
error && /* @__PURE__ */ jsxs8("div", { className: "rs-amount-error", children: [
|
|
2144
|
+
/* @__PURE__ */ jsx8(
|
|
2145
|
+
"svg",
|
|
2146
|
+
{
|
|
2147
|
+
viewBox: "0 0 24 24",
|
|
2148
|
+
fill: "none",
|
|
2149
|
+
stroke: "currentColor",
|
|
2150
|
+
strokeWidth: "2",
|
|
2151
|
+
style: { width: 16, height: 16, flexShrink: 0 },
|
|
2152
|
+
children: /* @__PURE__ */ jsx8(
|
|
2153
|
+
"path",
|
|
2154
|
+
{
|
|
2155
|
+
strokeLinecap: "round",
|
|
2156
|
+
strokeLinejoin: "round",
|
|
2157
|
+
d: "M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z"
|
|
2158
|
+
}
|
|
2159
|
+
)
|
|
2160
|
+
}
|
|
2161
|
+
),
|
|
2162
|
+
/* @__PURE__ */ jsx8("span", { children: error })
|
|
2163
|
+
] })
|
|
2164
|
+
] }),
|
|
2165
|
+
/* @__PURE__ */ jsx8("div", { className: "rs-step-footer", children: /* @__PURE__ */ jsx8(
|
|
2166
|
+
Button,
|
|
2167
|
+
{
|
|
2168
|
+
onClick: handleContinue,
|
|
2169
|
+
fullWidth: true,
|
|
2170
|
+
disabled: !amount,
|
|
2171
|
+
children: "Continue"
|
|
2172
|
+
}
|
|
2173
|
+
) }),
|
|
2174
|
+
/* @__PURE__ */ jsx8(PoweredBy, {})
|
|
2175
|
+
] });
|
|
2176
|
+
}
|
|
2177
|
+
|
|
2178
|
+
// src/components/steps/SolanaConfirmStep.tsx
|
|
2179
|
+
import { useState as useState9 } from "react";
|
|
2180
|
+
import { parseUnits as parseUnits4 } from "viem";
|
|
2181
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2182
|
+
function SolanaConfirmStep({
|
|
2183
|
+
smartAccount,
|
|
2184
|
+
solanaAddress,
|
|
2185
|
+
solanaDepositAddress,
|
|
2186
|
+
token,
|
|
2187
|
+
amount,
|
|
2188
|
+
targetAmount,
|
|
2189
|
+
targetTokenPriceUsd,
|
|
2190
|
+
targetChain,
|
|
2191
|
+
targetToken,
|
|
2192
|
+
service,
|
|
2193
|
+
solanaProvider,
|
|
2194
|
+
onConfirm,
|
|
2195
|
+
onError,
|
|
2196
|
+
debug
|
|
2197
|
+
}) {
|
|
2198
|
+
const [isSubmitting, setIsSubmitting] = useState9(false);
|
|
2199
|
+
const [error, setError] = useState9(null);
|
|
2200
|
+
const targetSymbol = getTokenSymbol(targetToken, targetChain);
|
|
2201
|
+
const isSameToken = token.symbol.toUpperCase() === targetSymbol.toUpperCase();
|
|
2202
|
+
const formattedAmount = amount && !Number.isNaN(Number(amount)) ? Number(amount).toLocaleString("en-US", { maximumFractionDigits: 6 }) : "0";
|
|
2203
|
+
const formattedReceiveAmount = (() => {
|
|
2204
|
+
if (isSameToken) return formattedAmount;
|
|
2205
|
+
const dollarValue = Number(targetAmount);
|
|
2206
|
+
if (!Number.isFinite(dollarValue) || dollarValue <= 0)
|
|
2207
|
+
return formattedAmount;
|
|
2208
|
+
if (targetTokenPriceUsd !== null && targetTokenPriceUsd > 0) {
|
|
2209
|
+
const tokenAmount = dollarValue / targetTokenPriceUsd;
|
|
2210
|
+
return tokenAmount.toLocaleString("en-US", { maximumFractionDigits: 6 });
|
|
2211
|
+
}
|
|
2212
|
+
return formattedAmount;
|
|
2213
|
+
})();
|
|
2214
|
+
const receiveAmount = isSameToken ? formattedReceiveAmount : `~ ${formattedReceiveAmount}`;
|
|
2215
|
+
const handleConfirm = async () => {
|
|
2216
|
+
if (!solanaProvider) {
|
|
2217
|
+
debugLog(debug, "solana-confirm", "submit:blocked", {
|
|
2218
|
+
reason: "missing-provider"
|
|
2219
|
+
});
|
|
2220
|
+
setError("Solana wallet not connected");
|
|
2221
|
+
return;
|
|
2222
|
+
}
|
|
2223
|
+
const parsedAmount = parseFloat(amount);
|
|
2224
|
+
if (isNaN(parsedAmount) || parsedAmount <= 0) {
|
|
2225
|
+
debugLog(debug, "solana-confirm", "submit:blocked", {
|
|
2226
|
+
reason: "invalid-amount",
|
|
2227
|
+
amount
|
|
2228
|
+
});
|
|
2229
|
+
setError("Please enter a valid amount");
|
|
2230
|
+
return;
|
|
2231
|
+
}
|
|
2232
|
+
setError(null);
|
|
2233
|
+
setIsSubmitting(true);
|
|
2234
|
+
debugLog(debug, "solana-confirm", "submit:start", {
|
|
2235
|
+
smartAccount,
|
|
2236
|
+
solanaAddress,
|
|
2237
|
+
solanaDepositAddress,
|
|
2238
|
+
token: token.symbol,
|
|
2239
|
+
amount
|
|
2240
|
+
});
|
|
2241
|
+
try {
|
|
2242
|
+
const check = await service.checkAccount(smartAccount);
|
|
2243
|
+
debugLog(debug, "solana-confirm", "check:success", {
|
|
2244
|
+
smartAccount,
|
|
2245
|
+
isRegistered: check.isRegistered,
|
|
2246
|
+
targetChain: check.targetChain,
|
|
2247
|
+
targetToken: check.targetToken
|
|
2248
|
+
});
|
|
2249
|
+
if (!check.isRegistered) {
|
|
2250
|
+
throw new Error(
|
|
2251
|
+
"Deposit account is not registered yet. Please restart setup and try again."
|
|
2252
|
+
);
|
|
2253
|
+
}
|
|
2254
|
+
const connection = getSolanaConnection();
|
|
2255
|
+
const amountUnits = parseUnits4(amount, token.decimals);
|
|
2256
|
+
debugLog(debug, "solana-confirm", "tx:build:start", {
|
|
2257
|
+
token: token.symbol,
|
|
2258
|
+
amount,
|
|
2259
|
+
amountUnits: amountUnits.toString()
|
|
2260
|
+
});
|
|
2261
|
+
const transaction = isNativeSol(token) ? await buildSolTransferTransaction(
|
|
2262
|
+
connection,
|
|
2263
|
+
solanaAddress,
|
|
2264
|
+
solanaDepositAddress,
|
|
2265
|
+
amountUnits
|
|
2266
|
+
) : await buildSplTransferTransaction(
|
|
2267
|
+
connection,
|
|
2268
|
+
solanaAddress,
|
|
2269
|
+
solanaDepositAddress,
|
|
2270
|
+
token.mint,
|
|
2271
|
+
amountUnits
|
|
2272
|
+
);
|
|
2273
|
+
debugLog(debug, "solana-confirm", "tx:build:success", {
|
|
2274
|
+
token: token.symbol,
|
|
2275
|
+
instructionCount: transaction.instructions.length,
|
|
2276
|
+
feePayer: transaction.feePayer?.toBase58(),
|
|
2277
|
+
recentBlockhash: transaction.recentBlockhash
|
|
2278
|
+
});
|
|
2279
|
+
const txHash = await sendSolanaTransaction(
|
|
2280
|
+
solanaProvider,
|
|
2281
|
+
connection,
|
|
2282
|
+
transaction
|
|
2283
|
+
);
|
|
2284
|
+
debugLog(debug, "solana-confirm", "tx:sent", {
|
|
2285
|
+
txHash,
|
|
2286
|
+
amountUnits: amountUnits.toString()
|
|
2287
|
+
});
|
|
2288
|
+
onConfirm(txHash, amountUnits.toString());
|
|
2289
|
+
} catch (err) {
|
|
2290
|
+
const raw = err instanceof Error ? err.message : "Transfer failed";
|
|
2291
|
+
const message = formatUserError(raw);
|
|
2292
|
+
debugError(debug, "solana-confirm", "submit:failure", err, {
|
|
2293
|
+
smartAccount,
|
|
2294
|
+
token: token.symbol,
|
|
2295
|
+
amount
|
|
2296
|
+
});
|
|
2297
|
+
setError(message);
|
|
2298
|
+
onError?.(message, "SOLANA_TRANSFER_ERROR");
|
|
2299
|
+
} finally {
|
|
2300
|
+
setIsSubmitting(false);
|
|
2301
|
+
}
|
|
2302
|
+
};
|
|
2303
|
+
return /* @__PURE__ */ jsxs9("div", { className: "rs-step", children: [
|
|
2304
|
+
/* @__PURE__ */ jsx9("div", { style: { padding: "12px 12px 10px" }, children: /* @__PURE__ */ jsx9("div", { className: "rs-step-title", children: "Review order" }) }),
|
|
2305
|
+
/* @__PURE__ */ jsxs9("div", { className: "rs-step-body rs-space-y-3", style: { paddingTop: 0 }, children: [
|
|
2306
|
+
/* @__PURE__ */ jsxs9("div", { className: "rs-card", children: [
|
|
2307
|
+
/* @__PURE__ */ jsxs9("div", { className: "rs-card-row", children: [
|
|
2308
|
+
/* @__PURE__ */ jsx9("span", { className: "rs-card-label", children: "Source" }),
|
|
2309
|
+
/* @__PURE__ */ jsxs9(
|
|
2310
|
+
"span",
|
|
2311
|
+
{
|
|
2312
|
+
className: "rs-card-value",
|
|
2313
|
+
style: { display: "flex", alignItems: "center", gap: 8 },
|
|
2314
|
+
children: [
|
|
2315
|
+
getChainIcon("solana") && /* @__PURE__ */ jsx9(
|
|
2316
|
+
"img",
|
|
2317
|
+
{
|
|
2318
|
+
src: getChainIcon("solana"),
|
|
2319
|
+
alt: "",
|
|
2320
|
+
style: { width: 16, height: 16, borderRadius: 3 }
|
|
2321
|
+
}
|
|
2322
|
+
),
|
|
2323
|
+
getChainName("solana")
|
|
2324
|
+
]
|
|
2325
|
+
}
|
|
2326
|
+
)
|
|
2327
|
+
] }),
|
|
2328
|
+
/* @__PURE__ */ jsxs9("div", { className: "rs-card-row", children: [
|
|
2329
|
+
/* @__PURE__ */ jsx9("span", { className: "rs-card-label", children: "Destination" }),
|
|
2330
|
+
/* @__PURE__ */ jsxs9(
|
|
2331
|
+
"span",
|
|
2332
|
+
{
|
|
2333
|
+
className: "rs-card-value",
|
|
2334
|
+
style: { display: "flex", alignItems: "center", gap: 8 },
|
|
2335
|
+
children: [
|
|
2336
|
+
getChainIcon(targetChain) && /* @__PURE__ */ jsx9(
|
|
2337
|
+
"img",
|
|
2338
|
+
{
|
|
2339
|
+
src: getChainIcon(targetChain),
|
|
2340
|
+
alt: "",
|
|
2341
|
+
style: { width: 16, height: 16, borderRadius: 3 }
|
|
2342
|
+
}
|
|
2343
|
+
),
|
|
2344
|
+
getChainName(targetChain)
|
|
2345
|
+
]
|
|
2346
|
+
}
|
|
2347
|
+
)
|
|
2348
|
+
] }),
|
|
2349
|
+
/* @__PURE__ */ jsxs9("div", { className: "rs-card-row", children: [
|
|
2350
|
+
/* @__PURE__ */ jsx9("span", { className: "rs-card-label", children: "Estimated time" }),
|
|
2351
|
+
/* @__PURE__ */ jsx9("span", { className: "rs-card-value", children: "< 1 min" })
|
|
2352
|
+
] })
|
|
2353
|
+
] }),
|
|
2354
|
+
/* @__PURE__ */ jsxs9("div", { className: "rs-card", children: [
|
|
2355
|
+
/* @__PURE__ */ jsxs9("div", { className: "rs-card-row", children: [
|
|
2356
|
+
/* @__PURE__ */ jsx9("span", { className: "rs-card-label", children: "You send" }),
|
|
2357
|
+
/* @__PURE__ */ jsxs9(
|
|
2358
|
+
"span",
|
|
2359
|
+
{
|
|
2360
|
+
className: "rs-card-value",
|
|
2361
|
+
style: { display: "flex", alignItems: "center", gap: 6 },
|
|
2362
|
+
children: [
|
|
2363
|
+
getTokenIcon(token.symbol) && /* @__PURE__ */ jsx9(
|
|
2364
|
+
"img",
|
|
2365
|
+
{
|
|
2366
|
+
src: getTokenIcon(token.symbol),
|
|
2367
|
+
alt: "",
|
|
2368
|
+
style: { width: 16, height: 16, borderRadius: "50%" }
|
|
2369
|
+
}
|
|
2370
|
+
),
|
|
2371
|
+
formattedAmount,
|
|
2372
|
+
" ",
|
|
2373
|
+
token.symbol
|
|
2374
|
+
]
|
|
2375
|
+
}
|
|
2376
|
+
)
|
|
2377
|
+
] }),
|
|
2378
|
+
/* @__PURE__ */ jsxs9("div", { className: "rs-card-row", children: [
|
|
2379
|
+
/* @__PURE__ */ jsx9("span", { className: "rs-card-label", children: "You receive" }),
|
|
2380
|
+
/* @__PURE__ */ jsxs9(
|
|
2381
|
+
"span",
|
|
2382
|
+
{
|
|
2383
|
+
className: "rs-card-value",
|
|
2384
|
+
style: { display: "flex", alignItems: "center", gap: 6 },
|
|
2385
|
+
children: [
|
|
2386
|
+
getTokenIcon(targetSymbol) && /* @__PURE__ */ jsx9(
|
|
2387
|
+
"img",
|
|
2388
|
+
{
|
|
2389
|
+
src: getTokenIcon(targetSymbol),
|
|
2390
|
+
alt: "",
|
|
2391
|
+
style: { width: 16, height: 16, borderRadius: "50%" }
|
|
2392
|
+
}
|
|
2393
|
+
),
|
|
2394
|
+
receiveAmount,
|
|
2395
|
+
" ",
|
|
2396
|
+
targetSymbol
|
|
2397
|
+
]
|
|
2398
|
+
}
|
|
2399
|
+
)
|
|
2400
|
+
] })
|
|
2401
|
+
] }),
|
|
2402
|
+
error && /* @__PURE__ */ jsxs9("div", { className: "rs-alert rs-alert--error", children: [
|
|
2403
|
+
/* @__PURE__ */ jsx9(
|
|
2404
|
+
"svg",
|
|
2405
|
+
{
|
|
2406
|
+
className: "rs-alert-icon",
|
|
2407
|
+
viewBox: "0 0 24 24",
|
|
2408
|
+
fill: "none",
|
|
2409
|
+
stroke: "currentColor",
|
|
2410
|
+
strokeWidth: "2",
|
|
2411
|
+
children: /* @__PURE__ */ jsx9(
|
|
2412
|
+
"path",
|
|
2413
|
+
{
|
|
2414
|
+
strokeLinecap: "round",
|
|
2415
|
+
strokeLinejoin: "round",
|
|
2416
|
+
d: "M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z"
|
|
2417
|
+
}
|
|
2418
|
+
)
|
|
2419
|
+
}
|
|
2420
|
+
),
|
|
2421
|
+
/* @__PURE__ */ jsx9("span", { className: "rs-alert-text", children: error })
|
|
2422
|
+
] })
|
|
2423
|
+
] }),
|
|
2424
|
+
/* @__PURE__ */ jsx9("div", { className: "rs-step-footer", children: /* @__PURE__ */ jsx9(
|
|
2425
|
+
Button,
|
|
2426
|
+
{
|
|
2427
|
+
onClick: handleConfirm,
|
|
2428
|
+
loading: isSubmitting,
|
|
2429
|
+
disabled: !amount || Number(amount) <= 0,
|
|
2430
|
+
fullWidth: true,
|
|
2431
|
+
children: "Confirm Order"
|
|
2432
|
+
}
|
|
2433
|
+
) }),
|
|
2434
|
+
/* @__PURE__ */ jsx9(PoweredBy, {})
|
|
2435
|
+
] });
|
|
2436
|
+
}
|
|
2437
|
+
|
|
2438
|
+
// src/DepositFlow.tsx
|
|
2439
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2440
|
+
function isSameRoute(sourceChain, sourceToken, targetChain, targetToken) {
|
|
2441
|
+
return sourceChain === targetChain && sourceToken.toLowerCase() === targetToken.toLowerCase();
|
|
2442
|
+
}
|
|
2443
|
+
function getAddressKey(address) {
|
|
2444
|
+
return address ? address.toLowerCase() : null;
|
|
2445
|
+
}
|
|
2446
|
+
function DepositFlow({
|
|
2447
|
+
dappWalletClient,
|
|
2448
|
+
dappPublicClient,
|
|
2449
|
+
dappAddress,
|
|
2450
|
+
targetChain,
|
|
2451
|
+
targetToken,
|
|
2452
|
+
service,
|
|
2453
|
+
sourceChain: defaultSourceChain,
|
|
2454
|
+
sourceToken: defaultSourceToken,
|
|
2455
|
+
amount: defaultAmount,
|
|
2456
|
+
recipient,
|
|
2457
|
+
signerAddress = DEFAULT_SIGNER_ADDRESS,
|
|
2458
|
+
sessionChainIds,
|
|
2459
|
+
forceRegister = false,
|
|
2460
|
+
waitForFinalTx = true,
|
|
2461
|
+
reownWallet,
|
|
2462
|
+
onConnect,
|
|
2463
|
+
onDisconnect,
|
|
2464
|
+
onRequestConnect,
|
|
2465
|
+
connectButtonLabel,
|
|
2466
|
+
uiConfig,
|
|
2467
|
+
onStepChange,
|
|
2468
|
+
onTotalBalanceChange,
|
|
2469
|
+
onClose,
|
|
2470
|
+
onConnected,
|
|
2471
|
+
onDepositSubmitted,
|
|
2472
|
+
onDepositComplete,
|
|
2473
|
+
onDepositFailed,
|
|
2474
|
+
onError,
|
|
2475
|
+
debug
|
|
2476
|
+
}) {
|
|
2477
|
+
const [step, setStep] = useState10({ type: "setup" });
|
|
2478
|
+
const [flowMode, setFlowMode] = useState10(null);
|
|
2479
|
+
const [totalBalanceUsd, setTotalBalanceUsd] = useState10(0);
|
|
2480
|
+
const [isConnectSelectionConfirmed, setIsConnectSelectionConfirmed] = useState10(false);
|
|
2481
|
+
const [selectedWalletId, setSelectedWalletId] = useState10(null);
|
|
2482
|
+
const portfolioAssetsRef = useRef5([]);
|
|
2483
|
+
const stableWalletSignerRef = useRef5(null);
|
|
2484
|
+
const stableWalletSelectionKeyRef = useRef5(null);
|
|
2485
|
+
const logFlow = useCallback3(
|
|
2486
|
+
(message, data) => {
|
|
2487
|
+
debugLog(debug, "deposit-flow", message, data);
|
|
2488
|
+
},
|
|
2489
|
+
[debug]
|
|
2490
|
+
);
|
|
2491
|
+
const logFlowError = useCallback3(
|
|
2492
|
+
(message, error, data) => {
|
|
2493
|
+
debugError(debug, "deposit-flow", message, error, data);
|
|
2494
|
+
},
|
|
2495
|
+
[debug]
|
|
2496
|
+
);
|
|
2497
|
+
const handleAssetsLoaded = useCallback3((assets) => {
|
|
2498
|
+
portfolioAssetsRef.current = assets;
|
|
2499
|
+
}, []);
|
|
2500
|
+
const getTokenPriceUsd = useCallback3((symbol) => {
|
|
2501
|
+
const sym = symbol.toLowerCase();
|
|
2502
|
+
for (const asset of portfolioAssetsRef.current) {
|
|
2503
|
+
if (asset.symbol.toLowerCase() === sym && asset.balanceUsd && asset.balance) {
|
|
2504
|
+
try {
|
|
2505
|
+
const balanceUnits = Number(asset.balance) / 10 ** asset.decimals;
|
|
2506
|
+
if (balanceUnits > 0) return asset.balanceUsd / balanceUnits;
|
|
2507
|
+
} catch {
|
|
2508
|
+
}
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
return null;
|
|
2512
|
+
}, []);
|
|
2513
|
+
const dappSwitchChain = useMemo7(() => {
|
|
2514
|
+
if (!dappWalletClient?.switchChain) return void 0;
|
|
2515
|
+
return async (chainId) => {
|
|
2516
|
+
await dappWalletClient.switchChain?.({ id: chainId });
|
|
2517
|
+
};
|
|
2518
|
+
}, [dappWalletClient]);
|
|
2519
|
+
const connectedWalletAddress = dappWalletClient?.account?.address ?? null;
|
|
2520
|
+
const walletOptions = useMemo7(() => {
|
|
2521
|
+
const options = [];
|
|
2522
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2523
|
+
if (connectedWalletAddress && dappAddress) {
|
|
2524
|
+
const id = `evm:${connectedWalletAddress.toLowerCase()}`;
|
|
2525
|
+
options.push({
|
|
2526
|
+
id,
|
|
2527
|
+
address: connectedWalletAddress,
|
|
2528
|
+
label: "Connected Wallet",
|
|
2529
|
+
kind: "connected"
|
|
2530
|
+
});
|
|
2531
|
+
seen.add(id);
|
|
2532
|
+
}
|
|
2533
|
+
if (reownWallet?.isConnected && reownWallet.isSolana && reownWallet.solanaAddress && dappAddress) {
|
|
2534
|
+
const id = reownWallet.caipAddress ?? `solana:${reownWallet.solanaAddress}`;
|
|
2535
|
+
if (!seen.has(id)) {
|
|
2536
|
+
options.push({
|
|
2537
|
+
id,
|
|
2538
|
+
solanaAddress: reownWallet.solanaAddress,
|
|
2539
|
+
label: "Solana Wallet",
|
|
2540
|
+
kind: "solana",
|
|
2541
|
+
icon: reownWallet.icon
|
|
2542
|
+
});
|
|
2543
|
+
seen.add(id);
|
|
2544
|
+
}
|
|
2545
|
+
} else if (reownWallet?.address && reownWallet.isConnected && reownWallet.walletClient && reownWallet.publicClient && !seen.has(`evm:${reownWallet.address.toLowerCase()}`)) {
|
|
2546
|
+
const id = `evm:${reownWallet.address.toLowerCase()}`;
|
|
2547
|
+
if (!seen.has(id)) {
|
|
2548
|
+
options.push({
|
|
2549
|
+
id,
|
|
2550
|
+
address: reownWallet.address,
|
|
2551
|
+
label: "External Wallet",
|
|
2552
|
+
kind: "external",
|
|
2553
|
+
icon: reownWallet.icon
|
|
2554
|
+
});
|
|
2555
|
+
seen.add(id);
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
return options;
|
|
2559
|
+
}, [
|
|
2560
|
+
connectedWalletAddress,
|
|
2561
|
+
dappAddress,
|
|
2562
|
+
reownWallet?.address,
|
|
2563
|
+
reownWallet?.isConnected,
|
|
2564
|
+
reownWallet?.walletClient,
|
|
2565
|
+
reownWallet?.publicClient,
|
|
2566
|
+
reownWallet?.icon,
|
|
2567
|
+
reownWallet?.isSolana,
|
|
2568
|
+
reownWallet?.solanaAddress,
|
|
2569
|
+
reownWallet?.caipAddress
|
|
2570
|
+
]);
|
|
2571
|
+
const canAutoLock = dappWalletClient?.account && dappAddress && !reownWallet;
|
|
2572
|
+
const hasWalletOptions = walletOptions.length > 0;
|
|
2573
|
+
const hasReownSession = Boolean(
|
|
2574
|
+
reownWallet?.isConnected || reownWallet?.address
|
|
2575
|
+
);
|
|
2576
|
+
const showConnectStep = flowMode === null && !canAutoLock && !isConnectSelectionConfirmed;
|
|
2577
|
+
const walletSelectionKey = useMemo7(() => {
|
|
2578
|
+
if (flowMode !== "wallet") return null;
|
|
2579
|
+
if (canAutoLock) {
|
|
2580
|
+
return getAddressKey(connectedWalletAddress);
|
|
2581
|
+
}
|
|
2582
|
+
if (!isConnectSelectionConfirmed) return null;
|
|
2583
|
+
return selectedWalletId;
|
|
2584
|
+
}, [
|
|
2585
|
+
flowMode,
|
|
2586
|
+
canAutoLock,
|
|
2587
|
+
connectedWalletAddress,
|
|
2588
|
+
isConnectSelectionConfirmed,
|
|
2589
|
+
selectedWalletId
|
|
2590
|
+
]);
|
|
2591
|
+
const walletSignerContext = useMemo7(() => {
|
|
2592
|
+
if (flowMode === "deposit-address") {
|
|
2593
|
+
return null;
|
|
2594
|
+
}
|
|
2595
|
+
if (flowMode === "solana-wallet") {
|
|
2596
|
+
if (!dappAddress) return null;
|
|
2597
|
+
return {
|
|
2598
|
+
ownerAddress: dappAddress,
|
|
2599
|
+
walletClient: void 0,
|
|
2600
|
+
publicClient: dappPublicClient ?? getPublicClient(targetChain),
|
|
2601
|
+
switchChain: void 0
|
|
2602
|
+
};
|
|
2603
|
+
}
|
|
2604
|
+
if (canAutoLock) {
|
|
2605
|
+
const fallbackChainId = dappWalletClient?.chain?.id ?? targetChain;
|
|
2606
|
+
return {
|
|
2607
|
+
ownerAddress: dappWalletClient.account.address,
|
|
2608
|
+
walletClient: dappWalletClient,
|
|
2609
|
+
publicClient: dappPublicClient ?? getPublicClient(fallbackChainId),
|
|
2610
|
+
switchChain: dappSwitchChain
|
|
2611
|
+
};
|
|
2612
|
+
}
|
|
2613
|
+
if (!isConnectSelectionConfirmed || !selectedWalletId) return null;
|
|
2614
|
+
const selectedOption = walletOptions.find(
|
|
2615
|
+
(option) => option.id === selectedWalletId
|
|
2616
|
+
);
|
|
2617
|
+
if (!selectedOption) return null;
|
|
2618
|
+
if (selectedOption.kind === "solana") {
|
|
2619
|
+
if (!dappAddress) return null;
|
|
2620
|
+
return {
|
|
2621
|
+
ownerAddress: dappAddress,
|
|
2622
|
+
walletClient: void 0,
|
|
2623
|
+
publicClient: dappPublicClient ?? getPublicClient(targetChain),
|
|
2624
|
+
switchChain: void 0
|
|
2625
|
+
};
|
|
2626
|
+
}
|
|
2627
|
+
if (selectedOption.kind === "connected" && dappWalletClient?.account && selectedOption.address && dappWalletClient.account.address.toLowerCase() === selectedOption.address.toLowerCase()) {
|
|
2628
|
+
const fallbackChainId = dappWalletClient?.chain?.id ?? targetChain;
|
|
2629
|
+
return {
|
|
2630
|
+
ownerAddress: dappWalletClient.account.address,
|
|
2631
|
+
walletClient: dappWalletClient,
|
|
2632
|
+
publicClient: dappPublicClient ?? getPublicClient(fallbackChainId),
|
|
2633
|
+
switchChain: dappSwitchChain
|
|
2634
|
+
};
|
|
2635
|
+
}
|
|
2636
|
+
if (selectedOption.kind === "external" && reownWallet?.address && selectedOption.address && reownWallet.address.toLowerCase() === selectedOption.address.toLowerCase()) {
|
|
2637
|
+
return {
|
|
2638
|
+
ownerAddress: reownWallet.address,
|
|
2639
|
+
walletClient: reownWallet.walletClient,
|
|
2640
|
+
publicClient: reownWallet.publicClient ?? getPublicClient(targetChain),
|
|
2641
|
+
switchChain: reownWallet.switchChain
|
|
2642
|
+
};
|
|
2643
|
+
}
|
|
2644
|
+
return null;
|
|
2645
|
+
}, [
|
|
2646
|
+
canAutoLock,
|
|
2647
|
+
isConnectSelectionConfirmed,
|
|
2648
|
+
selectedWalletId,
|
|
2649
|
+
walletOptions,
|
|
2650
|
+
dappWalletClient,
|
|
2651
|
+
dappPublicClient,
|
|
2652
|
+
dappSwitchChain,
|
|
1703
2653
|
dappAddress,
|
|
1704
2654
|
reownWallet,
|
|
1705
2655
|
targetChain
|
|
1706
2656
|
]);
|
|
1707
|
-
|
|
2657
|
+
useEffect8(() => {
|
|
1708
2658
|
if (flowMode !== "wallet") {
|
|
1709
2659
|
stableWalletSelectionKeyRef.current = null;
|
|
1710
2660
|
stableWalletSignerRef.current = null;
|
|
@@ -1719,7 +2669,7 @@ function DepositFlow({
|
|
|
1719
2669
|
stableWalletSignerRef.current = walletSignerContext;
|
|
1720
2670
|
}
|
|
1721
2671
|
}, [flowMode, walletSelectionKey, walletSignerContext]);
|
|
1722
|
-
const signerContext =
|
|
2672
|
+
const signerContext = useMemo7(() => {
|
|
1723
2673
|
if (flowMode === "deposit-address") {
|
|
1724
2674
|
if (!dappAddress) return null;
|
|
1725
2675
|
return {
|
|
@@ -1749,7 +2699,7 @@ function DepositFlow({
|
|
|
1749
2699
|
]);
|
|
1750
2700
|
const sessionKeyAddress = dappAddress ?? signerContext?.ownerAddress ?? null;
|
|
1751
2701
|
const lastTargetRef = useRef5(null);
|
|
1752
|
-
|
|
2702
|
+
useEffect8(() => {
|
|
1753
2703
|
const prev = lastTargetRef.current;
|
|
1754
2704
|
if (prev && (prev.chain !== targetChain || prev.token.toLowerCase() !== targetToken.toLowerCase())) {
|
|
1755
2705
|
if (step.type !== "processing") {
|
|
@@ -1779,6 +2729,37 @@ function DepositFlow({
|
|
|
1779
2729
|
setIsConnectSelectionConfirmed(false);
|
|
1780
2730
|
}
|
|
1781
2731
|
}, [hasWalletOptions, reownWallet]);
|
|
2732
|
+
const handleBackFromSolanaTokenSelect = useCallback3(() => {
|
|
2733
|
+
setFlowMode(null);
|
|
2734
|
+
setStep({ type: "setup" });
|
|
2735
|
+
if (hasWalletOptions || reownWallet) {
|
|
2736
|
+
hasNavigatedBackRef.current = true;
|
|
2737
|
+
setIsConnectSelectionConfirmed(false);
|
|
2738
|
+
}
|
|
2739
|
+
}, [hasWalletOptions, reownWallet]);
|
|
2740
|
+
const handleBackFromSolanaAmount = useCallback3(() => {
|
|
2741
|
+
setStep((prev) => {
|
|
2742
|
+
if (prev.type !== "solana-amount") return prev;
|
|
2743
|
+
return {
|
|
2744
|
+
type: "solana-token-select",
|
|
2745
|
+
smartAccount: prev.smartAccount,
|
|
2746
|
+
solanaDepositAddress: prev.solanaDepositAddress
|
|
2747
|
+
};
|
|
2748
|
+
});
|
|
2749
|
+
}, []);
|
|
2750
|
+
const handleBackFromSolanaConfirm = useCallback3(() => {
|
|
2751
|
+
setStep((prev) => {
|
|
2752
|
+
if (prev.type !== "solana-confirm") return prev;
|
|
2753
|
+
return {
|
|
2754
|
+
type: "solana-amount",
|
|
2755
|
+
smartAccount: prev.smartAccount,
|
|
2756
|
+
solanaDepositAddress: prev.solanaDepositAddress,
|
|
2757
|
+
token: prev.token,
|
|
2758
|
+
balance: prev.balance,
|
|
2759
|
+
balanceUsd: prev.balanceUsd
|
|
2760
|
+
};
|
|
2761
|
+
});
|
|
2762
|
+
}, []);
|
|
1782
2763
|
const handleBackFromConfirm = useCallback3(() => {
|
|
1783
2764
|
setStep((prev) => {
|
|
1784
2765
|
if (prev.type !== "confirm") return prev;
|
|
@@ -1789,50 +2770,90 @@ function DepositFlow({
|
|
|
1789
2770
|
};
|
|
1790
2771
|
});
|
|
1791
2772
|
}, []);
|
|
1792
|
-
const stepIndex = step.type === "setup" ? 0 : step.type === "deposit-address" ? 1 : step.type === "select-asset" ? 1 : step.type === "amount" ? 2 : step.type === "confirm" ? 3 : 4;
|
|
1793
|
-
const currentBackHandler = step.type === "deposit-address" ? handleBackFromDepositAddress : step.type === "select-asset" && signerContext && !canAutoLock ? handleBackFromSelectAsset : step.type === "amount" ? handleBackFromAmount : step.type === "confirm" ? handleBackFromConfirm : void 0;
|
|
1794
|
-
|
|
2773
|
+
const stepIndex = step.type === "setup" ? 0 : step.type === "deposit-address" ? 1 : step.type === "select-asset" ? 1 : step.type === "solana-token-select" ? 1 : step.type === "solana-amount" ? 2 : step.type === "amount" ? 2 : step.type === "confirm" ? 3 : step.type === "solana-confirm" ? 3 : 4;
|
|
2774
|
+
const currentBackHandler = step.type === "deposit-address" ? handleBackFromDepositAddress : step.type === "select-asset" && signerContext && !canAutoLock ? handleBackFromSelectAsset : step.type === "solana-token-select" ? handleBackFromSolanaTokenSelect : step.type === "solana-amount" ? handleBackFromSolanaAmount : step.type === "solana-confirm" ? handleBackFromSolanaConfirm : step.type === "amount" ? handleBackFromAmount : step.type === "confirm" ? handleBackFromConfirm : void 0;
|
|
2775
|
+
useEffect8(() => {
|
|
1795
2776
|
onStepChange?.(stepIndex, currentBackHandler);
|
|
1796
2777
|
}, [stepIndex, currentBackHandler, onStepChange]);
|
|
1797
|
-
|
|
2778
|
+
useEffect8(() => {
|
|
2779
|
+
logFlow("state:changed", {
|
|
2780
|
+
step: step.type,
|
|
2781
|
+
flowMode,
|
|
2782
|
+
targetChain,
|
|
2783
|
+
targetToken,
|
|
2784
|
+
selectedWalletId
|
|
2785
|
+
});
|
|
2786
|
+
}, [
|
|
2787
|
+
flowMode,
|
|
2788
|
+
logFlow,
|
|
2789
|
+
selectedWalletId,
|
|
2790
|
+
step.type,
|
|
2791
|
+
targetChain,
|
|
2792
|
+
targetToken
|
|
2793
|
+
]);
|
|
2794
|
+
useEffect8(() => {
|
|
1798
2795
|
onTotalBalanceChange?.(totalBalanceUsd);
|
|
1799
2796
|
}, [totalBalanceUsd, onTotalBalanceChange]);
|
|
1800
2797
|
const isDepositAddressMode = flowMode === "deposit-address";
|
|
2798
|
+
const isSolanaWalletMode = flowMode === "solana-wallet";
|
|
1801
2799
|
const handleSelectProvider = useCallback3(() => {
|
|
1802
2800
|
setFlowMode("wallet");
|
|
1803
2801
|
}, []);
|
|
2802
|
+
const handleSelectSolanaWallet = useCallback3(() => {
|
|
2803
|
+
setFlowMode("solana-wallet");
|
|
2804
|
+
}, []);
|
|
1804
2805
|
const handleSelectTransferCrypto = useCallback3(() => {
|
|
1805
2806
|
setFlowMode("deposit-address");
|
|
1806
2807
|
setStep({ type: "setup" });
|
|
1807
2808
|
}, []);
|
|
1808
|
-
const
|
|
1809
|
-
portfolioAssetsRef.current = [];
|
|
1810
|
-
stableWalletSignerRef.current = null;
|
|
1811
|
-
stableWalletSelectionKeyRef.current = null;
|
|
1812
|
-
hasNavigatedBackRef.current = false;
|
|
1813
|
-
setTotalBalanceUsd(0);
|
|
1814
|
-
setSelectedConnectAddress(null);
|
|
1815
|
-
setIsConnectSelectionConfirmed(false);
|
|
2809
|
+
const handleNewDeposit = useCallback3(() => {
|
|
1816
2810
|
setFlowMode(null);
|
|
1817
2811
|
setStep({ type: "setup" });
|
|
1818
2812
|
}, []);
|
|
1819
|
-
const handleNewDeposit = useCallback3(() => {
|
|
1820
|
-
handleResetFlow();
|
|
1821
|
-
}, [handleResetFlow]);
|
|
1822
2813
|
const handleSetupComplete = useCallback3(
|
|
1823
|
-
(smartAccount) => {
|
|
2814
|
+
(smartAccount, solanaDepositAddress) => {
|
|
2815
|
+
logFlow("setup:complete", {
|
|
2816
|
+
smartAccount,
|
|
2817
|
+
hasSolanaDepositAddress: Boolean(solanaDepositAddress),
|
|
2818
|
+
flowMode: isDepositAddressMode ? "deposit-address" : isSolanaWalletMode ? "solana-wallet" : "wallet"
|
|
2819
|
+
});
|
|
1824
2820
|
if (isDepositAddressMode) {
|
|
1825
|
-
setStep({
|
|
2821
|
+
setStep({
|
|
2822
|
+
type: "deposit-address",
|
|
2823
|
+
smartAccount,
|
|
2824
|
+
solanaDepositAddress
|
|
2825
|
+
});
|
|
2826
|
+
} else if (isSolanaWalletMode) {
|
|
2827
|
+
if (solanaDepositAddress) {
|
|
2828
|
+
setStep({
|
|
2829
|
+
type: "solana-token-select",
|
|
2830
|
+
smartAccount,
|
|
2831
|
+
solanaDepositAddress
|
|
2832
|
+
});
|
|
2833
|
+
} else {
|
|
2834
|
+
onError?.({
|
|
2835
|
+
message: "Solana deposit address not available. Please try again.",
|
|
2836
|
+
code: "SOLANA_SETUP_FAILED"
|
|
2837
|
+
});
|
|
2838
|
+
}
|
|
1826
2839
|
} else {
|
|
1827
2840
|
setStep({ type: "select-asset", smartAccount });
|
|
1828
2841
|
}
|
|
1829
2842
|
},
|
|
1830
|
-
[isDepositAddressMode]
|
|
2843
|
+
[isDepositAddressMode, isSolanaWalletMode, logFlow]
|
|
1831
2844
|
);
|
|
1832
2845
|
const handleDepositAddressDetected = useCallback3(
|
|
1833
|
-
(txHash, chainId, amount, token) => {
|
|
2846
|
+
(txHash, chainId, amount, token, sourceSymbol, sourceDecimals) => {
|
|
2847
|
+
logFlow("deposit-address:detected", {
|
|
2848
|
+
txHash,
|
|
2849
|
+
sourceChain: chainId,
|
|
2850
|
+
sourceToken: token,
|
|
2851
|
+
amount
|
|
2852
|
+
});
|
|
1834
2853
|
setStep((prev) => {
|
|
1835
2854
|
if (prev.type !== "deposit-address") return prev;
|
|
2855
|
+
const isEvmToken = /^0x[a-fA-F0-9]{40}$/.test(token);
|
|
2856
|
+
const directTransfer = typeof chainId === "number" && isEvmToken && isSameRoute(chainId, token, targetChain, targetToken);
|
|
1836
2857
|
return {
|
|
1837
2858
|
type: "processing",
|
|
1838
2859
|
smartAccount: prev.smartAccount,
|
|
@@ -1840,13 +2861,94 @@ function DepositFlow({
|
|
|
1840
2861
|
sourceChain: chainId,
|
|
1841
2862
|
sourceToken: token,
|
|
1842
2863
|
amount,
|
|
1843
|
-
|
|
2864
|
+
sourceSymbol,
|
|
2865
|
+
sourceDecimals,
|
|
2866
|
+
directTransfer
|
|
1844
2867
|
};
|
|
1845
2868
|
});
|
|
1846
2869
|
onDepositSubmitted?.({ txHash, sourceChain: chainId, amount });
|
|
1847
2870
|
},
|
|
1848
2871
|
[onDepositSubmitted, targetChain, targetToken]
|
|
1849
2872
|
);
|
|
2873
|
+
const handleSolanaTokenContinue = useCallback3(
|
|
2874
|
+
(token, balance, balanceUsd) => {
|
|
2875
|
+
logFlow("solana:token:continue", { token: token.symbol });
|
|
2876
|
+
setStep((prev) => {
|
|
2877
|
+
if (prev.type !== "solana-token-select") return prev;
|
|
2878
|
+
return {
|
|
2879
|
+
type: "solana-amount",
|
|
2880
|
+
smartAccount: prev.smartAccount,
|
|
2881
|
+
solanaDepositAddress: prev.solanaDepositAddress,
|
|
2882
|
+
token,
|
|
2883
|
+
balance,
|
|
2884
|
+
balanceUsd
|
|
2885
|
+
};
|
|
2886
|
+
});
|
|
2887
|
+
},
|
|
2888
|
+
[logFlow]
|
|
2889
|
+
);
|
|
2890
|
+
const handleSolanaAmountContinue = useCallback3(
|
|
2891
|
+
(token, amount) => {
|
|
2892
|
+
const targetSym = getTokenSymbol(targetToken, targetChain);
|
|
2893
|
+
const isTargetStable = isStablecoinSymbol(targetSym);
|
|
2894
|
+
const targetTokenPriceUsd = isTargetStable ? 1 : getTokenPriceUsd(targetSym);
|
|
2895
|
+
logFlow("solana:amount:continue", {
|
|
2896
|
+
token: token.symbol,
|
|
2897
|
+
amount,
|
|
2898
|
+
targetSymbol: targetSym,
|
|
2899
|
+
targetTokenPriceUsd
|
|
2900
|
+
});
|
|
2901
|
+
setStep((prev) => {
|
|
2902
|
+
if (prev.type !== "solana-amount") return prev;
|
|
2903
|
+
const sourceBalance = Number(
|
|
2904
|
+
formatUnits5(prev.balance, prev.token.decimals)
|
|
2905
|
+
);
|
|
2906
|
+
const sourceTokenPriceUsd = Number.isFinite(sourceBalance) && sourceBalance > 0 && prev.balanceUsd > 0 ? prev.balanceUsd / sourceBalance : null;
|
|
2907
|
+
const parsedAmount = Number(amount);
|
|
2908
|
+
const targetAmount = sourceTokenPriceUsd !== null && Number.isFinite(parsedAmount) && parsedAmount > 0 ? (parsedAmount * sourceTokenPriceUsd).toString() : amount;
|
|
2909
|
+
return {
|
|
2910
|
+
type: "solana-confirm",
|
|
2911
|
+
smartAccount: prev.smartAccount,
|
|
2912
|
+
solanaDepositAddress: prev.solanaDepositAddress,
|
|
2913
|
+
token,
|
|
2914
|
+
amount,
|
|
2915
|
+
targetAmount,
|
|
2916
|
+
targetTokenPriceUsd,
|
|
2917
|
+
balance: prev.balance,
|
|
2918
|
+
balanceUsd: prev.balanceUsd
|
|
2919
|
+
};
|
|
2920
|
+
});
|
|
2921
|
+
},
|
|
2922
|
+
[targetToken, targetChain, getTokenPriceUsd, logFlow]
|
|
2923
|
+
);
|
|
2924
|
+
const handleSolanaConfirmed = useCallback3(
|
|
2925
|
+
(txHash, amountUnits) => {
|
|
2926
|
+
setStep((prev) => {
|
|
2927
|
+
if (prev.type !== "solana-confirm") return prev;
|
|
2928
|
+
logFlow("solana:submitted", {
|
|
2929
|
+
txHash,
|
|
2930
|
+
amountUnits,
|
|
2931
|
+
token: prev.token.symbol
|
|
2932
|
+
});
|
|
2933
|
+
return {
|
|
2934
|
+
type: "processing",
|
|
2935
|
+
smartAccount: prev.smartAccount,
|
|
2936
|
+
txHash,
|
|
2937
|
+
sourceChain: "solana",
|
|
2938
|
+
sourceToken: prev.token.mint,
|
|
2939
|
+
amount: amountUnits,
|
|
2940
|
+
sourceSymbol: prev.token.symbol,
|
|
2941
|
+
sourceDecimals: prev.token.decimals
|
|
2942
|
+
};
|
|
2943
|
+
});
|
|
2944
|
+
onDepositSubmitted?.({
|
|
2945
|
+
txHash,
|
|
2946
|
+
sourceChain: "solana",
|
|
2947
|
+
amount: amountUnits
|
|
2948
|
+
});
|
|
2949
|
+
},
|
|
2950
|
+
[logFlow, onDepositSubmitted]
|
|
2951
|
+
);
|
|
1850
2952
|
const handleConnected = useCallback3(
|
|
1851
2953
|
(addr, smartAccount) => {
|
|
1852
2954
|
onConnected?.({ address: addr, smartAccount });
|
|
@@ -1889,6 +2991,12 @@ function DepositFlow({
|
|
|
1889
2991
|
);
|
|
1890
2992
|
const handleDepositSubmitted = useCallback3(
|
|
1891
2993
|
(txHash, chainId, amount, token) => {
|
|
2994
|
+
logFlow("evm:submitted", {
|
|
2995
|
+
txHash,
|
|
2996
|
+
sourceChain: chainId,
|
|
2997
|
+
sourceToken: token,
|
|
2998
|
+
amount
|
|
2999
|
+
});
|
|
1892
3000
|
setStep((prev) => {
|
|
1893
3001
|
if (prev.type !== "confirm") return prev;
|
|
1894
3002
|
return {
|
|
@@ -1912,48 +3020,69 @@ function DepositFlow({
|
|
|
1912
3020
|
);
|
|
1913
3021
|
const handleDepositComplete = useCallback3(
|
|
1914
3022
|
(txHash, destinationTxHash) => {
|
|
3023
|
+
logFlow("deposit:complete", { txHash, destinationTxHash });
|
|
1915
3024
|
onDepositComplete?.({ txHash, destinationTxHash });
|
|
1916
3025
|
},
|
|
1917
|
-
[onDepositComplete]
|
|
3026
|
+
[logFlow, onDepositComplete]
|
|
1918
3027
|
);
|
|
1919
3028
|
const handleDepositFailed = useCallback3(
|
|
1920
3029
|
(txHash, error) => {
|
|
3030
|
+
logFlowError("deposit:failed", error, { txHash });
|
|
1921
3031
|
onDepositFailed?.({ txHash, error });
|
|
1922
3032
|
},
|
|
1923
|
-
[onDepositFailed]
|
|
3033
|
+
[logFlowError, onDepositFailed]
|
|
1924
3034
|
);
|
|
1925
3035
|
const handleError = useCallback3(
|
|
1926
3036
|
(message, code) => {
|
|
3037
|
+
logFlowError("flow:error", message, { code });
|
|
1927
3038
|
onError?.({ message, code });
|
|
1928
3039
|
},
|
|
1929
|
-
[onError]
|
|
3040
|
+
[logFlowError, onError]
|
|
1930
3041
|
);
|
|
1931
3042
|
const handleTotalBalanceComputed = useCallback3((total) => {
|
|
1932
3043
|
setTotalBalanceUsd(total);
|
|
1933
3044
|
}, []);
|
|
1934
|
-
const
|
|
1935
|
-
if (
|
|
3045
|
+
const selectedWalletIdEffective = useMemo7(() => {
|
|
3046
|
+
if (selectedWalletId) return selectedWalletId;
|
|
1936
3047
|
if (walletOptions.length === 1) {
|
|
1937
|
-
return walletOptions[0].
|
|
3048
|
+
return walletOptions[0].id;
|
|
1938
3049
|
}
|
|
1939
3050
|
return null;
|
|
1940
|
-
}, [
|
|
1941
|
-
|
|
3051
|
+
}, [selectedWalletId, walletOptions]);
|
|
3052
|
+
const walletOptionsKey = useMemo7(
|
|
3053
|
+
() => walletOptions.map((option) => option.id).join(","),
|
|
3054
|
+
[walletOptions]
|
|
3055
|
+
);
|
|
3056
|
+
const hasNavigatedBackRef = useRef5(false);
|
|
3057
|
+
useEffect8(() => {
|
|
3058
|
+
setIsConnectSelectionConfirmed(false);
|
|
3059
|
+
setSelectedWalletId(null);
|
|
3060
|
+
setFlowMode(null);
|
|
3061
|
+
if (step.type !== "processing" && step.type !== "confirm" && step.type !== "solana-confirm" && step.type !== "amount" && step.type !== "solana-amount") {
|
|
3062
|
+
setStep({ type: "setup" });
|
|
3063
|
+
}
|
|
3064
|
+
}, [walletOptionsKey]);
|
|
3065
|
+
useEffect8(() => {
|
|
1942
3066
|
if (!showConnectStep && isConnectSelectionConfirmed && flowMode === "wallet" && !signerContext) {
|
|
1943
|
-
|
|
3067
|
+
setSelectedWalletId(null);
|
|
1944
3068
|
setIsConnectSelectionConfirmed(false);
|
|
1945
3069
|
setFlowMode(null);
|
|
1946
3070
|
}
|
|
1947
3071
|
}, [showConnectStep, isConnectSelectionConfirmed, flowMode, signerContext]);
|
|
1948
|
-
|
|
3072
|
+
useEffect8(() => {
|
|
1949
3073
|
if (hasNavigatedBackRef.current || isConnectSelectionConfirmed || flowMode) {
|
|
1950
3074
|
return;
|
|
1951
3075
|
}
|
|
1952
3076
|
if (hasWalletOptions) {
|
|
1953
|
-
const
|
|
1954
|
-
if (
|
|
1955
|
-
|
|
1956
|
-
|
|
3077
|
+
const walletId = selectedWalletIdEffective;
|
|
3078
|
+
if (walletId) {
|
|
3079
|
+
const selectedOption = walletOptions.find((o) => o.id === walletId);
|
|
3080
|
+
setSelectedWalletId(walletId);
|
|
3081
|
+
if (selectedOption?.kind === "solana") {
|
|
3082
|
+
handleSelectSolanaWallet();
|
|
3083
|
+
} else {
|
|
3084
|
+
handleSelectProvider();
|
|
3085
|
+
}
|
|
1957
3086
|
setIsConnectSelectionConfirmed(true);
|
|
1958
3087
|
return;
|
|
1959
3088
|
}
|
|
@@ -1967,18 +3096,20 @@ function DepositFlow({
|
|
|
1967
3096
|
hasReownSession,
|
|
1968
3097
|
isConnectSelectionConfirmed,
|
|
1969
3098
|
flowMode,
|
|
1970
|
-
|
|
3099
|
+
selectedWalletIdEffective,
|
|
1971
3100
|
dappAddress,
|
|
3101
|
+
walletOptions,
|
|
1972
3102
|
handleSelectProvider,
|
|
3103
|
+
handleSelectSolanaWallet,
|
|
1973
3104
|
handleSelectTransferCrypto
|
|
1974
3105
|
]);
|
|
1975
3106
|
if (showConnectStep) {
|
|
1976
|
-
return /* @__PURE__ */
|
|
3107
|
+
return /* @__PURE__ */ jsx10("div", { className: "rs-modal-body", children: /* @__PURE__ */ jsx10(
|
|
1977
3108
|
ConnectStep,
|
|
1978
3109
|
{
|
|
1979
3110
|
walletOptions,
|
|
1980
|
-
|
|
1981
|
-
|
|
3111
|
+
selectedWalletId: selectedWalletIdEffective,
|
|
3112
|
+
onSelectWallet: setSelectedWalletId,
|
|
1982
3113
|
onSelectTransferCrypto: dappAddress ? () => {
|
|
1983
3114
|
handleSelectTransferCrypto();
|
|
1984
3115
|
setIsConnectSelectionConfirmed(true);
|
|
@@ -1987,10 +3118,17 @@ function DepositFlow({
|
|
|
1987
3118
|
onConnect,
|
|
1988
3119
|
onDisconnect,
|
|
1989
3120
|
onContinue: () => {
|
|
1990
|
-
if (
|
|
1991
|
-
|
|
3121
|
+
if (selectedWalletIdEffective) {
|
|
3122
|
+
setSelectedWalletId(selectedWalletIdEffective);
|
|
3123
|
+
}
|
|
3124
|
+
const selectedOption = walletOptions.find(
|
|
3125
|
+
(o) => o.id === selectedWalletIdEffective
|
|
3126
|
+
);
|
|
3127
|
+
if (selectedOption?.kind === "solana") {
|
|
3128
|
+
handleSelectSolanaWallet();
|
|
3129
|
+
} else {
|
|
3130
|
+
handleSelectProvider();
|
|
1992
3131
|
}
|
|
1993
|
-
handleSelectProvider();
|
|
1994
3132
|
setIsConnectSelectionConfirmed(true);
|
|
1995
3133
|
},
|
|
1996
3134
|
connectButtonLabel
|
|
@@ -1999,8 +3137,8 @@ function DepositFlow({
|
|
|
1999
3137
|
}
|
|
2000
3138
|
if (isDepositAddressMode) {
|
|
2001
3139
|
if (!dappAddress || !sessionKeyAddress) return null;
|
|
2002
|
-
return /* @__PURE__ */
|
|
2003
|
-
step.type === "setup" && /* @__PURE__ */
|
|
3140
|
+
return /* @__PURE__ */ jsxs10("div", { className: "rs-modal-body", children: [
|
|
3141
|
+
step.type === "setup" && /* @__PURE__ */ jsx10(
|
|
2004
3142
|
SetupStep,
|
|
2005
3143
|
{
|
|
2006
3144
|
address: sessionKeyAddress,
|
|
@@ -2016,16 +3154,134 @@ function DepositFlow({
|
|
|
2016
3154
|
onError: handleError
|
|
2017
3155
|
}
|
|
2018
3156
|
),
|
|
2019
|
-
step.type === "deposit-address" && /* @__PURE__ */
|
|
3157
|
+
step.type === "deposit-address" && /* @__PURE__ */ jsx10(
|
|
2020
3158
|
DepositAddressStep,
|
|
2021
3159
|
{
|
|
2022
3160
|
smartAccount: step.smartAccount,
|
|
3161
|
+
solanaDepositAddress: step.solanaDepositAddress,
|
|
2023
3162
|
service,
|
|
2024
3163
|
onDepositDetected: handleDepositAddressDetected,
|
|
2025
3164
|
onError: handleError
|
|
2026
3165
|
}
|
|
2027
3166
|
),
|
|
2028
|
-
step.type === "processing" && /* @__PURE__ */
|
|
3167
|
+
step.type === "processing" && /* @__PURE__ */ jsx10(
|
|
3168
|
+
ProcessingStep,
|
|
3169
|
+
{
|
|
3170
|
+
smartAccount: step.smartAccount,
|
|
3171
|
+
txHash: step.txHash,
|
|
3172
|
+
sourceChain: step.sourceChain,
|
|
3173
|
+
sourceToken: step.sourceToken,
|
|
3174
|
+
targetChain,
|
|
3175
|
+
amount: step.amount,
|
|
3176
|
+
sourceSymbol: step.sourceSymbol,
|
|
3177
|
+
sourceDecimals: step.sourceDecimals,
|
|
3178
|
+
waitForFinalTx,
|
|
3179
|
+
service,
|
|
3180
|
+
directTransfer: step.directTransfer,
|
|
3181
|
+
onClose,
|
|
3182
|
+
onNewDeposit: handleNewDeposit,
|
|
3183
|
+
onDepositComplete: handleDepositComplete,
|
|
3184
|
+
onDepositFailed: handleDepositFailed,
|
|
3185
|
+
onError: handleError,
|
|
3186
|
+
debug
|
|
3187
|
+
}
|
|
3188
|
+
)
|
|
3189
|
+
] });
|
|
3190
|
+
}
|
|
3191
|
+
if (isSolanaWalletMode) {
|
|
3192
|
+
if (!sessionKeyAddress) return null;
|
|
3193
|
+
const solanaAddr = reownWallet?.solanaAddress;
|
|
3194
|
+
const solanaProvider = reownWallet?.solanaProvider;
|
|
3195
|
+
return /* @__PURE__ */ jsxs10("div", { className: "rs-modal-body", children: [
|
|
3196
|
+
step.type === "setup" && /* @__PURE__ */ jsx10(
|
|
3197
|
+
SetupStep,
|
|
3198
|
+
{
|
|
3199
|
+
address: sessionKeyAddress,
|
|
3200
|
+
targetChain,
|
|
3201
|
+
targetToken,
|
|
3202
|
+
signerAddress,
|
|
3203
|
+
sessionChainIds,
|
|
3204
|
+
recipient,
|
|
3205
|
+
forceRegister,
|
|
3206
|
+
service,
|
|
3207
|
+
onSetupComplete: handleSetupComplete,
|
|
3208
|
+
onConnected: handleConnected,
|
|
3209
|
+
onError: handleError
|
|
3210
|
+
}
|
|
3211
|
+
),
|
|
3212
|
+
step.type === "solana-token-select" && solanaAddr && /* @__PURE__ */ jsx10(
|
|
3213
|
+
SolanaTokenSelectStep,
|
|
3214
|
+
{
|
|
3215
|
+
solanaAddress: solanaAddr,
|
|
3216
|
+
service,
|
|
3217
|
+
onContinue: handleSolanaTokenContinue,
|
|
3218
|
+
onTotalBalanceComputed: handleTotalBalanceComputed,
|
|
3219
|
+
debug
|
|
3220
|
+
}
|
|
3221
|
+
),
|
|
3222
|
+
step.type === "solana-amount" && /* @__PURE__ */ jsx10(
|
|
3223
|
+
SolanaAmountStep,
|
|
3224
|
+
{
|
|
3225
|
+
token: step.token,
|
|
3226
|
+
balance: step.balance,
|
|
3227
|
+
balanceUsd: step.balanceUsd,
|
|
3228
|
+
onContinue: handleSolanaAmountContinue,
|
|
3229
|
+
debug
|
|
3230
|
+
}
|
|
3231
|
+
),
|
|
3232
|
+
step.type === "solana-confirm" && solanaAddr && solanaProvider ? /* @__PURE__ */ jsx10(
|
|
3233
|
+
SolanaConfirmStep,
|
|
3234
|
+
{
|
|
3235
|
+
smartAccount: step.smartAccount,
|
|
3236
|
+
solanaAddress: solanaAddr,
|
|
3237
|
+
solanaDepositAddress: step.solanaDepositAddress,
|
|
3238
|
+
token: step.token,
|
|
3239
|
+
amount: step.amount,
|
|
3240
|
+
targetAmount: step.targetAmount,
|
|
3241
|
+
targetTokenPriceUsd: step.targetTokenPriceUsd,
|
|
3242
|
+
targetChain,
|
|
3243
|
+
targetToken,
|
|
3244
|
+
service,
|
|
3245
|
+
solanaProvider,
|
|
3246
|
+
onConfirm: handleSolanaConfirmed,
|
|
3247
|
+
onError: handleError,
|
|
3248
|
+
debug
|
|
3249
|
+
}
|
|
3250
|
+
) : step.type === "solana-confirm" ? /* @__PURE__ */ jsxs10("div", { className: "rs-step", children: [
|
|
3251
|
+
/* @__PURE__ */ jsxs10("div", { className: "rs-loading-state", children: [
|
|
3252
|
+
/* @__PURE__ */ jsx10("div", { className: "rs-step-icon rs-step-icon--error", children: /* @__PURE__ */ jsx10(
|
|
3253
|
+
"svg",
|
|
3254
|
+
{
|
|
3255
|
+
viewBox: "0 0 24 24",
|
|
3256
|
+
fill: "none",
|
|
3257
|
+
stroke: "currentColor",
|
|
3258
|
+
strokeWidth: "2",
|
|
3259
|
+
children: /* @__PURE__ */ jsx10(
|
|
3260
|
+
"path",
|
|
3261
|
+
{
|
|
3262
|
+
strokeLinecap: "round",
|
|
3263
|
+
strokeLinejoin: "round",
|
|
3264
|
+
d: "M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z"
|
|
3265
|
+
}
|
|
3266
|
+
)
|
|
3267
|
+
}
|
|
3268
|
+
) }),
|
|
3269
|
+
/* @__PURE__ */ jsxs10("div", { className: "rs-loading-text", children: [
|
|
3270
|
+
/* @__PURE__ */ jsx10("div", { className: "rs-loading-title rs-text-error", children: "Wallet disconnected" }),
|
|
3271
|
+
/* @__PURE__ */ jsx10("div", { className: "rs-loading-subtitle", children: "Please reconnect your Solana wallet to continue." })
|
|
3272
|
+
] })
|
|
3273
|
+
] }),
|
|
3274
|
+
/* @__PURE__ */ jsx10("div", { className: "rs-step-footer", children: /* @__PURE__ */ jsx10(
|
|
3275
|
+
"button",
|
|
3276
|
+
{
|
|
3277
|
+
type: "button",
|
|
3278
|
+
className: "rs-button rs-button--default rs-button--full-width",
|
|
3279
|
+
onClick: handleBackFromSolanaConfirm,
|
|
3280
|
+
children: /* @__PURE__ */ jsx10("span", { children: "Go Back" })
|
|
3281
|
+
}
|
|
3282
|
+
) })
|
|
3283
|
+
] }) : null,
|
|
3284
|
+
step.type === "processing" && /* @__PURE__ */ jsx10(
|
|
2029
3285
|
ProcessingStep,
|
|
2030
3286
|
{
|
|
2031
3287
|
smartAccount: step.smartAccount,
|
|
@@ -2034,6 +3290,8 @@ function DepositFlow({
|
|
|
2034
3290
|
sourceToken: step.sourceToken,
|
|
2035
3291
|
targetChain,
|
|
2036
3292
|
amount: step.amount,
|
|
3293
|
+
sourceSymbol: step.sourceSymbol,
|
|
3294
|
+
sourceDecimals: step.sourceDecimals,
|
|
2037
3295
|
waitForFinalTx,
|
|
2038
3296
|
service,
|
|
2039
3297
|
directTransfer: step.directTransfer,
|
|
@@ -2048,7 +3306,7 @@ function DepositFlow({
|
|
|
2048
3306
|
] });
|
|
2049
3307
|
}
|
|
2050
3308
|
if (!signerContext?.walletClient || !signerContext?.publicClient) {
|
|
2051
|
-
return
|
|
3309
|
+
return /* @__PURE__ */ jsx10("div", { className: "rs-modal-body", children: /* @__PURE__ */ jsx10("div", { className: "rs-step", children: /* @__PURE__ */ jsx10("div", { className: "rs-loading-state", children: /* @__PURE__ */ jsx10("div", { className: "rs-loading-text", children: /* @__PURE__ */ jsx10("div", { className: "rs-loading-title", children: "Connecting wallet..." }) }) }) }) });
|
|
2052
3310
|
}
|
|
2053
3311
|
const ownerAddress = signerContext.ownerAddress;
|
|
2054
3312
|
const ownerChainId = signerContext.walletClient?.chain?.id ?? signerContext.publicClient.chain?.id ?? targetChain;
|
|
@@ -2058,8 +3316,8 @@ function DepositFlow({
|
|
|
2058
3316
|
}
|
|
2059
3317
|
return getPublicClient(chainId);
|
|
2060
3318
|
};
|
|
2061
|
-
return /* @__PURE__ */
|
|
2062
|
-
step.type === "setup" && /* @__PURE__ */
|
|
3319
|
+
return /* @__PURE__ */ jsxs10("div", { className: "rs-modal-body", children: [
|
|
3320
|
+
step.type === "setup" && /* @__PURE__ */ jsx10(
|
|
2063
3321
|
SetupStep,
|
|
2064
3322
|
{
|
|
2065
3323
|
walletClient: signerContext.walletClient,
|
|
@@ -2076,7 +3334,7 @@ function DepositFlow({
|
|
|
2076
3334
|
onError: handleError
|
|
2077
3335
|
}
|
|
2078
3336
|
),
|
|
2079
|
-
step.type === "select-asset" && /* @__PURE__ */
|
|
3337
|
+
step.type === "select-asset" && /* @__PURE__ */ jsx10(
|
|
2080
3338
|
AssetSelectStep,
|
|
2081
3339
|
{
|
|
2082
3340
|
address: ownerAddress,
|
|
@@ -2089,7 +3347,7 @@ function DepositFlow({
|
|
|
2089
3347
|
onAssetsLoaded: handleAssetsLoaded
|
|
2090
3348
|
}
|
|
2091
3349
|
),
|
|
2092
|
-
step.type === "amount" && /* @__PURE__ */
|
|
3350
|
+
step.type === "amount" && /* @__PURE__ */ jsx10(
|
|
2093
3351
|
AmountStep,
|
|
2094
3352
|
{
|
|
2095
3353
|
walletClient: signerContext.walletClient,
|
|
@@ -2104,7 +3362,7 @@ function DepositFlow({
|
|
|
2104
3362
|
onContinue: handleAmountContinue
|
|
2105
3363
|
}
|
|
2106
3364
|
),
|
|
2107
|
-
step.type === "confirm" && /* @__PURE__ */
|
|
3365
|
+
step.type === "confirm" && /* @__PURE__ */ jsx10(
|
|
2108
3366
|
ConfirmStep,
|
|
2109
3367
|
{
|
|
2110
3368
|
walletClient: signerContext.walletClient,
|
|
@@ -2124,7 +3382,7 @@ function DepositFlow({
|
|
|
2124
3382
|
onError: handleError
|
|
2125
3383
|
}
|
|
2126
3384
|
),
|
|
2127
|
-
step.type === "processing" && /* @__PURE__ */
|
|
3385
|
+
step.type === "processing" && /* @__PURE__ */ jsx10(
|
|
2128
3386
|
ProcessingStep,
|
|
2129
3387
|
{
|
|
2130
3388
|
smartAccount: step.smartAccount,
|
|
@@ -2133,6 +3391,8 @@ function DepositFlow({
|
|
|
2133
3391
|
sourceToken: step.sourceToken,
|
|
2134
3392
|
targetChain,
|
|
2135
3393
|
amount: step.amount,
|
|
3394
|
+
sourceSymbol: step.sourceSymbol,
|
|
3395
|
+
sourceDecimals: step.sourceDecimals,
|
|
2136
3396
|
waitForFinalTx,
|
|
2137
3397
|
service,
|
|
2138
3398
|
directTransfer: step.directTransfer,
|
|
@@ -2140,23 +3400,24 @@ function DepositFlow({
|
|
|
2140
3400
|
onNewDeposit: handleNewDeposit,
|
|
2141
3401
|
onDepositComplete: handleDepositComplete,
|
|
2142
3402
|
onDepositFailed: handleDepositFailed,
|
|
2143
|
-
onError: handleError
|
|
3403
|
+
onError: handleError,
|
|
3404
|
+
debug
|
|
2144
3405
|
}
|
|
2145
3406
|
)
|
|
2146
3407
|
] });
|
|
2147
3408
|
}
|
|
2148
3409
|
|
|
2149
3410
|
// src/DepositModal.tsx
|
|
2150
|
-
import { jsx as
|
|
3411
|
+
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2151
3412
|
var ReownDepositInner = lazy(
|
|
2152
|
-
() => import("./DepositModalReown-
|
|
3413
|
+
() => import("./DepositModalReown-3GPEVG26.mjs").then((m) => ({ default: m.DepositModalReown }))
|
|
2153
3414
|
);
|
|
2154
3415
|
function DepositModal(props) {
|
|
2155
3416
|
const needsReown = !!props.reownAppId;
|
|
2156
3417
|
if (needsReown) {
|
|
2157
|
-
return /* @__PURE__ */
|
|
3418
|
+
return /* @__PURE__ */ jsx11(Suspense, { fallback: null, children: /* @__PURE__ */ jsx11(ReownDepositInner, { ...props }) });
|
|
2158
3419
|
}
|
|
2159
|
-
return /* @__PURE__ */
|
|
3420
|
+
return /* @__PURE__ */ jsx11(DepositModalInner, { ...props });
|
|
2160
3421
|
}
|
|
2161
3422
|
DepositModal.displayName = "DepositModal";
|
|
2162
3423
|
function DepositModalInner({
|
|
@@ -2173,6 +3434,7 @@ function DepositModalInner({
|
|
|
2173
3434
|
defaultAmount,
|
|
2174
3435
|
recipient,
|
|
2175
3436
|
backendUrl = DEFAULT_BACKEND_URL,
|
|
3437
|
+
solanaRpcUrl,
|
|
2176
3438
|
signerAddress = DEFAULT_SIGNER_ADDRESS,
|
|
2177
3439
|
sessionChainIds,
|
|
2178
3440
|
forceRegister = false,
|
|
@@ -2195,30 +3457,36 @@ function DepositModalInner({
|
|
|
2195
3457
|
debug
|
|
2196
3458
|
}) {
|
|
2197
3459
|
const modalRef = useRef6(null);
|
|
2198
|
-
const [currentStepIndex, setCurrentStepIndex] =
|
|
2199
|
-
const [totalBalanceUsd, setTotalBalanceUsd] =
|
|
3460
|
+
const [currentStepIndex, setCurrentStepIndex] = useState11(0);
|
|
3461
|
+
const [totalBalanceUsd, setTotalBalanceUsd] = useState11(null);
|
|
2200
3462
|
const backHandlerRef = useRef6(void 0);
|
|
2201
3463
|
const targetChain = getChainId(targetChainProp);
|
|
2202
3464
|
const sourceChain = sourceChainProp ? getChainId(sourceChainProp) : void 0;
|
|
2203
|
-
const service =
|
|
2204
|
-
|
|
3465
|
+
const service = useMemo8(
|
|
3466
|
+
() => createDepositService(backendUrl, {
|
|
3467
|
+
debug,
|
|
3468
|
+
debugScope: "service:deposit"
|
|
3469
|
+
}),
|
|
3470
|
+
[backendUrl, debug]
|
|
3471
|
+
);
|
|
3472
|
+
useEffect9(() => {
|
|
2205
3473
|
if (isOpen && modalRef.current) {
|
|
2206
3474
|
applyTheme(modalRef.current, theme);
|
|
2207
3475
|
}
|
|
2208
3476
|
}, [isOpen, theme]);
|
|
3477
|
+
useEffect9(() => {
|
|
3478
|
+
configureSolanaRpcUrl(solanaRpcUrl);
|
|
3479
|
+
}, [solanaRpcUrl]);
|
|
2209
3480
|
const hasCalledReady = useRef6(false);
|
|
2210
|
-
|
|
3481
|
+
useEffect9(() => {
|
|
2211
3482
|
if (isOpen && !hasCalledReady.current) {
|
|
2212
3483
|
hasCalledReady.current = true;
|
|
2213
3484
|
onReady?.();
|
|
2214
3485
|
}
|
|
2215
3486
|
}, [isOpen, onReady]);
|
|
2216
|
-
|
|
3487
|
+
useEffect9(() => {
|
|
2217
3488
|
if (!isOpen) {
|
|
2218
3489
|
setCurrentStepIndex(0);
|
|
2219
|
-
setTotalBalanceUsd(null);
|
|
2220
|
-
backHandlerRef.current = void 0;
|
|
2221
|
-
hasCalledReady.current = false;
|
|
2222
3490
|
}
|
|
2223
3491
|
}, [isOpen]);
|
|
2224
3492
|
const handleStepChange = useCallback4(
|
|
@@ -2241,30 +3509,30 @@ function DepositModalInner({
|
|
|
2241
3509
|
const logoUrl = branding?.logoUrl ?? "https://github.com/rhinestonewtf.png";
|
|
2242
3510
|
const title = branding?.title ?? "Deposit";
|
|
2243
3511
|
const canGoBack = currentStepIndex > 0 && currentStepIndex < 4 && backHandlerRef.current !== void 0;
|
|
2244
|
-
return /* @__PURE__ */
|
|
3512
|
+
return /* @__PURE__ */ jsx11(
|
|
2245
3513
|
Modal,
|
|
2246
3514
|
{
|
|
2247
3515
|
isOpen,
|
|
2248
3516
|
onClose,
|
|
2249
3517
|
className,
|
|
2250
3518
|
inline,
|
|
2251
|
-
children: /* @__PURE__ */
|
|
2252
|
-
/* @__PURE__ */
|
|
2253
|
-
/* @__PURE__ */
|
|
3519
|
+
children: /* @__PURE__ */ jsxs11("div", { ref: modalRef, className: "rs-modal", children: [
|
|
3520
|
+
/* @__PURE__ */ jsxs11("div", { className: "rs-modal-header--redesigned", children: [
|
|
3521
|
+
/* @__PURE__ */ jsx11("div", { className: "rs-modal-header-nav-left", children: showBackButton && canGoBack && /* @__PURE__ */ jsx11(
|
|
2254
3522
|
"button",
|
|
2255
3523
|
{
|
|
2256
3524
|
type: "button",
|
|
2257
3525
|
className: "rs-modal-header-back",
|
|
2258
3526
|
"aria-label": "Go back",
|
|
2259
3527
|
onClick: handleBack,
|
|
2260
|
-
children: /* @__PURE__ */
|
|
3528
|
+
children: /* @__PURE__ */ jsx11(
|
|
2261
3529
|
"svg",
|
|
2262
3530
|
{
|
|
2263
3531
|
viewBox: "0 0 24 24",
|
|
2264
3532
|
fill: "none",
|
|
2265
3533
|
stroke: "currentColor",
|
|
2266
3534
|
strokeWidth: "2",
|
|
2267
|
-
children: /* @__PURE__ */
|
|
3535
|
+
children: /* @__PURE__ */ jsx11(
|
|
2268
3536
|
"path",
|
|
2269
3537
|
{
|
|
2270
3538
|
strokeLinecap: "round",
|
|
@@ -2276,9 +3544,9 @@ function DepositModalInner({
|
|
|
2276
3544
|
)
|
|
2277
3545
|
}
|
|
2278
3546
|
) }),
|
|
2279
|
-
/* @__PURE__ */
|
|
2280
|
-
/* @__PURE__ */
|
|
2281
|
-
showLogo && logoUrl && /* @__PURE__ */
|
|
3547
|
+
/* @__PURE__ */ jsxs11("div", { className: "rs-modal-header-nav-center", children: [
|
|
3548
|
+
/* @__PURE__ */ jsxs11("div", { className: "rs-modal-header-title-row", children: [
|
|
3549
|
+
showLogo && logoUrl && /* @__PURE__ */ jsx11(
|
|
2282
3550
|
"img",
|
|
2283
3551
|
{
|
|
2284
3552
|
src: logoUrl,
|
|
@@ -2289,8 +3557,8 @@ function DepositModalInner({
|
|
|
2289
3557
|
}
|
|
2290
3558
|
}
|
|
2291
3559
|
),
|
|
2292
|
-
/* @__PURE__ */
|
|
2293
|
-
showStepper && /* @__PURE__ */
|
|
3560
|
+
/* @__PURE__ */ jsx11("span", { className: "rs-modal-header-title", children: title }),
|
|
3561
|
+
showStepper && /* @__PURE__ */ jsx11("div", { className: "rs-modal-progress", style: { marginLeft: 8 }, children: [0, 1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx11(
|
|
2294
3562
|
"div",
|
|
2295
3563
|
{
|
|
2296
3564
|
className: `rs-modal-progress-dot ${i <= currentStepIndex ? "rs-modal-progress-dot--active" : "rs-modal-progress-dot--inactive"}`
|
|
@@ -2298,29 +3566,29 @@ function DepositModalInner({
|
|
|
2298
3566
|
i
|
|
2299
3567
|
)) })
|
|
2300
3568
|
] }),
|
|
2301
|
-
balance && /* @__PURE__ */
|
|
2302
|
-
/* @__PURE__ */
|
|
3569
|
+
balance && /* @__PURE__ */ jsxs11("div", { className: "rs-modal-header-balance", children: [
|
|
3570
|
+
/* @__PURE__ */ jsxs11("span", { children: [
|
|
2303
3571
|
balance.title,
|
|
2304
3572
|
":"
|
|
2305
3573
|
] }),
|
|
2306
|
-
/* @__PURE__ */
|
|
3574
|
+
/* @__PURE__ */ jsx11("span", { className: "rs-modal-header-balance-value", children: balance.amount ?? (totalBalanceUsd !== null ? currencyFormatter.format(totalBalanceUsd) : null) })
|
|
2307
3575
|
] })
|
|
2308
3576
|
] }),
|
|
2309
|
-
/* @__PURE__ */
|
|
3577
|
+
/* @__PURE__ */ jsx11("div", { className: "rs-modal-header-nav-right", children: /* @__PURE__ */ jsx11(
|
|
2310
3578
|
"button",
|
|
2311
3579
|
{
|
|
2312
3580
|
type: "button",
|
|
2313
3581
|
onClick: onClose,
|
|
2314
3582
|
className: "rs-modal-close",
|
|
2315
3583
|
"aria-label": "Close",
|
|
2316
|
-
children: /* @__PURE__ */
|
|
3584
|
+
children: /* @__PURE__ */ jsx11(
|
|
2317
3585
|
"svg",
|
|
2318
3586
|
{
|
|
2319
3587
|
viewBox: "0 0 24 24",
|
|
2320
3588
|
fill: "none",
|
|
2321
3589
|
stroke: "currentColor",
|
|
2322
3590
|
strokeWidth: "2",
|
|
2323
|
-
children: /* @__PURE__ */
|
|
3591
|
+
children: /* @__PURE__ */ jsx11(
|
|
2324
3592
|
"path",
|
|
2325
3593
|
{
|
|
2326
3594
|
strokeLinecap: "round",
|
|
@@ -2333,7 +3601,7 @@ function DepositModalInner({
|
|
|
2333
3601
|
}
|
|
2334
3602
|
) })
|
|
2335
3603
|
] }),
|
|
2336
|
-
/* @__PURE__ */
|
|
3604
|
+
/* @__PURE__ */ jsx11(
|
|
2337
3605
|
DepositFlow,
|
|
2338
3606
|
{
|
|
2339
3607
|
dappWalletClient,
|