@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.cjs
CHANGED
|
@@ -78,14 +78,16 @@ function getTheme(mode) {
|
|
|
78
78
|
}
|
|
79
79
|
var BLINK_PRIVY_APP_ID = "cmlil87uv004n0ck0blwumwek";
|
|
80
80
|
var wagmiConfig = wagmi.createConfig({
|
|
81
|
-
|
|
81
|
+
// baseSepolia: guest/testnet flows (e.g. smokebox e2e) call switchChain to the source chain from the API.
|
|
82
|
+
chains: [chains.mainnet, chains.arbitrum, chains.base, chains.polygon, chains.bsc, chains.baseSepolia],
|
|
82
83
|
connectors: [connectors.injected({ shimDisconnect: true, unstable_shimAsyncInject: 2e3 })],
|
|
83
84
|
transports: {
|
|
84
85
|
[chains.mainnet.id]: wagmi.http(),
|
|
85
86
|
[chains.arbitrum.id]: wagmi.http(),
|
|
86
87
|
[chains.base.id]: wagmi.http(),
|
|
87
88
|
[chains.polygon.id]: wagmi.http(),
|
|
88
|
-
[chains.bsc.id]: wagmi.http()
|
|
89
|
+
[chains.bsc.id]: wagmi.http(),
|
|
90
|
+
[chains.baseSepolia.id]: wagmi.http()
|
|
89
91
|
}
|
|
90
92
|
});
|
|
91
93
|
var BlinkContext = react.createContext(null);
|
|
@@ -495,6 +497,7 @@ __export(api_exports, {
|
|
|
495
497
|
getGuestTransfer: () => getGuestTransfer,
|
|
496
498
|
getTransferByGuestToken: () => getTransferByGuestToken,
|
|
497
499
|
postGuestTransferFeeQuote: () => postGuestTransferFeeQuote,
|
|
500
|
+
postTransferQuote: () => postTransferQuote,
|
|
498
501
|
putGuestTransferSender: () => putGuestTransferSender,
|
|
499
502
|
registerPasskey: () => registerPasskey,
|
|
500
503
|
reportActionCompletion: () => reportActionCompletion,
|
|
@@ -610,7 +613,8 @@ async function createTransfer(apiBaseUrl, token, params) {
|
|
|
610
613
|
amount: {
|
|
611
614
|
amount: params.amount,
|
|
612
615
|
currency: params.currency ?? "USD"
|
|
613
|
-
}
|
|
616
|
+
},
|
|
617
|
+
...params.quoteId ? { quoteId: params.quoteId } : {}
|
|
614
618
|
};
|
|
615
619
|
const res = await fetch(`${apiBaseUrl}/v1/transfers`, {
|
|
616
620
|
method: "POST",
|
|
@@ -623,6 +627,28 @@ async function createTransfer(apiBaseUrl, token, params) {
|
|
|
623
627
|
if (!res.ok) await throwApiError(res);
|
|
624
628
|
return await res.json();
|
|
625
629
|
}
|
|
630
|
+
async function postTransferQuote(apiBaseUrl, bearerToken, params) {
|
|
631
|
+
const body = {
|
|
632
|
+
walletId: params.walletId,
|
|
633
|
+
...params.sourceTokenAddress ? { sourceTokenAddress: params.sourceTokenAddress } : {},
|
|
634
|
+
destination: {
|
|
635
|
+
chainId: params.destination.chainId,
|
|
636
|
+
token: { address: params.destination.token.address },
|
|
637
|
+
address: params.destination.address
|
|
638
|
+
},
|
|
639
|
+
amount: params.amount
|
|
640
|
+
};
|
|
641
|
+
const res = await fetch(`${apiBaseUrl}/v1/transfers/quotes`, {
|
|
642
|
+
method: "POST",
|
|
643
|
+
headers: {
|
|
644
|
+
"Content-Type": "application/json",
|
|
645
|
+
Authorization: `Bearer ${bearerToken}`
|
|
646
|
+
},
|
|
647
|
+
body: JSON.stringify(body)
|
|
648
|
+
});
|
|
649
|
+
if (!res.ok) await throwApiError(res);
|
|
650
|
+
return await res.json();
|
|
651
|
+
}
|
|
626
652
|
async function fetchMerchantPublicKey(apiBaseUrl, merchantId) {
|
|
627
653
|
const res = await fetch(
|
|
628
654
|
`${apiBaseUrl}/v1/merchants/${encodeURIComponent(merchantId)}/public-key`
|
|
@@ -964,6 +990,23 @@ function normalizeSignature(sig) {
|
|
|
964
990
|
);
|
|
965
991
|
}
|
|
966
992
|
|
|
993
|
+
// src/authorizationErrors.ts
|
|
994
|
+
var AuthorizationSessionCancelledError = class extends Error {
|
|
995
|
+
constructor() {
|
|
996
|
+
super("Authorization session cancelled");
|
|
997
|
+
this.name = "AuthorizationSessionCancelledError";
|
|
998
|
+
}
|
|
999
|
+
};
|
|
1000
|
+
function isAuthorizationSessionCancelled(err) {
|
|
1001
|
+
if (err instanceof AuthorizationSessionCancelledError) return true;
|
|
1002
|
+
return typeof err === "object" && err !== null && "name" in err && err.name === "AuthorizationSessionCancelledError";
|
|
1003
|
+
}
|
|
1004
|
+
function isUserDismissedAuthorizationError(err) {
|
|
1005
|
+
if (!(err instanceof Error)) return false;
|
|
1006
|
+
const m = err.message.toLowerCase();
|
|
1007
|
+
return m.includes("authorization session aborted") || m.includes("aborted by user");
|
|
1008
|
+
}
|
|
1009
|
+
|
|
967
1010
|
// src/hooks/authorizationExecutor.ts
|
|
968
1011
|
var WALLET_CLIENT_MAX_ATTEMPTS = 25;
|
|
969
1012
|
var WALLET_CLIENT_POLL_MS = 400;
|
|
@@ -1277,39 +1320,80 @@ function useAuthorizationExecutor(options) {
|
|
|
1277
1320
|
const [error, setError] = react.useState(null);
|
|
1278
1321
|
const [currentAction, setCurrentAction] = react.useState(null);
|
|
1279
1322
|
const executingRef = react.useRef(false);
|
|
1323
|
+
const oneTapPauseActiveRef = react.useRef(false);
|
|
1324
|
+
const sessionStackRef = react.useRef([]);
|
|
1325
|
+
const [authorizationSessionStackDepth, setAuthorizationSessionStackDepth] = react.useState(0);
|
|
1280
1326
|
const [pendingSelectSource, setPendingSelectSource] = react.useState(null);
|
|
1281
1327
|
const selectSourceResolverRef = react.useRef(null);
|
|
1328
|
+
const selectSourceRejectRef = react.useRef(null);
|
|
1282
1329
|
const sessionIdRef = react.useRef(null);
|
|
1283
1330
|
const resolveSelectSource = react.useCallback((selection) => {
|
|
1284
1331
|
if (selectSourceResolverRef.current) {
|
|
1285
1332
|
selectSourceResolverRef.current(selection);
|
|
1286
1333
|
selectSourceResolverRef.current = null;
|
|
1334
|
+
selectSourceRejectRef.current = null;
|
|
1287
1335
|
setPendingSelectSource(null);
|
|
1288
1336
|
}
|
|
1289
1337
|
}, []);
|
|
1290
1338
|
const waitForSelection = react.useCallback(
|
|
1291
|
-
(action) => new Promise((resolve) => {
|
|
1292
|
-
selectSourceResolverRef.current =
|
|
1339
|
+
(action) => new Promise((resolve, reject) => {
|
|
1340
|
+
selectSourceResolverRef.current = (selection) => {
|
|
1341
|
+
resolve(selection);
|
|
1342
|
+
selectSourceResolverRef.current = null;
|
|
1343
|
+
selectSourceRejectRef.current = null;
|
|
1344
|
+
};
|
|
1345
|
+
selectSourceRejectRef.current = reject;
|
|
1293
1346
|
setPendingSelectSource(action);
|
|
1294
1347
|
}),
|
|
1295
1348
|
[]
|
|
1296
1349
|
);
|
|
1297
1350
|
const [pendingOneTapSetup, setPendingOneTapSetup] = react.useState(null);
|
|
1298
1351
|
const oneTapSetupResolverRef = react.useRef(null);
|
|
1352
|
+
const oneTapSetupRejectRef = react.useRef(null);
|
|
1299
1353
|
const resolveOneTapSetup = react.useCallback(() => {
|
|
1300
1354
|
if (oneTapSetupResolverRef.current) {
|
|
1301
1355
|
oneTapSetupResolverRef.current();
|
|
1302
1356
|
oneTapSetupResolverRef.current = null;
|
|
1357
|
+
oneTapSetupRejectRef.current = null;
|
|
1303
1358
|
setPendingOneTapSetup(null);
|
|
1304
1359
|
}
|
|
1305
1360
|
}, []);
|
|
1306
1361
|
const waitForOneTapSetup = react.useCallback(
|
|
1307
|
-
(action) => new Promise((resolve) => {
|
|
1308
|
-
|
|
1362
|
+
(action) => new Promise((resolve, reject) => {
|
|
1363
|
+
oneTapPauseActiveRef.current = true;
|
|
1364
|
+
oneTapSetupResolverRef.current = () => {
|
|
1365
|
+
oneTapPauseActiveRef.current = false;
|
|
1366
|
+
resolve();
|
|
1367
|
+
oneTapSetupResolverRef.current = null;
|
|
1368
|
+
oneTapSetupRejectRef.current = null;
|
|
1369
|
+
};
|
|
1370
|
+
oneTapSetupRejectRef.current = (reason) => {
|
|
1371
|
+
oneTapPauseActiveRef.current = false;
|
|
1372
|
+
reject(reason);
|
|
1373
|
+
};
|
|
1309
1374
|
setPendingOneTapSetup(action);
|
|
1310
1375
|
}),
|
|
1311
1376
|
[]
|
|
1312
1377
|
);
|
|
1378
|
+
const cancelPendingExecution = react.useCallback(() => {
|
|
1379
|
+
if (selectSourceRejectRef.current) {
|
|
1380
|
+
selectSourceRejectRef.current(new AuthorizationSessionCancelledError());
|
|
1381
|
+
selectSourceRejectRef.current = null;
|
|
1382
|
+
selectSourceResolverRef.current = null;
|
|
1383
|
+
setPendingSelectSource(null);
|
|
1384
|
+
}
|
|
1385
|
+
if (oneTapSetupRejectRef.current) {
|
|
1386
|
+
oneTapPauseActiveRef.current = false;
|
|
1387
|
+
oneTapSetupRejectRef.current(new AuthorizationSessionCancelledError());
|
|
1388
|
+
oneTapSetupRejectRef.current = null;
|
|
1389
|
+
oneTapSetupResolverRef.current = null;
|
|
1390
|
+
setPendingOneTapSetup(null);
|
|
1391
|
+
}
|
|
1392
|
+
setError(null);
|
|
1393
|
+
setCurrentAction(null);
|
|
1394
|
+
setExecuting(false);
|
|
1395
|
+
executingRef.current = false;
|
|
1396
|
+
}, []);
|
|
1313
1397
|
const dispatchAction = react.useCallback(
|
|
1314
1398
|
async (action) => {
|
|
1315
1399
|
setCurrentAction(action);
|
|
@@ -1344,20 +1428,26 @@ function useAuthorizationExecutor(options) {
|
|
|
1344
1428
|
);
|
|
1345
1429
|
const executeSessionById = react.useCallback(
|
|
1346
1430
|
async (sessionId) => {
|
|
1347
|
-
if (executingRef.current) return;
|
|
1348
|
-
executingRef.current = true;
|
|
1349
1431
|
if (!sessionId) {
|
|
1350
|
-
executingRef.current = false;
|
|
1351
1432
|
throw new Error("No authorization session id provided.");
|
|
1352
1433
|
}
|
|
1353
1434
|
if (!apiBaseUrl) {
|
|
1354
|
-
executingRef.current = false;
|
|
1355
1435
|
throw new Error("Missing apiBaseUrl. Provide useAuthorizationExecutor({ apiBaseUrl }) or wrap in <BlinkProvider>.");
|
|
1356
1436
|
}
|
|
1357
|
-
|
|
1358
|
-
|
|
1437
|
+
const allowNested = executingRef.current && oneTapPauseActiveRef.current;
|
|
1438
|
+
if (executingRef.current && !allowNested) {
|
|
1439
|
+
return;
|
|
1440
|
+
}
|
|
1441
|
+
const isNestedRun = allowNested;
|
|
1442
|
+
if (!isNestedRun) {
|
|
1443
|
+
executingRef.current = true;
|
|
1444
|
+
setExecuting(true);
|
|
1445
|
+
setResults([]);
|
|
1446
|
+
}
|
|
1359
1447
|
setError(null);
|
|
1360
|
-
|
|
1448
|
+
sessionStackRef.current.push(sessionId);
|
|
1449
|
+
setAuthorizationSessionStackDepth(sessionStackRef.current.length);
|
|
1450
|
+
sessionIdRef.current = sessionId;
|
|
1361
1451
|
try {
|
|
1362
1452
|
let session = await fetchAuthorizationSession(apiBaseUrl, sessionId);
|
|
1363
1453
|
const allResults = [];
|
|
@@ -1393,13 +1483,23 @@ function useAuthorizationExecutor(options) {
|
|
|
1393
1483
|
pending = getPendingActions(session, completedIds);
|
|
1394
1484
|
}
|
|
1395
1485
|
} catch (err) {
|
|
1396
|
-
|
|
1397
|
-
|
|
1486
|
+
if (isAuthorizationSessionCancelled(err)) {
|
|
1487
|
+
setError(null);
|
|
1488
|
+
} else {
|
|
1489
|
+
const msg = err instanceof Error ? err.message : "Authorization failed";
|
|
1490
|
+
setError(msg);
|
|
1491
|
+
}
|
|
1398
1492
|
throw err;
|
|
1399
1493
|
} finally {
|
|
1494
|
+
sessionStackRef.current.pop();
|
|
1495
|
+
const depth = sessionStackRef.current.length;
|
|
1496
|
+
setAuthorizationSessionStackDepth(depth);
|
|
1497
|
+
sessionIdRef.current = depth > 0 ? sessionStackRef.current[depth - 1] : null;
|
|
1400
1498
|
setCurrentAction(null);
|
|
1401
|
-
|
|
1402
|
-
|
|
1499
|
+
if (depth === 0) {
|
|
1500
|
+
setExecuting(false);
|
|
1501
|
+
executingRef.current = false;
|
|
1502
|
+
}
|
|
1403
1503
|
}
|
|
1404
1504
|
},
|
|
1405
1505
|
[apiBaseUrl, dispatchAction]
|
|
@@ -1413,7 +1513,9 @@ function useAuthorizationExecutor(options) {
|
|
|
1413
1513
|
resolveSelectSource,
|
|
1414
1514
|
pendingOneTapSetup,
|
|
1415
1515
|
resolveOneTapSetup,
|
|
1416
|
-
executeSessionById
|
|
1516
|
+
executeSessionById,
|
|
1517
|
+
cancelPendingExecution,
|
|
1518
|
+
authorizationSessionStackDepth
|
|
1417
1519
|
};
|
|
1418
1520
|
}
|
|
1419
1521
|
var TRANSFER_SIGN_MAX_POLLS = 60;
|
|
@@ -1643,6 +1745,37 @@ function getPreferredDepositWallet(account, transferAmount) {
|
|
|
1643
1745
|
function getDepositEligibleAccounts(accounts) {
|
|
1644
1746
|
return accounts.filter((account) => getAddressableWallets(account).length > 0);
|
|
1645
1747
|
}
|
|
1748
|
+
function resolveDepositSelectionAfterRefresh(accounts, transferAmount, prev) {
|
|
1749
|
+
const { selectedAccountId, selectedWalletId, selectedTokenSymbol } = prev;
|
|
1750
|
+
if (selectedAccountId && selectedWalletId) {
|
|
1751
|
+
const acct = accounts.find((a) => a.id === selectedAccountId);
|
|
1752
|
+
const wallet = acct?.wallets.find((w) => w.id === selectedWalletId);
|
|
1753
|
+
if (wallet) {
|
|
1754
|
+
if (selectedTokenSymbol) {
|
|
1755
|
+
const hasToken = wallet.sources.some((s) => s.token.symbol === selectedTokenSymbol);
|
|
1756
|
+
if (hasToken) {
|
|
1757
|
+
return {
|
|
1758
|
+
defaults: { accountId: selectedAccountId, walletId: selectedWalletId },
|
|
1759
|
+
resetSelectedTokenSymbol: false
|
|
1760
|
+
};
|
|
1761
|
+
}
|
|
1762
|
+
const fallback = resolveDepositSelection(accounts, transferAmount, selectedAccountId);
|
|
1763
|
+
return {
|
|
1764
|
+
defaults: fallback,
|
|
1765
|
+
resetSelectedTokenSymbol: true
|
|
1766
|
+
};
|
|
1767
|
+
}
|
|
1768
|
+
return {
|
|
1769
|
+
defaults: { accountId: selectedAccountId, walletId: selectedWalletId },
|
|
1770
|
+
resetSelectedTokenSymbol: false
|
|
1771
|
+
};
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
return {
|
|
1775
|
+
defaults: resolveDepositSelection(accounts, transferAmount, selectedAccountId),
|
|
1776
|
+
resetSelectedTokenSymbol: false
|
|
1777
|
+
};
|
|
1778
|
+
}
|
|
1646
1779
|
function resolveDepositSelection(accounts, transferAmount, selectedAccountId) {
|
|
1647
1780
|
const eligibleAccounts = getDepositEligibleAccounts(accounts);
|
|
1648
1781
|
if (eligibleAccounts.length === 0) return null;
|
|
@@ -1709,6 +1842,32 @@ function buildSelectSourceChoices(options) {
|
|
|
1709
1842
|
tokens: chain.tokens.filter((t) => t.balance > 0).sort((a, b) => b.balance - a.balance)
|
|
1710
1843
|
})).filter((chain) => chain.tokens.length > 0).sort((a, b) => b.balance - a.balance);
|
|
1711
1844
|
}
|
|
1845
|
+
function resolveSelectSourceAvailableBalance(choices, options, chainName, tokenSymbol, recommended) {
|
|
1846
|
+
const chain = chainName.trim();
|
|
1847
|
+
const token = tokenSymbol.trim();
|
|
1848
|
+
if (chain && token) {
|
|
1849
|
+
const chainChoice = choices.find((c) => c.chainName === chain);
|
|
1850
|
+
const row = chainChoice?.tokens.find((t) => t.tokenSymbol === token);
|
|
1851
|
+
if (row !== void 0) return row.balance;
|
|
1852
|
+
const direct = options.find(
|
|
1853
|
+
(opt) => opt.chainName === chain && opt.tokenSymbol === token
|
|
1854
|
+
);
|
|
1855
|
+
if (direct) return parseRawBalance(direct.rawBalance, direct.decimals);
|
|
1856
|
+
return 0;
|
|
1857
|
+
}
|
|
1858
|
+
if (recommended) {
|
|
1859
|
+
const match = options.find(
|
|
1860
|
+
(opt) => opt.chainName === recommended.chainName && opt.tokenSymbol === recommended.tokenSymbol
|
|
1861
|
+
);
|
|
1862
|
+
if (match) return parseRawBalance(match.rawBalance, match.decimals);
|
|
1863
|
+
}
|
|
1864
|
+
let max = 0;
|
|
1865
|
+
for (const opt of options) {
|
|
1866
|
+
const bal = parseRawBalance(opt.rawBalance, opt.decimals);
|
|
1867
|
+
if (bal > max) max = bal;
|
|
1868
|
+
}
|
|
1869
|
+
return max;
|
|
1870
|
+
}
|
|
1712
1871
|
|
|
1713
1872
|
// src/walletFlow.ts
|
|
1714
1873
|
var MOBILE_USER_AGENT_PATTERN = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
|
|
@@ -1792,11 +1951,12 @@ function resolvePhase(state) {
|
|
|
1792
1951
|
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);
|
|
1793
1952
|
const walletPickerSwitchEligible = currentPhase.step === "wallet-picker" && currentPhase.reason === "switch" && !state.creatingTransfer && !(state.mobileFlow && state.deeplinkUri);
|
|
1794
1953
|
const missingActivePasskeyCredential = state.passkeyConfigLoaded && !state.activeCredentialId;
|
|
1795
|
-
const shouldPromptPasskeyVerification = missingActivePasskeyCredential && state.knownCredentialIds.length > 0
|
|
1954
|
+
const shouldPromptPasskeyVerification = missingActivePasskeyCredential && state.knownCredentialIds.length > 0;
|
|
1955
|
+
const guestPreauthClaimPending = state.guestPreauthAccountId != null && state.guestSessionToken != null && state.privyAuthenticated && state.activeCredentialId != null && !state.guestPreauthSetupCompletePending && !state.error;
|
|
1796
1956
|
const branchGuestSetupComplete = state.guestPreauthSetupCompletePending && state.privyReady && state.privyAuthenticated;
|
|
1797
1957
|
const branchKeepGuestPreauthPin = !branchGuestSetupComplete && guestPreauthPinsCurrentPhase;
|
|
1798
1958
|
const branchGuestPostPayLogin = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && guestPostPayLogin;
|
|
1799
|
-
const branchCompleted = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && transferCompleted && !state.verificationTarget && !needsPasskeyBootstrap;
|
|
1959
|
+
const branchCompleted = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && transferCompleted && !state.verificationTarget && !needsPasskeyBootstrap && !guestPreauthClaimPending && !state.loginRequested;
|
|
1800
1960
|
const branchFailed = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && state.transfer?.status === "FAILED";
|
|
1801
1961
|
const branchProcessing = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && (state.creatingTransfer || isTransferAwaitingCompletion(state.transfer));
|
|
1802
1962
|
const branchStandardDesktopInlineOpenWallet = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && state.standardDesktopInlineOpenWallet && state.privyAuthenticated && state.activeCredentialId != null && state.selectedAccountId != null && !state.loginRequested && !state.guestPreauthorizing;
|
|
@@ -1812,7 +1972,7 @@ function resolvePhase(state) {
|
|
|
1812
1972
|
const branchLoginRequested = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && state.loginRequested;
|
|
1813
1973
|
const branchPasskeyVerify = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && shouldPromptPasskeyVerification;
|
|
1814
1974
|
const branchPasskeyCreate = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && !branchPasskeyVerify && missingActivePasskeyCredential;
|
|
1815
|
-
const branchGuestPreauthClaiming = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && !branchPasskeyVerify && !branchPasskeyCreate &&
|
|
1975
|
+
const branchGuestPreauthClaiming = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && !branchPasskeyVerify && !branchPasskeyCreate && guestPreauthClaimPending;
|
|
1816
1976
|
const branchDataLoading = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && !branchPasskeyVerify && !branchPasskeyCreate && !branchGuestPreauthClaiming && state.loadingData && state.activeCredentialId != null && hasActiveWallet(state.accounts);
|
|
1817
1977
|
const branchWalletPickerLink = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && !branchPasskeyVerify && !branchPasskeyCreate && !branchGuestPreauthClaiming && !branchDataLoading && state.activeCredentialId != null && !hasActiveWallet(state.accounts) && !state.mobileFlow;
|
|
1818
1978
|
const branchDeposit = !branchGuestSetupComplete && !branchKeepGuestPreauthPin && !branchGuestPostPayLogin && !branchCompleted && !branchFailed && !branchProcessing && !branchKeepFundingSubflow && !branchMobileWalletSetup && !branchStandardDesktopInlineOpenWallet && !branchKeepGuestPreauthDesktopOpenWallet && !branchKeepGuestWalletSetup && !branchGuestTokenPicker && !branchKeepWalletPickerSwitch && !branchInitializingPrivy && !branchInitializingPasskeyConfig && !branchOtpVerify && !branchLoginRequested && !branchPasskeyVerify && !branchPasskeyCreate && !branchGuestPreauthClaiming && !branchDataLoading && !branchWalletPickerLink && state.activeCredentialId != null && hasActiveWallet(state.accounts) && !state.loadingData;
|
|
@@ -1983,6 +2143,7 @@ function createInitialState(config) {
|
|
|
1983
2143
|
selectedAccountId: null,
|
|
1984
2144
|
selectedWalletId: null,
|
|
1985
2145
|
selectedTokenSymbol: null,
|
|
2146
|
+
savedSelection: null,
|
|
1986
2147
|
amount: config.depositAmount != null ? config.depositAmount.toString() : "",
|
|
1987
2148
|
transfer: null,
|
|
1988
2149
|
creatingTransfer: false,
|
|
@@ -2009,7 +2170,8 @@ function createInitialState(config) {
|
|
|
2009
2170
|
standardDesktopInlineOpenWallet: false,
|
|
2010
2171
|
guestPreauthSetupCompletePending: false,
|
|
2011
2172
|
privyReady: false,
|
|
2012
|
-
privyAuthenticated: false
|
|
2173
|
+
privyAuthenticated: false,
|
|
2174
|
+
lastResumedAt: 0
|
|
2013
2175
|
};
|
|
2014
2176
|
}
|
|
2015
2177
|
function paymentReducer(state, action) {
|
|
@@ -2107,6 +2269,9 @@ function applyAction(state, action) {
|
|
|
2107
2269
|
next.mobileFlow = false;
|
|
2108
2270
|
next.deeplinkUri = null;
|
|
2109
2271
|
}
|
|
2272
|
+
if (action.resetSelectedTokenSymbol) {
|
|
2273
|
+
next.selectedTokenSymbol = null;
|
|
2274
|
+
}
|
|
2110
2275
|
return next;
|
|
2111
2276
|
}
|
|
2112
2277
|
case "DATA_LOAD_END":
|
|
@@ -2121,8 +2286,43 @@ function applyAction(state, action) {
|
|
|
2121
2286
|
next.selectedAccountId = action.defaults.accountId;
|
|
2122
2287
|
next.selectedWalletId = action.defaults.walletId;
|
|
2123
2288
|
}
|
|
2289
|
+
if (action.resetSelectedTokenSymbol) {
|
|
2290
|
+
next.selectedTokenSymbol = null;
|
|
2291
|
+
}
|
|
2124
2292
|
return next;
|
|
2125
2293
|
}
|
|
2294
|
+
case "SAVE_SELECTION":
|
|
2295
|
+
return {
|
|
2296
|
+
...state,
|
|
2297
|
+
savedSelection: {
|
|
2298
|
+
selectedProviderId: state.selectedProviderId,
|
|
2299
|
+
selectedAccountId: state.selectedAccountId,
|
|
2300
|
+
selectedWalletId: state.selectedWalletId,
|
|
2301
|
+
selectedTokenSymbol: state.selectedTokenSymbol
|
|
2302
|
+
}
|
|
2303
|
+
};
|
|
2304
|
+
case "RESTORE_SELECTION": {
|
|
2305
|
+
const snap = state.savedSelection;
|
|
2306
|
+
if (!snap) {
|
|
2307
|
+
return {
|
|
2308
|
+
...state,
|
|
2309
|
+
error: null,
|
|
2310
|
+
increasingLimit: false
|
|
2311
|
+
};
|
|
2312
|
+
}
|
|
2313
|
+
return {
|
|
2314
|
+
...state,
|
|
2315
|
+
selectedProviderId: snap.selectedProviderId,
|
|
2316
|
+
selectedAccountId: snap.selectedAccountId,
|
|
2317
|
+
selectedWalletId: snap.selectedWalletId,
|
|
2318
|
+
selectedTokenSymbol: snap.selectedTokenSymbol,
|
|
2319
|
+
savedSelection: null,
|
|
2320
|
+
error: null,
|
|
2321
|
+
increasingLimit: false
|
|
2322
|
+
};
|
|
2323
|
+
}
|
|
2324
|
+
case "DISCARD_SAVED_SELECTION":
|
|
2325
|
+
return { ...state, savedSelection: null };
|
|
2126
2326
|
// ── Source selection ──────────────────────────────────────────
|
|
2127
2327
|
case "SELECT_PROVIDER":
|
|
2128
2328
|
return {
|
|
@@ -2417,7 +2617,8 @@ function applyAction(state, action) {
|
|
|
2417
2617
|
oneTapLimitSavedDuringSetup: false,
|
|
2418
2618
|
guestPreauthorizing: false,
|
|
2419
2619
|
guestPreauthSetupCompletePending: false,
|
|
2420
|
-
standardDesktopInlineOpenWallet: false
|
|
2620
|
+
standardDesktopInlineOpenWallet: false,
|
|
2621
|
+
savedSelection: null
|
|
2421
2622
|
};
|
|
2422
2623
|
case "LOGOUT":
|
|
2423
2624
|
return {
|
|
@@ -2440,6 +2641,8 @@ function applyAction(state, action) {
|
|
|
2440
2641
|
};
|
|
2441
2642
|
case "SYNC_AMOUNT":
|
|
2442
2643
|
return { ...state, amount: action.amount };
|
|
2644
|
+
case "PAGE_RESUMED":
|
|
2645
|
+
return { ...state, lastResumedAt: Date.now() };
|
|
2443
2646
|
default:
|
|
2444
2647
|
return state;
|
|
2445
2648
|
}
|
|
@@ -2529,6 +2732,41 @@ function screenForPhase(phase) {
|
|
|
2529
2732
|
return "guest-preauth-linking";
|
|
2530
2733
|
}
|
|
2531
2734
|
}
|
|
2735
|
+
|
|
2736
|
+
// src/depositTokenSelection.ts
|
|
2737
|
+
function tokenOptionsForLinkedAccount(selectedAccount, chains) {
|
|
2738
|
+
if (!selectedAccount) return [];
|
|
2739
|
+
return selectedAccount.wallets.flatMap((w) => {
|
|
2740
|
+
const evmChainId = chains.find((c) => c.name === w.chain.name)?.commonId ?? void 0;
|
|
2741
|
+
return w.sources.filter((s) => s.balance.total.amount > 0).map((s) => ({
|
|
2742
|
+
symbol: s.token.symbol,
|
|
2743
|
+
chainName: w.chain.name,
|
|
2744
|
+
balance: s.balance.available.amount,
|
|
2745
|
+
walletId: w.id,
|
|
2746
|
+
status: s.token.status,
|
|
2747
|
+
tokenAddress: s.address,
|
|
2748
|
+
chainId: evmChainId
|
|
2749
|
+
}));
|
|
2750
|
+
});
|
|
2751
|
+
}
|
|
2752
|
+
function handleInlineTokenSelection(handlers, chains, selectedAccount, symbol, chainName, walletId) {
|
|
2753
|
+
if (walletId && selectedAccount) {
|
|
2754
|
+
const wallet = selectedAccount.wallets.find((w) => w.id === walletId);
|
|
2755
|
+
if (wallet && wallet.chain.name === chainName) {
|
|
2756
|
+
const source = wallet.sources.find((s) => s.token.symbol === symbol);
|
|
2757
|
+
const evmChainId = chains.find((c) => c.name === chainName)?.commonId ?? void 0;
|
|
2758
|
+
const authorized = !source?.token.status || source.token.status === "AUTHORIZED";
|
|
2759
|
+
if (source && !authorized && source.address && evmChainId != null) {
|
|
2760
|
+
void handlers.onAuthorizeToken(walletId, source.address, evmChainId, symbol);
|
|
2761
|
+
return;
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2764
|
+
handlers.onSelectAuthorizedToken(walletId, symbol);
|
|
2765
|
+
return;
|
|
2766
|
+
}
|
|
2767
|
+
handlers.onSelectSourceChainChange(chainName);
|
|
2768
|
+
handlers.onSetSelectSourceTokenSymbol(symbol);
|
|
2769
|
+
}
|
|
2532
2770
|
var MUTED = "#7fa4b0";
|
|
2533
2771
|
var LOGO_SIZE = 48;
|
|
2534
2772
|
function BlinkLoadingScreen() {
|
|
@@ -3522,16 +3760,33 @@ function PasskeyScreen({
|
|
|
3522
3760
|
creating,
|
|
3523
3761
|
error,
|
|
3524
3762
|
popupFallback = false,
|
|
3525
|
-
onCreatePasskeyViaPopup
|
|
3763
|
+
onCreatePasskeyViaPopup,
|
|
3764
|
+
onCreateNewPasskey,
|
|
3765
|
+
onCreateNewPasskeyViaPopup,
|
|
3766
|
+
createNewPopupFallback,
|
|
3767
|
+
creatingNewPasskey
|
|
3526
3768
|
}) {
|
|
3527
3769
|
const { tokens } = useBlinkConfig();
|
|
3528
3770
|
const handleCreate = popupFallback && onCreatePasskeyViaPopup ? onCreatePasskeyViaPopup : onCreatePasskey;
|
|
3529
3771
|
const buttonLabel = popupFallback ? "Open Passkey Window" : "Verify Passkey";
|
|
3772
|
+
const showCreateNewLink = onCreateNewPasskey != null;
|
|
3773
|
+
const usePopupForNew = createNewPopupFallback ?? popupFallback;
|
|
3774
|
+
const handleCreateNew = usePopupForNew && onCreateNewPasskeyViaPopup ? onCreateNewPasskeyViaPopup : onCreateNewPasskey;
|
|
3530
3775
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3531
3776
|
ScreenLayout,
|
|
3532
3777
|
{
|
|
3533
3778
|
footer: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3534
|
-
/* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: handleCreate, disabled: creating, loading: creating, children: buttonLabel }),
|
|
3779
|
+
/* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: handleCreate, disabled: creating || creatingNewPasskey, loading: creating, children: buttonLabel }),
|
|
3780
|
+
showCreateNewLink && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3781
|
+
"button",
|
|
3782
|
+
{
|
|
3783
|
+
type: "button",
|
|
3784
|
+
onClick: handleCreateNew,
|
|
3785
|
+
disabled: creatingNewPasskey || creating,
|
|
3786
|
+
style: createNewLinkStyle(tokens.textMuted),
|
|
3787
|
+
children: creatingNewPasskey ? "Creating passkey\u2026" : "Create a new passkey for this device"
|
|
3788
|
+
}
|
|
3789
|
+
),
|
|
3535
3790
|
/* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {})
|
|
3536
3791
|
] }),
|
|
3537
3792
|
children: [
|
|
@@ -3566,6 +3821,17 @@ var subtitleStyle3 = (color) => ({
|
|
|
3566
3821
|
margin: "0 0 20px",
|
|
3567
3822
|
lineHeight: 1.5
|
|
3568
3823
|
});
|
|
3824
|
+
var createNewLinkStyle = (color) => ({
|
|
3825
|
+
background: "none",
|
|
3826
|
+
border: "none",
|
|
3827
|
+
color,
|
|
3828
|
+
fontSize: "0.85rem",
|
|
3829
|
+
cursor: "pointer",
|
|
3830
|
+
padding: "8px 16px",
|
|
3831
|
+
textDecoration: "underline",
|
|
3832
|
+
fontFamily: "inherit",
|
|
3833
|
+
width: "100%"
|
|
3834
|
+
});
|
|
3569
3835
|
var errorBannerStyle2 = (tokens) => ({
|
|
3570
3836
|
background: tokens.errorBg,
|
|
3571
3837
|
border: `1px solid ${tokens.error}66`,
|
|
@@ -4081,6 +4347,22 @@ var loginButtonStyle = (accentColor) => ({
|
|
|
4081
4347
|
fontFamily: "inherit",
|
|
4082
4348
|
textDecoration: "underline"
|
|
4083
4349
|
});
|
|
4350
|
+
|
|
4351
|
+
// src/setupScreenSelection.ts
|
|
4352
|
+
function matchesSetupTokenSelection(opt, selectedTokenSymbol, selectedChainName, allOptions) {
|
|
4353
|
+
if (!selectedTokenSymbol || opt.symbol !== selectedTokenSymbol) {
|
|
4354
|
+
return false;
|
|
4355
|
+
}
|
|
4356
|
+
const chain = selectedChainName?.trim();
|
|
4357
|
+
if (chain) {
|
|
4358
|
+
return opt.chainName === chain;
|
|
4359
|
+
}
|
|
4360
|
+
const sameSymbol = allOptions.filter((o) => o.symbol === selectedTokenSymbol);
|
|
4361
|
+
if (sameSymbol.length === 1) {
|
|
4362
|
+
return opt.chainName === sameSymbol[0].chainName;
|
|
4363
|
+
}
|
|
4364
|
+
return false;
|
|
4365
|
+
}
|
|
4084
4366
|
var DEFAULT_MAX = 1e7;
|
|
4085
4367
|
var ABSOLUTE_MIN = 0.01;
|
|
4086
4368
|
var PRESETS = [100, 250, 1e3];
|
|
@@ -4096,13 +4378,16 @@ function SetupScreen({
|
|
|
4096
4378
|
loading,
|
|
4097
4379
|
error,
|
|
4098
4380
|
selectedTokenSymbol,
|
|
4381
|
+
selectedChainName,
|
|
4099
4382
|
tokenOptions,
|
|
4100
4383
|
onSelectToken
|
|
4101
4384
|
}) {
|
|
4102
4385
|
const { tokens } = useBlinkConfig();
|
|
4103
4386
|
const effectiveMax = DEFAULT_MAX;
|
|
4104
4387
|
const effectiveMin = Math.min(ABSOLUTE_MIN, effectiveMax);
|
|
4105
|
-
const
|
|
4388
|
+
const autoLimit = Math.min(Math.max(availableBalance, 0), effectiveMax);
|
|
4389
|
+
const [userChosenLimit, setUserChosenLimit] = react.useState(null);
|
|
4390
|
+
const limit = userChosenLimit ?? autoLimit;
|
|
4106
4391
|
const [activePreset, setActivePreset] = react.useState(null);
|
|
4107
4392
|
const [showAdvanced, setShowAdvanced] = react.useState(false);
|
|
4108
4393
|
const [editing, setEditing] = react.useState(false);
|
|
@@ -4141,20 +4426,22 @@ function SetupScreen({
|
|
|
4141
4426
|
const commitEdit = react.useCallback(() => {
|
|
4142
4427
|
const parsed = parseFloat(inputValue);
|
|
4143
4428
|
if (!isNaN(parsed)) {
|
|
4144
|
-
|
|
4429
|
+
setUserChosenLimit(
|
|
4430
|
+
Math.min(effectiveMax, Math.max(effectiveMin, Math.round(parsed * 100) / 100))
|
|
4431
|
+
);
|
|
4145
4432
|
}
|
|
4146
4433
|
setActivePreset(null);
|
|
4147
4434
|
setEditing(false);
|
|
4148
4435
|
}, [inputValue, effectiveMax, effectiveMin]);
|
|
4149
4436
|
const selectPreset = (value) => {
|
|
4150
|
-
|
|
4437
|
+
setUserChosenLimit(Math.min(value, effectiveMax));
|
|
4151
4438
|
setActivePreset(value);
|
|
4152
4439
|
};
|
|
4153
4440
|
const selectMax = () => {
|
|
4154
|
-
|
|
4441
|
+
setUserChosenLimit(autoLimit);
|
|
4155
4442
|
setActivePreset("max");
|
|
4156
4443
|
};
|
|
4157
|
-
const
|
|
4444
|
+
const options = tokenOptions ?? [];
|
|
4158
4445
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4159
4446
|
ScreenLayout,
|
|
4160
4447
|
{
|
|
@@ -4187,12 +4474,7 @@ function SetupScreen({
|
|
|
4187
4474
|
children: [
|
|
4188
4475
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenRowLabelStyle(tokens.text), children: "Token for one tap" }),
|
|
4189
4476
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenRowRightStyle, children: [
|
|
4190
|
-
|
|
4191
|
-
selectedOption.symbol,
|
|
4192
|
-
" \xB7 ",
|
|
4193
|
-
selectedOption.chainName
|
|
4194
|
-
] }),
|
|
4195
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenIconWrapStyle, children: selectedTokenSymbol && TOKEN_LOGOS[selectedTokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: TOKEN_LOGOS[selectedTokenSymbol], alt: selectedTokenSymbol, width: 36, height: 36, style: { borderRadius: "50%" } }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "36", height: "36", viewBox: "0 0 36 36", fill: "none", children: [
|
|
4477
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenIconWrapStyle, children: selectedTokenSymbol && TOKEN_LOGOS[selectedTokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: TOKEN_LOGOS[selectedTokenSymbol], alt: "", width: 36, height: 36, style: { borderRadius: "50%" } }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "36", height: "36", viewBox: "0 0 36 36", fill: "none", children: [
|
|
4196
4478
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "18", cy: "18", r: "18", fill: "#2DB84B" }),
|
|
4197
4479
|
/* @__PURE__ */ jsxRuntime.jsx("text", { x: "18", y: "23", textAnchor: "middle", fontSize: "18", fill: "#fff", fontWeight: "700", children: "$" })
|
|
4198
4480
|
] }) }),
|
|
@@ -4204,14 +4486,21 @@ function SetupScreen({
|
|
|
4204
4486
|
tokenDropdownOpen && tokenOptions && tokenOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: dropdownOuterStyle(tokens), children: [
|
|
4205
4487
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: dropdownLabelStyle(tokens.textMuted), children: "Choose token" }),
|
|
4206
4488
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: dropdownInnerStyle(tokens), children: tokenOptions.map((opt, index) => {
|
|
4207
|
-
const selected =
|
|
4489
|
+
const selected = matchesSetupTokenSelection(
|
|
4490
|
+
opt,
|
|
4491
|
+
selectedTokenSymbol,
|
|
4492
|
+
selectedChainName,
|
|
4493
|
+
options
|
|
4494
|
+
);
|
|
4208
4495
|
const isLast = index === tokenOptions.length - 1;
|
|
4496
|
+
const authorized = !opt.status || opt.status === "AUTHORIZED";
|
|
4209
4497
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4210
4498
|
"button",
|
|
4211
4499
|
{
|
|
4212
4500
|
type: "button",
|
|
4213
4501
|
onClick: () => handlePickToken(opt),
|
|
4214
4502
|
style: dropdownRowStyle(tokens, selected, isLast),
|
|
4503
|
+
"aria-label": opt.balance != null ? `${opt.symbol} on ${opt.chainName}, $${opt.balance.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })} balance${!authorized ? ", not authorized" : ""}` : `${opt.symbol} on ${opt.chainName}${!authorized ? ", not authorized" : ""}`,
|
|
4215
4504
|
children: [
|
|
4216
4505
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: dropdownRowLeftStyle, children: [
|
|
4217
4506
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: dropdownTokenIconStyle(tokens, !!TOKEN_LOGOS[opt.symbol]), children: TOKEN_LOGOS[opt.symbol] ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: TOKEN_LOGOS[opt.symbol], alt: opt.symbol, style: dropdownTokenLogoStyle }) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: dropdownTokenFallbackStyle(tokens.textMuted), children: "$" }) }),
|
|
@@ -4221,9 +4510,12 @@ function SetupScreen({
|
|
|
4221
4510
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: dropdownTokenDotStyle(tokens.textMuted), children: "\xB7" }),
|
|
4222
4511
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: dropdownTokenChainStyle(tokens.textMuted), children: opt.chainName })
|
|
4223
4512
|
] }),
|
|
4224
|
-
|
|
4225
|
-
"
|
|
4226
|
-
|
|
4513
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: dropdownTokenBalanceRowStyle, children: [
|
|
4514
|
+
opt.balance != null && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: dropdownTokenBalanceStyle(tokens.textMuted), children: [
|
|
4515
|
+
"$",
|
|
4516
|
+
opt.balance.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
|
4517
|
+
] }),
|
|
4518
|
+
!authorized && /* @__PURE__ */ jsxRuntime.jsx("span", { style: dropdownNotAuthorizedStyle(tokens.textMuted), children: "Not authorized" })
|
|
4227
4519
|
] })
|
|
4228
4520
|
] })
|
|
4229
4521
|
] }),
|
|
@@ -4343,11 +4635,6 @@ var tokenRowRightStyle = {
|
|
|
4343
4635
|
gap: 6,
|
|
4344
4636
|
flexShrink: 0
|
|
4345
4637
|
};
|
|
4346
|
-
var tokenRowSymbolStyle = (color) => ({
|
|
4347
|
-
fontSize: "0.84rem",
|
|
4348
|
-
fontWeight: 500,
|
|
4349
|
-
color
|
|
4350
|
-
});
|
|
4351
4638
|
var advancedToggleStyle = (accentColor) => ({
|
|
4352
4639
|
display: "block",
|
|
4353
4640
|
margin: "4px auto 24px",
|
|
@@ -4495,10 +4782,20 @@ var dropdownTokenChainStyle = (color) => ({
|
|
|
4495
4782
|
fontWeight: 400,
|
|
4496
4783
|
color
|
|
4497
4784
|
});
|
|
4785
|
+
var dropdownTokenBalanceRowStyle = {
|
|
4786
|
+
display: "flex",
|
|
4787
|
+
alignItems: "center",
|
|
4788
|
+
gap: 8
|
|
4789
|
+
};
|
|
4498
4790
|
var dropdownTokenBalanceStyle = (color) => ({
|
|
4499
4791
|
fontSize: "0.78rem",
|
|
4500
4792
|
color
|
|
4501
4793
|
});
|
|
4794
|
+
var dropdownNotAuthorizedStyle = (color) => ({
|
|
4795
|
+
fontSize: "0.7rem",
|
|
4796
|
+
fontWeight: 500,
|
|
4797
|
+
color
|
|
4798
|
+
});
|
|
4502
4799
|
var dropdownRadioEmptyStyle = (borderColor) => ({
|
|
4503
4800
|
width: 22,
|
|
4504
4801
|
height: 22,
|
|
@@ -4613,6 +4910,38 @@ var waitHintStyle = (color) => ({
|
|
|
4613
4910
|
color,
|
|
4614
4911
|
margin: 0
|
|
4615
4912
|
});
|
|
4913
|
+
|
|
4914
|
+
// src/feeFormat.ts
|
|
4915
|
+
function isPreciseMoneyNonPositive(fee) {
|
|
4916
|
+
const raw = fee.value.trim();
|
|
4917
|
+
if (!/^-?\d+(\.\d*)?$/.test(raw)) return false;
|
|
4918
|
+
const n = Number(raw);
|
|
4919
|
+
return Number.isFinite(n) && n <= 0;
|
|
4920
|
+
}
|
|
4921
|
+
function formatNonPositiveFeeDisplay(fee) {
|
|
4922
|
+
if (fee.currency === "USD") return "Under $0.01";
|
|
4923
|
+
return `Less than 0.01 ${fee.currency}`;
|
|
4924
|
+
}
|
|
4925
|
+
function formatPreciseMoneyForDisplay(fee) {
|
|
4926
|
+
const raw = fee.value.trim();
|
|
4927
|
+
if (fee.currency === "USD") {
|
|
4928
|
+
if (!/^\d+(\.\d*)?$/.test(raw)) {
|
|
4929
|
+
return `$${raw}`;
|
|
4930
|
+
}
|
|
4931
|
+
const [whole, frac = ""] = raw.split(".");
|
|
4932
|
+
const dec = `${frac}00`.slice(0, 2);
|
|
4933
|
+
const intFmt = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
4934
|
+
return `$${intFmt}.${dec}`;
|
|
4935
|
+
}
|
|
4936
|
+
return `${raw} ${fee.currency}`;
|
|
4937
|
+
}
|
|
4938
|
+
function formatUsdTwoDecimals(value) {
|
|
4939
|
+
const n = Number(value);
|
|
4940
|
+
return (Number.isFinite(n) ? n : 0).toLocaleString("en-US", {
|
|
4941
|
+
minimumFractionDigits: 2,
|
|
4942
|
+
maximumFractionDigits: 2
|
|
4943
|
+
});
|
|
4944
|
+
}
|
|
4616
4945
|
function DepositScreen({
|
|
4617
4946
|
merchantName,
|
|
4618
4947
|
availableBalance,
|
|
@@ -4620,6 +4949,8 @@ function DepositScreen({
|
|
|
4620
4949
|
tokenCount,
|
|
4621
4950
|
initialAmount,
|
|
4622
4951
|
minDepositFloor,
|
|
4952
|
+
quoteFee,
|
|
4953
|
+
quoteLoading,
|
|
4623
4954
|
processing,
|
|
4624
4955
|
error,
|
|
4625
4956
|
onDeposit,
|
|
@@ -4634,13 +4965,19 @@ function DepositScreen({
|
|
|
4634
4965
|
onAuthorizeAccount,
|
|
4635
4966
|
onAddProvider,
|
|
4636
4967
|
onSelectToken,
|
|
4968
|
+
tokenOptions,
|
|
4969
|
+
onPickToken,
|
|
4637
4970
|
selectedSourceLabel,
|
|
4638
|
-
selectedTokenSymbol
|
|
4971
|
+
selectedTokenSymbol,
|
|
4972
|
+
selectedChainName
|
|
4639
4973
|
}) {
|
|
4640
4974
|
const { tokens } = useBlinkConfig();
|
|
4641
4975
|
const amount = initialAmount;
|
|
4642
4976
|
const [accountPickerOpen, setAccountPickerOpen] = react.useState(false);
|
|
4977
|
+
const [tokenPickerOpen, setTokenPickerOpen] = react.useState(false);
|
|
4643
4978
|
const pickerRef = react.useRef(null);
|
|
4979
|
+
const tokenPickerRef = react.useRef(null);
|
|
4980
|
+
const hasTokenDropdown = tokenOptions != null && tokenOptions.length > 0 && onPickToken != null;
|
|
4644
4981
|
react.useEffect(() => {
|
|
4645
4982
|
if (!accountPickerOpen) return;
|
|
4646
4983
|
const handleClick = (e) => {
|
|
@@ -4651,47 +4988,129 @@ function DepositScreen({
|
|
|
4651
4988
|
document.addEventListener("mousedown", handleClick);
|
|
4652
4989
|
return () => document.removeEventListener("mousedown", handleClick);
|
|
4653
4990
|
}, [accountPickerOpen]);
|
|
4991
|
+
react.useEffect(() => {
|
|
4992
|
+
if (!tokenPickerOpen) return;
|
|
4993
|
+
const handleMouseDown = (e) => {
|
|
4994
|
+
if (tokenPickerRef.current && !tokenPickerRef.current.contains(e.target)) {
|
|
4995
|
+
setTokenPickerOpen(false);
|
|
4996
|
+
}
|
|
4997
|
+
};
|
|
4998
|
+
document.addEventListener("mousedown", handleMouseDown);
|
|
4999
|
+
return () => document.removeEventListener("mousedown", handleMouseDown);
|
|
5000
|
+
}, [tokenPickerOpen]);
|
|
5001
|
+
const handleTokenBadgeClick = react.useCallback(() => {
|
|
5002
|
+
if (hasTokenDropdown) {
|
|
5003
|
+
setTokenPickerOpen((v) => !v);
|
|
5004
|
+
setAccountPickerOpen(false);
|
|
5005
|
+
} else {
|
|
5006
|
+
onSelectToken?.();
|
|
5007
|
+
}
|
|
5008
|
+
}, [hasTokenDropdown, onSelectToken]);
|
|
5009
|
+
const handlePickToken = react.useCallback((opt) => {
|
|
5010
|
+
onPickToken?.(opt.symbol, opt.chainName, opt.walletId);
|
|
5011
|
+
setTokenPickerOpen(false);
|
|
5012
|
+
}, [onPickToken]);
|
|
4654
5013
|
const selectedAccount = accounts?.find((a) => a.id === selectedAccountId);
|
|
4655
5014
|
const selectedProviderName = selectedAccount?.name ?? "Wallet";
|
|
4656
5015
|
const selectedProviderLogo = KNOWN_LOGOS[selectedProviderName.toLowerCase()];
|
|
4657
5016
|
const totalAccountBalance = selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : availableBalance;
|
|
4658
5017
|
const isLowBalance = availableBalance < minDepositFloor;
|
|
5018
|
+
const insufficientFunds = availableBalance < amount;
|
|
4659
5019
|
const exceedsLimit = remainingLimit != null && amount > remainingLimit && !isLowBalance;
|
|
4660
|
-
const canDeposit = amount >= minDepositFloor && !exceedsLimit && !isLowBalance && !processing;
|
|
5020
|
+
const canDeposit = amount >= minDepositFloor && !exceedsLimit && !isLowBalance && !insufficientFunds && !processing;
|
|
4661
5021
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4662
5022
|
ScreenLayout,
|
|
4663
5023
|
{
|
|
4664
5024
|
footer: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4665
|
-
!accountPickerOpen && (exceedsLimit && onIncreaseLimit ? /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: onIncreaseLimit, loading: increasingLimit, children: "Increase limit" }) : /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: () => onDeposit(amount), disabled: !canDeposit, loading: processing, children: "Confirm" })),
|
|
5025
|
+
!accountPickerOpen && !tokenPickerOpen && (exceedsLimit && onIncreaseLimit ? /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: onIncreaseLimit, loading: increasingLimit, children: "Increase limit" }) : /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: () => onDeposit(amount), disabled: !canDeposit, loading: processing, children: insufficientFunds ? "Insufficient Funds" : "Confirm" })),
|
|
4666
5026
|
/* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {})
|
|
4667
5027
|
] }),
|
|
4668
5028
|
children: [
|
|
4669
5029
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack, onLogout }),
|
|
4670
5030
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { ref: pickerRef, style: depositCardWrapStyle, children: [
|
|
4671
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
5031
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: depositCardStyle(tokens), children: [
|
|
4672
5032
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: depositLabelStyle(tokens.textMuted), children: "Depositing" }),
|
|
4673
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
4674
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4675
|
-
"
|
|
4676
|
-
|
|
5033
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { ref: tokenPickerRef, children: [
|
|
5034
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: amountRowStyle, children: [
|
|
5035
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: amountValueStyle(tokens.text), children: [
|
|
5036
|
+
"$",
|
|
5037
|
+
formatUsdTwoDecimals(amount)
|
|
5038
|
+
] }),
|
|
5039
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5040
|
+
"button",
|
|
5041
|
+
{
|
|
5042
|
+
type: "button",
|
|
5043
|
+
"data-testid": "deposit-token-badge",
|
|
5044
|
+
onClick: handleTokenBadgeClick,
|
|
5045
|
+
style: tokenIconButtonStyle(hasTokenDropdown || !!onSelectToken),
|
|
5046
|
+
"aria-expanded": hasTokenDropdown ? tokenPickerOpen : void 0,
|
|
5047
|
+
"aria-haspopup": hasTokenDropdown ? "listbox" : void 0,
|
|
5048
|
+
children: [
|
|
5049
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenIconWrapStyle2, children: selectedTokenSymbol && TOKEN_LOGOS[selectedTokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: TOKEN_LOGOS[selectedTokenSymbol], alt: selectedTokenSymbol, width: 36, height: 36, style: { borderRadius: "50%" } }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "36", height: "36", viewBox: "0 0 36 36", fill: "none", children: [
|
|
5050
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "18", cy: "18", r: "18", fill: "#2DB84B" }),
|
|
5051
|
+
/* @__PURE__ */ jsxRuntime.jsx("text", { x: "18", y: "23", textAnchor: "middle", fontSize: "18", fill: "#fff", fontWeight: "700", children: "$" })
|
|
5052
|
+
] }) }),
|
|
5053
|
+
/* @__PURE__ */ jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", style: { opacity: 0.5 }, children: tokenPickerOpen ? /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 15l-6-6-6 6", stroke: tokens.textMuted, strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }) : /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 9l6 6 6-6", stroke: tokens.textMuted, strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
5054
|
+
]
|
|
5055
|
+
}
|
|
5056
|
+
)
|
|
4677
5057
|
] }),
|
|
4678
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4679
|
-
"
|
|
4680
|
-
{
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
5058
|
+
tokenPickerOpen && tokenOptions && tokenOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenDropdownStyle(tokens), children: [
|
|
5059
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenDropdownLabelStyle(tokens.textMuted), children: "Choose token" }),
|
|
5060
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenDropdownInnerStyle(tokens), children: tokenOptions.map((opt, index) => {
|
|
5061
|
+
const selected = opt.symbol === selectedTokenSymbol && (!selectedChainName || opt.chainName === selectedChainName);
|
|
5062
|
+
const isLast = index === tokenOptions.length - 1;
|
|
5063
|
+
const authorized = !opt.status || opt.status === "AUTHORIZED";
|
|
5064
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5065
|
+
"button",
|
|
5066
|
+
{
|
|
5067
|
+
type: "button",
|
|
5068
|
+
onClick: () => handlePickToken(opt),
|
|
5069
|
+
style: tokenDropdownRowStyle(tokens, selected, isLast),
|
|
5070
|
+
"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" : ""}`,
|
|
5071
|
+
children: [
|
|
5072
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenDropdownRowLeftStyle, children: [
|
|
5073
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenDropdownIconStyle(tokens, !!TOKEN_LOGOS[opt.symbol]), children: TOKEN_LOGOS[opt.symbol] ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: TOKEN_LOGOS[opt.symbol], alt: opt.symbol, style: tokenDropdownLogoStyle }) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenDropdownFallbackStyle(tokens.textMuted), children: "$" }) }),
|
|
5074
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenDropdownInfoStyle, children: [
|
|
5075
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenDropdownNameRowStyle, children: [
|
|
5076
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenDropdownSymbolStyle(tokens.text), children: opt.symbol }),
|
|
5077
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenDropdownDotStyle(tokens.textMuted), children: "\xB7" }),
|
|
5078
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenDropdownChainStyle(tokens.textMuted), children: opt.chainName })
|
|
5079
|
+
] }),
|
|
5080
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenDropdownBalanceRowStyle, children: [
|
|
5081
|
+
opt.balance != null && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: tokenDropdownBalanceStyle(tokens.textMuted), children: [
|
|
5082
|
+
"$",
|
|
5083
|
+
formatUsdTwoDecimals(opt.balance)
|
|
5084
|
+
] }),
|
|
5085
|
+
!authorized && /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenDropdownNotAuthStyle(tokens.textMuted), children: "Not authorized" })
|
|
5086
|
+
] })
|
|
5087
|
+
] })
|
|
5088
|
+
] }),
|
|
5089
|
+
selected ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "22", height: "22", viewBox: "0 0 22 22", fill: "none", children: [
|
|
5090
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "11", fill: tokens.success }),
|
|
5091
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7 11l3 3 5-5", stroke: "#fff", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
5092
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenDropdownRadioStyle(tokens.border) })
|
|
5093
|
+
]
|
|
5094
|
+
},
|
|
5095
|
+
`${opt.chainName}-${opt.symbol}`
|
|
5096
|
+
);
|
|
5097
|
+
}) })
|
|
5098
|
+
] })
|
|
4693
5099
|
] }),
|
|
4694
|
-
!accountPickerOpen &&
|
|
5100
|
+
!accountPickerOpen && !tokenPickerOpen && (() => {
|
|
5101
|
+
if (quoteLoading) {
|
|
5102
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: feeRowContainerStyle, "aria-live": "polite", children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: feeRowLabelStyle(tokens.textMuted), children: "Getting fee estimate\u2026" }) });
|
|
5103
|
+
}
|
|
5104
|
+
if (quoteFee) {
|
|
5105
|
+
const feeText = isPreciseMoneyNonPositive(quoteFee) ? formatNonPositiveFeeDisplay(quoteFee) : formatPreciseMoneyForDisplay(quoteFee);
|
|
5106
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: feeRowContainerStyle, "aria-live": "polite", children: [
|
|
5107
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: feeRowLabelStyle(tokens.textMuted), children: "Fee estimate: " }),
|
|
5108
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: feeRowAmountStyle(tokens.textSecondary), children: feeText })
|
|
5109
|
+
] });
|
|
5110
|
+
}
|
|
5111
|
+
return null;
|
|
5112
|
+
})(),
|
|
5113
|
+
!accountPickerOpen && !tokenPickerOpen && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4695
5114
|
"button",
|
|
4696
5115
|
{
|
|
4697
5116
|
type: "button",
|
|
@@ -4701,7 +5120,7 @@ function DepositScreen({
|
|
|
4701
5120
|
selectedProviderLogo ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: selectedProviderLogo, alt: selectedProviderName, style: providerLogoStyle }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: providerFallbackStyle(tokens.textMuted), children: selectedProviderName.charAt(0) }),
|
|
4702
5121
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: walletBalanceStyle(tokens.text), children: [
|
|
4703
5122
|
"$",
|
|
4704
|
-
totalAccountBalance
|
|
5123
|
+
formatUsdTwoDecimals(totalAccountBalance)
|
|
4705
5124
|
] }),
|
|
4706
5125
|
/* @__PURE__ */ jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", style: { opacity: 0.4 }, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7 10l5-5 5 5M7 14l5 5 5-5", stroke: tokens.textMuted, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
4707
5126
|
]
|
|
@@ -4742,7 +5161,7 @@ function DepositScreen({
|
|
|
4742
5161
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: accountAddressStyle(tokens.text), children: truncatedAddress ?? account.nickname ?? account.name }),
|
|
4743
5162
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: accountBalanceTextStyle(tokens.textMuted), children: [
|
|
4744
5163
|
"$",
|
|
4745
|
-
accountBalance
|
|
5164
|
+
formatUsdTwoDecimals(accountBalance)
|
|
4746
5165
|
] })
|
|
4747
5166
|
] })
|
|
4748
5167
|
] }),
|
|
@@ -4778,21 +5197,21 @@ function DepositScreen({
|
|
|
4778
5197
|
" ",
|
|
4779
5198
|
/* @__PURE__ */ jsxRuntime.jsxs("strong", { style: { color: tokens.text }, children: [
|
|
4780
5199
|
"$",
|
|
4781
|
-
remainingLimit
|
|
5200
|
+
formatUsdTwoDecimals(remainingLimit)
|
|
4782
5201
|
] }),
|
|
4783
5202
|
exceedsLimit && /* @__PURE__ */ jsxRuntime.jsxs("p", { style: limitExceededHintStyle(tokens.warning), children: [
|
|
4784
5203
|
"Your deposit of $",
|
|
4785
|
-
amount
|
|
5204
|
+
formatUsdTwoDecimals(amount),
|
|
4786
5205
|
" exceeds your One-Tap limit of $",
|
|
4787
|
-
remainingLimit
|
|
5206
|
+
remainingLimit != null ? formatUsdTwoDecimals(remainingLimit) : "0.00",
|
|
4788
5207
|
". Increase your limit to continue."
|
|
4789
5208
|
] })
|
|
4790
5209
|
] }),
|
|
4791
5210
|
!accountPickerOpen && isLowBalance && /* @__PURE__ */ jsxRuntime.jsxs(WarningBanner, { title: "Not enough funds", children: [
|
|
4792
5211
|
"Your wallet balance is $",
|
|
4793
|
-
availableBalance
|
|
5212
|
+
formatUsdTwoDecimals(availableBalance),
|
|
4794
5213
|
" \u2014 you need at least $",
|
|
4795
|
-
minDepositFloor
|
|
5214
|
+
formatUsdTwoDecimals(minDepositFloor),
|
|
4796
5215
|
" to deposit via One-Tap."
|
|
4797
5216
|
] }),
|
|
4798
5217
|
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle6(tokens), children: error })
|
|
@@ -4804,6 +5223,11 @@ var depositCardWrapStyle = {
|
|
|
4804
5223
|
position: "relative",
|
|
4805
5224
|
marginBottom: 20
|
|
4806
5225
|
};
|
|
5226
|
+
var depositCardStyle = (tokens) => ({
|
|
5227
|
+
border: `1px solid ${tokens.border}`,
|
|
5228
|
+
borderRadius: tokens.radiusLg,
|
|
5229
|
+
padding: "16px 20px"
|
|
5230
|
+
});
|
|
4807
5231
|
var depositLabelStyle = (color) => ({
|
|
4808
5232
|
fontSize: "0.75rem",
|
|
4809
5233
|
fontWeight: 500,
|
|
@@ -4837,104 +5261,214 @@ var tokenIconWrapStyle2 = {
|
|
|
4837
5261
|
width: 36,
|
|
4838
5262
|
height: 36
|
|
4839
5263
|
};
|
|
4840
|
-
var
|
|
4841
|
-
display: "flex",
|
|
4842
|
-
alignItems: "center",
|
|
4843
|
-
justifyContent: "center",
|
|
4844
|
-
gap: 8,
|
|
4845
|
-
background: "transparent",
|
|
4846
|
-
border: "none",
|
|
4847
|
-
padding: 0,
|
|
4848
|
-
width: "100%",
|
|
4849
|
-
cursor: "pointer",
|
|
4850
|
-
fontFamily: "inherit",
|
|
4851
|
-
outline: "none"
|
|
4852
|
-
};
|
|
4853
|
-
var providerLogoStyle = {
|
|
4854
|
-
width: 18,
|
|
4855
|
-
height: 18,
|
|
4856
|
-
borderRadius: "50%",
|
|
4857
|
-
objectFit: "contain"
|
|
4858
|
-
};
|
|
4859
|
-
var providerFallbackStyle = (color) => ({
|
|
4860
|
-
width: 18,
|
|
4861
|
-
height: 18,
|
|
4862
|
-
borderRadius: "50%",
|
|
4863
|
-
display: "flex",
|
|
4864
|
-
alignItems: "center",
|
|
4865
|
-
justifyContent: "center",
|
|
4866
|
-
fontSize: "0.65rem",
|
|
4867
|
-
fontWeight: 700,
|
|
4868
|
-
color,
|
|
4869
|
-
flexShrink: 0
|
|
4870
|
-
});
|
|
4871
|
-
var walletBalanceStyle = (color) => ({
|
|
4872
|
-
fontSize: "0.9rem",
|
|
4873
|
-
fontWeight: 600,
|
|
4874
|
-
color
|
|
4875
|
-
});
|
|
4876
|
-
var accountDropdownOuterStyle = (tokens) => ({
|
|
5264
|
+
var tokenDropdownStyle = (t) => ({
|
|
4877
5265
|
marginTop: 4,
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
5266
|
+
marginBottom: 12,
|
|
5267
|
+
background: t.bgCard,
|
|
5268
|
+
border: `1px solid ${t.border}`,
|
|
5269
|
+
borderRadius: t.radiusLg,
|
|
5270
|
+
boxShadow: t.shadowLg,
|
|
4882
5271
|
padding: "12px 14px 14px"
|
|
4883
5272
|
});
|
|
4884
|
-
var
|
|
5273
|
+
var tokenDropdownLabelStyle = (color) => ({
|
|
4885
5274
|
fontSize: "0.78rem",
|
|
4886
5275
|
fontWeight: 500,
|
|
4887
5276
|
color,
|
|
4888
5277
|
marginBottom: 8
|
|
4889
5278
|
});
|
|
4890
|
-
var
|
|
4891
|
-
background:
|
|
4892
|
-
border: `1px solid ${
|
|
4893
|
-
borderRadius:
|
|
5279
|
+
var tokenDropdownInnerStyle = (t) => ({
|
|
5280
|
+
background: t.bgInput,
|
|
5281
|
+
border: `1px solid ${t.border}`,
|
|
5282
|
+
borderRadius: t.radiusLg,
|
|
4894
5283
|
overflow: "hidden"
|
|
4895
5284
|
});
|
|
4896
|
-
var
|
|
5285
|
+
var tokenDropdownRowStyle = (t, isSelected, isLast) => ({
|
|
4897
5286
|
display: "flex",
|
|
4898
5287
|
alignItems: "center",
|
|
4899
5288
|
justifyContent: "space-between",
|
|
4900
5289
|
width: "100%",
|
|
4901
5290
|
padding: "14px 16px",
|
|
4902
|
-
background: isSelected ? `${
|
|
5291
|
+
background: isSelected ? `${t.accent}18` : "transparent",
|
|
4903
5292
|
border: "none",
|
|
4904
|
-
borderBottom: `1px solid ${
|
|
5293
|
+
borderBottom: isLast ? "none" : `1px solid ${t.border}`,
|
|
4905
5294
|
cursor: "pointer",
|
|
4906
5295
|
fontFamily: "inherit",
|
|
4907
5296
|
textAlign: "left",
|
|
4908
5297
|
outline: "none"
|
|
4909
5298
|
});
|
|
4910
|
-
var
|
|
5299
|
+
var tokenDropdownRowLeftStyle = {
|
|
4911
5300
|
display: "flex",
|
|
4912
5301
|
alignItems: "center",
|
|
4913
5302
|
gap: 12,
|
|
4914
5303
|
minWidth: 0,
|
|
4915
5304
|
flex: 1
|
|
4916
5305
|
};
|
|
4917
|
-
var
|
|
4918
|
-
width:
|
|
4919
|
-
height:
|
|
4920
|
-
borderRadius: "50%",
|
|
4921
|
-
objectFit: "contain",
|
|
4922
|
-
flexShrink: 0
|
|
4923
|
-
};
|
|
4924
|
-
var accountFallbackIconStyle = (color) => ({
|
|
4925
|
-
width: 28,
|
|
4926
|
-
height: 28,
|
|
5306
|
+
var tokenDropdownIconStyle = (t, hasLogo) => ({
|
|
5307
|
+
width: 36,
|
|
5308
|
+
height: 36,
|
|
4927
5309
|
borderRadius: "50%",
|
|
5310
|
+
border: hasLogo ? "none" : `1.5px solid ${t.border}`,
|
|
4928
5311
|
display: "flex",
|
|
4929
5312
|
alignItems: "center",
|
|
4930
5313
|
justifyContent: "center",
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
color,
|
|
4934
|
-
flexShrink: 0
|
|
5314
|
+
flexShrink: 0,
|
|
5315
|
+
overflow: "hidden"
|
|
4935
5316
|
});
|
|
4936
|
-
var
|
|
4937
|
-
|
|
5317
|
+
var tokenDropdownLogoStyle = {
|
|
5318
|
+
width: 36,
|
|
5319
|
+
height: 36,
|
|
5320
|
+
borderRadius: "50%",
|
|
5321
|
+
objectFit: "cover"
|
|
5322
|
+
};
|
|
5323
|
+
var tokenDropdownFallbackStyle = (color) => ({
|
|
5324
|
+
fontSize: "1rem",
|
|
5325
|
+
fontWeight: 700,
|
|
5326
|
+
color
|
|
5327
|
+
});
|
|
5328
|
+
var tokenDropdownInfoStyle = {
|
|
5329
|
+
display: "flex",
|
|
5330
|
+
flexDirection: "column",
|
|
5331
|
+
gap: 2,
|
|
5332
|
+
minWidth: 0
|
|
5333
|
+
};
|
|
5334
|
+
var tokenDropdownNameRowStyle = {
|
|
5335
|
+
display: "flex",
|
|
5336
|
+
alignItems: "center",
|
|
5337
|
+
gap: 4
|
|
5338
|
+
};
|
|
5339
|
+
var tokenDropdownSymbolStyle = (color) => ({
|
|
5340
|
+
fontSize: "0.92rem",
|
|
5341
|
+
fontWeight: 600,
|
|
5342
|
+
color
|
|
5343
|
+
});
|
|
5344
|
+
var tokenDropdownDotStyle = (color) => ({
|
|
5345
|
+
fontSize: "0.8rem",
|
|
5346
|
+
color
|
|
5347
|
+
});
|
|
5348
|
+
var tokenDropdownChainStyle = (color) => ({
|
|
5349
|
+
fontSize: "0.84rem",
|
|
5350
|
+
fontWeight: 400,
|
|
5351
|
+
color
|
|
5352
|
+
});
|
|
5353
|
+
var tokenDropdownBalanceRowStyle = {
|
|
5354
|
+
display: "flex",
|
|
5355
|
+
alignItems: "center",
|
|
5356
|
+
gap: 8
|
|
5357
|
+
};
|
|
5358
|
+
var tokenDropdownBalanceStyle = (color) => ({
|
|
5359
|
+
fontSize: "0.78rem",
|
|
5360
|
+
color
|
|
5361
|
+
});
|
|
5362
|
+
var tokenDropdownNotAuthStyle = (color) => ({
|
|
5363
|
+
fontSize: "0.7rem",
|
|
5364
|
+
fontWeight: 500,
|
|
5365
|
+
color
|
|
5366
|
+
});
|
|
5367
|
+
var tokenDropdownRadioStyle = (borderColor) => ({
|
|
5368
|
+
width: 22,
|
|
5369
|
+
height: 22,
|
|
5370
|
+
borderRadius: "50%",
|
|
5371
|
+
border: `2px solid ${borderColor}`,
|
|
5372
|
+
flexShrink: 0
|
|
5373
|
+
});
|
|
5374
|
+
var walletBalanceRowStyle = {
|
|
5375
|
+
display: "flex",
|
|
5376
|
+
alignItems: "center",
|
|
5377
|
+
justifyContent: "center",
|
|
5378
|
+
gap: 8,
|
|
5379
|
+
background: "transparent",
|
|
5380
|
+
border: "none",
|
|
5381
|
+
padding: 0,
|
|
5382
|
+
width: "100%",
|
|
5383
|
+
cursor: "pointer",
|
|
5384
|
+
fontFamily: "inherit",
|
|
5385
|
+
outline: "none"
|
|
5386
|
+
};
|
|
5387
|
+
var providerLogoStyle = {
|
|
5388
|
+
width: 18,
|
|
5389
|
+
height: 18,
|
|
5390
|
+
borderRadius: "50%",
|
|
5391
|
+
objectFit: "contain"
|
|
5392
|
+
};
|
|
5393
|
+
var providerFallbackStyle = (color) => ({
|
|
5394
|
+
width: 18,
|
|
5395
|
+
height: 18,
|
|
5396
|
+
borderRadius: "50%",
|
|
5397
|
+
display: "flex",
|
|
5398
|
+
alignItems: "center",
|
|
5399
|
+
justifyContent: "center",
|
|
5400
|
+
fontSize: "0.65rem",
|
|
5401
|
+
fontWeight: 700,
|
|
5402
|
+
color,
|
|
5403
|
+
flexShrink: 0
|
|
5404
|
+
});
|
|
5405
|
+
var walletBalanceStyle = (color) => ({
|
|
5406
|
+
fontSize: "0.9rem",
|
|
5407
|
+
fontWeight: 600,
|
|
5408
|
+
color
|
|
5409
|
+
});
|
|
5410
|
+
var accountDropdownOuterStyle = (tokens) => ({
|
|
5411
|
+
marginTop: 4,
|
|
5412
|
+
background: tokens.bgCard,
|
|
5413
|
+
border: `1px solid ${tokens.border}`,
|
|
5414
|
+
borderRadius: tokens.radiusLg,
|
|
5415
|
+
boxShadow: tokens.shadowLg,
|
|
5416
|
+
padding: "12px 14px 14px"
|
|
5417
|
+
});
|
|
5418
|
+
var accountDropdownLabelStyle = (color) => ({
|
|
5419
|
+
fontSize: "0.78rem",
|
|
5420
|
+
fontWeight: 500,
|
|
5421
|
+
color,
|
|
5422
|
+
marginBottom: 8
|
|
5423
|
+
});
|
|
5424
|
+
var accountDropdownInnerStyle = (tokens) => ({
|
|
5425
|
+
background: tokens.bgInput,
|
|
5426
|
+
border: `1px solid ${tokens.border}`,
|
|
5427
|
+
borderRadius: tokens.radiusLg,
|
|
5428
|
+
overflow: "hidden"
|
|
5429
|
+
});
|
|
5430
|
+
var accountRowStyle = (tokens, isSelected) => ({
|
|
5431
|
+
display: "flex",
|
|
5432
|
+
alignItems: "center",
|
|
5433
|
+
justifyContent: "space-between",
|
|
5434
|
+
width: "100%",
|
|
5435
|
+
padding: "14px 16px",
|
|
5436
|
+
background: isSelected ? `${tokens.accent}10` : "transparent",
|
|
5437
|
+
border: "none",
|
|
5438
|
+
borderBottom: `1px solid ${tokens.border}`,
|
|
5439
|
+
cursor: "pointer",
|
|
5440
|
+
fontFamily: "inherit",
|
|
5441
|
+
textAlign: "left",
|
|
5442
|
+
outline: "none"
|
|
5443
|
+
});
|
|
5444
|
+
var accountRowLeftStyle = {
|
|
5445
|
+
display: "flex",
|
|
5446
|
+
alignItems: "center",
|
|
5447
|
+
gap: 12,
|
|
5448
|
+
minWidth: 0,
|
|
5449
|
+
flex: 1
|
|
5450
|
+
};
|
|
5451
|
+
var accountLogoStyle = {
|
|
5452
|
+
width: 28,
|
|
5453
|
+
height: 28,
|
|
5454
|
+
borderRadius: "50%",
|
|
5455
|
+
objectFit: "contain",
|
|
5456
|
+
flexShrink: 0
|
|
5457
|
+
};
|
|
5458
|
+
var accountFallbackIconStyle = (color) => ({
|
|
5459
|
+
width: 28,
|
|
5460
|
+
height: 28,
|
|
5461
|
+
borderRadius: "50%",
|
|
5462
|
+
display: "flex",
|
|
5463
|
+
alignItems: "center",
|
|
5464
|
+
justifyContent: "center",
|
|
5465
|
+
fontSize: "0.75rem",
|
|
5466
|
+
fontWeight: 700,
|
|
5467
|
+
color,
|
|
5468
|
+
flexShrink: 0
|
|
5469
|
+
});
|
|
5470
|
+
var accountInfoStyle = {
|
|
5471
|
+
display: "flex",
|
|
4938
5472
|
flexDirection: "column",
|
|
4939
5473
|
gap: 2,
|
|
4940
5474
|
minWidth: 0
|
|
@@ -4998,9 +5532,20 @@ var limitExceededHintStyle = (color) => ({
|
|
|
4998
5532
|
margin: "12px 0 2px",
|
|
4999
5533
|
lineHeight: 1.5
|
|
5000
5534
|
});
|
|
5535
|
+
var feeRowContainerStyle = {
|
|
5536
|
+
fontSize: "0.84rem",
|
|
5537
|
+
fontWeight: 500,
|
|
5538
|
+
marginTop: 6,
|
|
5539
|
+
marginBottom: 4
|
|
5540
|
+
};
|
|
5541
|
+
var feeRowLabelStyle = (color) => ({ color });
|
|
5542
|
+
var feeRowAmountStyle = (color) => ({
|
|
5543
|
+
color,
|
|
5544
|
+
fontVariantNumeric: "tabular-nums"
|
|
5545
|
+
});
|
|
5001
5546
|
function SuccessScreen({
|
|
5002
5547
|
amount,
|
|
5003
|
-
currency,
|
|
5548
|
+
currency: _currency,
|
|
5004
5549
|
succeeded,
|
|
5005
5550
|
error,
|
|
5006
5551
|
merchantName,
|
|
@@ -5013,22 +5558,30 @@ function SuccessScreen({
|
|
|
5013
5558
|
onPreauthorize
|
|
5014
5559
|
}) {
|
|
5015
5560
|
const { tokens } = useBlinkConfig();
|
|
5561
|
+
const isGuestDepositSuccess = succeeded && onPreauthorize != null;
|
|
5016
5562
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5017
5563
|
ScreenLayout,
|
|
5018
5564
|
{
|
|
5019
5565
|
footer: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5020
|
-
|
|
5021
|
-
/* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: onPreauthorize, children: "
|
|
5022
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: onDone, style: skipButtonStyle(tokens.textMuted), children: "
|
|
5566
|
+
isGuestDepositSuccess ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5567
|
+
/* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: onPreauthorize, children: "Set up one tap" }),
|
|
5568
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: onDone, style: skipButtonStyle(tokens.textMuted), children: "Return to app" })
|
|
5023
5569
|
] }) : /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: onDone, children: succeeded ? "Done" : "Try again" }),
|
|
5024
5570
|
onManageAccount && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: onManageAccount, style: manageStyle(tokens.textMuted), children: "Manage Blink account \u2192" }),
|
|
5025
5571
|
/* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {})
|
|
5026
5572
|
] }),
|
|
5027
5573
|
children: [
|
|
5028
5574
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
|
|
5029
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
5030
|
-
|
|
5031
|
-
/* @__PURE__ */ jsxRuntime.
|
|
5575
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: screenContentStyle, children: [
|
|
5576
|
+
isGuestDepositSuccess ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyleCompact, children: [
|
|
5577
|
+
/* @__PURE__ */ jsxRuntime.jsxs("h2", { style: headingStyle7(tokens.text), children: [
|
|
5578
|
+
"$",
|
|
5579
|
+
amount.toFixed(2),
|
|
5580
|
+
" deposited"
|
|
5581
|
+
] }),
|
|
5582
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { ...subtitleStyle7(tokens.text), fontWeight: 600, margin: "0 0 8px" }, children: "Next time, do it in one tap" }),
|
|
5583
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle7(tokens.textSecondary), children: "Set up one tap for this wallet and skip the extra steps." })
|
|
5584
|
+
] }) : succeeded ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyleCompact, children: [
|
|
5032
5585
|
/* @__PURE__ */ jsxRuntime.jsxs("h2", { style: headingStyle7(tokens.text), children: [
|
|
5033
5586
|
"$",
|
|
5034
5587
|
amount.toFixed(2),
|
|
@@ -5040,10 +5593,10 @@ function SuccessScreen({
|
|
|
5040
5593
|
] })
|
|
5041
5594
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5042
5595
|
/* @__PURE__ */ jsxRuntime.jsx(IconCircle, { variant: "error", size: 64, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z", fill: tokens.error }) }) }),
|
|
5043
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { style:
|
|
5044
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("p", { style:
|
|
5596
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: failureHeadingStyle(tokens.text), children: "Transfer failed" }),
|
|
5597
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: failureSubtitleStyle(tokens.error), children: error })
|
|
5045
5598
|
] }),
|
|
5046
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryCardStyle(tokens), children: [
|
|
5599
|
+
!isGuestDepositSuccess && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryCardStyle(tokens), children: [
|
|
5047
5600
|
sourceName && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryRowStyle, children: [
|
|
5048
5601
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: summaryLabelStyle(tokens.textMuted), children: "From" }),
|
|
5049
5602
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: summaryValueStyle(tokens.text), children: sourceName })
|
|
@@ -5060,7 +5613,7 @@ function SuccessScreen({
|
|
|
5060
5613
|
] })
|
|
5061
5614
|
] })
|
|
5062
5615
|
] }),
|
|
5063
|
-
succeeded && onIncreaseLimits && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: upsellCardStyle(tokens), children: [
|
|
5616
|
+
succeeded && onIncreaseLimits && !isGuestDepositSuccess && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: upsellCardStyle(tokens), children: [
|
|
5064
5617
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: upsellHeaderStyle, children: [
|
|
5065
5618
|
/* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { marginRight: 6 }, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7 14l5-5 5 5", stroke: tokens.accent, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
|
|
5066
5619
|
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Want higher limits?" })
|
|
@@ -5073,21 +5626,42 @@ function SuccessScreen({
|
|
|
5073
5626
|
}
|
|
5074
5627
|
);
|
|
5075
5628
|
}
|
|
5076
|
-
var
|
|
5629
|
+
var screenContentStyle = {
|
|
5077
5630
|
flex: 1,
|
|
5078
5631
|
display: "flex",
|
|
5079
5632
|
flexDirection: "column",
|
|
5080
5633
|
alignItems: "center",
|
|
5081
5634
|
paddingTop: 16
|
|
5082
5635
|
};
|
|
5636
|
+
var contentStyleCompact = {
|
|
5637
|
+
textAlign: "center",
|
|
5638
|
+
display: "flex",
|
|
5639
|
+
flexDirection: "column",
|
|
5640
|
+
alignItems: "center",
|
|
5641
|
+
width: "100%"
|
|
5642
|
+
};
|
|
5083
5643
|
var headingStyle7 = (color) => ({
|
|
5644
|
+
fontSize: "1.45rem",
|
|
5645
|
+
fontWeight: 700,
|
|
5646
|
+
letterSpacing: "-0.02em",
|
|
5647
|
+
color,
|
|
5648
|
+
margin: "20px 0 8px"
|
|
5649
|
+
});
|
|
5650
|
+
var subtitleStyle7 = (color) => ({
|
|
5651
|
+
fontSize: "0.9rem",
|
|
5652
|
+
color,
|
|
5653
|
+
margin: "0 0 28px",
|
|
5654
|
+
lineHeight: 1.5,
|
|
5655
|
+
maxWidth: 280
|
|
5656
|
+
});
|
|
5657
|
+
var failureHeadingStyle = (color) => ({
|
|
5084
5658
|
fontSize: "1.5rem",
|
|
5085
5659
|
fontWeight: 700,
|
|
5086
5660
|
letterSpacing: "-0.02em",
|
|
5087
5661
|
color,
|
|
5088
5662
|
margin: "20px 0 4px"
|
|
5089
5663
|
});
|
|
5090
|
-
var
|
|
5664
|
+
var failureSubtitleStyle = (color) => ({
|
|
5091
5665
|
fontSize: "0.9rem",
|
|
5092
5666
|
color,
|
|
5093
5667
|
margin: "0 0 20px"
|
|
@@ -5603,7 +6177,7 @@ function TransferStatusScreen({
|
|
|
5603
6177
|
const steps = buildSteps(phase);
|
|
5604
6178
|
return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { footer: /* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {}), children: [
|
|
5605
6179
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
|
|
5606
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
6180
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle6, children: [
|
|
5607
6181
|
/* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 64 }),
|
|
5608
6182
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle9(tokens.text), children: "Depositing your money..." }),
|
|
5609
6183
|
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle7(tokens), children: error }),
|
|
@@ -5611,7 +6185,7 @@ function TransferStatusScreen({
|
|
|
5611
6185
|
] })
|
|
5612
6186
|
] });
|
|
5613
6187
|
}
|
|
5614
|
-
var
|
|
6188
|
+
var contentStyle6 = {
|
|
5615
6189
|
flex: 1,
|
|
5616
6190
|
display: "flex",
|
|
5617
6191
|
flexDirection: "column",
|
|
@@ -5681,7 +6255,7 @@ function OpenWalletScreen({
|
|
|
5681
6255
|
] }),
|
|
5682
6256
|
children: [
|
|
5683
6257
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
|
|
5684
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
6258
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle7, children: [
|
|
5685
6259
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: logoCircleStyle(tokens.bgInput), children: logoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoSrc, alt: displayName, style: logoStyle2 }) : /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 32 }) }),
|
|
5686
6260
|
/* @__PURE__ */ jsxRuntime.jsxs("h2", { style: headingStyle10(tokens.text), children: [
|
|
5687
6261
|
"Setting up ",
|
|
@@ -5714,7 +6288,7 @@ function OpenWalletScreen({
|
|
|
5714
6288
|
] }),
|
|
5715
6289
|
children: [
|
|
5716
6290
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack, onLogout }),
|
|
5717
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
6291
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle7, children: [
|
|
5718
6292
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: logoCircleStyle(tokens.bgInput), children: logoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoSrc, alt: displayName, style: logoStyle2 }) : /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 32 }) }),
|
|
5719
6293
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle10(tokens.text), children: loading ? "Connecting..." : `Open ${displayName}` }),
|
|
5720
6294
|
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle10(tokens.textSecondary), children: loading ? "Creating transfer and preparing your wallet link..." : `Continue in ${displayName} to authorize this connection.` }),
|
|
@@ -5727,7 +6301,7 @@ function OpenWalletScreen({
|
|
|
5727
6301
|
}
|
|
5728
6302
|
);
|
|
5729
6303
|
}
|
|
5730
|
-
var
|
|
6304
|
+
var contentStyle7 = {
|
|
5731
6305
|
flex: 1,
|
|
5732
6306
|
display: "flex",
|
|
5733
6307
|
flexDirection: "column",
|
|
@@ -5813,7 +6387,7 @@ function ConfirmSignScreen({
|
|
|
5813
6387
|
] }),
|
|
5814
6388
|
children: [
|
|
5815
6389
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
|
|
5816
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
6390
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle8, children: [
|
|
5817
6391
|
logoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoSrc, alt: displayName, style: logoStyle3 }) : /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 48 }),
|
|
5818
6392
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle11(tokens.text), children: "Wallet authorized" }),
|
|
5819
6393
|
/* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle11(tokens.textSecondary), children: [
|
|
@@ -5829,7 +6403,7 @@ function ConfirmSignScreen({
|
|
|
5829
6403
|
}
|
|
5830
6404
|
);
|
|
5831
6405
|
}
|
|
5832
|
-
var
|
|
6406
|
+
var contentStyle8 = {
|
|
5833
6407
|
flex: 1,
|
|
5834
6408
|
display: "flex",
|
|
5835
6409
|
flexDirection: "column",
|
|
@@ -6124,29 +6698,6 @@ var selectCircleSelectedStyle = (color) => ({
|
|
|
6124
6698
|
function entryKey(entry) {
|
|
6125
6699
|
return `${entry.sourceChainId}-${entry.tokenAddress.toLowerCase()}`;
|
|
6126
6700
|
}
|
|
6127
|
-
function isPreciseMoneyNonPositive(fee) {
|
|
6128
|
-
const raw = fee.value.trim();
|
|
6129
|
-
if (!/^-?\d+(\.\d*)?$/.test(raw)) return false;
|
|
6130
|
-
const n = Number(raw);
|
|
6131
|
-
return Number.isFinite(n) && n <= 0;
|
|
6132
|
-
}
|
|
6133
|
-
function formatNonPositiveFeeDisplay(fee) {
|
|
6134
|
-
if (fee.currency === "USD") return "Under $0.01";
|
|
6135
|
-
return `Less than 0.01 ${fee.currency}`;
|
|
6136
|
-
}
|
|
6137
|
-
function formatPreciseMoneyForDisplay(fee) {
|
|
6138
|
-
const raw = fee.value.trim();
|
|
6139
|
-
if (fee.currency === "USD") {
|
|
6140
|
-
if (!/^\d+(\.\d*)?$/.test(raw)) {
|
|
6141
|
-
return `$${raw}`;
|
|
6142
|
-
}
|
|
6143
|
-
const [whole, frac = ""] = raw.split(".");
|
|
6144
|
-
const dec = `${frac}00`.slice(0, 2);
|
|
6145
|
-
const intFmt = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
6146
|
-
return `$${intFmt}.${dec}`;
|
|
6147
|
-
}
|
|
6148
|
-
return `${raw} ${fee.currency}`;
|
|
6149
|
-
}
|
|
6150
6701
|
function GuestTokenPickerScreen({
|
|
6151
6702
|
entries,
|
|
6152
6703
|
loading,
|
|
@@ -6186,13 +6737,13 @@ function GuestTokenPickerScreen({
|
|
|
6186
6737
|
const canConfirm = Boolean(quoteFee && pendingEntry && !quoteLoading);
|
|
6187
6738
|
const feeLine = (() => {
|
|
6188
6739
|
if (quoteLoading && pendingEntry) {
|
|
6189
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
6740
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: feeRowContainerStyle2, "aria-live": "polite", children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: feeRowLabelStyle2(t.textMuted), children: "Getting fee estimate\u2026" }) });
|
|
6190
6741
|
}
|
|
6191
6742
|
if (quoteFee) {
|
|
6192
6743
|
const feeText = isPreciseMoneyNonPositive(quoteFee) ? formatNonPositiveFeeDisplay(quoteFee) : formatPreciseMoneyForDisplay(quoteFee);
|
|
6193
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
6194
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
6195
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
6744
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: feeRowContainerStyle2, "aria-live": "polite", children: [
|
|
6745
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: feeRowLabelStyle2(t.textMuted), children: "Fee estimate: " }),
|
|
6746
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: feeRowAmountStyle2(t.textSecondary), children: feeText })
|
|
6196
6747
|
] });
|
|
6197
6748
|
}
|
|
6198
6749
|
return null;
|
|
@@ -6214,7 +6765,7 @@ function GuestTokenPickerScreen({
|
|
|
6214
6765
|
depositAmount != null && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: depositAmountStyle2(t.text), children: [
|
|
6215
6766
|
"$",
|
|
6216
6767
|
depositAmount.toLocaleString("en-US", {
|
|
6217
|
-
minimumFractionDigits:
|
|
6768
|
+
minimumFractionDigits: 2,
|
|
6218
6769
|
maximumFractionDigits: 2
|
|
6219
6770
|
})
|
|
6220
6771
|
] }),
|
|
@@ -6296,7 +6847,7 @@ function GuestTokenPickerScreen({
|
|
|
6296
6847
|
] }),
|
|
6297
6848
|
tokenListOpen && entries.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenDropdownOuterStyle(t), children: [
|
|
6298
6849
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: accountDropdownLabelStyle2(t.textMuted), children: "Choose token" }),
|
|
6299
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
6850
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenDropdownInnerStyle2(t), children: entries.map((entry, index) => {
|
|
6300
6851
|
const selected = pendingKey === entryKey(entry);
|
|
6301
6852
|
const isLast = index === entries.length - 1;
|
|
6302
6853
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -6397,13 +6948,13 @@ var depositAmountStyle2 = (color) => ({
|
|
|
6397
6948
|
color,
|
|
6398
6949
|
lineHeight: 1.05
|
|
6399
6950
|
});
|
|
6400
|
-
var
|
|
6951
|
+
var feeRowContainerStyle2 = {
|
|
6401
6952
|
fontSize: "0.84rem",
|
|
6402
6953
|
fontWeight: 500,
|
|
6403
6954
|
marginTop: 6
|
|
6404
6955
|
};
|
|
6405
|
-
var
|
|
6406
|
-
var
|
|
6956
|
+
var feeRowLabelStyle2 = (color) => ({ color });
|
|
6957
|
+
var feeRowAmountStyle2 = (color) => ({
|
|
6407
6958
|
color,
|
|
6408
6959
|
fontVariantNumeric: "tabular-nums"
|
|
6409
6960
|
});
|
|
@@ -6449,7 +7000,7 @@ var accountDropdownLabelStyle2 = (color) => ({
|
|
|
6449
7000
|
color,
|
|
6450
7001
|
marginBottom: 8
|
|
6451
7002
|
});
|
|
6452
|
-
var
|
|
7003
|
+
var tokenDropdownInnerStyle2 = (tokens) => ({
|
|
6453
7004
|
background: tokens.bgInput,
|
|
6454
7005
|
border: `1px solid ${tokens.border}`,
|
|
6455
7006
|
borderRadius: tokens.radiusLg,
|
|
@@ -6561,7 +7112,7 @@ function GuestPreauthSetupCompleteScreen({
|
|
|
6561
7112
|
] }),
|
|
6562
7113
|
children: [
|
|
6563
7114
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
|
|
6564
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
7115
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle9, children: [
|
|
6565
7116
|
/* @__PURE__ */ jsxRuntime.jsx(IconCircle, { variant: "success", size: 64, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6566
7117
|
"path",
|
|
6567
7118
|
{
|
|
@@ -6570,13 +7121,13 @@ function GuestPreauthSetupCompleteScreen({
|
|
|
6570
7121
|
}
|
|
6571
7122
|
) }) }),
|
|
6572
7123
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle12(tokens.text), children: "Setup complete" }),
|
|
6573
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle12(tokens.textSecondary), children: "Your account is linked and ready. You can close this window
|
|
7124
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle12(tokens.textSecondary), children: "Your account is linked and ready. You can close this window." })
|
|
6574
7125
|
] })
|
|
6575
7126
|
]
|
|
6576
7127
|
}
|
|
6577
7128
|
);
|
|
6578
7129
|
}
|
|
6579
|
-
var
|
|
7130
|
+
var contentStyle9 = {
|
|
6580
7131
|
display: "flex",
|
|
6581
7132
|
flexDirection: "column",
|
|
6582
7133
|
alignItems: "center",
|
|
@@ -6605,14 +7156,14 @@ function GuestPreauthLinkingScreen({ onLogout }) {
|
|
|
6605
7156
|
const { tokens } = useBlinkConfig();
|
|
6606
7157
|
return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { children: [
|
|
6607
7158
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
|
|
6608
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
7159
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle10, children: [
|
|
6609
7160
|
/* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 48 }),
|
|
6610
7161
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle13(tokens.text), children: "Setting up your account..." }),
|
|
6611
7162
|
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle13(tokens.textSecondary), children: "Linking your wallet to your Blink account. This usually takes a few seconds." })
|
|
6612
7163
|
] })
|
|
6613
7164
|
] });
|
|
6614
7165
|
}
|
|
6615
|
-
var
|
|
7166
|
+
var contentStyle10 = {
|
|
6616
7167
|
flex: 1,
|
|
6617
7168
|
display: "flex",
|
|
6618
7169
|
flexDirection: "column",
|
|
@@ -6789,13 +7340,15 @@ function StepRendererContent({
|
|
|
6789
7340
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6790
7341
|
PasskeyScreen,
|
|
6791
7342
|
{
|
|
6792
|
-
onCreatePasskey: handlers.
|
|
7343
|
+
onCreatePasskey: handlers.onVerifyPasskey,
|
|
6793
7344
|
onBack: handlers.onLogout,
|
|
6794
7345
|
onLogout: handlers.onLogout,
|
|
6795
|
-
creating: state.
|
|
7346
|
+
creating: state.registeringPasskey,
|
|
6796
7347
|
error: state.error,
|
|
6797
|
-
|
|
6798
|
-
|
|
7348
|
+
onCreateNewPasskey: handlers.onCreateNewPasskey,
|
|
7349
|
+
onCreateNewPasskeyViaPopup: handlers.onCreateNewPasskeyViaPopup,
|
|
7350
|
+
createNewPopupFallback: state.passkeyPopupNeeded,
|
|
7351
|
+
creatingNewPasskey: state.registeringPasskey
|
|
6799
7352
|
}
|
|
6800
7353
|
);
|
|
6801
7354
|
case "wallet-picker": {
|
|
@@ -6852,15 +7405,11 @@ function StepRendererContent({
|
|
|
6852
7405
|
0
|
|
6853
7406
|
);
|
|
6854
7407
|
const effectiveTokenCount = tokenCount > 0 ? tokenCount : selectSourceTokenCount;
|
|
6855
|
-
const
|
|
6856
|
-
const
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
balance: s.balance.available.amount,
|
|
6861
|
-
walletId: w.id
|
|
6862
|
-
}))
|
|
6863
|
-
) : selectSourceChoices.flatMap(
|
|
7408
|
+
const setupFromPendingSelectSource = pendingSelectSource != null;
|
|
7409
|
+
const setupSelectedTokenSymbol = setupFromPendingSelectSource ? selectSourceTokenSymbol || selectSourceRecommended?.tokenSymbol || "" : selectedSource?.token.symbol ?? selectSourceTokenSymbol;
|
|
7410
|
+
const setupSelectedChainName = setupFromPendingSelectSource ? selectSourceChainName || selectSourceRecommended?.chainName || "" : selectedWallet?.chain.name ?? selectSourceChainName;
|
|
7411
|
+
const effectiveSourceLabel = setupFromPendingSelectSource ? setupSelectedTokenSymbol && setupSelectedChainName ? `${setupSelectedTokenSymbol} on ${setupSelectedChainName}` : void 0 : selectedSourceLabel ?? (selectSourceChainName && selectSourceTokenSymbol ? `${selectSourceTokenSymbol} on ${selectSourceChainName}` : void 0);
|
|
7412
|
+
const setupTokenOptions = selectedAccount ? tokenOptionsForLinkedAccount(selectedAccount, state.chains) : selectSourceChoices.flatMap(
|
|
6864
7413
|
(chain) => chain.tokens.map((t) => ({
|
|
6865
7414
|
symbol: t.tokenSymbol,
|
|
6866
7415
|
chainName: chain.chainName,
|
|
@@ -6868,9 +7417,8 @@ function StepRendererContent({
|
|
|
6868
7417
|
}))
|
|
6869
7418
|
);
|
|
6870
7419
|
const handleSetupSelectToken = (symbol, chainName, walletId) => {
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
} else {
|
|
7420
|
+
handleInlineTokenSelection(handlers, state.chains, selectedAccount, symbol, chainName, walletId);
|
|
7421
|
+
if (pendingSelectSource) {
|
|
6874
7422
|
handlers.onSelectSourceChainChange(chainName);
|
|
6875
7423
|
handlers.onSetSelectSourceTokenSymbol(symbol);
|
|
6876
7424
|
}
|
|
@@ -6878,17 +7426,18 @@ function StepRendererContent({
|
|
|
6878
7426
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6879
7427
|
SetupScreen,
|
|
6880
7428
|
{
|
|
6881
|
-
availableBalance: selectedSource ? selectedSource.balance.available.amount : selectSourceAvailableBalance > 0 ? selectSourceAvailableBalance : selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : maxSourceBalance,
|
|
7429
|
+
availableBalance: selectedSource ? selectedSource.balance.available.amount : setupFromPendingSelectSource ? selectSourceAvailableBalance : selectSourceAvailableBalance > 0 ? selectSourceAvailableBalance : selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : maxSourceBalance,
|
|
6882
7430
|
tokenCount: effectiveTokenCount,
|
|
6883
7431
|
sourceName,
|
|
6884
7432
|
onSetupOneTap: handlers.onSetupOneTap,
|
|
6885
|
-
onBack:
|
|
7433
|
+
onBack: handlers.onBackFromSubflow,
|
|
6886
7434
|
onLogout: handlers.onLogout,
|
|
6887
7435
|
onAdvanced: handlers.onSelectToken,
|
|
6888
7436
|
selectedSourceLabel: effectiveSourceLabel,
|
|
6889
7437
|
loading: savingOneTapLimit,
|
|
6890
7438
|
error: state.error,
|
|
6891
|
-
selectedTokenSymbol:
|
|
7439
|
+
selectedTokenSymbol: setupSelectedTokenSymbol,
|
|
7440
|
+
selectedChainName: setupSelectedChainName,
|
|
6892
7441
|
tokenOptions: setupTokenOptions,
|
|
6893
7442
|
onSelectToken: handleSetupSelectToken
|
|
6894
7443
|
}
|
|
@@ -6910,6 +7459,7 @@ function StepRendererContent({
|
|
|
6910
7459
|
case "deposit": {
|
|
6911
7460
|
const parsedAmt = depositAmount != null ? depositAmount : 5;
|
|
6912
7461
|
const minDepositFloor = depositAmount != null ? depositAmount : DEFAULT_MIN_DEPOSIT_USD;
|
|
7462
|
+
const depositTokenOptions = tokenOptionsForLinkedAccount(selectedAccount, state.chains);
|
|
6913
7463
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6914
7464
|
DepositScreen,
|
|
6915
7465
|
{
|
|
@@ -6918,6 +7468,8 @@ function StepRendererContent({
|
|
|
6918
7468
|
remainingLimit: selectedSource != null ? selectedSource.remainingAllowance ?? null : selectedAccount?.remainingAllowance ?? null,
|
|
6919
7469
|
tokenCount,
|
|
6920
7470
|
initialAmount: parsedAmt,
|
|
7471
|
+
quoteFee: forms.depositQuoteFee,
|
|
7472
|
+
quoteLoading: forms.depositQuoteLoading,
|
|
6921
7473
|
processing: state.creatingTransfer,
|
|
6922
7474
|
error: state.error,
|
|
6923
7475
|
onDeposit: handlers.onPay,
|
|
@@ -6932,8 +7484,13 @@ function StepRendererContent({
|
|
|
6932
7484
|
onAuthorizeAccount: handlers.onContinueConnection,
|
|
6933
7485
|
onAddProvider: () => handlers.onSetPhase({ step: "wallet-picker", reason: "switch" }),
|
|
6934
7486
|
onSelectToken: handlers.onSelectToken,
|
|
7487
|
+
tokenOptions: depositTokenOptions,
|
|
7488
|
+
onPickToken: (symbol, chainName, walletId) => {
|
|
7489
|
+
handleInlineTokenSelection(handlers, state.chains, selectedAccount, symbol, chainName, walletId);
|
|
7490
|
+
},
|
|
6935
7491
|
selectedSourceLabel,
|
|
6936
7492
|
selectedTokenSymbol: selectedSource?.token.symbol,
|
|
7493
|
+
selectedChainName: selectedWallet?.chain.name,
|
|
6937
7494
|
minDepositFloor
|
|
6938
7495
|
}
|
|
6939
7496
|
);
|
|
@@ -6974,7 +7531,7 @@ function StepRendererContent({
|
|
|
6974
7531
|
chains: state.chains,
|
|
6975
7532
|
onSelectAuthorized: handlers.onSelectAuthorizedToken,
|
|
6976
7533
|
onAuthorizeToken: handlers.onAuthorizeToken,
|
|
6977
|
-
onBack:
|
|
7534
|
+
onBack: handlers.onBackFromSubflow,
|
|
6978
7535
|
onLogout: handlers.onLogout,
|
|
6979
7536
|
depositAmount: depositAmount ?? void 0,
|
|
6980
7537
|
selectedTokenSymbol: selectedSource?.token.symbol,
|
|
@@ -7053,7 +7610,7 @@ function StepRendererContent({
|
|
|
7053
7610
|
})() : void 0,
|
|
7054
7611
|
onDone: onDismiss ?? handlers.onNewPayment,
|
|
7055
7612
|
onLogout: authenticated ? handlers.onLogout : void 0,
|
|
7056
|
-
onPreauthorize: state.isGuestFlow ? handlers.onPreauthorize : void 0
|
|
7613
|
+
onPreauthorize: state.isGuestFlow && isDesktop ? handlers.onPreauthorize : void 0
|
|
7057
7614
|
}
|
|
7058
7615
|
);
|
|
7059
7616
|
}
|
|
@@ -7341,6 +7898,53 @@ function usePasskeyHandlers(dispatch, apiBaseUrl, accounts, knownCredentialIds)
|
|
|
7341
7898
|
dispatch({ type: "SET_REGISTERING_PASSKEY", value: false });
|
|
7342
7899
|
}
|
|
7343
7900
|
}, [user, knownCredentialIds, activateExistingCredential, completePasskeyRegistration, dispatch]);
|
|
7901
|
+
const handleVerifyPasskey = react.useCallback(async () => {
|
|
7902
|
+
dispatch({ type: "SET_REGISTERING_PASSKEY", value: true });
|
|
7903
|
+
dispatch({ type: "SET_ERROR", error: null });
|
|
7904
|
+
try {
|
|
7905
|
+
const matched = await findDevicePasskey(knownCredentialIds);
|
|
7906
|
+
if (matched) {
|
|
7907
|
+
await activateExistingCredential(matched);
|
|
7908
|
+
} else {
|
|
7909
|
+
dispatch({
|
|
7910
|
+
type: "SET_ERROR",
|
|
7911
|
+
error: "No matching passkey found on this device. Please try again."
|
|
7912
|
+
});
|
|
7913
|
+
}
|
|
7914
|
+
} catch (err) {
|
|
7915
|
+
captureException(err);
|
|
7916
|
+
dispatch({
|
|
7917
|
+
type: "SET_ERROR",
|
|
7918
|
+
error: err instanceof Error ? err.message : "Passkey verification failed."
|
|
7919
|
+
});
|
|
7920
|
+
} finally {
|
|
7921
|
+
dispatch({ type: "SET_REGISTERING_PASSKEY", value: false });
|
|
7922
|
+
}
|
|
7923
|
+
}, [knownCredentialIds, activateExistingCredential, dispatch]);
|
|
7924
|
+
const handleCreateNewPasskey = react.useCallback(async () => {
|
|
7925
|
+
dispatch({ type: "SET_REGISTERING_PASSKEY", value: true });
|
|
7926
|
+
dispatch({ type: "SET_ERROR", error: null });
|
|
7927
|
+
try {
|
|
7928
|
+
const passkeyDisplayName = user?.email?.address ?? user?.google?.name ?? user?.id ?? "Blink User";
|
|
7929
|
+
const { credentialId, publicKey } = await createPasskeyCredential({
|
|
7930
|
+
userId: user?.id ?? "unknown",
|
|
7931
|
+
displayName: passkeyDisplayName
|
|
7932
|
+
});
|
|
7933
|
+
await completePasskeyRegistration(credentialId, publicKey);
|
|
7934
|
+
} catch (err) {
|
|
7935
|
+
if (err instanceof PasskeyIframeBlockedError) {
|
|
7936
|
+
dispatch({ type: "SET_PASSKEY_POPUP_NEEDED", needed: true });
|
|
7937
|
+
} else {
|
|
7938
|
+
captureException(err);
|
|
7939
|
+
dispatch({
|
|
7940
|
+
type: "SET_ERROR",
|
|
7941
|
+
error: err instanceof Error ? err.message : "Failed to register passkey"
|
|
7942
|
+
});
|
|
7943
|
+
}
|
|
7944
|
+
} finally {
|
|
7945
|
+
dispatch({ type: "SET_REGISTERING_PASSKEY", value: false });
|
|
7946
|
+
}
|
|
7947
|
+
}, [user, completePasskeyRegistration, dispatch]);
|
|
7344
7948
|
const handleCreatePasskeyViaPopup = react.useCallback(async () => {
|
|
7345
7949
|
dispatch({ type: "SET_REGISTERING_PASSKEY", value: true });
|
|
7346
7950
|
dispatch({ type: "SET_ERROR", error: null });
|
|
@@ -7387,6 +7991,35 @@ function usePasskeyHandlers(dispatch, apiBaseUrl, accounts, knownCredentialIds)
|
|
|
7387
7991
|
dispatch({ type: "SET_REGISTERING_PASSKEY", value: false });
|
|
7388
7992
|
}
|
|
7389
7993
|
}, [user, knownCredentialIds, getAccessToken, apiBaseUrl, activateExistingCredential, dispatch]);
|
|
7994
|
+
const handleCreateNewPasskeyViaPopup = react.useCallback(async () => {
|
|
7995
|
+
dispatch({ type: "SET_REGISTERING_PASSKEY", value: true });
|
|
7996
|
+
dispatch({ type: "SET_ERROR", error: null });
|
|
7997
|
+
try {
|
|
7998
|
+
const token = await getAccessToken();
|
|
7999
|
+
const passkeyDisplayName = user?.email?.address ?? user?.google?.name ?? user?.id ?? "Blink User";
|
|
8000
|
+
const popupOptions = buildPasskeyPopupOptions({
|
|
8001
|
+
userId: user?.id ?? "unknown",
|
|
8002
|
+
displayName: passkeyDisplayName,
|
|
8003
|
+
authToken: token ?? void 0,
|
|
8004
|
+
apiBaseUrl
|
|
8005
|
+
});
|
|
8006
|
+
const { credentialId, publicKey } = await createPasskeyViaPopup(popupOptions);
|
|
8007
|
+
dispatch({ type: "PASSKEY_ACTIVATED", credentialId, publicKey });
|
|
8008
|
+
localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, credentialId);
|
|
8009
|
+
if (token) {
|
|
8010
|
+
reportPasskeyActivity(apiBaseUrl, token, credentialId).catch(() => {
|
|
8011
|
+
});
|
|
8012
|
+
}
|
|
8013
|
+
} catch (err) {
|
|
8014
|
+
captureException(err);
|
|
8015
|
+
dispatch({
|
|
8016
|
+
type: "SET_ERROR",
|
|
8017
|
+
error: err instanceof Error ? err.message : "Failed to register passkey"
|
|
8018
|
+
});
|
|
8019
|
+
} finally {
|
|
8020
|
+
dispatch({ type: "SET_REGISTERING_PASSKEY", value: false });
|
|
8021
|
+
}
|
|
8022
|
+
}, [user, getAccessToken, apiBaseUrl, dispatch]);
|
|
7390
8023
|
const handleVerifyPasskeyViaPopup = react.useCallback(async () => {
|
|
7391
8024
|
dispatch({ type: "SET_VERIFYING_PASSKEY", value: true });
|
|
7392
8025
|
dispatch({ type: "SET_ERROR", error: null });
|
|
@@ -7429,7 +8062,10 @@ function usePasskeyHandlers(dispatch, apiBaseUrl, accounts, knownCredentialIds)
|
|
|
7429
8062
|
}, [knownCredentialIds, getAccessToken, apiBaseUrl, dispatch]);
|
|
7430
8063
|
return {
|
|
7431
8064
|
handleRegisterPasskey,
|
|
8065
|
+
handleVerifyPasskey,
|
|
8066
|
+
handleCreateNewPasskey,
|
|
7432
8067
|
handleCreatePasskeyViaPopup,
|
|
8068
|
+
handleCreateNewPasskeyViaPopup,
|
|
7433
8069
|
handleVerifyPasskeyViaPopup,
|
|
7434
8070
|
checkingPasskeyRef
|
|
7435
8071
|
};
|
|
@@ -7452,6 +8088,9 @@ function useTransferHandlers(deps) {
|
|
|
7452
8088
|
sourceTokenAddress,
|
|
7453
8089
|
activeCredentialId,
|
|
7454
8090
|
selectedAccountId,
|
|
8091
|
+
selectedWalletId,
|
|
8092
|
+
selectedTokenSymbol,
|
|
8093
|
+
quoteId,
|
|
7455
8094
|
transfer,
|
|
7456
8095
|
accounts
|
|
7457
8096
|
} = deps;
|
|
@@ -7465,9 +8104,32 @@ function useTransferHandlers(deps) {
|
|
|
7465
8104
|
fetchProviders(apiBaseUrl, token)
|
|
7466
8105
|
]);
|
|
7467
8106
|
const parsedAmt = depositAmount != null ? depositAmount : 0;
|
|
7468
|
-
const defaults =
|
|
7469
|
-
|
|
7470
|
-
|
|
8107
|
+
const { defaults, resetSelectedTokenSymbol } = resolveDepositSelectionAfterRefresh(
|
|
8108
|
+
accts,
|
|
8109
|
+
parsedAmt,
|
|
8110
|
+
{
|
|
8111
|
+
selectedAccountId,
|
|
8112
|
+
selectedWalletId,
|
|
8113
|
+
selectedTokenSymbol
|
|
8114
|
+
}
|
|
8115
|
+
);
|
|
8116
|
+
dispatch({
|
|
8117
|
+
type: "ACCOUNTS_RELOADED",
|
|
8118
|
+
accounts: accts,
|
|
8119
|
+
providers: prov,
|
|
8120
|
+
defaults,
|
|
8121
|
+
resetSelectedTokenSymbol
|
|
8122
|
+
});
|
|
8123
|
+
}, [
|
|
8124
|
+
getAccessToken,
|
|
8125
|
+
activeCredentialId,
|
|
8126
|
+
selectedAccountId,
|
|
8127
|
+
selectedWalletId,
|
|
8128
|
+
selectedTokenSymbol,
|
|
8129
|
+
apiBaseUrl,
|
|
8130
|
+
depositAmount,
|
|
8131
|
+
dispatch
|
|
8132
|
+
]);
|
|
7471
8133
|
const handlePay = react.useCallback(async (payAmount, sourceOverrides) => {
|
|
7472
8134
|
const minUsd = effectiveMinTransferAmountUsd(depositAmount);
|
|
7473
8135
|
if (isNaN(payAmount) || payAmount < minUsd) {
|
|
@@ -7511,7 +8173,8 @@ function useTransferHandlers(deps) {
|
|
|
7511
8173
|
sourceId: effectiveSourceId,
|
|
7512
8174
|
sourceTokenAddress,
|
|
7513
8175
|
destination,
|
|
7514
|
-
amount: payAmount
|
|
8176
|
+
amount: payAmount,
|
|
8177
|
+
...quoteId ? { quoteId } : {}
|
|
7515
8178
|
});
|
|
7516
8179
|
dispatch({ type: "TRANSFER_CREATED", transfer: t });
|
|
7517
8180
|
if (t.status === "COMPLETED") {
|
|
@@ -7543,6 +8206,7 @@ function useTransferHandlers(deps) {
|
|
|
7543
8206
|
accounts,
|
|
7544
8207
|
destination,
|
|
7545
8208
|
apiBaseUrl,
|
|
8209
|
+
quoteId,
|
|
7546
8210
|
getAccessToken,
|
|
7547
8211
|
transferSigning,
|
|
7548
8212
|
polling,
|
|
@@ -7593,20 +8257,20 @@ function useSourceSelectionHandlers(dispatch, authExecutor, options) {
|
|
|
7593
8257
|
const selectSourceAvailableBalance = react.useMemo(() => {
|
|
7594
8258
|
if (!pendingSelectSourceAction) return 0;
|
|
7595
8259
|
const options2 = pendingSelectSourceAction.metadata?.options ?? [];
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
8260
|
+
return resolveSelectSourceAvailableBalance(
|
|
8261
|
+
selectSourceChoices,
|
|
8262
|
+
options2,
|
|
8263
|
+
selectSourceChainName,
|
|
8264
|
+
selectSourceTokenSymbol,
|
|
8265
|
+
selectSourceRecommended
|
|
8266
|
+
);
|
|
8267
|
+
}, [
|
|
8268
|
+
pendingSelectSourceAction,
|
|
8269
|
+
selectSourceChoices,
|
|
8270
|
+
selectSourceChainName,
|
|
8271
|
+
selectSourceTokenSymbol,
|
|
8272
|
+
selectSourceRecommended
|
|
8273
|
+
]);
|
|
7610
8274
|
const handleSelectSourceChainChange = react.useCallback(
|
|
7611
8275
|
(chainName) => {
|
|
7612
8276
|
setSelectSourceChainName(chainName);
|
|
@@ -7657,7 +8321,7 @@ function useSourceSelectionHandlers(dispatch, authExecutor, options) {
|
|
|
7657
8321
|
initializedSelectSourceActionRef
|
|
7658
8322
|
};
|
|
7659
8323
|
}
|
|
7660
|
-
function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransferIdRef, stateTransfer, refs, guestCheckout, onComplete) {
|
|
8324
|
+
function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransferIdRef, stateTransfer, refs, guestCheckout, onComplete, lastResumedAt) {
|
|
7661
8325
|
const {
|
|
7662
8326
|
mobileSetupFlowRef,
|
|
7663
8327
|
handlingMobileReturnRef,
|
|
@@ -7668,6 +8332,8 @@ function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransfe
|
|
|
7668
8332
|
onCompleteRef.current = onComplete;
|
|
7669
8333
|
const guestPollingActiveRef = react.useRef(false);
|
|
7670
8334
|
const guestPollingCleanupRef = react.useRef(null);
|
|
8335
|
+
const mobileFlowRef = react.useRef(guestCheckout.mobileFlow);
|
|
8336
|
+
mobileFlowRef.current = guestCheckout.mobileFlow;
|
|
7671
8337
|
const guestTransferIdRef = react.useRef(guestCheckout.guestTransferId);
|
|
7672
8338
|
guestTransferIdRef.current = guestCheckout.guestTransferId;
|
|
7673
8339
|
const guestSessionTokenRef = react.useRef(guestCheckout.guestSessionToken);
|
|
@@ -7723,27 +8389,15 @@ function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransfe
|
|
|
7723
8389
|
startGuestPolling
|
|
7724
8390
|
]);
|
|
7725
8391
|
react.useEffect(() => {
|
|
7726
|
-
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
}
|
|
7734
|
-
|
|
7735
|
-
if (document.visibilityState === "visible") tryStartPolling();
|
|
7736
|
-
};
|
|
7737
|
-
const handlePageShow = (e) => {
|
|
7738
|
-
if (e.persisted) tryStartPolling();
|
|
7739
|
-
};
|
|
7740
|
-
document.addEventListener("visibilitychange", handleVisibility);
|
|
7741
|
-
window.addEventListener("pageshow", handlePageShow);
|
|
7742
|
-
return () => {
|
|
7743
|
-
document.removeEventListener("visibilitychange", handleVisibility);
|
|
7744
|
-
window.removeEventListener("pageshow", handlePageShow);
|
|
7745
|
-
};
|
|
7746
|
-
}, [startGuestPolling]);
|
|
8392
|
+
if (!lastResumedAt) return;
|
|
8393
|
+
if (guestPollingActiveRef.current) return;
|
|
8394
|
+
if (!mobileFlowRef.current) return;
|
|
8395
|
+
const transferId = guestTransferIdRef.current;
|
|
8396
|
+
const token = guestSessionTokenRef.current;
|
|
8397
|
+
if (transferId && token) {
|
|
8398
|
+
startGuestPolling(transferId, token);
|
|
8399
|
+
}
|
|
8400
|
+
}, [lastResumedAt, startGuestPolling]);
|
|
7747
8401
|
const handleAuthorizedMobileReturn = react.useCallback(async (authorizedTransfer, isSetup) => {
|
|
7748
8402
|
if (handlingMobileReturnRef.current) return;
|
|
7749
8403
|
handlingMobileReturnRef.current = true;
|
|
@@ -7977,6 +8631,9 @@ function useProviderHandlers(deps) {
|
|
|
7977
8631
|
await reloadAccounts();
|
|
7978
8632
|
}
|
|
7979
8633
|
} catch (err) {
|
|
8634
|
+
if (isAuthorizationSessionCancelled(err) || isUserDismissedAuthorizationError(err)) {
|
|
8635
|
+
return;
|
|
8636
|
+
}
|
|
7980
8637
|
captureException(err);
|
|
7981
8638
|
const msg = err instanceof Error ? err.message : "Failed to set up wallet";
|
|
7982
8639
|
dispatch({ type: "PAY_ERROR", error: msg });
|
|
@@ -8043,7 +8700,12 @@ function useProviderHandlers(deps) {
|
|
|
8043
8700
|
}
|
|
8044
8701
|
const acct = accounts.find((a) => a.id === selectedAccountId);
|
|
8045
8702
|
const matchedProvider = acct ? providers.find((p) => p.name === acct.name) : void 0;
|
|
8046
|
-
|
|
8703
|
+
const isMobile = !shouldUseWalletConnector({
|
|
8704
|
+
useWalletConnector: useWalletConnectorProp,
|
|
8705
|
+
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8706
|
+
});
|
|
8707
|
+
if (matchedProvider && isMobile) {
|
|
8708
|
+
dispatch({ type: "SAVE_SELECTION" });
|
|
8047
8709
|
dispatch({ type: "SELECT_PROVIDER", providerId: matchedProvider.id });
|
|
8048
8710
|
}
|
|
8049
8711
|
dispatch({ type: "SET_ERROR", error: null });
|
|
@@ -8063,10 +8725,6 @@ function useProviderHandlers(deps) {
|
|
|
8063
8725
|
activeCredentialId,
|
|
8064
8726
|
{ tokenAddress: source?.address, chainId: evmChainId }
|
|
8065
8727
|
);
|
|
8066
|
-
const isMobile = !shouldUseWalletConnector({
|
|
8067
|
-
useWalletConnector: useWalletConnectorProp,
|
|
8068
|
-
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8069
|
-
});
|
|
8070
8728
|
if (isMobile) {
|
|
8071
8729
|
handlingMobileReturnRef.current = false;
|
|
8072
8730
|
mobileSetupFlowRef.current = true;
|
|
@@ -8083,12 +8741,20 @@ function useProviderHandlers(deps) {
|
|
|
8083
8741
|
});
|
|
8084
8742
|
dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
|
|
8085
8743
|
triggerDeeplink(session.uri);
|
|
8744
|
+
dispatch({ type: "DISCARD_SAVED_SELECTION" });
|
|
8086
8745
|
} else {
|
|
8087
8746
|
await authExecutor.executeSessionById(session.id);
|
|
8088
8747
|
await reloadAccounts();
|
|
8748
|
+
dispatch({ type: "DISCARD_SAVED_SELECTION" });
|
|
8089
8749
|
}
|
|
8090
8750
|
} catch (err) {
|
|
8751
|
+
if (isAuthorizationSessionCancelled(err) || isUserDismissedAuthorizationError(err)) {
|
|
8752
|
+
return;
|
|
8753
|
+
}
|
|
8091
8754
|
captureException(err);
|
|
8755
|
+
if (isMobile) {
|
|
8756
|
+
dispatch({ type: "RESTORE_SELECTION" });
|
|
8757
|
+
}
|
|
8092
8758
|
const msg = err instanceof Error ? err.message : "Failed to increase limit";
|
|
8093
8759
|
dispatch({ type: "SET_ERROR", error: msg });
|
|
8094
8760
|
onError?.(msg);
|
|
@@ -8133,7 +8799,12 @@ function useProviderHandlers(deps) {
|
|
|
8133
8799
|
}
|
|
8134
8800
|
const acct = accounts.find((a) => a.id === selectedAccountId);
|
|
8135
8801
|
const matchedProvider = acct ? providers.find((p) => p.name === acct.name) : void 0;
|
|
8136
|
-
|
|
8802
|
+
const isMobile = !shouldUseWalletConnector({
|
|
8803
|
+
useWalletConnector: useWalletConnectorProp,
|
|
8804
|
+
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8805
|
+
});
|
|
8806
|
+
if (matchedProvider && isMobile) {
|
|
8807
|
+
dispatch({ type: "SAVE_SELECTION" });
|
|
8137
8808
|
dispatch({ type: "SELECT_PROVIDER", providerId: matchedProvider.id });
|
|
8138
8809
|
}
|
|
8139
8810
|
dispatch({ type: "SET_ERROR", error: null });
|
|
@@ -8148,10 +8819,6 @@ function useProviderHandlers(deps) {
|
|
|
8148
8819
|
activeCredentialId,
|
|
8149
8820
|
{ tokenAddress, chainId }
|
|
8150
8821
|
);
|
|
8151
|
-
const isMobile = !shouldUseWalletConnector({
|
|
8152
|
-
useWalletConnector: useWalletConnectorProp,
|
|
8153
|
-
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8154
|
-
});
|
|
8155
8822
|
if (isMobile) {
|
|
8156
8823
|
handlingMobileReturnRef.current = false;
|
|
8157
8824
|
mobileSetupFlowRef.current = true;
|
|
@@ -8169,13 +8836,21 @@ function useProviderHandlers(deps) {
|
|
|
8169
8836
|
});
|
|
8170
8837
|
dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
|
|
8171
8838
|
triggerDeeplink(session.uri);
|
|
8839
|
+
dispatch({ type: "DISCARD_SAVED_SELECTION" });
|
|
8172
8840
|
} else {
|
|
8173
8841
|
await authExecutor.executeSessionById(session.id);
|
|
8174
8842
|
await reloadAccounts();
|
|
8175
8843
|
dispatch({ type: "SELECT_TOKEN", walletId: _walletId, tokenSymbol });
|
|
8844
|
+
dispatch({ type: "DISCARD_SAVED_SELECTION" });
|
|
8176
8845
|
}
|
|
8177
8846
|
} catch (err) {
|
|
8847
|
+
if (isAuthorizationSessionCancelled(err) || isUserDismissedAuthorizationError(err)) {
|
|
8848
|
+
return;
|
|
8849
|
+
}
|
|
8178
8850
|
captureException(err);
|
|
8851
|
+
if (isMobile) {
|
|
8852
|
+
dispatch({ type: "RESTORE_SELECTION" });
|
|
8853
|
+
}
|
|
8179
8854
|
const msg = err instanceof Error ? err.message : "Failed to authorize token";
|
|
8180
8855
|
dispatch({ type: "SET_ERROR", error: msg });
|
|
8181
8856
|
onError?.(msg);
|
|
@@ -9008,28 +9683,6 @@ function usePasskeyCheckEffect(deps) {
|
|
|
9008
9683
|
await restoreState(activeCredentialId, token);
|
|
9009
9684
|
return;
|
|
9010
9685
|
}
|
|
9011
|
-
if (cancelled) return;
|
|
9012
|
-
const credentialIds = allPasskeys.map((p) => p.credentialId);
|
|
9013
|
-
let matched = null;
|
|
9014
|
-
if (isSafari() && isInCrossOriginIframe()) {
|
|
9015
|
-
matched = await findDevicePasskeyViaPopup({
|
|
9016
|
-
credentialIds,
|
|
9017
|
-
rpId: resolvePasskeyRpId(),
|
|
9018
|
-
authToken: token ?? void 0,
|
|
9019
|
-
apiBaseUrl
|
|
9020
|
-
});
|
|
9021
|
-
} else {
|
|
9022
|
-
matched = await findDevicePasskey(credentialIds);
|
|
9023
|
-
}
|
|
9024
|
-
if (cancelled) return;
|
|
9025
|
-
if (matched) {
|
|
9026
|
-
const publicKey = allPasskeys.find((p) => p.credentialId === matched)?.publicKey;
|
|
9027
|
-
dispatch({ type: "PASSKEY_ACTIVATED", credentialId: matched, publicKey });
|
|
9028
|
-
window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, matched);
|
|
9029
|
-
reportPasskeyActivity(apiBaseUrl, token, matched).catch(() => {
|
|
9030
|
-
});
|
|
9031
|
-
await restoreState(matched, token);
|
|
9032
|
-
}
|
|
9033
9686
|
} catch (err) {
|
|
9034
9687
|
dispatch({
|
|
9035
9688
|
type: "PASSKEY_CONFIG_LOADED",
|
|
@@ -9112,7 +9765,15 @@ function useDataLoadEffect(deps) {
|
|
|
9112
9765
|
]);
|
|
9113
9766
|
if (cancelled) return;
|
|
9114
9767
|
const parsedAmt = depositAmount != null ? depositAmount : 0;
|
|
9115
|
-
const defaults =
|
|
9768
|
+
const { defaults, resetSelectedTokenSymbol } = resolveDepositSelectionAfterRefresh(
|
|
9769
|
+
accts,
|
|
9770
|
+
parsedAmt,
|
|
9771
|
+
{
|
|
9772
|
+
selectedAccountId: state.selectedAccountId,
|
|
9773
|
+
selectedWalletId: state.selectedWalletId,
|
|
9774
|
+
selectedTokenSymbol: state.selectedTokenSymbol
|
|
9775
|
+
}
|
|
9776
|
+
);
|
|
9116
9777
|
const persisted = loadMobileFlowState();
|
|
9117
9778
|
const clearMobile = persisted?.isSetup && accts.some((a) => a.wallets.some((w) => w.status === "ACTIVE"));
|
|
9118
9779
|
dispatch({
|
|
@@ -9121,7 +9782,8 @@ function useDataLoadEffect(deps) {
|
|
|
9121
9782
|
accounts: accts,
|
|
9122
9783
|
chains: chn,
|
|
9123
9784
|
defaults,
|
|
9124
|
-
clearMobileState: clearMobile
|
|
9785
|
+
clearMobileState: clearMobile,
|
|
9786
|
+
resetSelectedTokenSymbol
|
|
9125
9787
|
});
|
|
9126
9788
|
if (clearMobile) clearMobileFlowState();
|
|
9127
9789
|
} catch (err) {
|
|
@@ -9150,6 +9812,8 @@ function useDataLoadEffect(deps) {
|
|
|
9150
9812
|
apiBaseUrl,
|
|
9151
9813
|
state.activeCredentialId,
|
|
9152
9814
|
state.selectedAccountId,
|
|
9815
|
+
state.selectedWalletId,
|
|
9816
|
+
state.selectedTokenSymbol,
|
|
9153
9817
|
depositAmount
|
|
9154
9818
|
]);
|
|
9155
9819
|
react.useEffect(() => {
|
|
@@ -9378,25 +10042,16 @@ function useMobilePollingEffect(deps) {
|
|
|
9378
10042
|
const poll = isReauth ? pollReauthorization : pollWalletActive;
|
|
9379
10043
|
poll();
|
|
9380
10044
|
const intervalId = window.setInterval(poll, POLL_INTERVAL_MS);
|
|
9381
|
-
const handleVisibility = () => {
|
|
9382
|
-
if (document.visibilityState === "visible" && !cancelled) poll();
|
|
9383
|
-
};
|
|
9384
|
-
const handlePageShow = (e) => {
|
|
9385
|
-
if (e.persisted && !cancelled) poll();
|
|
9386
|
-
};
|
|
9387
|
-
document.addEventListener("visibilitychange", handleVisibility);
|
|
9388
|
-
window.addEventListener("pageshow", handlePageShow);
|
|
9389
10045
|
return () => {
|
|
9390
10046
|
cancelled = true;
|
|
9391
10047
|
window.clearInterval(intervalId);
|
|
9392
|
-
document.removeEventListener("visibilitychange", handleVisibility);
|
|
9393
|
-
window.removeEventListener("pageshow", handlePageShow);
|
|
9394
10048
|
};
|
|
9395
10049
|
}, [
|
|
9396
10050
|
state.mobileFlow,
|
|
9397
10051
|
state.isGuestFlow,
|
|
9398
10052
|
state.guestPreauthSessionId,
|
|
9399
10053
|
state.activeCredentialId,
|
|
10054
|
+
state.lastResumedAt,
|
|
9400
10055
|
apiBaseUrl,
|
|
9401
10056
|
reloadAccounts,
|
|
9402
10057
|
dispatch,
|
|
@@ -9413,28 +10068,13 @@ function useMobilePollingEffect(deps) {
|
|
|
9413
10068
|
const transferIdToResume = pollingTransferIdRef.current ?? state.transfer?.id;
|
|
9414
10069
|
if (!transferIdToResume) return;
|
|
9415
10070
|
if (!polling.isPolling) polling.startPolling(transferIdToResume);
|
|
9416
|
-
const handleVisibility = () => {
|
|
9417
|
-
if (document.visibilityState === "visible" && !handlingMobileReturnRef.current) {
|
|
9418
|
-
polling.startPolling(transferIdToResume);
|
|
9419
|
-
}
|
|
9420
|
-
};
|
|
9421
|
-
const handlePageShow = (e) => {
|
|
9422
|
-
if (e.persisted && !handlingMobileReturnRef.current) {
|
|
9423
|
-
polling.startPolling(transferIdToResume);
|
|
9424
|
-
}
|
|
9425
|
-
};
|
|
9426
|
-
document.addEventListener("visibilitychange", handleVisibility);
|
|
9427
|
-
window.addEventListener("pageshow", handlePageShow);
|
|
9428
|
-
return () => {
|
|
9429
|
-
document.removeEventListener("visibilitychange", handleVisibility);
|
|
9430
|
-
window.removeEventListener("pageshow", handlePageShow);
|
|
9431
|
-
};
|
|
9432
10071
|
}, [
|
|
9433
10072
|
state.mobileFlow,
|
|
9434
10073
|
state.transfer?.id,
|
|
9435
10074
|
state.isGuestFlow,
|
|
9436
10075
|
state.guestPreauthSessionId,
|
|
9437
10076
|
state.guestPreauthAccountId,
|
|
10077
|
+
state.lastResumedAt,
|
|
9438
10078
|
polling.isPolling,
|
|
9439
10079
|
polling.startPolling,
|
|
9440
10080
|
handlingMobileReturnRef,
|
|
@@ -9445,6 +10085,7 @@ function useGuestPreauthMobileRestoreEffect(deps) {
|
|
|
9445
10085
|
const {
|
|
9446
10086
|
dispatch,
|
|
9447
10087
|
privyReady,
|
|
10088
|
+
lastResumedAt,
|
|
9448
10089
|
mobileSetupFlowRef,
|
|
9449
10090
|
setupAccountIdRef,
|
|
9450
10091
|
startGuestAccountPolling
|
|
@@ -9455,68 +10096,43 @@ function useGuestPreauthMobileRestoreEffect(deps) {
|
|
|
9455
10096
|
console.info("[blink-sdk] guestPreauthMobileRestore: skipping, privyReady=false");
|
|
9456
10097
|
return;
|
|
9457
10098
|
}
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
|
|
9461
|
-
|
|
9462
|
-
|
|
9463
|
-
|
|
9464
|
-
|
|
9465
|
-
|
|
9466
|
-
|
|
9467
|
-
|
|
9468
|
-
|
|
9469
|
-
|
|
9470
|
-
|
|
9471
|
-
|
|
9472
|
-
|
|
9473
|
-
|
|
9474
|
-
|
|
9475
|
-
|
|
9476
|
-
|
|
9477
|
-
|
|
9478
|
-
|
|
9479
|
-
|
|
9480
|
-
if (persisted.accountId) {
|
|
9481
|
-
dispatch({
|
|
9482
|
-
type: "GUEST_PREAUTH_DETECTED",
|
|
9483
|
-
accountId: persisted.accountId,
|
|
9484
|
-
sessionId: persisted.sessionId
|
|
9485
|
-
});
|
|
9486
|
-
}
|
|
10099
|
+
if (startedRef.current) {
|
|
10100
|
+
console.info("[blink-sdk] guestPreauthMobileRestore: already started");
|
|
10101
|
+
return;
|
|
10102
|
+
}
|
|
10103
|
+
const persisted = loadMobileFlowState();
|
|
10104
|
+
console.info("[blink-sdk] guestPreauthMobileRestore.tryStart", {
|
|
10105
|
+
trigger: lastResumedAt ? "page-resume" : "initial",
|
|
10106
|
+
hasPersistedState: !!persisted,
|
|
10107
|
+
isGuestPreauth: persisted?.isGuestPreauth ?? false,
|
|
10108
|
+
hasGuestSessionToken: !!persisted?.guestSessionToken,
|
|
10109
|
+
hasSessionId: !!persisted?.sessionId,
|
|
10110
|
+
accountId: persisted?.accountId ?? null
|
|
10111
|
+
});
|
|
10112
|
+
if (!persisted?.isGuestPreauth || !persisted.guestSessionToken || !persisted.sessionId) {
|
|
10113
|
+
return;
|
|
10114
|
+
}
|
|
10115
|
+
startedRef.current = true;
|
|
10116
|
+
mobileSetupFlowRef.current = true;
|
|
10117
|
+
if (persisted.accountId) {
|
|
10118
|
+
setupAccountIdRef.current = persisted.accountId;
|
|
10119
|
+
}
|
|
10120
|
+
if (persisted.accountId) {
|
|
9487
10121
|
dispatch({
|
|
9488
|
-
type: "
|
|
9489
|
-
|
|
9490
|
-
});
|
|
9491
|
-
console.info("[blink-sdk] guestPreauthMobileRestore: starting guest account polling", {
|
|
9492
|
-
trigger,
|
|
10122
|
+
type: "GUEST_PREAUTH_DETECTED",
|
|
10123
|
+
accountId: persisted.accountId,
|
|
9493
10124
|
sessionId: persisted.sessionId
|
|
9494
10125
|
});
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9498
|
-
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
console.info("[blink-sdk] guestPreauthMobileRestore: pageshow fired", {
|
|
9506
|
-
persisted: e.persisted,
|
|
9507
|
-
visibilityState: document.visibilityState,
|
|
9508
|
-
startedRef: startedRef.current
|
|
9509
|
-
});
|
|
9510
|
-
if (document.visibilityState === "visible") tryStart("pageshow");
|
|
9511
|
-
};
|
|
9512
|
-
tryStart("initial");
|
|
9513
|
-
document.addEventListener("visibilitychange", onVisibility);
|
|
9514
|
-
window.addEventListener("pageshow", onPageShow);
|
|
9515
|
-
return () => {
|
|
9516
|
-
document.removeEventListener("visibilitychange", onVisibility);
|
|
9517
|
-
window.removeEventListener("pageshow", onPageShow);
|
|
9518
|
-
};
|
|
9519
|
-
}, [privyReady, dispatch, mobileSetupFlowRef, setupAccountIdRef, startGuestAccountPolling]);
|
|
10126
|
+
}
|
|
10127
|
+
dispatch({
|
|
10128
|
+
type: "MOBILE_DEEPLINK_READY",
|
|
10129
|
+
deeplinkUri: persisted.deeplinkUri
|
|
10130
|
+
});
|
|
10131
|
+
console.info("[blink-sdk] guestPreauthMobileRestore: starting guest account polling", {
|
|
10132
|
+
sessionId: persisted.sessionId
|
|
10133
|
+
});
|
|
10134
|
+
startGuestAccountPolling(persisted.guestSessionToken, persisted.sessionId);
|
|
10135
|
+
}, [privyReady, lastResumedAt, dispatch, mobileSetupFlowRef, setupAccountIdRef, startGuestAccountPolling]);
|
|
9520
10136
|
}
|
|
9521
10137
|
function useSelectSourceEffect(deps) {
|
|
9522
10138
|
const {
|
|
@@ -9820,7 +10436,7 @@ function useStandardDesktopInlineOpenWalletEffect(deps) {
|
|
|
9820
10436
|
react.useEffect(() => {
|
|
9821
10437
|
if (!isDesktop || state.guestPreauthorizing) return;
|
|
9822
10438
|
if (!state.privyAuthenticated || !state.activeCredentialId || !state.selectedAccountId) return;
|
|
9823
|
-
const shouldPin = authExecutor.executing && !authExecutor.pendingSelectSource && !authExecutor.pendingOneTapSetup;
|
|
10439
|
+
const shouldPin = authExecutor.executing && !authExecutor.pendingSelectSource && (!authExecutor.pendingOneTapSetup || authExecutor.authorizationSessionStackDepth > 1);
|
|
9824
10440
|
if (shouldPin && !state.standardDesktopInlineOpenWallet) {
|
|
9825
10441
|
dispatch({ type: "SET_STANDARD_DESKTOP_INLINE_OPEN_WALLET", value: true });
|
|
9826
10442
|
return;
|
|
@@ -9838,6 +10454,7 @@ function useStandardDesktopInlineOpenWalletEffect(deps) {
|
|
|
9838
10454
|
authExecutor.executing,
|
|
9839
10455
|
authExecutor.pendingSelectSource,
|
|
9840
10456
|
authExecutor.pendingOneTapSetup,
|
|
10457
|
+
authExecutor.authorizationSessionStackDepth,
|
|
9841
10458
|
dispatch
|
|
9842
10459
|
]);
|
|
9843
10460
|
}
|
|
@@ -9856,7 +10473,84 @@ function useGuestAccountAutoPollingEffect(deps) {
|
|
|
9856
10473
|
startPolling(guestSessionToken);
|
|
9857
10474
|
}, [mobileFlow, isGuestFlow, guestSessionToken, isPolling, guestAccount, startPolling]);
|
|
9858
10475
|
}
|
|
9859
|
-
|
|
10476
|
+
var WATCHDOG_INTERVAL_MS = 1e3;
|
|
10477
|
+
var WATCHDOG_THRESHOLD_MS = 3e3;
|
|
10478
|
+
var DEDUP_COOLDOWN_MS = 500;
|
|
10479
|
+
function usePageResume(callback) {
|
|
10480
|
+
const callbackRef = react.useRef(callback);
|
|
10481
|
+
callbackRef.current = callback;
|
|
10482
|
+
react.useEffect(() => {
|
|
10483
|
+
let lastTickAt = Date.now();
|
|
10484
|
+
let lastFiredAt = 0;
|
|
10485
|
+
const fire = (source, frozenDurationMs) => {
|
|
10486
|
+
const now = Date.now();
|
|
10487
|
+
if (now - lastFiredAt < DEDUP_COOLDOWN_MS) return;
|
|
10488
|
+
lastFiredAt = now;
|
|
10489
|
+
callbackRef.current({ frozenDurationMs, source });
|
|
10490
|
+
};
|
|
10491
|
+
const watchdogId = window.setInterval(() => {
|
|
10492
|
+
const now = Date.now();
|
|
10493
|
+
const elapsed = now - lastTickAt;
|
|
10494
|
+
lastTickAt = now;
|
|
10495
|
+
if (elapsed > WATCHDOG_THRESHOLD_MS) {
|
|
10496
|
+
fire("watchdog", elapsed);
|
|
10497
|
+
}
|
|
10498
|
+
}, WATCHDOG_INTERVAL_MS);
|
|
10499
|
+
const handleVisibility = () => {
|
|
10500
|
+
const now = Date.now();
|
|
10501
|
+
if (document.visibilityState === "visible") {
|
|
10502
|
+
fire("visibilitychange", now - lastTickAt);
|
|
10503
|
+
}
|
|
10504
|
+
lastTickAt = now;
|
|
10505
|
+
};
|
|
10506
|
+
const handlePageShow = (_e) => {
|
|
10507
|
+
const now = Date.now();
|
|
10508
|
+
if (document.visibilityState === "visible") {
|
|
10509
|
+
fire("pageshow", now - lastTickAt);
|
|
10510
|
+
}
|
|
10511
|
+
lastTickAt = now;
|
|
10512
|
+
};
|
|
10513
|
+
const handleFocus = () => {
|
|
10514
|
+
const now = Date.now();
|
|
10515
|
+
const elapsed = now - lastTickAt;
|
|
10516
|
+
lastTickAt = now;
|
|
10517
|
+
if (elapsed > WATCHDOG_THRESHOLD_MS) {
|
|
10518
|
+
fire("focus", elapsed);
|
|
10519
|
+
}
|
|
10520
|
+
};
|
|
10521
|
+
document.addEventListener("visibilitychange", handleVisibility);
|
|
10522
|
+
window.addEventListener("pageshow", handlePageShow);
|
|
10523
|
+
window.addEventListener("focus", handleFocus);
|
|
10524
|
+
return () => {
|
|
10525
|
+
window.clearInterval(watchdogId);
|
|
10526
|
+
document.removeEventListener("visibilitychange", handleVisibility);
|
|
10527
|
+
window.removeEventListener("pageshow", handlePageShow);
|
|
10528
|
+
window.removeEventListener("focus", handleFocus);
|
|
10529
|
+
};
|
|
10530
|
+
}, []);
|
|
10531
|
+
}
|
|
10532
|
+
var STUCK_REF_THRESHOLD_MS = 5e3;
|
|
10533
|
+
function usePageResumeEffect(deps) {
|
|
10534
|
+
const { dispatch, handlingMobileReturnRef } = deps;
|
|
10535
|
+
const dispatchRef = react.useRef(dispatch);
|
|
10536
|
+
dispatchRef.current = dispatch;
|
|
10537
|
+
usePageResume((info) => {
|
|
10538
|
+
console.info("[blink-sdk] PAGE_RESUMED", {
|
|
10539
|
+
source: info.source,
|
|
10540
|
+
frozenDurationMs: info.frozenDurationMs
|
|
10541
|
+
});
|
|
10542
|
+
dispatchRef.current({ type: "PAGE_RESUMED", frozenDurationMs: info.frozenDurationMs });
|
|
10543
|
+
if (info.frozenDurationMs > STUCK_REF_THRESHOLD_MS) {
|
|
10544
|
+
if (handlingMobileReturnRef.current) {
|
|
10545
|
+
console.info("[blink-sdk] PAGE_RESUMED: clearing stuck handlingMobileReturnRef", {
|
|
10546
|
+
frozenDurationMs: info.frozenDurationMs
|
|
10547
|
+
});
|
|
10548
|
+
handlingMobileReturnRef.current = false;
|
|
10549
|
+
}
|
|
10550
|
+
}
|
|
10551
|
+
});
|
|
10552
|
+
}
|
|
10553
|
+
function useGuestAccountPolling(intervalMs = 3e3, lastResumedAt = 0) {
|
|
9860
10554
|
const { apiBaseUrl } = useBlinkConfig();
|
|
9861
10555
|
const [guestAccount, setGuestAccount] = react.useState(null);
|
|
9862
10556
|
const [isPolling, setIsPolling] = react.useState(false);
|
|
@@ -9954,36 +10648,71 @@ function useGuestAccountPolling(intervalMs = 3e3) {
|
|
|
9954
10648
|
[poll, intervalMs, stopPolling]
|
|
9955
10649
|
);
|
|
9956
10650
|
react.useEffect(() => {
|
|
9957
|
-
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
|
|
9969
|
-
|
|
9970
|
-
|
|
9971
|
-
|
|
9972
|
-
|
|
10651
|
+
if (!lastResumedAt || !guestTokenRef.current) return;
|
|
10652
|
+
console.info("[blink-sdk] useGuestAccountPolling: page resumed, triggering poll", {
|
|
10653
|
+
lastResumedAt,
|
|
10654
|
+
hasToken: !!guestTokenRef.current,
|
|
10655
|
+
hasSessionId: !!sessionIdRef.current
|
|
10656
|
+
});
|
|
10657
|
+
void poll();
|
|
10658
|
+
}, [lastResumedAt, poll]);
|
|
10659
|
+
react.useEffect(() => () => stopPolling(), [stopPolling]);
|
|
10660
|
+
return { guestAccount, error, isPolling, startPolling, stopPolling };
|
|
10661
|
+
}
|
|
10662
|
+
function useDepositFeeEstimate({
|
|
10663
|
+
apiBaseUrl,
|
|
10664
|
+
getAccessToken,
|
|
10665
|
+
walletId,
|
|
10666
|
+
sourceTokenAddress,
|
|
10667
|
+
destination,
|
|
10668
|
+
amount,
|
|
10669
|
+
enabled
|
|
10670
|
+
}) {
|
|
10671
|
+
const [quoteId, setQuoteId] = react.useState(null);
|
|
10672
|
+
const [quoteFee, setQuoteFee] = react.useState(null);
|
|
10673
|
+
const [quoteLoading, setQuoteLoading] = react.useState(false);
|
|
10674
|
+
const abortRef = react.useRef(null);
|
|
10675
|
+
const fetchQuote = react.useCallback(async () => {
|
|
10676
|
+
if (!enabled || !walletId || !sourceTokenAddress) {
|
|
10677
|
+
setQuoteId(null);
|
|
10678
|
+
setQuoteFee(null);
|
|
10679
|
+
setQuoteLoading(false);
|
|
10680
|
+
return;
|
|
10681
|
+
}
|
|
10682
|
+
abortRef.current?.abort();
|
|
10683
|
+
const controller = new AbortController();
|
|
10684
|
+
abortRef.current = controller;
|
|
10685
|
+
setQuoteLoading(true);
|
|
10686
|
+
try {
|
|
10687
|
+
const token = await getAccessToken();
|
|
10688
|
+
if (!token || controller.signal.aborted) return;
|
|
10689
|
+
const quote = await postTransferQuote(apiBaseUrl, token, {
|
|
10690
|
+
walletId,
|
|
10691
|
+
sourceTokenAddress,
|
|
10692
|
+
destination,
|
|
10693
|
+
amount: { amount, currency: "USD" }
|
|
9973
10694
|
});
|
|
9974
|
-
if (
|
|
9975
|
-
|
|
10695
|
+
if (controller.signal.aborted) return;
|
|
10696
|
+
setQuoteId(quote.id);
|
|
10697
|
+
setQuoteFee(quote.fee);
|
|
10698
|
+
} catch (err) {
|
|
10699
|
+
if (controller.signal.aborted) return;
|
|
10700
|
+
console.warn("[blink-sdk] Fee quote failed:", err);
|
|
10701
|
+
setQuoteId(null);
|
|
10702
|
+
setQuoteFee(null);
|
|
10703
|
+
} finally {
|
|
10704
|
+
if (!controller.signal.aborted) {
|
|
10705
|
+
setQuoteLoading(false);
|
|
9976
10706
|
}
|
|
9977
|
-
}
|
|
9978
|
-
|
|
9979
|
-
|
|
10707
|
+
}
|
|
10708
|
+
}, [enabled, walletId, sourceTokenAddress, destination, amount, apiBaseUrl, getAccessToken]);
|
|
10709
|
+
react.useEffect(() => {
|
|
10710
|
+
fetchQuote();
|
|
9980
10711
|
return () => {
|
|
9981
|
-
|
|
9982
|
-
window.removeEventListener("pageshow", handlePageShow);
|
|
10712
|
+
abortRef.current?.abort();
|
|
9983
10713
|
};
|
|
9984
|
-
}, [
|
|
9985
|
-
|
|
9986
|
-
return { guestAccount, error, isPolling, startPolling, stopPolling };
|
|
10714
|
+
}, [fetchQuote]);
|
|
10715
|
+
return { quoteId, quoteFee, quoteLoading };
|
|
9987
10716
|
}
|
|
9988
10717
|
function BlinkPayment(props) {
|
|
9989
10718
|
const resetKey = react.useRef(0);
|
|
@@ -10016,14 +10745,14 @@ function BlinkPaymentInner({
|
|
|
10016
10745
|
paymentReducer,
|
|
10017
10746
|
{
|
|
10018
10747
|
depositAmount,
|
|
10019
|
-
passkeyPopupNeeded: isSafari() && isInCrossOriginIframe(),
|
|
10748
|
+
passkeyPopupNeeded: isSafari() && isInCrossOriginIframe() && !isDesktop,
|
|
10020
10749
|
activeCredentialId: typeof window === "undefined" ? null : window.localStorage.getItem(ACTIVE_CREDENTIAL_STORAGE_KEY)
|
|
10021
10750
|
},
|
|
10022
10751
|
createInitialState
|
|
10023
10752
|
);
|
|
10024
10753
|
const authExecutor = useAuthorizationExecutor();
|
|
10025
10754
|
const polling = useTransferPolling();
|
|
10026
|
-
const guestAccountPolling = useGuestAccountPolling();
|
|
10755
|
+
const guestAccountPolling = useGuestAccountPolling(3e3, state.lastResumedAt);
|
|
10027
10756
|
const transferSigning = useTransferSigning();
|
|
10028
10757
|
const mobileFlowRefs = {
|
|
10029
10758
|
mobileSetupFlowRef: react.useRef(false),
|
|
@@ -10041,6 +10770,15 @@ function BlinkPaymentInner({
|
|
|
10041
10770
|
state.accounts,
|
|
10042
10771
|
state.knownCredentialIds
|
|
10043
10772
|
);
|
|
10773
|
+
const depositFee = useDepositFeeEstimate({
|
|
10774
|
+
apiBaseUrl,
|
|
10775
|
+
getAccessToken,
|
|
10776
|
+
walletId: state.selectedWalletId,
|
|
10777
|
+
sourceTokenAddress: derived.selectedSource?.address,
|
|
10778
|
+
destination,
|
|
10779
|
+
amount: depositAmount ?? 5,
|
|
10780
|
+
enabled: state.phase.step === "deposit" && !state.isGuestFlow && authenticated
|
|
10781
|
+
});
|
|
10044
10782
|
const transfer = useTransferHandlers({
|
|
10045
10783
|
dispatch,
|
|
10046
10784
|
getAccessToken,
|
|
@@ -10058,6 +10796,9 @@ function BlinkPaymentInner({
|
|
|
10058
10796
|
sourceTokenAddress: derived.selectedSource?.address,
|
|
10059
10797
|
activeCredentialId: state.activeCredentialId,
|
|
10060
10798
|
selectedAccountId: state.selectedAccountId,
|
|
10799
|
+
selectedWalletId: state.selectedWalletId,
|
|
10800
|
+
selectedTokenSymbol: state.selectedTokenSymbol,
|
|
10801
|
+
quoteId: depositFee.quoteId,
|
|
10061
10802
|
transfer: state.transfer,
|
|
10062
10803
|
accounts: state.accounts
|
|
10063
10804
|
});
|
|
@@ -10074,7 +10815,8 @@ function BlinkPaymentInner({
|
|
|
10074
10815
|
guestTransferId: state.guestTransferId,
|
|
10075
10816
|
guestSessionToken: state.guestSessionToken
|
|
10076
10817
|
},
|
|
10077
|
-
onComplete
|
|
10818
|
+
onComplete,
|
|
10819
|
+
state.lastResumedAt
|
|
10078
10820
|
);
|
|
10079
10821
|
const sourceSelection = useSourceSelectionHandlers(dispatch, authExecutor, {
|
|
10080
10822
|
guestPreauthSessionId: state.guestPreauthSessionId,
|
|
@@ -10170,10 +10912,15 @@ function BlinkPaymentInner({
|
|
|
10170
10912
|
dispatch({ type: "SYNC_AMOUNT", amount: depositAmount.toString() });
|
|
10171
10913
|
}
|
|
10172
10914
|
}, [depositAmount, dispatch]);
|
|
10915
|
+
usePageResumeEffect({
|
|
10916
|
+
dispatch,
|
|
10917
|
+
handlingMobileReturnRef: mobileFlowRefs.handlingMobileReturnRef
|
|
10918
|
+
});
|
|
10173
10919
|
usePrivySessionSyncEffect({ dispatch, ready, authenticated });
|
|
10174
10920
|
useGuestPreauthMobileRestoreEffect({
|
|
10175
10921
|
dispatch,
|
|
10176
10922
|
privyReady: state.privyReady,
|
|
10923
|
+
lastResumedAt: state.lastResumedAt,
|
|
10177
10924
|
mobileSetupFlowRef: mobileFlowRefs.mobileSetupFlowRef,
|
|
10178
10925
|
setupAccountIdRef: mobileFlowRefs.setupAccountIdRef,
|
|
10179
10926
|
startGuestAccountPolling: guestAccountPolling.startPolling
|
|
@@ -10186,25 +10933,24 @@ function BlinkPaymentInner({
|
|
|
10186
10933
|
guestAccount: guestAccountPolling.guestAccount,
|
|
10187
10934
|
startPolling: guestAccountPolling.startPolling
|
|
10188
10935
|
});
|
|
10189
|
-
const guestSessionTokenRef = react.useRef(state.guestSessionToken);
|
|
10190
|
-
guestSessionTokenRef.current = state.guestSessionToken;
|
|
10191
|
-
const guestPreauthSessionIdRef = react.useRef(state.guestPreauthSessionId);
|
|
10192
|
-
guestPreauthSessionIdRef.current = state.guestPreauthSessionId;
|
|
10193
10936
|
react.useEffect(() => {
|
|
10194
|
-
|
|
10195
|
-
|
|
10196
|
-
|
|
10197
|
-
|
|
10198
|
-
|
|
10199
|
-
|
|
10200
|
-
|
|
10201
|
-
|
|
10202
|
-
|
|
10203
|
-
|
|
10204
|
-
|
|
10205
|
-
|
|
10206
|
-
|
|
10207
|
-
|
|
10937
|
+
if (!state.lastResumedAt) return;
|
|
10938
|
+
const token = state.guestSessionToken;
|
|
10939
|
+
const sessionId = state.guestPreauthSessionId;
|
|
10940
|
+
if (!token) return;
|
|
10941
|
+
if (guestAccountPolling.isPolling || guestAccountPolling.guestAccount) return;
|
|
10942
|
+
console.info("[blink-sdk] warm-return: restarting guest account polling from React state", {
|
|
10943
|
+
sessionId: sessionId ?? "(none \u2014 account-only mode)"
|
|
10944
|
+
});
|
|
10945
|
+
guestAccountPolling.startPolling(token, sessionId ?? void 0);
|
|
10946
|
+
}, [
|
|
10947
|
+
state.lastResumedAt,
|
|
10948
|
+
state.guestSessionToken,
|
|
10949
|
+
state.guestPreauthSessionId,
|
|
10950
|
+
guestAccountPolling.isPolling,
|
|
10951
|
+
guestAccountPolling.guestAccount,
|
|
10952
|
+
guestAccountPolling.startPolling
|
|
10953
|
+
]);
|
|
10208
10954
|
react.useEffect(() => {
|
|
10209
10955
|
console.info("[blink-sdk] guestPreauthCompletion effect", {
|
|
10210
10956
|
hasGuestAccount: !!guestAccountPolling.guestAccount,
|
|
@@ -10355,7 +11101,10 @@ function BlinkPaymentInner({
|
|
|
10355
11101
|
dispatch({ type: "BACK_TO_LOGIN" });
|
|
10356
11102
|
},
|
|
10357
11103
|
onRegisterPasskey: passkey.handleRegisterPasskey,
|
|
11104
|
+
onVerifyPasskey: passkey.handleVerifyPasskey,
|
|
11105
|
+
onCreateNewPasskey: passkey.handleCreateNewPasskey,
|
|
10358
11106
|
onCreatePasskeyViaPopup: passkey.handleCreatePasskeyViaPopup,
|
|
11107
|
+
onCreateNewPasskeyViaPopup: passkey.handleCreateNewPasskeyViaPopup,
|
|
10359
11108
|
onVerifyPasskeyViaPopup: passkey.handleVerifyPasskeyViaPopup,
|
|
10360
11109
|
onPrepareProvider: provider.handlePrepareProvider,
|
|
10361
11110
|
onSelectProvider: provider.handleSelectProvider,
|
|
@@ -10369,6 +11118,11 @@ function BlinkPaymentInner({
|
|
|
10369
11118
|
onLogout: handleLogout,
|
|
10370
11119
|
onNewPayment: handleNewPayment,
|
|
10371
11120
|
onSetPhase: (phase) => dispatch({ type: "SET_USER_INTENT", intent: phase }),
|
|
11121
|
+
onBackFromSubflow: () => {
|
|
11122
|
+
authExecutor.cancelPendingExecution();
|
|
11123
|
+
dispatch({ type: "RESTORE_SELECTION" });
|
|
11124
|
+
dispatch({ type: "SET_USER_INTENT", intent: { step: "deposit" } });
|
|
11125
|
+
},
|
|
10372
11126
|
onSetAuthInput: auth.setAuthInput,
|
|
10373
11127
|
onSetOtpCode: (code) => {
|
|
10374
11128
|
auth.setOtpCode(code);
|
|
@@ -10402,7 +11156,8 @@ function BlinkPaymentInner({
|
|
|
10402
11156
|
handleLogout,
|
|
10403
11157
|
handleNewPayment,
|
|
10404
11158
|
onDismiss,
|
|
10405
|
-
dispatch
|
|
11159
|
+
dispatch,
|
|
11160
|
+
authExecutor
|
|
10406
11161
|
]);
|
|
10407
11162
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10408
11163
|
StepRenderer,
|
|
@@ -10451,7 +11206,10 @@ function BlinkPaymentInner({
|
|
|
10451
11206
|
guestSettingSender: guestTransfer.settingSender,
|
|
10452
11207
|
guestPendingEntry: guestTransfer.pendingGuestEntry,
|
|
10453
11208
|
guestQuoteFee: guestTransfer.guestFee?.quote ?? null,
|
|
10454
|
-
guestQuoteLoading: guestTransfer.guestQuoteLoading
|
|
11209
|
+
guestQuoteLoading: guestTransfer.guestQuoteLoading,
|
|
11210
|
+
depositQuoteId: depositFee.quoteId,
|
|
11211
|
+
depositQuoteFee: depositFee.quoteFee,
|
|
11212
|
+
depositQuoteLoading: depositFee.quoteLoading
|
|
10455
11213
|
},
|
|
10456
11214
|
handlers
|
|
10457
11215
|
}
|
|
@@ -10459,6 +11217,7 @@ function BlinkPaymentInner({
|
|
|
10459
11217
|
}
|
|
10460
11218
|
|
|
10461
11219
|
exports.AdvancedSourceScreen = AdvancedSourceScreen;
|
|
11220
|
+
exports.AuthorizationSessionCancelledError = AuthorizationSessionCancelledError;
|
|
10462
11221
|
exports.BLINK_LOGO = BLINK_LOGO;
|
|
10463
11222
|
exports.BLINK_MASCOT = BLINK_MASCOT;
|
|
10464
11223
|
exports.BlinkLoadingScreen = BlinkLoadingScreen;
|
|
@@ -10503,6 +11262,8 @@ exports.findDevicePasskey = findDevicePasskey;
|
|
|
10503
11262
|
exports.findDevicePasskeyViaPopup = findDevicePasskeyViaPopup;
|
|
10504
11263
|
exports.getTheme = getTheme;
|
|
10505
11264
|
exports.guestEntryMatchingRecommended = guestEntryMatchingRecommended;
|
|
11265
|
+
exports.isAuthorizationSessionCancelled = isAuthorizationSessionCancelled;
|
|
11266
|
+
exports.isUserDismissedAuthorizationError = isUserDismissedAuthorizationError;
|
|
10506
11267
|
exports.lightTheme = lightTheme;
|
|
10507
11268
|
exports.mapGuestPickerEntries = mapGuestPickerEntries;
|
|
10508
11269
|
exports.resolvePasskeyRpId = resolvePasskeyRpId;
|