@swype-org/react-sdk 0.1.300 → 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 +1021 -345
- 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 +1020 -347
- package/dist/index.js.map +1 -1
- package/package.json +11 -3
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createContext, useRef, useState, useCallback, useMemo, useContext, useEffect, useReducer, Component } from 'react';
|
|
2
2
|
import { PrivyProvider, usePrivy, useLoginWithOAuth, useLoginWithEmail, useLoginWithSms } from '@privy-io/react-auth';
|
|
3
3
|
import { createConfig, http, WagmiProvider, useConfig, useConnect, useSwitchChain } from 'wagmi';
|
|
4
|
-
import { mainnet, arbitrum, base, polygon, bsc } from 'wagmi/chains';
|
|
4
|
+
import { mainnet, arbitrum, base, polygon, bsc, baseSepolia } from 'wagmi/chains';
|
|
5
5
|
import { injected } from 'wagmi/connectors';
|
|
6
6
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
7
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -75,14 +75,16 @@ function getTheme(mode) {
|
|
|
75
75
|
}
|
|
76
76
|
var BLINK_PRIVY_APP_ID = "cmlil87uv004n0ck0blwumwek";
|
|
77
77
|
var wagmiConfig = createConfig({
|
|
78
|
-
|
|
78
|
+
// baseSepolia: guest/testnet flows (e.g. smokebox e2e) call switchChain to the source chain from the API.
|
|
79
|
+
chains: [mainnet, arbitrum, base, polygon, bsc, baseSepolia],
|
|
79
80
|
connectors: [injected({ shimDisconnect: true, unstable_shimAsyncInject: 2e3 })],
|
|
80
81
|
transports: {
|
|
81
82
|
[mainnet.id]: http(),
|
|
82
83
|
[arbitrum.id]: http(),
|
|
83
84
|
[base.id]: http(),
|
|
84
85
|
[polygon.id]: http(),
|
|
85
|
-
[bsc.id]: http()
|
|
86
|
+
[bsc.id]: http(),
|
|
87
|
+
[baseSepolia.id]: http()
|
|
86
88
|
}
|
|
87
89
|
});
|
|
88
90
|
var BlinkContext = createContext(null);
|
|
@@ -492,6 +494,7 @@ __export(api_exports, {
|
|
|
492
494
|
getGuestTransfer: () => getGuestTransfer,
|
|
493
495
|
getTransferByGuestToken: () => getTransferByGuestToken,
|
|
494
496
|
postGuestTransferFeeQuote: () => postGuestTransferFeeQuote,
|
|
497
|
+
postTransferQuote: () => postTransferQuote,
|
|
495
498
|
putGuestTransferSender: () => putGuestTransferSender,
|
|
496
499
|
registerPasskey: () => registerPasskey,
|
|
497
500
|
reportActionCompletion: () => reportActionCompletion,
|
|
@@ -607,7 +610,8 @@ async function createTransfer(apiBaseUrl, token, params) {
|
|
|
607
610
|
amount: {
|
|
608
611
|
amount: params.amount,
|
|
609
612
|
currency: params.currency ?? "USD"
|
|
610
|
-
}
|
|
613
|
+
},
|
|
614
|
+
...params.quoteId ? { quoteId: params.quoteId } : {}
|
|
611
615
|
};
|
|
612
616
|
const res = await fetch(`${apiBaseUrl}/v1/transfers`, {
|
|
613
617
|
method: "POST",
|
|
@@ -620,6 +624,28 @@ async function createTransfer(apiBaseUrl, token, params) {
|
|
|
620
624
|
if (!res.ok) await throwApiError(res);
|
|
621
625
|
return await res.json();
|
|
622
626
|
}
|
|
627
|
+
async function postTransferQuote(apiBaseUrl, bearerToken, params) {
|
|
628
|
+
const body = {
|
|
629
|
+
walletId: params.walletId,
|
|
630
|
+
...params.sourceTokenAddress ? { sourceTokenAddress: params.sourceTokenAddress } : {},
|
|
631
|
+
destination: {
|
|
632
|
+
chainId: params.destination.chainId,
|
|
633
|
+
token: { address: params.destination.token.address },
|
|
634
|
+
address: params.destination.address
|
|
635
|
+
},
|
|
636
|
+
amount: params.amount
|
|
637
|
+
};
|
|
638
|
+
const res = await fetch(`${apiBaseUrl}/v1/transfers/quotes`, {
|
|
639
|
+
method: "POST",
|
|
640
|
+
headers: {
|
|
641
|
+
"Content-Type": "application/json",
|
|
642
|
+
Authorization: `Bearer ${bearerToken}`
|
|
643
|
+
},
|
|
644
|
+
body: JSON.stringify(body)
|
|
645
|
+
});
|
|
646
|
+
if (!res.ok) await throwApiError(res);
|
|
647
|
+
return await res.json();
|
|
648
|
+
}
|
|
623
649
|
async function fetchMerchantPublicKey(apiBaseUrl, merchantId) {
|
|
624
650
|
const res = await fetch(
|
|
625
651
|
`${apiBaseUrl}/v1/merchants/${encodeURIComponent(merchantId)}/public-key`
|
|
@@ -961,6 +987,23 @@ function normalizeSignature(sig) {
|
|
|
961
987
|
);
|
|
962
988
|
}
|
|
963
989
|
|
|
990
|
+
// src/authorizationErrors.ts
|
|
991
|
+
var AuthorizationSessionCancelledError = class extends Error {
|
|
992
|
+
constructor() {
|
|
993
|
+
super("Authorization session cancelled");
|
|
994
|
+
this.name = "AuthorizationSessionCancelledError";
|
|
995
|
+
}
|
|
996
|
+
};
|
|
997
|
+
function isAuthorizationSessionCancelled(err) {
|
|
998
|
+
if (err instanceof AuthorizationSessionCancelledError) return true;
|
|
999
|
+
return typeof err === "object" && err !== null && "name" in err && err.name === "AuthorizationSessionCancelledError";
|
|
1000
|
+
}
|
|
1001
|
+
function isUserDismissedAuthorizationError(err) {
|
|
1002
|
+
if (!(err instanceof Error)) return false;
|
|
1003
|
+
const m = err.message.toLowerCase();
|
|
1004
|
+
return m.includes("authorization session aborted") || m.includes("aborted by user");
|
|
1005
|
+
}
|
|
1006
|
+
|
|
964
1007
|
// src/hooks/authorizationExecutor.ts
|
|
965
1008
|
var WALLET_CLIENT_MAX_ATTEMPTS = 25;
|
|
966
1009
|
var WALLET_CLIENT_POLL_MS = 400;
|
|
@@ -1274,39 +1317,80 @@ function useAuthorizationExecutor(options) {
|
|
|
1274
1317
|
const [error, setError] = useState(null);
|
|
1275
1318
|
const [currentAction, setCurrentAction] = useState(null);
|
|
1276
1319
|
const executingRef = useRef(false);
|
|
1320
|
+
const oneTapPauseActiveRef = useRef(false);
|
|
1321
|
+
const sessionStackRef = useRef([]);
|
|
1322
|
+
const [authorizationSessionStackDepth, setAuthorizationSessionStackDepth] = useState(0);
|
|
1277
1323
|
const [pendingSelectSource, setPendingSelectSource] = useState(null);
|
|
1278
1324
|
const selectSourceResolverRef = useRef(null);
|
|
1325
|
+
const selectSourceRejectRef = useRef(null);
|
|
1279
1326
|
const sessionIdRef = useRef(null);
|
|
1280
1327
|
const resolveSelectSource = useCallback((selection) => {
|
|
1281
1328
|
if (selectSourceResolverRef.current) {
|
|
1282
1329
|
selectSourceResolverRef.current(selection);
|
|
1283
1330
|
selectSourceResolverRef.current = null;
|
|
1331
|
+
selectSourceRejectRef.current = null;
|
|
1284
1332
|
setPendingSelectSource(null);
|
|
1285
1333
|
}
|
|
1286
1334
|
}, []);
|
|
1287
1335
|
const waitForSelection = useCallback(
|
|
1288
|
-
(action) => new Promise((resolve) => {
|
|
1289
|
-
selectSourceResolverRef.current =
|
|
1336
|
+
(action) => new Promise((resolve, reject) => {
|
|
1337
|
+
selectSourceResolverRef.current = (selection) => {
|
|
1338
|
+
resolve(selection);
|
|
1339
|
+
selectSourceResolverRef.current = null;
|
|
1340
|
+
selectSourceRejectRef.current = null;
|
|
1341
|
+
};
|
|
1342
|
+
selectSourceRejectRef.current = reject;
|
|
1290
1343
|
setPendingSelectSource(action);
|
|
1291
1344
|
}),
|
|
1292
1345
|
[]
|
|
1293
1346
|
);
|
|
1294
1347
|
const [pendingOneTapSetup, setPendingOneTapSetup] = useState(null);
|
|
1295
1348
|
const oneTapSetupResolverRef = useRef(null);
|
|
1349
|
+
const oneTapSetupRejectRef = useRef(null);
|
|
1296
1350
|
const resolveOneTapSetup = useCallback(() => {
|
|
1297
1351
|
if (oneTapSetupResolverRef.current) {
|
|
1298
1352
|
oneTapSetupResolverRef.current();
|
|
1299
1353
|
oneTapSetupResolverRef.current = null;
|
|
1354
|
+
oneTapSetupRejectRef.current = null;
|
|
1300
1355
|
setPendingOneTapSetup(null);
|
|
1301
1356
|
}
|
|
1302
1357
|
}, []);
|
|
1303
1358
|
const waitForOneTapSetup = useCallback(
|
|
1304
|
-
(action) => new Promise((resolve) => {
|
|
1305
|
-
|
|
1359
|
+
(action) => new Promise((resolve, reject) => {
|
|
1360
|
+
oneTapPauseActiveRef.current = true;
|
|
1361
|
+
oneTapSetupResolverRef.current = () => {
|
|
1362
|
+
oneTapPauseActiveRef.current = false;
|
|
1363
|
+
resolve();
|
|
1364
|
+
oneTapSetupResolverRef.current = null;
|
|
1365
|
+
oneTapSetupRejectRef.current = null;
|
|
1366
|
+
};
|
|
1367
|
+
oneTapSetupRejectRef.current = (reason) => {
|
|
1368
|
+
oneTapPauseActiveRef.current = false;
|
|
1369
|
+
reject(reason);
|
|
1370
|
+
};
|
|
1306
1371
|
setPendingOneTapSetup(action);
|
|
1307
1372
|
}),
|
|
1308
1373
|
[]
|
|
1309
1374
|
);
|
|
1375
|
+
const cancelPendingExecution = useCallback(() => {
|
|
1376
|
+
if (selectSourceRejectRef.current) {
|
|
1377
|
+
selectSourceRejectRef.current(new AuthorizationSessionCancelledError());
|
|
1378
|
+
selectSourceRejectRef.current = null;
|
|
1379
|
+
selectSourceResolverRef.current = null;
|
|
1380
|
+
setPendingSelectSource(null);
|
|
1381
|
+
}
|
|
1382
|
+
if (oneTapSetupRejectRef.current) {
|
|
1383
|
+
oneTapPauseActiveRef.current = false;
|
|
1384
|
+
oneTapSetupRejectRef.current(new AuthorizationSessionCancelledError());
|
|
1385
|
+
oneTapSetupRejectRef.current = null;
|
|
1386
|
+
oneTapSetupResolverRef.current = null;
|
|
1387
|
+
setPendingOneTapSetup(null);
|
|
1388
|
+
}
|
|
1389
|
+
setError(null);
|
|
1390
|
+
setCurrentAction(null);
|
|
1391
|
+
setExecuting(false);
|
|
1392
|
+
executingRef.current = false;
|
|
1393
|
+
}, []);
|
|
1310
1394
|
const dispatchAction = useCallback(
|
|
1311
1395
|
async (action) => {
|
|
1312
1396
|
setCurrentAction(action);
|
|
@@ -1341,20 +1425,26 @@ function useAuthorizationExecutor(options) {
|
|
|
1341
1425
|
);
|
|
1342
1426
|
const executeSessionById = useCallback(
|
|
1343
1427
|
async (sessionId) => {
|
|
1344
|
-
if (executingRef.current) return;
|
|
1345
|
-
executingRef.current = true;
|
|
1346
1428
|
if (!sessionId) {
|
|
1347
|
-
executingRef.current = false;
|
|
1348
1429
|
throw new Error("No authorization session id provided.");
|
|
1349
1430
|
}
|
|
1350
1431
|
if (!apiBaseUrl) {
|
|
1351
|
-
executingRef.current = false;
|
|
1352
1432
|
throw new Error("Missing apiBaseUrl. Provide useAuthorizationExecutor({ apiBaseUrl }) or wrap in <BlinkProvider>.");
|
|
1353
1433
|
}
|
|
1354
|
-
|
|
1355
|
-
|
|
1434
|
+
const allowNested = executingRef.current && oneTapPauseActiveRef.current;
|
|
1435
|
+
if (executingRef.current && !allowNested) {
|
|
1436
|
+
return;
|
|
1437
|
+
}
|
|
1438
|
+
const isNestedRun = allowNested;
|
|
1439
|
+
if (!isNestedRun) {
|
|
1440
|
+
executingRef.current = true;
|
|
1441
|
+
setExecuting(true);
|
|
1442
|
+
setResults([]);
|
|
1443
|
+
}
|
|
1356
1444
|
setError(null);
|
|
1357
|
-
|
|
1445
|
+
sessionStackRef.current.push(sessionId);
|
|
1446
|
+
setAuthorizationSessionStackDepth(sessionStackRef.current.length);
|
|
1447
|
+
sessionIdRef.current = sessionId;
|
|
1358
1448
|
try {
|
|
1359
1449
|
let session = await fetchAuthorizationSession(apiBaseUrl, sessionId);
|
|
1360
1450
|
const allResults = [];
|
|
@@ -1390,13 +1480,23 @@ function useAuthorizationExecutor(options) {
|
|
|
1390
1480
|
pending = getPendingActions(session, completedIds);
|
|
1391
1481
|
}
|
|
1392
1482
|
} catch (err) {
|
|
1393
|
-
|
|
1394
|
-
|
|
1483
|
+
if (isAuthorizationSessionCancelled(err)) {
|
|
1484
|
+
setError(null);
|
|
1485
|
+
} else {
|
|
1486
|
+
const msg = err instanceof Error ? err.message : "Authorization failed";
|
|
1487
|
+
setError(msg);
|
|
1488
|
+
}
|
|
1395
1489
|
throw err;
|
|
1396
1490
|
} finally {
|
|
1491
|
+
sessionStackRef.current.pop();
|
|
1492
|
+
const depth = sessionStackRef.current.length;
|
|
1493
|
+
setAuthorizationSessionStackDepth(depth);
|
|
1494
|
+
sessionIdRef.current = depth > 0 ? sessionStackRef.current[depth - 1] : null;
|
|
1397
1495
|
setCurrentAction(null);
|
|
1398
|
-
|
|
1399
|
-
|
|
1496
|
+
if (depth === 0) {
|
|
1497
|
+
setExecuting(false);
|
|
1498
|
+
executingRef.current = false;
|
|
1499
|
+
}
|
|
1400
1500
|
}
|
|
1401
1501
|
},
|
|
1402
1502
|
[apiBaseUrl, dispatchAction]
|
|
@@ -1410,7 +1510,9 @@ function useAuthorizationExecutor(options) {
|
|
|
1410
1510
|
resolveSelectSource,
|
|
1411
1511
|
pendingOneTapSetup,
|
|
1412
1512
|
resolveOneTapSetup,
|
|
1413
|
-
executeSessionById
|
|
1513
|
+
executeSessionById,
|
|
1514
|
+
cancelPendingExecution,
|
|
1515
|
+
authorizationSessionStackDepth
|
|
1414
1516
|
};
|
|
1415
1517
|
}
|
|
1416
1518
|
var TRANSFER_SIGN_MAX_POLLS = 60;
|
|
@@ -1640,6 +1742,37 @@ function getPreferredDepositWallet(account, transferAmount) {
|
|
|
1640
1742
|
function getDepositEligibleAccounts(accounts) {
|
|
1641
1743
|
return accounts.filter((account) => getAddressableWallets(account).length > 0);
|
|
1642
1744
|
}
|
|
1745
|
+
function resolveDepositSelectionAfterRefresh(accounts, transferAmount, prev) {
|
|
1746
|
+
const { selectedAccountId, selectedWalletId, selectedTokenSymbol } = prev;
|
|
1747
|
+
if (selectedAccountId && selectedWalletId) {
|
|
1748
|
+
const acct = accounts.find((a) => a.id === selectedAccountId);
|
|
1749
|
+
const wallet = acct?.wallets.find((w) => w.id === selectedWalletId);
|
|
1750
|
+
if (wallet) {
|
|
1751
|
+
if (selectedTokenSymbol) {
|
|
1752
|
+
const hasToken = wallet.sources.some((s) => s.token.symbol === selectedTokenSymbol);
|
|
1753
|
+
if (hasToken) {
|
|
1754
|
+
return {
|
|
1755
|
+
defaults: { accountId: selectedAccountId, walletId: selectedWalletId },
|
|
1756
|
+
resetSelectedTokenSymbol: false
|
|
1757
|
+
};
|
|
1758
|
+
}
|
|
1759
|
+
const fallback = resolveDepositSelection(accounts, transferAmount, selectedAccountId);
|
|
1760
|
+
return {
|
|
1761
|
+
defaults: fallback,
|
|
1762
|
+
resetSelectedTokenSymbol: true
|
|
1763
|
+
};
|
|
1764
|
+
}
|
|
1765
|
+
return {
|
|
1766
|
+
defaults: { accountId: selectedAccountId, walletId: selectedWalletId },
|
|
1767
|
+
resetSelectedTokenSymbol: false
|
|
1768
|
+
};
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
return {
|
|
1772
|
+
defaults: resolveDepositSelection(accounts, transferAmount, selectedAccountId),
|
|
1773
|
+
resetSelectedTokenSymbol: false
|
|
1774
|
+
};
|
|
1775
|
+
}
|
|
1643
1776
|
function resolveDepositSelection(accounts, transferAmount, selectedAccountId) {
|
|
1644
1777
|
const eligibleAccounts = getDepositEligibleAccounts(accounts);
|
|
1645
1778
|
if (eligibleAccounts.length === 0) return null;
|
|
@@ -1706,6 +1839,32 @@ function buildSelectSourceChoices(options) {
|
|
|
1706
1839
|
tokens: chain.tokens.filter((t) => t.balance > 0).sort((a, b) => b.balance - a.balance)
|
|
1707
1840
|
})).filter((chain) => chain.tokens.length > 0).sort((a, b) => b.balance - a.balance);
|
|
1708
1841
|
}
|
|
1842
|
+
function resolveSelectSourceAvailableBalance(choices, options, chainName, tokenSymbol, recommended) {
|
|
1843
|
+
const chain = chainName.trim();
|
|
1844
|
+
const token = tokenSymbol.trim();
|
|
1845
|
+
if (chain && token) {
|
|
1846
|
+
const chainChoice = choices.find((c) => c.chainName === chain);
|
|
1847
|
+
const row = chainChoice?.tokens.find((t) => t.tokenSymbol === token);
|
|
1848
|
+
if (row !== void 0) return row.balance;
|
|
1849
|
+
const direct = options.find(
|
|
1850
|
+
(opt) => opt.chainName === chain && opt.tokenSymbol === token
|
|
1851
|
+
);
|
|
1852
|
+
if (direct) return parseRawBalance(direct.rawBalance, direct.decimals);
|
|
1853
|
+
return 0;
|
|
1854
|
+
}
|
|
1855
|
+
if (recommended) {
|
|
1856
|
+
const match = options.find(
|
|
1857
|
+
(opt) => opt.chainName === recommended.chainName && opt.tokenSymbol === recommended.tokenSymbol
|
|
1858
|
+
);
|
|
1859
|
+
if (match) return parseRawBalance(match.rawBalance, match.decimals);
|
|
1860
|
+
}
|
|
1861
|
+
let max = 0;
|
|
1862
|
+
for (const opt of options) {
|
|
1863
|
+
const bal = parseRawBalance(opt.rawBalance, opt.decimals);
|
|
1864
|
+
if (bal > max) max = bal;
|
|
1865
|
+
}
|
|
1866
|
+
return max;
|
|
1867
|
+
}
|
|
1709
1868
|
|
|
1710
1869
|
// src/walletFlow.ts
|
|
1711
1870
|
var MOBILE_USER_AGENT_PATTERN = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
|
|
@@ -1790,10 +1949,11 @@ function resolvePhase(state) {
|
|
|
1790
1949
|
const walletPickerSwitchEligible = currentPhase.step === "wallet-picker" && currentPhase.reason === "switch" && !state.creatingTransfer && !(state.mobileFlow && state.deeplinkUri);
|
|
1791
1950
|
const missingActivePasskeyCredential = state.passkeyConfigLoaded && !state.activeCredentialId;
|
|
1792
1951
|
const shouldPromptPasskeyVerification = missingActivePasskeyCredential && state.knownCredentialIds.length > 0 && state.passkeyPopupNeeded;
|
|
1952
|
+
const guestPreauthClaimPending = state.guestPreauthAccountId != null && state.guestSessionToken != null && state.privyAuthenticated && state.activeCredentialId != null && !state.guestPreauthSetupCompletePending && !state.error;
|
|
1793
1953
|
const branchGuestSetupComplete = state.guestPreauthSetupCompletePending && state.privyReady && state.privyAuthenticated;
|
|
1794
1954
|
const branchKeepGuestPreauthPin = !branchGuestSetupComplete && guestPreauthPinsCurrentPhase;
|
|
1795
1955
|
const branchGuestPostPayLogin = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && guestPostPayLogin;
|
|
1796
|
-
const branchCompleted = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && transferCompleted && !state.verificationTarget && !needsPasskeyBootstrap;
|
|
1956
|
+
const branchCompleted = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && transferCompleted && !state.verificationTarget && !needsPasskeyBootstrap && !guestPreauthClaimPending && !state.loginRequested;
|
|
1797
1957
|
const branchFailed = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && state.transfer?.status === "FAILED";
|
|
1798
1958
|
const branchProcessing = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && (state.creatingTransfer || isTransferAwaitingCompletion(state.transfer));
|
|
1799
1959
|
const branchStandardDesktopInlineOpenWallet = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && state.standardDesktopInlineOpenWallet && state.privyAuthenticated && state.activeCredentialId != null && state.selectedAccountId != null && !state.loginRequested && !state.guestPreauthorizing;
|
|
@@ -1809,7 +1969,7 @@ function resolvePhase(state) {
|
|
|
1809
1969
|
const branchLoginRequested = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && state.loginRequested;
|
|
1810
1970
|
const branchPasskeyVerify = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && shouldPromptPasskeyVerification;
|
|
1811
1971
|
const branchPasskeyCreate = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && !branchPasskeyVerify && missingActivePasskeyCredential;
|
|
1812
|
-
const branchGuestPreauthClaiming = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && !branchPasskeyVerify && !branchPasskeyCreate &&
|
|
1972
|
+
const branchGuestPreauthClaiming = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && !branchPasskeyVerify && !branchPasskeyCreate && guestPreauthClaimPending;
|
|
1813
1973
|
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);
|
|
1814
1974
|
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;
|
|
1815
1975
|
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;
|
|
@@ -1980,6 +2140,7 @@ function createInitialState(config) {
|
|
|
1980
2140
|
selectedAccountId: null,
|
|
1981
2141
|
selectedWalletId: null,
|
|
1982
2142
|
selectedTokenSymbol: null,
|
|
2143
|
+
savedSelection: null,
|
|
1983
2144
|
amount: config.depositAmount != null ? config.depositAmount.toString() : "",
|
|
1984
2145
|
transfer: null,
|
|
1985
2146
|
creatingTransfer: false,
|
|
@@ -2006,7 +2167,8 @@ function createInitialState(config) {
|
|
|
2006
2167
|
standardDesktopInlineOpenWallet: false,
|
|
2007
2168
|
guestPreauthSetupCompletePending: false,
|
|
2008
2169
|
privyReady: false,
|
|
2009
|
-
privyAuthenticated: false
|
|
2170
|
+
privyAuthenticated: false,
|
|
2171
|
+
lastResumedAt: 0
|
|
2010
2172
|
};
|
|
2011
2173
|
}
|
|
2012
2174
|
function paymentReducer(state, action) {
|
|
@@ -2104,6 +2266,9 @@ function applyAction(state, action) {
|
|
|
2104
2266
|
next.mobileFlow = false;
|
|
2105
2267
|
next.deeplinkUri = null;
|
|
2106
2268
|
}
|
|
2269
|
+
if (action.resetSelectedTokenSymbol) {
|
|
2270
|
+
next.selectedTokenSymbol = null;
|
|
2271
|
+
}
|
|
2107
2272
|
return next;
|
|
2108
2273
|
}
|
|
2109
2274
|
case "DATA_LOAD_END":
|
|
@@ -2118,8 +2283,43 @@ function applyAction(state, action) {
|
|
|
2118
2283
|
next.selectedAccountId = action.defaults.accountId;
|
|
2119
2284
|
next.selectedWalletId = action.defaults.walletId;
|
|
2120
2285
|
}
|
|
2286
|
+
if (action.resetSelectedTokenSymbol) {
|
|
2287
|
+
next.selectedTokenSymbol = null;
|
|
2288
|
+
}
|
|
2121
2289
|
return next;
|
|
2122
2290
|
}
|
|
2291
|
+
case "SAVE_SELECTION":
|
|
2292
|
+
return {
|
|
2293
|
+
...state,
|
|
2294
|
+
savedSelection: {
|
|
2295
|
+
selectedProviderId: state.selectedProviderId,
|
|
2296
|
+
selectedAccountId: state.selectedAccountId,
|
|
2297
|
+
selectedWalletId: state.selectedWalletId,
|
|
2298
|
+
selectedTokenSymbol: state.selectedTokenSymbol
|
|
2299
|
+
}
|
|
2300
|
+
};
|
|
2301
|
+
case "RESTORE_SELECTION": {
|
|
2302
|
+
const snap = state.savedSelection;
|
|
2303
|
+
if (!snap) {
|
|
2304
|
+
return {
|
|
2305
|
+
...state,
|
|
2306
|
+
error: null,
|
|
2307
|
+
increasingLimit: false
|
|
2308
|
+
};
|
|
2309
|
+
}
|
|
2310
|
+
return {
|
|
2311
|
+
...state,
|
|
2312
|
+
selectedProviderId: snap.selectedProviderId,
|
|
2313
|
+
selectedAccountId: snap.selectedAccountId,
|
|
2314
|
+
selectedWalletId: snap.selectedWalletId,
|
|
2315
|
+
selectedTokenSymbol: snap.selectedTokenSymbol,
|
|
2316
|
+
savedSelection: null,
|
|
2317
|
+
error: null,
|
|
2318
|
+
increasingLimit: false
|
|
2319
|
+
};
|
|
2320
|
+
}
|
|
2321
|
+
case "DISCARD_SAVED_SELECTION":
|
|
2322
|
+
return { ...state, savedSelection: null };
|
|
2123
2323
|
// ── Source selection ──────────────────────────────────────────
|
|
2124
2324
|
case "SELECT_PROVIDER":
|
|
2125
2325
|
return {
|
|
@@ -2414,7 +2614,8 @@ function applyAction(state, action) {
|
|
|
2414
2614
|
oneTapLimitSavedDuringSetup: false,
|
|
2415
2615
|
guestPreauthorizing: false,
|
|
2416
2616
|
guestPreauthSetupCompletePending: false,
|
|
2417
|
-
standardDesktopInlineOpenWallet: false
|
|
2617
|
+
standardDesktopInlineOpenWallet: false,
|
|
2618
|
+
savedSelection: null
|
|
2418
2619
|
};
|
|
2419
2620
|
case "LOGOUT":
|
|
2420
2621
|
return {
|
|
@@ -2437,6 +2638,8 @@ function applyAction(state, action) {
|
|
|
2437
2638
|
};
|
|
2438
2639
|
case "SYNC_AMOUNT":
|
|
2439
2640
|
return { ...state, amount: action.amount };
|
|
2641
|
+
case "PAGE_RESUMED":
|
|
2642
|
+
return { ...state, lastResumedAt: Date.now() };
|
|
2440
2643
|
default:
|
|
2441
2644
|
return state;
|
|
2442
2645
|
}
|
|
@@ -2526,6 +2729,41 @@ function screenForPhase(phase) {
|
|
|
2526
2729
|
return "guest-preauth-linking";
|
|
2527
2730
|
}
|
|
2528
2731
|
}
|
|
2732
|
+
|
|
2733
|
+
// src/depositTokenSelection.ts
|
|
2734
|
+
function tokenOptionsForLinkedAccount(selectedAccount, chains) {
|
|
2735
|
+
if (!selectedAccount) return [];
|
|
2736
|
+
return selectedAccount.wallets.flatMap((w) => {
|
|
2737
|
+
const evmChainId = chains.find((c) => c.name === w.chain.name)?.commonId ?? void 0;
|
|
2738
|
+
return w.sources.filter((s) => s.balance.total.amount > 0).map((s) => ({
|
|
2739
|
+
symbol: s.token.symbol,
|
|
2740
|
+
chainName: w.chain.name,
|
|
2741
|
+
balance: s.balance.available.amount,
|
|
2742
|
+
walletId: w.id,
|
|
2743
|
+
status: s.token.status,
|
|
2744
|
+
tokenAddress: s.address,
|
|
2745
|
+
chainId: evmChainId
|
|
2746
|
+
}));
|
|
2747
|
+
});
|
|
2748
|
+
}
|
|
2749
|
+
function handleInlineTokenSelection(handlers, chains, selectedAccount, symbol, chainName, walletId) {
|
|
2750
|
+
if (walletId && selectedAccount) {
|
|
2751
|
+
const wallet = selectedAccount.wallets.find((w) => w.id === walletId);
|
|
2752
|
+
if (wallet && wallet.chain.name === chainName) {
|
|
2753
|
+
const source = wallet.sources.find((s) => s.token.symbol === symbol);
|
|
2754
|
+
const evmChainId = chains.find((c) => c.name === chainName)?.commonId ?? void 0;
|
|
2755
|
+
const authorized = !source?.token.status || source.token.status === "AUTHORIZED";
|
|
2756
|
+
if (source && !authorized && source.address && evmChainId != null) {
|
|
2757
|
+
void handlers.onAuthorizeToken(walletId, source.address, evmChainId, symbol);
|
|
2758
|
+
return;
|
|
2759
|
+
}
|
|
2760
|
+
}
|
|
2761
|
+
handlers.onSelectAuthorizedToken(walletId, symbol);
|
|
2762
|
+
return;
|
|
2763
|
+
}
|
|
2764
|
+
handlers.onSelectSourceChainChange(chainName);
|
|
2765
|
+
handlers.onSetSelectSourceTokenSymbol(symbol);
|
|
2766
|
+
}
|
|
2529
2767
|
var MUTED = "#7fa4b0";
|
|
2530
2768
|
var LOGO_SIZE = 48;
|
|
2531
2769
|
function BlinkLoadingScreen() {
|
|
@@ -4078,6 +4316,22 @@ var loginButtonStyle = (accentColor) => ({
|
|
|
4078
4316
|
fontFamily: "inherit",
|
|
4079
4317
|
textDecoration: "underline"
|
|
4080
4318
|
});
|
|
4319
|
+
|
|
4320
|
+
// src/setupScreenSelection.ts
|
|
4321
|
+
function matchesSetupTokenSelection(opt, selectedTokenSymbol, selectedChainName, allOptions) {
|
|
4322
|
+
if (!selectedTokenSymbol || opt.symbol !== selectedTokenSymbol) {
|
|
4323
|
+
return false;
|
|
4324
|
+
}
|
|
4325
|
+
const chain = selectedChainName?.trim();
|
|
4326
|
+
if (chain) {
|
|
4327
|
+
return opt.chainName === chain;
|
|
4328
|
+
}
|
|
4329
|
+
const sameSymbol = allOptions.filter((o) => o.symbol === selectedTokenSymbol);
|
|
4330
|
+
if (sameSymbol.length === 1) {
|
|
4331
|
+
return opt.chainName === sameSymbol[0].chainName;
|
|
4332
|
+
}
|
|
4333
|
+
return false;
|
|
4334
|
+
}
|
|
4081
4335
|
var DEFAULT_MAX = 1e7;
|
|
4082
4336
|
var ABSOLUTE_MIN = 0.01;
|
|
4083
4337
|
var PRESETS = [100, 250, 1e3];
|
|
@@ -4093,13 +4347,16 @@ function SetupScreen({
|
|
|
4093
4347
|
loading,
|
|
4094
4348
|
error,
|
|
4095
4349
|
selectedTokenSymbol,
|
|
4350
|
+
selectedChainName,
|
|
4096
4351
|
tokenOptions,
|
|
4097
4352
|
onSelectToken
|
|
4098
4353
|
}) {
|
|
4099
4354
|
const { tokens } = useBlinkConfig();
|
|
4100
4355
|
const effectiveMax = DEFAULT_MAX;
|
|
4101
4356
|
const effectiveMin = Math.min(ABSOLUTE_MIN, effectiveMax);
|
|
4102
|
-
const
|
|
4357
|
+
const autoLimit = Math.min(Math.max(availableBalance, 0), effectiveMax);
|
|
4358
|
+
const [userChosenLimit, setUserChosenLimit] = useState(null);
|
|
4359
|
+
const limit = userChosenLimit ?? autoLimit;
|
|
4103
4360
|
const [activePreset, setActivePreset] = useState(null);
|
|
4104
4361
|
const [showAdvanced, setShowAdvanced] = useState(false);
|
|
4105
4362
|
const [editing, setEditing] = useState(false);
|
|
@@ -4138,20 +4395,22 @@ function SetupScreen({
|
|
|
4138
4395
|
const commitEdit = useCallback(() => {
|
|
4139
4396
|
const parsed = parseFloat(inputValue);
|
|
4140
4397
|
if (!isNaN(parsed)) {
|
|
4141
|
-
|
|
4398
|
+
setUserChosenLimit(
|
|
4399
|
+
Math.min(effectiveMax, Math.max(effectiveMin, Math.round(parsed * 100) / 100))
|
|
4400
|
+
);
|
|
4142
4401
|
}
|
|
4143
4402
|
setActivePreset(null);
|
|
4144
4403
|
setEditing(false);
|
|
4145
4404
|
}, [inputValue, effectiveMax, effectiveMin]);
|
|
4146
4405
|
const selectPreset = (value) => {
|
|
4147
|
-
|
|
4406
|
+
setUserChosenLimit(Math.min(value, effectiveMax));
|
|
4148
4407
|
setActivePreset(value);
|
|
4149
4408
|
};
|
|
4150
4409
|
const selectMax = () => {
|
|
4151
|
-
|
|
4410
|
+
setUserChosenLimit(autoLimit);
|
|
4152
4411
|
setActivePreset("max");
|
|
4153
4412
|
};
|
|
4154
|
-
const
|
|
4413
|
+
const options = tokenOptions ?? [];
|
|
4155
4414
|
return /* @__PURE__ */ jsxs(
|
|
4156
4415
|
ScreenLayout,
|
|
4157
4416
|
{
|
|
@@ -4184,12 +4443,7 @@ function SetupScreen({
|
|
|
4184
4443
|
children: [
|
|
4185
4444
|
/* @__PURE__ */ jsx("span", { style: tokenRowLabelStyle(tokens.text), children: "Token for one tap" }),
|
|
4186
4445
|
/* @__PURE__ */ jsxs("div", { style: tokenRowRightStyle, children: [
|
|
4187
|
-
|
|
4188
|
-
selectedOption.symbol,
|
|
4189
|
-
" \xB7 ",
|
|
4190
|
-
selectedOption.chainName
|
|
4191
|
-
] }),
|
|
4192
|
-
/* @__PURE__ */ jsx("div", { style: tokenIconWrapStyle, children: selectedTokenSymbol && TOKEN_LOGOS[selectedTokenSymbol] ? /* @__PURE__ */ jsx("img", { src: TOKEN_LOGOS[selectedTokenSymbol], alt: selectedTokenSymbol, width: 36, height: 36, style: { borderRadius: "50%" } }) : /* @__PURE__ */ jsxs("svg", { width: "36", height: "36", viewBox: "0 0 36 36", fill: "none", children: [
|
|
4446
|
+
/* @__PURE__ */ jsx("div", { style: tokenIconWrapStyle, children: selectedTokenSymbol && TOKEN_LOGOS[selectedTokenSymbol] ? /* @__PURE__ */ jsx("img", { src: TOKEN_LOGOS[selectedTokenSymbol], alt: "", width: 36, height: 36, style: { borderRadius: "50%" } }) : /* @__PURE__ */ jsxs("svg", { width: "36", height: "36", viewBox: "0 0 36 36", fill: "none", children: [
|
|
4193
4447
|
/* @__PURE__ */ jsx("circle", { cx: "18", cy: "18", r: "18", fill: "#2DB84B" }),
|
|
4194
4448
|
/* @__PURE__ */ jsx("text", { x: "18", y: "23", textAnchor: "middle", fontSize: "18", fill: "#fff", fontWeight: "700", children: "$" })
|
|
4195
4449
|
] }) }),
|
|
@@ -4201,14 +4455,21 @@ function SetupScreen({
|
|
|
4201
4455
|
tokenDropdownOpen && tokenOptions && tokenOptions.length > 0 && /* @__PURE__ */ jsxs("div", { style: dropdownOuterStyle(tokens), children: [
|
|
4202
4456
|
/* @__PURE__ */ jsx("div", { style: dropdownLabelStyle(tokens.textMuted), children: "Choose token" }),
|
|
4203
4457
|
/* @__PURE__ */ jsx("div", { style: dropdownInnerStyle(tokens), children: tokenOptions.map((opt, index) => {
|
|
4204
|
-
const selected =
|
|
4458
|
+
const selected = matchesSetupTokenSelection(
|
|
4459
|
+
opt,
|
|
4460
|
+
selectedTokenSymbol,
|
|
4461
|
+
selectedChainName,
|
|
4462
|
+
options
|
|
4463
|
+
);
|
|
4205
4464
|
const isLast = index === tokenOptions.length - 1;
|
|
4465
|
+
const authorized = !opt.status || opt.status === "AUTHORIZED";
|
|
4206
4466
|
return /* @__PURE__ */ jsxs(
|
|
4207
4467
|
"button",
|
|
4208
4468
|
{
|
|
4209
4469
|
type: "button",
|
|
4210
4470
|
onClick: () => handlePickToken(opt),
|
|
4211
4471
|
style: dropdownRowStyle(tokens, selected, isLast),
|
|
4472
|
+
"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" : ""}`,
|
|
4212
4473
|
children: [
|
|
4213
4474
|
/* @__PURE__ */ jsxs("div", { style: dropdownRowLeftStyle, children: [
|
|
4214
4475
|
/* @__PURE__ */ jsx("div", { style: dropdownTokenIconStyle(tokens, !!TOKEN_LOGOS[opt.symbol]), children: TOKEN_LOGOS[opt.symbol] ? /* @__PURE__ */ jsx("img", { src: TOKEN_LOGOS[opt.symbol], alt: opt.symbol, style: dropdownTokenLogoStyle }) : /* @__PURE__ */ jsx("span", { style: dropdownTokenFallbackStyle(tokens.textMuted), children: "$" }) }),
|
|
@@ -4218,9 +4479,12 @@ function SetupScreen({
|
|
|
4218
4479
|
/* @__PURE__ */ jsx("span", { style: dropdownTokenDotStyle(tokens.textMuted), children: "\xB7" }),
|
|
4219
4480
|
/* @__PURE__ */ jsx("span", { style: dropdownTokenChainStyle(tokens.textMuted), children: opt.chainName })
|
|
4220
4481
|
] }),
|
|
4221
|
-
|
|
4222
|
-
"
|
|
4223
|
-
|
|
4482
|
+
/* @__PURE__ */ jsxs("div", { style: dropdownTokenBalanceRowStyle, children: [
|
|
4483
|
+
opt.balance != null && /* @__PURE__ */ jsxs("span", { style: dropdownTokenBalanceStyle(tokens.textMuted), children: [
|
|
4484
|
+
"$",
|
|
4485
|
+
opt.balance.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
|
4486
|
+
] }),
|
|
4487
|
+
!authorized && /* @__PURE__ */ jsx("span", { style: dropdownNotAuthorizedStyle(tokens.textMuted), children: "Not authorized" })
|
|
4224
4488
|
] })
|
|
4225
4489
|
] })
|
|
4226
4490
|
] }),
|
|
@@ -4340,11 +4604,6 @@ var tokenRowRightStyle = {
|
|
|
4340
4604
|
gap: 6,
|
|
4341
4605
|
flexShrink: 0
|
|
4342
4606
|
};
|
|
4343
|
-
var tokenRowSymbolStyle = (color) => ({
|
|
4344
|
-
fontSize: "0.84rem",
|
|
4345
|
-
fontWeight: 500,
|
|
4346
|
-
color
|
|
4347
|
-
});
|
|
4348
4607
|
var advancedToggleStyle = (accentColor) => ({
|
|
4349
4608
|
display: "block",
|
|
4350
4609
|
margin: "4px auto 24px",
|
|
@@ -4492,10 +4751,20 @@ var dropdownTokenChainStyle = (color) => ({
|
|
|
4492
4751
|
fontWeight: 400,
|
|
4493
4752
|
color
|
|
4494
4753
|
});
|
|
4754
|
+
var dropdownTokenBalanceRowStyle = {
|
|
4755
|
+
display: "flex",
|
|
4756
|
+
alignItems: "center",
|
|
4757
|
+
gap: 8
|
|
4758
|
+
};
|
|
4495
4759
|
var dropdownTokenBalanceStyle = (color) => ({
|
|
4496
4760
|
fontSize: "0.78rem",
|
|
4497
4761
|
color
|
|
4498
4762
|
});
|
|
4763
|
+
var dropdownNotAuthorizedStyle = (color) => ({
|
|
4764
|
+
fontSize: "0.7rem",
|
|
4765
|
+
fontWeight: 500,
|
|
4766
|
+
color
|
|
4767
|
+
});
|
|
4499
4768
|
var dropdownRadioEmptyStyle = (borderColor) => ({
|
|
4500
4769
|
width: 22,
|
|
4501
4770
|
height: 22,
|
|
@@ -4610,6 +4879,38 @@ var waitHintStyle = (color) => ({
|
|
|
4610
4879
|
color,
|
|
4611
4880
|
margin: 0
|
|
4612
4881
|
});
|
|
4882
|
+
|
|
4883
|
+
// src/feeFormat.ts
|
|
4884
|
+
function isPreciseMoneyNonPositive(fee) {
|
|
4885
|
+
const raw = fee.value.trim();
|
|
4886
|
+
if (!/^-?\d+(\.\d*)?$/.test(raw)) return false;
|
|
4887
|
+
const n = Number(raw);
|
|
4888
|
+
return Number.isFinite(n) && n <= 0;
|
|
4889
|
+
}
|
|
4890
|
+
function formatNonPositiveFeeDisplay(fee) {
|
|
4891
|
+
if (fee.currency === "USD") return "Under $0.01";
|
|
4892
|
+
return `Less than 0.01 ${fee.currency}`;
|
|
4893
|
+
}
|
|
4894
|
+
function formatPreciseMoneyForDisplay(fee) {
|
|
4895
|
+
const raw = fee.value.trim();
|
|
4896
|
+
if (fee.currency === "USD") {
|
|
4897
|
+
if (!/^\d+(\.\d*)?$/.test(raw)) {
|
|
4898
|
+
return `$${raw}`;
|
|
4899
|
+
}
|
|
4900
|
+
const [whole, frac = ""] = raw.split(".");
|
|
4901
|
+
const dec = `${frac}00`.slice(0, 2);
|
|
4902
|
+
const intFmt = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
4903
|
+
return `$${intFmt}.${dec}`;
|
|
4904
|
+
}
|
|
4905
|
+
return `${raw} ${fee.currency}`;
|
|
4906
|
+
}
|
|
4907
|
+
function formatUsdTwoDecimals(value) {
|
|
4908
|
+
const n = Number(value);
|
|
4909
|
+
return (Number.isFinite(n) ? n : 0).toLocaleString("en-US", {
|
|
4910
|
+
minimumFractionDigits: 2,
|
|
4911
|
+
maximumFractionDigits: 2
|
|
4912
|
+
});
|
|
4913
|
+
}
|
|
4613
4914
|
function DepositScreen({
|
|
4614
4915
|
merchantName,
|
|
4615
4916
|
availableBalance,
|
|
@@ -4617,6 +4918,8 @@ function DepositScreen({
|
|
|
4617
4918
|
tokenCount,
|
|
4618
4919
|
initialAmount,
|
|
4619
4920
|
minDepositFloor,
|
|
4921
|
+
quoteFee,
|
|
4922
|
+
quoteLoading,
|
|
4620
4923
|
processing,
|
|
4621
4924
|
error,
|
|
4622
4925
|
onDeposit,
|
|
@@ -4631,13 +4934,19 @@ function DepositScreen({
|
|
|
4631
4934
|
onAuthorizeAccount,
|
|
4632
4935
|
onAddProvider,
|
|
4633
4936
|
onSelectToken,
|
|
4937
|
+
tokenOptions,
|
|
4938
|
+
onPickToken,
|
|
4634
4939
|
selectedSourceLabel,
|
|
4635
|
-
selectedTokenSymbol
|
|
4940
|
+
selectedTokenSymbol,
|
|
4941
|
+
selectedChainName
|
|
4636
4942
|
}) {
|
|
4637
4943
|
const { tokens } = useBlinkConfig();
|
|
4638
4944
|
const amount = initialAmount;
|
|
4639
4945
|
const [accountPickerOpen, setAccountPickerOpen] = useState(false);
|
|
4946
|
+
const [tokenPickerOpen, setTokenPickerOpen] = useState(false);
|
|
4640
4947
|
const pickerRef = useRef(null);
|
|
4948
|
+
const tokenPickerRef = useRef(null);
|
|
4949
|
+
const hasTokenDropdown = tokenOptions != null && tokenOptions.length > 0 && onPickToken != null;
|
|
4641
4950
|
useEffect(() => {
|
|
4642
4951
|
if (!accountPickerOpen) return;
|
|
4643
4952
|
const handleClick = (e) => {
|
|
@@ -4648,6 +4957,28 @@ function DepositScreen({
|
|
|
4648
4957
|
document.addEventListener("mousedown", handleClick);
|
|
4649
4958
|
return () => document.removeEventListener("mousedown", handleClick);
|
|
4650
4959
|
}, [accountPickerOpen]);
|
|
4960
|
+
useEffect(() => {
|
|
4961
|
+
if (!tokenPickerOpen) return;
|
|
4962
|
+
const handleMouseDown = (e) => {
|
|
4963
|
+
if (tokenPickerRef.current && !tokenPickerRef.current.contains(e.target)) {
|
|
4964
|
+
setTokenPickerOpen(false);
|
|
4965
|
+
}
|
|
4966
|
+
};
|
|
4967
|
+
document.addEventListener("mousedown", handleMouseDown);
|
|
4968
|
+
return () => document.removeEventListener("mousedown", handleMouseDown);
|
|
4969
|
+
}, [tokenPickerOpen]);
|
|
4970
|
+
const handleTokenBadgeClick = useCallback(() => {
|
|
4971
|
+
if (hasTokenDropdown) {
|
|
4972
|
+
setTokenPickerOpen((v) => !v);
|
|
4973
|
+
setAccountPickerOpen(false);
|
|
4974
|
+
} else {
|
|
4975
|
+
onSelectToken?.();
|
|
4976
|
+
}
|
|
4977
|
+
}, [hasTokenDropdown, onSelectToken]);
|
|
4978
|
+
const handlePickToken = useCallback((opt) => {
|
|
4979
|
+
onPickToken?.(opt.symbol, opt.chainName, opt.walletId);
|
|
4980
|
+
setTokenPickerOpen(false);
|
|
4981
|
+
}, [onPickToken]);
|
|
4651
4982
|
const selectedAccount = accounts?.find((a) => a.id === selectedAccountId);
|
|
4652
4983
|
const selectedProviderName = selectedAccount?.name ?? "Wallet";
|
|
4653
4984
|
const selectedProviderLogo = KNOWN_LOGOS[selectedProviderName.toLowerCase()];
|
|
@@ -4659,36 +4990,95 @@ function DepositScreen({
|
|
|
4659
4990
|
ScreenLayout,
|
|
4660
4991
|
{
|
|
4661
4992
|
footer: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4662
|
-
!accountPickerOpen && (exceedsLimit && onIncreaseLimit ? /* @__PURE__ */ jsx(PrimaryButton, { onClick: onIncreaseLimit, loading: increasingLimit, children: "Increase limit" }) : /* @__PURE__ */ jsx(PrimaryButton, { onClick: () => onDeposit(amount), disabled: !canDeposit, loading: processing, children: "Confirm" })),
|
|
4993
|
+
!accountPickerOpen && !tokenPickerOpen && (exceedsLimit && onIncreaseLimit ? /* @__PURE__ */ jsx(PrimaryButton, { onClick: onIncreaseLimit, loading: increasingLimit, children: "Increase limit" }) : /* @__PURE__ */ jsx(PrimaryButton, { onClick: () => onDeposit(amount), disabled: !canDeposit, loading: processing, children: "Confirm" })),
|
|
4663
4994
|
/* @__PURE__ */ jsx(PoweredByFooter, {})
|
|
4664
4995
|
] }),
|
|
4665
4996
|
children: [
|
|
4666
4997
|
/* @__PURE__ */ jsx(ScreenHeader, { onBack, onLogout }),
|
|
4667
4998
|
/* @__PURE__ */ jsxs("div", { ref: pickerRef, style: depositCardWrapStyle, children: [
|
|
4668
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
4999
|
+
/* @__PURE__ */ jsxs("div", { style: depositCardStyle(tokens), children: [
|
|
4669
5000
|
/* @__PURE__ */ jsx("div", { style: depositLabelStyle(tokens.textMuted), children: "Depositing" }),
|
|
4670
|
-
/* @__PURE__ */ jsxs("div", {
|
|
4671
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
4672
|
-
"
|
|
4673
|
-
|
|
5001
|
+
/* @__PURE__ */ jsxs("div", { ref: tokenPickerRef, children: [
|
|
5002
|
+
/* @__PURE__ */ jsxs("div", { style: amountRowStyle, children: [
|
|
5003
|
+
/* @__PURE__ */ jsxs("div", { style: amountValueStyle(tokens.text), children: [
|
|
5004
|
+
"$",
|
|
5005
|
+
formatUsdTwoDecimals(amount)
|
|
5006
|
+
] }),
|
|
5007
|
+
/* @__PURE__ */ jsxs(
|
|
5008
|
+
"button",
|
|
5009
|
+
{
|
|
5010
|
+
type: "button",
|
|
5011
|
+
"data-testid": "deposit-token-badge",
|
|
5012
|
+
onClick: handleTokenBadgeClick,
|
|
5013
|
+
style: tokenIconButtonStyle(hasTokenDropdown || !!onSelectToken),
|
|
5014
|
+
"aria-expanded": hasTokenDropdown ? tokenPickerOpen : void 0,
|
|
5015
|
+
"aria-haspopup": hasTokenDropdown ? "listbox" : void 0,
|
|
5016
|
+
children: [
|
|
5017
|
+
/* @__PURE__ */ jsx("div", { style: tokenIconWrapStyle2, children: selectedTokenSymbol && TOKEN_LOGOS[selectedTokenSymbol] ? /* @__PURE__ */ jsx("img", { src: TOKEN_LOGOS[selectedTokenSymbol], alt: selectedTokenSymbol, width: 36, height: 36, style: { borderRadius: "50%" } }) : /* @__PURE__ */ jsxs("svg", { width: "36", height: "36", viewBox: "0 0 36 36", fill: "none", children: [
|
|
5018
|
+
/* @__PURE__ */ jsx("circle", { cx: "18", cy: "18", r: "18", fill: "#2DB84B" }),
|
|
5019
|
+
/* @__PURE__ */ jsx("text", { x: "18", y: "23", textAnchor: "middle", fontSize: "18", fill: "#fff", fontWeight: "700", children: "$" })
|
|
5020
|
+
] }) }),
|
|
5021
|
+
/* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", style: { opacity: 0.5 }, children: tokenPickerOpen ? /* @__PURE__ */ jsx("path", { d: "M18 15l-6-6-6 6", stroke: tokens.textMuted, strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }) : /* @__PURE__ */ jsx("path", { d: "M6 9l6 6 6-6", stroke: tokens.textMuted, strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
5022
|
+
]
|
|
5023
|
+
}
|
|
5024
|
+
)
|
|
4674
5025
|
] }),
|
|
4675
|
-
/* @__PURE__ */ jsxs(
|
|
4676
|
-
"
|
|
4677
|
-
{
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
5026
|
+
tokenPickerOpen && tokenOptions && tokenOptions.length > 0 && /* @__PURE__ */ jsxs("div", { style: tokenDropdownStyle(tokens), children: [
|
|
5027
|
+
/* @__PURE__ */ jsx("div", { style: tokenDropdownLabelStyle(tokens.textMuted), children: "Choose token" }),
|
|
5028
|
+
/* @__PURE__ */ jsx("div", { style: tokenDropdownInnerStyle(tokens), children: tokenOptions.map((opt, index) => {
|
|
5029
|
+
const selected = opt.symbol === selectedTokenSymbol && (!selectedChainName || opt.chainName === selectedChainName);
|
|
5030
|
+
const isLast = index === tokenOptions.length - 1;
|
|
5031
|
+
const authorized = !opt.status || opt.status === "AUTHORIZED";
|
|
5032
|
+
return /* @__PURE__ */ jsxs(
|
|
5033
|
+
"button",
|
|
5034
|
+
{
|
|
5035
|
+
type: "button",
|
|
5036
|
+
onClick: () => handlePickToken(opt),
|
|
5037
|
+
style: tokenDropdownRowStyle(tokens, selected, isLast),
|
|
5038
|
+
"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" : ""}`,
|
|
5039
|
+
children: [
|
|
5040
|
+
/* @__PURE__ */ jsxs("div", { style: tokenDropdownRowLeftStyle, children: [
|
|
5041
|
+
/* @__PURE__ */ jsx("div", { style: tokenDropdownIconStyle(tokens, !!TOKEN_LOGOS[opt.symbol]), children: TOKEN_LOGOS[opt.symbol] ? /* @__PURE__ */ jsx("img", { src: TOKEN_LOGOS[opt.symbol], alt: opt.symbol, style: tokenDropdownLogoStyle }) : /* @__PURE__ */ jsx("span", { style: tokenDropdownFallbackStyle(tokens.textMuted), children: "$" }) }),
|
|
5042
|
+
/* @__PURE__ */ jsxs("div", { style: tokenDropdownInfoStyle, children: [
|
|
5043
|
+
/* @__PURE__ */ jsxs("div", { style: tokenDropdownNameRowStyle, children: [
|
|
5044
|
+
/* @__PURE__ */ jsx("span", { style: tokenDropdownSymbolStyle(tokens.text), children: opt.symbol }),
|
|
5045
|
+
/* @__PURE__ */ jsx("span", { style: tokenDropdownDotStyle(tokens.textMuted), children: "\xB7" }),
|
|
5046
|
+
/* @__PURE__ */ jsx("span", { style: tokenDropdownChainStyle(tokens.textMuted), children: opt.chainName })
|
|
5047
|
+
] }),
|
|
5048
|
+
/* @__PURE__ */ jsxs("div", { style: tokenDropdownBalanceRowStyle, children: [
|
|
5049
|
+
opt.balance != null && /* @__PURE__ */ jsxs("span", { style: tokenDropdownBalanceStyle(tokens.textMuted), children: [
|
|
5050
|
+
"$",
|
|
5051
|
+
formatUsdTwoDecimals(opt.balance)
|
|
5052
|
+
] }),
|
|
5053
|
+
!authorized && /* @__PURE__ */ jsx("span", { style: tokenDropdownNotAuthStyle(tokens.textMuted), children: "Not authorized" })
|
|
5054
|
+
] })
|
|
5055
|
+
] })
|
|
5056
|
+
] }),
|
|
5057
|
+
selected ? /* @__PURE__ */ jsxs("svg", { width: "22", height: "22", viewBox: "0 0 22 22", fill: "none", children: [
|
|
5058
|
+
/* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "11", fill: tokens.success }),
|
|
5059
|
+
/* @__PURE__ */ jsx("path", { d: "M7 11l3 3 5-5", stroke: "#fff", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
5060
|
+
] }) : /* @__PURE__ */ jsx("div", { style: tokenDropdownRadioStyle(tokens.border) })
|
|
5061
|
+
]
|
|
5062
|
+
},
|
|
5063
|
+
`${opt.chainName}-${opt.symbol}`
|
|
5064
|
+
);
|
|
5065
|
+
}) })
|
|
5066
|
+
] })
|
|
4690
5067
|
] }),
|
|
4691
|
-
!accountPickerOpen &&
|
|
5068
|
+
!accountPickerOpen && !tokenPickerOpen && (() => {
|
|
5069
|
+
if (quoteLoading) {
|
|
5070
|
+
return /* @__PURE__ */ jsx("div", { style: feeRowContainerStyle, "aria-live": "polite", children: /* @__PURE__ */ jsx("span", { style: feeRowLabelStyle(tokens.textMuted), children: "Getting fee estimate\u2026" }) });
|
|
5071
|
+
}
|
|
5072
|
+
if (quoteFee) {
|
|
5073
|
+
const feeText = isPreciseMoneyNonPositive(quoteFee) ? formatNonPositiveFeeDisplay(quoteFee) : formatPreciseMoneyForDisplay(quoteFee);
|
|
5074
|
+
return /* @__PURE__ */ jsxs("div", { style: feeRowContainerStyle, "aria-live": "polite", children: [
|
|
5075
|
+
/* @__PURE__ */ jsx("span", { style: feeRowLabelStyle(tokens.textMuted), children: "Fee estimate: " }),
|
|
5076
|
+
/* @__PURE__ */ jsx("span", { style: feeRowAmountStyle(tokens.textSecondary), children: feeText })
|
|
5077
|
+
] });
|
|
5078
|
+
}
|
|
5079
|
+
return null;
|
|
5080
|
+
})(),
|
|
5081
|
+
!accountPickerOpen && !tokenPickerOpen && /* @__PURE__ */ jsxs(
|
|
4692
5082
|
"button",
|
|
4693
5083
|
{
|
|
4694
5084
|
type: "button",
|
|
@@ -4698,7 +5088,7 @@ function DepositScreen({
|
|
|
4698
5088
|
selectedProviderLogo ? /* @__PURE__ */ jsx("img", { src: selectedProviderLogo, alt: selectedProviderName, style: providerLogoStyle }) : /* @__PURE__ */ jsx("div", { style: providerFallbackStyle(tokens.textMuted), children: selectedProviderName.charAt(0) }),
|
|
4699
5089
|
/* @__PURE__ */ jsxs("span", { style: walletBalanceStyle(tokens.text), children: [
|
|
4700
5090
|
"$",
|
|
4701
|
-
totalAccountBalance
|
|
5091
|
+
formatUsdTwoDecimals(totalAccountBalance)
|
|
4702
5092
|
] }),
|
|
4703
5093
|
/* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", style: { opacity: 0.4 }, children: /* @__PURE__ */ jsx("path", { d: "M7 10l5-5 5 5M7 14l5 5 5-5", stroke: tokens.textMuted, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
4704
5094
|
]
|
|
@@ -4739,7 +5129,7 @@ function DepositScreen({
|
|
|
4739
5129
|
/* @__PURE__ */ jsx("span", { style: accountAddressStyle(tokens.text), children: truncatedAddress ?? account.nickname ?? account.name }),
|
|
4740
5130
|
/* @__PURE__ */ jsxs("span", { style: accountBalanceTextStyle(tokens.textMuted), children: [
|
|
4741
5131
|
"$",
|
|
4742
|
-
accountBalance
|
|
5132
|
+
formatUsdTwoDecimals(accountBalance)
|
|
4743
5133
|
] })
|
|
4744
5134
|
] })
|
|
4745
5135
|
] }),
|
|
@@ -4775,21 +5165,21 @@ function DepositScreen({
|
|
|
4775
5165
|
" ",
|
|
4776
5166
|
/* @__PURE__ */ jsxs("strong", { style: { color: tokens.text }, children: [
|
|
4777
5167
|
"$",
|
|
4778
|
-
remainingLimit
|
|
5168
|
+
formatUsdTwoDecimals(remainingLimit)
|
|
4779
5169
|
] }),
|
|
4780
5170
|
exceedsLimit && /* @__PURE__ */ jsxs("p", { style: limitExceededHintStyle(tokens.warning), children: [
|
|
4781
5171
|
"Your deposit of $",
|
|
4782
|
-
amount
|
|
5172
|
+
formatUsdTwoDecimals(amount),
|
|
4783
5173
|
" exceeds your One-Tap limit of $",
|
|
4784
|
-
remainingLimit
|
|
5174
|
+
remainingLimit != null ? formatUsdTwoDecimals(remainingLimit) : "0.00",
|
|
4785
5175
|
". Increase your limit to continue."
|
|
4786
5176
|
] })
|
|
4787
5177
|
] }),
|
|
4788
5178
|
!accountPickerOpen && isLowBalance && /* @__PURE__ */ jsxs(WarningBanner, { title: "Not enough funds", children: [
|
|
4789
5179
|
"Your wallet balance is $",
|
|
4790
|
-
availableBalance
|
|
5180
|
+
formatUsdTwoDecimals(availableBalance),
|
|
4791
5181
|
" \u2014 you need at least $",
|
|
4792
|
-
minDepositFloor
|
|
5182
|
+
formatUsdTwoDecimals(minDepositFloor),
|
|
4793
5183
|
" to deposit via One-Tap."
|
|
4794
5184
|
] }),
|
|
4795
5185
|
error && /* @__PURE__ */ jsx("div", { style: errorBannerStyle6(tokens), children: error })
|
|
@@ -4801,6 +5191,11 @@ var depositCardWrapStyle = {
|
|
|
4801
5191
|
position: "relative",
|
|
4802
5192
|
marginBottom: 20
|
|
4803
5193
|
};
|
|
5194
|
+
var depositCardStyle = (tokens) => ({
|
|
5195
|
+
border: `1px solid ${tokens.border}`,
|
|
5196
|
+
borderRadius: tokens.radiusLg,
|
|
5197
|
+
padding: "16px 20px"
|
|
5198
|
+
});
|
|
4804
5199
|
var depositLabelStyle = (color) => ({
|
|
4805
5200
|
fontSize: "0.75rem",
|
|
4806
5201
|
fontWeight: 500,
|
|
@@ -4834,6 +5229,116 @@ var tokenIconWrapStyle2 = {
|
|
|
4834
5229
|
width: 36,
|
|
4835
5230
|
height: 36
|
|
4836
5231
|
};
|
|
5232
|
+
var tokenDropdownStyle = (t) => ({
|
|
5233
|
+
marginTop: 4,
|
|
5234
|
+
marginBottom: 12,
|
|
5235
|
+
background: t.bgCard,
|
|
5236
|
+
border: `1px solid ${t.border}`,
|
|
5237
|
+
borderRadius: t.radiusLg,
|
|
5238
|
+
boxShadow: t.shadowLg,
|
|
5239
|
+
padding: "12px 14px 14px"
|
|
5240
|
+
});
|
|
5241
|
+
var tokenDropdownLabelStyle = (color) => ({
|
|
5242
|
+
fontSize: "0.78rem",
|
|
5243
|
+
fontWeight: 500,
|
|
5244
|
+
color,
|
|
5245
|
+
marginBottom: 8
|
|
5246
|
+
});
|
|
5247
|
+
var tokenDropdownInnerStyle = (t) => ({
|
|
5248
|
+
background: t.bgInput,
|
|
5249
|
+
border: `1px solid ${t.border}`,
|
|
5250
|
+
borderRadius: t.radiusLg,
|
|
5251
|
+
overflow: "hidden"
|
|
5252
|
+
});
|
|
5253
|
+
var tokenDropdownRowStyle = (t, isSelected, isLast) => ({
|
|
5254
|
+
display: "flex",
|
|
5255
|
+
alignItems: "center",
|
|
5256
|
+
justifyContent: "space-between",
|
|
5257
|
+
width: "100%",
|
|
5258
|
+
padding: "14px 16px",
|
|
5259
|
+
background: isSelected ? `${t.accent}18` : "transparent",
|
|
5260
|
+
border: "none",
|
|
5261
|
+
borderBottom: isLast ? "none" : `1px solid ${t.border}`,
|
|
5262
|
+
cursor: "pointer",
|
|
5263
|
+
fontFamily: "inherit",
|
|
5264
|
+
textAlign: "left",
|
|
5265
|
+
outline: "none"
|
|
5266
|
+
});
|
|
5267
|
+
var tokenDropdownRowLeftStyle = {
|
|
5268
|
+
display: "flex",
|
|
5269
|
+
alignItems: "center",
|
|
5270
|
+
gap: 12,
|
|
5271
|
+
minWidth: 0,
|
|
5272
|
+
flex: 1
|
|
5273
|
+
};
|
|
5274
|
+
var tokenDropdownIconStyle = (t, hasLogo) => ({
|
|
5275
|
+
width: 36,
|
|
5276
|
+
height: 36,
|
|
5277
|
+
borderRadius: "50%",
|
|
5278
|
+
border: hasLogo ? "none" : `1.5px solid ${t.border}`,
|
|
5279
|
+
display: "flex",
|
|
5280
|
+
alignItems: "center",
|
|
5281
|
+
justifyContent: "center",
|
|
5282
|
+
flexShrink: 0,
|
|
5283
|
+
overflow: "hidden"
|
|
5284
|
+
});
|
|
5285
|
+
var tokenDropdownLogoStyle = {
|
|
5286
|
+
width: 36,
|
|
5287
|
+
height: 36,
|
|
5288
|
+
borderRadius: "50%",
|
|
5289
|
+
objectFit: "cover"
|
|
5290
|
+
};
|
|
5291
|
+
var tokenDropdownFallbackStyle = (color) => ({
|
|
5292
|
+
fontSize: "1rem",
|
|
5293
|
+
fontWeight: 700,
|
|
5294
|
+
color
|
|
5295
|
+
});
|
|
5296
|
+
var tokenDropdownInfoStyle = {
|
|
5297
|
+
display: "flex",
|
|
5298
|
+
flexDirection: "column",
|
|
5299
|
+
gap: 2,
|
|
5300
|
+
minWidth: 0
|
|
5301
|
+
};
|
|
5302
|
+
var tokenDropdownNameRowStyle = {
|
|
5303
|
+
display: "flex",
|
|
5304
|
+
alignItems: "center",
|
|
5305
|
+
gap: 4
|
|
5306
|
+
};
|
|
5307
|
+
var tokenDropdownSymbolStyle = (color) => ({
|
|
5308
|
+
fontSize: "0.92rem",
|
|
5309
|
+
fontWeight: 600,
|
|
5310
|
+
color
|
|
5311
|
+
});
|
|
5312
|
+
var tokenDropdownDotStyle = (color) => ({
|
|
5313
|
+
fontSize: "0.8rem",
|
|
5314
|
+
color
|
|
5315
|
+
});
|
|
5316
|
+
var tokenDropdownChainStyle = (color) => ({
|
|
5317
|
+
fontSize: "0.84rem",
|
|
5318
|
+
fontWeight: 400,
|
|
5319
|
+
color
|
|
5320
|
+
});
|
|
5321
|
+
var tokenDropdownBalanceRowStyle = {
|
|
5322
|
+
display: "flex",
|
|
5323
|
+
alignItems: "center",
|
|
5324
|
+
gap: 8
|
|
5325
|
+
};
|
|
5326
|
+
var tokenDropdownBalanceStyle = (color) => ({
|
|
5327
|
+
fontSize: "0.78rem",
|
|
5328
|
+
color
|
|
5329
|
+
});
|
|
5330
|
+
var tokenDropdownNotAuthStyle = (color) => ({
|
|
5331
|
+
fontSize: "0.7rem",
|
|
5332
|
+
fontWeight: 500,
|
|
5333
|
+
color
|
|
5334
|
+
});
|
|
5335
|
+
var tokenDropdownRadioStyle = (borderColor) => ({
|
|
5336
|
+
width: 22,
|
|
5337
|
+
height: 22,
|
|
5338
|
+
borderRadius: "50%",
|
|
5339
|
+
border: `2px solid ${borderColor}`,
|
|
5340
|
+
flexShrink: 0
|
|
5341
|
+
});
|
|
4837
5342
|
var walletBalanceRowStyle = {
|
|
4838
5343
|
display: "flex",
|
|
4839
5344
|
alignItems: "center",
|
|
@@ -4995,9 +5500,20 @@ var limitExceededHintStyle = (color) => ({
|
|
|
4995
5500
|
margin: "12px 0 2px",
|
|
4996
5501
|
lineHeight: 1.5
|
|
4997
5502
|
});
|
|
5503
|
+
var feeRowContainerStyle = {
|
|
5504
|
+
fontSize: "0.84rem",
|
|
5505
|
+
fontWeight: 500,
|
|
5506
|
+
marginTop: 6,
|
|
5507
|
+
marginBottom: 4
|
|
5508
|
+
};
|
|
5509
|
+
var feeRowLabelStyle = (color) => ({ color });
|
|
5510
|
+
var feeRowAmountStyle = (color) => ({
|
|
5511
|
+
color,
|
|
5512
|
+
fontVariantNumeric: "tabular-nums"
|
|
5513
|
+
});
|
|
4998
5514
|
function SuccessScreen({
|
|
4999
5515
|
amount,
|
|
5000
|
-
currency,
|
|
5516
|
+
currency: _currency,
|
|
5001
5517
|
succeeded,
|
|
5002
5518
|
error,
|
|
5003
5519
|
merchantName,
|
|
@@ -5010,22 +5526,30 @@ function SuccessScreen({
|
|
|
5010
5526
|
onPreauthorize
|
|
5011
5527
|
}) {
|
|
5012
5528
|
const { tokens } = useBlinkConfig();
|
|
5529
|
+
const isGuestDepositSuccess = succeeded && onPreauthorize != null;
|
|
5013
5530
|
return /* @__PURE__ */ jsxs(
|
|
5014
5531
|
ScreenLayout,
|
|
5015
5532
|
{
|
|
5016
5533
|
footer: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5017
|
-
|
|
5018
|
-
/* @__PURE__ */ jsx(PrimaryButton, { onClick: onPreauthorize, children: "
|
|
5019
|
-
/* @__PURE__ */ jsx("button", { type: "button", onClick: onDone, style: skipButtonStyle(tokens.textMuted), children: "
|
|
5534
|
+
isGuestDepositSuccess ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5535
|
+
/* @__PURE__ */ jsx(PrimaryButton, { onClick: onPreauthorize, children: "Set up one tap" }),
|
|
5536
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: onDone, style: skipButtonStyle(tokens.textMuted), children: "Return to app" })
|
|
5020
5537
|
] }) : /* @__PURE__ */ jsx(PrimaryButton, { onClick: onDone, children: succeeded ? "Done" : "Try again" }),
|
|
5021
5538
|
onManageAccount && /* @__PURE__ */ jsx("button", { type: "button", onClick: onManageAccount, style: manageStyle(tokens.textMuted), children: "Manage Blink account \u2192" }),
|
|
5022
5539
|
/* @__PURE__ */ jsx(PoweredByFooter, {})
|
|
5023
5540
|
] }),
|
|
5024
5541
|
children: [
|
|
5025
5542
|
/* @__PURE__ */ jsx(ScreenHeader, { onLogout }),
|
|
5026
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
5027
|
-
|
|
5028
|
-
/* @__PURE__ */
|
|
5543
|
+
/* @__PURE__ */ jsxs("div", { style: screenContentStyle, children: [
|
|
5544
|
+
isGuestDepositSuccess ? /* @__PURE__ */ jsxs("div", { style: contentStyleCompact, children: [
|
|
5545
|
+
/* @__PURE__ */ jsxs("h2", { style: headingStyle7(tokens.text), children: [
|
|
5546
|
+
"$",
|
|
5547
|
+
amount.toFixed(2),
|
|
5548
|
+
" deposited"
|
|
5549
|
+
] }),
|
|
5550
|
+
/* @__PURE__ */ jsx("p", { style: { ...subtitleStyle7(tokens.text), fontWeight: 600, margin: "0 0 8px" }, children: "Next time, do it in one tap" }),
|
|
5551
|
+
/* @__PURE__ */ jsx("p", { style: subtitleStyle7(tokens.textSecondary), children: "Set up one tap for this wallet and skip the extra steps." })
|
|
5552
|
+
] }) : succeeded ? /* @__PURE__ */ jsxs("div", { style: contentStyleCompact, children: [
|
|
5029
5553
|
/* @__PURE__ */ jsxs("h2", { style: headingStyle7(tokens.text), children: [
|
|
5030
5554
|
"$",
|
|
5031
5555
|
amount.toFixed(2),
|
|
@@ -5037,10 +5561,10 @@ function SuccessScreen({
|
|
|
5037
5561
|
] })
|
|
5038
5562
|
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5039
5563
|
/* @__PURE__ */ jsx(IconCircle, { variant: "error", size: 64, children: /* @__PURE__ */ jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ 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 }) }) }),
|
|
5040
|
-
/* @__PURE__ */ jsx("h2", { style:
|
|
5041
|
-
error && /* @__PURE__ */ jsx("p", { style:
|
|
5564
|
+
/* @__PURE__ */ jsx("h2", { style: failureHeadingStyle(tokens.text), children: "Transfer failed" }),
|
|
5565
|
+
error && /* @__PURE__ */ jsx("p", { style: failureSubtitleStyle(tokens.error), children: error })
|
|
5042
5566
|
] }),
|
|
5043
|
-
/* @__PURE__ */ jsxs("div", { style: summaryCardStyle(tokens), children: [
|
|
5567
|
+
!isGuestDepositSuccess && /* @__PURE__ */ jsxs("div", { style: summaryCardStyle(tokens), children: [
|
|
5044
5568
|
sourceName && /* @__PURE__ */ jsxs("div", { style: summaryRowStyle, children: [
|
|
5045
5569
|
/* @__PURE__ */ jsx("span", { style: summaryLabelStyle(tokens.textMuted), children: "From" }),
|
|
5046
5570
|
/* @__PURE__ */ jsx("span", { style: summaryValueStyle(tokens.text), children: sourceName })
|
|
@@ -5057,7 +5581,7 @@ function SuccessScreen({
|
|
|
5057
5581
|
] })
|
|
5058
5582
|
] })
|
|
5059
5583
|
] }),
|
|
5060
|
-
succeeded && onIncreaseLimits && /* @__PURE__ */ jsxs("div", { style: upsellCardStyle(tokens), children: [
|
|
5584
|
+
succeeded && onIncreaseLimits && !isGuestDepositSuccess && /* @__PURE__ */ jsxs("div", { style: upsellCardStyle(tokens), children: [
|
|
5061
5585
|
/* @__PURE__ */ jsxs("div", { style: upsellHeaderStyle, children: [
|
|
5062
5586
|
/* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { marginRight: 6 }, children: /* @__PURE__ */ jsx("path", { d: "M7 14l5-5 5 5", stroke: tokens.accent, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
|
|
5063
5587
|
/* @__PURE__ */ jsx("strong", { children: "Want higher limits?" })
|
|
@@ -5070,21 +5594,42 @@ function SuccessScreen({
|
|
|
5070
5594
|
}
|
|
5071
5595
|
);
|
|
5072
5596
|
}
|
|
5073
|
-
var
|
|
5597
|
+
var screenContentStyle = {
|
|
5074
5598
|
flex: 1,
|
|
5075
5599
|
display: "flex",
|
|
5076
5600
|
flexDirection: "column",
|
|
5077
5601
|
alignItems: "center",
|
|
5078
5602
|
paddingTop: 16
|
|
5079
5603
|
};
|
|
5604
|
+
var contentStyleCompact = {
|
|
5605
|
+
textAlign: "center",
|
|
5606
|
+
display: "flex",
|
|
5607
|
+
flexDirection: "column",
|
|
5608
|
+
alignItems: "center",
|
|
5609
|
+
width: "100%"
|
|
5610
|
+
};
|
|
5080
5611
|
var headingStyle7 = (color) => ({
|
|
5612
|
+
fontSize: "1.45rem",
|
|
5613
|
+
fontWeight: 700,
|
|
5614
|
+
letterSpacing: "-0.02em",
|
|
5615
|
+
color,
|
|
5616
|
+
margin: "20px 0 8px"
|
|
5617
|
+
});
|
|
5618
|
+
var subtitleStyle7 = (color) => ({
|
|
5619
|
+
fontSize: "0.9rem",
|
|
5620
|
+
color,
|
|
5621
|
+
margin: "0 0 28px",
|
|
5622
|
+
lineHeight: 1.5,
|
|
5623
|
+
maxWidth: 280
|
|
5624
|
+
});
|
|
5625
|
+
var failureHeadingStyle = (color) => ({
|
|
5081
5626
|
fontSize: "1.5rem",
|
|
5082
5627
|
fontWeight: 700,
|
|
5083
5628
|
letterSpacing: "-0.02em",
|
|
5084
5629
|
color,
|
|
5085
5630
|
margin: "20px 0 4px"
|
|
5086
5631
|
});
|
|
5087
|
-
var
|
|
5632
|
+
var failureSubtitleStyle = (color) => ({
|
|
5088
5633
|
fontSize: "0.9rem",
|
|
5089
5634
|
color,
|
|
5090
5635
|
margin: "0 0 20px"
|
|
@@ -5600,7 +6145,7 @@ function TransferStatusScreen({
|
|
|
5600
6145
|
const steps = buildSteps(phase);
|
|
5601
6146
|
return /* @__PURE__ */ jsxs(ScreenLayout, { footer: /* @__PURE__ */ jsx(PoweredByFooter, {}), children: [
|
|
5602
6147
|
/* @__PURE__ */ jsx(ScreenHeader, { onLogout }),
|
|
5603
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
6148
|
+
/* @__PURE__ */ jsxs("div", { style: contentStyle6, children: [
|
|
5604
6149
|
/* @__PURE__ */ jsx(Spinner, { size: 64 }),
|
|
5605
6150
|
/* @__PURE__ */ jsx("h2", { style: headingStyle9(tokens.text), children: "Depositing your money..." }),
|
|
5606
6151
|
error && /* @__PURE__ */ jsx("div", { style: errorBannerStyle7(tokens), children: error }),
|
|
@@ -5608,7 +6153,7 @@ function TransferStatusScreen({
|
|
|
5608
6153
|
] })
|
|
5609
6154
|
] });
|
|
5610
6155
|
}
|
|
5611
|
-
var
|
|
6156
|
+
var contentStyle6 = {
|
|
5612
6157
|
flex: 1,
|
|
5613
6158
|
display: "flex",
|
|
5614
6159
|
flexDirection: "column",
|
|
@@ -5678,7 +6223,7 @@ function OpenWalletScreen({
|
|
|
5678
6223
|
] }),
|
|
5679
6224
|
children: [
|
|
5680
6225
|
/* @__PURE__ */ jsx(ScreenHeader, { onLogout }),
|
|
5681
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
6226
|
+
/* @__PURE__ */ jsxs("div", { style: contentStyle7, children: [
|
|
5682
6227
|
/* @__PURE__ */ jsx("div", { style: logoCircleStyle(tokens.bgInput), children: logoSrc ? /* @__PURE__ */ jsx("img", { src: logoSrc, alt: displayName, style: logoStyle2 }) : /* @__PURE__ */ jsx(Spinner, { size: 32 }) }),
|
|
5683
6228
|
/* @__PURE__ */ jsxs("h2", { style: headingStyle10(tokens.text), children: [
|
|
5684
6229
|
"Setting up ",
|
|
@@ -5711,7 +6256,7 @@ function OpenWalletScreen({
|
|
|
5711
6256
|
] }),
|
|
5712
6257
|
children: [
|
|
5713
6258
|
/* @__PURE__ */ jsx(ScreenHeader, { onBack, onLogout }),
|
|
5714
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
6259
|
+
/* @__PURE__ */ jsxs("div", { style: contentStyle7, children: [
|
|
5715
6260
|
/* @__PURE__ */ jsx("div", { style: logoCircleStyle(tokens.bgInput), children: logoSrc ? /* @__PURE__ */ jsx("img", { src: logoSrc, alt: displayName, style: logoStyle2 }) : /* @__PURE__ */ jsx(Spinner, { size: 32 }) }),
|
|
5716
6261
|
/* @__PURE__ */ jsx("h2", { style: headingStyle10(tokens.text), children: loading ? "Connecting..." : `Open ${displayName}` }),
|
|
5717
6262
|
/* @__PURE__ */ jsx("p", { style: subtitleStyle10(tokens.textSecondary), children: loading ? "Creating transfer and preparing your wallet link..." : `Continue in ${displayName} to authorize this connection.` }),
|
|
@@ -5724,7 +6269,7 @@ function OpenWalletScreen({
|
|
|
5724
6269
|
}
|
|
5725
6270
|
);
|
|
5726
6271
|
}
|
|
5727
|
-
var
|
|
6272
|
+
var contentStyle7 = {
|
|
5728
6273
|
flex: 1,
|
|
5729
6274
|
display: "flex",
|
|
5730
6275
|
flexDirection: "column",
|
|
@@ -5810,7 +6355,7 @@ function ConfirmSignScreen({
|
|
|
5810
6355
|
] }),
|
|
5811
6356
|
children: [
|
|
5812
6357
|
/* @__PURE__ */ jsx(ScreenHeader, { onLogout }),
|
|
5813
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
6358
|
+
/* @__PURE__ */ jsxs("div", { style: contentStyle8, children: [
|
|
5814
6359
|
logoSrc ? /* @__PURE__ */ jsx("img", { src: logoSrc, alt: displayName, style: logoStyle3 }) : /* @__PURE__ */ jsx(Spinner, { size: 48 }),
|
|
5815
6360
|
/* @__PURE__ */ jsx("h2", { style: headingStyle11(tokens.text), children: "Wallet authorized" }),
|
|
5816
6361
|
/* @__PURE__ */ jsxs("p", { style: subtitleStyle11(tokens.textSecondary), children: [
|
|
@@ -5826,7 +6371,7 @@ function ConfirmSignScreen({
|
|
|
5826
6371
|
}
|
|
5827
6372
|
);
|
|
5828
6373
|
}
|
|
5829
|
-
var
|
|
6374
|
+
var contentStyle8 = {
|
|
5830
6375
|
flex: 1,
|
|
5831
6376
|
display: "flex",
|
|
5832
6377
|
flexDirection: "column",
|
|
@@ -6121,29 +6666,6 @@ var selectCircleSelectedStyle = (color) => ({
|
|
|
6121
6666
|
function entryKey(entry) {
|
|
6122
6667
|
return `${entry.sourceChainId}-${entry.tokenAddress.toLowerCase()}`;
|
|
6123
6668
|
}
|
|
6124
|
-
function isPreciseMoneyNonPositive(fee) {
|
|
6125
|
-
const raw = fee.value.trim();
|
|
6126
|
-
if (!/^-?\d+(\.\d*)?$/.test(raw)) return false;
|
|
6127
|
-
const n = Number(raw);
|
|
6128
|
-
return Number.isFinite(n) && n <= 0;
|
|
6129
|
-
}
|
|
6130
|
-
function formatNonPositiveFeeDisplay(fee) {
|
|
6131
|
-
if (fee.currency === "USD") return "Under $0.01";
|
|
6132
|
-
return `Less than 0.01 ${fee.currency}`;
|
|
6133
|
-
}
|
|
6134
|
-
function formatPreciseMoneyForDisplay(fee) {
|
|
6135
|
-
const raw = fee.value.trim();
|
|
6136
|
-
if (fee.currency === "USD") {
|
|
6137
|
-
if (!/^\d+(\.\d*)?$/.test(raw)) {
|
|
6138
|
-
return `$${raw}`;
|
|
6139
|
-
}
|
|
6140
|
-
const [whole, frac = ""] = raw.split(".");
|
|
6141
|
-
const dec = `${frac}00`.slice(0, 2);
|
|
6142
|
-
const intFmt = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
6143
|
-
return `$${intFmt}.${dec}`;
|
|
6144
|
-
}
|
|
6145
|
-
return `${raw} ${fee.currency}`;
|
|
6146
|
-
}
|
|
6147
6669
|
function GuestTokenPickerScreen({
|
|
6148
6670
|
entries,
|
|
6149
6671
|
loading,
|
|
@@ -6183,13 +6705,13 @@ function GuestTokenPickerScreen({
|
|
|
6183
6705
|
const canConfirm = Boolean(quoteFee && pendingEntry && !quoteLoading);
|
|
6184
6706
|
const feeLine = (() => {
|
|
6185
6707
|
if (quoteLoading && pendingEntry) {
|
|
6186
|
-
return /* @__PURE__ */ jsx("div", { style:
|
|
6708
|
+
return /* @__PURE__ */ jsx("div", { style: feeRowContainerStyle2, "aria-live": "polite", children: /* @__PURE__ */ jsx("span", { style: feeRowLabelStyle2(t.textMuted), children: "Getting fee estimate\u2026" }) });
|
|
6187
6709
|
}
|
|
6188
6710
|
if (quoteFee) {
|
|
6189
6711
|
const feeText = isPreciseMoneyNonPositive(quoteFee) ? formatNonPositiveFeeDisplay(quoteFee) : formatPreciseMoneyForDisplay(quoteFee);
|
|
6190
|
-
return /* @__PURE__ */ jsxs("div", { style:
|
|
6191
|
-
/* @__PURE__ */ jsx("span", { style:
|
|
6192
|
-
/* @__PURE__ */ jsx("span", { style:
|
|
6712
|
+
return /* @__PURE__ */ jsxs("div", { style: feeRowContainerStyle2, "aria-live": "polite", children: [
|
|
6713
|
+
/* @__PURE__ */ jsx("span", { style: feeRowLabelStyle2(t.textMuted), children: "Fee estimate: " }),
|
|
6714
|
+
/* @__PURE__ */ jsx("span", { style: feeRowAmountStyle2(t.textSecondary), children: feeText })
|
|
6193
6715
|
] });
|
|
6194
6716
|
}
|
|
6195
6717
|
return null;
|
|
@@ -6211,7 +6733,7 @@ function GuestTokenPickerScreen({
|
|
|
6211
6733
|
depositAmount != null && /* @__PURE__ */ jsxs("div", { style: depositAmountStyle2(t.text), children: [
|
|
6212
6734
|
"$",
|
|
6213
6735
|
depositAmount.toLocaleString("en-US", {
|
|
6214
|
-
minimumFractionDigits:
|
|
6736
|
+
minimumFractionDigits: 2,
|
|
6215
6737
|
maximumFractionDigits: 2
|
|
6216
6738
|
})
|
|
6217
6739
|
] }),
|
|
@@ -6293,7 +6815,7 @@ function GuestTokenPickerScreen({
|
|
|
6293
6815
|
] }),
|
|
6294
6816
|
tokenListOpen && entries.length > 0 && /* @__PURE__ */ jsxs("div", { style: tokenDropdownOuterStyle(t), children: [
|
|
6295
6817
|
/* @__PURE__ */ jsx("div", { style: accountDropdownLabelStyle2(t.textMuted), children: "Choose token" }),
|
|
6296
|
-
/* @__PURE__ */ jsx("div", { style:
|
|
6818
|
+
/* @__PURE__ */ jsx("div", { style: tokenDropdownInnerStyle2(t), children: entries.map((entry, index) => {
|
|
6297
6819
|
const selected = pendingKey === entryKey(entry);
|
|
6298
6820
|
const isLast = index === entries.length - 1;
|
|
6299
6821
|
return /* @__PURE__ */ jsxs(
|
|
@@ -6394,13 +6916,13 @@ var depositAmountStyle2 = (color) => ({
|
|
|
6394
6916
|
color,
|
|
6395
6917
|
lineHeight: 1.05
|
|
6396
6918
|
});
|
|
6397
|
-
var
|
|
6919
|
+
var feeRowContainerStyle2 = {
|
|
6398
6920
|
fontSize: "0.84rem",
|
|
6399
6921
|
fontWeight: 500,
|
|
6400
6922
|
marginTop: 6
|
|
6401
6923
|
};
|
|
6402
|
-
var
|
|
6403
|
-
var
|
|
6924
|
+
var feeRowLabelStyle2 = (color) => ({ color });
|
|
6925
|
+
var feeRowAmountStyle2 = (color) => ({
|
|
6404
6926
|
color,
|
|
6405
6927
|
fontVariantNumeric: "tabular-nums"
|
|
6406
6928
|
});
|
|
@@ -6446,7 +6968,7 @@ var accountDropdownLabelStyle2 = (color) => ({
|
|
|
6446
6968
|
color,
|
|
6447
6969
|
marginBottom: 8
|
|
6448
6970
|
});
|
|
6449
|
-
var
|
|
6971
|
+
var tokenDropdownInnerStyle2 = (tokens) => ({
|
|
6450
6972
|
background: tokens.bgInput,
|
|
6451
6973
|
border: `1px solid ${tokens.border}`,
|
|
6452
6974
|
borderRadius: tokens.radiusLg,
|
|
@@ -6558,7 +7080,7 @@ function GuestPreauthSetupCompleteScreen({
|
|
|
6558
7080
|
] }),
|
|
6559
7081
|
children: [
|
|
6560
7082
|
/* @__PURE__ */ jsx(ScreenHeader, { onLogout }),
|
|
6561
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
7083
|
+
/* @__PURE__ */ jsxs("div", { style: contentStyle9, children: [
|
|
6562
7084
|
/* @__PURE__ */ jsx(IconCircle, { variant: "success", size: 64, children: /* @__PURE__ */ jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
|
|
6563
7085
|
"path",
|
|
6564
7086
|
{
|
|
@@ -6567,13 +7089,13 @@ function GuestPreauthSetupCompleteScreen({
|
|
|
6567
7089
|
}
|
|
6568
7090
|
) }) }),
|
|
6569
7091
|
/* @__PURE__ */ jsx("h2", { style: headingStyle12(tokens.text), children: "Setup complete" }),
|
|
6570
|
-
/* @__PURE__ */ jsx("p", { style: subtitleStyle12(tokens.textSecondary), children: "Your account is linked and ready. You can close this window
|
|
7092
|
+
/* @__PURE__ */ jsx("p", { style: subtitleStyle12(tokens.textSecondary), children: "Your account is linked and ready. You can close this window." })
|
|
6571
7093
|
] })
|
|
6572
7094
|
]
|
|
6573
7095
|
}
|
|
6574
7096
|
);
|
|
6575
7097
|
}
|
|
6576
|
-
var
|
|
7098
|
+
var contentStyle9 = {
|
|
6577
7099
|
display: "flex",
|
|
6578
7100
|
flexDirection: "column",
|
|
6579
7101
|
alignItems: "center",
|
|
@@ -6602,14 +7124,14 @@ function GuestPreauthLinkingScreen({ onLogout }) {
|
|
|
6602
7124
|
const { tokens } = useBlinkConfig();
|
|
6603
7125
|
return /* @__PURE__ */ jsxs(ScreenLayout, { children: [
|
|
6604
7126
|
/* @__PURE__ */ jsx(ScreenHeader, { onLogout }),
|
|
6605
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
7127
|
+
/* @__PURE__ */ jsxs("div", { style: contentStyle10, children: [
|
|
6606
7128
|
/* @__PURE__ */ jsx(Spinner, { size: 48 }),
|
|
6607
7129
|
/* @__PURE__ */ jsx("h2", { style: headingStyle13(tokens.text), children: "Setting up your account..." }),
|
|
6608
7130
|
/* @__PURE__ */ jsx("p", { style: subtitleStyle13(tokens.textSecondary), children: "Linking your wallet to your Blink account. This usually takes a few seconds." })
|
|
6609
7131
|
] })
|
|
6610
7132
|
] });
|
|
6611
7133
|
}
|
|
6612
|
-
var
|
|
7134
|
+
var contentStyle10 = {
|
|
6613
7135
|
flex: 1,
|
|
6614
7136
|
display: "flex",
|
|
6615
7137
|
flexDirection: "column",
|
|
@@ -6666,6 +7188,10 @@ function resolveHeaderFlowPhase(screen, phase, authenticated) {
|
|
|
6666
7188
|
return raw;
|
|
6667
7189
|
}
|
|
6668
7190
|
var DEFAULT_MIN_DEPOSIT_USD = 0.25;
|
|
7191
|
+
var GUEST_PREAUTH_LOGIN_HERO_TITLE = "Create an account to complete one tap setup";
|
|
7192
|
+
function isGuestPreauthLogin(state) {
|
|
7193
|
+
return state.isGuestFlow && (state.guestPreauthSessionId != null || state.guestPreauthAccountId != null);
|
|
7194
|
+
}
|
|
6669
7195
|
function StepRenderer(props) {
|
|
6670
7196
|
const screen = screenForPhase(props.flow.state.phase);
|
|
6671
7197
|
const flowPhase = resolveHeaderFlowPhase(
|
|
@@ -6745,7 +7271,8 @@ function StepRendererContent({
|
|
|
6745
7271
|
sending: activeOtpStatus === "sending-code",
|
|
6746
7272
|
error: state.error,
|
|
6747
7273
|
onBack,
|
|
6748
|
-
merchantInitials: merchantName ? merchantName.slice(0, 2).toUpperCase() : void 0
|
|
7274
|
+
merchantInitials: merchantName ? merchantName.slice(0, 2).toUpperCase() : void 0,
|
|
7275
|
+
heroTitle: isGuestPreauthLogin(state) ? GUEST_PREAUTH_LOGIN_HERO_TITLE : void 0
|
|
6749
7276
|
}
|
|
6750
7277
|
);
|
|
6751
7278
|
case "otp-verify":
|
|
@@ -6844,15 +7371,11 @@ function StepRendererContent({
|
|
|
6844
7371
|
0
|
|
6845
7372
|
);
|
|
6846
7373
|
const effectiveTokenCount = tokenCount > 0 ? tokenCount : selectSourceTokenCount;
|
|
6847
|
-
const
|
|
6848
|
-
const
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
balance: s.balance.available.amount,
|
|
6853
|
-
walletId: w.id
|
|
6854
|
-
}))
|
|
6855
|
-
) : selectSourceChoices.flatMap(
|
|
7374
|
+
const setupFromPendingSelectSource = pendingSelectSource != null;
|
|
7375
|
+
const setupSelectedTokenSymbol = setupFromPendingSelectSource ? selectSourceTokenSymbol || selectSourceRecommended?.tokenSymbol || "" : selectedSource?.token.symbol ?? selectSourceTokenSymbol;
|
|
7376
|
+
const setupSelectedChainName = setupFromPendingSelectSource ? selectSourceChainName || selectSourceRecommended?.chainName || "" : selectedWallet?.chain.name ?? selectSourceChainName;
|
|
7377
|
+
const effectiveSourceLabel = setupFromPendingSelectSource ? setupSelectedTokenSymbol && setupSelectedChainName ? `${setupSelectedTokenSymbol} on ${setupSelectedChainName}` : void 0 : selectedSourceLabel ?? (selectSourceChainName && selectSourceTokenSymbol ? `${selectSourceTokenSymbol} on ${selectSourceChainName}` : void 0);
|
|
7378
|
+
const setupTokenOptions = selectedAccount ? tokenOptionsForLinkedAccount(selectedAccount, state.chains) : selectSourceChoices.flatMap(
|
|
6856
7379
|
(chain) => chain.tokens.map((t) => ({
|
|
6857
7380
|
symbol: t.tokenSymbol,
|
|
6858
7381
|
chainName: chain.chainName,
|
|
@@ -6860,9 +7383,8 @@ function StepRendererContent({
|
|
|
6860
7383
|
}))
|
|
6861
7384
|
);
|
|
6862
7385
|
const handleSetupSelectToken = (symbol, chainName, walletId) => {
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
} else {
|
|
7386
|
+
handleInlineTokenSelection(handlers, state.chains, selectedAccount, symbol, chainName, walletId);
|
|
7387
|
+
if (pendingSelectSource) {
|
|
6866
7388
|
handlers.onSelectSourceChainChange(chainName);
|
|
6867
7389
|
handlers.onSetSelectSourceTokenSymbol(symbol);
|
|
6868
7390
|
}
|
|
@@ -6870,17 +7392,18 @@ function StepRendererContent({
|
|
|
6870
7392
|
return /* @__PURE__ */ jsx(
|
|
6871
7393
|
SetupScreen,
|
|
6872
7394
|
{
|
|
6873
|
-
availableBalance: selectedSource ? selectedSource.balance.available.amount : selectSourceAvailableBalance > 0 ? selectSourceAvailableBalance : selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : maxSourceBalance,
|
|
7395
|
+
availableBalance: selectedSource ? selectedSource.balance.available.amount : setupFromPendingSelectSource ? selectSourceAvailableBalance : selectSourceAvailableBalance > 0 ? selectSourceAvailableBalance : selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : maxSourceBalance,
|
|
6874
7396
|
tokenCount: effectiveTokenCount,
|
|
6875
7397
|
sourceName,
|
|
6876
7398
|
onSetupOneTap: handlers.onSetupOneTap,
|
|
6877
|
-
onBack:
|
|
7399
|
+
onBack: handlers.onBackFromSubflow,
|
|
6878
7400
|
onLogout: handlers.onLogout,
|
|
6879
7401
|
onAdvanced: handlers.onSelectToken,
|
|
6880
7402
|
selectedSourceLabel: effectiveSourceLabel,
|
|
6881
7403
|
loading: savingOneTapLimit,
|
|
6882
7404
|
error: state.error,
|
|
6883
|
-
selectedTokenSymbol:
|
|
7405
|
+
selectedTokenSymbol: setupSelectedTokenSymbol,
|
|
7406
|
+
selectedChainName: setupSelectedChainName,
|
|
6884
7407
|
tokenOptions: setupTokenOptions,
|
|
6885
7408
|
onSelectToken: handleSetupSelectToken
|
|
6886
7409
|
}
|
|
@@ -6902,6 +7425,7 @@ function StepRendererContent({
|
|
|
6902
7425
|
case "deposit": {
|
|
6903
7426
|
const parsedAmt = depositAmount != null ? depositAmount : 5;
|
|
6904
7427
|
const minDepositFloor = depositAmount != null ? depositAmount : DEFAULT_MIN_DEPOSIT_USD;
|
|
7428
|
+
const depositTokenOptions = tokenOptionsForLinkedAccount(selectedAccount, state.chains);
|
|
6905
7429
|
return /* @__PURE__ */ jsx(
|
|
6906
7430
|
DepositScreen,
|
|
6907
7431
|
{
|
|
@@ -6910,6 +7434,8 @@ function StepRendererContent({
|
|
|
6910
7434
|
remainingLimit: selectedSource != null ? selectedSource.remainingAllowance ?? null : selectedAccount?.remainingAllowance ?? null,
|
|
6911
7435
|
tokenCount,
|
|
6912
7436
|
initialAmount: parsedAmt,
|
|
7437
|
+
quoteFee: forms.depositQuoteFee,
|
|
7438
|
+
quoteLoading: forms.depositQuoteLoading,
|
|
6913
7439
|
processing: state.creatingTransfer,
|
|
6914
7440
|
error: state.error,
|
|
6915
7441
|
onDeposit: handlers.onPay,
|
|
@@ -6924,8 +7450,13 @@ function StepRendererContent({
|
|
|
6924
7450
|
onAuthorizeAccount: handlers.onContinueConnection,
|
|
6925
7451
|
onAddProvider: () => handlers.onSetPhase({ step: "wallet-picker", reason: "switch" }),
|
|
6926
7452
|
onSelectToken: handlers.onSelectToken,
|
|
7453
|
+
tokenOptions: depositTokenOptions,
|
|
7454
|
+
onPickToken: (symbol, chainName, walletId) => {
|
|
7455
|
+
handleInlineTokenSelection(handlers, state.chains, selectedAccount, symbol, chainName, walletId);
|
|
7456
|
+
},
|
|
6927
7457
|
selectedSourceLabel,
|
|
6928
7458
|
selectedTokenSymbol: selectedSource?.token.symbol,
|
|
7459
|
+
selectedChainName: selectedWallet?.chain.name,
|
|
6929
7460
|
minDepositFloor
|
|
6930
7461
|
}
|
|
6931
7462
|
);
|
|
@@ -6966,7 +7497,7 @@ function StepRendererContent({
|
|
|
6966
7497
|
chains: state.chains,
|
|
6967
7498
|
onSelectAuthorized: handlers.onSelectAuthorizedToken,
|
|
6968
7499
|
onAuthorizeToken: handlers.onAuthorizeToken,
|
|
6969
|
-
onBack:
|
|
7500
|
+
onBack: handlers.onBackFromSubflow,
|
|
6970
7501
|
onLogout: handlers.onLogout,
|
|
6971
7502
|
depositAmount: depositAmount ?? void 0,
|
|
6972
7503
|
selectedTokenSymbol: selectedSource?.token.symbol,
|
|
@@ -7045,7 +7576,7 @@ function StepRendererContent({
|
|
|
7045
7576
|
})() : void 0,
|
|
7046
7577
|
onDone: onDismiss ?? handlers.onNewPayment,
|
|
7047
7578
|
onLogout: authenticated ? handlers.onLogout : void 0,
|
|
7048
|
-
onPreauthorize: state.isGuestFlow ? handlers.onPreauthorize : void 0
|
|
7579
|
+
onPreauthorize: state.isGuestFlow && isDesktop ? handlers.onPreauthorize : void 0
|
|
7049
7580
|
}
|
|
7050
7581
|
);
|
|
7051
7582
|
}
|
|
@@ -7444,6 +7975,9 @@ function useTransferHandlers(deps) {
|
|
|
7444
7975
|
sourceTokenAddress,
|
|
7445
7976
|
activeCredentialId,
|
|
7446
7977
|
selectedAccountId,
|
|
7978
|
+
selectedWalletId,
|
|
7979
|
+
selectedTokenSymbol,
|
|
7980
|
+
quoteId,
|
|
7447
7981
|
transfer,
|
|
7448
7982
|
accounts
|
|
7449
7983
|
} = deps;
|
|
@@ -7457,9 +7991,32 @@ function useTransferHandlers(deps) {
|
|
|
7457
7991
|
fetchProviders(apiBaseUrl, token)
|
|
7458
7992
|
]);
|
|
7459
7993
|
const parsedAmt = depositAmount != null ? depositAmount : 0;
|
|
7460
|
-
const defaults =
|
|
7461
|
-
|
|
7462
|
-
|
|
7994
|
+
const { defaults, resetSelectedTokenSymbol } = resolveDepositSelectionAfterRefresh(
|
|
7995
|
+
accts,
|
|
7996
|
+
parsedAmt,
|
|
7997
|
+
{
|
|
7998
|
+
selectedAccountId,
|
|
7999
|
+
selectedWalletId,
|
|
8000
|
+
selectedTokenSymbol
|
|
8001
|
+
}
|
|
8002
|
+
);
|
|
8003
|
+
dispatch({
|
|
8004
|
+
type: "ACCOUNTS_RELOADED",
|
|
8005
|
+
accounts: accts,
|
|
8006
|
+
providers: prov,
|
|
8007
|
+
defaults,
|
|
8008
|
+
resetSelectedTokenSymbol
|
|
8009
|
+
});
|
|
8010
|
+
}, [
|
|
8011
|
+
getAccessToken,
|
|
8012
|
+
activeCredentialId,
|
|
8013
|
+
selectedAccountId,
|
|
8014
|
+
selectedWalletId,
|
|
8015
|
+
selectedTokenSymbol,
|
|
8016
|
+
apiBaseUrl,
|
|
8017
|
+
depositAmount,
|
|
8018
|
+
dispatch
|
|
8019
|
+
]);
|
|
7463
8020
|
const handlePay = useCallback(async (payAmount, sourceOverrides) => {
|
|
7464
8021
|
const minUsd = effectiveMinTransferAmountUsd(depositAmount);
|
|
7465
8022
|
if (isNaN(payAmount) || payAmount < minUsd) {
|
|
@@ -7503,7 +8060,8 @@ function useTransferHandlers(deps) {
|
|
|
7503
8060
|
sourceId: effectiveSourceId,
|
|
7504
8061
|
sourceTokenAddress,
|
|
7505
8062
|
destination,
|
|
7506
|
-
amount: payAmount
|
|
8063
|
+
amount: payAmount,
|
|
8064
|
+
...quoteId ? { quoteId } : {}
|
|
7507
8065
|
});
|
|
7508
8066
|
dispatch({ type: "TRANSFER_CREATED", transfer: t });
|
|
7509
8067
|
if (t.status === "COMPLETED") {
|
|
@@ -7535,6 +8093,7 @@ function useTransferHandlers(deps) {
|
|
|
7535
8093
|
accounts,
|
|
7536
8094
|
destination,
|
|
7537
8095
|
apiBaseUrl,
|
|
8096
|
+
quoteId,
|
|
7538
8097
|
getAccessToken,
|
|
7539
8098
|
transferSigning,
|
|
7540
8099
|
polling,
|
|
@@ -7585,20 +8144,20 @@ function useSourceSelectionHandlers(dispatch, authExecutor, options) {
|
|
|
7585
8144
|
const selectSourceAvailableBalance = useMemo(() => {
|
|
7586
8145
|
if (!pendingSelectSourceAction) return 0;
|
|
7587
8146
|
const options2 = pendingSelectSourceAction.metadata?.options ?? [];
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
8147
|
+
return resolveSelectSourceAvailableBalance(
|
|
8148
|
+
selectSourceChoices,
|
|
8149
|
+
options2,
|
|
8150
|
+
selectSourceChainName,
|
|
8151
|
+
selectSourceTokenSymbol,
|
|
8152
|
+
selectSourceRecommended
|
|
8153
|
+
);
|
|
8154
|
+
}, [
|
|
8155
|
+
pendingSelectSourceAction,
|
|
8156
|
+
selectSourceChoices,
|
|
8157
|
+
selectSourceChainName,
|
|
8158
|
+
selectSourceTokenSymbol,
|
|
8159
|
+
selectSourceRecommended
|
|
8160
|
+
]);
|
|
7602
8161
|
const handleSelectSourceChainChange = useCallback(
|
|
7603
8162
|
(chainName) => {
|
|
7604
8163
|
setSelectSourceChainName(chainName);
|
|
@@ -7649,7 +8208,7 @@ function useSourceSelectionHandlers(dispatch, authExecutor, options) {
|
|
|
7649
8208
|
initializedSelectSourceActionRef
|
|
7650
8209
|
};
|
|
7651
8210
|
}
|
|
7652
|
-
function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransferIdRef, stateTransfer, refs, guestCheckout, onComplete) {
|
|
8211
|
+
function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransferIdRef, stateTransfer, refs, guestCheckout, onComplete, lastResumedAt) {
|
|
7653
8212
|
const {
|
|
7654
8213
|
mobileSetupFlowRef,
|
|
7655
8214
|
handlingMobileReturnRef,
|
|
@@ -7660,6 +8219,8 @@ function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransfe
|
|
|
7660
8219
|
onCompleteRef.current = onComplete;
|
|
7661
8220
|
const guestPollingActiveRef = useRef(false);
|
|
7662
8221
|
const guestPollingCleanupRef = useRef(null);
|
|
8222
|
+
const mobileFlowRef = useRef(guestCheckout.mobileFlow);
|
|
8223
|
+
mobileFlowRef.current = guestCheckout.mobileFlow;
|
|
7663
8224
|
const guestTransferIdRef = useRef(guestCheckout.guestTransferId);
|
|
7664
8225
|
guestTransferIdRef.current = guestCheckout.guestTransferId;
|
|
7665
8226
|
const guestSessionTokenRef = useRef(guestCheckout.guestSessionToken);
|
|
@@ -7715,27 +8276,15 @@ function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransfe
|
|
|
7715
8276
|
startGuestPolling
|
|
7716
8277
|
]);
|
|
7717
8278
|
useEffect(() => {
|
|
7718
|
-
|
|
7719
|
-
|
|
7720
|
-
|
|
7721
|
-
|
|
7722
|
-
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
}
|
|
7726
|
-
|
|
7727
|
-
if (document.visibilityState === "visible") tryStartPolling();
|
|
7728
|
-
};
|
|
7729
|
-
const handlePageShow = (e) => {
|
|
7730
|
-
if (e.persisted) tryStartPolling();
|
|
7731
|
-
};
|
|
7732
|
-
document.addEventListener("visibilitychange", handleVisibility);
|
|
7733
|
-
window.addEventListener("pageshow", handlePageShow);
|
|
7734
|
-
return () => {
|
|
7735
|
-
document.removeEventListener("visibilitychange", handleVisibility);
|
|
7736
|
-
window.removeEventListener("pageshow", handlePageShow);
|
|
7737
|
-
};
|
|
7738
|
-
}, [startGuestPolling]);
|
|
8279
|
+
if (!lastResumedAt) return;
|
|
8280
|
+
if (guestPollingActiveRef.current) return;
|
|
8281
|
+
if (!mobileFlowRef.current) return;
|
|
8282
|
+
const transferId = guestTransferIdRef.current;
|
|
8283
|
+
const token = guestSessionTokenRef.current;
|
|
8284
|
+
if (transferId && token) {
|
|
8285
|
+
startGuestPolling(transferId, token);
|
|
8286
|
+
}
|
|
8287
|
+
}, [lastResumedAt, startGuestPolling]);
|
|
7739
8288
|
const handleAuthorizedMobileReturn = useCallback(async (authorizedTransfer, isSetup) => {
|
|
7740
8289
|
if (handlingMobileReturnRef.current) return;
|
|
7741
8290
|
handlingMobileReturnRef.current = true;
|
|
@@ -7922,9 +8471,6 @@ function useProviderHandlers(deps) {
|
|
|
7922
8471
|
useWalletConnector: useWalletConnectorProp,
|
|
7923
8472
|
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
7924
8473
|
});
|
|
7925
|
-
if (!isMobile) {
|
|
7926
|
-
dispatch({ type: "PAY_STARTED" });
|
|
7927
|
-
}
|
|
7928
8474
|
try {
|
|
7929
8475
|
let accountId;
|
|
7930
8476
|
let sessionId;
|
|
@@ -7963,18 +8509,22 @@ function useProviderHandlers(deps) {
|
|
|
7963
8509
|
triggerDeeplink(sessionUri);
|
|
7964
8510
|
dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: sessionUri });
|
|
7965
8511
|
} else {
|
|
8512
|
+
dispatch({
|
|
8513
|
+
type: "SELECT_ACCOUNT",
|
|
8514
|
+
accountId,
|
|
8515
|
+
walletId: null
|
|
8516
|
+
});
|
|
7966
8517
|
await authExecutor.executeSessionById(sessionId);
|
|
7967
8518
|
await reloadAccounts();
|
|
7968
8519
|
}
|
|
7969
8520
|
} catch (err) {
|
|
8521
|
+
if (isAuthorizationSessionCancelled(err) || isUserDismissedAuthorizationError(err)) {
|
|
8522
|
+
return;
|
|
8523
|
+
}
|
|
7970
8524
|
captureException(err);
|
|
7971
8525
|
const msg = err instanceof Error ? err.message : "Failed to set up wallet";
|
|
7972
8526
|
dispatch({ type: "PAY_ERROR", error: msg });
|
|
7973
8527
|
onError?.(msg);
|
|
7974
|
-
} finally {
|
|
7975
|
-
if (!isMobile) {
|
|
7976
|
-
dispatch({ type: "PAY_ENDED" });
|
|
7977
|
-
}
|
|
7978
8528
|
}
|
|
7979
8529
|
}, [
|
|
7980
8530
|
authenticated,
|
|
@@ -8037,7 +8587,12 @@ function useProviderHandlers(deps) {
|
|
|
8037
8587
|
}
|
|
8038
8588
|
const acct = accounts.find((a) => a.id === selectedAccountId);
|
|
8039
8589
|
const matchedProvider = acct ? providers.find((p) => p.name === acct.name) : void 0;
|
|
8040
|
-
|
|
8590
|
+
const isMobile = !shouldUseWalletConnector({
|
|
8591
|
+
useWalletConnector: useWalletConnectorProp,
|
|
8592
|
+
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8593
|
+
});
|
|
8594
|
+
if (matchedProvider && isMobile) {
|
|
8595
|
+
dispatch({ type: "SAVE_SELECTION" });
|
|
8041
8596
|
dispatch({ type: "SELECT_PROVIDER", providerId: matchedProvider.id });
|
|
8042
8597
|
}
|
|
8043
8598
|
dispatch({ type: "SET_ERROR", error: null });
|
|
@@ -8057,10 +8612,6 @@ function useProviderHandlers(deps) {
|
|
|
8057
8612
|
activeCredentialId,
|
|
8058
8613
|
{ tokenAddress: source?.address, chainId: evmChainId }
|
|
8059
8614
|
);
|
|
8060
|
-
const isMobile = !shouldUseWalletConnector({
|
|
8061
|
-
useWalletConnector: useWalletConnectorProp,
|
|
8062
|
-
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8063
|
-
});
|
|
8064
8615
|
if (isMobile) {
|
|
8065
8616
|
handlingMobileReturnRef.current = false;
|
|
8066
8617
|
mobileSetupFlowRef.current = true;
|
|
@@ -8077,12 +8628,20 @@ function useProviderHandlers(deps) {
|
|
|
8077
8628
|
});
|
|
8078
8629
|
dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
|
|
8079
8630
|
triggerDeeplink(session.uri);
|
|
8631
|
+
dispatch({ type: "DISCARD_SAVED_SELECTION" });
|
|
8080
8632
|
} else {
|
|
8081
8633
|
await authExecutor.executeSessionById(session.id);
|
|
8082
8634
|
await reloadAccounts();
|
|
8635
|
+
dispatch({ type: "DISCARD_SAVED_SELECTION" });
|
|
8083
8636
|
}
|
|
8084
8637
|
} catch (err) {
|
|
8638
|
+
if (isAuthorizationSessionCancelled(err) || isUserDismissedAuthorizationError(err)) {
|
|
8639
|
+
return;
|
|
8640
|
+
}
|
|
8085
8641
|
captureException(err);
|
|
8642
|
+
if (isMobile) {
|
|
8643
|
+
dispatch({ type: "RESTORE_SELECTION" });
|
|
8644
|
+
}
|
|
8086
8645
|
const msg = err instanceof Error ? err.message : "Failed to increase limit";
|
|
8087
8646
|
dispatch({ type: "SET_ERROR", error: msg });
|
|
8088
8647
|
onError?.(msg);
|
|
@@ -8127,7 +8686,12 @@ function useProviderHandlers(deps) {
|
|
|
8127
8686
|
}
|
|
8128
8687
|
const acct = accounts.find((a) => a.id === selectedAccountId);
|
|
8129
8688
|
const matchedProvider = acct ? providers.find((p) => p.name === acct.name) : void 0;
|
|
8130
|
-
|
|
8689
|
+
const isMobile = !shouldUseWalletConnector({
|
|
8690
|
+
useWalletConnector: useWalletConnectorProp,
|
|
8691
|
+
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8692
|
+
});
|
|
8693
|
+
if (matchedProvider && isMobile) {
|
|
8694
|
+
dispatch({ type: "SAVE_SELECTION" });
|
|
8131
8695
|
dispatch({ type: "SELECT_PROVIDER", providerId: matchedProvider.id });
|
|
8132
8696
|
}
|
|
8133
8697
|
dispatch({ type: "SET_ERROR", error: null });
|
|
@@ -8142,10 +8706,6 @@ function useProviderHandlers(deps) {
|
|
|
8142
8706
|
activeCredentialId,
|
|
8143
8707
|
{ tokenAddress, chainId }
|
|
8144
8708
|
);
|
|
8145
|
-
const isMobile = !shouldUseWalletConnector({
|
|
8146
|
-
useWalletConnector: useWalletConnectorProp,
|
|
8147
|
-
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8148
|
-
});
|
|
8149
8709
|
if (isMobile) {
|
|
8150
8710
|
handlingMobileReturnRef.current = false;
|
|
8151
8711
|
mobileSetupFlowRef.current = true;
|
|
@@ -8163,13 +8723,21 @@ function useProviderHandlers(deps) {
|
|
|
8163
8723
|
});
|
|
8164
8724
|
dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
|
|
8165
8725
|
triggerDeeplink(session.uri);
|
|
8726
|
+
dispatch({ type: "DISCARD_SAVED_SELECTION" });
|
|
8166
8727
|
} else {
|
|
8167
8728
|
await authExecutor.executeSessionById(session.id);
|
|
8168
8729
|
await reloadAccounts();
|
|
8169
8730
|
dispatch({ type: "SELECT_TOKEN", walletId: _walletId, tokenSymbol });
|
|
8731
|
+
dispatch({ type: "DISCARD_SAVED_SELECTION" });
|
|
8170
8732
|
}
|
|
8171
8733
|
} catch (err) {
|
|
8734
|
+
if (isAuthorizationSessionCancelled(err) || isUserDismissedAuthorizationError(err)) {
|
|
8735
|
+
return;
|
|
8736
|
+
}
|
|
8172
8737
|
captureException(err);
|
|
8738
|
+
if (isMobile) {
|
|
8739
|
+
dispatch({ type: "RESTORE_SELECTION" });
|
|
8740
|
+
}
|
|
8173
8741
|
const msg = err instanceof Error ? err.message : "Failed to authorize token";
|
|
8174
8742
|
dispatch({ type: "SET_ERROR", error: msg });
|
|
8175
8743
|
onError?.(msg);
|
|
@@ -9106,7 +9674,15 @@ function useDataLoadEffect(deps) {
|
|
|
9106
9674
|
]);
|
|
9107
9675
|
if (cancelled) return;
|
|
9108
9676
|
const parsedAmt = depositAmount != null ? depositAmount : 0;
|
|
9109
|
-
const defaults =
|
|
9677
|
+
const { defaults, resetSelectedTokenSymbol } = resolveDepositSelectionAfterRefresh(
|
|
9678
|
+
accts,
|
|
9679
|
+
parsedAmt,
|
|
9680
|
+
{
|
|
9681
|
+
selectedAccountId: state.selectedAccountId,
|
|
9682
|
+
selectedWalletId: state.selectedWalletId,
|
|
9683
|
+
selectedTokenSymbol: state.selectedTokenSymbol
|
|
9684
|
+
}
|
|
9685
|
+
);
|
|
9110
9686
|
const persisted = loadMobileFlowState();
|
|
9111
9687
|
const clearMobile = persisted?.isSetup && accts.some((a) => a.wallets.some((w) => w.status === "ACTIVE"));
|
|
9112
9688
|
dispatch({
|
|
@@ -9115,7 +9691,8 @@ function useDataLoadEffect(deps) {
|
|
|
9115
9691
|
accounts: accts,
|
|
9116
9692
|
chains: chn,
|
|
9117
9693
|
defaults,
|
|
9118
|
-
clearMobileState: clearMobile
|
|
9694
|
+
clearMobileState: clearMobile,
|
|
9695
|
+
resetSelectedTokenSymbol
|
|
9119
9696
|
});
|
|
9120
9697
|
if (clearMobile) clearMobileFlowState();
|
|
9121
9698
|
} catch (err) {
|
|
@@ -9144,6 +9721,8 @@ function useDataLoadEffect(deps) {
|
|
|
9144
9721
|
apiBaseUrl,
|
|
9145
9722
|
state.activeCredentialId,
|
|
9146
9723
|
state.selectedAccountId,
|
|
9724
|
+
state.selectedWalletId,
|
|
9725
|
+
state.selectedTokenSymbol,
|
|
9147
9726
|
depositAmount
|
|
9148
9727
|
]);
|
|
9149
9728
|
useEffect(() => {
|
|
@@ -9372,25 +9951,16 @@ function useMobilePollingEffect(deps) {
|
|
|
9372
9951
|
const poll = isReauth ? pollReauthorization : pollWalletActive;
|
|
9373
9952
|
poll();
|
|
9374
9953
|
const intervalId = window.setInterval(poll, POLL_INTERVAL_MS);
|
|
9375
|
-
const handleVisibility = () => {
|
|
9376
|
-
if (document.visibilityState === "visible" && !cancelled) poll();
|
|
9377
|
-
};
|
|
9378
|
-
const handlePageShow = (e) => {
|
|
9379
|
-
if (e.persisted && !cancelled) poll();
|
|
9380
|
-
};
|
|
9381
|
-
document.addEventListener("visibilitychange", handleVisibility);
|
|
9382
|
-
window.addEventListener("pageshow", handlePageShow);
|
|
9383
9954
|
return () => {
|
|
9384
9955
|
cancelled = true;
|
|
9385
9956
|
window.clearInterval(intervalId);
|
|
9386
|
-
document.removeEventListener("visibilitychange", handleVisibility);
|
|
9387
|
-
window.removeEventListener("pageshow", handlePageShow);
|
|
9388
9957
|
};
|
|
9389
9958
|
}, [
|
|
9390
9959
|
state.mobileFlow,
|
|
9391
9960
|
state.isGuestFlow,
|
|
9392
9961
|
state.guestPreauthSessionId,
|
|
9393
9962
|
state.activeCredentialId,
|
|
9963
|
+
state.lastResumedAt,
|
|
9394
9964
|
apiBaseUrl,
|
|
9395
9965
|
reloadAccounts,
|
|
9396
9966
|
dispatch,
|
|
@@ -9407,28 +9977,13 @@ function useMobilePollingEffect(deps) {
|
|
|
9407
9977
|
const transferIdToResume = pollingTransferIdRef.current ?? state.transfer?.id;
|
|
9408
9978
|
if (!transferIdToResume) return;
|
|
9409
9979
|
if (!polling.isPolling) polling.startPolling(transferIdToResume);
|
|
9410
|
-
const handleVisibility = () => {
|
|
9411
|
-
if (document.visibilityState === "visible" && !handlingMobileReturnRef.current) {
|
|
9412
|
-
polling.startPolling(transferIdToResume);
|
|
9413
|
-
}
|
|
9414
|
-
};
|
|
9415
|
-
const handlePageShow = (e) => {
|
|
9416
|
-
if (e.persisted && !handlingMobileReturnRef.current) {
|
|
9417
|
-
polling.startPolling(transferIdToResume);
|
|
9418
|
-
}
|
|
9419
|
-
};
|
|
9420
|
-
document.addEventListener("visibilitychange", handleVisibility);
|
|
9421
|
-
window.addEventListener("pageshow", handlePageShow);
|
|
9422
|
-
return () => {
|
|
9423
|
-
document.removeEventListener("visibilitychange", handleVisibility);
|
|
9424
|
-
window.removeEventListener("pageshow", handlePageShow);
|
|
9425
|
-
};
|
|
9426
9980
|
}, [
|
|
9427
9981
|
state.mobileFlow,
|
|
9428
9982
|
state.transfer?.id,
|
|
9429
9983
|
state.isGuestFlow,
|
|
9430
9984
|
state.guestPreauthSessionId,
|
|
9431
9985
|
state.guestPreauthAccountId,
|
|
9986
|
+
state.lastResumedAt,
|
|
9432
9987
|
polling.isPolling,
|
|
9433
9988
|
polling.startPolling,
|
|
9434
9989
|
handlingMobileReturnRef,
|
|
@@ -9439,6 +9994,7 @@ function useGuestPreauthMobileRestoreEffect(deps) {
|
|
|
9439
9994
|
const {
|
|
9440
9995
|
dispatch,
|
|
9441
9996
|
privyReady,
|
|
9997
|
+
lastResumedAt,
|
|
9442
9998
|
mobileSetupFlowRef,
|
|
9443
9999
|
setupAccountIdRef,
|
|
9444
10000
|
startGuestAccountPolling
|
|
@@ -9449,68 +10005,43 @@ function useGuestPreauthMobileRestoreEffect(deps) {
|
|
|
9449
10005
|
console.info("[blink-sdk] guestPreauthMobileRestore: skipping, privyReady=false");
|
|
9450
10006
|
return;
|
|
9451
10007
|
}
|
|
9452
|
-
|
|
9453
|
-
|
|
9454
|
-
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
|
|
9461
|
-
|
|
9462
|
-
|
|
9463
|
-
|
|
9464
|
-
|
|
9465
|
-
|
|
9466
|
-
|
|
9467
|
-
|
|
9468
|
-
|
|
9469
|
-
|
|
9470
|
-
|
|
9471
|
-
|
|
9472
|
-
|
|
9473
|
-
|
|
9474
|
-
if (persisted.accountId) {
|
|
9475
|
-
dispatch({
|
|
9476
|
-
type: "GUEST_PREAUTH_DETECTED",
|
|
9477
|
-
accountId: persisted.accountId,
|
|
9478
|
-
sessionId: persisted.sessionId
|
|
9479
|
-
});
|
|
9480
|
-
}
|
|
10008
|
+
if (startedRef.current) {
|
|
10009
|
+
console.info("[blink-sdk] guestPreauthMobileRestore: already started");
|
|
10010
|
+
return;
|
|
10011
|
+
}
|
|
10012
|
+
const persisted = loadMobileFlowState();
|
|
10013
|
+
console.info("[blink-sdk] guestPreauthMobileRestore.tryStart", {
|
|
10014
|
+
trigger: lastResumedAt ? "page-resume" : "initial",
|
|
10015
|
+
hasPersistedState: !!persisted,
|
|
10016
|
+
isGuestPreauth: persisted?.isGuestPreauth ?? false,
|
|
10017
|
+
hasGuestSessionToken: !!persisted?.guestSessionToken,
|
|
10018
|
+
hasSessionId: !!persisted?.sessionId,
|
|
10019
|
+
accountId: persisted?.accountId ?? null
|
|
10020
|
+
});
|
|
10021
|
+
if (!persisted?.isGuestPreauth || !persisted.guestSessionToken || !persisted.sessionId) {
|
|
10022
|
+
return;
|
|
10023
|
+
}
|
|
10024
|
+
startedRef.current = true;
|
|
10025
|
+
mobileSetupFlowRef.current = true;
|
|
10026
|
+
if (persisted.accountId) {
|
|
10027
|
+
setupAccountIdRef.current = persisted.accountId;
|
|
10028
|
+
}
|
|
10029
|
+
if (persisted.accountId) {
|
|
9481
10030
|
dispatch({
|
|
9482
|
-
type: "
|
|
9483
|
-
|
|
9484
|
-
});
|
|
9485
|
-
console.info("[blink-sdk] guestPreauthMobileRestore: starting guest account polling", {
|
|
9486
|
-
trigger,
|
|
10031
|
+
type: "GUEST_PREAUTH_DETECTED",
|
|
10032
|
+
accountId: persisted.accountId,
|
|
9487
10033
|
sessionId: persisted.sessionId
|
|
9488
10034
|
});
|
|
9489
|
-
|
|
9490
|
-
|
|
9491
|
-
|
|
9492
|
-
|
|
9493
|
-
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9498
|
-
|
|
9499
|
-
console.info("[blink-sdk] guestPreauthMobileRestore: pageshow fired", {
|
|
9500
|
-
persisted: e.persisted,
|
|
9501
|
-
visibilityState: document.visibilityState,
|
|
9502
|
-
startedRef: startedRef.current
|
|
9503
|
-
});
|
|
9504
|
-
if (document.visibilityState === "visible") tryStart("pageshow");
|
|
9505
|
-
};
|
|
9506
|
-
tryStart("initial");
|
|
9507
|
-
document.addEventListener("visibilitychange", onVisibility);
|
|
9508
|
-
window.addEventListener("pageshow", onPageShow);
|
|
9509
|
-
return () => {
|
|
9510
|
-
document.removeEventListener("visibilitychange", onVisibility);
|
|
9511
|
-
window.removeEventListener("pageshow", onPageShow);
|
|
9512
|
-
};
|
|
9513
|
-
}, [privyReady, dispatch, mobileSetupFlowRef, setupAccountIdRef, startGuestAccountPolling]);
|
|
10035
|
+
}
|
|
10036
|
+
dispatch({
|
|
10037
|
+
type: "MOBILE_DEEPLINK_READY",
|
|
10038
|
+
deeplinkUri: persisted.deeplinkUri
|
|
10039
|
+
});
|
|
10040
|
+
console.info("[blink-sdk] guestPreauthMobileRestore: starting guest account polling", {
|
|
10041
|
+
sessionId: persisted.sessionId
|
|
10042
|
+
});
|
|
10043
|
+
startGuestAccountPolling(persisted.guestSessionToken, persisted.sessionId);
|
|
10044
|
+
}, [privyReady, lastResumedAt, dispatch, mobileSetupFlowRef, setupAccountIdRef, startGuestAccountPolling]);
|
|
9514
10045
|
}
|
|
9515
10046
|
function useSelectSourceEffect(deps) {
|
|
9516
10047
|
const {
|
|
@@ -9711,7 +10242,9 @@ function useGuestDesktopPreauthSessionEffect(deps) {
|
|
|
9711
10242
|
function useGuestPreauthPhaseSyncEffect(deps) {
|
|
9712
10243
|
const { state, dispatch, authExecutor, isDesktop, privyAuthenticated } = deps;
|
|
9713
10244
|
useEffect(() => {
|
|
9714
|
-
if (!
|
|
10245
|
+
if (!isDesktop) return;
|
|
10246
|
+
const standardDesktopAuth = privyAuthenticated && state.activeCredentialId != null && !state.guestPreauthorizing;
|
|
10247
|
+
if (!state.guestPreauthorizing && !standardDesktopAuth) return;
|
|
9715
10248
|
const pending = authExecutor.pendingSelectSource;
|
|
9716
10249
|
if (pending) {
|
|
9717
10250
|
if (state.phase.step === "token-picker") {
|
|
@@ -9735,7 +10268,7 @@ function useGuestPreauthPhaseSyncEffect(deps) {
|
|
|
9735
10268
|
dispatch({ type: "SET_USER_INTENT", intent: { step: "one-tap-setup", action: null } });
|
|
9736
10269
|
return;
|
|
9737
10270
|
}
|
|
9738
|
-
if (!privyAuthenticated && authExecutor.executing && state.guestPreauthAccountId) {
|
|
10271
|
+
if (state.guestPreauthorizing && !privyAuthenticated && authExecutor.executing && state.guestPreauthAccountId) {
|
|
9739
10272
|
const accountId = state.guestPreauthAccountId;
|
|
9740
10273
|
const p = state.phase;
|
|
9741
10274
|
if (p.step === "wallet-setup" && p.mobile == null && p.guestDesktopExtension && p.accountId === accountId) {
|
|
@@ -9763,6 +10296,7 @@ function useGuestPreauthPhaseSyncEffect(deps) {
|
|
|
9763
10296
|
state.guestPreauthorizing,
|
|
9764
10297
|
state.phase,
|
|
9765
10298
|
state.guestPreauthAccountId,
|
|
10299
|
+
state.activeCredentialId,
|
|
9766
10300
|
isDesktop,
|
|
9767
10301
|
privyAuthenticated,
|
|
9768
10302
|
authExecutor.pendingSelectSource,
|
|
@@ -9811,7 +10345,7 @@ function useStandardDesktopInlineOpenWalletEffect(deps) {
|
|
|
9811
10345
|
useEffect(() => {
|
|
9812
10346
|
if (!isDesktop || state.guestPreauthorizing) return;
|
|
9813
10347
|
if (!state.privyAuthenticated || !state.activeCredentialId || !state.selectedAccountId) return;
|
|
9814
|
-
const shouldPin = authExecutor.executing && !authExecutor.pendingSelectSource && !authExecutor.pendingOneTapSetup;
|
|
10348
|
+
const shouldPin = authExecutor.executing && !authExecutor.pendingSelectSource && (!authExecutor.pendingOneTapSetup || authExecutor.authorizationSessionStackDepth > 1);
|
|
9815
10349
|
if (shouldPin && !state.standardDesktopInlineOpenWallet) {
|
|
9816
10350
|
dispatch({ type: "SET_STANDARD_DESKTOP_INLINE_OPEN_WALLET", value: true });
|
|
9817
10351
|
return;
|
|
@@ -9829,6 +10363,7 @@ function useStandardDesktopInlineOpenWalletEffect(deps) {
|
|
|
9829
10363
|
authExecutor.executing,
|
|
9830
10364
|
authExecutor.pendingSelectSource,
|
|
9831
10365
|
authExecutor.pendingOneTapSetup,
|
|
10366
|
+
authExecutor.authorizationSessionStackDepth,
|
|
9832
10367
|
dispatch
|
|
9833
10368
|
]);
|
|
9834
10369
|
}
|
|
@@ -9847,7 +10382,84 @@ function useGuestAccountAutoPollingEffect(deps) {
|
|
|
9847
10382
|
startPolling(guestSessionToken);
|
|
9848
10383
|
}, [mobileFlow, isGuestFlow, guestSessionToken, isPolling, guestAccount, startPolling]);
|
|
9849
10384
|
}
|
|
9850
|
-
|
|
10385
|
+
var WATCHDOG_INTERVAL_MS = 1e3;
|
|
10386
|
+
var WATCHDOG_THRESHOLD_MS = 3e3;
|
|
10387
|
+
var DEDUP_COOLDOWN_MS = 500;
|
|
10388
|
+
function usePageResume(callback) {
|
|
10389
|
+
const callbackRef = useRef(callback);
|
|
10390
|
+
callbackRef.current = callback;
|
|
10391
|
+
useEffect(() => {
|
|
10392
|
+
let lastTickAt = Date.now();
|
|
10393
|
+
let lastFiredAt = 0;
|
|
10394
|
+
const fire = (source, frozenDurationMs) => {
|
|
10395
|
+
const now = Date.now();
|
|
10396
|
+
if (now - lastFiredAt < DEDUP_COOLDOWN_MS) return;
|
|
10397
|
+
lastFiredAt = now;
|
|
10398
|
+
callbackRef.current({ frozenDurationMs, source });
|
|
10399
|
+
};
|
|
10400
|
+
const watchdogId = window.setInterval(() => {
|
|
10401
|
+
const now = Date.now();
|
|
10402
|
+
const elapsed = now - lastTickAt;
|
|
10403
|
+
lastTickAt = now;
|
|
10404
|
+
if (elapsed > WATCHDOG_THRESHOLD_MS) {
|
|
10405
|
+
fire("watchdog", elapsed);
|
|
10406
|
+
}
|
|
10407
|
+
}, WATCHDOG_INTERVAL_MS);
|
|
10408
|
+
const handleVisibility = () => {
|
|
10409
|
+
const now = Date.now();
|
|
10410
|
+
if (document.visibilityState === "visible") {
|
|
10411
|
+
fire("visibilitychange", now - lastTickAt);
|
|
10412
|
+
}
|
|
10413
|
+
lastTickAt = now;
|
|
10414
|
+
};
|
|
10415
|
+
const handlePageShow = (_e) => {
|
|
10416
|
+
const now = Date.now();
|
|
10417
|
+
if (document.visibilityState === "visible") {
|
|
10418
|
+
fire("pageshow", now - lastTickAt);
|
|
10419
|
+
}
|
|
10420
|
+
lastTickAt = now;
|
|
10421
|
+
};
|
|
10422
|
+
const handleFocus = () => {
|
|
10423
|
+
const now = Date.now();
|
|
10424
|
+
const elapsed = now - lastTickAt;
|
|
10425
|
+
lastTickAt = now;
|
|
10426
|
+
if (elapsed > WATCHDOG_THRESHOLD_MS) {
|
|
10427
|
+
fire("focus", elapsed);
|
|
10428
|
+
}
|
|
10429
|
+
};
|
|
10430
|
+
document.addEventListener("visibilitychange", handleVisibility);
|
|
10431
|
+
window.addEventListener("pageshow", handlePageShow);
|
|
10432
|
+
window.addEventListener("focus", handleFocus);
|
|
10433
|
+
return () => {
|
|
10434
|
+
window.clearInterval(watchdogId);
|
|
10435
|
+
document.removeEventListener("visibilitychange", handleVisibility);
|
|
10436
|
+
window.removeEventListener("pageshow", handlePageShow);
|
|
10437
|
+
window.removeEventListener("focus", handleFocus);
|
|
10438
|
+
};
|
|
10439
|
+
}, []);
|
|
10440
|
+
}
|
|
10441
|
+
var STUCK_REF_THRESHOLD_MS = 5e3;
|
|
10442
|
+
function usePageResumeEffect(deps) {
|
|
10443
|
+
const { dispatch, handlingMobileReturnRef } = deps;
|
|
10444
|
+
const dispatchRef = useRef(dispatch);
|
|
10445
|
+
dispatchRef.current = dispatch;
|
|
10446
|
+
usePageResume((info) => {
|
|
10447
|
+
console.info("[blink-sdk] PAGE_RESUMED", {
|
|
10448
|
+
source: info.source,
|
|
10449
|
+
frozenDurationMs: info.frozenDurationMs
|
|
10450
|
+
});
|
|
10451
|
+
dispatchRef.current({ type: "PAGE_RESUMED", frozenDurationMs: info.frozenDurationMs });
|
|
10452
|
+
if (info.frozenDurationMs > STUCK_REF_THRESHOLD_MS) {
|
|
10453
|
+
if (handlingMobileReturnRef.current) {
|
|
10454
|
+
console.info("[blink-sdk] PAGE_RESUMED: clearing stuck handlingMobileReturnRef", {
|
|
10455
|
+
frozenDurationMs: info.frozenDurationMs
|
|
10456
|
+
});
|
|
10457
|
+
handlingMobileReturnRef.current = false;
|
|
10458
|
+
}
|
|
10459
|
+
}
|
|
10460
|
+
});
|
|
10461
|
+
}
|
|
10462
|
+
function useGuestAccountPolling(intervalMs = 3e3, lastResumedAt = 0) {
|
|
9851
10463
|
const { apiBaseUrl } = useBlinkConfig();
|
|
9852
10464
|
const [guestAccount, setGuestAccount] = useState(null);
|
|
9853
10465
|
const [isPolling, setIsPolling] = useState(false);
|
|
@@ -9945,36 +10557,71 @@ function useGuestAccountPolling(intervalMs = 3e3) {
|
|
|
9945
10557
|
[poll, intervalMs, stopPolling]
|
|
9946
10558
|
);
|
|
9947
10559
|
useEffect(() => {
|
|
9948
|
-
|
|
9949
|
-
|
|
9950
|
-
|
|
9951
|
-
|
|
9952
|
-
|
|
9953
|
-
|
|
9954
|
-
|
|
9955
|
-
|
|
9956
|
-
|
|
9957
|
-
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
|
|
10560
|
+
if (!lastResumedAt || !guestTokenRef.current) return;
|
|
10561
|
+
console.info("[blink-sdk] useGuestAccountPolling: page resumed, triggering poll", {
|
|
10562
|
+
lastResumedAt,
|
|
10563
|
+
hasToken: !!guestTokenRef.current,
|
|
10564
|
+
hasSessionId: !!sessionIdRef.current
|
|
10565
|
+
});
|
|
10566
|
+
void poll();
|
|
10567
|
+
}, [lastResumedAt, poll]);
|
|
10568
|
+
useEffect(() => () => stopPolling(), [stopPolling]);
|
|
10569
|
+
return { guestAccount, error, isPolling, startPolling, stopPolling };
|
|
10570
|
+
}
|
|
10571
|
+
function useDepositFeeEstimate({
|
|
10572
|
+
apiBaseUrl,
|
|
10573
|
+
getAccessToken,
|
|
10574
|
+
walletId,
|
|
10575
|
+
sourceTokenAddress,
|
|
10576
|
+
destination,
|
|
10577
|
+
amount,
|
|
10578
|
+
enabled
|
|
10579
|
+
}) {
|
|
10580
|
+
const [quoteId, setQuoteId] = useState(null);
|
|
10581
|
+
const [quoteFee, setQuoteFee] = useState(null);
|
|
10582
|
+
const [quoteLoading, setQuoteLoading] = useState(false);
|
|
10583
|
+
const abortRef = useRef(null);
|
|
10584
|
+
const fetchQuote = useCallback(async () => {
|
|
10585
|
+
if (!enabled || !walletId || !sourceTokenAddress) {
|
|
10586
|
+
setQuoteId(null);
|
|
10587
|
+
setQuoteFee(null);
|
|
10588
|
+
setQuoteLoading(false);
|
|
10589
|
+
return;
|
|
10590
|
+
}
|
|
10591
|
+
abortRef.current?.abort();
|
|
10592
|
+
const controller = new AbortController();
|
|
10593
|
+
abortRef.current = controller;
|
|
10594
|
+
setQuoteLoading(true);
|
|
10595
|
+
try {
|
|
10596
|
+
const token = await getAccessToken();
|
|
10597
|
+
if (!token || controller.signal.aborted) return;
|
|
10598
|
+
const quote = await postTransferQuote(apiBaseUrl, token, {
|
|
10599
|
+
walletId,
|
|
10600
|
+
sourceTokenAddress,
|
|
10601
|
+
destination,
|
|
10602
|
+
amount: { amount, currency: "USD" }
|
|
9964
10603
|
});
|
|
9965
|
-
if (
|
|
9966
|
-
|
|
10604
|
+
if (controller.signal.aborted) return;
|
|
10605
|
+
setQuoteId(quote.id);
|
|
10606
|
+
setQuoteFee(quote.fee);
|
|
10607
|
+
} catch (err) {
|
|
10608
|
+
if (controller.signal.aborted) return;
|
|
10609
|
+
console.warn("[blink-sdk] Fee quote failed:", err);
|
|
10610
|
+
setQuoteId(null);
|
|
10611
|
+
setQuoteFee(null);
|
|
10612
|
+
} finally {
|
|
10613
|
+
if (!controller.signal.aborted) {
|
|
10614
|
+
setQuoteLoading(false);
|
|
9967
10615
|
}
|
|
9968
|
-
}
|
|
9969
|
-
|
|
9970
|
-
|
|
10616
|
+
}
|
|
10617
|
+
}, [enabled, walletId, sourceTokenAddress, destination, amount, apiBaseUrl, getAccessToken]);
|
|
10618
|
+
useEffect(() => {
|
|
10619
|
+
fetchQuote();
|
|
9971
10620
|
return () => {
|
|
9972
|
-
|
|
9973
|
-
window.removeEventListener("pageshow", handlePageShow);
|
|
10621
|
+
abortRef.current?.abort();
|
|
9974
10622
|
};
|
|
9975
|
-
}, [
|
|
9976
|
-
|
|
9977
|
-
return { guestAccount, error, isPolling, startPolling, stopPolling };
|
|
10623
|
+
}, [fetchQuote]);
|
|
10624
|
+
return { quoteId, quoteFee, quoteLoading };
|
|
9978
10625
|
}
|
|
9979
10626
|
function BlinkPayment(props) {
|
|
9980
10627
|
const resetKey = useRef(0);
|
|
@@ -10014,7 +10661,7 @@ function BlinkPaymentInner({
|
|
|
10014
10661
|
);
|
|
10015
10662
|
const authExecutor = useAuthorizationExecutor();
|
|
10016
10663
|
const polling = useTransferPolling();
|
|
10017
|
-
const guestAccountPolling = useGuestAccountPolling();
|
|
10664
|
+
const guestAccountPolling = useGuestAccountPolling(3e3, state.lastResumedAt);
|
|
10018
10665
|
const transferSigning = useTransferSigning();
|
|
10019
10666
|
const mobileFlowRefs = {
|
|
10020
10667
|
mobileSetupFlowRef: useRef(false),
|
|
@@ -10032,6 +10679,15 @@ function BlinkPaymentInner({
|
|
|
10032
10679
|
state.accounts,
|
|
10033
10680
|
state.knownCredentialIds
|
|
10034
10681
|
);
|
|
10682
|
+
const depositFee = useDepositFeeEstimate({
|
|
10683
|
+
apiBaseUrl,
|
|
10684
|
+
getAccessToken,
|
|
10685
|
+
walletId: state.selectedWalletId,
|
|
10686
|
+
sourceTokenAddress: derived.selectedSource?.address,
|
|
10687
|
+
destination,
|
|
10688
|
+
amount: depositAmount ?? 5,
|
|
10689
|
+
enabled: state.phase.step === "deposit" && !state.isGuestFlow && authenticated
|
|
10690
|
+
});
|
|
10035
10691
|
const transfer = useTransferHandlers({
|
|
10036
10692
|
dispatch,
|
|
10037
10693
|
getAccessToken,
|
|
@@ -10049,6 +10705,9 @@ function BlinkPaymentInner({
|
|
|
10049
10705
|
sourceTokenAddress: derived.selectedSource?.address,
|
|
10050
10706
|
activeCredentialId: state.activeCredentialId,
|
|
10051
10707
|
selectedAccountId: state.selectedAccountId,
|
|
10708
|
+
selectedWalletId: state.selectedWalletId,
|
|
10709
|
+
selectedTokenSymbol: state.selectedTokenSymbol,
|
|
10710
|
+
quoteId: depositFee.quoteId,
|
|
10052
10711
|
transfer: state.transfer,
|
|
10053
10712
|
accounts: state.accounts
|
|
10054
10713
|
});
|
|
@@ -10065,7 +10724,8 @@ function BlinkPaymentInner({
|
|
|
10065
10724
|
guestTransferId: state.guestTransferId,
|
|
10066
10725
|
guestSessionToken: state.guestSessionToken
|
|
10067
10726
|
},
|
|
10068
|
-
onComplete
|
|
10727
|
+
onComplete,
|
|
10728
|
+
state.lastResumedAt
|
|
10069
10729
|
);
|
|
10070
10730
|
const sourceSelection = useSourceSelectionHandlers(dispatch, authExecutor, {
|
|
10071
10731
|
guestPreauthSessionId: state.guestPreauthSessionId,
|
|
@@ -10161,10 +10821,15 @@ function BlinkPaymentInner({
|
|
|
10161
10821
|
dispatch({ type: "SYNC_AMOUNT", amount: depositAmount.toString() });
|
|
10162
10822
|
}
|
|
10163
10823
|
}, [depositAmount, dispatch]);
|
|
10824
|
+
usePageResumeEffect({
|
|
10825
|
+
dispatch,
|
|
10826
|
+
handlingMobileReturnRef: mobileFlowRefs.handlingMobileReturnRef
|
|
10827
|
+
});
|
|
10164
10828
|
usePrivySessionSyncEffect({ dispatch, ready, authenticated });
|
|
10165
10829
|
useGuestPreauthMobileRestoreEffect({
|
|
10166
10830
|
dispatch,
|
|
10167
10831
|
privyReady: state.privyReady,
|
|
10832
|
+
lastResumedAt: state.lastResumedAt,
|
|
10168
10833
|
mobileSetupFlowRef: mobileFlowRefs.mobileSetupFlowRef,
|
|
10169
10834
|
setupAccountIdRef: mobileFlowRefs.setupAccountIdRef,
|
|
10170
10835
|
startGuestAccountPolling: guestAccountPolling.startPolling
|
|
@@ -10177,25 +10842,24 @@ function BlinkPaymentInner({
|
|
|
10177
10842
|
guestAccount: guestAccountPolling.guestAccount,
|
|
10178
10843
|
startPolling: guestAccountPolling.startPolling
|
|
10179
10844
|
});
|
|
10180
|
-
const guestSessionTokenRef = useRef(state.guestSessionToken);
|
|
10181
|
-
guestSessionTokenRef.current = state.guestSessionToken;
|
|
10182
|
-
const guestPreauthSessionIdRef = useRef(state.guestPreauthSessionId);
|
|
10183
|
-
guestPreauthSessionIdRef.current = state.guestPreauthSessionId;
|
|
10184
10845
|
useEffect(() => {
|
|
10185
|
-
|
|
10186
|
-
|
|
10187
|
-
|
|
10188
|
-
|
|
10189
|
-
|
|
10190
|
-
|
|
10191
|
-
|
|
10192
|
-
|
|
10193
|
-
|
|
10194
|
-
|
|
10195
|
-
|
|
10196
|
-
|
|
10197
|
-
|
|
10198
|
-
|
|
10846
|
+
if (!state.lastResumedAt) return;
|
|
10847
|
+
const token = state.guestSessionToken;
|
|
10848
|
+
const sessionId = state.guestPreauthSessionId;
|
|
10849
|
+
if (!token) return;
|
|
10850
|
+
if (guestAccountPolling.isPolling || guestAccountPolling.guestAccount) return;
|
|
10851
|
+
console.info("[blink-sdk] warm-return: restarting guest account polling from React state", {
|
|
10852
|
+
sessionId: sessionId ?? "(none \u2014 account-only mode)"
|
|
10853
|
+
});
|
|
10854
|
+
guestAccountPolling.startPolling(token, sessionId ?? void 0);
|
|
10855
|
+
}, [
|
|
10856
|
+
state.lastResumedAt,
|
|
10857
|
+
state.guestSessionToken,
|
|
10858
|
+
state.guestPreauthSessionId,
|
|
10859
|
+
guestAccountPolling.isPolling,
|
|
10860
|
+
guestAccountPolling.guestAccount,
|
|
10861
|
+
guestAccountPolling.startPolling
|
|
10862
|
+
]);
|
|
10199
10863
|
useEffect(() => {
|
|
10200
10864
|
console.info("[blink-sdk] guestPreauthCompletion effect", {
|
|
10201
10865
|
hasGuestAccount: !!guestAccountPolling.guestAccount,
|
|
@@ -10360,6 +11024,11 @@ function BlinkPaymentInner({
|
|
|
10360
11024
|
onLogout: handleLogout,
|
|
10361
11025
|
onNewPayment: handleNewPayment,
|
|
10362
11026
|
onSetPhase: (phase) => dispatch({ type: "SET_USER_INTENT", intent: phase }),
|
|
11027
|
+
onBackFromSubflow: () => {
|
|
11028
|
+
authExecutor.cancelPendingExecution();
|
|
11029
|
+
dispatch({ type: "RESTORE_SELECTION" });
|
|
11030
|
+
dispatch({ type: "SET_USER_INTENT", intent: { step: "deposit" } });
|
|
11031
|
+
},
|
|
10363
11032
|
onSetAuthInput: auth.setAuthInput,
|
|
10364
11033
|
onSetOtpCode: (code) => {
|
|
10365
11034
|
auth.setOtpCode(code);
|
|
@@ -10393,7 +11062,8 @@ function BlinkPaymentInner({
|
|
|
10393
11062
|
handleLogout,
|
|
10394
11063
|
handleNewPayment,
|
|
10395
11064
|
onDismiss,
|
|
10396
|
-
dispatch
|
|
11065
|
+
dispatch,
|
|
11066
|
+
authExecutor
|
|
10397
11067
|
]);
|
|
10398
11068
|
return /* @__PURE__ */ jsx(
|
|
10399
11069
|
StepRenderer,
|
|
@@ -10442,13 +11112,16 @@ function BlinkPaymentInner({
|
|
|
10442
11112
|
guestSettingSender: guestTransfer.settingSender,
|
|
10443
11113
|
guestPendingEntry: guestTransfer.pendingGuestEntry,
|
|
10444
11114
|
guestQuoteFee: guestTransfer.guestFee?.quote ?? null,
|
|
10445
|
-
guestQuoteLoading: guestTransfer.guestQuoteLoading
|
|
11115
|
+
guestQuoteLoading: guestTransfer.guestQuoteLoading,
|
|
11116
|
+
depositQuoteId: depositFee.quoteId,
|
|
11117
|
+
depositQuoteFee: depositFee.quoteFee,
|
|
11118
|
+
depositQuoteLoading: depositFee.quoteLoading
|
|
10446
11119
|
},
|
|
10447
11120
|
handlers
|
|
10448
11121
|
}
|
|
10449
11122
|
);
|
|
10450
11123
|
}
|
|
10451
11124
|
|
|
10452
|
-
export { AdvancedSourceScreen, BLINK_LOGO, BLINK_MASCOT, BlinkLoadingScreen, BlinkPayment, BlinkProvider, ConfirmSignScreen, DepositScreen, FlowPhaseProvider, GuestPreauthLinkingScreen, GuestPreauthSetupCompleteScreen, GuestTokenPickerScreen, IconCircle, InfoBanner, LoginScreen, OpenWalletScreen, OtpVerifyScreen, OutlineButton, PasskeyIframeBlockedError, PasskeyScreen, PoweredByFooter, PrimaryButton, ScreenHeader, ScreenLayout, SelectSourceScreen, SettingsMenu, SetupScreen, SetupStatusScreen, Spinner, StepList, SuccessScreen, TokenPickerScreen, TransferStatusScreen, VerifyPasskeyScreen, WalletPickerScreen, api_exports as blinkApi, buildPasskeyPopupOptions, createPasskeyCredential, createPasskeyViaPopup, darkTheme, deviceHasPasskey, findDevicePasskey, findDevicePasskeyViaPopup, getTheme, guestEntryMatchingRecommended, lightTheme, mapGuestPickerEntries, resolvePasskeyRpId, screenForPhase, useAuthorizationExecutor, useBlinkConfig, useBlinkDepositAmount, useTransferPolling, useTransferSigning };
|
|
11125
|
+
export { AdvancedSourceScreen, AuthorizationSessionCancelledError, BLINK_LOGO, BLINK_MASCOT, BlinkLoadingScreen, BlinkPayment, BlinkProvider, ConfirmSignScreen, DepositScreen, FlowPhaseProvider, GuestPreauthLinkingScreen, GuestPreauthSetupCompleteScreen, GuestTokenPickerScreen, IconCircle, InfoBanner, LoginScreen, OpenWalletScreen, OtpVerifyScreen, OutlineButton, PasskeyIframeBlockedError, PasskeyScreen, PoweredByFooter, PrimaryButton, ScreenHeader, ScreenLayout, SelectSourceScreen, SettingsMenu, SetupScreen, SetupStatusScreen, Spinner, StepList, SuccessScreen, TokenPickerScreen, TransferStatusScreen, VerifyPasskeyScreen, WalletPickerScreen, api_exports as blinkApi, buildPasskeyPopupOptions, createPasskeyCredential, createPasskeyViaPopup, darkTheme, deviceHasPasskey, findDevicePasskey, findDevicePasskeyViaPopup, getTheme, guestEntryMatchingRecommended, isAuthorizationSessionCancelled, isUserDismissedAuthorizationError, lightTheme, mapGuestPickerEntries, resolvePasskeyRpId, screenForPhase, useAuthorizationExecutor, useBlinkConfig, useBlinkDepositAmount, useTransferPolling, useTransferSigning };
|
|
10453
11126
|
//# sourceMappingURL=index.js.map
|
|
10454
11127
|
//# sourceMappingURL=index.js.map
|