@swype-org/react-sdk 0.1.301 → 0.1.329
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 +19 -0
- package/dist/index.cjs +1005 -335
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -9
- package/dist/index.d.ts +59 -9
- package/dist/index.js +1004 -337
- package/dist/index.js.map +1 -1
- package/package.json +11 -3
package/dist/index.cjs
CHANGED
|
@@ -78,14 +78,16 @@ function getTheme(mode) {
|
|
|
78
78
|
}
|
|
79
79
|
var BLINK_PRIVY_APP_ID = "cmlil87uv004n0ck0blwumwek";
|
|
80
80
|
var wagmiConfig = wagmi.createConfig({
|
|
81
|
-
|
|
81
|
+
// baseSepolia: guest/testnet flows (e.g. smokebox e2e) call switchChain to the source chain from the API.
|
|
82
|
+
chains: [chains.mainnet, chains.arbitrum, chains.base, chains.polygon, chains.bsc, chains.baseSepolia],
|
|
82
83
|
connectors: [connectors.injected({ shimDisconnect: true, unstable_shimAsyncInject: 2e3 })],
|
|
83
84
|
transports: {
|
|
84
85
|
[chains.mainnet.id]: wagmi.http(),
|
|
85
86
|
[chains.arbitrum.id]: wagmi.http(),
|
|
86
87
|
[chains.base.id]: wagmi.http(),
|
|
87
88
|
[chains.polygon.id]: wagmi.http(),
|
|
88
|
-
[chains.bsc.id]: wagmi.http()
|
|
89
|
+
[chains.bsc.id]: wagmi.http(),
|
|
90
|
+
[chains.baseSepolia.id]: wagmi.http()
|
|
89
91
|
}
|
|
90
92
|
});
|
|
91
93
|
var BlinkContext = react.createContext(null);
|
|
@@ -495,6 +497,7 @@ __export(api_exports, {
|
|
|
495
497
|
getGuestTransfer: () => getGuestTransfer,
|
|
496
498
|
getTransferByGuestToken: () => getTransferByGuestToken,
|
|
497
499
|
postGuestTransferFeeQuote: () => postGuestTransferFeeQuote,
|
|
500
|
+
postTransferQuote: () => postTransferQuote,
|
|
498
501
|
putGuestTransferSender: () => putGuestTransferSender,
|
|
499
502
|
registerPasskey: () => registerPasskey,
|
|
500
503
|
reportActionCompletion: () => reportActionCompletion,
|
|
@@ -610,7 +613,8 @@ async function createTransfer(apiBaseUrl, token, params) {
|
|
|
610
613
|
amount: {
|
|
611
614
|
amount: params.amount,
|
|
612
615
|
currency: params.currency ?? "USD"
|
|
613
|
-
}
|
|
616
|
+
},
|
|
617
|
+
...params.quoteId ? { quoteId: params.quoteId } : {}
|
|
614
618
|
};
|
|
615
619
|
const res = await fetch(`${apiBaseUrl}/v1/transfers`, {
|
|
616
620
|
method: "POST",
|
|
@@ -623,6 +627,28 @@ async function createTransfer(apiBaseUrl, token, params) {
|
|
|
623
627
|
if (!res.ok) await throwApiError(res);
|
|
624
628
|
return await res.json();
|
|
625
629
|
}
|
|
630
|
+
async function postTransferQuote(apiBaseUrl, bearerToken, params) {
|
|
631
|
+
const body = {
|
|
632
|
+
walletId: params.walletId,
|
|
633
|
+
...params.sourceTokenAddress ? { sourceTokenAddress: params.sourceTokenAddress } : {},
|
|
634
|
+
destination: {
|
|
635
|
+
chainId: params.destination.chainId,
|
|
636
|
+
token: { address: params.destination.token.address },
|
|
637
|
+
address: params.destination.address
|
|
638
|
+
},
|
|
639
|
+
amount: params.amount
|
|
640
|
+
};
|
|
641
|
+
const res = await fetch(`${apiBaseUrl}/v1/transfers/quotes`, {
|
|
642
|
+
method: "POST",
|
|
643
|
+
headers: {
|
|
644
|
+
"Content-Type": "application/json",
|
|
645
|
+
Authorization: `Bearer ${bearerToken}`
|
|
646
|
+
},
|
|
647
|
+
body: JSON.stringify(body)
|
|
648
|
+
});
|
|
649
|
+
if (!res.ok) await throwApiError(res);
|
|
650
|
+
return await res.json();
|
|
651
|
+
}
|
|
626
652
|
async function fetchMerchantPublicKey(apiBaseUrl, merchantId) {
|
|
627
653
|
const res = await fetch(
|
|
628
654
|
`${apiBaseUrl}/v1/merchants/${encodeURIComponent(merchantId)}/public-key`
|
|
@@ -964,6 +990,23 @@ function normalizeSignature(sig) {
|
|
|
964
990
|
);
|
|
965
991
|
}
|
|
966
992
|
|
|
993
|
+
// src/authorizationErrors.ts
|
|
994
|
+
var AuthorizationSessionCancelledError = class extends Error {
|
|
995
|
+
constructor() {
|
|
996
|
+
super("Authorization session cancelled");
|
|
997
|
+
this.name = "AuthorizationSessionCancelledError";
|
|
998
|
+
}
|
|
999
|
+
};
|
|
1000
|
+
function isAuthorizationSessionCancelled(err) {
|
|
1001
|
+
if (err instanceof AuthorizationSessionCancelledError) return true;
|
|
1002
|
+
return typeof err === "object" && err !== null && "name" in err && err.name === "AuthorizationSessionCancelledError";
|
|
1003
|
+
}
|
|
1004
|
+
function isUserDismissedAuthorizationError(err) {
|
|
1005
|
+
if (!(err instanceof Error)) return false;
|
|
1006
|
+
const m = err.message.toLowerCase();
|
|
1007
|
+
return m.includes("authorization session aborted") || m.includes("aborted by user");
|
|
1008
|
+
}
|
|
1009
|
+
|
|
967
1010
|
// src/hooks/authorizationExecutor.ts
|
|
968
1011
|
var WALLET_CLIENT_MAX_ATTEMPTS = 25;
|
|
969
1012
|
var WALLET_CLIENT_POLL_MS = 400;
|
|
@@ -1277,39 +1320,80 @@ function useAuthorizationExecutor(options) {
|
|
|
1277
1320
|
const [error, setError] = react.useState(null);
|
|
1278
1321
|
const [currentAction, setCurrentAction] = react.useState(null);
|
|
1279
1322
|
const executingRef = react.useRef(false);
|
|
1323
|
+
const oneTapPauseActiveRef = react.useRef(false);
|
|
1324
|
+
const sessionStackRef = react.useRef([]);
|
|
1325
|
+
const [authorizationSessionStackDepth, setAuthorizationSessionStackDepth] = react.useState(0);
|
|
1280
1326
|
const [pendingSelectSource, setPendingSelectSource] = react.useState(null);
|
|
1281
1327
|
const selectSourceResolverRef = react.useRef(null);
|
|
1328
|
+
const selectSourceRejectRef = react.useRef(null);
|
|
1282
1329
|
const sessionIdRef = react.useRef(null);
|
|
1283
1330
|
const resolveSelectSource = react.useCallback((selection) => {
|
|
1284
1331
|
if (selectSourceResolverRef.current) {
|
|
1285
1332
|
selectSourceResolverRef.current(selection);
|
|
1286
1333
|
selectSourceResolverRef.current = null;
|
|
1334
|
+
selectSourceRejectRef.current = null;
|
|
1287
1335
|
setPendingSelectSource(null);
|
|
1288
1336
|
}
|
|
1289
1337
|
}, []);
|
|
1290
1338
|
const waitForSelection = react.useCallback(
|
|
1291
|
-
(action) => new Promise((resolve) => {
|
|
1292
|
-
selectSourceResolverRef.current =
|
|
1339
|
+
(action) => new Promise((resolve, reject) => {
|
|
1340
|
+
selectSourceResolverRef.current = (selection) => {
|
|
1341
|
+
resolve(selection);
|
|
1342
|
+
selectSourceResolverRef.current = null;
|
|
1343
|
+
selectSourceRejectRef.current = null;
|
|
1344
|
+
};
|
|
1345
|
+
selectSourceRejectRef.current = reject;
|
|
1293
1346
|
setPendingSelectSource(action);
|
|
1294
1347
|
}),
|
|
1295
1348
|
[]
|
|
1296
1349
|
);
|
|
1297
1350
|
const [pendingOneTapSetup, setPendingOneTapSetup] = react.useState(null);
|
|
1298
1351
|
const oneTapSetupResolverRef = react.useRef(null);
|
|
1352
|
+
const oneTapSetupRejectRef = react.useRef(null);
|
|
1299
1353
|
const resolveOneTapSetup = react.useCallback(() => {
|
|
1300
1354
|
if (oneTapSetupResolverRef.current) {
|
|
1301
1355
|
oneTapSetupResolverRef.current();
|
|
1302
1356
|
oneTapSetupResolverRef.current = null;
|
|
1357
|
+
oneTapSetupRejectRef.current = null;
|
|
1303
1358
|
setPendingOneTapSetup(null);
|
|
1304
1359
|
}
|
|
1305
1360
|
}, []);
|
|
1306
1361
|
const waitForOneTapSetup = react.useCallback(
|
|
1307
|
-
(action) => new Promise((resolve) => {
|
|
1308
|
-
|
|
1362
|
+
(action) => new Promise((resolve, reject) => {
|
|
1363
|
+
oneTapPauseActiveRef.current = true;
|
|
1364
|
+
oneTapSetupResolverRef.current = () => {
|
|
1365
|
+
oneTapPauseActiveRef.current = false;
|
|
1366
|
+
resolve();
|
|
1367
|
+
oneTapSetupResolverRef.current = null;
|
|
1368
|
+
oneTapSetupRejectRef.current = null;
|
|
1369
|
+
};
|
|
1370
|
+
oneTapSetupRejectRef.current = (reason) => {
|
|
1371
|
+
oneTapPauseActiveRef.current = false;
|
|
1372
|
+
reject(reason);
|
|
1373
|
+
};
|
|
1309
1374
|
setPendingOneTapSetup(action);
|
|
1310
1375
|
}),
|
|
1311
1376
|
[]
|
|
1312
1377
|
);
|
|
1378
|
+
const cancelPendingExecution = react.useCallback(() => {
|
|
1379
|
+
if (selectSourceRejectRef.current) {
|
|
1380
|
+
selectSourceRejectRef.current(new AuthorizationSessionCancelledError());
|
|
1381
|
+
selectSourceRejectRef.current = null;
|
|
1382
|
+
selectSourceResolverRef.current = null;
|
|
1383
|
+
setPendingSelectSource(null);
|
|
1384
|
+
}
|
|
1385
|
+
if (oneTapSetupRejectRef.current) {
|
|
1386
|
+
oneTapPauseActiveRef.current = false;
|
|
1387
|
+
oneTapSetupRejectRef.current(new AuthorizationSessionCancelledError());
|
|
1388
|
+
oneTapSetupRejectRef.current = null;
|
|
1389
|
+
oneTapSetupResolverRef.current = null;
|
|
1390
|
+
setPendingOneTapSetup(null);
|
|
1391
|
+
}
|
|
1392
|
+
setError(null);
|
|
1393
|
+
setCurrentAction(null);
|
|
1394
|
+
setExecuting(false);
|
|
1395
|
+
executingRef.current = false;
|
|
1396
|
+
}, []);
|
|
1313
1397
|
const dispatchAction = react.useCallback(
|
|
1314
1398
|
async (action) => {
|
|
1315
1399
|
setCurrentAction(action);
|
|
@@ -1344,20 +1428,26 @@ function useAuthorizationExecutor(options) {
|
|
|
1344
1428
|
);
|
|
1345
1429
|
const executeSessionById = react.useCallback(
|
|
1346
1430
|
async (sessionId) => {
|
|
1347
|
-
if (executingRef.current) return;
|
|
1348
|
-
executingRef.current = true;
|
|
1349
1431
|
if (!sessionId) {
|
|
1350
|
-
executingRef.current = false;
|
|
1351
1432
|
throw new Error("No authorization session id provided.");
|
|
1352
1433
|
}
|
|
1353
1434
|
if (!apiBaseUrl) {
|
|
1354
|
-
executingRef.current = false;
|
|
1355
1435
|
throw new Error("Missing apiBaseUrl. Provide useAuthorizationExecutor({ apiBaseUrl }) or wrap in <BlinkProvider>.");
|
|
1356
1436
|
}
|
|
1357
|
-
|
|
1358
|
-
|
|
1437
|
+
const allowNested = executingRef.current && oneTapPauseActiveRef.current;
|
|
1438
|
+
if (executingRef.current && !allowNested) {
|
|
1439
|
+
return;
|
|
1440
|
+
}
|
|
1441
|
+
const isNestedRun = allowNested;
|
|
1442
|
+
if (!isNestedRun) {
|
|
1443
|
+
executingRef.current = true;
|
|
1444
|
+
setExecuting(true);
|
|
1445
|
+
setResults([]);
|
|
1446
|
+
}
|
|
1359
1447
|
setError(null);
|
|
1360
|
-
|
|
1448
|
+
sessionStackRef.current.push(sessionId);
|
|
1449
|
+
setAuthorizationSessionStackDepth(sessionStackRef.current.length);
|
|
1450
|
+
sessionIdRef.current = sessionId;
|
|
1361
1451
|
try {
|
|
1362
1452
|
let session = await fetchAuthorizationSession(apiBaseUrl, sessionId);
|
|
1363
1453
|
const allResults = [];
|
|
@@ -1393,13 +1483,23 @@ function useAuthorizationExecutor(options) {
|
|
|
1393
1483
|
pending = getPendingActions(session, completedIds);
|
|
1394
1484
|
}
|
|
1395
1485
|
} catch (err) {
|
|
1396
|
-
|
|
1397
|
-
|
|
1486
|
+
if (isAuthorizationSessionCancelled(err)) {
|
|
1487
|
+
setError(null);
|
|
1488
|
+
} else {
|
|
1489
|
+
const msg = err instanceof Error ? err.message : "Authorization failed";
|
|
1490
|
+
setError(msg);
|
|
1491
|
+
}
|
|
1398
1492
|
throw err;
|
|
1399
1493
|
} finally {
|
|
1494
|
+
sessionStackRef.current.pop();
|
|
1495
|
+
const depth = sessionStackRef.current.length;
|
|
1496
|
+
setAuthorizationSessionStackDepth(depth);
|
|
1497
|
+
sessionIdRef.current = depth > 0 ? sessionStackRef.current[depth - 1] : null;
|
|
1400
1498
|
setCurrentAction(null);
|
|
1401
|
-
|
|
1402
|
-
|
|
1499
|
+
if (depth === 0) {
|
|
1500
|
+
setExecuting(false);
|
|
1501
|
+
executingRef.current = false;
|
|
1502
|
+
}
|
|
1403
1503
|
}
|
|
1404
1504
|
},
|
|
1405
1505
|
[apiBaseUrl, dispatchAction]
|
|
@@ -1413,7 +1513,9 @@ function useAuthorizationExecutor(options) {
|
|
|
1413
1513
|
resolveSelectSource,
|
|
1414
1514
|
pendingOneTapSetup,
|
|
1415
1515
|
resolveOneTapSetup,
|
|
1416
|
-
executeSessionById
|
|
1516
|
+
executeSessionById,
|
|
1517
|
+
cancelPendingExecution,
|
|
1518
|
+
authorizationSessionStackDepth
|
|
1417
1519
|
};
|
|
1418
1520
|
}
|
|
1419
1521
|
var TRANSFER_SIGN_MAX_POLLS = 60;
|
|
@@ -1643,6 +1745,37 @@ function getPreferredDepositWallet(account, transferAmount) {
|
|
|
1643
1745
|
function getDepositEligibleAccounts(accounts) {
|
|
1644
1746
|
return accounts.filter((account) => getAddressableWallets(account).length > 0);
|
|
1645
1747
|
}
|
|
1748
|
+
function resolveDepositSelectionAfterRefresh(accounts, transferAmount, prev) {
|
|
1749
|
+
const { selectedAccountId, selectedWalletId, selectedTokenSymbol } = prev;
|
|
1750
|
+
if (selectedAccountId && selectedWalletId) {
|
|
1751
|
+
const acct = accounts.find((a) => a.id === selectedAccountId);
|
|
1752
|
+
const wallet = acct?.wallets.find((w) => w.id === selectedWalletId);
|
|
1753
|
+
if (wallet) {
|
|
1754
|
+
if (selectedTokenSymbol) {
|
|
1755
|
+
const hasToken = wallet.sources.some((s) => s.token.symbol === selectedTokenSymbol);
|
|
1756
|
+
if (hasToken) {
|
|
1757
|
+
return {
|
|
1758
|
+
defaults: { accountId: selectedAccountId, walletId: selectedWalletId },
|
|
1759
|
+
resetSelectedTokenSymbol: false
|
|
1760
|
+
};
|
|
1761
|
+
}
|
|
1762
|
+
const fallback = resolveDepositSelection(accounts, transferAmount, selectedAccountId);
|
|
1763
|
+
return {
|
|
1764
|
+
defaults: fallback,
|
|
1765
|
+
resetSelectedTokenSymbol: true
|
|
1766
|
+
};
|
|
1767
|
+
}
|
|
1768
|
+
return {
|
|
1769
|
+
defaults: { accountId: selectedAccountId, walletId: selectedWalletId },
|
|
1770
|
+
resetSelectedTokenSymbol: false
|
|
1771
|
+
};
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
return {
|
|
1775
|
+
defaults: resolveDepositSelection(accounts, transferAmount, selectedAccountId),
|
|
1776
|
+
resetSelectedTokenSymbol: false
|
|
1777
|
+
};
|
|
1778
|
+
}
|
|
1646
1779
|
function resolveDepositSelection(accounts, transferAmount, selectedAccountId) {
|
|
1647
1780
|
const eligibleAccounts = getDepositEligibleAccounts(accounts);
|
|
1648
1781
|
if (eligibleAccounts.length === 0) return null;
|
|
@@ -1709,6 +1842,32 @@ function buildSelectSourceChoices(options) {
|
|
|
1709
1842
|
tokens: chain.tokens.filter((t) => t.balance > 0).sort((a, b) => b.balance - a.balance)
|
|
1710
1843
|
})).filter((chain) => chain.tokens.length > 0).sort((a, b) => b.balance - a.balance);
|
|
1711
1844
|
}
|
|
1845
|
+
function resolveSelectSourceAvailableBalance(choices, options, chainName, tokenSymbol, recommended) {
|
|
1846
|
+
const chain = chainName.trim();
|
|
1847
|
+
const token = tokenSymbol.trim();
|
|
1848
|
+
if (chain && token) {
|
|
1849
|
+
const chainChoice = choices.find((c) => c.chainName === chain);
|
|
1850
|
+
const row = chainChoice?.tokens.find((t) => t.tokenSymbol === token);
|
|
1851
|
+
if (row !== void 0) return row.balance;
|
|
1852
|
+
const direct = options.find(
|
|
1853
|
+
(opt) => opt.chainName === chain && opt.tokenSymbol === token
|
|
1854
|
+
);
|
|
1855
|
+
if (direct) return parseRawBalance(direct.rawBalance, direct.decimals);
|
|
1856
|
+
return 0;
|
|
1857
|
+
}
|
|
1858
|
+
if (recommended) {
|
|
1859
|
+
const match = options.find(
|
|
1860
|
+
(opt) => opt.chainName === recommended.chainName && opt.tokenSymbol === recommended.tokenSymbol
|
|
1861
|
+
);
|
|
1862
|
+
if (match) return parseRawBalance(match.rawBalance, match.decimals);
|
|
1863
|
+
}
|
|
1864
|
+
let max = 0;
|
|
1865
|
+
for (const opt of options) {
|
|
1866
|
+
const bal = parseRawBalance(opt.rawBalance, opt.decimals);
|
|
1867
|
+
if (bal > max) max = bal;
|
|
1868
|
+
}
|
|
1869
|
+
return max;
|
|
1870
|
+
}
|
|
1712
1871
|
|
|
1713
1872
|
// src/walletFlow.ts
|
|
1714
1873
|
var MOBILE_USER_AGENT_PATTERN = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
|
|
@@ -1793,10 +1952,11 @@ function resolvePhase(state) {
|
|
|
1793
1952
|
const walletPickerSwitchEligible = currentPhase.step === "wallet-picker" && currentPhase.reason === "switch" && !state.creatingTransfer && !(state.mobileFlow && state.deeplinkUri);
|
|
1794
1953
|
const missingActivePasskeyCredential = state.passkeyConfigLoaded && !state.activeCredentialId;
|
|
1795
1954
|
const shouldPromptPasskeyVerification = missingActivePasskeyCredential && state.knownCredentialIds.length > 0 && state.passkeyPopupNeeded;
|
|
1955
|
+
const guestPreauthClaimPending = state.guestPreauthAccountId != null && state.guestSessionToken != null && state.privyAuthenticated && state.activeCredentialId != null && !state.guestPreauthSetupCompletePending && !state.error;
|
|
1796
1956
|
const branchGuestSetupComplete = state.guestPreauthSetupCompletePending && state.privyReady && state.privyAuthenticated;
|
|
1797
1957
|
const branchKeepGuestPreauthPin = !branchGuestSetupComplete && guestPreauthPinsCurrentPhase;
|
|
1798
1958
|
const branchGuestPostPayLogin = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && guestPostPayLogin;
|
|
1799
|
-
const branchCompleted = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && transferCompleted && !state.verificationTarget && !needsPasskeyBootstrap;
|
|
1959
|
+
const branchCompleted = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && transferCompleted && !state.verificationTarget && !needsPasskeyBootstrap && !guestPreauthClaimPending && !state.loginRequested;
|
|
1800
1960
|
const branchFailed = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && state.transfer?.status === "FAILED";
|
|
1801
1961
|
const branchProcessing = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && (state.creatingTransfer || isTransferAwaitingCompletion(state.transfer));
|
|
1802
1962
|
const branchStandardDesktopInlineOpenWallet = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && state.standardDesktopInlineOpenWallet && state.privyAuthenticated && state.activeCredentialId != null && state.selectedAccountId != null && !state.loginRequested && !state.guestPreauthorizing;
|
|
@@ -1812,7 +1972,7 @@ function resolvePhase(state) {
|
|
|
1812
1972
|
const branchLoginRequested = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && state.loginRequested;
|
|
1813
1973
|
const branchPasskeyVerify = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && shouldPromptPasskeyVerification;
|
|
1814
1974
|
const branchPasskeyCreate = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && !branchPasskeyVerify && missingActivePasskeyCredential;
|
|
1815
|
-
const branchGuestPreauthClaiming = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && !branchPasskeyVerify && !branchPasskeyCreate &&
|
|
1975
|
+
const branchGuestPreauthClaiming = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && !branchPasskeyVerify && !branchPasskeyCreate && guestPreauthClaimPending;
|
|
1816
1976
|
const branchDataLoading = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && !branchPasskeyVerify && !branchPasskeyCreate && !branchGuestPreauthClaiming && state.loadingData && state.activeCredentialId != null && hasActiveWallet(state.accounts);
|
|
1817
1977
|
const branchWalletPickerLink = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && !branchPasskeyVerify && !branchPasskeyCreate && !branchGuestPreauthClaiming && !branchDataLoading && state.activeCredentialId != null && !hasActiveWallet(state.accounts) && !state.mobileFlow;
|
|
1818
1978
|
const branchDeposit = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && !branchPasskeyVerify && !branchPasskeyCreate && !branchGuestPreauthClaiming && !branchDataLoading && !branchWalletPickerLink && state.activeCredentialId != null && hasActiveWallet(state.accounts) && !state.loadingData;
|
|
@@ -1983,6 +2143,7 @@ function createInitialState(config) {
|
|
|
1983
2143
|
selectedAccountId: null,
|
|
1984
2144
|
selectedWalletId: null,
|
|
1985
2145
|
selectedTokenSymbol: null,
|
|
2146
|
+
savedSelection: null,
|
|
1986
2147
|
amount: config.depositAmount != null ? config.depositAmount.toString() : "",
|
|
1987
2148
|
transfer: null,
|
|
1988
2149
|
creatingTransfer: false,
|
|
@@ -2009,7 +2170,8 @@ function createInitialState(config) {
|
|
|
2009
2170
|
standardDesktopInlineOpenWallet: false,
|
|
2010
2171
|
guestPreauthSetupCompletePending: false,
|
|
2011
2172
|
privyReady: false,
|
|
2012
|
-
privyAuthenticated: false
|
|
2173
|
+
privyAuthenticated: false,
|
|
2174
|
+
lastResumedAt: 0
|
|
2013
2175
|
};
|
|
2014
2176
|
}
|
|
2015
2177
|
function paymentReducer(state, action) {
|
|
@@ -2107,6 +2269,9 @@ function applyAction(state, action) {
|
|
|
2107
2269
|
next.mobileFlow = false;
|
|
2108
2270
|
next.deeplinkUri = null;
|
|
2109
2271
|
}
|
|
2272
|
+
if (action.resetSelectedTokenSymbol) {
|
|
2273
|
+
next.selectedTokenSymbol = null;
|
|
2274
|
+
}
|
|
2110
2275
|
return next;
|
|
2111
2276
|
}
|
|
2112
2277
|
case "DATA_LOAD_END":
|
|
@@ -2121,8 +2286,43 @@ function applyAction(state, action) {
|
|
|
2121
2286
|
next.selectedAccountId = action.defaults.accountId;
|
|
2122
2287
|
next.selectedWalletId = action.defaults.walletId;
|
|
2123
2288
|
}
|
|
2289
|
+
if (action.resetSelectedTokenSymbol) {
|
|
2290
|
+
next.selectedTokenSymbol = null;
|
|
2291
|
+
}
|
|
2124
2292
|
return next;
|
|
2125
2293
|
}
|
|
2294
|
+
case "SAVE_SELECTION":
|
|
2295
|
+
return {
|
|
2296
|
+
...state,
|
|
2297
|
+
savedSelection: {
|
|
2298
|
+
selectedProviderId: state.selectedProviderId,
|
|
2299
|
+
selectedAccountId: state.selectedAccountId,
|
|
2300
|
+
selectedWalletId: state.selectedWalletId,
|
|
2301
|
+
selectedTokenSymbol: state.selectedTokenSymbol
|
|
2302
|
+
}
|
|
2303
|
+
};
|
|
2304
|
+
case "RESTORE_SELECTION": {
|
|
2305
|
+
const snap = state.savedSelection;
|
|
2306
|
+
if (!snap) {
|
|
2307
|
+
return {
|
|
2308
|
+
...state,
|
|
2309
|
+
error: null,
|
|
2310
|
+
increasingLimit: false
|
|
2311
|
+
};
|
|
2312
|
+
}
|
|
2313
|
+
return {
|
|
2314
|
+
...state,
|
|
2315
|
+
selectedProviderId: snap.selectedProviderId,
|
|
2316
|
+
selectedAccountId: snap.selectedAccountId,
|
|
2317
|
+
selectedWalletId: snap.selectedWalletId,
|
|
2318
|
+
selectedTokenSymbol: snap.selectedTokenSymbol,
|
|
2319
|
+
savedSelection: null,
|
|
2320
|
+
error: null,
|
|
2321
|
+
increasingLimit: false
|
|
2322
|
+
};
|
|
2323
|
+
}
|
|
2324
|
+
case "DISCARD_SAVED_SELECTION":
|
|
2325
|
+
return { ...state, savedSelection: null };
|
|
2126
2326
|
// ── Source selection ──────────────────────────────────────────
|
|
2127
2327
|
case "SELECT_PROVIDER":
|
|
2128
2328
|
return {
|
|
@@ -2417,7 +2617,8 @@ function applyAction(state, action) {
|
|
|
2417
2617
|
oneTapLimitSavedDuringSetup: false,
|
|
2418
2618
|
guestPreauthorizing: false,
|
|
2419
2619
|
guestPreauthSetupCompletePending: false,
|
|
2420
|
-
standardDesktopInlineOpenWallet: false
|
|
2620
|
+
standardDesktopInlineOpenWallet: false,
|
|
2621
|
+
savedSelection: null
|
|
2421
2622
|
};
|
|
2422
2623
|
case "LOGOUT":
|
|
2423
2624
|
return {
|
|
@@ -2440,6 +2641,8 @@ function applyAction(state, action) {
|
|
|
2440
2641
|
};
|
|
2441
2642
|
case "SYNC_AMOUNT":
|
|
2442
2643
|
return { ...state, amount: action.amount };
|
|
2644
|
+
case "PAGE_RESUMED":
|
|
2645
|
+
return { ...state, lastResumedAt: Date.now() };
|
|
2443
2646
|
default:
|
|
2444
2647
|
return state;
|
|
2445
2648
|
}
|
|
@@ -2529,6 +2732,41 @@ function screenForPhase(phase) {
|
|
|
2529
2732
|
return "guest-preauth-linking";
|
|
2530
2733
|
}
|
|
2531
2734
|
}
|
|
2735
|
+
|
|
2736
|
+
// src/depositTokenSelection.ts
|
|
2737
|
+
function tokenOptionsForLinkedAccount(selectedAccount, chains) {
|
|
2738
|
+
if (!selectedAccount) return [];
|
|
2739
|
+
return selectedAccount.wallets.flatMap((w) => {
|
|
2740
|
+
const evmChainId = chains.find((c) => c.name === w.chain.name)?.commonId ?? void 0;
|
|
2741
|
+
return w.sources.filter((s) => s.balance.total.amount > 0).map((s) => ({
|
|
2742
|
+
symbol: s.token.symbol,
|
|
2743
|
+
chainName: w.chain.name,
|
|
2744
|
+
balance: s.balance.available.amount,
|
|
2745
|
+
walletId: w.id,
|
|
2746
|
+
status: s.token.status,
|
|
2747
|
+
tokenAddress: s.address,
|
|
2748
|
+
chainId: evmChainId
|
|
2749
|
+
}));
|
|
2750
|
+
});
|
|
2751
|
+
}
|
|
2752
|
+
function handleInlineTokenSelection(handlers, chains, selectedAccount, symbol, chainName, walletId) {
|
|
2753
|
+
if (walletId && selectedAccount) {
|
|
2754
|
+
const wallet = selectedAccount.wallets.find((w) => w.id === walletId);
|
|
2755
|
+
if (wallet && wallet.chain.name === chainName) {
|
|
2756
|
+
const source = wallet.sources.find((s) => s.token.symbol === symbol);
|
|
2757
|
+
const evmChainId = chains.find((c) => c.name === chainName)?.commonId ?? void 0;
|
|
2758
|
+
const authorized = !source?.token.status || source.token.status === "AUTHORIZED";
|
|
2759
|
+
if (source && !authorized && source.address && evmChainId != null) {
|
|
2760
|
+
void handlers.onAuthorizeToken(walletId, source.address, evmChainId, symbol);
|
|
2761
|
+
return;
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2764
|
+
handlers.onSelectAuthorizedToken(walletId, symbol);
|
|
2765
|
+
return;
|
|
2766
|
+
}
|
|
2767
|
+
handlers.onSelectSourceChainChange(chainName);
|
|
2768
|
+
handlers.onSetSelectSourceTokenSymbol(symbol);
|
|
2769
|
+
}
|
|
2532
2770
|
var MUTED = "#7fa4b0";
|
|
2533
2771
|
var LOGO_SIZE = 48;
|
|
2534
2772
|
function BlinkLoadingScreen() {
|
|
@@ -4081,6 +4319,22 @@ var loginButtonStyle = (accentColor) => ({
|
|
|
4081
4319
|
fontFamily: "inherit",
|
|
4082
4320
|
textDecoration: "underline"
|
|
4083
4321
|
});
|
|
4322
|
+
|
|
4323
|
+
// src/setupScreenSelection.ts
|
|
4324
|
+
function matchesSetupTokenSelection(opt, selectedTokenSymbol, selectedChainName, allOptions) {
|
|
4325
|
+
if (!selectedTokenSymbol || opt.symbol !== selectedTokenSymbol) {
|
|
4326
|
+
return false;
|
|
4327
|
+
}
|
|
4328
|
+
const chain = selectedChainName?.trim();
|
|
4329
|
+
if (chain) {
|
|
4330
|
+
return opt.chainName === chain;
|
|
4331
|
+
}
|
|
4332
|
+
const sameSymbol = allOptions.filter((o) => o.symbol === selectedTokenSymbol);
|
|
4333
|
+
if (sameSymbol.length === 1) {
|
|
4334
|
+
return opt.chainName === sameSymbol[0].chainName;
|
|
4335
|
+
}
|
|
4336
|
+
return false;
|
|
4337
|
+
}
|
|
4084
4338
|
var DEFAULT_MAX = 1e7;
|
|
4085
4339
|
var ABSOLUTE_MIN = 0.01;
|
|
4086
4340
|
var PRESETS = [100, 250, 1e3];
|
|
@@ -4096,13 +4350,16 @@ function SetupScreen({
|
|
|
4096
4350
|
loading,
|
|
4097
4351
|
error,
|
|
4098
4352
|
selectedTokenSymbol,
|
|
4353
|
+
selectedChainName,
|
|
4099
4354
|
tokenOptions,
|
|
4100
4355
|
onSelectToken
|
|
4101
4356
|
}) {
|
|
4102
4357
|
const { tokens } = useBlinkConfig();
|
|
4103
4358
|
const effectiveMax = DEFAULT_MAX;
|
|
4104
4359
|
const effectiveMin = Math.min(ABSOLUTE_MIN, effectiveMax);
|
|
4105
|
-
const
|
|
4360
|
+
const autoLimit = Math.min(Math.max(availableBalance, 0), effectiveMax);
|
|
4361
|
+
const [userChosenLimit, setUserChosenLimit] = react.useState(null);
|
|
4362
|
+
const limit = userChosenLimit ?? autoLimit;
|
|
4106
4363
|
const [activePreset, setActivePreset] = react.useState(null);
|
|
4107
4364
|
const [showAdvanced, setShowAdvanced] = react.useState(false);
|
|
4108
4365
|
const [editing, setEditing] = react.useState(false);
|
|
@@ -4141,20 +4398,22 @@ function SetupScreen({
|
|
|
4141
4398
|
const commitEdit = react.useCallback(() => {
|
|
4142
4399
|
const parsed = parseFloat(inputValue);
|
|
4143
4400
|
if (!isNaN(parsed)) {
|
|
4144
|
-
|
|
4401
|
+
setUserChosenLimit(
|
|
4402
|
+
Math.min(effectiveMax, Math.max(effectiveMin, Math.round(parsed * 100) / 100))
|
|
4403
|
+
);
|
|
4145
4404
|
}
|
|
4146
4405
|
setActivePreset(null);
|
|
4147
4406
|
setEditing(false);
|
|
4148
4407
|
}, [inputValue, effectiveMax, effectiveMin]);
|
|
4149
4408
|
const selectPreset = (value) => {
|
|
4150
|
-
|
|
4409
|
+
setUserChosenLimit(Math.min(value, effectiveMax));
|
|
4151
4410
|
setActivePreset(value);
|
|
4152
4411
|
};
|
|
4153
4412
|
const selectMax = () => {
|
|
4154
|
-
|
|
4413
|
+
setUserChosenLimit(autoLimit);
|
|
4155
4414
|
setActivePreset("max");
|
|
4156
4415
|
};
|
|
4157
|
-
const
|
|
4416
|
+
const options = tokenOptions ?? [];
|
|
4158
4417
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4159
4418
|
ScreenLayout,
|
|
4160
4419
|
{
|
|
@@ -4187,12 +4446,7 @@ function SetupScreen({
|
|
|
4187
4446
|
children: [
|
|
4188
4447
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenRowLabelStyle(tokens.text), children: "Token for one tap" }),
|
|
4189
4448
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenRowRightStyle, children: [
|
|
4190
|
-
|
|
4191
|
-
selectedOption.symbol,
|
|
4192
|
-
" \xB7 ",
|
|
4193
|
-
selectedOption.chainName
|
|
4194
|
-
] }),
|
|
4195
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenIconWrapStyle, children: selectedTokenSymbol && TOKEN_LOGOS[selectedTokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: TOKEN_LOGOS[selectedTokenSymbol], alt: selectedTokenSymbol, width: 36, height: 36, style: { borderRadius: "50%" } }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "36", height: "36", viewBox: "0 0 36 36", fill: "none", children: [
|
|
4449
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenIconWrapStyle, children: selectedTokenSymbol && TOKEN_LOGOS[selectedTokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: TOKEN_LOGOS[selectedTokenSymbol], alt: "", width: 36, height: 36, style: { borderRadius: "50%" } }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "36", height: "36", viewBox: "0 0 36 36", fill: "none", children: [
|
|
4196
4450
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "18", cy: "18", r: "18", fill: "#2DB84B" }),
|
|
4197
4451
|
/* @__PURE__ */ jsxRuntime.jsx("text", { x: "18", y: "23", textAnchor: "middle", fontSize: "18", fill: "#fff", fontWeight: "700", children: "$" })
|
|
4198
4452
|
] }) }),
|
|
@@ -4204,14 +4458,21 @@ function SetupScreen({
|
|
|
4204
4458
|
tokenDropdownOpen && tokenOptions && tokenOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: dropdownOuterStyle(tokens), children: [
|
|
4205
4459
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: dropdownLabelStyle(tokens.textMuted), children: "Choose token" }),
|
|
4206
4460
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: dropdownInnerStyle(tokens), children: tokenOptions.map((opt, index) => {
|
|
4207
|
-
const selected =
|
|
4461
|
+
const selected = matchesSetupTokenSelection(
|
|
4462
|
+
opt,
|
|
4463
|
+
selectedTokenSymbol,
|
|
4464
|
+
selectedChainName,
|
|
4465
|
+
options
|
|
4466
|
+
);
|
|
4208
4467
|
const isLast = index === tokenOptions.length - 1;
|
|
4468
|
+
const authorized = !opt.status || opt.status === "AUTHORIZED";
|
|
4209
4469
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4210
4470
|
"button",
|
|
4211
4471
|
{
|
|
4212
4472
|
type: "button",
|
|
4213
4473
|
onClick: () => handlePickToken(opt),
|
|
4214
4474
|
style: dropdownRowStyle(tokens, selected, isLast),
|
|
4475
|
+
"aria-label": opt.balance != null ? `${opt.symbol} on ${opt.chainName}, $${opt.balance.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })} balance${!authorized ? ", not authorized" : ""}` : `${opt.symbol} on ${opt.chainName}${!authorized ? ", not authorized" : ""}`,
|
|
4215
4476
|
children: [
|
|
4216
4477
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: dropdownRowLeftStyle, children: [
|
|
4217
4478
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: dropdownTokenIconStyle(tokens, !!TOKEN_LOGOS[opt.symbol]), children: TOKEN_LOGOS[opt.symbol] ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: TOKEN_LOGOS[opt.symbol], alt: opt.symbol, style: dropdownTokenLogoStyle }) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: dropdownTokenFallbackStyle(tokens.textMuted), children: "$" }) }),
|
|
@@ -4221,9 +4482,12 @@ function SetupScreen({
|
|
|
4221
4482
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: dropdownTokenDotStyle(tokens.textMuted), children: "\xB7" }),
|
|
4222
4483
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: dropdownTokenChainStyle(tokens.textMuted), children: opt.chainName })
|
|
4223
4484
|
] }),
|
|
4224
|
-
|
|
4225
|
-
"
|
|
4226
|
-
|
|
4485
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: dropdownTokenBalanceRowStyle, children: [
|
|
4486
|
+
opt.balance != null && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: dropdownTokenBalanceStyle(tokens.textMuted), children: [
|
|
4487
|
+
"$",
|
|
4488
|
+
opt.balance.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
|
4489
|
+
] }),
|
|
4490
|
+
!authorized && /* @__PURE__ */ jsxRuntime.jsx("span", { style: dropdownNotAuthorizedStyle(tokens.textMuted), children: "Not authorized" })
|
|
4227
4491
|
] })
|
|
4228
4492
|
] })
|
|
4229
4493
|
] }),
|
|
@@ -4343,11 +4607,6 @@ var tokenRowRightStyle = {
|
|
|
4343
4607
|
gap: 6,
|
|
4344
4608
|
flexShrink: 0
|
|
4345
4609
|
};
|
|
4346
|
-
var tokenRowSymbolStyle = (color) => ({
|
|
4347
|
-
fontSize: "0.84rem",
|
|
4348
|
-
fontWeight: 500,
|
|
4349
|
-
color
|
|
4350
|
-
});
|
|
4351
4610
|
var advancedToggleStyle = (accentColor) => ({
|
|
4352
4611
|
display: "block",
|
|
4353
4612
|
margin: "4px auto 24px",
|
|
@@ -4495,10 +4754,20 @@ var dropdownTokenChainStyle = (color) => ({
|
|
|
4495
4754
|
fontWeight: 400,
|
|
4496
4755
|
color
|
|
4497
4756
|
});
|
|
4757
|
+
var dropdownTokenBalanceRowStyle = {
|
|
4758
|
+
display: "flex",
|
|
4759
|
+
alignItems: "center",
|
|
4760
|
+
gap: 8
|
|
4761
|
+
};
|
|
4498
4762
|
var dropdownTokenBalanceStyle = (color) => ({
|
|
4499
4763
|
fontSize: "0.78rem",
|
|
4500
4764
|
color
|
|
4501
4765
|
});
|
|
4766
|
+
var dropdownNotAuthorizedStyle = (color) => ({
|
|
4767
|
+
fontSize: "0.7rem",
|
|
4768
|
+
fontWeight: 500,
|
|
4769
|
+
color
|
|
4770
|
+
});
|
|
4502
4771
|
var dropdownRadioEmptyStyle = (borderColor) => ({
|
|
4503
4772
|
width: 22,
|
|
4504
4773
|
height: 22,
|
|
@@ -4613,6 +4882,38 @@ var waitHintStyle = (color) => ({
|
|
|
4613
4882
|
color,
|
|
4614
4883
|
margin: 0
|
|
4615
4884
|
});
|
|
4885
|
+
|
|
4886
|
+
// src/feeFormat.ts
|
|
4887
|
+
function isPreciseMoneyNonPositive(fee) {
|
|
4888
|
+
const raw = fee.value.trim();
|
|
4889
|
+
if (!/^-?\d+(\.\d*)?$/.test(raw)) return false;
|
|
4890
|
+
const n = Number(raw);
|
|
4891
|
+
return Number.isFinite(n) && n <= 0;
|
|
4892
|
+
}
|
|
4893
|
+
function formatNonPositiveFeeDisplay(fee) {
|
|
4894
|
+
if (fee.currency === "USD") return "Under $0.01";
|
|
4895
|
+
return `Less than 0.01 ${fee.currency}`;
|
|
4896
|
+
}
|
|
4897
|
+
function formatPreciseMoneyForDisplay(fee) {
|
|
4898
|
+
const raw = fee.value.trim();
|
|
4899
|
+
if (fee.currency === "USD") {
|
|
4900
|
+
if (!/^\d+(\.\d*)?$/.test(raw)) {
|
|
4901
|
+
return `$${raw}`;
|
|
4902
|
+
}
|
|
4903
|
+
const [whole, frac = ""] = raw.split(".");
|
|
4904
|
+
const dec = `${frac}00`.slice(0, 2);
|
|
4905
|
+
const intFmt = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
4906
|
+
return `$${intFmt}.${dec}`;
|
|
4907
|
+
}
|
|
4908
|
+
return `${raw} ${fee.currency}`;
|
|
4909
|
+
}
|
|
4910
|
+
function formatUsdTwoDecimals(value) {
|
|
4911
|
+
const n = Number(value);
|
|
4912
|
+
return (Number.isFinite(n) ? n : 0).toLocaleString("en-US", {
|
|
4913
|
+
minimumFractionDigits: 2,
|
|
4914
|
+
maximumFractionDigits: 2
|
|
4915
|
+
});
|
|
4916
|
+
}
|
|
4616
4917
|
function DepositScreen({
|
|
4617
4918
|
merchantName,
|
|
4618
4919
|
availableBalance,
|
|
@@ -4620,6 +4921,8 @@ function DepositScreen({
|
|
|
4620
4921
|
tokenCount,
|
|
4621
4922
|
initialAmount,
|
|
4622
4923
|
minDepositFloor,
|
|
4924
|
+
quoteFee,
|
|
4925
|
+
quoteLoading,
|
|
4623
4926
|
processing,
|
|
4624
4927
|
error,
|
|
4625
4928
|
onDeposit,
|
|
@@ -4634,13 +4937,19 @@ function DepositScreen({
|
|
|
4634
4937
|
onAuthorizeAccount,
|
|
4635
4938
|
onAddProvider,
|
|
4636
4939
|
onSelectToken,
|
|
4940
|
+
tokenOptions,
|
|
4941
|
+
onPickToken,
|
|
4637
4942
|
selectedSourceLabel,
|
|
4638
|
-
selectedTokenSymbol
|
|
4943
|
+
selectedTokenSymbol,
|
|
4944
|
+
selectedChainName
|
|
4639
4945
|
}) {
|
|
4640
4946
|
const { tokens } = useBlinkConfig();
|
|
4641
4947
|
const amount = initialAmount;
|
|
4642
4948
|
const [accountPickerOpen, setAccountPickerOpen] = react.useState(false);
|
|
4949
|
+
const [tokenPickerOpen, setTokenPickerOpen] = react.useState(false);
|
|
4643
4950
|
const pickerRef = react.useRef(null);
|
|
4951
|
+
const tokenPickerRef = react.useRef(null);
|
|
4952
|
+
const hasTokenDropdown = tokenOptions != null && tokenOptions.length > 0 && onPickToken != null;
|
|
4644
4953
|
react.useEffect(() => {
|
|
4645
4954
|
if (!accountPickerOpen) return;
|
|
4646
4955
|
const handleClick = (e) => {
|
|
@@ -4651,6 +4960,28 @@ function DepositScreen({
|
|
|
4651
4960
|
document.addEventListener("mousedown", handleClick);
|
|
4652
4961
|
return () => document.removeEventListener("mousedown", handleClick);
|
|
4653
4962
|
}, [accountPickerOpen]);
|
|
4963
|
+
react.useEffect(() => {
|
|
4964
|
+
if (!tokenPickerOpen) return;
|
|
4965
|
+
const handleMouseDown = (e) => {
|
|
4966
|
+
if (tokenPickerRef.current && !tokenPickerRef.current.contains(e.target)) {
|
|
4967
|
+
setTokenPickerOpen(false);
|
|
4968
|
+
}
|
|
4969
|
+
};
|
|
4970
|
+
document.addEventListener("mousedown", handleMouseDown);
|
|
4971
|
+
return () => document.removeEventListener("mousedown", handleMouseDown);
|
|
4972
|
+
}, [tokenPickerOpen]);
|
|
4973
|
+
const handleTokenBadgeClick = react.useCallback(() => {
|
|
4974
|
+
if (hasTokenDropdown) {
|
|
4975
|
+
setTokenPickerOpen((v) => !v);
|
|
4976
|
+
setAccountPickerOpen(false);
|
|
4977
|
+
} else {
|
|
4978
|
+
onSelectToken?.();
|
|
4979
|
+
}
|
|
4980
|
+
}, [hasTokenDropdown, onSelectToken]);
|
|
4981
|
+
const handlePickToken = react.useCallback((opt) => {
|
|
4982
|
+
onPickToken?.(opt.symbol, opt.chainName, opt.walletId);
|
|
4983
|
+
setTokenPickerOpen(false);
|
|
4984
|
+
}, [onPickToken]);
|
|
4654
4985
|
const selectedAccount = accounts?.find((a) => a.id === selectedAccountId);
|
|
4655
4986
|
const selectedProviderName = selectedAccount?.name ?? "Wallet";
|
|
4656
4987
|
const selectedProviderLogo = KNOWN_LOGOS[selectedProviderName.toLowerCase()];
|
|
@@ -4662,36 +4993,95 @@ function DepositScreen({
|
|
|
4662
4993
|
ScreenLayout,
|
|
4663
4994
|
{
|
|
4664
4995
|
footer: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4665
|
-
!accountPickerOpen && (exceedsLimit && onIncreaseLimit ? /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: onIncreaseLimit, loading: increasingLimit, children: "Increase limit" }) : /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: () => onDeposit(amount), disabled: !canDeposit, loading: processing, children: "Confirm" })),
|
|
4996
|
+
!accountPickerOpen && !tokenPickerOpen && (exceedsLimit && onIncreaseLimit ? /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: onIncreaseLimit, loading: increasingLimit, children: "Increase limit" }) : /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: () => onDeposit(amount), disabled: !canDeposit, loading: processing, children: "Confirm" })),
|
|
4666
4997
|
/* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {})
|
|
4667
4998
|
] }),
|
|
4668
4999
|
children: [
|
|
4669
5000
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack, onLogout }),
|
|
4670
5001
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { ref: pickerRef, style: depositCardWrapStyle, children: [
|
|
4671
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
5002
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: depositCardStyle(tokens), children: [
|
|
4672
5003
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: depositLabelStyle(tokens.textMuted), children: "Depositing" }),
|
|
4673
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
4674
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4675
|
-
"
|
|
4676
|
-
|
|
5004
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { ref: tokenPickerRef, children: [
|
|
5005
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: amountRowStyle, children: [
|
|
5006
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: amountValueStyle(tokens.text), children: [
|
|
5007
|
+
"$",
|
|
5008
|
+
formatUsdTwoDecimals(amount)
|
|
5009
|
+
] }),
|
|
5010
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5011
|
+
"button",
|
|
5012
|
+
{
|
|
5013
|
+
type: "button",
|
|
5014
|
+
"data-testid": "deposit-token-badge",
|
|
5015
|
+
onClick: handleTokenBadgeClick,
|
|
5016
|
+
style: tokenIconButtonStyle(hasTokenDropdown || !!onSelectToken),
|
|
5017
|
+
"aria-expanded": hasTokenDropdown ? tokenPickerOpen : void 0,
|
|
5018
|
+
"aria-haspopup": hasTokenDropdown ? "listbox" : void 0,
|
|
5019
|
+
children: [
|
|
5020
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenIconWrapStyle2, children: selectedTokenSymbol && TOKEN_LOGOS[selectedTokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: TOKEN_LOGOS[selectedTokenSymbol], alt: selectedTokenSymbol, width: 36, height: 36, style: { borderRadius: "50%" } }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "36", height: "36", viewBox: "0 0 36 36", fill: "none", children: [
|
|
5021
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "18", cy: "18", r: "18", fill: "#2DB84B" }),
|
|
5022
|
+
/* @__PURE__ */ jsxRuntime.jsx("text", { x: "18", y: "23", textAnchor: "middle", fontSize: "18", fill: "#fff", fontWeight: "700", children: "$" })
|
|
5023
|
+
] }) }),
|
|
5024
|
+
/* @__PURE__ */ jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", style: { opacity: 0.5 }, children: tokenPickerOpen ? /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 15l-6-6-6 6", stroke: tokens.textMuted, strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }) : /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 9l6 6 6-6", stroke: tokens.textMuted, strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
5025
|
+
]
|
|
5026
|
+
}
|
|
5027
|
+
)
|
|
4677
5028
|
] }),
|
|
4678
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4679
|
-
"
|
|
4680
|
-
{
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
5029
|
+
tokenPickerOpen && tokenOptions && tokenOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenDropdownStyle(tokens), children: [
|
|
5030
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenDropdownLabelStyle(tokens.textMuted), children: "Choose token" }),
|
|
5031
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenDropdownInnerStyle(tokens), children: tokenOptions.map((opt, index) => {
|
|
5032
|
+
const selected = opt.symbol === selectedTokenSymbol && (!selectedChainName || opt.chainName === selectedChainName);
|
|
5033
|
+
const isLast = index === tokenOptions.length - 1;
|
|
5034
|
+
const authorized = !opt.status || opt.status === "AUTHORIZED";
|
|
5035
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5036
|
+
"button",
|
|
5037
|
+
{
|
|
5038
|
+
type: "button",
|
|
5039
|
+
onClick: () => handlePickToken(opt),
|
|
5040
|
+
style: tokenDropdownRowStyle(tokens, selected, isLast),
|
|
5041
|
+
"aria-label": opt.balance != null ? `${opt.symbol} on ${opt.chainName}, $${formatUsdTwoDecimals(opt.balance)} balance${!authorized ? ", not authorized" : ""}` : `${opt.symbol} on ${opt.chainName}${!authorized ? ", not authorized" : ""}`,
|
|
5042
|
+
children: [
|
|
5043
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenDropdownRowLeftStyle, children: [
|
|
5044
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenDropdownIconStyle(tokens, !!TOKEN_LOGOS[opt.symbol]), children: TOKEN_LOGOS[opt.symbol] ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: TOKEN_LOGOS[opt.symbol], alt: opt.symbol, style: tokenDropdownLogoStyle }) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenDropdownFallbackStyle(tokens.textMuted), children: "$" }) }),
|
|
5045
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenDropdownInfoStyle, children: [
|
|
5046
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenDropdownNameRowStyle, children: [
|
|
5047
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenDropdownSymbolStyle(tokens.text), children: opt.symbol }),
|
|
5048
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenDropdownDotStyle(tokens.textMuted), children: "\xB7" }),
|
|
5049
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenDropdownChainStyle(tokens.textMuted), children: opt.chainName })
|
|
5050
|
+
] }),
|
|
5051
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenDropdownBalanceRowStyle, children: [
|
|
5052
|
+
opt.balance != null && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: tokenDropdownBalanceStyle(tokens.textMuted), children: [
|
|
5053
|
+
"$",
|
|
5054
|
+
formatUsdTwoDecimals(opt.balance)
|
|
5055
|
+
] }),
|
|
5056
|
+
!authorized && /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenDropdownNotAuthStyle(tokens.textMuted), children: "Not authorized" })
|
|
5057
|
+
] })
|
|
5058
|
+
] })
|
|
5059
|
+
] }),
|
|
5060
|
+
selected ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "22", height: "22", viewBox: "0 0 22 22", fill: "none", children: [
|
|
5061
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "11", fill: tokens.success }),
|
|
5062
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7 11l3 3 5-5", stroke: "#fff", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
5063
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenDropdownRadioStyle(tokens.border) })
|
|
5064
|
+
]
|
|
5065
|
+
},
|
|
5066
|
+
`${opt.chainName}-${opt.symbol}`
|
|
5067
|
+
);
|
|
5068
|
+
}) })
|
|
5069
|
+
] })
|
|
4693
5070
|
] }),
|
|
4694
|
-
!accountPickerOpen &&
|
|
5071
|
+
!accountPickerOpen && !tokenPickerOpen && (() => {
|
|
5072
|
+
if (quoteLoading) {
|
|
5073
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: feeRowContainerStyle, "aria-live": "polite", children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: feeRowLabelStyle(tokens.textMuted), children: "Getting fee estimate\u2026" }) });
|
|
5074
|
+
}
|
|
5075
|
+
if (quoteFee) {
|
|
5076
|
+
const feeText = isPreciseMoneyNonPositive(quoteFee) ? formatNonPositiveFeeDisplay(quoteFee) : formatPreciseMoneyForDisplay(quoteFee);
|
|
5077
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: feeRowContainerStyle, "aria-live": "polite", children: [
|
|
5078
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: feeRowLabelStyle(tokens.textMuted), children: "Fee estimate: " }),
|
|
5079
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: feeRowAmountStyle(tokens.textSecondary), children: feeText })
|
|
5080
|
+
] });
|
|
5081
|
+
}
|
|
5082
|
+
return null;
|
|
5083
|
+
})(),
|
|
5084
|
+
!accountPickerOpen && !tokenPickerOpen && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4695
5085
|
"button",
|
|
4696
5086
|
{
|
|
4697
5087
|
type: "button",
|
|
@@ -4701,7 +5091,7 @@ function DepositScreen({
|
|
|
4701
5091
|
selectedProviderLogo ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: selectedProviderLogo, alt: selectedProviderName, style: providerLogoStyle }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: providerFallbackStyle(tokens.textMuted), children: selectedProviderName.charAt(0) }),
|
|
4702
5092
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: walletBalanceStyle(tokens.text), children: [
|
|
4703
5093
|
"$",
|
|
4704
|
-
totalAccountBalance
|
|
5094
|
+
formatUsdTwoDecimals(totalAccountBalance)
|
|
4705
5095
|
] }),
|
|
4706
5096
|
/* @__PURE__ */ jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", style: { opacity: 0.4 }, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7 10l5-5 5 5M7 14l5 5 5-5", stroke: tokens.textMuted, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
4707
5097
|
]
|
|
@@ -4742,7 +5132,7 @@ function DepositScreen({
|
|
|
4742
5132
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: accountAddressStyle(tokens.text), children: truncatedAddress ?? account.nickname ?? account.name }),
|
|
4743
5133
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: accountBalanceTextStyle(tokens.textMuted), children: [
|
|
4744
5134
|
"$",
|
|
4745
|
-
accountBalance
|
|
5135
|
+
formatUsdTwoDecimals(accountBalance)
|
|
4746
5136
|
] })
|
|
4747
5137
|
] })
|
|
4748
5138
|
] }),
|
|
@@ -4778,21 +5168,21 @@ function DepositScreen({
|
|
|
4778
5168
|
" ",
|
|
4779
5169
|
/* @__PURE__ */ jsxRuntime.jsxs("strong", { style: { color: tokens.text }, children: [
|
|
4780
5170
|
"$",
|
|
4781
|
-
remainingLimit
|
|
5171
|
+
formatUsdTwoDecimals(remainingLimit)
|
|
4782
5172
|
] }),
|
|
4783
5173
|
exceedsLimit && /* @__PURE__ */ jsxRuntime.jsxs("p", { style: limitExceededHintStyle(tokens.warning), children: [
|
|
4784
5174
|
"Your deposit of $",
|
|
4785
|
-
amount
|
|
5175
|
+
formatUsdTwoDecimals(amount),
|
|
4786
5176
|
" exceeds your One-Tap limit of $",
|
|
4787
|
-
remainingLimit
|
|
5177
|
+
remainingLimit != null ? formatUsdTwoDecimals(remainingLimit) : "0.00",
|
|
4788
5178
|
". Increase your limit to continue."
|
|
4789
5179
|
] })
|
|
4790
5180
|
] }),
|
|
4791
5181
|
!accountPickerOpen && isLowBalance && /* @__PURE__ */ jsxRuntime.jsxs(WarningBanner, { title: "Not enough funds", children: [
|
|
4792
5182
|
"Your wallet balance is $",
|
|
4793
|
-
availableBalance
|
|
5183
|
+
formatUsdTwoDecimals(availableBalance),
|
|
4794
5184
|
" \u2014 you need at least $",
|
|
4795
|
-
minDepositFloor
|
|
5185
|
+
formatUsdTwoDecimals(minDepositFloor),
|
|
4796
5186
|
" to deposit via One-Tap."
|
|
4797
5187
|
] }),
|
|
4798
5188
|
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle6(tokens), children: error })
|
|
@@ -4804,6 +5194,11 @@ var depositCardWrapStyle = {
|
|
|
4804
5194
|
position: "relative",
|
|
4805
5195
|
marginBottom: 20
|
|
4806
5196
|
};
|
|
5197
|
+
var depositCardStyle = (tokens) => ({
|
|
5198
|
+
border: `1px solid ${tokens.border}`,
|
|
5199
|
+
borderRadius: tokens.radiusLg,
|
|
5200
|
+
padding: "16px 20px"
|
|
5201
|
+
});
|
|
4807
5202
|
var depositLabelStyle = (color) => ({
|
|
4808
5203
|
fontSize: "0.75rem",
|
|
4809
5204
|
fontWeight: 500,
|
|
@@ -4837,6 +5232,116 @@ var tokenIconWrapStyle2 = {
|
|
|
4837
5232
|
width: 36,
|
|
4838
5233
|
height: 36
|
|
4839
5234
|
};
|
|
5235
|
+
var tokenDropdownStyle = (t) => ({
|
|
5236
|
+
marginTop: 4,
|
|
5237
|
+
marginBottom: 12,
|
|
5238
|
+
background: t.bgCard,
|
|
5239
|
+
border: `1px solid ${t.border}`,
|
|
5240
|
+
borderRadius: t.radiusLg,
|
|
5241
|
+
boxShadow: t.shadowLg,
|
|
5242
|
+
padding: "12px 14px 14px"
|
|
5243
|
+
});
|
|
5244
|
+
var tokenDropdownLabelStyle = (color) => ({
|
|
5245
|
+
fontSize: "0.78rem",
|
|
5246
|
+
fontWeight: 500,
|
|
5247
|
+
color,
|
|
5248
|
+
marginBottom: 8
|
|
5249
|
+
});
|
|
5250
|
+
var tokenDropdownInnerStyle = (t) => ({
|
|
5251
|
+
background: t.bgInput,
|
|
5252
|
+
border: `1px solid ${t.border}`,
|
|
5253
|
+
borderRadius: t.radiusLg,
|
|
5254
|
+
overflow: "hidden"
|
|
5255
|
+
});
|
|
5256
|
+
var tokenDropdownRowStyle = (t, isSelected, isLast) => ({
|
|
5257
|
+
display: "flex",
|
|
5258
|
+
alignItems: "center",
|
|
5259
|
+
justifyContent: "space-between",
|
|
5260
|
+
width: "100%",
|
|
5261
|
+
padding: "14px 16px",
|
|
5262
|
+
background: isSelected ? `${t.accent}18` : "transparent",
|
|
5263
|
+
border: "none",
|
|
5264
|
+
borderBottom: isLast ? "none" : `1px solid ${t.border}`,
|
|
5265
|
+
cursor: "pointer",
|
|
5266
|
+
fontFamily: "inherit",
|
|
5267
|
+
textAlign: "left",
|
|
5268
|
+
outline: "none"
|
|
5269
|
+
});
|
|
5270
|
+
var tokenDropdownRowLeftStyle = {
|
|
5271
|
+
display: "flex",
|
|
5272
|
+
alignItems: "center",
|
|
5273
|
+
gap: 12,
|
|
5274
|
+
minWidth: 0,
|
|
5275
|
+
flex: 1
|
|
5276
|
+
};
|
|
5277
|
+
var tokenDropdownIconStyle = (t, hasLogo) => ({
|
|
5278
|
+
width: 36,
|
|
5279
|
+
height: 36,
|
|
5280
|
+
borderRadius: "50%",
|
|
5281
|
+
border: hasLogo ? "none" : `1.5px solid ${t.border}`,
|
|
5282
|
+
display: "flex",
|
|
5283
|
+
alignItems: "center",
|
|
5284
|
+
justifyContent: "center",
|
|
5285
|
+
flexShrink: 0,
|
|
5286
|
+
overflow: "hidden"
|
|
5287
|
+
});
|
|
5288
|
+
var tokenDropdownLogoStyle = {
|
|
5289
|
+
width: 36,
|
|
5290
|
+
height: 36,
|
|
5291
|
+
borderRadius: "50%",
|
|
5292
|
+
objectFit: "cover"
|
|
5293
|
+
};
|
|
5294
|
+
var tokenDropdownFallbackStyle = (color) => ({
|
|
5295
|
+
fontSize: "1rem",
|
|
5296
|
+
fontWeight: 700,
|
|
5297
|
+
color
|
|
5298
|
+
});
|
|
5299
|
+
var tokenDropdownInfoStyle = {
|
|
5300
|
+
display: "flex",
|
|
5301
|
+
flexDirection: "column",
|
|
5302
|
+
gap: 2,
|
|
5303
|
+
minWidth: 0
|
|
5304
|
+
};
|
|
5305
|
+
var tokenDropdownNameRowStyle = {
|
|
5306
|
+
display: "flex",
|
|
5307
|
+
alignItems: "center",
|
|
5308
|
+
gap: 4
|
|
5309
|
+
};
|
|
5310
|
+
var tokenDropdownSymbolStyle = (color) => ({
|
|
5311
|
+
fontSize: "0.92rem",
|
|
5312
|
+
fontWeight: 600,
|
|
5313
|
+
color
|
|
5314
|
+
});
|
|
5315
|
+
var tokenDropdownDotStyle = (color) => ({
|
|
5316
|
+
fontSize: "0.8rem",
|
|
5317
|
+
color
|
|
5318
|
+
});
|
|
5319
|
+
var tokenDropdownChainStyle = (color) => ({
|
|
5320
|
+
fontSize: "0.84rem",
|
|
5321
|
+
fontWeight: 400,
|
|
5322
|
+
color
|
|
5323
|
+
});
|
|
5324
|
+
var tokenDropdownBalanceRowStyle = {
|
|
5325
|
+
display: "flex",
|
|
5326
|
+
alignItems: "center",
|
|
5327
|
+
gap: 8
|
|
5328
|
+
};
|
|
5329
|
+
var tokenDropdownBalanceStyle = (color) => ({
|
|
5330
|
+
fontSize: "0.78rem",
|
|
5331
|
+
color
|
|
5332
|
+
});
|
|
5333
|
+
var tokenDropdownNotAuthStyle = (color) => ({
|
|
5334
|
+
fontSize: "0.7rem",
|
|
5335
|
+
fontWeight: 500,
|
|
5336
|
+
color
|
|
5337
|
+
});
|
|
5338
|
+
var tokenDropdownRadioStyle = (borderColor) => ({
|
|
5339
|
+
width: 22,
|
|
5340
|
+
height: 22,
|
|
5341
|
+
borderRadius: "50%",
|
|
5342
|
+
border: `2px solid ${borderColor}`,
|
|
5343
|
+
flexShrink: 0
|
|
5344
|
+
});
|
|
4840
5345
|
var walletBalanceRowStyle = {
|
|
4841
5346
|
display: "flex",
|
|
4842
5347
|
alignItems: "center",
|
|
@@ -4998,9 +5503,20 @@ var limitExceededHintStyle = (color) => ({
|
|
|
4998
5503
|
margin: "12px 0 2px",
|
|
4999
5504
|
lineHeight: 1.5
|
|
5000
5505
|
});
|
|
5506
|
+
var feeRowContainerStyle = {
|
|
5507
|
+
fontSize: "0.84rem",
|
|
5508
|
+
fontWeight: 500,
|
|
5509
|
+
marginTop: 6,
|
|
5510
|
+
marginBottom: 4
|
|
5511
|
+
};
|
|
5512
|
+
var feeRowLabelStyle = (color) => ({ color });
|
|
5513
|
+
var feeRowAmountStyle = (color) => ({
|
|
5514
|
+
color,
|
|
5515
|
+
fontVariantNumeric: "tabular-nums"
|
|
5516
|
+
});
|
|
5001
5517
|
function SuccessScreen({
|
|
5002
5518
|
amount,
|
|
5003
|
-
currency,
|
|
5519
|
+
currency: _currency,
|
|
5004
5520
|
succeeded,
|
|
5005
5521
|
error,
|
|
5006
5522
|
merchantName,
|
|
@@ -5013,22 +5529,30 @@ function SuccessScreen({
|
|
|
5013
5529
|
onPreauthorize
|
|
5014
5530
|
}) {
|
|
5015
5531
|
const { tokens } = useBlinkConfig();
|
|
5532
|
+
const isGuestDepositSuccess = succeeded && onPreauthorize != null;
|
|
5016
5533
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5017
5534
|
ScreenLayout,
|
|
5018
5535
|
{
|
|
5019
5536
|
footer: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5020
|
-
|
|
5021
|
-
/* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: onPreauthorize, children: "
|
|
5022
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: onDone, style: skipButtonStyle(tokens.textMuted), children: "
|
|
5537
|
+
isGuestDepositSuccess ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5538
|
+
/* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: onPreauthorize, children: "Set up one tap" }),
|
|
5539
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: onDone, style: skipButtonStyle(tokens.textMuted), children: "Return to app" })
|
|
5023
5540
|
] }) : /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: onDone, children: succeeded ? "Done" : "Try again" }),
|
|
5024
5541
|
onManageAccount && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: onManageAccount, style: manageStyle(tokens.textMuted), children: "Manage Blink account \u2192" }),
|
|
5025
5542
|
/* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {})
|
|
5026
5543
|
] }),
|
|
5027
5544
|
children: [
|
|
5028
5545
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
|
|
5029
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
5030
|
-
|
|
5031
|
-
/* @__PURE__ */ jsxRuntime.
|
|
5546
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: screenContentStyle, children: [
|
|
5547
|
+
isGuestDepositSuccess ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyleCompact, children: [
|
|
5548
|
+
/* @__PURE__ */ jsxRuntime.jsxs("h2", { style: headingStyle7(tokens.text), children: [
|
|
5549
|
+
"$",
|
|
5550
|
+
amount.toFixed(2),
|
|
5551
|
+
" deposited"
|
|
5552
|
+
] }),
|
|
5553
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { ...subtitleStyle7(tokens.text), fontWeight: 600, margin: "0 0 8px" }, children: "Next time, do it in one tap" }),
|
|
5554
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle7(tokens.textSecondary), children: "Set up one tap for this wallet and skip the extra steps." })
|
|
5555
|
+
] }) : succeeded ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyleCompact, children: [
|
|
5032
5556
|
/* @__PURE__ */ jsxRuntime.jsxs("h2", { style: headingStyle7(tokens.text), children: [
|
|
5033
5557
|
"$",
|
|
5034
5558
|
amount.toFixed(2),
|
|
@@ -5040,10 +5564,10 @@ function SuccessScreen({
|
|
|
5040
5564
|
] })
|
|
5041
5565
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5042
5566
|
/* @__PURE__ */ jsxRuntime.jsx(IconCircle, { variant: "error", size: 64, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z", fill: tokens.error }) }) }),
|
|
5043
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { style:
|
|
5044
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("p", { style:
|
|
5567
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: failureHeadingStyle(tokens.text), children: "Transfer failed" }),
|
|
5568
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: failureSubtitleStyle(tokens.error), children: error })
|
|
5045
5569
|
] }),
|
|
5046
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryCardStyle(tokens), children: [
|
|
5570
|
+
!isGuestDepositSuccess && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryCardStyle(tokens), children: [
|
|
5047
5571
|
sourceName && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryRowStyle, children: [
|
|
5048
5572
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: summaryLabelStyle(tokens.textMuted), children: "From" }),
|
|
5049
5573
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: summaryValueStyle(tokens.text), children: sourceName })
|
|
@@ -5060,7 +5584,7 @@ function SuccessScreen({
|
|
|
5060
5584
|
] })
|
|
5061
5585
|
] })
|
|
5062
5586
|
] }),
|
|
5063
|
-
succeeded && onIncreaseLimits && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: upsellCardStyle(tokens), children: [
|
|
5587
|
+
succeeded && onIncreaseLimits && !isGuestDepositSuccess && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: upsellCardStyle(tokens), children: [
|
|
5064
5588
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: upsellHeaderStyle, children: [
|
|
5065
5589
|
/* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { marginRight: 6 }, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7 14l5-5 5 5", stroke: tokens.accent, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
|
|
5066
5590
|
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Want higher limits?" })
|
|
@@ -5073,21 +5597,42 @@ function SuccessScreen({
|
|
|
5073
5597
|
}
|
|
5074
5598
|
);
|
|
5075
5599
|
}
|
|
5076
|
-
var
|
|
5600
|
+
var screenContentStyle = {
|
|
5077
5601
|
flex: 1,
|
|
5078
5602
|
display: "flex",
|
|
5079
5603
|
flexDirection: "column",
|
|
5080
5604
|
alignItems: "center",
|
|
5081
5605
|
paddingTop: 16
|
|
5082
5606
|
};
|
|
5607
|
+
var contentStyleCompact = {
|
|
5608
|
+
textAlign: "center",
|
|
5609
|
+
display: "flex",
|
|
5610
|
+
flexDirection: "column",
|
|
5611
|
+
alignItems: "center",
|
|
5612
|
+
width: "100%"
|
|
5613
|
+
};
|
|
5083
5614
|
var headingStyle7 = (color) => ({
|
|
5615
|
+
fontSize: "1.45rem",
|
|
5616
|
+
fontWeight: 700,
|
|
5617
|
+
letterSpacing: "-0.02em",
|
|
5618
|
+
color,
|
|
5619
|
+
margin: "20px 0 8px"
|
|
5620
|
+
});
|
|
5621
|
+
var subtitleStyle7 = (color) => ({
|
|
5622
|
+
fontSize: "0.9rem",
|
|
5623
|
+
color,
|
|
5624
|
+
margin: "0 0 28px",
|
|
5625
|
+
lineHeight: 1.5,
|
|
5626
|
+
maxWidth: 280
|
|
5627
|
+
});
|
|
5628
|
+
var failureHeadingStyle = (color) => ({
|
|
5084
5629
|
fontSize: "1.5rem",
|
|
5085
5630
|
fontWeight: 700,
|
|
5086
5631
|
letterSpacing: "-0.02em",
|
|
5087
5632
|
color,
|
|
5088
5633
|
margin: "20px 0 4px"
|
|
5089
5634
|
});
|
|
5090
|
-
var
|
|
5635
|
+
var failureSubtitleStyle = (color) => ({
|
|
5091
5636
|
fontSize: "0.9rem",
|
|
5092
5637
|
color,
|
|
5093
5638
|
margin: "0 0 20px"
|
|
@@ -5603,7 +6148,7 @@ function TransferStatusScreen({
|
|
|
5603
6148
|
const steps = buildSteps(phase);
|
|
5604
6149
|
return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { footer: /* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {}), children: [
|
|
5605
6150
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
|
|
5606
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
6151
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle6, children: [
|
|
5607
6152
|
/* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 64 }),
|
|
5608
6153
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle9(tokens.text), children: "Depositing your money..." }),
|
|
5609
6154
|
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle7(tokens), children: error }),
|
|
@@ -5611,7 +6156,7 @@ function TransferStatusScreen({
|
|
|
5611
6156
|
] })
|
|
5612
6157
|
] });
|
|
5613
6158
|
}
|
|
5614
|
-
var
|
|
6159
|
+
var contentStyle6 = {
|
|
5615
6160
|
flex: 1,
|
|
5616
6161
|
display: "flex",
|
|
5617
6162
|
flexDirection: "column",
|
|
@@ -5681,7 +6226,7 @@ function OpenWalletScreen({
|
|
|
5681
6226
|
] }),
|
|
5682
6227
|
children: [
|
|
5683
6228
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
|
|
5684
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
6229
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle7, children: [
|
|
5685
6230
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: logoCircleStyle(tokens.bgInput), children: logoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoSrc, alt: displayName, style: logoStyle2 }) : /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 32 }) }),
|
|
5686
6231
|
/* @__PURE__ */ jsxRuntime.jsxs("h2", { style: headingStyle10(tokens.text), children: [
|
|
5687
6232
|
"Setting up ",
|
|
@@ -5714,7 +6259,7 @@ function OpenWalletScreen({
|
|
|
5714
6259
|
] }),
|
|
5715
6260
|
children: [
|
|
5716
6261
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack, onLogout }),
|
|
5717
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
6262
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle7, children: [
|
|
5718
6263
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: logoCircleStyle(tokens.bgInput), children: logoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoSrc, alt: displayName, style: logoStyle2 }) : /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 32 }) }),
|
|
5719
6264
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle10(tokens.text), children: loading ? "Connecting..." : `Open ${displayName}` }),
|
|
5720
6265
|
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle10(tokens.textSecondary), children: loading ? "Creating transfer and preparing your wallet link..." : `Continue in ${displayName} to authorize this connection.` }),
|
|
@@ -5727,7 +6272,7 @@ function OpenWalletScreen({
|
|
|
5727
6272
|
}
|
|
5728
6273
|
);
|
|
5729
6274
|
}
|
|
5730
|
-
var
|
|
6275
|
+
var contentStyle7 = {
|
|
5731
6276
|
flex: 1,
|
|
5732
6277
|
display: "flex",
|
|
5733
6278
|
flexDirection: "column",
|
|
@@ -5813,7 +6358,7 @@ function ConfirmSignScreen({
|
|
|
5813
6358
|
] }),
|
|
5814
6359
|
children: [
|
|
5815
6360
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
|
|
5816
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
6361
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle8, children: [
|
|
5817
6362
|
logoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoSrc, alt: displayName, style: logoStyle3 }) : /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 48 }),
|
|
5818
6363
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle11(tokens.text), children: "Wallet authorized" }),
|
|
5819
6364
|
/* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle11(tokens.textSecondary), children: [
|
|
@@ -5829,7 +6374,7 @@ function ConfirmSignScreen({
|
|
|
5829
6374
|
}
|
|
5830
6375
|
);
|
|
5831
6376
|
}
|
|
5832
|
-
var
|
|
6377
|
+
var contentStyle8 = {
|
|
5833
6378
|
flex: 1,
|
|
5834
6379
|
display: "flex",
|
|
5835
6380
|
flexDirection: "column",
|
|
@@ -6124,29 +6669,6 @@ var selectCircleSelectedStyle = (color) => ({
|
|
|
6124
6669
|
function entryKey(entry) {
|
|
6125
6670
|
return `${entry.sourceChainId}-${entry.tokenAddress.toLowerCase()}`;
|
|
6126
6671
|
}
|
|
6127
|
-
function isPreciseMoneyNonPositive(fee) {
|
|
6128
|
-
const raw = fee.value.trim();
|
|
6129
|
-
if (!/^-?\d+(\.\d*)?$/.test(raw)) return false;
|
|
6130
|
-
const n = Number(raw);
|
|
6131
|
-
return Number.isFinite(n) && n <= 0;
|
|
6132
|
-
}
|
|
6133
|
-
function formatNonPositiveFeeDisplay(fee) {
|
|
6134
|
-
if (fee.currency === "USD") return "Under $0.01";
|
|
6135
|
-
return `Less than 0.01 ${fee.currency}`;
|
|
6136
|
-
}
|
|
6137
|
-
function formatPreciseMoneyForDisplay(fee) {
|
|
6138
|
-
const raw = fee.value.trim();
|
|
6139
|
-
if (fee.currency === "USD") {
|
|
6140
|
-
if (!/^\d+(\.\d*)?$/.test(raw)) {
|
|
6141
|
-
return `$${raw}`;
|
|
6142
|
-
}
|
|
6143
|
-
const [whole, frac = ""] = raw.split(".");
|
|
6144
|
-
const dec = `${frac}00`.slice(0, 2);
|
|
6145
|
-
const intFmt = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
6146
|
-
return `$${intFmt}.${dec}`;
|
|
6147
|
-
}
|
|
6148
|
-
return `${raw} ${fee.currency}`;
|
|
6149
|
-
}
|
|
6150
6672
|
function GuestTokenPickerScreen({
|
|
6151
6673
|
entries,
|
|
6152
6674
|
loading,
|
|
@@ -6186,13 +6708,13 @@ function GuestTokenPickerScreen({
|
|
|
6186
6708
|
const canConfirm = Boolean(quoteFee && pendingEntry && !quoteLoading);
|
|
6187
6709
|
const feeLine = (() => {
|
|
6188
6710
|
if (quoteLoading && pendingEntry) {
|
|
6189
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
6711
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: feeRowContainerStyle2, "aria-live": "polite", children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: feeRowLabelStyle2(t.textMuted), children: "Getting fee estimate\u2026" }) });
|
|
6190
6712
|
}
|
|
6191
6713
|
if (quoteFee) {
|
|
6192
6714
|
const feeText = isPreciseMoneyNonPositive(quoteFee) ? formatNonPositiveFeeDisplay(quoteFee) : formatPreciseMoneyForDisplay(quoteFee);
|
|
6193
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
6194
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
6195
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
6715
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: feeRowContainerStyle2, "aria-live": "polite", children: [
|
|
6716
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: feeRowLabelStyle2(t.textMuted), children: "Fee estimate: " }),
|
|
6717
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: feeRowAmountStyle2(t.textSecondary), children: feeText })
|
|
6196
6718
|
] });
|
|
6197
6719
|
}
|
|
6198
6720
|
return null;
|
|
@@ -6214,7 +6736,7 @@ function GuestTokenPickerScreen({
|
|
|
6214
6736
|
depositAmount != null && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: depositAmountStyle2(t.text), children: [
|
|
6215
6737
|
"$",
|
|
6216
6738
|
depositAmount.toLocaleString("en-US", {
|
|
6217
|
-
minimumFractionDigits:
|
|
6739
|
+
minimumFractionDigits: 2,
|
|
6218
6740
|
maximumFractionDigits: 2
|
|
6219
6741
|
})
|
|
6220
6742
|
] }),
|
|
@@ -6296,7 +6818,7 @@ function GuestTokenPickerScreen({
|
|
|
6296
6818
|
] }),
|
|
6297
6819
|
tokenListOpen && entries.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenDropdownOuterStyle(t), children: [
|
|
6298
6820
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: accountDropdownLabelStyle2(t.textMuted), children: "Choose token" }),
|
|
6299
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
6821
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenDropdownInnerStyle2(t), children: entries.map((entry, index) => {
|
|
6300
6822
|
const selected = pendingKey === entryKey(entry);
|
|
6301
6823
|
const isLast = index === entries.length - 1;
|
|
6302
6824
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -6397,13 +6919,13 @@ var depositAmountStyle2 = (color) => ({
|
|
|
6397
6919
|
color,
|
|
6398
6920
|
lineHeight: 1.05
|
|
6399
6921
|
});
|
|
6400
|
-
var
|
|
6922
|
+
var feeRowContainerStyle2 = {
|
|
6401
6923
|
fontSize: "0.84rem",
|
|
6402
6924
|
fontWeight: 500,
|
|
6403
6925
|
marginTop: 6
|
|
6404
6926
|
};
|
|
6405
|
-
var
|
|
6406
|
-
var
|
|
6927
|
+
var feeRowLabelStyle2 = (color) => ({ color });
|
|
6928
|
+
var feeRowAmountStyle2 = (color) => ({
|
|
6407
6929
|
color,
|
|
6408
6930
|
fontVariantNumeric: "tabular-nums"
|
|
6409
6931
|
});
|
|
@@ -6449,7 +6971,7 @@ var accountDropdownLabelStyle2 = (color) => ({
|
|
|
6449
6971
|
color,
|
|
6450
6972
|
marginBottom: 8
|
|
6451
6973
|
});
|
|
6452
|
-
var
|
|
6974
|
+
var tokenDropdownInnerStyle2 = (tokens) => ({
|
|
6453
6975
|
background: tokens.bgInput,
|
|
6454
6976
|
border: `1px solid ${tokens.border}`,
|
|
6455
6977
|
borderRadius: tokens.radiusLg,
|
|
@@ -6561,7 +7083,7 @@ function GuestPreauthSetupCompleteScreen({
|
|
|
6561
7083
|
] }),
|
|
6562
7084
|
children: [
|
|
6563
7085
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
|
|
6564
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
7086
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle9, children: [
|
|
6565
7087
|
/* @__PURE__ */ jsxRuntime.jsx(IconCircle, { variant: "success", size: 64, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6566
7088
|
"path",
|
|
6567
7089
|
{
|
|
@@ -6570,13 +7092,13 @@ function GuestPreauthSetupCompleteScreen({
|
|
|
6570
7092
|
}
|
|
6571
7093
|
) }) }),
|
|
6572
7094
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle12(tokens.text), children: "Setup complete" }),
|
|
6573
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle12(tokens.textSecondary), children: "Your account is linked and ready. You can close this window
|
|
7095
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle12(tokens.textSecondary), children: "Your account is linked and ready. You can close this window." })
|
|
6574
7096
|
] })
|
|
6575
7097
|
]
|
|
6576
7098
|
}
|
|
6577
7099
|
);
|
|
6578
7100
|
}
|
|
6579
|
-
var
|
|
7101
|
+
var contentStyle9 = {
|
|
6580
7102
|
display: "flex",
|
|
6581
7103
|
flexDirection: "column",
|
|
6582
7104
|
alignItems: "center",
|
|
@@ -6605,14 +7127,14 @@ function GuestPreauthLinkingScreen({ onLogout }) {
|
|
|
6605
7127
|
const { tokens } = useBlinkConfig();
|
|
6606
7128
|
return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { children: [
|
|
6607
7129
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
|
|
6608
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
7130
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle10, children: [
|
|
6609
7131
|
/* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 48 }),
|
|
6610
7132
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle13(tokens.text), children: "Setting up your account..." }),
|
|
6611
7133
|
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle13(tokens.textSecondary), children: "Linking your wallet to your Blink account. This usually takes a few seconds." })
|
|
6612
7134
|
] })
|
|
6613
7135
|
] });
|
|
6614
7136
|
}
|
|
6615
|
-
var
|
|
7137
|
+
var contentStyle10 = {
|
|
6616
7138
|
flex: 1,
|
|
6617
7139
|
display: "flex",
|
|
6618
7140
|
flexDirection: "column",
|
|
@@ -6852,15 +7374,11 @@ function StepRendererContent({
|
|
|
6852
7374
|
0
|
|
6853
7375
|
);
|
|
6854
7376
|
const effectiveTokenCount = tokenCount > 0 ? tokenCount : selectSourceTokenCount;
|
|
6855
|
-
const
|
|
6856
|
-
const
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
balance: s.balance.available.amount,
|
|
6861
|
-
walletId: w.id
|
|
6862
|
-
}))
|
|
6863
|
-
) : selectSourceChoices.flatMap(
|
|
7377
|
+
const setupFromPendingSelectSource = pendingSelectSource != null;
|
|
7378
|
+
const setupSelectedTokenSymbol = setupFromPendingSelectSource ? selectSourceTokenSymbol || selectSourceRecommended?.tokenSymbol || "" : selectedSource?.token.symbol ?? selectSourceTokenSymbol;
|
|
7379
|
+
const setupSelectedChainName = setupFromPendingSelectSource ? selectSourceChainName || selectSourceRecommended?.chainName || "" : selectedWallet?.chain.name ?? selectSourceChainName;
|
|
7380
|
+
const effectiveSourceLabel = setupFromPendingSelectSource ? setupSelectedTokenSymbol && setupSelectedChainName ? `${setupSelectedTokenSymbol} on ${setupSelectedChainName}` : void 0 : selectedSourceLabel ?? (selectSourceChainName && selectSourceTokenSymbol ? `${selectSourceTokenSymbol} on ${selectSourceChainName}` : void 0);
|
|
7381
|
+
const setupTokenOptions = selectedAccount ? tokenOptionsForLinkedAccount(selectedAccount, state.chains) : selectSourceChoices.flatMap(
|
|
6864
7382
|
(chain) => chain.tokens.map((t) => ({
|
|
6865
7383
|
symbol: t.tokenSymbol,
|
|
6866
7384
|
chainName: chain.chainName,
|
|
@@ -6868,9 +7386,8 @@ function StepRendererContent({
|
|
|
6868
7386
|
}))
|
|
6869
7387
|
);
|
|
6870
7388
|
const handleSetupSelectToken = (symbol, chainName, walletId) => {
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
} else {
|
|
7389
|
+
handleInlineTokenSelection(handlers, state.chains, selectedAccount, symbol, chainName, walletId);
|
|
7390
|
+
if (pendingSelectSource) {
|
|
6874
7391
|
handlers.onSelectSourceChainChange(chainName);
|
|
6875
7392
|
handlers.onSetSelectSourceTokenSymbol(symbol);
|
|
6876
7393
|
}
|
|
@@ -6878,17 +7395,18 @@ function StepRendererContent({
|
|
|
6878
7395
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6879
7396
|
SetupScreen,
|
|
6880
7397
|
{
|
|
6881
|
-
availableBalance: selectedSource ? selectedSource.balance.available.amount : selectSourceAvailableBalance > 0 ? selectSourceAvailableBalance : selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : maxSourceBalance,
|
|
7398
|
+
availableBalance: selectedSource ? selectedSource.balance.available.amount : setupFromPendingSelectSource ? selectSourceAvailableBalance : selectSourceAvailableBalance > 0 ? selectSourceAvailableBalance : selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : maxSourceBalance,
|
|
6882
7399
|
tokenCount: effectiveTokenCount,
|
|
6883
7400
|
sourceName,
|
|
6884
7401
|
onSetupOneTap: handlers.onSetupOneTap,
|
|
6885
|
-
onBack:
|
|
7402
|
+
onBack: handlers.onBackFromSubflow,
|
|
6886
7403
|
onLogout: handlers.onLogout,
|
|
6887
7404
|
onAdvanced: handlers.onSelectToken,
|
|
6888
7405
|
selectedSourceLabel: effectiveSourceLabel,
|
|
6889
7406
|
loading: savingOneTapLimit,
|
|
6890
7407
|
error: state.error,
|
|
6891
|
-
selectedTokenSymbol:
|
|
7408
|
+
selectedTokenSymbol: setupSelectedTokenSymbol,
|
|
7409
|
+
selectedChainName: setupSelectedChainName,
|
|
6892
7410
|
tokenOptions: setupTokenOptions,
|
|
6893
7411
|
onSelectToken: handleSetupSelectToken
|
|
6894
7412
|
}
|
|
@@ -6910,6 +7428,7 @@ function StepRendererContent({
|
|
|
6910
7428
|
case "deposit": {
|
|
6911
7429
|
const parsedAmt = depositAmount != null ? depositAmount : 5;
|
|
6912
7430
|
const minDepositFloor = depositAmount != null ? depositAmount : DEFAULT_MIN_DEPOSIT_USD;
|
|
7431
|
+
const depositTokenOptions = tokenOptionsForLinkedAccount(selectedAccount, state.chains);
|
|
6913
7432
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6914
7433
|
DepositScreen,
|
|
6915
7434
|
{
|
|
@@ -6918,6 +7437,8 @@ function StepRendererContent({
|
|
|
6918
7437
|
remainingLimit: selectedSource != null ? selectedSource.remainingAllowance ?? null : selectedAccount?.remainingAllowance ?? null,
|
|
6919
7438
|
tokenCount,
|
|
6920
7439
|
initialAmount: parsedAmt,
|
|
7440
|
+
quoteFee: forms.depositQuoteFee,
|
|
7441
|
+
quoteLoading: forms.depositQuoteLoading,
|
|
6921
7442
|
processing: state.creatingTransfer,
|
|
6922
7443
|
error: state.error,
|
|
6923
7444
|
onDeposit: handlers.onPay,
|
|
@@ -6932,8 +7453,13 @@ function StepRendererContent({
|
|
|
6932
7453
|
onAuthorizeAccount: handlers.onContinueConnection,
|
|
6933
7454
|
onAddProvider: () => handlers.onSetPhase({ step: "wallet-picker", reason: "switch" }),
|
|
6934
7455
|
onSelectToken: handlers.onSelectToken,
|
|
7456
|
+
tokenOptions: depositTokenOptions,
|
|
7457
|
+
onPickToken: (symbol, chainName, walletId) => {
|
|
7458
|
+
handleInlineTokenSelection(handlers, state.chains, selectedAccount, symbol, chainName, walletId);
|
|
7459
|
+
},
|
|
6935
7460
|
selectedSourceLabel,
|
|
6936
7461
|
selectedTokenSymbol: selectedSource?.token.symbol,
|
|
7462
|
+
selectedChainName: selectedWallet?.chain.name,
|
|
6937
7463
|
minDepositFloor
|
|
6938
7464
|
}
|
|
6939
7465
|
);
|
|
@@ -6974,7 +7500,7 @@ function StepRendererContent({
|
|
|
6974
7500
|
chains: state.chains,
|
|
6975
7501
|
onSelectAuthorized: handlers.onSelectAuthorizedToken,
|
|
6976
7502
|
onAuthorizeToken: handlers.onAuthorizeToken,
|
|
6977
|
-
onBack:
|
|
7503
|
+
onBack: handlers.onBackFromSubflow,
|
|
6978
7504
|
onLogout: handlers.onLogout,
|
|
6979
7505
|
depositAmount: depositAmount ?? void 0,
|
|
6980
7506
|
selectedTokenSymbol: selectedSource?.token.symbol,
|
|
@@ -7053,7 +7579,7 @@ function StepRendererContent({
|
|
|
7053
7579
|
})() : void 0,
|
|
7054
7580
|
onDone: onDismiss ?? handlers.onNewPayment,
|
|
7055
7581
|
onLogout: authenticated ? handlers.onLogout : void 0,
|
|
7056
|
-
onPreauthorize: state.isGuestFlow ? handlers.onPreauthorize : void 0
|
|
7582
|
+
onPreauthorize: state.isGuestFlow && isDesktop ? handlers.onPreauthorize : void 0
|
|
7057
7583
|
}
|
|
7058
7584
|
);
|
|
7059
7585
|
}
|
|
@@ -7452,6 +7978,9 @@ function useTransferHandlers(deps) {
|
|
|
7452
7978
|
sourceTokenAddress,
|
|
7453
7979
|
activeCredentialId,
|
|
7454
7980
|
selectedAccountId,
|
|
7981
|
+
selectedWalletId,
|
|
7982
|
+
selectedTokenSymbol,
|
|
7983
|
+
quoteId,
|
|
7455
7984
|
transfer,
|
|
7456
7985
|
accounts
|
|
7457
7986
|
} = deps;
|
|
@@ -7465,9 +7994,32 @@ function useTransferHandlers(deps) {
|
|
|
7465
7994
|
fetchProviders(apiBaseUrl, token)
|
|
7466
7995
|
]);
|
|
7467
7996
|
const parsedAmt = depositAmount != null ? depositAmount : 0;
|
|
7468
|
-
const defaults =
|
|
7469
|
-
|
|
7470
|
-
|
|
7997
|
+
const { defaults, resetSelectedTokenSymbol } = resolveDepositSelectionAfterRefresh(
|
|
7998
|
+
accts,
|
|
7999
|
+
parsedAmt,
|
|
8000
|
+
{
|
|
8001
|
+
selectedAccountId,
|
|
8002
|
+
selectedWalletId,
|
|
8003
|
+
selectedTokenSymbol
|
|
8004
|
+
}
|
|
8005
|
+
);
|
|
8006
|
+
dispatch({
|
|
8007
|
+
type: "ACCOUNTS_RELOADED",
|
|
8008
|
+
accounts: accts,
|
|
8009
|
+
providers: prov,
|
|
8010
|
+
defaults,
|
|
8011
|
+
resetSelectedTokenSymbol
|
|
8012
|
+
});
|
|
8013
|
+
}, [
|
|
8014
|
+
getAccessToken,
|
|
8015
|
+
activeCredentialId,
|
|
8016
|
+
selectedAccountId,
|
|
8017
|
+
selectedWalletId,
|
|
8018
|
+
selectedTokenSymbol,
|
|
8019
|
+
apiBaseUrl,
|
|
8020
|
+
depositAmount,
|
|
8021
|
+
dispatch
|
|
8022
|
+
]);
|
|
7471
8023
|
const handlePay = react.useCallback(async (payAmount, sourceOverrides) => {
|
|
7472
8024
|
const minUsd = effectiveMinTransferAmountUsd(depositAmount);
|
|
7473
8025
|
if (isNaN(payAmount) || payAmount < minUsd) {
|
|
@@ -7511,7 +8063,8 @@ function useTransferHandlers(deps) {
|
|
|
7511
8063
|
sourceId: effectiveSourceId,
|
|
7512
8064
|
sourceTokenAddress,
|
|
7513
8065
|
destination,
|
|
7514
|
-
amount: payAmount
|
|
8066
|
+
amount: payAmount,
|
|
8067
|
+
...quoteId ? { quoteId } : {}
|
|
7515
8068
|
});
|
|
7516
8069
|
dispatch({ type: "TRANSFER_CREATED", transfer: t });
|
|
7517
8070
|
if (t.status === "COMPLETED") {
|
|
@@ -7543,6 +8096,7 @@ function useTransferHandlers(deps) {
|
|
|
7543
8096
|
accounts,
|
|
7544
8097
|
destination,
|
|
7545
8098
|
apiBaseUrl,
|
|
8099
|
+
quoteId,
|
|
7546
8100
|
getAccessToken,
|
|
7547
8101
|
transferSigning,
|
|
7548
8102
|
polling,
|
|
@@ -7593,20 +8147,20 @@ function useSourceSelectionHandlers(dispatch, authExecutor, options) {
|
|
|
7593
8147
|
const selectSourceAvailableBalance = react.useMemo(() => {
|
|
7594
8148
|
if (!pendingSelectSourceAction) return 0;
|
|
7595
8149
|
const options2 = pendingSelectSourceAction.metadata?.options ?? [];
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
8150
|
+
return resolveSelectSourceAvailableBalance(
|
|
8151
|
+
selectSourceChoices,
|
|
8152
|
+
options2,
|
|
8153
|
+
selectSourceChainName,
|
|
8154
|
+
selectSourceTokenSymbol,
|
|
8155
|
+
selectSourceRecommended
|
|
8156
|
+
);
|
|
8157
|
+
}, [
|
|
8158
|
+
pendingSelectSourceAction,
|
|
8159
|
+
selectSourceChoices,
|
|
8160
|
+
selectSourceChainName,
|
|
8161
|
+
selectSourceTokenSymbol,
|
|
8162
|
+
selectSourceRecommended
|
|
8163
|
+
]);
|
|
7610
8164
|
const handleSelectSourceChainChange = react.useCallback(
|
|
7611
8165
|
(chainName) => {
|
|
7612
8166
|
setSelectSourceChainName(chainName);
|
|
@@ -7657,7 +8211,7 @@ function useSourceSelectionHandlers(dispatch, authExecutor, options) {
|
|
|
7657
8211
|
initializedSelectSourceActionRef
|
|
7658
8212
|
};
|
|
7659
8213
|
}
|
|
7660
|
-
function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransferIdRef, stateTransfer, refs, guestCheckout, onComplete) {
|
|
8214
|
+
function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransferIdRef, stateTransfer, refs, guestCheckout, onComplete, lastResumedAt) {
|
|
7661
8215
|
const {
|
|
7662
8216
|
mobileSetupFlowRef,
|
|
7663
8217
|
handlingMobileReturnRef,
|
|
@@ -7668,6 +8222,8 @@ function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransfe
|
|
|
7668
8222
|
onCompleteRef.current = onComplete;
|
|
7669
8223
|
const guestPollingActiveRef = react.useRef(false);
|
|
7670
8224
|
const guestPollingCleanupRef = react.useRef(null);
|
|
8225
|
+
const mobileFlowRef = react.useRef(guestCheckout.mobileFlow);
|
|
8226
|
+
mobileFlowRef.current = guestCheckout.mobileFlow;
|
|
7671
8227
|
const guestTransferIdRef = react.useRef(guestCheckout.guestTransferId);
|
|
7672
8228
|
guestTransferIdRef.current = guestCheckout.guestTransferId;
|
|
7673
8229
|
const guestSessionTokenRef = react.useRef(guestCheckout.guestSessionToken);
|
|
@@ -7723,27 +8279,15 @@ function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransfe
|
|
|
7723
8279
|
startGuestPolling
|
|
7724
8280
|
]);
|
|
7725
8281
|
react.useEffect(() => {
|
|
7726
|
-
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
}
|
|
7734
|
-
|
|
7735
|
-
if (document.visibilityState === "visible") tryStartPolling();
|
|
7736
|
-
};
|
|
7737
|
-
const handlePageShow = (e) => {
|
|
7738
|
-
if (e.persisted) tryStartPolling();
|
|
7739
|
-
};
|
|
7740
|
-
document.addEventListener("visibilitychange", handleVisibility);
|
|
7741
|
-
window.addEventListener("pageshow", handlePageShow);
|
|
7742
|
-
return () => {
|
|
7743
|
-
document.removeEventListener("visibilitychange", handleVisibility);
|
|
7744
|
-
window.removeEventListener("pageshow", handlePageShow);
|
|
7745
|
-
};
|
|
7746
|
-
}, [startGuestPolling]);
|
|
8282
|
+
if (!lastResumedAt) return;
|
|
8283
|
+
if (guestPollingActiveRef.current) return;
|
|
8284
|
+
if (!mobileFlowRef.current) return;
|
|
8285
|
+
const transferId = guestTransferIdRef.current;
|
|
8286
|
+
const token = guestSessionTokenRef.current;
|
|
8287
|
+
if (transferId && token) {
|
|
8288
|
+
startGuestPolling(transferId, token);
|
|
8289
|
+
}
|
|
8290
|
+
}, [lastResumedAt, startGuestPolling]);
|
|
7747
8291
|
const handleAuthorizedMobileReturn = react.useCallback(async (authorizedTransfer, isSetup) => {
|
|
7748
8292
|
if (handlingMobileReturnRef.current) return;
|
|
7749
8293
|
handlingMobileReturnRef.current = true;
|
|
@@ -7977,6 +8521,9 @@ function useProviderHandlers(deps) {
|
|
|
7977
8521
|
await reloadAccounts();
|
|
7978
8522
|
}
|
|
7979
8523
|
} catch (err) {
|
|
8524
|
+
if (isAuthorizationSessionCancelled(err) || isUserDismissedAuthorizationError(err)) {
|
|
8525
|
+
return;
|
|
8526
|
+
}
|
|
7980
8527
|
captureException(err);
|
|
7981
8528
|
const msg = err instanceof Error ? err.message : "Failed to set up wallet";
|
|
7982
8529
|
dispatch({ type: "PAY_ERROR", error: msg });
|
|
@@ -8043,7 +8590,12 @@ function useProviderHandlers(deps) {
|
|
|
8043
8590
|
}
|
|
8044
8591
|
const acct = accounts.find((a) => a.id === selectedAccountId);
|
|
8045
8592
|
const matchedProvider = acct ? providers.find((p) => p.name === acct.name) : void 0;
|
|
8046
|
-
|
|
8593
|
+
const isMobile = !shouldUseWalletConnector({
|
|
8594
|
+
useWalletConnector: useWalletConnectorProp,
|
|
8595
|
+
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8596
|
+
});
|
|
8597
|
+
if (matchedProvider && isMobile) {
|
|
8598
|
+
dispatch({ type: "SAVE_SELECTION" });
|
|
8047
8599
|
dispatch({ type: "SELECT_PROVIDER", providerId: matchedProvider.id });
|
|
8048
8600
|
}
|
|
8049
8601
|
dispatch({ type: "SET_ERROR", error: null });
|
|
@@ -8063,10 +8615,6 @@ function useProviderHandlers(deps) {
|
|
|
8063
8615
|
activeCredentialId,
|
|
8064
8616
|
{ tokenAddress: source?.address, chainId: evmChainId }
|
|
8065
8617
|
);
|
|
8066
|
-
const isMobile = !shouldUseWalletConnector({
|
|
8067
|
-
useWalletConnector: useWalletConnectorProp,
|
|
8068
|
-
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8069
|
-
});
|
|
8070
8618
|
if (isMobile) {
|
|
8071
8619
|
handlingMobileReturnRef.current = false;
|
|
8072
8620
|
mobileSetupFlowRef.current = true;
|
|
@@ -8083,12 +8631,20 @@ function useProviderHandlers(deps) {
|
|
|
8083
8631
|
});
|
|
8084
8632
|
dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
|
|
8085
8633
|
triggerDeeplink(session.uri);
|
|
8634
|
+
dispatch({ type: "DISCARD_SAVED_SELECTION" });
|
|
8086
8635
|
} else {
|
|
8087
8636
|
await authExecutor.executeSessionById(session.id);
|
|
8088
8637
|
await reloadAccounts();
|
|
8638
|
+
dispatch({ type: "DISCARD_SAVED_SELECTION" });
|
|
8089
8639
|
}
|
|
8090
8640
|
} catch (err) {
|
|
8641
|
+
if (isAuthorizationSessionCancelled(err) || isUserDismissedAuthorizationError(err)) {
|
|
8642
|
+
return;
|
|
8643
|
+
}
|
|
8091
8644
|
captureException(err);
|
|
8645
|
+
if (isMobile) {
|
|
8646
|
+
dispatch({ type: "RESTORE_SELECTION" });
|
|
8647
|
+
}
|
|
8092
8648
|
const msg = err instanceof Error ? err.message : "Failed to increase limit";
|
|
8093
8649
|
dispatch({ type: "SET_ERROR", error: msg });
|
|
8094
8650
|
onError?.(msg);
|
|
@@ -8133,7 +8689,12 @@ function useProviderHandlers(deps) {
|
|
|
8133
8689
|
}
|
|
8134
8690
|
const acct = accounts.find((a) => a.id === selectedAccountId);
|
|
8135
8691
|
const matchedProvider = acct ? providers.find((p) => p.name === acct.name) : void 0;
|
|
8136
|
-
|
|
8692
|
+
const isMobile = !shouldUseWalletConnector({
|
|
8693
|
+
useWalletConnector: useWalletConnectorProp,
|
|
8694
|
+
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8695
|
+
});
|
|
8696
|
+
if (matchedProvider && isMobile) {
|
|
8697
|
+
dispatch({ type: "SAVE_SELECTION" });
|
|
8137
8698
|
dispatch({ type: "SELECT_PROVIDER", providerId: matchedProvider.id });
|
|
8138
8699
|
}
|
|
8139
8700
|
dispatch({ type: "SET_ERROR", error: null });
|
|
@@ -8148,10 +8709,6 @@ function useProviderHandlers(deps) {
|
|
|
8148
8709
|
activeCredentialId,
|
|
8149
8710
|
{ tokenAddress, chainId }
|
|
8150
8711
|
);
|
|
8151
|
-
const isMobile = !shouldUseWalletConnector({
|
|
8152
|
-
useWalletConnector: useWalletConnectorProp,
|
|
8153
|
-
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8154
|
-
});
|
|
8155
8712
|
if (isMobile) {
|
|
8156
8713
|
handlingMobileReturnRef.current = false;
|
|
8157
8714
|
mobileSetupFlowRef.current = true;
|
|
@@ -8169,13 +8726,21 @@ function useProviderHandlers(deps) {
|
|
|
8169
8726
|
});
|
|
8170
8727
|
dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
|
|
8171
8728
|
triggerDeeplink(session.uri);
|
|
8729
|
+
dispatch({ type: "DISCARD_SAVED_SELECTION" });
|
|
8172
8730
|
} else {
|
|
8173
8731
|
await authExecutor.executeSessionById(session.id);
|
|
8174
8732
|
await reloadAccounts();
|
|
8175
8733
|
dispatch({ type: "SELECT_TOKEN", walletId: _walletId, tokenSymbol });
|
|
8734
|
+
dispatch({ type: "DISCARD_SAVED_SELECTION" });
|
|
8176
8735
|
}
|
|
8177
8736
|
} catch (err) {
|
|
8737
|
+
if (isAuthorizationSessionCancelled(err) || isUserDismissedAuthorizationError(err)) {
|
|
8738
|
+
return;
|
|
8739
|
+
}
|
|
8178
8740
|
captureException(err);
|
|
8741
|
+
if (isMobile) {
|
|
8742
|
+
dispatch({ type: "RESTORE_SELECTION" });
|
|
8743
|
+
}
|
|
8179
8744
|
const msg = err instanceof Error ? err.message : "Failed to authorize token";
|
|
8180
8745
|
dispatch({ type: "SET_ERROR", error: msg });
|
|
8181
8746
|
onError?.(msg);
|
|
@@ -9112,7 +9677,15 @@ function useDataLoadEffect(deps) {
|
|
|
9112
9677
|
]);
|
|
9113
9678
|
if (cancelled) return;
|
|
9114
9679
|
const parsedAmt = depositAmount != null ? depositAmount : 0;
|
|
9115
|
-
const defaults =
|
|
9680
|
+
const { defaults, resetSelectedTokenSymbol } = resolveDepositSelectionAfterRefresh(
|
|
9681
|
+
accts,
|
|
9682
|
+
parsedAmt,
|
|
9683
|
+
{
|
|
9684
|
+
selectedAccountId: state.selectedAccountId,
|
|
9685
|
+
selectedWalletId: state.selectedWalletId,
|
|
9686
|
+
selectedTokenSymbol: state.selectedTokenSymbol
|
|
9687
|
+
}
|
|
9688
|
+
);
|
|
9116
9689
|
const persisted = loadMobileFlowState();
|
|
9117
9690
|
const clearMobile = persisted?.isSetup && accts.some((a) => a.wallets.some((w) => w.status === "ACTIVE"));
|
|
9118
9691
|
dispatch({
|
|
@@ -9121,7 +9694,8 @@ function useDataLoadEffect(deps) {
|
|
|
9121
9694
|
accounts: accts,
|
|
9122
9695
|
chains: chn,
|
|
9123
9696
|
defaults,
|
|
9124
|
-
clearMobileState: clearMobile
|
|
9697
|
+
clearMobileState: clearMobile,
|
|
9698
|
+
resetSelectedTokenSymbol
|
|
9125
9699
|
});
|
|
9126
9700
|
if (clearMobile) clearMobileFlowState();
|
|
9127
9701
|
} catch (err) {
|
|
@@ -9150,6 +9724,8 @@ function useDataLoadEffect(deps) {
|
|
|
9150
9724
|
apiBaseUrl,
|
|
9151
9725
|
state.activeCredentialId,
|
|
9152
9726
|
state.selectedAccountId,
|
|
9727
|
+
state.selectedWalletId,
|
|
9728
|
+
state.selectedTokenSymbol,
|
|
9153
9729
|
depositAmount
|
|
9154
9730
|
]);
|
|
9155
9731
|
react.useEffect(() => {
|
|
@@ -9378,25 +9954,16 @@ function useMobilePollingEffect(deps) {
|
|
|
9378
9954
|
const poll = isReauth ? pollReauthorization : pollWalletActive;
|
|
9379
9955
|
poll();
|
|
9380
9956
|
const intervalId = window.setInterval(poll, POLL_INTERVAL_MS);
|
|
9381
|
-
const handleVisibility = () => {
|
|
9382
|
-
if (document.visibilityState === "visible" && !cancelled) poll();
|
|
9383
|
-
};
|
|
9384
|
-
const handlePageShow = (e) => {
|
|
9385
|
-
if (e.persisted && !cancelled) poll();
|
|
9386
|
-
};
|
|
9387
|
-
document.addEventListener("visibilitychange", handleVisibility);
|
|
9388
|
-
window.addEventListener("pageshow", handlePageShow);
|
|
9389
9957
|
return () => {
|
|
9390
9958
|
cancelled = true;
|
|
9391
9959
|
window.clearInterval(intervalId);
|
|
9392
|
-
document.removeEventListener("visibilitychange", handleVisibility);
|
|
9393
|
-
window.removeEventListener("pageshow", handlePageShow);
|
|
9394
9960
|
};
|
|
9395
9961
|
}, [
|
|
9396
9962
|
state.mobileFlow,
|
|
9397
9963
|
state.isGuestFlow,
|
|
9398
9964
|
state.guestPreauthSessionId,
|
|
9399
9965
|
state.activeCredentialId,
|
|
9966
|
+
state.lastResumedAt,
|
|
9400
9967
|
apiBaseUrl,
|
|
9401
9968
|
reloadAccounts,
|
|
9402
9969
|
dispatch,
|
|
@@ -9413,28 +9980,13 @@ function useMobilePollingEffect(deps) {
|
|
|
9413
9980
|
const transferIdToResume = pollingTransferIdRef.current ?? state.transfer?.id;
|
|
9414
9981
|
if (!transferIdToResume) return;
|
|
9415
9982
|
if (!polling.isPolling) polling.startPolling(transferIdToResume);
|
|
9416
|
-
const handleVisibility = () => {
|
|
9417
|
-
if (document.visibilityState === "visible" && !handlingMobileReturnRef.current) {
|
|
9418
|
-
polling.startPolling(transferIdToResume);
|
|
9419
|
-
}
|
|
9420
|
-
};
|
|
9421
|
-
const handlePageShow = (e) => {
|
|
9422
|
-
if (e.persisted && !handlingMobileReturnRef.current) {
|
|
9423
|
-
polling.startPolling(transferIdToResume);
|
|
9424
|
-
}
|
|
9425
|
-
};
|
|
9426
|
-
document.addEventListener("visibilitychange", handleVisibility);
|
|
9427
|
-
window.addEventListener("pageshow", handlePageShow);
|
|
9428
|
-
return () => {
|
|
9429
|
-
document.removeEventListener("visibilitychange", handleVisibility);
|
|
9430
|
-
window.removeEventListener("pageshow", handlePageShow);
|
|
9431
|
-
};
|
|
9432
9983
|
}, [
|
|
9433
9984
|
state.mobileFlow,
|
|
9434
9985
|
state.transfer?.id,
|
|
9435
9986
|
state.isGuestFlow,
|
|
9436
9987
|
state.guestPreauthSessionId,
|
|
9437
9988
|
state.guestPreauthAccountId,
|
|
9989
|
+
state.lastResumedAt,
|
|
9438
9990
|
polling.isPolling,
|
|
9439
9991
|
polling.startPolling,
|
|
9440
9992
|
handlingMobileReturnRef,
|
|
@@ -9445,6 +9997,7 @@ function useGuestPreauthMobileRestoreEffect(deps) {
|
|
|
9445
9997
|
const {
|
|
9446
9998
|
dispatch,
|
|
9447
9999
|
privyReady,
|
|
10000
|
+
lastResumedAt,
|
|
9448
10001
|
mobileSetupFlowRef,
|
|
9449
10002
|
setupAccountIdRef,
|
|
9450
10003
|
startGuestAccountPolling
|
|
@@ -9455,68 +10008,43 @@ function useGuestPreauthMobileRestoreEffect(deps) {
|
|
|
9455
10008
|
console.info("[blink-sdk] guestPreauthMobileRestore: skipping, privyReady=false");
|
|
9456
10009
|
return;
|
|
9457
10010
|
}
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
|
|
9461
|
-
|
|
9462
|
-
|
|
9463
|
-
|
|
9464
|
-
|
|
9465
|
-
|
|
9466
|
-
|
|
9467
|
-
|
|
9468
|
-
|
|
9469
|
-
|
|
9470
|
-
|
|
9471
|
-
|
|
9472
|
-
|
|
9473
|
-
|
|
9474
|
-
|
|
9475
|
-
|
|
9476
|
-
|
|
9477
|
-
|
|
9478
|
-
|
|
9479
|
-
|
|
9480
|
-
if (persisted.accountId) {
|
|
9481
|
-
dispatch({
|
|
9482
|
-
type: "GUEST_PREAUTH_DETECTED",
|
|
9483
|
-
accountId: persisted.accountId,
|
|
9484
|
-
sessionId: persisted.sessionId
|
|
9485
|
-
});
|
|
9486
|
-
}
|
|
10011
|
+
if (startedRef.current) {
|
|
10012
|
+
console.info("[blink-sdk] guestPreauthMobileRestore: already started");
|
|
10013
|
+
return;
|
|
10014
|
+
}
|
|
10015
|
+
const persisted = loadMobileFlowState();
|
|
10016
|
+
console.info("[blink-sdk] guestPreauthMobileRestore.tryStart", {
|
|
10017
|
+
trigger: lastResumedAt ? "page-resume" : "initial",
|
|
10018
|
+
hasPersistedState: !!persisted,
|
|
10019
|
+
isGuestPreauth: persisted?.isGuestPreauth ?? false,
|
|
10020
|
+
hasGuestSessionToken: !!persisted?.guestSessionToken,
|
|
10021
|
+
hasSessionId: !!persisted?.sessionId,
|
|
10022
|
+
accountId: persisted?.accountId ?? null
|
|
10023
|
+
});
|
|
10024
|
+
if (!persisted?.isGuestPreauth || !persisted.guestSessionToken || !persisted.sessionId) {
|
|
10025
|
+
return;
|
|
10026
|
+
}
|
|
10027
|
+
startedRef.current = true;
|
|
10028
|
+
mobileSetupFlowRef.current = true;
|
|
10029
|
+
if (persisted.accountId) {
|
|
10030
|
+
setupAccountIdRef.current = persisted.accountId;
|
|
10031
|
+
}
|
|
10032
|
+
if (persisted.accountId) {
|
|
9487
10033
|
dispatch({
|
|
9488
|
-
type: "
|
|
9489
|
-
|
|
9490
|
-
});
|
|
9491
|
-
console.info("[blink-sdk] guestPreauthMobileRestore: starting guest account polling", {
|
|
9492
|
-
trigger,
|
|
10034
|
+
type: "GUEST_PREAUTH_DETECTED",
|
|
10035
|
+
accountId: persisted.accountId,
|
|
9493
10036
|
sessionId: persisted.sessionId
|
|
9494
10037
|
});
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9498
|
-
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
console.info("[blink-sdk] guestPreauthMobileRestore: pageshow fired", {
|
|
9506
|
-
persisted: e.persisted,
|
|
9507
|
-
visibilityState: document.visibilityState,
|
|
9508
|
-
startedRef: startedRef.current
|
|
9509
|
-
});
|
|
9510
|
-
if (document.visibilityState === "visible") tryStart("pageshow");
|
|
9511
|
-
};
|
|
9512
|
-
tryStart("initial");
|
|
9513
|
-
document.addEventListener("visibilitychange", onVisibility);
|
|
9514
|
-
window.addEventListener("pageshow", onPageShow);
|
|
9515
|
-
return () => {
|
|
9516
|
-
document.removeEventListener("visibilitychange", onVisibility);
|
|
9517
|
-
window.removeEventListener("pageshow", onPageShow);
|
|
9518
|
-
};
|
|
9519
|
-
}, [privyReady, dispatch, mobileSetupFlowRef, setupAccountIdRef, startGuestAccountPolling]);
|
|
10038
|
+
}
|
|
10039
|
+
dispatch({
|
|
10040
|
+
type: "MOBILE_DEEPLINK_READY",
|
|
10041
|
+
deeplinkUri: persisted.deeplinkUri
|
|
10042
|
+
});
|
|
10043
|
+
console.info("[blink-sdk] guestPreauthMobileRestore: starting guest account polling", {
|
|
10044
|
+
sessionId: persisted.sessionId
|
|
10045
|
+
});
|
|
10046
|
+
startGuestAccountPolling(persisted.guestSessionToken, persisted.sessionId);
|
|
10047
|
+
}, [privyReady, lastResumedAt, dispatch, mobileSetupFlowRef, setupAccountIdRef, startGuestAccountPolling]);
|
|
9520
10048
|
}
|
|
9521
10049
|
function useSelectSourceEffect(deps) {
|
|
9522
10050
|
const {
|
|
@@ -9820,7 +10348,7 @@ function useStandardDesktopInlineOpenWalletEffect(deps) {
|
|
|
9820
10348
|
react.useEffect(() => {
|
|
9821
10349
|
if (!isDesktop || state.guestPreauthorizing) return;
|
|
9822
10350
|
if (!state.privyAuthenticated || !state.activeCredentialId || !state.selectedAccountId) return;
|
|
9823
|
-
const shouldPin = authExecutor.executing && !authExecutor.pendingSelectSource && !authExecutor.pendingOneTapSetup;
|
|
10351
|
+
const shouldPin = authExecutor.executing && !authExecutor.pendingSelectSource && (!authExecutor.pendingOneTapSetup || authExecutor.authorizationSessionStackDepth > 1);
|
|
9824
10352
|
if (shouldPin && !state.standardDesktopInlineOpenWallet) {
|
|
9825
10353
|
dispatch({ type: "SET_STANDARD_DESKTOP_INLINE_OPEN_WALLET", value: true });
|
|
9826
10354
|
return;
|
|
@@ -9838,6 +10366,7 @@ function useStandardDesktopInlineOpenWalletEffect(deps) {
|
|
|
9838
10366
|
authExecutor.executing,
|
|
9839
10367
|
authExecutor.pendingSelectSource,
|
|
9840
10368
|
authExecutor.pendingOneTapSetup,
|
|
10369
|
+
authExecutor.authorizationSessionStackDepth,
|
|
9841
10370
|
dispatch
|
|
9842
10371
|
]);
|
|
9843
10372
|
}
|
|
@@ -9856,7 +10385,84 @@ function useGuestAccountAutoPollingEffect(deps) {
|
|
|
9856
10385
|
startPolling(guestSessionToken);
|
|
9857
10386
|
}, [mobileFlow, isGuestFlow, guestSessionToken, isPolling, guestAccount, startPolling]);
|
|
9858
10387
|
}
|
|
9859
|
-
|
|
10388
|
+
var WATCHDOG_INTERVAL_MS = 1e3;
|
|
10389
|
+
var WATCHDOG_THRESHOLD_MS = 3e3;
|
|
10390
|
+
var DEDUP_COOLDOWN_MS = 500;
|
|
10391
|
+
function usePageResume(callback) {
|
|
10392
|
+
const callbackRef = react.useRef(callback);
|
|
10393
|
+
callbackRef.current = callback;
|
|
10394
|
+
react.useEffect(() => {
|
|
10395
|
+
let lastTickAt = Date.now();
|
|
10396
|
+
let lastFiredAt = 0;
|
|
10397
|
+
const fire = (source, frozenDurationMs) => {
|
|
10398
|
+
const now = Date.now();
|
|
10399
|
+
if (now - lastFiredAt < DEDUP_COOLDOWN_MS) return;
|
|
10400
|
+
lastFiredAt = now;
|
|
10401
|
+
callbackRef.current({ frozenDurationMs, source });
|
|
10402
|
+
};
|
|
10403
|
+
const watchdogId = window.setInterval(() => {
|
|
10404
|
+
const now = Date.now();
|
|
10405
|
+
const elapsed = now - lastTickAt;
|
|
10406
|
+
lastTickAt = now;
|
|
10407
|
+
if (elapsed > WATCHDOG_THRESHOLD_MS) {
|
|
10408
|
+
fire("watchdog", elapsed);
|
|
10409
|
+
}
|
|
10410
|
+
}, WATCHDOG_INTERVAL_MS);
|
|
10411
|
+
const handleVisibility = () => {
|
|
10412
|
+
const now = Date.now();
|
|
10413
|
+
if (document.visibilityState === "visible") {
|
|
10414
|
+
fire("visibilitychange", now - lastTickAt);
|
|
10415
|
+
}
|
|
10416
|
+
lastTickAt = now;
|
|
10417
|
+
};
|
|
10418
|
+
const handlePageShow = (_e) => {
|
|
10419
|
+
const now = Date.now();
|
|
10420
|
+
if (document.visibilityState === "visible") {
|
|
10421
|
+
fire("pageshow", now - lastTickAt);
|
|
10422
|
+
}
|
|
10423
|
+
lastTickAt = now;
|
|
10424
|
+
};
|
|
10425
|
+
const handleFocus = () => {
|
|
10426
|
+
const now = Date.now();
|
|
10427
|
+
const elapsed = now - lastTickAt;
|
|
10428
|
+
lastTickAt = now;
|
|
10429
|
+
if (elapsed > WATCHDOG_THRESHOLD_MS) {
|
|
10430
|
+
fire("focus", elapsed);
|
|
10431
|
+
}
|
|
10432
|
+
};
|
|
10433
|
+
document.addEventListener("visibilitychange", handleVisibility);
|
|
10434
|
+
window.addEventListener("pageshow", handlePageShow);
|
|
10435
|
+
window.addEventListener("focus", handleFocus);
|
|
10436
|
+
return () => {
|
|
10437
|
+
window.clearInterval(watchdogId);
|
|
10438
|
+
document.removeEventListener("visibilitychange", handleVisibility);
|
|
10439
|
+
window.removeEventListener("pageshow", handlePageShow);
|
|
10440
|
+
window.removeEventListener("focus", handleFocus);
|
|
10441
|
+
};
|
|
10442
|
+
}, []);
|
|
10443
|
+
}
|
|
10444
|
+
var STUCK_REF_THRESHOLD_MS = 5e3;
|
|
10445
|
+
function usePageResumeEffect(deps) {
|
|
10446
|
+
const { dispatch, handlingMobileReturnRef } = deps;
|
|
10447
|
+
const dispatchRef = react.useRef(dispatch);
|
|
10448
|
+
dispatchRef.current = dispatch;
|
|
10449
|
+
usePageResume((info) => {
|
|
10450
|
+
console.info("[blink-sdk] PAGE_RESUMED", {
|
|
10451
|
+
source: info.source,
|
|
10452
|
+
frozenDurationMs: info.frozenDurationMs
|
|
10453
|
+
});
|
|
10454
|
+
dispatchRef.current({ type: "PAGE_RESUMED", frozenDurationMs: info.frozenDurationMs });
|
|
10455
|
+
if (info.frozenDurationMs > STUCK_REF_THRESHOLD_MS) {
|
|
10456
|
+
if (handlingMobileReturnRef.current) {
|
|
10457
|
+
console.info("[blink-sdk] PAGE_RESUMED: clearing stuck handlingMobileReturnRef", {
|
|
10458
|
+
frozenDurationMs: info.frozenDurationMs
|
|
10459
|
+
});
|
|
10460
|
+
handlingMobileReturnRef.current = false;
|
|
10461
|
+
}
|
|
10462
|
+
}
|
|
10463
|
+
});
|
|
10464
|
+
}
|
|
10465
|
+
function useGuestAccountPolling(intervalMs = 3e3, lastResumedAt = 0) {
|
|
9860
10466
|
const { apiBaseUrl } = useBlinkConfig();
|
|
9861
10467
|
const [guestAccount, setGuestAccount] = react.useState(null);
|
|
9862
10468
|
const [isPolling, setIsPolling] = react.useState(false);
|
|
@@ -9954,36 +10560,71 @@ function useGuestAccountPolling(intervalMs = 3e3) {
|
|
|
9954
10560
|
[poll, intervalMs, stopPolling]
|
|
9955
10561
|
);
|
|
9956
10562
|
react.useEffect(() => {
|
|
9957
|
-
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
|
|
9969
|
-
|
|
9970
|
-
|
|
9971
|
-
|
|
9972
|
-
|
|
10563
|
+
if (!lastResumedAt || !guestTokenRef.current) return;
|
|
10564
|
+
console.info("[blink-sdk] useGuestAccountPolling: page resumed, triggering poll", {
|
|
10565
|
+
lastResumedAt,
|
|
10566
|
+
hasToken: !!guestTokenRef.current,
|
|
10567
|
+
hasSessionId: !!sessionIdRef.current
|
|
10568
|
+
});
|
|
10569
|
+
void poll();
|
|
10570
|
+
}, [lastResumedAt, poll]);
|
|
10571
|
+
react.useEffect(() => () => stopPolling(), [stopPolling]);
|
|
10572
|
+
return { guestAccount, error, isPolling, startPolling, stopPolling };
|
|
10573
|
+
}
|
|
10574
|
+
function useDepositFeeEstimate({
|
|
10575
|
+
apiBaseUrl,
|
|
10576
|
+
getAccessToken,
|
|
10577
|
+
walletId,
|
|
10578
|
+
sourceTokenAddress,
|
|
10579
|
+
destination,
|
|
10580
|
+
amount,
|
|
10581
|
+
enabled
|
|
10582
|
+
}) {
|
|
10583
|
+
const [quoteId, setQuoteId] = react.useState(null);
|
|
10584
|
+
const [quoteFee, setQuoteFee] = react.useState(null);
|
|
10585
|
+
const [quoteLoading, setQuoteLoading] = react.useState(false);
|
|
10586
|
+
const abortRef = react.useRef(null);
|
|
10587
|
+
const fetchQuote = react.useCallback(async () => {
|
|
10588
|
+
if (!enabled || !walletId || !sourceTokenAddress) {
|
|
10589
|
+
setQuoteId(null);
|
|
10590
|
+
setQuoteFee(null);
|
|
10591
|
+
setQuoteLoading(false);
|
|
10592
|
+
return;
|
|
10593
|
+
}
|
|
10594
|
+
abortRef.current?.abort();
|
|
10595
|
+
const controller = new AbortController();
|
|
10596
|
+
abortRef.current = controller;
|
|
10597
|
+
setQuoteLoading(true);
|
|
10598
|
+
try {
|
|
10599
|
+
const token = await getAccessToken();
|
|
10600
|
+
if (!token || controller.signal.aborted) return;
|
|
10601
|
+
const quote = await postTransferQuote(apiBaseUrl, token, {
|
|
10602
|
+
walletId,
|
|
10603
|
+
sourceTokenAddress,
|
|
10604
|
+
destination,
|
|
10605
|
+
amount: { amount, currency: "USD" }
|
|
9973
10606
|
});
|
|
9974
|
-
if (
|
|
9975
|
-
|
|
10607
|
+
if (controller.signal.aborted) return;
|
|
10608
|
+
setQuoteId(quote.id);
|
|
10609
|
+
setQuoteFee(quote.fee);
|
|
10610
|
+
} catch (err) {
|
|
10611
|
+
if (controller.signal.aborted) return;
|
|
10612
|
+
console.warn("[blink-sdk] Fee quote failed:", err);
|
|
10613
|
+
setQuoteId(null);
|
|
10614
|
+
setQuoteFee(null);
|
|
10615
|
+
} finally {
|
|
10616
|
+
if (!controller.signal.aborted) {
|
|
10617
|
+
setQuoteLoading(false);
|
|
9976
10618
|
}
|
|
9977
|
-
}
|
|
9978
|
-
|
|
9979
|
-
|
|
10619
|
+
}
|
|
10620
|
+
}, [enabled, walletId, sourceTokenAddress, destination, amount, apiBaseUrl, getAccessToken]);
|
|
10621
|
+
react.useEffect(() => {
|
|
10622
|
+
fetchQuote();
|
|
9980
10623
|
return () => {
|
|
9981
|
-
|
|
9982
|
-
window.removeEventListener("pageshow", handlePageShow);
|
|
10624
|
+
abortRef.current?.abort();
|
|
9983
10625
|
};
|
|
9984
|
-
}, [
|
|
9985
|
-
|
|
9986
|
-
return { guestAccount, error, isPolling, startPolling, stopPolling };
|
|
10626
|
+
}, [fetchQuote]);
|
|
10627
|
+
return { quoteId, quoteFee, quoteLoading };
|
|
9987
10628
|
}
|
|
9988
10629
|
function BlinkPayment(props) {
|
|
9989
10630
|
const resetKey = react.useRef(0);
|
|
@@ -10023,7 +10664,7 @@ function BlinkPaymentInner({
|
|
|
10023
10664
|
);
|
|
10024
10665
|
const authExecutor = useAuthorizationExecutor();
|
|
10025
10666
|
const polling = useTransferPolling();
|
|
10026
|
-
const guestAccountPolling = useGuestAccountPolling();
|
|
10667
|
+
const guestAccountPolling = useGuestAccountPolling(3e3, state.lastResumedAt);
|
|
10027
10668
|
const transferSigning = useTransferSigning();
|
|
10028
10669
|
const mobileFlowRefs = {
|
|
10029
10670
|
mobileSetupFlowRef: react.useRef(false),
|
|
@@ -10041,6 +10682,15 @@ function BlinkPaymentInner({
|
|
|
10041
10682
|
state.accounts,
|
|
10042
10683
|
state.knownCredentialIds
|
|
10043
10684
|
);
|
|
10685
|
+
const depositFee = useDepositFeeEstimate({
|
|
10686
|
+
apiBaseUrl,
|
|
10687
|
+
getAccessToken,
|
|
10688
|
+
walletId: state.selectedWalletId,
|
|
10689
|
+
sourceTokenAddress: derived.selectedSource?.address,
|
|
10690
|
+
destination,
|
|
10691
|
+
amount: depositAmount ?? 5,
|
|
10692
|
+
enabled: state.phase.step === "deposit" && !state.isGuestFlow && authenticated
|
|
10693
|
+
});
|
|
10044
10694
|
const transfer = useTransferHandlers({
|
|
10045
10695
|
dispatch,
|
|
10046
10696
|
getAccessToken,
|
|
@@ -10058,6 +10708,9 @@ function BlinkPaymentInner({
|
|
|
10058
10708
|
sourceTokenAddress: derived.selectedSource?.address,
|
|
10059
10709
|
activeCredentialId: state.activeCredentialId,
|
|
10060
10710
|
selectedAccountId: state.selectedAccountId,
|
|
10711
|
+
selectedWalletId: state.selectedWalletId,
|
|
10712
|
+
selectedTokenSymbol: state.selectedTokenSymbol,
|
|
10713
|
+
quoteId: depositFee.quoteId,
|
|
10061
10714
|
transfer: state.transfer,
|
|
10062
10715
|
accounts: state.accounts
|
|
10063
10716
|
});
|
|
@@ -10074,7 +10727,8 @@ function BlinkPaymentInner({
|
|
|
10074
10727
|
guestTransferId: state.guestTransferId,
|
|
10075
10728
|
guestSessionToken: state.guestSessionToken
|
|
10076
10729
|
},
|
|
10077
|
-
onComplete
|
|
10730
|
+
onComplete,
|
|
10731
|
+
state.lastResumedAt
|
|
10078
10732
|
);
|
|
10079
10733
|
const sourceSelection = useSourceSelectionHandlers(dispatch, authExecutor, {
|
|
10080
10734
|
guestPreauthSessionId: state.guestPreauthSessionId,
|
|
@@ -10170,10 +10824,15 @@ function BlinkPaymentInner({
|
|
|
10170
10824
|
dispatch({ type: "SYNC_AMOUNT", amount: depositAmount.toString() });
|
|
10171
10825
|
}
|
|
10172
10826
|
}, [depositAmount, dispatch]);
|
|
10827
|
+
usePageResumeEffect({
|
|
10828
|
+
dispatch,
|
|
10829
|
+
handlingMobileReturnRef: mobileFlowRefs.handlingMobileReturnRef
|
|
10830
|
+
});
|
|
10173
10831
|
usePrivySessionSyncEffect({ dispatch, ready, authenticated });
|
|
10174
10832
|
useGuestPreauthMobileRestoreEffect({
|
|
10175
10833
|
dispatch,
|
|
10176
10834
|
privyReady: state.privyReady,
|
|
10835
|
+
lastResumedAt: state.lastResumedAt,
|
|
10177
10836
|
mobileSetupFlowRef: mobileFlowRefs.mobileSetupFlowRef,
|
|
10178
10837
|
setupAccountIdRef: mobileFlowRefs.setupAccountIdRef,
|
|
10179
10838
|
startGuestAccountPolling: guestAccountPolling.startPolling
|
|
@@ -10186,25 +10845,24 @@ function BlinkPaymentInner({
|
|
|
10186
10845
|
guestAccount: guestAccountPolling.guestAccount,
|
|
10187
10846
|
startPolling: guestAccountPolling.startPolling
|
|
10188
10847
|
});
|
|
10189
|
-
const guestSessionTokenRef = react.useRef(state.guestSessionToken);
|
|
10190
|
-
guestSessionTokenRef.current = state.guestSessionToken;
|
|
10191
|
-
const guestPreauthSessionIdRef = react.useRef(state.guestPreauthSessionId);
|
|
10192
|
-
guestPreauthSessionIdRef.current = state.guestPreauthSessionId;
|
|
10193
10848
|
react.useEffect(() => {
|
|
10194
|
-
|
|
10195
|
-
|
|
10196
|
-
|
|
10197
|
-
|
|
10198
|
-
|
|
10199
|
-
|
|
10200
|
-
|
|
10201
|
-
|
|
10202
|
-
|
|
10203
|
-
|
|
10204
|
-
|
|
10205
|
-
|
|
10206
|
-
|
|
10207
|
-
|
|
10849
|
+
if (!state.lastResumedAt) return;
|
|
10850
|
+
const token = state.guestSessionToken;
|
|
10851
|
+
const sessionId = state.guestPreauthSessionId;
|
|
10852
|
+
if (!token) return;
|
|
10853
|
+
if (guestAccountPolling.isPolling || guestAccountPolling.guestAccount) return;
|
|
10854
|
+
console.info("[blink-sdk] warm-return: restarting guest account polling from React state", {
|
|
10855
|
+
sessionId: sessionId ?? "(none \u2014 account-only mode)"
|
|
10856
|
+
});
|
|
10857
|
+
guestAccountPolling.startPolling(token, sessionId ?? void 0);
|
|
10858
|
+
}, [
|
|
10859
|
+
state.lastResumedAt,
|
|
10860
|
+
state.guestSessionToken,
|
|
10861
|
+
state.guestPreauthSessionId,
|
|
10862
|
+
guestAccountPolling.isPolling,
|
|
10863
|
+
guestAccountPolling.guestAccount,
|
|
10864
|
+
guestAccountPolling.startPolling
|
|
10865
|
+
]);
|
|
10208
10866
|
react.useEffect(() => {
|
|
10209
10867
|
console.info("[blink-sdk] guestPreauthCompletion effect", {
|
|
10210
10868
|
hasGuestAccount: !!guestAccountPolling.guestAccount,
|
|
@@ -10369,6 +11027,11 @@ function BlinkPaymentInner({
|
|
|
10369
11027
|
onLogout: handleLogout,
|
|
10370
11028
|
onNewPayment: handleNewPayment,
|
|
10371
11029
|
onSetPhase: (phase) => dispatch({ type: "SET_USER_INTENT", intent: phase }),
|
|
11030
|
+
onBackFromSubflow: () => {
|
|
11031
|
+
authExecutor.cancelPendingExecution();
|
|
11032
|
+
dispatch({ type: "RESTORE_SELECTION" });
|
|
11033
|
+
dispatch({ type: "SET_USER_INTENT", intent: { step: "deposit" } });
|
|
11034
|
+
},
|
|
10372
11035
|
onSetAuthInput: auth.setAuthInput,
|
|
10373
11036
|
onSetOtpCode: (code) => {
|
|
10374
11037
|
auth.setOtpCode(code);
|
|
@@ -10402,7 +11065,8 @@ function BlinkPaymentInner({
|
|
|
10402
11065
|
handleLogout,
|
|
10403
11066
|
handleNewPayment,
|
|
10404
11067
|
onDismiss,
|
|
10405
|
-
dispatch
|
|
11068
|
+
dispatch,
|
|
11069
|
+
authExecutor
|
|
10406
11070
|
]);
|
|
10407
11071
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10408
11072
|
StepRenderer,
|
|
@@ -10451,7 +11115,10 @@ function BlinkPaymentInner({
|
|
|
10451
11115
|
guestSettingSender: guestTransfer.settingSender,
|
|
10452
11116
|
guestPendingEntry: guestTransfer.pendingGuestEntry,
|
|
10453
11117
|
guestQuoteFee: guestTransfer.guestFee?.quote ?? null,
|
|
10454
|
-
guestQuoteLoading: guestTransfer.guestQuoteLoading
|
|
11118
|
+
guestQuoteLoading: guestTransfer.guestQuoteLoading,
|
|
11119
|
+
depositQuoteId: depositFee.quoteId,
|
|
11120
|
+
depositQuoteFee: depositFee.quoteFee,
|
|
11121
|
+
depositQuoteLoading: depositFee.quoteLoading
|
|
10455
11122
|
},
|
|
10456
11123
|
handlers
|
|
10457
11124
|
}
|
|
@@ -10459,6 +11126,7 @@ function BlinkPaymentInner({
|
|
|
10459
11126
|
}
|
|
10460
11127
|
|
|
10461
11128
|
exports.AdvancedSourceScreen = AdvancedSourceScreen;
|
|
11129
|
+
exports.AuthorizationSessionCancelledError = AuthorizationSessionCancelledError;
|
|
10462
11130
|
exports.BLINK_LOGO = BLINK_LOGO;
|
|
10463
11131
|
exports.BLINK_MASCOT = BLINK_MASCOT;
|
|
10464
11132
|
exports.BlinkLoadingScreen = BlinkLoadingScreen;
|
|
@@ -10503,6 +11171,8 @@ exports.findDevicePasskey = findDevicePasskey;
|
|
|
10503
11171
|
exports.findDevicePasskeyViaPopup = findDevicePasskeyViaPopup;
|
|
10504
11172
|
exports.getTheme = getTheme;
|
|
10505
11173
|
exports.guestEntryMatchingRecommended = guestEntryMatchingRecommended;
|
|
11174
|
+
exports.isAuthorizationSessionCancelled = isAuthorizationSessionCancelled;
|
|
11175
|
+
exports.isUserDismissedAuthorizationError = isUserDismissedAuthorizationError;
|
|
10506
11176
|
exports.lightTheme = lightTheme;
|
|
10507
11177
|
exports.mapGuestPickerEntries = mapGuestPickerEntries;
|
|
10508
11178
|
exports.resolvePasskeyRpId = resolvePasskeyRpId;
|