@swype-org/react-sdk 0.1.301 → 0.1.333
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 +1193 -432
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -11
- package/dist/index.d.ts +69 -11
- package/dist/index.js +1192 -434
- 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;
|
|
@@ -1789,11 +1948,12 @@ function resolvePhase(state) {
|
|
|
1789
1948
|
const isFundingSourceSubflow = !state.loginRequested && (currentPhase.step === "token-picker" || currentPhase.step === "one-tap-setup" || currentPhase.step === "select-source" || currentPhase.step === "confirm-sign" || currentPhase.step === "guest-token-picker" && guestTokenPickerEligible);
|
|
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
|
-
const shouldPromptPasskeyVerification = missingActivePasskeyCredential && state.knownCredentialIds.length > 0
|
|
1951
|
+
const shouldPromptPasskeyVerification = missingActivePasskeyCredential && state.knownCredentialIds.length > 0;
|
|
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() {
|
|
@@ -3519,16 +3757,33 @@ function PasskeyScreen({
|
|
|
3519
3757
|
creating,
|
|
3520
3758
|
error,
|
|
3521
3759
|
popupFallback = false,
|
|
3522
|
-
onCreatePasskeyViaPopup
|
|
3760
|
+
onCreatePasskeyViaPopup,
|
|
3761
|
+
onCreateNewPasskey,
|
|
3762
|
+
onCreateNewPasskeyViaPopup,
|
|
3763
|
+
createNewPopupFallback,
|
|
3764
|
+
creatingNewPasskey
|
|
3523
3765
|
}) {
|
|
3524
3766
|
const { tokens } = useBlinkConfig();
|
|
3525
3767
|
const handleCreate = popupFallback && onCreatePasskeyViaPopup ? onCreatePasskeyViaPopup : onCreatePasskey;
|
|
3526
3768
|
const buttonLabel = popupFallback ? "Open Passkey Window" : "Verify Passkey";
|
|
3769
|
+
const showCreateNewLink = onCreateNewPasskey != null;
|
|
3770
|
+
const usePopupForNew = createNewPopupFallback ?? popupFallback;
|
|
3771
|
+
const handleCreateNew = usePopupForNew && onCreateNewPasskeyViaPopup ? onCreateNewPasskeyViaPopup : onCreateNewPasskey;
|
|
3527
3772
|
return /* @__PURE__ */ jsxs(
|
|
3528
3773
|
ScreenLayout,
|
|
3529
3774
|
{
|
|
3530
3775
|
footer: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3531
|
-
/* @__PURE__ */ jsx(PrimaryButton, { onClick: handleCreate, disabled: creating, loading: creating, children: buttonLabel }),
|
|
3776
|
+
/* @__PURE__ */ jsx(PrimaryButton, { onClick: handleCreate, disabled: creating || creatingNewPasskey, loading: creating, children: buttonLabel }),
|
|
3777
|
+
showCreateNewLink && /* @__PURE__ */ jsx(
|
|
3778
|
+
"button",
|
|
3779
|
+
{
|
|
3780
|
+
type: "button",
|
|
3781
|
+
onClick: handleCreateNew,
|
|
3782
|
+
disabled: creatingNewPasskey || creating,
|
|
3783
|
+
style: createNewLinkStyle(tokens.textMuted),
|
|
3784
|
+
children: creatingNewPasskey ? "Creating passkey\u2026" : "Create a new passkey for this device"
|
|
3785
|
+
}
|
|
3786
|
+
),
|
|
3532
3787
|
/* @__PURE__ */ jsx(PoweredByFooter, {})
|
|
3533
3788
|
] }),
|
|
3534
3789
|
children: [
|
|
@@ -3563,6 +3818,17 @@ var subtitleStyle3 = (color) => ({
|
|
|
3563
3818
|
margin: "0 0 20px",
|
|
3564
3819
|
lineHeight: 1.5
|
|
3565
3820
|
});
|
|
3821
|
+
var createNewLinkStyle = (color) => ({
|
|
3822
|
+
background: "none",
|
|
3823
|
+
border: "none",
|
|
3824
|
+
color,
|
|
3825
|
+
fontSize: "0.85rem",
|
|
3826
|
+
cursor: "pointer",
|
|
3827
|
+
padding: "8px 16px",
|
|
3828
|
+
textDecoration: "underline",
|
|
3829
|
+
fontFamily: "inherit",
|
|
3830
|
+
width: "100%"
|
|
3831
|
+
});
|
|
3566
3832
|
var errorBannerStyle2 = (tokens) => ({
|
|
3567
3833
|
background: tokens.errorBg,
|
|
3568
3834
|
border: `1px solid ${tokens.error}66`,
|
|
@@ -4078,6 +4344,22 @@ var loginButtonStyle = (accentColor) => ({
|
|
|
4078
4344
|
fontFamily: "inherit",
|
|
4079
4345
|
textDecoration: "underline"
|
|
4080
4346
|
});
|
|
4347
|
+
|
|
4348
|
+
// src/setupScreenSelection.ts
|
|
4349
|
+
function matchesSetupTokenSelection(opt, selectedTokenSymbol, selectedChainName, allOptions) {
|
|
4350
|
+
if (!selectedTokenSymbol || opt.symbol !== selectedTokenSymbol) {
|
|
4351
|
+
return false;
|
|
4352
|
+
}
|
|
4353
|
+
const chain = selectedChainName?.trim();
|
|
4354
|
+
if (chain) {
|
|
4355
|
+
return opt.chainName === chain;
|
|
4356
|
+
}
|
|
4357
|
+
const sameSymbol = allOptions.filter((o) => o.symbol === selectedTokenSymbol);
|
|
4358
|
+
if (sameSymbol.length === 1) {
|
|
4359
|
+
return opt.chainName === sameSymbol[0].chainName;
|
|
4360
|
+
}
|
|
4361
|
+
return false;
|
|
4362
|
+
}
|
|
4081
4363
|
var DEFAULT_MAX = 1e7;
|
|
4082
4364
|
var ABSOLUTE_MIN = 0.01;
|
|
4083
4365
|
var PRESETS = [100, 250, 1e3];
|
|
@@ -4093,13 +4375,16 @@ function SetupScreen({
|
|
|
4093
4375
|
loading,
|
|
4094
4376
|
error,
|
|
4095
4377
|
selectedTokenSymbol,
|
|
4378
|
+
selectedChainName,
|
|
4096
4379
|
tokenOptions,
|
|
4097
4380
|
onSelectToken
|
|
4098
4381
|
}) {
|
|
4099
4382
|
const { tokens } = useBlinkConfig();
|
|
4100
4383
|
const effectiveMax = DEFAULT_MAX;
|
|
4101
4384
|
const effectiveMin = Math.min(ABSOLUTE_MIN, effectiveMax);
|
|
4102
|
-
const
|
|
4385
|
+
const autoLimit = Math.min(Math.max(availableBalance, 0), effectiveMax);
|
|
4386
|
+
const [userChosenLimit, setUserChosenLimit] = useState(null);
|
|
4387
|
+
const limit = userChosenLimit ?? autoLimit;
|
|
4103
4388
|
const [activePreset, setActivePreset] = useState(null);
|
|
4104
4389
|
const [showAdvanced, setShowAdvanced] = useState(false);
|
|
4105
4390
|
const [editing, setEditing] = useState(false);
|
|
@@ -4138,20 +4423,22 @@ function SetupScreen({
|
|
|
4138
4423
|
const commitEdit = useCallback(() => {
|
|
4139
4424
|
const parsed = parseFloat(inputValue);
|
|
4140
4425
|
if (!isNaN(parsed)) {
|
|
4141
|
-
|
|
4426
|
+
setUserChosenLimit(
|
|
4427
|
+
Math.min(effectiveMax, Math.max(effectiveMin, Math.round(parsed * 100) / 100))
|
|
4428
|
+
);
|
|
4142
4429
|
}
|
|
4143
4430
|
setActivePreset(null);
|
|
4144
4431
|
setEditing(false);
|
|
4145
4432
|
}, [inputValue, effectiveMax, effectiveMin]);
|
|
4146
4433
|
const selectPreset = (value) => {
|
|
4147
|
-
|
|
4434
|
+
setUserChosenLimit(Math.min(value, effectiveMax));
|
|
4148
4435
|
setActivePreset(value);
|
|
4149
4436
|
};
|
|
4150
4437
|
const selectMax = () => {
|
|
4151
|
-
|
|
4438
|
+
setUserChosenLimit(autoLimit);
|
|
4152
4439
|
setActivePreset("max");
|
|
4153
4440
|
};
|
|
4154
|
-
const
|
|
4441
|
+
const options = tokenOptions ?? [];
|
|
4155
4442
|
return /* @__PURE__ */ jsxs(
|
|
4156
4443
|
ScreenLayout,
|
|
4157
4444
|
{
|
|
@@ -4184,12 +4471,7 @@ function SetupScreen({
|
|
|
4184
4471
|
children: [
|
|
4185
4472
|
/* @__PURE__ */ jsx("span", { style: tokenRowLabelStyle(tokens.text), children: "Token for one tap" }),
|
|
4186
4473
|
/* @__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: [
|
|
4474
|
+
/* @__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
4475
|
/* @__PURE__ */ jsx("circle", { cx: "18", cy: "18", r: "18", fill: "#2DB84B" }),
|
|
4194
4476
|
/* @__PURE__ */ jsx("text", { x: "18", y: "23", textAnchor: "middle", fontSize: "18", fill: "#fff", fontWeight: "700", children: "$" })
|
|
4195
4477
|
] }) }),
|
|
@@ -4201,14 +4483,21 @@ function SetupScreen({
|
|
|
4201
4483
|
tokenDropdownOpen && tokenOptions && tokenOptions.length > 0 && /* @__PURE__ */ jsxs("div", { style: dropdownOuterStyle(tokens), children: [
|
|
4202
4484
|
/* @__PURE__ */ jsx("div", { style: dropdownLabelStyle(tokens.textMuted), children: "Choose token" }),
|
|
4203
4485
|
/* @__PURE__ */ jsx("div", { style: dropdownInnerStyle(tokens), children: tokenOptions.map((opt, index) => {
|
|
4204
|
-
const selected =
|
|
4486
|
+
const selected = matchesSetupTokenSelection(
|
|
4487
|
+
opt,
|
|
4488
|
+
selectedTokenSymbol,
|
|
4489
|
+
selectedChainName,
|
|
4490
|
+
options
|
|
4491
|
+
);
|
|
4205
4492
|
const isLast = index === tokenOptions.length - 1;
|
|
4493
|
+
const authorized = !opt.status || opt.status === "AUTHORIZED";
|
|
4206
4494
|
return /* @__PURE__ */ jsxs(
|
|
4207
4495
|
"button",
|
|
4208
4496
|
{
|
|
4209
4497
|
type: "button",
|
|
4210
4498
|
onClick: () => handlePickToken(opt),
|
|
4211
4499
|
style: dropdownRowStyle(tokens, selected, isLast),
|
|
4500
|
+
"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
4501
|
children: [
|
|
4213
4502
|
/* @__PURE__ */ jsxs("div", { style: dropdownRowLeftStyle, children: [
|
|
4214
4503
|
/* @__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 +4507,12 @@ function SetupScreen({
|
|
|
4218
4507
|
/* @__PURE__ */ jsx("span", { style: dropdownTokenDotStyle(tokens.textMuted), children: "\xB7" }),
|
|
4219
4508
|
/* @__PURE__ */ jsx("span", { style: dropdownTokenChainStyle(tokens.textMuted), children: opt.chainName })
|
|
4220
4509
|
] }),
|
|
4221
|
-
|
|
4222
|
-
"
|
|
4223
|
-
|
|
4510
|
+
/* @__PURE__ */ jsxs("div", { style: dropdownTokenBalanceRowStyle, children: [
|
|
4511
|
+
opt.balance != null && /* @__PURE__ */ jsxs("span", { style: dropdownTokenBalanceStyle(tokens.textMuted), children: [
|
|
4512
|
+
"$",
|
|
4513
|
+
opt.balance.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
|
4514
|
+
] }),
|
|
4515
|
+
!authorized && /* @__PURE__ */ jsx("span", { style: dropdownNotAuthorizedStyle(tokens.textMuted), children: "Not authorized" })
|
|
4224
4516
|
] })
|
|
4225
4517
|
] })
|
|
4226
4518
|
] }),
|
|
@@ -4340,11 +4632,6 @@ var tokenRowRightStyle = {
|
|
|
4340
4632
|
gap: 6,
|
|
4341
4633
|
flexShrink: 0
|
|
4342
4634
|
};
|
|
4343
|
-
var tokenRowSymbolStyle = (color) => ({
|
|
4344
|
-
fontSize: "0.84rem",
|
|
4345
|
-
fontWeight: 500,
|
|
4346
|
-
color
|
|
4347
|
-
});
|
|
4348
4635
|
var advancedToggleStyle = (accentColor) => ({
|
|
4349
4636
|
display: "block",
|
|
4350
4637
|
margin: "4px auto 24px",
|
|
@@ -4492,10 +4779,20 @@ var dropdownTokenChainStyle = (color) => ({
|
|
|
4492
4779
|
fontWeight: 400,
|
|
4493
4780
|
color
|
|
4494
4781
|
});
|
|
4782
|
+
var dropdownTokenBalanceRowStyle = {
|
|
4783
|
+
display: "flex",
|
|
4784
|
+
alignItems: "center",
|
|
4785
|
+
gap: 8
|
|
4786
|
+
};
|
|
4495
4787
|
var dropdownTokenBalanceStyle = (color) => ({
|
|
4496
4788
|
fontSize: "0.78rem",
|
|
4497
4789
|
color
|
|
4498
4790
|
});
|
|
4791
|
+
var dropdownNotAuthorizedStyle = (color) => ({
|
|
4792
|
+
fontSize: "0.7rem",
|
|
4793
|
+
fontWeight: 500,
|
|
4794
|
+
color
|
|
4795
|
+
});
|
|
4499
4796
|
var dropdownRadioEmptyStyle = (borderColor) => ({
|
|
4500
4797
|
width: 22,
|
|
4501
4798
|
height: 22,
|
|
@@ -4610,6 +4907,38 @@ var waitHintStyle = (color) => ({
|
|
|
4610
4907
|
color,
|
|
4611
4908
|
margin: 0
|
|
4612
4909
|
});
|
|
4910
|
+
|
|
4911
|
+
// src/feeFormat.ts
|
|
4912
|
+
function isPreciseMoneyNonPositive(fee) {
|
|
4913
|
+
const raw = fee.value.trim();
|
|
4914
|
+
if (!/^-?\d+(\.\d*)?$/.test(raw)) return false;
|
|
4915
|
+
const n = Number(raw);
|
|
4916
|
+
return Number.isFinite(n) && n <= 0;
|
|
4917
|
+
}
|
|
4918
|
+
function formatNonPositiveFeeDisplay(fee) {
|
|
4919
|
+
if (fee.currency === "USD") return "Under $0.01";
|
|
4920
|
+
return `Less than 0.01 ${fee.currency}`;
|
|
4921
|
+
}
|
|
4922
|
+
function formatPreciseMoneyForDisplay(fee) {
|
|
4923
|
+
const raw = fee.value.trim();
|
|
4924
|
+
if (fee.currency === "USD") {
|
|
4925
|
+
if (!/^\d+(\.\d*)?$/.test(raw)) {
|
|
4926
|
+
return `$${raw}`;
|
|
4927
|
+
}
|
|
4928
|
+
const [whole, frac = ""] = raw.split(".");
|
|
4929
|
+
const dec = `${frac}00`.slice(0, 2);
|
|
4930
|
+
const intFmt = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
4931
|
+
return `$${intFmt}.${dec}`;
|
|
4932
|
+
}
|
|
4933
|
+
return `${raw} ${fee.currency}`;
|
|
4934
|
+
}
|
|
4935
|
+
function formatUsdTwoDecimals(value) {
|
|
4936
|
+
const n = Number(value);
|
|
4937
|
+
return (Number.isFinite(n) ? n : 0).toLocaleString("en-US", {
|
|
4938
|
+
minimumFractionDigits: 2,
|
|
4939
|
+
maximumFractionDigits: 2
|
|
4940
|
+
});
|
|
4941
|
+
}
|
|
4613
4942
|
function DepositScreen({
|
|
4614
4943
|
merchantName,
|
|
4615
4944
|
availableBalance,
|
|
@@ -4617,6 +4946,8 @@ function DepositScreen({
|
|
|
4617
4946
|
tokenCount,
|
|
4618
4947
|
initialAmount,
|
|
4619
4948
|
minDepositFloor,
|
|
4949
|
+
quoteFee,
|
|
4950
|
+
quoteLoading,
|
|
4620
4951
|
processing,
|
|
4621
4952
|
error,
|
|
4622
4953
|
onDeposit,
|
|
@@ -4631,13 +4962,19 @@ function DepositScreen({
|
|
|
4631
4962
|
onAuthorizeAccount,
|
|
4632
4963
|
onAddProvider,
|
|
4633
4964
|
onSelectToken,
|
|
4965
|
+
tokenOptions,
|
|
4966
|
+
onPickToken,
|
|
4634
4967
|
selectedSourceLabel,
|
|
4635
|
-
selectedTokenSymbol
|
|
4968
|
+
selectedTokenSymbol,
|
|
4969
|
+
selectedChainName
|
|
4636
4970
|
}) {
|
|
4637
4971
|
const { tokens } = useBlinkConfig();
|
|
4638
4972
|
const amount = initialAmount;
|
|
4639
4973
|
const [accountPickerOpen, setAccountPickerOpen] = useState(false);
|
|
4974
|
+
const [tokenPickerOpen, setTokenPickerOpen] = useState(false);
|
|
4640
4975
|
const pickerRef = useRef(null);
|
|
4976
|
+
const tokenPickerRef = useRef(null);
|
|
4977
|
+
const hasTokenDropdown = tokenOptions != null && tokenOptions.length > 0 && onPickToken != null;
|
|
4641
4978
|
useEffect(() => {
|
|
4642
4979
|
if (!accountPickerOpen) return;
|
|
4643
4980
|
const handleClick = (e) => {
|
|
@@ -4648,47 +4985,129 @@ function DepositScreen({
|
|
|
4648
4985
|
document.addEventListener("mousedown", handleClick);
|
|
4649
4986
|
return () => document.removeEventListener("mousedown", handleClick);
|
|
4650
4987
|
}, [accountPickerOpen]);
|
|
4988
|
+
useEffect(() => {
|
|
4989
|
+
if (!tokenPickerOpen) return;
|
|
4990
|
+
const handleMouseDown = (e) => {
|
|
4991
|
+
if (tokenPickerRef.current && !tokenPickerRef.current.contains(e.target)) {
|
|
4992
|
+
setTokenPickerOpen(false);
|
|
4993
|
+
}
|
|
4994
|
+
};
|
|
4995
|
+
document.addEventListener("mousedown", handleMouseDown);
|
|
4996
|
+
return () => document.removeEventListener("mousedown", handleMouseDown);
|
|
4997
|
+
}, [tokenPickerOpen]);
|
|
4998
|
+
const handleTokenBadgeClick = useCallback(() => {
|
|
4999
|
+
if (hasTokenDropdown) {
|
|
5000
|
+
setTokenPickerOpen((v) => !v);
|
|
5001
|
+
setAccountPickerOpen(false);
|
|
5002
|
+
} else {
|
|
5003
|
+
onSelectToken?.();
|
|
5004
|
+
}
|
|
5005
|
+
}, [hasTokenDropdown, onSelectToken]);
|
|
5006
|
+
const handlePickToken = useCallback((opt) => {
|
|
5007
|
+
onPickToken?.(opt.symbol, opt.chainName, opt.walletId);
|
|
5008
|
+
setTokenPickerOpen(false);
|
|
5009
|
+
}, [onPickToken]);
|
|
4651
5010
|
const selectedAccount = accounts?.find((a) => a.id === selectedAccountId);
|
|
4652
5011
|
const selectedProviderName = selectedAccount?.name ?? "Wallet";
|
|
4653
5012
|
const selectedProviderLogo = KNOWN_LOGOS[selectedProviderName.toLowerCase()];
|
|
4654
5013
|
const totalAccountBalance = selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : availableBalance;
|
|
4655
5014
|
const isLowBalance = availableBalance < minDepositFloor;
|
|
5015
|
+
const insufficientFunds = availableBalance < amount;
|
|
4656
5016
|
const exceedsLimit = remainingLimit != null && amount > remainingLimit && !isLowBalance;
|
|
4657
|
-
const canDeposit = amount >= minDepositFloor && !exceedsLimit && !isLowBalance && !processing;
|
|
5017
|
+
const canDeposit = amount >= minDepositFloor && !exceedsLimit && !isLowBalance && !insufficientFunds && !processing;
|
|
4658
5018
|
return /* @__PURE__ */ jsxs(
|
|
4659
5019
|
ScreenLayout,
|
|
4660
5020
|
{
|
|
4661
5021
|
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" })),
|
|
5022
|
+
!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: insufficientFunds ? "Insufficient Funds" : "Confirm" })),
|
|
4663
5023
|
/* @__PURE__ */ jsx(PoweredByFooter, {})
|
|
4664
5024
|
] }),
|
|
4665
5025
|
children: [
|
|
4666
5026
|
/* @__PURE__ */ jsx(ScreenHeader, { onBack, onLogout }),
|
|
4667
5027
|
/* @__PURE__ */ jsxs("div", { ref: pickerRef, style: depositCardWrapStyle, children: [
|
|
4668
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
5028
|
+
/* @__PURE__ */ jsxs("div", { style: depositCardStyle(tokens), children: [
|
|
4669
5029
|
/* @__PURE__ */ jsx("div", { style: depositLabelStyle(tokens.textMuted), children: "Depositing" }),
|
|
4670
|
-
/* @__PURE__ */ jsxs("div", {
|
|
4671
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
4672
|
-
"
|
|
4673
|
-
|
|
5030
|
+
/* @__PURE__ */ jsxs("div", { ref: tokenPickerRef, children: [
|
|
5031
|
+
/* @__PURE__ */ jsxs("div", { style: amountRowStyle, children: [
|
|
5032
|
+
/* @__PURE__ */ jsxs("div", { style: amountValueStyle(tokens.text), children: [
|
|
5033
|
+
"$",
|
|
5034
|
+
formatUsdTwoDecimals(amount)
|
|
5035
|
+
] }),
|
|
5036
|
+
/* @__PURE__ */ jsxs(
|
|
5037
|
+
"button",
|
|
5038
|
+
{
|
|
5039
|
+
type: "button",
|
|
5040
|
+
"data-testid": "deposit-token-badge",
|
|
5041
|
+
onClick: handleTokenBadgeClick,
|
|
5042
|
+
style: tokenIconButtonStyle(hasTokenDropdown || !!onSelectToken),
|
|
5043
|
+
"aria-expanded": hasTokenDropdown ? tokenPickerOpen : void 0,
|
|
5044
|
+
"aria-haspopup": hasTokenDropdown ? "listbox" : void 0,
|
|
5045
|
+
children: [
|
|
5046
|
+
/* @__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: [
|
|
5047
|
+
/* @__PURE__ */ jsx("circle", { cx: "18", cy: "18", r: "18", fill: "#2DB84B" }),
|
|
5048
|
+
/* @__PURE__ */ jsx("text", { x: "18", y: "23", textAnchor: "middle", fontSize: "18", fill: "#fff", fontWeight: "700", children: "$" })
|
|
5049
|
+
] }) }),
|
|
5050
|
+
/* @__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" }) })
|
|
5051
|
+
]
|
|
5052
|
+
}
|
|
5053
|
+
)
|
|
4674
5054
|
] }),
|
|
4675
|
-
/* @__PURE__ */ jsxs(
|
|
4676
|
-
"
|
|
4677
|
-
{
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
5055
|
+
tokenPickerOpen && tokenOptions && tokenOptions.length > 0 && /* @__PURE__ */ jsxs("div", { style: tokenDropdownStyle(tokens), children: [
|
|
5056
|
+
/* @__PURE__ */ jsx("div", { style: tokenDropdownLabelStyle(tokens.textMuted), children: "Choose token" }),
|
|
5057
|
+
/* @__PURE__ */ jsx("div", { style: tokenDropdownInnerStyle(tokens), children: tokenOptions.map((opt, index) => {
|
|
5058
|
+
const selected = opt.symbol === selectedTokenSymbol && (!selectedChainName || opt.chainName === selectedChainName);
|
|
5059
|
+
const isLast = index === tokenOptions.length - 1;
|
|
5060
|
+
const authorized = !opt.status || opt.status === "AUTHORIZED";
|
|
5061
|
+
return /* @__PURE__ */ jsxs(
|
|
5062
|
+
"button",
|
|
5063
|
+
{
|
|
5064
|
+
type: "button",
|
|
5065
|
+
onClick: () => handlePickToken(opt),
|
|
5066
|
+
style: tokenDropdownRowStyle(tokens, selected, isLast),
|
|
5067
|
+
"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" : ""}`,
|
|
5068
|
+
children: [
|
|
5069
|
+
/* @__PURE__ */ jsxs("div", { style: tokenDropdownRowLeftStyle, children: [
|
|
5070
|
+
/* @__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: "$" }) }),
|
|
5071
|
+
/* @__PURE__ */ jsxs("div", { style: tokenDropdownInfoStyle, children: [
|
|
5072
|
+
/* @__PURE__ */ jsxs("div", { style: tokenDropdownNameRowStyle, children: [
|
|
5073
|
+
/* @__PURE__ */ jsx("span", { style: tokenDropdownSymbolStyle(tokens.text), children: opt.symbol }),
|
|
5074
|
+
/* @__PURE__ */ jsx("span", { style: tokenDropdownDotStyle(tokens.textMuted), children: "\xB7" }),
|
|
5075
|
+
/* @__PURE__ */ jsx("span", { style: tokenDropdownChainStyle(tokens.textMuted), children: opt.chainName })
|
|
5076
|
+
] }),
|
|
5077
|
+
/* @__PURE__ */ jsxs("div", { style: tokenDropdownBalanceRowStyle, children: [
|
|
5078
|
+
opt.balance != null && /* @__PURE__ */ jsxs("span", { style: tokenDropdownBalanceStyle(tokens.textMuted), children: [
|
|
5079
|
+
"$",
|
|
5080
|
+
formatUsdTwoDecimals(opt.balance)
|
|
5081
|
+
] }),
|
|
5082
|
+
!authorized && /* @__PURE__ */ jsx("span", { style: tokenDropdownNotAuthStyle(tokens.textMuted), children: "Not authorized" })
|
|
5083
|
+
] })
|
|
5084
|
+
] })
|
|
5085
|
+
] }),
|
|
5086
|
+
selected ? /* @__PURE__ */ jsxs("svg", { width: "22", height: "22", viewBox: "0 0 22 22", fill: "none", children: [
|
|
5087
|
+
/* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "11", fill: tokens.success }),
|
|
5088
|
+
/* @__PURE__ */ jsx("path", { d: "M7 11l3 3 5-5", stroke: "#fff", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
5089
|
+
] }) : /* @__PURE__ */ jsx("div", { style: tokenDropdownRadioStyle(tokens.border) })
|
|
5090
|
+
]
|
|
5091
|
+
},
|
|
5092
|
+
`${opt.chainName}-${opt.symbol}`
|
|
5093
|
+
);
|
|
5094
|
+
}) })
|
|
5095
|
+
] })
|
|
4690
5096
|
] }),
|
|
4691
|
-
!accountPickerOpen &&
|
|
5097
|
+
!accountPickerOpen && !tokenPickerOpen && (() => {
|
|
5098
|
+
if (quoteLoading) {
|
|
5099
|
+
return /* @__PURE__ */ jsx("div", { style: feeRowContainerStyle, "aria-live": "polite", children: /* @__PURE__ */ jsx("span", { style: feeRowLabelStyle(tokens.textMuted), children: "Getting fee estimate\u2026" }) });
|
|
5100
|
+
}
|
|
5101
|
+
if (quoteFee) {
|
|
5102
|
+
const feeText = isPreciseMoneyNonPositive(quoteFee) ? formatNonPositiveFeeDisplay(quoteFee) : formatPreciseMoneyForDisplay(quoteFee);
|
|
5103
|
+
return /* @__PURE__ */ jsxs("div", { style: feeRowContainerStyle, "aria-live": "polite", children: [
|
|
5104
|
+
/* @__PURE__ */ jsx("span", { style: feeRowLabelStyle(tokens.textMuted), children: "Fee estimate: " }),
|
|
5105
|
+
/* @__PURE__ */ jsx("span", { style: feeRowAmountStyle(tokens.textSecondary), children: feeText })
|
|
5106
|
+
] });
|
|
5107
|
+
}
|
|
5108
|
+
return null;
|
|
5109
|
+
})(),
|
|
5110
|
+
!accountPickerOpen && !tokenPickerOpen && /* @__PURE__ */ jsxs(
|
|
4692
5111
|
"button",
|
|
4693
5112
|
{
|
|
4694
5113
|
type: "button",
|
|
@@ -4698,7 +5117,7 @@ function DepositScreen({
|
|
|
4698
5117
|
selectedProviderLogo ? /* @__PURE__ */ jsx("img", { src: selectedProviderLogo, alt: selectedProviderName, style: providerLogoStyle }) : /* @__PURE__ */ jsx("div", { style: providerFallbackStyle(tokens.textMuted), children: selectedProviderName.charAt(0) }),
|
|
4699
5118
|
/* @__PURE__ */ jsxs("span", { style: walletBalanceStyle(tokens.text), children: [
|
|
4700
5119
|
"$",
|
|
4701
|
-
totalAccountBalance
|
|
5120
|
+
formatUsdTwoDecimals(totalAccountBalance)
|
|
4702
5121
|
] }),
|
|
4703
5122
|
/* @__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
5123
|
]
|
|
@@ -4739,7 +5158,7 @@ function DepositScreen({
|
|
|
4739
5158
|
/* @__PURE__ */ jsx("span", { style: accountAddressStyle(tokens.text), children: truncatedAddress ?? account.nickname ?? account.name }),
|
|
4740
5159
|
/* @__PURE__ */ jsxs("span", { style: accountBalanceTextStyle(tokens.textMuted), children: [
|
|
4741
5160
|
"$",
|
|
4742
|
-
accountBalance
|
|
5161
|
+
formatUsdTwoDecimals(accountBalance)
|
|
4743
5162
|
] })
|
|
4744
5163
|
] })
|
|
4745
5164
|
] }),
|
|
@@ -4775,21 +5194,21 @@ function DepositScreen({
|
|
|
4775
5194
|
" ",
|
|
4776
5195
|
/* @__PURE__ */ jsxs("strong", { style: { color: tokens.text }, children: [
|
|
4777
5196
|
"$",
|
|
4778
|
-
remainingLimit
|
|
5197
|
+
formatUsdTwoDecimals(remainingLimit)
|
|
4779
5198
|
] }),
|
|
4780
5199
|
exceedsLimit && /* @__PURE__ */ jsxs("p", { style: limitExceededHintStyle(tokens.warning), children: [
|
|
4781
5200
|
"Your deposit of $",
|
|
4782
|
-
amount
|
|
5201
|
+
formatUsdTwoDecimals(amount),
|
|
4783
5202
|
" exceeds your One-Tap limit of $",
|
|
4784
|
-
remainingLimit
|
|
5203
|
+
remainingLimit != null ? formatUsdTwoDecimals(remainingLimit) : "0.00",
|
|
4785
5204
|
". Increase your limit to continue."
|
|
4786
5205
|
] })
|
|
4787
5206
|
] }),
|
|
4788
5207
|
!accountPickerOpen && isLowBalance && /* @__PURE__ */ jsxs(WarningBanner, { title: "Not enough funds", children: [
|
|
4789
5208
|
"Your wallet balance is $",
|
|
4790
|
-
availableBalance
|
|
5209
|
+
formatUsdTwoDecimals(availableBalance),
|
|
4791
5210
|
" \u2014 you need at least $",
|
|
4792
|
-
minDepositFloor
|
|
5211
|
+
formatUsdTwoDecimals(minDepositFloor),
|
|
4793
5212
|
" to deposit via One-Tap."
|
|
4794
5213
|
] }),
|
|
4795
5214
|
error && /* @__PURE__ */ jsx("div", { style: errorBannerStyle6(tokens), children: error })
|
|
@@ -4801,6 +5220,11 @@ var depositCardWrapStyle = {
|
|
|
4801
5220
|
position: "relative",
|
|
4802
5221
|
marginBottom: 20
|
|
4803
5222
|
};
|
|
5223
|
+
var depositCardStyle = (tokens) => ({
|
|
5224
|
+
border: `1px solid ${tokens.border}`,
|
|
5225
|
+
borderRadius: tokens.radiusLg,
|
|
5226
|
+
padding: "16px 20px"
|
|
5227
|
+
});
|
|
4804
5228
|
var depositLabelStyle = (color) => ({
|
|
4805
5229
|
fontSize: "0.75rem",
|
|
4806
5230
|
fontWeight: 500,
|
|
@@ -4834,104 +5258,214 @@ var tokenIconWrapStyle2 = {
|
|
|
4834
5258
|
width: 36,
|
|
4835
5259
|
height: 36
|
|
4836
5260
|
};
|
|
4837
|
-
var
|
|
4838
|
-
display: "flex",
|
|
4839
|
-
alignItems: "center",
|
|
4840
|
-
justifyContent: "center",
|
|
4841
|
-
gap: 8,
|
|
4842
|
-
background: "transparent",
|
|
4843
|
-
border: "none",
|
|
4844
|
-
padding: 0,
|
|
4845
|
-
width: "100%",
|
|
4846
|
-
cursor: "pointer",
|
|
4847
|
-
fontFamily: "inherit",
|
|
4848
|
-
outline: "none"
|
|
4849
|
-
};
|
|
4850
|
-
var providerLogoStyle = {
|
|
4851
|
-
width: 18,
|
|
4852
|
-
height: 18,
|
|
4853
|
-
borderRadius: "50%",
|
|
4854
|
-
objectFit: "contain"
|
|
4855
|
-
};
|
|
4856
|
-
var providerFallbackStyle = (color) => ({
|
|
4857
|
-
width: 18,
|
|
4858
|
-
height: 18,
|
|
4859
|
-
borderRadius: "50%",
|
|
4860
|
-
display: "flex",
|
|
4861
|
-
alignItems: "center",
|
|
4862
|
-
justifyContent: "center",
|
|
4863
|
-
fontSize: "0.65rem",
|
|
4864
|
-
fontWeight: 700,
|
|
4865
|
-
color,
|
|
4866
|
-
flexShrink: 0
|
|
4867
|
-
});
|
|
4868
|
-
var walletBalanceStyle = (color) => ({
|
|
4869
|
-
fontSize: "0.9rem",
|
|
4870
|
-
fontWeight: 600,
|
|
4871
|
-
color
|
|
4872
|
-
});
|
|
4873
|
-
var accountDropdownOuterStyle = (tokens) => ({
|
|
5261
|
+
var tokenDropdownStyle = (t) => ({
|
|
4874
5262
|
marginTop: 4,
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
5263
|
+
marginBottom: 12,
|
|
5264
|
+
background: t.bgCard,
|
|
5265
|
+
border: `1px solid ${t.border}`,
|
|
5266
|
+
borderRadius: t.radiusLg,
|
|
5267
|
+
boxShadow: t.shadowLg,
|
|
4879
5268
|
padding: "12px 14px 14px"
|
|
4880
5269
|
});
|
|
4881
|
-
var
|
|
5270
|
+
var tokenDropdownLabelStyle = (color) => ({
|
|
4882
5271
|
fontSize: "0.78rem",
|
|
4883
5272
|
fontWeight: 500,
|
|
4884
5273
|
color,
|
|
4885
5274
|
marginBottom: 8
|
|
4886
5275
|
});
|
|
4887
|
-
var
|
|
4888
|
-
background:
|
|
4889
|
-
border: `1px solid ${
|
|
4890
|
-
borderRadius:
|
|
5276
|
+
var tokenDropdownInnerStyle = (t) => ({
|
|
5277
|
+
background: t.bgInput,
|
|
5278
|
+
border: `1px solid ${t.border}`,
|
|
5279
|
+
borderRadius: t.radiusLg,
|
|
4891
5280
|
overflow: "hidden"
|
|
4892
5281
|
});
|
|
4893
|
-
var
|
|
5282
|
+
var tokenDropdownRowStyle = (t, isSelected, isLast) => ({
|
|
4894
5283
|
display: "flex",
|
|
4895
5284
|
alignItems: "center",
|
|
4896
5285
|
justifyContent: "space-between",
|
|
4897
5286
|
width: "100%",
|
|
4898
5287
|
padding: "14px 16px",
|
|
4899
|
-
background: isSelected ? `${
|
|
5288
|
+
background: isSelected ? `${t.accent}18` : "transparent",
|
|
4900
5289
|
border: "none",
|
|
4901
|
-
borderBottom: `1px solid ${
|
|
5290
|
+
borderBottom: isLast ? "none" : `1px solid ${t.border}`,
|
|
4902
5291
|
cursor: "pointer",
|
|
4903
5292
|
fontFamily: "inherit",
|
|
4904
5293
|
textAlign: "left",
|
|
4905
5294
|
outline: "none"
|
|
4906
5295
|
});
|
|
4907
|
-
var
|
|
5296
|
+
var tokenDropdownRowLeftStyle = {
|
|
4908
5297
|
display: "flex",
|
|
4909
5298
|
alignItems: "center",
|
|
4910
5299
|
gap: 12,
|
|
4911
5300
|
minWidth: 0,
|
|
4912
5301
|
flex: 1
|
|
4913
5302
|
};
|
|
4914
|
-
var
|
|
4915
|
-
width:
|
|
4916
|
-
height:
|
|
4917
|
-
borderRadius: "50%",
|
|
4918
|
-
objectFit: "contain",
|
|
4919
|
-
flexShrink: 0
|
|
4920
|
-
};
|
|
4921
|
-
var accountFallbackIconStyle = (color) => ({
|
|
4922
|
-
width: 28,
|
|
4923
|
-
height: 28,
|
|
5303
|
+
var tokenDropdownIconStyle = (t, hasLogo) => ({
|
|
5304
|
+
width: 36,
|
|
5305
|
+
height: 36,
|
|
4924
5306
|
borderRadius: "50%",
|
|
5307
|
+
border: hasLogo ? "none" : `1.5px solid ${t.border}`,
|
|
4925
5308
|
display: "flex",
|
|
4926
5309
|
alignItems: "center",
|
|
4927
5310
|
justifyContent: "center",
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
color,
|
|
4931
|
-
flexShrink: 0
|
|
5311
|
+
flexShrink: 0,
|
|
5312
|
+
overflow: "hidden"
|
|
4932
5313
|
});
|
|
4933
|
-
var
|
|
4934
|
-
|
|
5314
|
+
var tokenDropdownLogoStyle = {
|
|
5315
|
+
width: 36,
|
|
5316
|
+
height: 36,
|
|
5317
|
+
borderRadius: "50%",
|
|
5318
|
+
objectFit: "cover"
|
|
5319
|
+
};
|
|
5320
|
+
var tokenDropdownFallbackStyle = (color) => ({
|
|
5321
|
+
fontSize: "1rem",
|
|
5322
|
+
fontWeight: 700,
|
|
5323
|
+
color
|
|
5324
|
+
});
|
|
5325
|
+
var tokenDropdownInfoStyle = {
|
|
5326
|
+
display: "flex",
|
|
5327
|
+
flexDirection: "column",
|
|
5328
|
+
gap: 2,
|
|
5329
|
+
minWidth: 0
|
|
5330
|
+
};
|
|
5331
|
+
var tokenDropdownNameRowStyle = {
|
|
5332
|
+
display: "flex",
|
|
5333
|
+
alignItems: "center",
|
|
5334
|
+
gap: 4
|
|
5335
|
+
};
|
|
5336
|
+
var tokenDropdownSymbolStyle = (color) => ({
|
|
5337
|
+
fontSize: "0.92rem",
|
|
5338
|
+
fontWeight: 600,
|
|
5339
|
+
color
|
|
5340
|
+
});
|
|
5341
|
+
var tokenDropdownDotStyle = (color) => ({
|
|
5342
|
+
fontSize: "0.8rem",
|
|
5343
|
+
color
|
|
5344
|
+
});
|
|
5345
|
+
var tokenDropdownChainStyle = (color) => ({
|
|
5346
|
+
fontSize: "0.84rem",
|
|
5347
|
+
fontWeight: 400,
|
|
5348
|
+
color
|
|
5349
|
+
});
|
|
5350
|
+
var tokenDropdownBalanceRowStyle = {
|
|
5351
|
+
display: "flex",
|
|
5352
|
+
alignItems: "center",
|
|
5353
|
+
gap: 8
|
|
5354
|
+
};
|
|
5355
|
+
var tokenDropdownBalanceStyle = (color) => ({
|
|
5356
|
+
fontSize: "0.78rem",
|
|
5357
|
+
color
|
|
5358
|
+
});
|
|
5359
|
+
var tokenDropdownNotAuthStyle = (color) => ({
|
|
5360
|
+
fontSize: "0.7rem",
|
|
5361
|
+
fontWeight: 500,
|
|
5362
|
+
color
|
|
5363
|
+
});
|
|
5364
|
+
var tokenDropdownRadioStyle = (borderColor) => ({
|
|
5365
|
+
width: 22,
|
|
5366
|
+
height: 22,
|
|
5367
|
+
borderRadius: "50%",
|
|
5368
|
+
border: `2px solid ${borderColor}`,
|
|
5369
|
+
flexShrink: 0
|
|
5370
|
+
});
|
|
5371
|
+
var walletBalanceRowStyle = {
|
|
5372
|
+
display: "flex",
|
|
5373
|
+
alignItems: "center",
|
|
5374
|
+
justifyContent: "center",
|
|
5375
|
+
gap: 8,
|
|
5376
|
+
background: "transparent",
|
|
5377
|
+
border: "none",
|
|
5378
|
+
padding: 0,
|
|
5379
|
+
width: "100%",
|
|
5380
|
+
cursor: "pointer",
|
|
5381
|
+
fontFamily: "inherit",
|
|
5382
|
+
outline: "none"
|
|
5383
|
+
};
|
|
5384
|
+
var providerLogoStyle = {
|
|
5385
|
+
width: 18,
|
|
5386
|
+
height: 18,
|
|
5387
|
+
borderRadius: "50%",
|
|
5388
|
+
objectFit: "contain"
|
|
5389
|
+
};
|
|
5390
|
+
var providerFallbackStyle = (color) => ({
|
|
5391
|
+
width: 18,
|
|
5392
|
+
height: 18,
|
|
5393
|
+
borderRadius: "50%",
|
|
5394
|
+
display: "flex",
|
|
5395
|
+
alignItems: "center",
|
|
5396
|
+
justifyContent: "center",
|
|
5397
|
+
fontSize: "0.65rem",
|
|
5398
|
+
fontWeight: 700,
|
|
5399
|
+
color,
|
|
5400
|
+
flexShrink: 0
|
|
5401
|
+
});
|
|
5402
|
+
var walletBalanceStyle = (color) => ({
|
|
5403
|
+
fontSize: "0.9rem",
|
|
5404
|
+
fontWeight: 600,
|
|
5405
|
+
color
|
|
5406
|
+
});
|
|
5407
|
+
var accountDropdownOuterStyle = (tokens) => ({
|
|
5408
|
+
marginTop: 4,
|
|
5409
|
+
background: tokens.bgCard,
|
|
5410
|
+
border: `1px solid ${tokens.border}`,
|
|
5411
|
+
borderRadius: tokens.radiusLg,
|
|
5412
|
+
boxShadow: tokens.shadowLg,
|
|
5413
|
+
padding: "12px 14px 14px"
|
|
5414
|
+
});
|
|
5415
|
+
var accountDropdownLabelStyle = (color) => ({
|
|
5416
|
+
fontSize: "0.78rem",
|
|
5417
|
+
fontWeight: 500,
|
|
5418
|
+
color,
|
|
5419
|
+
marginBottom: 8
|
|
5420
|
+
});
|
|
5421
|
+
var accountDropdownInnerStyle = (tokens) => ({
|
|
5422
|
+
background: tokens.bgInput,
|
|
5423
|
+
border: `1px solid ${tokens.border}`,
|
|
5424
|
+
borderRadius: tokens.radiusLg,
|
|
5425
|
+
overflow: "hidden"
|
|
5426
|
+
});
|
|
5427
|
+
var accountRowStyle = (tokens, isSelected) => ({
|
|
5428
|
+
display: "flex",
|
|
5429
|
+
alignItems: "center",
|
|
5430
|
+
justifyContent: "space-between",
|
|
5431
|
+
width: "100%",
|
|
5432
|
+
padding: "14px 16px",
|
|
5433
|
+
background: isSelected ? `${tokens.accent}10` : "transparent",
|
|
5434
|
+
border: "none",
|
|
5435
|
+
borderBottom: `1px solid ${tokens.border}`,
|
|
5436
|
+
cursor: "pointer",
|
|
5437
|
+
fontFamily: "inherit",
|
|
5438
|
+
textAlign: "left",
|
|
5439
|
+
outline: "none"
|
|
5440
|
+
});
|
|
5441
|
+
var accountRowLeftStyle = {
|
|
5442
|
+
display: "flex",
|
|
5443
|
+
alignItems: "center",
|
|
5444
|
+
gap: 12,
|
|
5445
|
+
minWidth: 0,
|
|
5446
|
+
flex: 1
|
|
5447
|
+
};
|
|
5448
|
+
var accountLogoStyle = {
|
|
5449
|
+
width: 28,
|
|
5450
|
+
height: 28,
|
|
5451
|
+
borderRadius: "50%",
|
|
5452
|
+
objectFit: "contain",
|
|
5453
|
+
flexShrink: 0
|
|
5454
|
+
};
|
|
5455
|
+
var accountFallbackIconStyle = (color) => ({
|
|
5456
|
+
width: 28,
|
|
5457
|
+
height: 28,
|
|
5458
|
+
borderRadius: "50%",
|
|
5459
|
+
display: "flex",
|
|
5460
|
+
alignItems: "center",
|
|
5461
|
+
justifyContent: "center",
|
|
5462
|
+
fontSize: "0.75rem",
|
|
5463
|
+
fontWeight: 700,
|
|
5464
|
+
color,
|
|
5465
|
+
flexShrink: 0
|
|
5466
|
+
});
|
|
5467
|
+
var accountInfoStyle = {
|
|
5468
|
+
display: "flex",
|
|
4935
5469
|
flexDirection: "column",
|
|
4936
5470
|
gap: 2,
|
|
4937
5471
|
minWidth: 0
|
|
@@ -4995,9 +5529,20 @@ var limitExceededHintStyle = (color) => ({
|
|
|
4995
5529
|
margin: "12px 0 2px",
|
|
4996
5530
|
lineHeight: 1.5
|
|
4997
5531
|
});
|
|
5532
|
+
var feeRowContainerStyle = {
|
|
5533
|
+
fontSize: "0.84rem",
|
|
5534
|
+
fontWeight: 500,
|
|
5535
|
+
marginTop: 6,
|
|
5536
|
+
marginBottom: 4
|
|
5537
|
+
};
|
|
5538
|
+
var feeRowLabelStyle = (color) => ({ color });
|
|
5539
|
+
var feeRowAmountStyle = (color) => ({
|
|
5540
|
+
color,
|
|
5541
|
+
fontVariantNumeric: "tabular-nums"
|
|
5542
|
+
});
|
|
4998
5543
|
function SuccessScreen({
|
|
4999
5544
|
amount,
|
|
5000
|
-
currency,
|
|
5545
|
+
currency: _currency,
|
|
5001
5546
|
succeeded,
|
|
5002
5547
|
error,
|
|
5003
5548
|
merchantName,
|
|
@@ -5010,22 +5555,30 @@ function SuccessScreen({
|
|
|
5010
5555
|
onPreauthorize
|
|
5011
5556
|
}) {
|
|
5012
5557
|
const { tokens } = useBlinkConfig();
|
|
5558
|
+
const isGuestDepositSuccess = succeeded && onPreauthorize != null;
|
|
5013
5559
|
return /* @__PURE__ */ jsxs(
|
|
5014
5560
|
ScreenLayout,
|
|
5015
5561
|
{
|
|
5016
5562
|
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: "
|
|
5563
|
+
isGuestDepositSuccess ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5564
|
+
/* @__PURE__ */ jsx(PrimaryButton, { onClick: onPreauthorize, children: "Set up one tap" }),
|
|
5565
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: onDone, style: skipButtonStyle(tokens.textMuted), children: "Return to app" })
|
|
5020
5566
|
] }) : /* @__PURE__ */ jsx(PrimaryButton, { onClick: onDone, children: succeeded ? "Done" : "Try again" }),
|
|
5021
5567
|
onManageAccount && /* @__PURE__ */ jsx("button", { type: "button", onClick: onManageAccount, style: manageStyle(tokens.textMuted), children: "Manage Blink account \u2192" }),
|
|
5022
5568
|
/* @__PURE__ */ jsx(PoweredByFooter, {})
|
|
5023
5569
|
] }),
|
|
5024
5570
|
children: [
|
|
5025
5571
|
/* @__PURE__ */ jsx(ScreenHeader, { onLogout }),
|
|
5026
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
5027
|
-
|
|
5028
|
-
/* @__PURE__ */
|
|
5572
|
+
/* @__PURE__ */ jsxs("div", { style: screenContentStyle, children: [
|
|
5573
|
+
isGuestDepositSuccess ? /* @__PURE__ */ jsxs("div", { style: contentStyleCompact, children: [
|
|
5574
|
+
/* @__PURE__ */ jsxs("h2", { style: headingStyle7(tokens.text), children: [
|
|
5575
|
+
"$",
|
|
5576
|
+
amount.toFixed(2),
|
|
5577
|
+
" deposited"
|
|
5578
|
+
] }),
|
|
5579
|
+
/* @__PURE__ */ jsx("p", { style: { ...subtitleStyle7(tokens.text), fontWeight: 600, margin: "0 0 8px" }, children: "Next time, do it in one tap" }),
|
|
5580
|
+
/* @__PURE__ */ jsx("p", { style: subtitleStyle7(tokens.textSecondary), children: "Set up one tap for this wallet and skip the extra steps." })
|
|
5581
|
+
] }) : succeeded ? /* @__PURE__ */ jsxs("div", { style: contentStyleCompact, children: [
|
|
5029
5582
|
/* @__PURE__ */ jsxs("h2", { style: headingStyle7(tokens.text), children: [
|
|
5030
5583
|
"$",
|
|
5031
5584
|
amount.toFixed(2),
|
|
@@ -5037,10 +5590,10 @@ function SuccessScreen({
|
|
|
5037
5590
|
] })
|
|
5038
5591
|
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5039
5592
|
/* @__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:
|
|
5593
|
+
/* @__PURE__ */ jsx("h2", { style: failureHeadingStyle(tokens.text), children: "Transfer failed" }),
|
|
5594
|
+
error && /* @__PURE__ */ jsx("p", { style: failureSubtitleStyle(tokens.error), children: error })
|
|
5042
5595
|
] }),
|
|
5043
|
-
/* @__PURE__ */ jsxs("div", { style: summaryCardStyle(tokens), children: [
|
|
5596
|
+
!isGuestDepositSuccess && /* @__PURE__ */ jsxs("div", { style: summaryCardStyle(tokens), children: [
|
|
5044
5597
|
sourceName && /* @__PURE__ */ jsxs("div", { style: summaryRowStyle, children: [
|
|
5045
5598
|
/* @__PURE__ */ jsx("span", { style: summaryLabelStyle(tokens.textMuted), children: "From" }),
|
|
5046
5599
|
/* @__PURE__ */ jsx("span", { style: summaryValueStyle(tokens.text), children: sourceName })
|
|
@@ -5057,7 +5610,7 @@ function SuccessScreen({
|
|
|
5057
5610
|
] })
|
|
5058
5611
|
] })
|
|
5059
5612
|
] }),
|
|
5060
|
-
succeeded && onIncreaseLimits && /* @__PURE__ */ jsxs("div", { style: upsellCardStyle(tokens), children: [
|
|
5613
|
+
succeeded && onIncreaseLimits && !isGuestDepositSuccess && /* @__PURE__ */ jsxs("div", { style: upsellCardStyle(tokens), children: [
|
|
5061
5614
|
/* @__PURE__ */ jsxs("div", { style: upsellHeaderStyle, children: [
|
|
5062
5615
|
/* @__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
5616
|
/* @__PURE__ */ jsx("strong", { children: "Want higher limits?" })
|
|
@@ -5070,21 +5623,42 @@ function SuccessScreen({
|
|
|
5070
5623
|
}
|
|
5071
5624
|
);
|
|
5072
5625
|
}
|
|
5073
|
-
var
|
|
5626
|
+
var screenContentStyle = {
|
|
5074
5627
|
flex: 1,
|
|
5075
5628
|
display: "flex",
|
|
5076
5629
|
flexDirection: "column",
|
|
5077
5630
|
alignItems: "center",
|
|
5078
5631
|
paddingTop: 16
|
|
5079
5632
|
};
|
|
5633
|
+
var contentStyleCompact = {
|
|
5634
|
+
textAlign: "center",
|
|
5635
|
+
display: "flex",
|
|
5636
|
+
flexDirection: "column",
|
|
5637
|
+
alignItems: "center",
|
|
5638
|
+
width: "100%"
|
|
5639
|
+
};
|
|
5080
5640
|
var headingStyle7 = (color) => ({
|
|
5641
|
+
fontSize: "1.45rem",
|
|
5642
|
+
fontWeight: 700,
|
|
5643
|
+
letterSpacing: "-0.02em",
|
|
5644
|
+
color,
|
|
5645
|
+
margin: "20px 0 8px"
|
|
5646
|
+
});
|
|
5647
|
+
var subtitleStyle7 = (color) => ({
|
|
5648
|
+
fontSize: "0.9rem",
|
|
5649
|
+
color,
|
|
5650
|
+
margin: "0 0 28px",
|
|
5651
|
+
lineHeight: 1.5,
|
|
5652
|
+
maxWidth: 280
|
|
5653
|
+
});
|
|
5654
|
+
var failureHeadingStyle = (color) => ({
|
|
5081
5655
|
fontSize: "1.5rem",
|
|
5082
5656
|
fontWeight: 700,
|
|
5083
5657
|
letterSpacing: "-0.02em",
|
|
5084
5658
|
color,
|
|
5085
5659
|
margin: "20px 0 4px"
|
|
5086
5660
|
});
|
|
5087
|
-
var
|
|
5661
|
+
var failureSubtitleStyle = (color) => ({
|
|
5088
5662
|
fontSize: "0.9rem",
|
|
5089
5663
|
color,
|
|
5090
5664
|
margin: "0 0 20px"
|
|
@@ -5600,7 +6174,7 @@ function TransferStatusScreen({
|
|
|
5600
6174
|
const steps = buildSteps(phase);
|
|
5601
6175
|
return /* @__PURE__ */ jsxs(ScreenLayout, { footer: /* @__PURE__ */ jsx(PoweredByFooter, {}), children: [
|
|
5602
6176
|
/* @__PURE__ */ jsx(ScreenHeader, { onLogout }),
|
|
5603
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
6177
|
+
/* @__PURE__ */ jsxs("div", { style: contentStyle6, children: [
|
|
5604
6178
|
/* @__PURE__ */ jsx(Spinner, { size: 64 }),
|
|
5605
6179
|
/* @__PURE__ */ jsx("h2", { style: headingStyle9(tokens.text), children: "Depositing your money..." }),
|
|
5606
6180
|
error && /* @__PURE__ */ jsx("div", { style: errorBannerStyle7(tokens), children: error }),
|
|
@@ -5608,7 +6182,7 @@ function TransferStatusScreen({
|
|
|
5608
6182
|
] })
|
|
5609
6183
|
] });
|
|
5610
6184
|
}
|
|
5611
|
-
var
|
|
6185
|
+
var contentStyle6 = {
|
|
5612
6186
|
flex: 1,
|
|
5613
6187
|
display: "flex",
|
|
5614
6188
|
flexDirection: "column",
|
|
@@ -5678,7 +6252,7 @@ function OpenWalletScreen({
|
|
|
5678
6252
|
] }),
|
|
5679
6253
|
children: [
|
|
5680
6254
|
/* @__PURE__ */ jsx(ScreenHeader, { onLogout }),
|
|
5681
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
6255
|
+
/* @__PURE__ */ jsxs("div", { style: contentStyle7, children: [
|
|
5682
6256
|
/* @__PURE__ */ jsx("div", { style: logoCircleStyle(tokens.bgInput), children: logoSrc ? /* @__PURE__ */ jsx("img", { src: logoSrc, alt: displayName, style: logoStyle2 }) : /* @__PURE__ */ jsx(Spinner, { size: 32 }) }),
|
|
5683
6257
|
/* @__PURE__ */ jsxs("h2", { style: headingStyle10(tokens.text), children: [
|
|
5684
6258
|
"Setting up ",
|
|
@@ -5711,7 +6285,7 @@ function OpenWalletScreen({
|
|
|
5711
6285
|
] }),
|
|
5712
6286
|
children: [
|
|
5713
6287
|
/* @__PURE__ */ jsx(ScreenHeader, { onBack, onLogout }),
|
|
5714
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
6288
|
+
/* @__PURE__ */ jsxs("div", { style: contentStyle7, children: [
|
|
5715
6289
|
/* @__PURE__ */ jsx("div", { style: logoCircleStyle(tokens.bgInput), children: logoSrc ? /* @__PURE__ */ jsx("img", { src: logoSrc, alt: displayName, style: logoStyle2 }) : /* @__PURE__ */ jsx(Spinner, { size: 32 }) }),
|
|
5716
6290
|
/* @__PURE__ */ jsx("h2", { style: headingStyle10(tokens.text), children: loading ? "Connecting..." : `Open ${displayName}` }),
|
|
5717
6291
|
/* @__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 +6298,7 @@ function OpenWalletScreen({
|
|
|
5724
6298
|
}
|
|
5725
6299
|
);
|
|
5726
6300
|
}
|
|
5727
|
-
var
|
|
6301
|
+
var contentStyle7 = {
|
|
5728
6302
|
flex: 1,
|
|
5729
6303
|
display: "flex",
|
|
5730
6304
|
flexDirection: "column",
|
|
@@ -5810,7 +6384,7 @@ function ConfirmSignScreen({
|
|
|
5810
6384
|
] }),
|
|
5811
6385
|
children: [
|
|
5812
6386
|
/* @__PURE__ */ jsx(ScreenHeader, { onLogout }),
|
|
5813
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
6387
|
+
/* @__PURE__ */ jsxs("div", { style: contentStyle8, children: [
|
|
5814
6388
|
logoSrc ? /* @__PURE__ */ jsx("img", { src: logoSrc, alt: displayName, style: logoStyle3 }) : /* @__PURE__ */ jsx(Spinner, { size: 48 }),
|
|
5815
6389
|
/* @__PURE__ */ jsx("h2", { style: headingStyle11(tokens.text), children: "Wallet authorized" }),
|
|
5816
6390
|
/* @__PURE__ */ jsxs("p", { style: subtitleStyle11(tokens.textSecondary), children: [
|
|
@@ -5826,7 +6400,7 @@ function ConfirmSignScreen({
|
|
|
5826
6400
|
}
|
|
5827
6401
|
);
|
|
5828
6402
|
}
|
|
5829
|
-
var
|
|
6403
|
+
var contentStyle8 = {
|
|
5830
6404
|
flex: 1,
|
|
5831
6405
|
display: "flex",
|
|
5832
6406
|
flexDirection: "column",
|
|
@@ -6121,29 +6695,6 @@ var selectCircleSelectedStyle = (color) => ({
|
|
|
6121
6695
|
function entryKey(entry) {
|
|
6122
6696
|
return `${entry.sourceChainId}-${entry.tokenAddress.toLowerCase()}`;
|
|
6123
6697
|
}
|
|
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
6698
|
function GuestTokenPickerScreen({
|
|
6148
6699
|
entries,
|
|
6149
6700
|
loading,
|
|
@@ -6183,13 +6734,13 @@ function GuestTokenPickerScreen({
|
|
|
6183
6734
|
const canConfirm = Boolean(quoteFee && pendingEntry && !quoteLoading);
|
|
6184
6735
|
const feeLine = (() => {
|
|
6185
6736
|
if (quoteLoading && pendingEntry) {
|
|
6186
|
-
return /* @__PURE__ */ jsx("div", { style:
|
|
6737
|
+
return /* @__PURE__ */ jsx("div", { style: feeRowContainerStyle2, "aria-live": "polite", children: /* @__PURE__ */ jsx("span", { style: feeRowLabelStyle2(t.textMuted), children: "Getting fee estimate\u2026" }) });
|
|
6187
6738
|
}
|
|
6188
6739
|
if (quoteFee) {
|
|
6189
6740
|
const feeText = isPreciseMoneyNonPositive(quoteFee) ? formatNonPositiveFeeDisplay(quoteFee) : formatPreciseMoneyForDisplay(quoteFee);
|
|
6190
|
-
return /* @__PURE__ */ jsxs("div", { style:
|
|
6191
|
-
/* @__PURE__ */ jsx("span", { style:
|
|
6192
|
-
/* @__PURE__ */ jsx("span", { style:
|
|
6741
|
+
return /* @__PURE__ */ jsxs("div", { style: feeRowContainerStyle2, "aria-live": "polite", children: [
|
|
6742
|
+
/* @__PURE__ */ jsx("span", { style: feeRowLabelStyle2(t.textMuted), children: "Fee estimate: " }),
|
|
6743
|
+
/* @__PURE__ */ jsx("span", { style: feeRowAmountStyle2(t.textSecondary), children: feeText })
|
|
6193
6744
|
] });
|
|
6194
6745
|
}
|
|
6195
6746
|
return null;
|
|
@@ -6211,7 +6762,7 @@ function GuestTokenPickerScreen({
|
|
|
6211
6762
|
depositAmount != null && /* @__PURE__ */ jsxs("div", { style: depositAmountStyle2(t.text), children: [
|
|
6212
6763
|
"$",
|
|
6213
6764
|
depositAmount.toLocaleString("en-US", {
|
|
6214
|
-
minimumFractionDigits:
|
|
6765
|
+
minimumFractionDigits: 2,
|
|
6215
6766
|
maximumFractionDigits: 2
|
|
6216
6767
|
})
|
|
6217
6768
|
] }),
|
|
@@ -6293,7 +6844,7 @@ function GuestTokenPickerScreen({
|
|
|
6293
6844
|
] }),
|
|
6294
6845
|
tokenListOpen && entries.length > 0 && /* @__PURE__ */ jsxs("div", { style: tokenDropdownOuterStyle(t), children: [
|
|
6295
6846
|
/* @__PURE__ */ jsx("div", { style: accountDropdownLabelStyle2(t.textMuted), children: "Choose token" }),
|
|
6296
|
-
/* @__PURE__ */ jsx("div", { style:
|
|
6847
|
+
/* @__PURE__ */ jsx("div", { style: tokenDropdownInnerStyle2(t), children: entries.map((entry, index) => {
|
|
6297
6848
|
const selected = pendingKey === entryKey(entry);
|
|
6298
6849
|
const isLast = index === entries.length - 1;
|
|
6299
6850
|
return /* @__PURE__ */ jsxs(
|
|
@@ -6394,13 +6945,13 @@ var depositAmountStyle2 = (color) => ({
|
|
|
6394
6945
|
color,
|
|
6395
6946
|
lineHeight: 1.05
|
|
6396
6947
|
});
|
|
6397
|
-
var
|
|
6948
|
+
var feeRowContainerStyle2 = {
|
|
6398
6949
|
fontSize: "0.84rem",
|
|
6399
6950
|
fontWeight: 500,
|
|
6400
6951
|
marginTop: 6
|
|
6401
6952
|
};
|
|
6402
|
-
var
|
|
6403
|
-
var
|
|
6953
|
+
var feeRowLabelStyle2 = (color) => ({ color });
|
|
6954
|
+
var feeRowAmountStyle2 = (color) => ({
|
|
6404
6955
|
color,
|
|
6405
6956
|
fontVariantNumeric: "tabular-nums"
|
|
6406
6957
|
});
|
|
@@ -6446,7 +6997,7 @@ var accountDropdownLabelStyle2 = (color) => ({
|
|
|
6446
6997
|
color,
|
|
6447
6998
|
marginBottom: 8
|
|
6448
6999
|
});
|
|
6449
|
-
var
|
|
7000
|
+
var tokenDropdownInnerStyle2 = (tokens) => ({
|
|
6450
7001
|
background: tokens.bgInput,
|
|
6451
7002
|
border: `1px solid ${tokens.border}`,
|
|
6452
7003
|
borderRadius: tokens.radiusLg,
|
|
@@ -6558,7 +7109,7 @@ function GuestPreauthSetupCompleteScreen({
|
|
|
6558
7109
|
] }),
|
|
6559
7110
|
children: [
|
|
6560
7111
|
/* @__PURE__ */ jsx(ScreenHeader, { onLogout }),
|
|
6561
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
7112
|
+
/* @__PURE__ */ jsxs("div", { style: contentStyle9, children: [
|
|
6562
7113
|
/* @__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
7114
|
"path",
|
|
6564
7115
|
{
|
|
@@ -6567,13 +7118,13 @@ function GuestPreauthSetupCompleteScreen({
|
|
|
6567
7118
|
}
|
|
6568
7119
|
) }) }),
|
|
6569
7120
|
/* @__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
|
|
7121
|
+
/* @__PURE__ */ jsx("p", { style: subtitleStyle12(tokens.textSecondary), children: "Your account is linked and ready. You can close this window." })
|
|
6571
7122
|
] })
|
|
6572
7123
|
]
|
|
6573
7124
|
}
|
|
6574
7125
|
);
|
|
6575
7126
|
}
|
|
6576
|
-
var
|
|
7127
|
+
var contentStyle9 = {
|
|
6577
7128
|
display: "flex",
|
|
6578
7129
|
flexDirection: "column",
|
|
6579
7130
|
alignItems: "center",
|
|
@@ -6602,14 +7153,14 @@ function GuestPreauthLinkingScreen({ onLogout }) {
|
|
|
6602
7153
|
const { tokens } = useBlinkConfig();
|
|
6603
7154
|
return /* @__PURE__ */ jsxs(ScreenLayout, { children: [
|
|
6604
7155
|
/* @__PURE__ */ jsx(ScreenHeader, { onLogout }),
|
|
6605
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
7156
|
+
/* @__PURE__ */ jsxs("div", { style: contentStyle10, children: [
|
|
6606
7157
|
/* @__PURE__ */ jsx(Spinner, { size: 48 }),
|
|
6607
7158
|
/* @__PURE__ */ jsx("h2", { style: headingStyle13(tokens.text), children: "Setting up your account..." }),
|
|
6608
7159
|
/* @__PURE__ */ jsx("p", { style: subtitleStyle13(tokens.textSecondary), children: "Linking your wallet to your Blink account. This usually takes a few seconds." })
|
|
6609
7160
|
] })
|
|
6610
7161
|
] });
|
|
6611
7162
|
}
|
|
6612
|
-
var
|
|
7163
|
+
var contentStyle10 = {
|
|
6613
7164
|
flex: 1,
|
|
6614
7165
|
display: "flex",
|
|
6615
7166
|
flexDirection: "column",
|
|
@@ -6786,13 +7337,15 @@ function StepRendererContent({
|
|
|
6786
7337
|
return /* @__PURE__ */ jsx(
|
|
6787
7338
|
PasskeyScreen,
|
|
6788
7339
|
{
|
|
6789
|
-
onCreatePasskey: handlers.
|
|
7340
|
+
onCreatePasskey: handlers.onVerifyPasskey,
|
|
6790
7341
|
onBack: handlers.onLogout,
|
|
6791
7342
|
onLogout: handlers.onLogout,
|
|
6792
|
-
creating: state.
|
|
7343
|
+
creating: state.registeringPasskey,
|
|
6793
7344
|
error: state.error,
|
|
6794
|
-
|
|
6795
|
-
|
|
7345
|
+
onCreateNewPasskey: handlers.onCreateNewPasskey,
|
|
7346
|
+
onCreateNewPasskeyViaPopup: handlers.onCreateNewPasskeyViaPopup,
|
|
7347
|
+
createNewPopupFallback: state.passkeyPopupNeeded,
|
|
7348
|
+
creatingNewPasskey: state.registeringPasskey
|
|
6796
7349
|
}
|
|
6797
7350
|
);
|
|
6798
7351
|
case "wallet-picker": {
|
|
@@ -6849,15 +7402,11 @@ function StepRendererContent({
|
|
|
6849
7402
|
0
|
|
6850
7403
|
);
|
|
6851
7404
|
const effectiveTokenCount = tokenCount > 0 ? tokenCount : selectSourceTokenCount;
|
|
6852
|
-
const
|
|
6853
|
-
const
|
|
6854
|
-
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
balance: s.balance.available.amount,
|
|
6858
|
-
walletId: w.id
|
|
6859
|
-
}))
|
|
6860
|
-
) : selectSourceChoices.flatMap(
|
|
7405
|
+
const setupFromPendingSelectSource = pendingSelectSource != null;
|
|
7406
|
+
const setupSelectedTokenSymbol = setupFromPendingSelectSource ? selectSourceTokenSymbol || selectSourceRecommended?.tokenSymbol || "" : selectedSource?.token.symbol ?? selectSourceTokenSymbol;
|
|
7407
|
+
const setupSelectedChainName = setupFromPendingSelectSource ? selectSourceChainName || selectSourceRecommended?.chainName || "" : selectedWallet?.chain.name ?? selectSourceChainName;
|
|
7408
|
+
const effectiveSourceLabel = setupFromPendingSelectSource ? setupSelectedTokenSymbol && setupSelectedChainName ? `${setupSelectedTokenSymbol} on ${setupSelectedChainName}` : void 0 : selectedSourceLabel ?? (selectSourceChainName && selectSourceTokenSymbol ? `${selectSourceTokenSymbol} on ${selectSourceChainName}` : void 0);
|
|
7409
|
+
const setupTokenOptions = selectedAccount ? tokenOptionsForLinkedAccount(selectedAccount, state.chains) : selectSourceChoices.flatMap(
|
|
6861
7410
|
(chain) => chain.tokens.map((t) => ({
|
|
6862
7411
|
symbol: t.tokenSymbol,
|
|
6863
7412
|
chainName: chain.chainName,
|
|
@@ -6865,9 +7414,8 @@ function StepRendererContent({
|
|
|
6865
7414
|
}))
|
|
6866
7415
|
);
|
|
6867
7416
|
const handleSetupSelectToken = (symbol, chainName, walletId) => {
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
} else {
|
|
7417
|
+
handleInlineTokenSelection(handlers, state.chains, selectedAccount, symbol, chainName, walletId);
|
|
7418
|
+
if (pendingSelectSource) {
|
|
6871
7419
|
handlers.onSelectSourceChainChange(chainName);
|
|
6872
7420
|
handlers.onSetSelectSourceTokenSymbol(symbol);
|
|
6873
7421
|
}
|
|
@@ -6875,17 +7423,18 @@ function StepRendererContent({
|
|
|
6875
7423
|
return /* @__PURE__ */ jsx(
|
|
6876
7424
|
SetupScreen,
|
|
6877
7425
|
{
|
|
6878
|
-
availableBalance: selectedSource ? selectedSource.balance.available.amount : selectSourceAvailableBalance > 0 ? selectSourceAvailableBalance : selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : maxSourceBalance,
|
|
7426
|
+
availableBalance: selectedSource ? selectedSource.balance.available.amount : setupFromPendingSelectSource ? selectSourceAvailableBalance : selectSourceAvailableBalance > 0 ? selectSourceAvailableBalance : selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : maxSourceBalance,
|
|
6879
7427
|
tokenCount: effectiveTokenCount,
|
|
6880
7428
|
sourceName,
|
|
6881
7429
|
onSetupOneTap: handlers.onSetupOneTap,
|
|
6882
|
-
onBack:
|
|
7430
|
+
onBack: handlers.onBackFromSubflow,
|
|
6883
7431
|
onLogout: handlers.onLogout,
|
|
6884
7432
|
onAdvanced: handlers.onSelectToken,
|
|
6885
7433
|
selectedSourceLabel: effectiveSourceLabel,
|
|
6886
7434
|
loading: savingOneTapLimit,
|
|
6887
7435
|
error: state.error,
|
|
6888
|
-
selectedTokenSymbol:
|
|
7436
|
+
selectedTokenSymbol: setupSelectedTokenSymbol,
|
|
7437
|
+
selectedChainName: setupSelectedChainName,
|
|
6889
7438
|
tokenOptions: setupTokenOptions,
|
|
6890
7439
|
onSelectToken: handleSetupSelectToken
|
|
6891
7440
|
}
|
|
@@ -6907,6 +7456,7 @@ function StepRendererContent({
|
|
|
6907
7456
|
case "deposit": {
|
|
6908
7457
|
const parsedAmt = depositAmount != null ? depositAmount : 5;
|
|
6909
7458
|
const minDepositFloor = depositAmount != null ? depositAmount : DEFAULT_MIN_DEPOSIT_USD;
|
|
7459
|
+
const depositTokenOptions = tokenOptionsForLinkedAccount(selectedAccount, state.chains);
|
|
6910
7460
|
return /* @__PURE__ */ jsx(
|
|
6911
7461
|
DepositScreen,
|
|
6912
7462
|
{
|
|
@@ -6915,6 +7465,8 @@ function StepRendererContent({
|
|
|
6915
7465
|
remainingLimit: selectedSource != null ? selectedSource.remainingAllowance ?? null : selectedAccount?.remainingAllowance ?? null,
|
|
6916
7466
|
tokenCount,
|
|
6917
7467
|
initialAmount: parsedAmt,
|
|
7468
|
+
quoteFee: forms.depositQuoteFee,
|
|
7469
|
+
quoteLoading: forms.depositQuoteLoading,
|
|
6918
7470
|
processing: state.creatingTransfer,
|
|
6919
7471
|
error: state.error,
|
|
6920
7472
|
onDeposit: handlers.onPay,
|
|
@@ -6929,8 +7481,13 @@ function StepRendererContent({
|
|
|
6929
7481
|
onAuthorizeAccount: handlers.onContinueConnection,
|
|
6930
7482
|
onAddProvider: () => handlers.onSetPhase({ step: "wallet-picker", reason: "switch" }),
|
|
6931
7483
|
onSelectToken: handlers.onSelectToken,
|
|
7484
|
+
tokenOptions: depositTokenOptions,
|
|
7485
|
+
onPickToken: (symbol, chainName, walletId) => {
|
|
7486
|
+
handleInlineTokenSelection(handlers, state.chains, selectedAccount, symbol, chainName, walletId);
|
|
7487
|
+
},
|
|
6932
7488
|
selectedSourceLabel,
|
|
6933
7489
|
selectedTokenSymbol: selectedSource?.token.symbol,
|
|
7490
|
+
selectedChainName: selectedWallet?.chain.name,
|
|
6934
7491
|
minDepositFloor
|
|
6935
7492
|
}
|
|
6936
7493
|
);
|
|
@@ -6971,7 +7528,7 @@ function StepRendererContent({
|
|
|
6971
7528
|
chains: state.chains,
|
|
6972
7529
|
onSelectAuthorized: handlers.onSelectAuthorizedToken,
|
|
6973
7530
|
onAuthorizeToken: handlers.onAuthorizeToken,
|
|
6974
|
-
onBack:
|
|
7531
|
+
onBack: handlers.onBackFromSubflow,
|
|
6975
7532
|
onLogout: handlers.onLogout,
|
|
6976
7533
|
depositAmount: depositAmount ?? void 0,
|
|
6977
7534
|
selectedTokenSymbol: selectedSource?.token.symbol,
|
|
@@ -7050,7 +7607,7 @@ function StepRendererContent({
|
|
|
7050
7607
|
})() : void 0,
|
|
7051
7608
|
onDone: onDismiss ?? handlers.onNewPayment,
|
|
7052
7609
|
onLogout: authenticated ? handlers.onLogout : void 0,
|
|
7053
|
-
onPreauthorize: state.isGuestFlow ? handlers.onPreauthorize : void 0
|
|
7610
|
+
onPreauthorize: state.isGuestFlow && isDesktop ? handlers.onPreauthorize : void 0
|
|
7054
7611
|
}
|
|
7055
7612
|
);
|
|
7056
7613
|
}
|
|
@@ -7338,6 +7895,53 @@ function usePasskeyHandlers(dispatch, apiBaseUrl, accounts, knownCredentialIds)
|
|
|
7338
7895
|
dispatch({ type: "SET_REGISTERING_PASSKEY", value: false });
|
|
7339
7896
|
}
|
|
7340
7897
|
}, [user, knownCredentialIds, activateExistingCredential, completePasskeyRegistration, dispatch]);
|
|
7898
|
+
const handleVerifyPasskey = useCallback(async () => {
|
|
7899
|
+
dispatch({ type: "SET_REGISTERING_PASSKEY", value: true });
|
|
7900
|
+
dispatch({ type: "SET_ERROR", error: null });
|
|
7901
|
+
try {
|
|
7902
|
+
const matched = await findDevicePasskey(knownCredentialIds);
|
|
7903
|
+
if (matched) {
|
|
7904
|
+
await activateExistingCredential(matched);
|
|
7905
|
+
} else {
|
|
7906
|
+
dispatch({
|
|
7907
|
+
type: "SET_ERROR",
|
|
7908
|
+
error: "No matching passkey found on this device. Please try again."
|
|
7909
|
+
});
|
|
7910
|
+
}
|
|
7911
|
+
} catch (err) {
|
|
7912
|
+
captureException(err);
|
|
7913
|
+
dispatch({
|
|
7914
|
+
type: "SET_ERROR",
|
|
7915
|
+
error: err instanceof Error ? err.message : "Passkey verification failed."
|
|
7916
|
+
});
|
|
7917
|
+
} finally {
|
|
7918
|
+
dispatch({ type: "SET_REGISTERING_PASSKEY", value: false });
|
|
7919
|
+
}
|
|
7920
|
+
}, [knownCredentialIds, activateExistingCredential, dispatch]);
|
|
7921
|
+
const handleCreateNewPasskey = useCallback(async () => {
|
|
7922
|
+
dispatch({ type: "SET_REGISTERING_PASSKEY", value: true });
|
|
7923
|
+
dispatch({ type: "SET_ERROR", error: null });
|
|
7924
|
+
try {
|
|
7925
|
+
const passkeyDisplayName = user?.email?.address ?? user?.google?.name ?? user?.id ?? "Blink User";
|
|
7926
|
+
const { credentialId, publicKey } = await createPasskeyCredential({
|
|
7927
|
+
userId: user?.id ?? "unknown",
|
|
7928
|
+
displayName: passkeyDisplayName
|
|
7929
|
+
});
|
|
7930
|
+
await completePasskeyRegistration(credentialId, publicKey);
|
|
7931
|
+
} catch (err) {
|
|
7932
|
+
if (err instanceof PasskeyIframeBlockedError) {
|
|
7933
|
+
dispatch({ type: "SET_PASSKEY_POPUP_NEEDED", needed: true });
|
|
7934
|
+
} else {
|
|
7935
|
+
captureException(err);
|
|
7936
|
+
dispatch({
|
|
7937
|
+
type: "SET_ERROR",
|
|
7938
|
+
error: err instanceof Error ? err.message : "Failed to register passkey"
|
|
7939
|
+
});
|
|
7940
|
+
}
|
|
7941
|
+
} finally {
|
|
7942
|
+
dispatch({ type: "SET_REGISTERING_PASSKEY", value: false });
|
|
7943
|
+
}
|
|
7944
|
+
}, [user, completePasskeyRegistration, dispatch]);
|
|
7341
7945
|
const handleCreatePasskeyViaPopup = useCallback(async () => {
|
|
7342
7946
|
dispatch({ type: "SET_REGISTERING_PASSKEY", value: true });
|
|
7343
7947
|
dispatch({ type: "SET_ERROR", error: null });
|
|
@@ -7384,6 +7988,35 @@ function usePasskeyHandlers(dispatch, apiBaseUrl, accounts, knownCredentialIds)
|
|
|
7384
7988
|
dispatch({ type: "SET_REGISTERING_PASSKEY", value: false });
|
|
7385
7989
|
}
|
|
7386
7990
|
}, [user, knownCredentialIds, getAccessToken, apiBaseUrl, activateExistingCredential, dispatch]);
|
|
7991
|
+
const handleCreateNewPasskeyViaPopup = useCallback(async () => {
|
|
7992
|
+
dispatch({ type: "SET_REGISTERING_PASSKEY", value: true });
|
|
7993
|
+
dispatch({ type: "SET_ERROR", error: null });
|
|
7994
|
+
try {
|
|
7995
|
+
const token = await getAccessToken();
|
|
7996
|
+
const passkeyDisplayName = user?.email?.address ?? user?.google?.name ?? user?.id ?? "Blink User";
|
|
7997
|
+
const popupOptions = buildPasskeyPopupOptions({
|
|
7998
|
+
userId: user?.id ?? "unknown",
|
|
7999
|
+
displayName: passkeyDisplayName,
|
|
8000
|
+
authToken: token ?? void 0,
|
|
8001
|
+
apiBaseUrl
|
|
8002
|
+
});
|
|
8003
|
+
const { credentialId, publicKey } = await createPasskeyViaPopup(popupOptions);
|
|
8004
|
+
dispatch({ type: "PASSKEY_ACTIVATED", credentialId, publicKey });
|
|
8005
|
+
localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, credentialId);
|
|
8006
|
+
if (token) {
|
|
8007
|
+
reportPasskeyActivity(apiBaseUrl, token, credentialId).catch(() => {
|
|
8008
|
+
});
|
|
8009
|
+
}
|
|
8010
|
+
} catch (err) {
|
|
8011
|
+
captureException(err);
|
|
8012
|
+
dispatch({
|
|
8013
|
+
type: "SET_ERROR",
|
|
8014
|
+
error: err instanceof Error ? err.message : "Failed to register passkey"
|
|
8015
|
+
});
|
|
8016
|
+
} finally {
|
|
8017
|
+
dispatch({ type: "SET_REGISTERING_PASSKEY", value: false });
|
|
8018
|
+
}
|
|
8019
|
+
}, [user, getAccessToken, apiBaseUrl, dispatch]);
|
|
7387
8020
|
const handleVerifyPasskeyViaPopup = useCallback(async () => {
|
|
7388
8021
|
dispatch({ type: "SET_VERIFYING_PASSKEY", value: true });
|
|
7389
8022
|
dispatch({ type: "SET_ERROR", error: null });
|
|
@@ -7426,7 +8059,10 @@ function usePasskeyHandlers(dispatch, apiBaseUrl, accounts, knownCredentialIds)
|
|
|
7426
8059
|
}, [knownCredentialIds, getAccessToken, apiBaseUrl, dispatch]);
|
|
7427
8060
|
return {
|
|
7428
8061
|
handleRegisterPasskey,
|
|
8062
|
+
handleVerifyPasskey,
|
|
8063
|
+
handleCreateNewPasskey,
|
|
7429
8064
|
handleCreatePasskeyViaPopup,
|
|
8065
|
+
handleCreateNewPasskeyViaPopup,
|
|
7430
8066
|
handleVerifyPasskeyViaPopup,
|
|
7431
8067
|
checkingPasskeyRef
|
|
7432
8068
|
};
|
|
@@ -7449,6 +8085,9 @@ function useTransferHandlers(deps) {
|
|
|
7449
8085
|
sourceTokenAddress,
|
|
7450
8086
|
activeCredentialId,
|
|
7451
8087
|
selectedAccountId,
|
|
8088
|
+
selectedWalletId,
|
|
8089
|
+
selectedTokenSymbol,
|
|
8090
|
+
quoteId,
|
|
7452
8091
|
transfer,
|
|
7453
8092
|
accounts
|
|
7454
8093
|
} = deps;
|
|
@@ -7462,9 +8101,32 @@ function useTransferHandlers(deps) {
|
|
|
7462
8101
|
fetchProviders(apiBaseUrl, token)
|
|
7463
8102
|
]);
|
|
7464
8103
|
const parsedAmt = depositAmount != null ? depositAmount : 0;
|
|
7465
|
-
const defaults =
|
|
7466
|
-
|
|
7467
|
-
|
|
8104
|
+
const { defaults, resetSelectedTokenSymbol } = resolveDepositSelectionAfterRefresh(
|
|
8105
|
+
accts,
|
|
8106
|
+
parsedAmt,
|
|
8107
|
+
{
|
|
8108
|
+
selectedAccountId,
|
|
8109
|
+
selectedWalletId,
|
|
8110
|
+
selectedTokenSymbol
|
|
8111
|
+
}
|
|
8112
|
+
);
|
|
8113
|
+
dispatch({
|
|
8114
|
+
type: "ACCOUNTS_RELOADED",
|
|
8115
|
+
accounts: accts,
|
|
8116
|
+
providers: prov,
|
|
8117
|
+
defaults,
|
|
8118
|
+
resetSelectedTokenSymbol
|
|
8119
|
+
});
|
|
8120
|
+
}, [
|
|
8121
|
+
getAccessToken,
|
|
8122
|
+
activeCredentialId,
|
|
8123
|
+
selectedAccountId,
|
|
8124
|
+
selectedWalletId,
|
|
8125
|
+
selectedTokenSymbol,
|
|
8126
|
+
apiBaseUrl,
|
|
8127
|
+
depositAmount,
|
|
8128
|
+
dispatch
|
|
8129
|
+
]);
|
|
7468
8130
|
const handlePay = useCallback(async (payAmount, sourceOverrides) => {
|
|
7469
8131
|
const minUsd = effectiveMinTransferAmountUsd(depositAmount);
|
|
7470
8132
|
if (isNaN(payAmount) || payAmount < minUsd) {
|
|
@@ -7508,7 +8170,8 @@ function useTransferHandlers(deps) {
|
|
|
7508
8170
|
sourceId: effectiveSourceId,
|
|
7509
8171
|
sourceTokenAddress,
|
|
7510
8172
|
destination,
|
|
7511
|
-
amount: payAmount
|
|
8173
|
+
amount: payAmount,
|
|
8174
|
+
...quoteId ? { quoteId } : {}
|
|
7512
8175
|
});
|
|
7513
8176
|
dispatch({ type: "TRANSFER_CREATED", transfer: t });
|
|
7514
8177
|
if (t.status === "COMPLETED") {
|
|
@@ -7540,6 +8203,7 @@ function useTransferHandlers(deps) {
|
|
|
7540
8203
|
accounts,
|
|
7541
8204
|
destination,
|
|
7542
8205
|
apiBaseUrl,
|
|
8206
|
+
quoteId,
|
|
7543
8207
|
getAccessToken,
|
|
7544
8208
|
transferSigning,
|
|
7545
8209
|
polling,
|
|
@@ -7590,20 +8254,20 @@ function useSourceSelectionHandlers(dispatch, authExecutor, options) {
|
|
|
7590
8254
|
const selectSourceAvailableBalance = useMemo(() => {
|
|
7591
8255
|
if (!pendingSelectSourceAction) return 0;
|
|
7592
8256
|
const options2 = pendingSelectSourceAction.metadata?.options ?? [];
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
8257
|
+
return resolveSelectSourceAvailableBalance(
|
|
8258
|
+
selectSourceChoices,
|
|
8259
|
+
options2,
|
|
8260
|
+
selectSourceChainName,
|
|
8261
|
+
selectSourceTokenSymbol,
|
|
8262
|
+
selectSourceRecommended
|
|
8263
|
+
);
|
|
8264
|
+
}, [
|
|
8265
|
+
pendingSelectSourceAction,
|
|
8266
|
+
selectSourceChoices,
|
|
8267
|
+
selectSourceChainName,
|
|
8268
|
+
selectSourceTokenSymbol,
|
|
8269
|
+
selectSourceRecommended
|
|
8270
|
+
]);
|
|
7607
8271
|
const handleSelectSourceChainChange = useCallback(
|
|
7608
8272
|
(chainName) => {
|
|
7609
8273
|
setSelectSourceChainName(chainName);
|
|
@@ -7654,7 +8318,7 @@ function useSourceSelectionHandlers(dispatch, authExecutor, options) {
|
|
|
7654
8318
|
initializedSelectSourceActionRef
|
|
7655
8319
|
};
|
|
7656
8320
|
}
|
|
7657
|
-
function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransferIdRef, stateTransfer, refs, guestCheckout, onComplete) {
|
|
8321
|
+
function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransferIdRef, stateTransfer, refs, guestCheckout, onComplete, lastResumedAt) {
|
|
7658
8322
|
const {
|
|
7659
8323
|
mobileSetupFlowRef,
|
|
7660
8324
|
handlingMobileReturnRef,
|
|
@@ -7665,6 +8329,8 @@ function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransfe
|
|
|
7665
8329
|
onCompleteRef.current = onComplete;
|
|
7666
8330
|
const guestPollingActiveRef = useRef(false);
|
|
7667
8331
|
const guestPollingCleanupRef = useRef(null);
|
|
8332
|
+
const mobileFlowRef = useRef(guestCheckout.mobileFlow);
|
|
8333
|
+
mobileFlowRef.current = guestCheckout.mobileFlow;
|
|
7668
8334
|
const guestTransferIdRef = useRef(guestCheckout.guestTransferId);
|
|
7669
8335
|
guestTransferIdRef.current = guestCheckout.guestTransferId;
|
|
7670
8336
|
const guestSessionTokenRef = useRef(guestCheckout.guestSessionToken);
|
|
@@ -7720,27 +8386,15 @@ function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransfe
|
|
|
7720
8386
|
startGuestPolling
|
|
7721
8387
|
]);
|
|
7722
8388
|
useEffect(() => {
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
}
|
|
7731
|
-
|
|
7732
|
-
if (document.visibilityState === "visible") tryStartPolling();
|
|
7733
|
-
};
|
|
7734
|
-
const handlePageShow = (e) => {
|
|
7735
|
-
if (e.persisted) tryStartPolling();
|
|
7736
|
-
};
|
|
7737
|
-
document.addEventListener("visibilitychange", handleVisibility);
|
|
7738
|
-
window.addEventListener("pageshow", handlePageShow);
|
|
7739
|
-
return () => {
|
|
7740
|
-
document.removeEventListener("visibilitychange", handleVisibility);
|
|
7741
|
-
window.removeEventListener("pageshow", handlePageShow);
|
|
7742
|
-
};
|
|
7743
|
-
}, [startGuestPolling]);
|
|
8389
|
+
if (!lastResumedAt) return;
|
|
8390
|
+
if (guestPollingActiveRef.current) return;
|
|
8391
|
+
if (!mobileFlowRef.current) return;
|
|
8392
|
+
const transferId = guestTransferIdRef.current;
|
|
8393
|
+
const token = guestSessionTokenRef.current;
|
|
8394
|
+
if (transferId && token) {
|
|
8395
|
+
startGuestPolling(transferId, token);
|
|
8396
|
+
}
|
|
8397
|
+
}, [lastResumedAt, startGuestPolling]);
|
|
7744
8398
|
const handleAuthorizedMobileReturn = useCallback(async (authorizedTransfer, isSetup) => {
|
|
7745
8399
|
if (handlingMobileReturnRef.current) return;
|
|
7746
8400
|
handlingMobileReturnRef.current = true;
|
|
@@ -7974,6 +8628,9 @@ function useProviderHandlers(deps) {
|
|
|
7974
8628
|
await reloadAccounts();
|
|
7975
8629
|
}
|
|
7976
8630
|
} catch (err) {
|
|
8631
|
+
if (isAuthorizationSessionCancelled(err) || isUserDismissedAuthorizationError(err)) {
|
|
8632
|
+
return;
|
|
8633
|
+
}
|
|
7977
8634
|
captureException(err);
|
|
7978
8635
|
const msg = err instanceof Error ? err.message : "Failed to set up wallet";
|
|
7979
8636
|
dispatch({ type: "PAY_ERROR", error: msg });
|
|
@@ -8040,7 +8697,12 @@ function useProviderHandlers(deps) {
|
|
|
8040
8697
|
}
|
|
8041
8698
|
const acct = accounts.find((a) => a.id === selectedAccountId);
|
|
8042
8699
|
const matchedProvider = acct ? providers.find((p) => p.name === acct.name) : void 0;
|
|
8043
|
-
|
|
8700
|
+
const isMobile = !shouldUseWalletConnector({
|
|
8701
|
+
useWalletConnector: useWalletConnectorProp,
|
|
8702
|
+
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8703
|
+
});
|
|
8704
|
+
if (matchedProvider && isMobile) {
|
|
8705
|
+
dispatch({ type: "SAVE_SELECTION" });
|
|
8044
8706
|
dispatch({ type: "SELECT_PROVIDER", providerId: matchedProvider.id });
|
|
8045
8707
|
}
|
|
8046
8708
|
dispatch({ type: "SET_ERROR", error: null });
|
|
@@ -8060,10 +8722,6 @@ function useProviderHandlers(deps) {
|
|
|
8060
8722
|
activeCredentialId,
|
|
8061
8723
|
{ tokenAddress: source?.address, chainId: evmChainId }
|
|
8062
8724
|
);
|
|
8063
|
-
const isMobile = !shouldUseWalletConnector({
|
|
8064
|
-
useWalletConnector: useWalletConnectorProp,
|
|
8065
|
-
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8066
|
-
});
|
|
8067
8725
|
if (isMobile) {
|
|
8068
8726
|
handlingMobileReturnRef.current = false;
|
|
8069
8727
|
mobileSetupFlowRef.current = true;
|
|
@@ -8080,12 +8738,20 @@ function useProviderHandlers(deps) {
|
|
|
8080
8738
|
});
|
|
8081
8739
|
dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
|
|
8082
8740
|
triggerDeeplink(session.uri);
|
|
8741
|
+
dispatch({ type: "DISCARD_SAVED_SELECTION" });
|
|
8083
8742
|
} else {
|
|
8084
8743
|
await authExecutor.executeSessionById(session.id);
|
|
8085
8744
|
await reloadAccounts();
|
|
8745
|
+
dispatch({ type: "DISCARD_SAVED_SELECTION" });
|
|
8086
8746
|
}
|
|
8087
8747
|
} catch (err) {
|
|
8748
|
+
if (isAuthorizationSessionCancelled(err) || isUserDismissedAuthorizationError(err)) {
|
|
8749
|
+
return;
|
|
8750
|
+
}
|
|
8088
8751
|
captureException(err);
|
|
8752
|
+
if (isMobile) {
|
|
8753
|
+
dispatch({ type: "RESTORE_SELECTION" });
|
|
8754
|
+
}
|
|
8089
8755
|
const msg = err instanceof Error ? err.message : "Failed to increase limit";
|
|
8090
8756
|
dispatch({ type: "SET_ERROR", error: msg });
|
|
8091
8757
|
onError?.(msg);
|
|
@@ -8130,7 +8796,12 @@ function useProviderHandlers(deps) {
|
|
|
8130
8796
|
}
|
|
8131
8797
|
const acct = accounts.find((a) => a.id === selectedAccountId);
|
|
8132
8798
|
const matchedProvider = acct ? providers.find((p) => p.name === acct.name) : void 0;
|
|
8133
|
-
|
|
8799
|
+
const isMobile = !shouldUseWalletConnector({
|
|
8800
|
+
useWalletConnector: useWalletConnectorProp,
|
|
8801
|
+
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8802
|
+
});
|
|
8803
|
+
if (matchedProvider && isMobile) {
|
|
8804
|
+
dispatch({ type: "SAVE_SELECTION" });
|
|
8134
8805
|
dispatch({ type: "SELECT_PROVIDER", providerId: matchedProvider.id });
|
|
8135
8806
|
}
|
|
8136
8807
|
dispatch({ type: "SET_ERROR", error: null });
|
|
@@ -8145,10 +8816,6 @@ function useProviderHandlers(deps) {
|
|
|
8145
8816
|
activeCredentialId,
|
|
8146
8817
|
{ tokenAddress, chainId }
|
|
8147
8818
|
);
|
|
8148
|
-
const isMobile = !shouldUseWalletConnector({
|
|
8149
|
-
useWalletConnector: useWalletConnectorProp,
|
|
8150
|
-
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8151
|
-
});
|
|
8152
8819
|
if (isMobile) {
|
|
8153
8820
|
handlingMobileReturnRef.current = false;
|
|
8154
8821
|
mobileSetupFlowRef.current = true;
|
|
@@ -8166,13 +8833,21 @@ function useProviderHandlers(deps) {
|
|
|
8166
8833
|
});
|
|
8167
8834
|
dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
|
|
8168
8835
|
triggerDeeplink(session.uri);
|
|
8836
|
+
dispatch({ type: "DISCARD_SAVED_SELECTION" });
|
|
8169
8837
|
} else {
|
|
8170
8838
|
await authExecutor.executeSessionById(session.id);
|
|
8171
8839
|
await reloadAccounts();
|
|
8172
8840
|
dispatch({ type: "SELECT_TOKEN", walletId: _walletId, tokenSymbol });
|
|
8841
|
+
dispatch({ type: "DISCARD_SAVED_SELECTION" });
|
|
8173
8842
|
}
|
|
8174
8843
|
} catch (err) {
|
|
8844
|
+
if (isAuthorizationSessionCancelled(err) || isUserDismissedAuthorizationError(err)) {
|
|
8845
|
+
return;
|
|
8846
|
+
}
|
|
8175
8847
|
captureException(err);
|
|
8848
|
+
if (isMobile) {
|
|
8849
|
+
dispatch({ type: "RESTORE_SELECTION" });
|
|
8850
|
+
}
|
|
8176
8851
|
const msg = err instanceof Error ? err.message : "Failed to authorize token";
|
|
8177
8852
|
dispatch({ type: "SET_ERROR", error: msg });
|
|
8178
8853
|
onError?.(msg);
|
|
@@ -9005,28 +9680,6 @@ function usePasskeyCheckEffect(deps) {
|
|
|
9005
9680
|
await restoreState(activeCredentialId, token);
|
|
9006
9681
|
return;
|
|
9007
9682
|
}
|
|
9008
|
-
if (cancelled) return;
|
|
9009
|
-
const credentialIds = allPasskeys.map((p) => p.credentialId);
|
|
9010
|
-
let matched = null;
|
|
9011
|
-
if (isSafari() && isInCrossOriginIframe()) {
|
|
9012
|
-
matched = await findDevicePasskeyViaPopup({
|
|
9013
|
-
credentialIds,
|
|
9014
|
-
rpId: resolvePasskeyRpId(),
|
|
9015
|
-
authToken: token ?? void 0,
|
|
9016
|
-
apiBaseUrl
|
|
9017
|
-
});
|
|
9018
|
-
} else {
|
|
9019
|
-
matched = await findDevicePasskey(credentialIds);
|
|
9020
|
-
}
|
|
9021
|
-
if (cancelled) return;
|
|
9022
|
-
if (matched) {
|
|
9023
|
-
const publicKey = allPasskeys.find((p) => p.credentialId === matched)?.publicKey;
|
|
9024
|
-
dispatch({ type: "PASSKEY_ACTIVATED", credentialId: matched, publicKey });
|
|
9025
|
-
window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, matched);
|
|
9026
|
-
reportPasskeyActivity(apiBaseUrl, token, matched).catch(() => {
|
|
9027
|
-
});
|
|
9028
|
-
await restoreState(matched, token);
|
|
9029
|
-
}
|
|
9030
9683
|
} catch (err) {
|
|
9031
9684
|
dispatch({
|
|
9032
9685
|
type: "PASSKEY_CONFIG_LOADED",
|
|
@@ -9109,7 +9762,15 @@ function useDataLoadEffect(deps) {
|
|
|
9109
9762
|
]);
|
|
9110
9763
|
if (cancelled) return;
|
|
9111
9764
|
const parsedAmt = depositAmount != null ? depositAmount : 0;
|
|
9112
|
-
const defaults =
|
|
9765
|
+
const { defaults, resetSelectedTokenSymbol } = resolveDepositSelectionAfterRefresh(
|
|
9766
|
+
accts,
|
|
9767
|
+
parsedAmt,
|
|
9768
|
+
{
|
|
9769
|
+
selectedAccountId: state.selectedAccountId,
|
|
9770
|
+
selectedWalletId: state.selectedWalletId,
|
|
9771
|
+
selectedTokenSymbol: state.selectedTokenSymbol
|
|
9772
|
+
}
|
|
9773
|
+
);
|
|
9113
9774
|
const persisted = loadMobileFlowState();
|
|
9114
9775
|
const clearMobile = persisted?.isSetup && accts.some((a) => a.wallets.some((w) => w.status === "ACTIVE"));
|
|
9115
9776
|
dispatch({
|
|
@@ -9118,7 +9779,8 @@ function useDataLoadEffect(deps) {
|
|
|
9118
9779
|
accounts: accts,
|
|
9119
9780
|
chains: chn,
|
|
9120
9781
|
defaults,
|
|
9121
|
-
clearMobileState: clearMobile
|
|
9782
|
+
clearMobileState: clearMobile,
|
|
9783
|
+
resetSelectedTokenSymbol
|
|
9122
9784
|
});
|
|
9123
9785
|
if (clearMobile) clearMobileFlowState();
|
|
9124
9786
|
} catch (err) {
|
|
@@ -9147,6 +9809,8 @@ function useDataLoadEffect(deps) {
|
|
|
9147
9809
|
apiBaseUrl,
|
|
9148
9810
|
state.activeCredentialId,
|
|
9149
9811
|
state.selectedAccountId,
|
|
9812
|
+
state.selectedWalletId,
|
|
9813
|
+
state.selectedTokenSymbol,
|
|
9150
9814
|
depositAmount
|
|
9151
9815
|
]);
|
|
9152
9816
|
useEffect(() => {
|
|
@@ -9375,25 +10039,16 @@ function useMobilePollingEffect(deps) {
|
|
|
9375
10039
|
const poll = isReauth ? pollReauthorization : pollWalletActive;
|
|
9376
10040
|
poll();
|
|
9377
10041
|
const intervalId = window.setInterval(poll, POLL_INTERVAL_MS);
|
|
9378
|
-
const handleVisibility = () => {
|
|
9379
|
-
if (document.visibilityState === "visible" && !cancelled) poll();
|
|
9380
|
-
};
|
|
9381
|
-
const handlePageShow = (e) => {
|
|
9382
|
-
if (e.persisted && !cancelled) poll();
|
|
9383
|
-
};
|
|
9384
|
-
document.addEventListener("visibilitychange", handleVisibility);
|
|
9385
|
-
window.addEventListener("pageshow", handlePageShow);
|
|
9386
10042
|
return () => {
|
|
9387
10043
|
cancelled = true;
|
|
9388
10044
|
window.clearInterval(intervalId);
|
|
9389
|
-
document.removeEventListener("visibilitychange", handleVisibility);
|
|
9390
|
-
window.removeEventListener("pageshow", handlePageShow);
|
|
9391
10045
|
};
|
|
9392
10046
|
}, [
|
|
9393
10047
|
state.mobileFlow,
|
|
9394
10048
|
state.isGuestFlow,
|
|
9395
10049
|
state.guestPreauthSessionId,
|
|
9396
10050
|
state.activeCredentialId,
|
|
10051
|
+
state.lastResumedAt,
|
|
9397
10052
|
apiBaseUrl,
|
|
9398
10053
|
reloadAccounts,
|
|
9399
10054
|
dispatch,
|
|
@@ -9410,28 +10065,13 @@ function useMobilePollingEffect(deps) {
|
|
|
9410
10065
|
const transferIdToResume = pollingTransferIdRef.current ?? state.transfer?.id;
|
|
9411
10066
|
if (!transferIdToResume) return;
|
|
9412
10067
|
if (!polling.isPolling) polling.startPolling(transferIdToResume);
|
|
9413
|
-
const handleVisibility = () => {
|
|
9414
|
-
if (document.visibilityState === "visible" && !handlingMobileReturnRef.current) {
|
|
9415
|
-
polling.startPolling(transferIdToResume);
|
|
9416
|
-
}
|
|
9417
|
-
};
|
|
9418
|
-
const handlePageShow = (e) => {
|
|
9419
|
-
if (e.persisted && !handlingMobileReturnRef.current) {
|
|
9420
|
-
polling.startPolling(transferIdToResume);
|
|
9421
|
-
}
|
|
9422
|
-
};
|
|
9423
|
-
document.addEventListener("visibilitychange", handleVisibility);
|
|
9424
|
-
window.addEventListener("pageshow", handlePageShow);
|
|
9425
|
-
return () => {
|
|
9426
|
-
document.removeEventListener("visibilitychange", handleVisibility);
|
|
9427
|
-
window.removeEventListener("pageshow", handlePageShow);
|
|
9428
|
-
};
|
|
9429
10068
|
}, [
|
|
9430
10069
|
state.mobileFlow,
|
|
9431
10070
|
state.transfer?.id,
|
|
9432
10071
|
state.isGuestFlow,
|
|
9433
10072
|
state.guestPreauthSessionId,
|
|
9434
10073
|
state.guestPreauthAccountId,
|
|
10074
|
+
state.lastResumedAt,
|
|
9435
10075
|
polling.isPolling,
|
|
9436
10076
|
polling.startPolling,
|
|
9437
10077
|
handlingMobileReturnRef,
|
|
@@ -9442,6 +10082,7 @@ function useGuestPreauthMobileRestoreEffect(deps) {
|
|
|
9442
10082
|
const {
|
|
9443
10083
|
dispatch,
|
|
9444
10084
|
privyReady,
|
|
10085
|
+
lastResumedAt,
|
|
9445
10086
|
mobileSetupFlowRef,
|
|
9446
10087
|
setupAccountIdRef,
|
|
9447
10088
|
startGuestAccountPolling
|
|
@@ -9452,68 +10093,43 @@ function useGuestPreauthMobileRestoreEffect(deps) {
|
|
|
9452
10093
|
console.info("[blink-sdk] guestPreauthMobileRestore: skipping, privyReady=false");
|
|
9453
10094
|
return;
|
|
9454
10095
|
}
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
|
|
9461
|
-
|
|
9462
|
-
|
|
9463
|
-
|
|
9464
|
-
|
|
9465
|
-
|
|
9466
|
-
|
|
9467
|
-
|
|
9468
|
-
|
|
9469
|
-
|
|
9470
|
-
|
|
9471
|
-
|
|
9472
|
-
|
|
9473
|
-
|
|
9474
|
-
|
|
9475
|
-
|
|
9476
|
-
|
|
9477
|
-
if (persisted.accountId) {
|
|
9478
|
-
dispatch({
|
|
9479
|
-
type: "GUEST_PREAUTH_DETECTED",
|
|
9480
|
-
accountId: persisted.accountId,
|
|
9481
|
-
sessionId: persisted.sessionId
|
|
9482
|
-
});
|
|
9483
|
-
}
|
|
10096
|
+
if (startedRef.current) {
|
|
10097
|
+
console.info("[blink-sdk] guestPreauthMobileRestore: already started");
|
|
10098
|
+
return;
|
|
10099
|
+
}
|
|
10100
|
+
const persisted = loadMobileFlowState();
|
|
10101
|
+
console.info("[blink-sdk] guestPreauthMobileRestore.tryStart", {
|
|
10102
|
+
trigger: lastResumedAt ? "page-resume" : "initial",
|
|
10103
|
+
hasPersistedState: !!persisted,
|
|
10104
|
+
isGuestPreauth: persisted?.isGuestPreauth ?? false,
|
|
10105
|
+
hasGuestSessionToken: !!persisted?.guestSessionToken,
|
|
10106
|
+
hasSessionId: !!persisted?.sessionId,
|
|
10107
|
+
accountId: persisted?.accountId ?? null
|
|
10108
|
+
});
|
|
10109
|
+
if (!persisted?.isGuestPreauth || !persisted.guestSessionToken || !persisted.sessionId) {
|
|
10110
|
+
return;
|
|
10111
|
+
}
|
|
10112
|
+
startedRef.current = true;
|
|
10113
|
+
mobileSetupFlowRef.current = true;
|
|
10114
|
+
if (persisted.accountId) {
|
|
10115
|
+
setupAccountIdRef.current = persisted.accountId;
|
|
10116
|
+
}
|
|
10117
|
+
if (persisted.accountId) {
|
|
9484
10118
|
dispatch({
|
|
9485
|
-
type: "
|
|
9486
|
-
|
|
9487
|
-
});
|
|
9488
|
-
console.info("[blink-sdk] guestPreauthMobileRestore: starting guest account polling", {
|
|
9489
|
-
trigger,
|
|
10119
|
+
type: "GUEST_PREAUTH_DETECTED",
|
|
10120
|
+
accountId: persisted.accountId,
|
|
9490
10121
|
sessionId: persisted.sessionId
|
|
9491
10122
|
});
|
|
9492
|
-
|
|
9493
|
-
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9498
|
-
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
console.info("[blink-sdk] guestPreauthMobileRestore: pageshow fired", {
|
|
9503
|
-
persisted: e.persisted,
|
|
9504
|
-
visibilityState: document.visibilityState,
|
|
9505
|
-
startedRef: startedRef.current
|
|
9506
|
-
});
|
|
9507
|
-
if (document.visibilityState === "visible") tryStart("pageshow");
|
|
9508
|
-
};
|
|
9509
|
-
tryStart("initial");
|
|
9510
|
-
document.addEventListener("visibilitychange", onVisibility);
|
|
9511
|
-
window.addEventListener("pageshow", onPageShow);
|
|
9512
|
-
return () => {
|
|
9513
|
-
document.removeEventListener("visibilitychange", onVisibility);
|
|
9514
|
-
window.removeEventListener("pageshow", onPageShow);
|
|
9515
|
-
};
|
|
9516
|
-
}, [privyReady, dispatch, mobileSetupFlowRef, setupAccountIdRef, startGuestAccountPolling]);
|
|
10123
|
+
}
|
|
10124
|
+
dispatch({
|
|
10125
|
+
type: "MOBILE_DEEPLINK_READY",
|
|
10126
|
+
deeplinkUri: persisted.deeplinkUri
|
|
10127
|
+
});
|
|
10128
|
+
console.info("[blink-sdk] guestPreauthMobileRestore: starting guest account polling", {
|
|
10129
|
+
sessionId: persisted.sessionId
|
|
10130
|
+
});
|
|
10131
|
+
startGuestAccountPolling(persisted.guestSessionToken, persisted.sessionId);
|
|
10132
|
+
}, [privyReady, lastResumedAt, dispatch, mobileSetupFlowRef, setupAccountIdRef, startGuestAccountPolling]);
|
|
9517
10133
|
}
|
|
9518
10134
|
function useSelectSourceEffect(deps) {
|
|
9519
10135
|
const {
|
|
@@ -9817,7 +10433,7 @@ function useStandardDesktopInlineOpenWalletEffect(deps) {
|
|
|
9817
10433
|
useEffect(() => {
|
|
9818
10434
|
if (!isDesktop || state.guestPreauthorizing) return;
|
|
9819
10435
|
if (!state.privyAuthenticated || !state.activeCredentialId || !state.selectedAccountId) return;
|
|
9820
|
-
const shouldPin = authExecutor.executing && !authExecutor.pendingSelectSource && !authExecutor.pendingOneTapSetup;
|
|
10436
|
+
const shouldPin = authExecutor.executing && !authExecutor.pendingSelectSource && (!authExecutor.pendingOneTapSetup || authExecutor.authorizationSessionStackDepth > 1);
|
|
9821
10437
|
if (shouldPin && !state.standardDesktopInlineOpenWallet) {
|
|
9822
10438
|
dispatch({ type: "SET_STANDARD_DESKTOP_INLINE_OPEN_WALLET", value: true });
|
|
9823
10439
|
return;
|
|
@@ -9835,6 +10451,7 @@ function useStandardDesktopInlineOpenWalletEffect(deps) {
|
|
|
9835
10451
|
authExecutor.executing,
|
|
9836
10452
|
authExecutor.pendingSelectSource,
|
|
9837
10453
|
authExecutor.pendingOneTapSetup,
|
|
10454
|
+
authExecutor.authorizationSessionStackDepth,
|
|
9838
10455
|
dispatch
|
|
9839
10456
|
]);
|
|
9840
10457
|
}
|
|
@@ -9853,7 +10470,84 @@ function useGuestAccountAutoPollingEffect(deps) {
|
|
|
9853
10470
|
startPolling(guestSessionToken);
|
|
9854
10471
|
}, [mobileFlow, isGuestFlow, guestSessionToken, isPolling, guestAccount, startPolling]);
|
|
9855
10472
|
}
|
|
9856
|
-
|
|
10473
|
+
var WATCHDOG_INTERVAL_MS = 1e3;
|
|
10474
|
+
var WATCHDOG_THRESHOLD_MS = 3e3;
|
|
10475
|
+
var DEDUP_COOLDOWN_MS = 500;
|
|
10476
|
+
function usePageResume(callback) {
|
|
10477
|
+
const callbackRef = useRef(callback);
|
|
10478
|
+
callbackRef.current = callback;
|
|
10479
|
+
useEffect(() => {
|
|
10480
|
+
let lastTickAt = Date.now();
|
|
10481
|
+
let lastFiredAt = 0;
|
|
10482
|
+
const fire = (source, frozenDurationMs) => {
|
|
10483
|
+
const now = Date.now();
|
|
10484
|
+
if (now - lastFiredAt < DEDUP_COOLDOWN_MS) return;
|
|
10485
|
+
lastFiredAt = now;
|
|
10486
|
+
callbackRef.current({ frozenDurationMs, source });
|
|
10487
|
+
};
|
|
10488
|
+
const watchdogId = window.setInterval(() => {
|
|
10489
|
+
const now = Date.now();
|
|
10490
|
+
const elapsed = now - lastTickAt;
|
|
10491
|
+
lastTickAt = now;
|
|
10492
|
+
if (elapsed > WATCHDOG_THRESHOLD_MS) {
|
|
10493
|
+
fire("watchdog", elapsed);
|
|
10494
|
+
}
|
|
10495
|
+
}, WATCHDOG_INTERVAL_MS);
|
|
10496
|
+
const handleVisibility = () => {
|
|
10497
|
+
const now = Date.now();
|
|
10498
|
+
if (document.visibilityState === "visible") {
|
|
10499
|
+
fire("visibilitychange", now - lastTickAt);
|
|
10500
|
+
}
|
|
10501
|
+
lastTickAt = now;
|
|
10502
|
+
};
|
|
10503
|
+
const handlePageShow = (_e) => {
|
|
10504
|
+
const now = Date.now();
|
|
10505
|
+
if (document.visibilityState === "visible") {
|
|
10506
|
+
fire("pageshow", now - lastTickAt);
|
|
10507
|
+
}
|
|
10508
|
+
lastTickAt = now;
|
|
10509
|
+
};
|
|
10510
|
+
const handleFocus = () => {
|
|
10511
|
+
const now = Date.now();
|
|
10512
|
+
const elapsed = now - lastTickAt;
|
|
10513
|
+
lastTickAt = now;
|
|
10514
|
+
if (elapsed > WATCHDOG_THRESHOLD_MS) {
|
|
10515
|
+
fire("focus", elapsed);
|
|
10516
|
+
}
|
|
10517
|
+
};
|
|
10518
|
+
document.addEventListener("visibilitychange", handleVisibility);
|
|
10519
|
+
window.addEventListener("pageshow", handlePageShow);
|
|
10520
|
+
window.addEventListener("focus", handleFocus);
|
|
10521
|
+
return () => {
|
|
10522
|
+
window.clearInterval(watchdogId);
|
|
10523
|
+
document.removeEventListener("visibilitychange", handleVisibility);
|
|
10524
|
+
window.removeEventListener("pageshow", handlePageShow);
|
|
10525
|
+
window.removeEventListener("focus", handleFocus);
|
|
10526
|
+
};
|
|
10527
|
+
}, []);
|
|
10528
|
+
}
|
|
10529
|
+
var STUCK_REF_THRESHOLD_MS = 5e3;
|
|
10530
|
+
function usePageResumeEffect(deps) {
|
|
10531
|
+
const { dispatch, handlingMobileReturnRef } = deps;
|
|
10532
|
+
const dispatchRef = useRef(dispatch);
|
|
10533
|
+
dispatchRef.current = dispatch;
|
|
10534
|
+
usePageResume((info) => {
|
|
10535
|
+
console.info("[blink-sdk] PAGE_RESUMED", {
|
|
10536
|
+
source: info.source,
|
|
10537
|
+
frozenDurationMs: info.frozenDurationMs
|
|
10538
|
+
});
|
|
10539
|
+
dispatchRef.current({ type: "PAGE_RESUMED", frozenDurationMs: info.frozenDurationMs });
|
|
10540
|
+
if (info.frozenDurationMs > STUCK_REF_THRESHOLD_MS) {
|
|
10541
|
+
if (handlingMobileReturnRef.current) {
|
|
10542
|
+
console.info("[blink-sdk] PAGE_RESUMED: clearing stuck handlingMobileReturnRef", {
|
|
10543
|
+
frozenDurationMs: info.frozenDurationMs
|
|
10544
|
+
});
|
|
10545
|
+
handlingMobileReturnRef.current = false;
|
|
10546
|
+
}
|
|
10547
|
+
}
|
|
10548
|
+
});
|
|
10549
|
+
}
|
|
10550
|
+
function useGuestAccountPolling(intervalMs = 3e3, lastResumedAt = 0) {
|
|
9857
10551
|
const { apiBaseUrl } = useBlinkConfig();
|
|
9858
10552
|
const [guestAccount, setGuestAccount] = useState(null);
|
|
9859
10553
|
const [isPolling, setIsPolling] = useState(false);
|
|
@@ -9951,36 +10645,71 @@ function useGuestAccountPolling(intervalMs = 3e3) {
|
|
|
9951
10645
|
[poll, intervalMs, stopPolling]
|
|
9952
10646
|
);
|
|
9953
10647
|
useEffect(() => {
|
|
9954
|
-
|
|
9955
|
-
|
|
9956
|
-
|
|
9957
|
-
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
|
|
9969
|
-
|
|
10648
|
+
if (!lastResumedAt || !guestTokenRef.current) return;
|
|
10649
|
+
console.info("[blink-sdk] useGuestAccountPolling: page resumed, triggering poll", {
|
|
10650
|
+
lastResumedAt,
|
|
10651
|
+
hasToken: !!guestTokenRef.current,
|
|
10652
|
+
hasSessionId: !!sessionIdRef.current
|
|
10653
|
+
});
|
|
10654
|
+
void poll();
|
|
10655
|
+
}, [lastResumedAt, poll]);
|
|
10656
|
+
useEffect(() => () => stopPolling(), [stopPolling]);
|
|
10657
|
+
return { guestAccount, error, isPolling, startPolling, stopPolling };
|
|
10658
|
+
}
|
|
10659
|
+
function useDepositFeeEstimate({
|
|
10660
|
+
apiBaseUrl,
|
|
10661
|
+
getAccessToken,
|
|
10662
|
+
walletId,
|
|
10663
|
+
sourceTokenAddress,
|
|
10664
|
+
destination,
|
|
10665
|
+
amount,
|
|
10666
|
+
enabled
|
|
10667
|
+
}) {
|
|
10668
|
+
const [quoteId, setQuoteId] = useState(null);
|
|
10669
|
+
const [quoteFee, setQuoteFee] = useState(null);
|
|
10670
|
+
const [quoteLoading, setQuoteLoading] = useState(false);
|
|
10671
|
+
const abortRef = useRef(null);
|
|
10672
|
+
const fetchQuote = useCallback(async () => {
|
|
10673
|
+
if (!enabled || !walletId || !sourceTokenAddress) {
|
|
10674
|
+
setQuoteId(null);
|
|
10675
|
+
setQuoteFee(null);
|
|
10676
|
+
setQuoteLoading(false);
|
|
10677
|
+
return;
|
|
10678
|
+
}
|
|
10679
|
+
abortRef.current?.abort();
|
|
10680
|
+
const controller = new AbortController();
|
|
10681
|
+
abortRef.current = controller;
|
|
10682
|
+
setQuoteLoading(true);
|
|
10683
|
+
try {
|
|
10684
|
+
const token = await getAccessToken();
|
|
10685
|
+
if (!token || controller.signal.aborted) return;
|
|
10686
|
+
const quote = await postTransferQuote(apiBaseUrl, token, {
|
|
10687
|
+
walletId,
|
|
10688
|
+
sourceTokenAddress,
|
|
10689
|
+
destination,
|
|
10690
|
+
amount: { amount, currency: "USD" }
|
|
9970
10691
|
});
|
|
9971
|
-
if (
|
|
9972
|
-
|
|
10692
|
+
if (controller.signal.aborted) return;
|
|
10693
|
+
setQuoteId(quote.id);
|
|
10694
|
+
setQuoteFee(quote.fee);
|
|
10695
|
+
} catch (err) {
|
|
10696
|
+
if (controller.signal.aborted) return;
|
|
10697
|
+
console.warn("[blink-sdk] Fee quote failed:", err);
|
|
10698
|
+
setQuoteId(null);
|
|
10699
|
+
setQuoteFee(null);
|
|
10700
|
+
} finally {
|
|
10701
|
+
if (!controller.signal.aborted) {
|
|
10702
|
+
setQuoteLoading(false);
|
|
9973
10703
|
}
|
|
9974
|
-
}
|
|
9975
|
-
|
|
9976
|
-
|
|
10704
|
+
}
|
|
10705
|
+
}, [enabled, walletId, sourceTokenAddress, destination, amount, apiBaseUrl, getAccessToken]);
|
|
10706
|
+
useEffect(() => {
|
|
10707
|
+
fetchQuote();
|
|
9977
10708
|
return () => {
|
|
9978
|
-
|
|
9979
|
-
window.removeEventListener("pageshow", handlePageShow);
|
|
10709
|
+
abortRef.current?.abort();
|
|
9980
10710
|
};
|
|
9981
|
-
}, [
|
|
9982
|
-
|
|
9983
|
-
return { guestAccount, error, isPolling, startPolling, stopPolling };
|
|
10711
|
+
}, [fetchQuote]);
|
|
10712
|
+
return { quoteId, quoteFee, quoteLoading };
|
|
9984
10713
|
}
|
|
9985
10714
|
function BlinkPayment(props) {
|
|
9986
10715
|
const resetKey = useRef(0);
|
|
@@ -10013,14 +10742,14 @@ function BlinkPaymentInner({
|
|
|
10013
10742
|
paymentReducer,
|
|
10014
10743
|
{
|
|
10015
10744
|
depositAmount,
|
|
10016
|
-
passkeyPopupNeeded: isSafari() && isInCrossOriginIframe(),
|
|
10745
|
+
passkeyPopupNeeded: isSafari() && isInCrossOriginIframe() && !isDesktop,
|
|
10017
10746
|
activeCredentialId: typeof window === "undefined" ? null : window.localStorage.getItem(ACTIVE_CREDENTIAL_STORAGE_KEY)
|
|
10018
10747
|
},
|
|
10019
10748
|
createInitialState
|
|
10020
10749
|
);
|
|
10021
10750
|
const authExecutor = useAuthorizationExecutor();
|
|
10022
10751
|
const polling = useTransferPolling();
|
|
10023
|
-
const guestAccountPolling = useGuestAccountPolling();
|
|
10752
|
+
const guestAccountPolling = useGuestAccountPolling(3e3, state.lastResumedAt);
|
|
10024
10753
|
const transferSigning = useTransferSigning();
|
|
10025
10754
|
const mobileFlowRefs = {
|
|
10026
10755
|
mobileSetupFlowRef: useRef(false),
|
|
@@ -10038,6 +10767,15 @@ function BlinkPaymentInner({
|
|
|
10038
10767
|
state.accounts,
|
|
10039
10768
|
state.knownCredentialIds
|
|
10040
10769
|
);
|
|
10770
|
+
const depositFee = useDepositFeeEstimate({
|
|
10771
|
+
apiBaseUrl,
|
|
10772
|
+
getAccessToken,
|
|
10773
|
+
walletId: state.selectedWalletId,
|
|
10774
|
+
sourceTokenAddress: derived.selectedSource?.address,
|
|
10775
|
+
destination,
|
|
10776
|
+
amount: depositAmount ?? 5,
|
|
10777
|
+
enabled: state.phase.step === "deposit" && !state.isGuestFlow && authenticated
|
|
10778
|
+
});
|
|
10041
10779
|
const transfer = useTransferHandlers({
|
|
10042
10780
|
dispatch,
|
|
10043
10781
|
getAccessToken,
|
|
@@ -10055,6 +10793,9 @@ function BlinkPaymentInner({
|
|
|
10055
10793
|
sourceTokenAddress: derived.selectedSource?.address,
|
|
10056
10794
|
activeCredentialId: state.activeCredentialId,
|
|
10057
10795
|
selectedAccountId: state.selectedAccountId,
|
|
10796
|
+
selectedWalletId: state.selectedWalletId,
|
|
10797
|
+
selectedTokenSymbol: state.selectedTokenSymbol,
|
|
10798
|
+
quoteId: depositFee.quoteId,
|
|
10058
10799
|
transfer: state.transfer,
|
|
10059
10800
|
accounts: state.accounts
|
|
10060
10801
|
});
|
|
@@ -10071,7 +10812,8 @@ function BlinkPaymentInner({
|
|
|
10071
10812
|
guestTransferId: state.guestTransferId,
|
|
10072
10813
|
guestSessionToken: state.guestSessionToken
|
|
10073
10814
|
},
|
|
10074
|
-
onComplete
|
|
10815
|
+
onComplete,
|
|
10816
|
+
state.lastResumedAt
|
|
10075
10817
|
);
|
|
10076
10818
|
const sourceSelection = useSourceSelectionHandlers(dispatch, authExecutor, {
|
|
10077
10819
|
guestPreauthSessionId: state.guestPreauthSessionId,
|
|
@@ -10167,10 +10909,15 @@ function BlinkPaymentInner({
|
|
|
10167
10909
|
dispatch({ type: "SYNC_AMOUNT", amount: depositAmount.toString() });
|
|
10168
10910
|
}
|
|
10169
10911
|
}, [depositAmount, dispatch]);
|
|
10912
|
+
usePageResumeEffect({
|
|
10913
|
+
dispatch,
|
|
10914
|
+
handlingMobileReturnRef: mobileFlowRefs.handlingMobileReturnRef
|
|
10915
|
+
});
|
|
10170
10916
|
usePrivySessionSyncEffect({ dispatch, ready, authenticated });
|
|
10171
10917
|
useGuestPreauthMobileRestoreEffect({
|
|
10172
10918
|
dispatch,
|
|
10173
10919
|
privyReady: state.privyReady,
|
|
10920
|
+
lastResumedAt: state.lastResumedAt,
|
|
10174
10921
|
mobileSetupFlowRef: mobileFlowRefs.mobileSetupFlowRef,
|
|
10175
10922
|
setupAccountIdRef: mobileFlowRefs.setupAccountIdRef,
|
|
10176
10923
|
startGuestAccountPolling: guestAccountPolling.startPolling
|
|
@@ -10183,25 +10930,24 @@ function BlinkPaymentInner({
|
|
|
10183
10930
|
guestAccount: guestAccountPolling.guestAccount,
|
|
10184
10931
|
startPolling: guestAccountPolling.startPolling
|
|
10185
10932
|
});
|
|
10186
|
-
const guestSessionTokenRef = useRef(state.guestSessionToken);
|
|
10187
|
-
guestSessionTokenRef.current = state.guestSessionToken;
|
|
10188
|
-
const guestPreauthSessionIdRef = useRef(state.guestPreauthSessionId);
|
|
10189
|
-
guestPreauthSessionIdRef.current = state.guestPreauthSessionId;
|
|
10190
10933
|
useEffect(() => {
|
|
10191
|
-
|
|
10192
|
-
|
|
10193
|
-
|
|
10194
|
-
|
|
10195
|
-
|
|
10196
|
-
|
|
10197
|
-
|
|
10198
|
-
|
|
10199
|
-
|
|
10200
|
-
|
|
10201
|
-
|
|
10202
|
-
|
|
10203
|
-
|
|
10204
|
-
|
|
10934
|
+
if (!state.lastResumedAt) return;
|
|
10935
|
+
const token = state.guestSessionToken;
|
|
10936
|
+
const sessionId = state.guestPreauthSessionId;
|
|
10937
|
+
if (!token) return;
|
|
10938
|
+
if (guestAccountPolling.isPolling || guestAccountPolling.guestAccount) return;
|
|
10939
|
+
console.info("[blink-sdk] warm-return: restarting guest account polling from React state", {
|
|
10940
|
+
sessionId: sessionId ?? "(none \u2014 account-only mode)"
|
|
10941
|
+
});
|
|
10942
|
+
guestAccountPolling.startPolling(token, sessionId ?? void 0);
|
|
10943
|
+
}, [
|
|
10944
|
+
state.lastResumedAt,
|
|
10945
|
+
state.guestSessionToken,
|
|
10946
|
+
state.guestPreauthSessionId,
|
|
10947
|
+
guestAccountPolling.isPolling,
|
|
10948
|
+
guestAccountPolling.guestAccount,
|
|
10949
|
+
guestAccountPolling.startPolling
|
|
10950
|
+
]);
|
|
10205
10951
|
useEffect(() => {
|
|
10206
10952
|
console.info("[blink-sdk] guestPreauthCompletion effect", {
|
|
10207
10953
|
hasGuestAccount: !!guestAccountPolling.guestAccount,
|
|
@@ -10352,7 +11098,10 @@ function BlinkPaymentInner({
|
|
|
10352
11098
|
dispatch({ type: "BACK_TO_LOGIN" });
|
|
10353
11099
|
},
|
|
10354
11100
|
onRegisterPasskey: passkey.handleRegisterPasskey,
|
|
11101
|
+
onVerifyPasskey: passkey.handleVerifyPasskey,
|
|
11102
|
+
onCreateNewPasskey: passkey.handleCreateNewPasskey,
|
|
10355
11103
|
onCreatePasskeyViaPopup: passkey.handleCreatePasskeyViaPopup,
|
|
11104
|
+
onCreateNewPasskeyViaPopup: passkey.handleCreateNewPasskeyViaPopup,
|
|
10356
11105
|
onVerifyPasskeyViaPopup: passkey.handleVerifyPasskeyViaPopup,
|
|
10357
11106
|
onPrepareProvider: provider.handlePrepareProvider,
|
|
10358
11107
|
onSelectProvider: provider.handleSelectProvider,
|
|
@@ -10366,6 +11115,11 @@ function BlinkPaymentInner({
|
|
|
10366
11115
|
onLogout: handleLogout,
|
|
10367
11116
|
onNewPayment: handleNewPayment,
|
|
10368
11117
|
onSetPhase: (phase) => dispatch({ type: "SET_USER_INTENT", intent: phase }),
|
|
11118
|
+
onBackFromSubflow: () => {
|
|
11119
|
+
authExecutor.cancelPendingExecution();
|
|
11120
|
+
dispatch({ type: "RESTORE_SELECTION" });
|
|
11121
|
+
dispatch({ type: "SET_USER_INTENT", intent: { step: "deposit" } });
|
|
11122
|
+
},
|
|
10369
11123
|
onSetAuthInput: auth.setAuthInput,
|
|
10370
11124
|
onSetOtpCode: (code) => {
|
|
10371
11125
|
auth.setOtpCode(code);
|
|
@@ -10399,7 +11153,8 @@ function BlinkPaymentInner({
|
|
|
10399
11153
|
handleLogout,
|
|
10400
11154
|
handleNewPayment,
|
|
10401
11155
|
onDismiss,
|
|
10402
|
-
dispatch
|
|
11156
|
+
dispatch,
|
|
11157
|
+
authExecutor
|
|
10403
11158
|
]);
|
|
10404
11159
|
return /* @__PURE__ */ jsx(
|
|
10405
11160
|
StepRenderer,
|
|
@@ -10448,13 +11203,16 @@ function BlinkPaymentInner({
|
|
|
10448
11203
|
guestSettingSender: guestTransfer.settingSender,
|
|
10449
11204
|
guestPendingEntry: guestTransfer.pendingGuestEntry,
|
|
10450
11205
|
guestQuoteFee: guestTransfer.guestFee?.quote ?? null,
|
|
10451
|
-
guestQuoteLoading: guestTransfer.guestQuoteLoading
|
|
11206
|
+
guestQuoteLoading: guestTransfer.guestQuoteLoading,
|
|
11207
|
+
depositQuoteId: depositFee.quoteId,
|
|
11208
|
+
depositQuoteFee: depositFee.quoteFee,
|
|
11209
|
+
depositQuoteLoading: depositFee.quoteLoading
|
|
10452
11210
|
},
|
|
10453
11211
|
handlers
|
|
10454
11212
|
}
|
|
10455
11213
|
);
|
|
10456
11214
|
}
|
|
10457
11215
|
|
|
10458
|
-
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 };
|
|
11216
|
+
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 };
|
|
10459
11217
|
//# sourceMappingURL=index.js.map
|
|
10460
11218
|
//# sourceMappingURL=index.js.map
|