@swype-org/react-sdk 0.1.287 → 0.1.300

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/dist/index.cjs CHANGED
@@ -7,9 +7,9 @@ var chains = require('wagmi/chains');
7
7
  var connectors = require('wagmi/connectors');
8
8
  var reactQuery = require('@tanstack/react-query');
9
9
  var jsxRuntime = require('react/jsx-runtime');
10
+ var core = require('@wagmi/core');
10
11
  var viem = require('viem');
11
12
  var utils = require('viem/utils');
12
- var actions = require('viem/actions');
13
13
 
14
14
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
15
15
  var __defProp = Object.defineProperty;
@@ -488,13 +488,14 @@ __export(api_exports, {
488
488
  fetchAuthorizationSessionByToken: () => fetchAuthorizationSessionByToken,
489
489
  fetchChains: () => fetchChains,
490
490
  fetchGuestAccount: () => fetchGuestAccount,
491
- fetchGuestTransferBalances: () => fetchGuestTransferBalances,
492
491
  fetchMerchantPublicKey: () => fetchMerchantPublicKey,
493
492
  fetchProviders: () => fetchProviders,
494
493
  fetchTransfer: () => fetchTransfer,
495
494
  fetchUserConfig: () => fetchUserConfig,
496
495
  getGuestTransfer: () => getGuestTransfer,
497
496
  getTransferByGuestToken: () => getTransferByGuestToken,
497
+ postGuestTransferFeeQuote: () => postGuestTransferFeeQuote,
498
+ putGuestTransferSender: () => putGuestTransferSender,
498
499
  registerPasskey: () => registerPasskey,
499
500
  reportActionCompletion: () => reportActionCompletion,
500
501
  reportPasskeyActivity: () => reportPasskeyActivity,
@@ -749,18 +750,37 @@ async function getTransferByGuestToken(apiBaseUrl, guestToken) {
749
750
  if (!res.ok) await throwApiError(res);
750
751
  return await res.json();
751
752
  }
752
- async function setTransferSender(apiBaseUrl, transferId, guestSessionToken, senderAddress, sourceChainId, sourceToken) {
753
+ async function postGuestTransferFeeQuote(apiBaseUrl, transferId, guestSessionToken, senderAddress, sourceChainId, sourceToken) {
754
+ const res = await fetch(`${apiBaseUrl}/v1/transfers/${transferId}/quotes`, {
755
+ method: "POST",
756
+ headers: {
757
+ "Content-Type": "application/json",
758
+ "x-guest-session-token": guestSessionToken
759
+ },
760
+ body: JSON.stringify({ senderAddress, sourceChainId, sourceToken })
761
+ });
762
+ if (!res.ok) await throwApiError(res);
763
+ return await res.json();
764
+ }
765
+ async function putGuestTransferSender(apiBaseUrl, transferId, guestSessionToken, body) {
753
766
  const res = await fetch(`${apiBaseUrl}/v1/transfers/${transferId}/sender`, {
754
767
  method: "PUT",
755
768
  headers: {
756
769
  "Content-Type": "application/json",
757
770
  "x-guest-session-token": guestSessionToken
758
771
  },
759
- body: JSON.stringify({ senderAddress, sourceChainId, sourceToken })
772
+ body: JSON.stringify(body)
760
773
  });
761
774
  if (!res.ok) await throwApiError(res);
762
775
  return await res.json();
763
776
  }
777
+ async function setTransferSender(apiBaseUrl, transferId, guestSessionToken, senderAddress, sourceChainId, sourceToken) {
778
+ return putGuestTransferSender(apiBaseUrl, transferId, guestSessionToken, {
779
+ senderAddress,
780
+ sourceChainId,
781
+ sourceToken
782
+ });
783
+ }
764
784
  async function signGuestTransfer(apiBaseUrl, transferId, guestSessionToken, originTxHash) {
765
785
  const res = await fetch(`${apiBaseUrl}/v1/transfers/${transferId}`, {
766
786
  method: "PATCH",
@@ -782,20 +802,6 @@ async function getGuestTransfer(apiBaseUrl, transferId, guestSessionToken) {
782
802
  if (!res.ok) await throwApiError(res);
783
803
  return await res.json();
784
804
  }
785
- async function fetchGuestTransferBalances(apiBaseUrl, transferId, guestSessionToken, walletAddress) {
786
- const params = new URLSearchParams({ walletAddress });
787
- const res = await fetch(
788
- `${apiBaseUrl}/v1/transfers/${transferId}/balances?${params.toString()}`,
789
- {
790
- headers: {
791
- "x-guest-session-token": guestSessionToken
792
- }
793
- }
794
- );
795
- if (!res.ok) await throwApiError(res);
796
- const data = await res.json();
797
- return data.items;
798
- }
799
805
  async function fetchGuestAccount(apiBaseUrl, guestToken) {
800
806
  const params = new URLSearchParams({ guestToken });
801
807
  const res = await fetch(`${apiBaseUrl}/v1/accounts?${params.toString()}`);
@@ -910,304 +916,6 @@ function useTransferPolling(intervalMs = 3e3) {
910
916
  react.useEffect(() => () => stopPolling(), [stopPolling]);
911
917
  return { transfer, error, isPolling, startPolling, stopPolling };
912
918
  }
913
-
914
- // node_modules/@wagmi/core/dist/esm/utils/getAction.js
915
- function getAction(client, actionFn, name) {
916
- const action_implicit = client[actionFn.name];
917
- if (typeof action_implicit === "function")
918
- return action_implicit;
919
- const action_explicit = client[name];
920
- if (typeof action_explicit === "function")
921
- return action_explicit;
922
- return (params) => actionFn(client, params);
923
- }
924
-
925
- // node_modules/@wagmi/core/dist/esm/version.js
926
- var version = "2.22.1";
927
-
928
- // node_modules/@wagmi/core/dist/esm/utils/getVersion.js
929
- var getVersion = () => `@wagmi/core@${version}`;
930
-
931
- // node_modules/@wagmi/core/dist/esm/errors/base.js
932
- var __classPrivateFieldGet = function(receiver, state, kind, f) {
933
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
934
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
935
- };
936
- var _BaseError_instances;
937
- var _BaseError_walk;
938
- var BaseError = class _BaseError extends Error {
939
- get docsBaseUrl() {
940
- return "https://wagmi.sh/core";
941
- }
942
- get version() {
943
- return getVersion();
944
- }
945
- constructor(shortMessage, options = {}) {
946
- super();
947
- _BaseError_instances.add(this);
948
- Object.defineProperty(this, "details", {
949
- enumerable: true,
950
- configurable: true,
951
- writable: true,
952
- value: void 0
953
- });
954
- Object.defineProperty(this, "docsPath", {
955
- enumerable: true,
956
- configurable: true,
957
- writable: true,
958
- value: void 0
959
- });
960
- Object.defineProperty(this, "metaMessages", {
961
- enumerable: true,
962
- configurable: true,
963
- writable: true,
964
- value: void 0
965
- });
966
- Object.defineProperty(this, "shortMessage", {
967
- enumerable: true,
968
- configurable: true,
969
- writable: true,
970
- value: void 0
971
- });
972
- Object.defineProperty(this, "name", {
973
- enumerable: true,
974
- configurable: true,
975
- writable: true,
976
- value: "WagmiCoreError"
977
- });
978
- const details = options.cause instanceof _BaseError ? options.cause.details : options.cause?.message ? options.cause.message : options.details;
979
- const docsPath = options.cause instanceof _BaseError ? options.cause.docsPath || options.docsPath : options.docsPath;
980
- this.message = [
981
- shortMessage || "An error occurred.",
982
- "",
983
- ...options.metaMessages ? [...options.metaMessages, ""] : [],
984
- ...docsPath ? [
985
- `Docs: ${this.docsBaseUrl}${docsPath}.html${options.docsSlug ? `#${options.docsSlug}` : ""}`
986
- ] : [],
987
- ...details ? [`Details: ${details}`] : [],
988
- `Version: ${this.version}`
989
- ].join("\n");
990
- if (options.cause)
991
- this.cause = options.cause;
992
- this.details = details;
993
- this.docsPath = docsPath;
994
- this.metaMessages = options.metaMessages;
995
- this.shortMessage = shortMessage;
996
- }
997
- walk(fn) {
998
- return __classPrivateFieldGet(this, _BaseError_instances, "m", _BaseError_walk).call(this, this, fn);
999
- }
1000
- };
1001
- _BaseError_instances = /* @__PURE__ */ new WeakSet(), _BaseError_walk = function _BaseError_walk2(err, fn) {
1002
- if (fn?.(err))
1003
- return err;
1004
- if (err.cause)
1005
- return __classPrivateFieldGet(this, _BaseError_instances, "m", _BaseError_walk2).call(this, err.cause, fn);
1006
- return err;
1007
- };
1008
-
1009
- // node_modules/@wagmi/core/dist/esm/errors/config.js
1010
- var ConnectorNotConnectedError = class extends BaseError {
1011
- constructor() {
1012
- super("Connector not connected.");
1013
- Object.defineProperty(this, "name", {
1014
- enumerable: true,
1015
- configurable: true,
1016
- writable: true,
1017
- value: "ConnectorNotConnectedError"
1018
- });
1019
- }
1020
- };
1021
- var ConnectorAccountNotFoundError = class extends BaseError {
1022
- constructor({ address, connector }) {
1023
- super(`Account "${address}" not found for connector "${connector.name}".`);
1024
- Object.defineProperty(this, "name", {
1025
- enumerable: true,
1026
- configurable: true,
1027
- writable: true,
1028
- value: "ConnectorAccountNotFoundError"
1029
- });
1030
- }
1031
- };
1032
- var ConnectorChainMismatchError = class extends BaseError {
1033
- constructor({ connectionChainId, connectorChainId }) {
1034
- super(`The current chain of the connector (id: ${connectorChainId}) does not match the connection's chain (id: ${connectionChainId}).`, {
1035
- metaMessages: [
1036
- `Current Chain ID: ${connectorChainId}`,
1037
- `Expected Chain ID: ${connectionChainId}`
1038
- ]
1039
- });
1040
- Object.defineProperty(this, "name", {
1041
- enumerable: true,
1042
- configurable: true,
1043
- writable: true,
1044
- value: "ConnectorChainMismatchError"
1045
- });
1046
- }
1047
- };
1048
- var ConnectorUnavailableReconnectingError = class extends BaseError {
1049
- constructor({ connector }) {
1050
- super(`Connector "${connector.name}" unavailable while reconnecting.`, {
1051
- details: [
1052
- "During the reconnection step, the only connector methods guaranteed to be available are: `id`, `name`, `type`, `uid`.",
1053
- "All other methods are not guaranteed to be available until reconnection completes and connectors are fully restored.",
1054
- "This error commonly occurs for connectors that asynchronously inject after reconnection has already started."
1055
- ].join(" ")
1056
- });
1057
- Object.defineProperty(this, "name", {
1058
- enumerable: true,
1059
- configurable: true,
1060
- writable: true,
1061
- value: "ConnectorUnavailableReconnectingError"
1062
- });
1063
- }
1064
- };
1065
- async function getConnectorClient(config, parameters = {}) {
1066
- const { assertChainId = true } = parameters;
1067
- let connection;
1068
- if (parameters.connector) {
1069
- const { connector: connector2 } = parameters;
1070
- if (config.state.status === "reconnecting" && !connector2.getAccounts && !connector2.getChainId)
1071
- throw new ConnectorUnavailableReconnectingError({ connector: connector2 });
1072
- const [accounts, chainId2] = await Promise.all([
1073
- connector2.getAccounts().catch((e) => {
1074
- if (parameters.account === null)
1075
- return [];
1076
- throw e;
1077
- }),
1078
- connector2.getChainId()
1079
- ]);
1080
- connection = {
1081
- accounts,
1082
- chainId: chainId2,
1083
- connector: connector2
1084
- };
1085
- } else
1086
- connection = config.state.connections.get(config.state.current);
1087
- if (!connection)
1088
- throw new ConnectorNotConnectedError();
1089
- const chainId = parameters.chainId ?? connection.chainId;
1090
- const connectorChainId = await connection.connector.getChainId();
1091
- if (assertChainId && connectorChainId !== chainId)
1092
- throw new ConnectorChainMismatchError({
1093
- connectionChainId: chainId,
1094
- connectorChainId
1095
- });
1096
- const connector = connection.connector;
1097
- if (connector.getClient)
1098
- return connector.getClient({ chainId });
1099
- const account = utils.parseAccount(parameters.account ?? connection.accounts[0]);
1100
- if (account)
1101
- account.address = utils.getAddress(account.address);
1102
- if (parameters.account && !connection.accounts.some((x) => x.toLowerCase() === account.address.toLowerCase()))
1103
- throw new ConnectorAccountNotFoundError({
1104
- address: account.address,
1105
- connector
1106
- });
1107
- const chain = config.chains.find((chain2) => chain2.id === chainId);
1108
- const provider = await connection.connector.getProvider({ chainId });
1109
- return viem.createClient({
1110
- account,
1111
- chain,
1112
- name: "Connector Client",
1113
- transport: (opts) => viem.custom(provider)({ ...opts, retryCount: 0 })
1114
- });
1115
- }
1116
-
1117
- // node_modules/@wagmi/core/dist/esm/actions/getAccount.js
1118
- function getAccount(config) {
1119
- const uid = config.state.current;
1120
- const connection = config.state.connections.get(uid);
1121
- const addresses = connection?.accounts;
1122
- const address = addresses?.[0];
1123
- const chain = config.chains.find((chain2) => chain2.id === connection?.chainId);
1124
- const status = config.state.status;
1125
- switch (status) {
1126
- case "connected":
1127
- return {
1128
- address,
1129
- addresses,
1130
- chain,
1131
- chainId: connection?.chainId,
1132
- connector: connection?.connector,
1133
- isConnected: true,
1134
- isConnecting: false,
1135
- isDisconnected: false,
1136
- isReconnecting: false,
1137
- status
1138
- };
1139
- case "reconnecting":
1140
- return {
1141
- address,
1142
- addresses,
1143
- chain,
1144
- chainId: connection?.chainId,
1145
- connector: connection?.connector,
1146
- isConnected: !!address,
1147
- isConnecting: false,
1148
- isDisconnected: false,
1149
- isReconnecting: true,
1150
- status
1151
- };
1152
- case "connecting":
1153
- return {
1154
- address,
1155
- addresses,
1156
- chain,
1157
- chainId: connection?.chainId,
1158
- connector: connection?.connector,
1159
- isConnected: false,
1160
- isConnecting: true,
1161
- isDisconnected: false,
1162
- isReconnecting: false,
1163
- status
1164
- };
1165
- case "disconnected":
1166
- return {
1167
- address: void 0,
1168
- addresses: void 0,
1169
- chain: void 0,
1170
- chainId: void 0,
1171
- connector: void 0,
1172
- isConnected: false,
1173
- isConnecting: false,
1174
- isDisconnected: true,
1175
- isReconnecting: false,
1176
- status
1177
- };
1178
- }
1179
- }
1180
- async function getWalletClient(config, parameters = {}) {
1181
- const client = await getConnectorClient(config, parameters);
1182
- return client.extend(viem.walletActions);
1183
- }
1184
- async function waitForTransactionReceipt(config, parameters) {
1185
- const { chainId, timeout = 0, ...rest } = parameters;
1186
- const client = config.getClient({ chainId });
1187
- const action = getAction(client, actions.waitForTransactionReceipt, "waitForTransactionReceipt");
1188
- const receipt = await action({ ...rest, timeout });
1189
- if (receipt.status === "reverted") {
1190
- const action_getTransaction = getAction(client, actions.getTransaction, "getTransaction");
1191
- const { from: account, ...txn } = await action_getTransaction({
1192
- hash: receipt.transactionHash
1193
- });
1194
- const action_call = getAction(client, actions.call, "call");
1195
- const code = await action_call({
1196
- ...txn,
1197
- account,
1198
- data: txn.input,
1199
- gasPrice: txn.type !== "eip1559" ? txn.gasPrice : void 0,
1200
- maxFeePerGas: txn.type === "eip1559" ? txn.maxFeePerGas : void 0,
1201
- maxPriorityFeePerGas: txn.type === "eip1559" ? txn.maxPriorityFeePerGas : void 0
1202
- });
1203
- const reason = code?.data ? viem.hexToString(`0x${code.data.substring(138)}`) : "unknown reason";
1204
- throw new Error(reason);
1205
- }
1206
- return {
1207
- ...receipt,
1208
- chainId: client.chain.id
1209
- };
1210
- }
1211
919
  var ERC_6492_MAGIC_SUFFIX = "6492649264926492649264926492649264926492649264926492649264926492";
1212
920
  function normalizeSignature(sig) {
1213
921
  const hex = sig.startsWith("0x") ? sig.slice(2) : sig;
@@ -1276,9 +984,9 @@ function isUserRejection(msg) {
1276
984
  async function waitForWalletClient(wagmiConfig2, params = {}) {
1277
985
  for (let i = 0; i < WALLET_CLIENT_MAX_ATTEMPTS; i++) {
1278
986
  try {
1279
- const account = getAccount(wagmiConfig2);
987
+ const account = core.getAccount(wagmiConfig2);
1280
988
  const enrichedParams = account.connector ? { ...params, connector: account.connector } : params;
1281
- return await getWalletClient(wagmiConfig2, enrichedParams);
989
+ return await core.getWalletClient(wagmiConfig2, enrichedParams);
1282
990
  } catch {
1283
991
  if (i === WALLET_CLIENT_MAX_ATTEMPTS - 1) {
1284
992
  throw new Error("Wallet not ready. Please try again.");
@@ -1314,7 +1022,7 @@ function getPendingActions(session, completedIds) {
1314
1022
  }
1315
1023
  async function executeOpenProvider(action, wagmiConfig2, connectors, connectAsync) {
1316
1024
  try {
1317
- const account = getAccount(wagmiConfig2);
1025
+ const account = core.getAccount(wagmiConfig2);
1318
1026
  if (account.isConnected && account.address) {
1319
1027
  const hexChainId2 = account.chainId ? `0x${account.chainId.toString(16)}` : void 0;
1320
1028
  return actionSuccess(
@@ -1381,7 +1089,7 @@ async function executeSelectSource(action, waitForSelection) {
1381
1089
  }
1382
1090
  async function executeSwitchChain(action, wagmiConfig2, switchChainAsync) {
1383
1091
  try {
1384
- const account = getAccount(wagmiConfig2);
1092
+ const account = core.getAccount(wagmiConfig2);
1385
1093
  const targetChainIdHex = action.metadata?.targetChainId;
1386
1094
  if (!targetChainIdHex) {
1387
1095
  return actionError(action, "No targetChainId in action metadata.");
@@ -1423,7 +1131,7 @@ async function executeSwitchChain(action, wagmiConfig2, switchChainAsync) {
1423
1131
  async function executeApprovePermit2(action, wagmiConfig2) {
1424
1132
  try {
1425
1133
  const walletClient = await waitForWalletClient(wagmiConfig2);
1426
- const account = getAccount(wagmiConfig2);
1134
+ const account = core.getAccount(wagmiConfig2);
1427
1135
  const sender = account.address ?? walletClient.account?.address;
1428
1136
  const expectedWallet = action.metadata?.walletAddress;
1429
1137
  if (!sender) {
@@ -1476,7 +1184,7 @@ async function executeSignPermit2(action, wagmiConfig2, apiBaseUrl, sessionId) {
1476
1184
  wagmiConfig2,
1477
1185
  expectedWallet ? { account: expectedWallet } : {}
1478
1186
  );
1479
- const account = getAccount(wagmiConfig2);
1187
+ const account = core.getAccount(wagmiConfig2);
1480
1188
  const connectedAddress = account.address ?? walletClient.account?.address;
1481
1189
  const sender = expectedWallet ?? connectedAddress;
1482
1190
  if (!sender) {
@@ -2080,8 +1788,8 @@ function resolvePhase(state) {
2080
1788
  const needsPasskeyBootstrap = state.privyAuthenticated && !state.activeCredentialId;
2081
1789
  const guestPreauthPinsCurrentPhase = transferCompleted && state.guestPreauthorizing && !state.verificationTarget && isGuestPreauthCompletedTransferPinPhase(currentPhase);
2082
1790
  const guestPostPayLogin = transferCompleted && state.isGuestFlow && state.guestPreauthSessionId != null && !state.guestPreauthorizing && !state.verificationTarget && !state.privyAuthenticated;
2083
- 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");
2084
1791
  const guestTokenPickerEligible = state.isGuestFlow && state.selectedProviderId != null && !state.transfer && !state.guestPreauthAccountId;
1792
+ 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);
2085
1793
  const walletPickerSwitchEligible = currentPhase.step === "wallet-picker" && currentPhase.reason === "switch" && !state.creatingTransfer && !(state.mobileFlow && state.deeplinkUri);
2086
1794
  const missingActivePasskeyCredential = state.passkeyConfigLoaded && !state.activeCredentialId;
2087
1795
  const shouldPromptPasskeyVerification = missingActivePasskeyCredential && state.knownCredentialIds.length > 0 && state.passkeyPopupNeeded;
@@ -3513,10 +3221,15 @@ function LoginScreen({
3513
3221
  error,
3514
3222
  onBack,
3515
3223
  merchantInitials,
3516
- onSocialLogin
3224
+ onSocialLogin,
3225
+ heroTitle,
3226
+ heroSubtitle,
3227
+ inputPlaceholder
3517
3228
  }) {
3518
3229
  const { tokens } = useBlinkConfig();
3519
3230
  const disabled = authInput.trim().length === 0 || sending;
3231
+ const heading = heroTitle ?? "Your Money. Any App.\nOne Tap.";
3232
+ const placeholder = inputPlaceholder ?? "Email or phone number";
3520
3233
  return /* @__PURE__ */ jsxRuntime.jsxs(
3521
3234
  ScreenLayout,
3522
3235
  {
@@ -3551,7 +3264,8 @@ function LoginScreen({
3551
3264
  ),
3552
3265
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle, children: [
3553
3266
  /* @__PURE__ */ jsxRuntime.jsx("img", { src: BLINK_LOGO, alt: "Blink", style: logoStyle }),
3554
- /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle(tokens.text), children: "Your Money. Any App.\nOne Tap." }),
3267
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle(tokens.text), children: heading }),
3268
+ heroSubtitle ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle(tokens.textMuted), children: heroSubtitle }) : null,
3555
3269
  error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorStyle(tokens), children: error }),
3556
3270
  /* @__PURE__ */ jsxRuntime.jsx(
3557
3271
  "input",
@@ -3560,7 +3274,7 @@ function LoginScreen({
3560
3274
  type: "text",
3561
3275
  inputMode: "text",
3562
3276
  autoComplete: "username",
3563
- placeholder: "Email or phone number",
3277
+ placeholder,
3564
3278
  value: authInput,
3565
3279
  onChange: (e) => onAuthInputChange(e.target.value),
3566
3280
  onKeyDown: (e) => {
@@ -3605,6 +3319,14 @@ var headingStyle = (color) => ({
3605
3319
  margin: "20px 0 8px",
3606
3320
  whiteSpace: "pre-line"
3607
3321
  });
3322
+ var subtitleStyle = (color) => ({
3323
+ fontSize: "0.9rem",
3324
+ fontWeight: 500,
3325
+ lineHeight: 1.45,
3326
+ color,
3327
+ margin: "0 0 16px",
3328
+ maxWidth: 320
3329
+ });
3608
3330
  var inputStyle2 = (tokens) => ({
3609
3331
  width: "100%",
3610
3332
  padding: "15px 16px",
@@ -3727,7 +3449,7 @@ function OtpVerifyScreen({
3727
3449
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack }),
3728
3450
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle2, children: [
3729
3451
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle2(tokens.text), children: "Confirm it is you" }),
3730
- /* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle(tokens.textSecondary), children: [
3452
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle2(tokens.textSecondary), children: [
3731
3453
  "We sent a 6-digit code to",
3732
3454
  "\n",
3733
3455
  /* @__PURE__ */ jsxRuntime.jsx("strong", { children: maskedIdentifier })
@@ -3763,7 +3485,7 @@ var headingStyle2 = (color) => ({
3763
3485
  color,
3764
3486
  margin: "20px 0 8px"
3765
3487
  });
3766
- var subtitleStyle = (color) => ({
3488
+ var subtitleStyle2 = (color) => ({
3767
3489
  fontSize: "0.88rem",
3768
3490
  color,
3769
3491
  margin: "0 0 28px",
@@ -3816,7 +3538,7 @@ function PasskeyScreen({
3816
3538
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack, onLogout }),
3817
3539
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle3, children: [
3818
3540
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle3(tokens.text), children: "Secure your account with a passkey" }),
3819
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle2(tokens.textSecondary), children: "This enables secure one-tap deposits on this device" }),
3541
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle3(tokens.textSecondary), children: "This enables secure one-tap deposits on this device" }),
3820
3542
  error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle2(tokens), children: error })
3821
3543
  ] })
3822
3544
  ]
@@ -3838,7 +3560,7 @@ var headingStyle3 = (color) => ({
3838
3560
  color,
3839
3561
  margin: "24px 0 8px"
3840
3562
  });
3841
- var subtitleStyle2 = (color) => ({
3563
+ var subtitleStyle3 = (color) => ({
3842
3564
  fontSize: "0.86rem",
3843
3565
  color,
3844
3566
  margin: "0 0 20px",
@@ -3856,6 +3578,72 @@ var errorBannerStyle2 = (tokens) => ({
3856
3578
  width: "100%",
3857
3579
  textAlign: "left"
3858
3580
  });
3581
+ function VerifyPasskeyScreen({
3582
+ onVerify,
3583
+ onBack,
3584
+ verifying,
3585
+ error
3586
+ }) {
3587
+ const { tokens } = useBlinkConfig();
3588
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3589
+ ScreenLayout,
3590
+ {
3591
+ footer: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3592
+ /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: onVerify, disabled: verifying, loading: verifying, children: "Verify passkey" }),
3593
+ /* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {})
3594
+ ] }),
3595
+ children: [
3596
+ /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack }),
3597
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle4, children: [
3598
+ /* @__PURE__ */ jsxRuntime.jsx(IconCircle, { variant: "accent", size: 64, children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "36", height: "36", viewBox: "0 0 24 24", fill: "none", children: [
3599
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "4", y: "4", width: "16", height: "16", rx: "3", stroke: tokens.accent, strokeWidth: "1.5", strokeDasharray: "3 2" }),
3600
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "9", cy: "10", r: "1", fill: tokens.accent }),
3601
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "15", cy: "10", r: "1", fill: tokens.accent }),
3602
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 14c0 1.5 1.34 2.5 3 2.5s3-1 3-2.5", stroke: tokens.accent, strokeWidth: "1.2", strokeLinecap: "round" })
3603
+ ] }) }),
3604
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle4(tokens.text), children: "Verify your passkey" }),
3605
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle4(tokens.textSecondary), children: "Your browser requires a separate window to verify your passkey. Tap the button below to continue." }),
3606
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle3(tokens), children: error }),
3607
+ /* @__PURE__ */ jsxRuntime.jsx(InfoBanner, { children: "Your passkey is stored securely on your device. Blink never sees your biometric data." })
3608
+ ] })
3609
+ ]
3610
+ }
3611
+ );
3612
+ }
3613
+ var contentStyle4 = {
3614
+ textAlign: "center",
3615
+ flex: 1,
3616
+ display: "flex",
3617
+ flexDirection: "column",
3618
+ alignItems: "center",
3619
+ paddingTop: 32
3620
+ };
3621
+ var headingStyle4 = (color) => ({
3622
+ fontSize: "1.45rem",
3623
+ fontWeight: 700,
3624
+ letterSpacing: "-0.02em",
3625
+ color,
3626
+ margin: "24px 0 8px"
3627
+ });
3628
+ var subtitleStyle4 = (color) => ({
3629
+ fontSize: "0.9rem",
3630
+ color,
3631
+ margin: "0 0 28px",
3632
+ lineHeight: 1.5,
3633
+ maxWidth: 280
3634
+ });
3635
+ var errorBannerStyle3 = (tokens) => ({
3636
+ background: tokens.errorBg,
3637
+ border: `1px solid ${tokens.error}66`,
3638
+ borderRadius: 16,
3639
+ padding: "11px 14px",
3640
+ color: tokens.error,
3641
+ fontSize: "0.84rem",
3642
+ marginBottom: 14,
3643
+ lineHeight: 1.5,
3644
+ width: "100%",
3645
+ textAlign: "left"
3646
+ });
3859
3647
  function Spinner({ size = 40, label }) {
3860
3648
  const { tokens } = useBlinkConfig();
3861
3649
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -3999,8 +3787,8 @@ function WalletPickerScreen({
3999
3787
  children: [
4000
3788
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { title: "Set up Blink", onBack, onLogout }),
4001
3789
  hasPending && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4002
- /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle4(tokens.text), children: "Continue where you left off" }),
4003
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle3(tokens.textSecondary), children: "You have a wallet that still needs setup" }),
3790
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle5(tokens.text), children: "Continue where you left off" }),
3791
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle5(tokens.textSecondary), children: "You have a wallet that still needs setup" }),
4004
3792
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: pendingListStyle, children: pendingConnections.map((acct) => {
4005
3793
  const wallet = acct.wallets[0];
4006
3794
  const address = wallet ? truncateAddress(wallet.name) : void 0;
@@ -4039,7 +3827,7 @@ function WalletPickerScreen({
4039
3827
  }) }),
4040
3828
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: dividerStyle2(tokens.border), children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: dividerTextStyle(tokens.textMuted), children: "Or connect a new wallet" }) })
4041
3829
  ] }),
4042
- !hasPending && /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle4(tokens.text), children: "Where is your money?" }),
3830
+ !hasPending && /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle5(tokens.text), children: "Where is your money?" }),
4043
3831
  /* @__PURE__ */ jsxRuntime.jsxs(
4044
3832
  "button",
4045
3833
  {
@@ -4110,14 +3898,14 @@ function WalletPickerScreen({
4110
3898
  }
4111
3899
  );
4112
3900
  }
4113
- var headingStyle4 = (color) => ({
3901
+ var headingStyle5 = (color) => ({
4114
3902
  fontSize: "1.35rem",
4115
3903
  fontWeight: 700,
4116
3904
  letterSpacing: "-0.02em",
4117
3905
  color,
4118
3906
  margin: "8px 0 4px"
4119
3907
  });
4120
- var subtitleStyle3 = (color) => ({
3908
+ var subtitleStyle5 = (color) => ({
4121
3909
  fontSize: "0.88rem",
4122
3910
  color,
4123
3911
  margin: "0 0 24px"
@@ -4296,6 +4084,9 @@ var loginButtonStyle = (accentColor) => ({
4296
4084
  var DEFAULT_MAX = 1e7;
4297
4085
  var ABSOLUTE_MIN = 0.01;
4298
4086
  var PRESETS = [100, 250, 1e3];
4087
+ function tokenOptionKey(opt) {
4088
+ return `${opt.chainName}-${opt.symbol}`;
4089
+ }
4299
4090
  function SetupScreen({
4300
4091
  availableBalance,
4301
4092
  onSetupOneTap,
@@ -4304,16 +4095,43 @@ function SetupScreen({
4304
4095
  onAdvanced,
4305
4096
  loading,
4306
4097
  error,
4307
- selectedTokenSymbol
4098
+ selectedTokenSymbol,
4099
+ tokenOptions,
4100
+ onSelectToken
4308
4101
  }) {
4309
4102
  const { tokens } = useBlinkConfig();
4310
4103
  const effectiveMax = DEFAULT_MAX;
4311
4104
  const effectiveMin = Math.min(ABSOLUTE_MIN, effectiveMax);
4312
4105
  const [limit, setLimit] = react.useState(() => Math.min(availableBalance, effectiveMax));
4313
4106
  const [activePreset, setActivePreset] = react.useState(null);
4107
+ const [showAdvanced, setShowAdvanced] = react.useState(false);
4314
4108
  const [editing, setEditing] = react.useState(false);
4315
4109
  const [inputValue, setInputValue] = react.useState("");
4316
4110
  const inputRef = react.useRef(null);
4111
+ const hasDropdown = tokenOptions != null && tokenOptions.length > 0 && onSelectToken != null;
4112
+ const [tokenDropdownOpen, setTokenDropdownOpen] = react.useState(false);
4113
+ const pickerRef = react.useRef(null);
4114
+ react.useEffect(() => {
4115
+ if (!tokenDropdownOpen) return;
4116
+ const handleMouseDown = (e) => {
4117
+ if (pickerRef.current && !pickerRef.current.contains(e.target)) {
4118
+ setTokenDropdownOpen(false);
4119
+ }
4120
+ };
4121
+ document.addEventListener("mousedown", handleMouseDown);
4122
+ return () => document.removeEventListener("mousedown", handleMouseDown);
4123
+ }, [tokenDropdownOpen]);
4124
+ const handleTokenRowClick = react.useCallback(() => {
4125
+ if (hasDropdown) {
4126
+ setTokenDropdownOpen((v) => !v);
4127
+ } else {
4128
+ onAdvanced?.();
4129
+ }
4130
+ }, [hasDropdown, onAdvanced]);
4131
+ const handlePickToken = react.useCallback((opt) => {
4132
+ onSelectToken?.(opt.symbol, opt.chainName, opt.walletId);
4133
+ setTokenDropdownOpen(false);
4134
+ }, [onSelectToken]);
4317
4135
  const startEditing = react.useCallback(() => {
4318
4136
  setInputValue(limit.toFixed(2));
4319
4137
  setEditing(true);
@@ -4336,6 +4154,7 @@ function SetupScreen({
4336
4154
  setLimit(Math.min(availableBalance, effectiveMax));
4337
4155
  setActivePreset("max");
4338
4156
  };
4157
+ const selectedOption = tokenOptions?.find((o) => o.symbol === selectedTokenSymbol);
4339
4158
  return /* @__PURE__ */ jsxRuntime.jsxs(
4340
4159
  ScreenLayout,
4341
4160
  {
@@ -4346,17 +4165,90 @@ function SetupScreen({
4346
4165
  onClick: () => onSetupOneTap(limit),
4347
4166
  disabled: loading,
4348
4167
  loading,
4349
- children: "Approve"
4168
+ children: "Continue"
4350
4169
  }
4351
4170
  ),
4352
4171
  /* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {})
4353
4172
  ] }),
4354
4173
  children: [
4355
4174
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack, onLogout }),
4356
- /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle5(tokens.text), children: "Set Spending Limit" }),
4357
- error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle3(tokens), children: error }),
4358
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: amountRowStyle, children: [
4359
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1 }, children: editing ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: limitValueStyle(tokens.text), children: [
4175
+ /* @__PURE__ */ jsxRuntime.jsx("img", { src: BLINK_LOGO, alt: "Blink", width: 56, height: 56, style: mascotStyle2 }),
4176
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: descriptionStyle(tokens.text), children: "Set a limit for one-tap deposits. You'll still confirm each one with your passkey." }),
4177
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle4(tokens), children: error }),
4178
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: pickerRef, children: [
4179
+ /* @__PURE__ */ jsxRuntime.jsxs(
4180
+ "button",
4181
+ {
4182
+ type: "button",
4183
+ onClick: handleTokenRowClick,
4184
+ style: tokenRowTriggerStyle(tokens, hasDropdown || !!onAdvanced),
4185
+ "aria-expanded": hasDropdown ? tokenDropdownOpen : void 0,
4186
+ "aria-haspopup": hasDropdown ? "listbox" : void 0,
4187
+ children: [
4188
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenRowLabelStyle(tokens.text), children: "Token for one tap" }),
4189
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenRowRightStyle, children: [
4190
+ selectedOption && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: tokenRowSymbolStyle(tokens.textSecondary), children: [
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: [
4196
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "18", cy: "18", r: "18", fill: "#2DB84B" }),
4197
+ /* @__PURE__ */ jsxRuntime.jsx("text", { x: "18", y: "23", textAnchor: "middle", fontSize: "18", fill: "#fff", fontWeight: "700", children: "$" })
4198
+ ] }) }),
4199
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", style: { opacity: 0.5 }, children: tokenDropdownOpen ? /* @__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" }) })
4200
+ ] })
4201
+ ]
4202
+ }
4203
+ ),
4204
+ tokenDropdownOpen && tokenOptions && tokenOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: dropdownOuterStyle(tokens), children: [
4205
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: dropdownLabelStyle(tokens.textMuted), children: "Choose token" }),
4206
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: dropdownInnerStyle(tokens), children: tokenOptions.map((opt, index) => {
4207
+ const selected = opt.symbol === selectedTokenSymbol;
4208
+ const isLast = index === tokenOptions.length - 1;
4209
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4210
+ "button",
4211
+ {
4212
+ type: "button",
4213
+ onClick: () => handlePickToken(opt),
4214
+ style: dropdownRowStyle(tokens, selected, isLast),
4215
+ children: [
4216
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: dropdownRowLeftStyle, children: [
4217
+ /* @__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: "$" }) }),
4218
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: dropdownTokenInfoStyle, children: [
4219
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: dropdownTokenNameRowStyle, children: [
4220
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: dropdownTokenSymbolStyle(tokens.text), children: opt.symbol }),
4221
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: dropdownTokenDotStyle(tokens.textMuted), children: "\xB7" }),
4222
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: dropdownTokenChainStyle(tokens.textMuted), children: opt.chainName })
4223
+ ] }),
4224
+ opt.balance != null && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: dropdownTokenBalanceStyle(tokens.textMuted), children: [
4225
+ "$",
4226
+ opt.balance.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
4227
+ ] })
4228
+ ] })
4229
+ ] }),
4230
+ selected ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "22", height: "22", viewBox: "0 0 22 22", fill: "none", children: [
4231
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "11", fill: tokens.success }),
4232
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7 11l3 3 5-5", stroke: "#fff", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })
4233
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: dropdownRadioEmptyStyle(tokens.border) })
4234
+ ]
4235
+ },
4236
+ tokenOptionKey(opt)
4237
+ );
4238
+ }) })
4239
+ ] })
4240
+ ] }),
4241
+ /* @__PURE__ */ jsxRuntime.jsx(
4242
+ "button",
4243
+ {
4244
+ type: "button",
4245
+ onClick: () => setShowAdvanced((v) => !v),
4246
+ style: advancedToggleStyle(tokens.accent),
4247
+ children: "Advanced"
4248
+ }
4249
+ ),
4250
+ showAdvanced && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4251
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: amountSectionStyle, children: editing ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: limitValueStyle(tokens.text), children: [
4360
4252
  "$",
4361
4253
  /* @__PURE__ */ jsxRuntime.jsx(
4362
4254
  "input",
@@ -4381,63 +4273,94 @@ function SetupScreen({
4381
4273
  onClick: startEditing,
4382
4274
  children: [
4383
4275
  "$",
4384
- limit.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
4276
+ limit.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }),
4277
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", style: { marginLeft: 8, opacity: 0.45 }, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16.47 3.53a2.74 2.74 0 0 1 3.88 0l.12.12a2.74 2.74 0 0 1 0 3.88L8.84 19.16a2 2 0 0 1-.9.52l-4.56 1.3a.75.75 0 0 1-.93-.93l1.3-4.56a2 2 0 0 1 .52-.9L16.47 3.53Z", stroke: tokens.textMuted, strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) })
4385
4278
  ]
4386
4279
  }
4387
4280
  ) }),
4388
- /* @__PURE__ */ jsxRuntime.jsxs(
4389
- "button",
4390
- {
4391
- type: "button",
4392
- onClick: onAdvanced,
4393
- style: tokenIconButtonStyle(!!onAdvanced),
4394
- children: [
4395
- /* @__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: [
4396
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "18", cy: "18", r: "18", fill: "#2DB84B" }),
4397
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: "18", y: "23", textAnchor: "middle", fontSize: "18", fill: "#fff", fontWeight: "700", children: "$" })
4398
- ] }) }),
4399
- /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", style: { opacity: 0.5 }, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 9l6 6 6-6", stroke: tokens.textMuted, strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
4400
- ]
4401
- }
4402
- )
4403
- ] }),
4404
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: presetsRowStyle, children: [
4405
- PRESETS.map((value) => /* @__PURE__ */ jsxRuntime.jsxs(
4406
- "button",
4407
- {
4408
- type: "button",
4409
- onClick: () => selectPreset(value),
4410
- style: presetButtonStyle(tokens, activePreset === value),
4411
- children: [
4412
- "$",
4413
- value.toLocaleString()
4414
- ]
4415
- },
4416
- value
4417
- )),
4418
- /* @__PURE__ */ jsxRuntime.jsx(
4419
- "button",
4420
- {
4421
- type: "button",
4422
- onClick: selectMax,
4423
- style: presetButtonStyle(tokens, activePreset === "max"),
4424
- children: "Max"
4425
- }
4426
- )
4281
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: presetsRowStyle, children: [
4282
+ PRESETS.map((value) => /* @__PURE__ */ jsxRuntime.jsxs(
4283
+ "button",
4284
+ {
4285
+ type: "button",
4286
+ onClick: () => selectPreset(value),
4287
+ style: presetButtonStyle(tokens, activePreset === value),
4288
+ children: [
4289
+ "$",
4290
+ value.toLocaleString()
4291
+ ]
4292
+ },
4293
+ value
4294
+ )),
4295
+ /* @__PURE__ */ jsxRuntime.jsx(
4296
+ "button",
4297
+ {
4298
+ type: "button",
4299
+ onClick: selectMax,
4300
+ style: presetButtonStyle(tokens, activePreset === "max"),
4301
+ children: "Max"
4302
+ }
4303
+ )
4304
+ ] })
4427
4305
  ] })
4428
4306
  ]
4429
4307
  }
4430
4308
  );
4431
4309
  }
4432
- var headingStyle5 = (color) => ({
4433
- fontSize: "1.1rem",
4434
- fontWeight: 700,
4435
- letterSpacing: "-0.02em",
4310
+ var mascotStyle2 = {
4311
+ display: "block",
4312
+ margin: "0 auto 12px"
4313
+ };
4314
+ var descriptionStyle = (color) => ({
4315
+ fontSize: "1.05rem",
4316
+ fontWeight: 600,
4317
+ lineHeight: 1.45,
4436
4318
  color,
4437
- margin: "8px 0 24px",
4319
+ margin: "0 0 24px",
4438
4320
  textAlign: "center"
4439
4321
  });
4440
- var errorBannerStyle3 = (tokens) => ({
4322
+ var tokenRowTriggerStyle = (themeTokens, clickable) => ({
4323
+ display: "flex",
4324
+ alignItems: "center",
4325
+ justifyContent: "space-between",
4326
+ width: "100%",
4327
+ padding: "10px 14px",
4328
+ borderRadius: 999,
4329
+ background: themeTokens.bgCard,
4330
+ border: `1px solid ${themeTokens.border}`,
4331
+ cursor: clickable ? "pointer" : "default",
4332
+ fontFamily: "inherit",
4333
+ marginBottom: 8
4334
+ });
4335
+ var tokenRowLabelStyle = (color) => ({
4336
+ fontSize: "0.95rem",
4337
+ fontWeight: 500,
4338
+ color
4339
+ });
4340
+ var tokenRowRightStyle = {
4341
+ display: "flex",
4342
+ alignItems: "center",
4343
+ gap: 6,
4344
+ flexShrink: 0
4345
+ };
4346
+ var tokenRowSymbolStyle = (color) => ({
4347
+ fontSize: "0.84rem",
4348
+ fontWeight: 500,
4349
+ color
4350
+ });
4351
+ var advancedToggleStyle = (accentColor) => ({
4352
+ display: "block",
4353
+ margin: "4px auto 24px",
4354
+ background: "transparent",
4355
+ border: "none",
4356
+ color: accentColor,
4357
+ fontSize: "0.92rem",
4358
+ fontWeight: 600,
4359
+ fontFamily: "inherit",
4360
+ cursor: "pointer",
4361
+ padding: "4px 8px"
4362
+ });
4363
+ var errorBannerStyle4 = (tokens) => ({
4441
4364
  background: tokens.errorBg,
4442
4365
  border: `1px solid ${tokens.error}66`,
4443
4366
  borderRadius: 16,
@@ -4447,27 +4370,25 @@ var errorBannerStyle3 = (tokens) => ({
4447
4370
  marginBottom: 14,
4448
4371
  lineHeight: 1.5
4449
4372
  });
4450
- var amountRowStyle = {
4451
- display: "flex",
4452
- alignItems: "center",
4453
- justifyContent: "space-between",
4454
- marginBottom: 24,
4455
- gap: 12
4373
+ var amountSectionStyle = {
4374
+ textAlign: "center",
4375
+ marginBottom: 16
4456
4376
  };
4457
4377
  var limitValueStyle = (color) => ({
4458
- fontSize: "2.4rem",
4378
+ fontSize: "2.8rem",
4459
4379
  fontWeight: 700,
4460
4380
  color,
4461
4381
  letterSpacing: "-0.02em",
4462
4382
  display: "flex",
4463
- alignItems: "baseline"
4383
+ alignItems: "center",
4384
+ justifyContent: "center"
4464
4385
  });
4465
4386
  var editableLimitStyle = (color) => ({
4466
4387
  ...limitValueStyle(color),
4467
4388
  cursor: "pointer"
4468
4389
  });
4469
4390
  var limitInputStyle = (color) => ({
4470
- fontSize: "2.4rem",
4391
+ fontSize: "2.8rem",
4471
4392
  fontWeight: 700,
4472
4393
  color,
4473
4394
  background: "transparent",
@@ -4477,25 +4398,117 @@ var limitInputStyle = (color) => ({
4477
4398
  width: "6ch",
4478
4399
  fontFamily: "inherit",
4479
4400
  padding: 0,
4480
- letterSpacing: "-0.02em"
4401
+ letterSpacing: "-0.02em",
4402
+ textAlign: "center"
4481
4403
  });
4482
- var tokenIconButtonStyle = (clickable) => ({
4404
+ var tokenIconWrapStyle = {
4405
+ position: "relative",
4406
+ width: 36,
4407
+ height: 36
4408
+ };
4409
+ var dropdownOuterStyle = (themeTokens) => ({
4410
+ marginTop: 4,
4411
+ marginBottom: 12,
4412
+ background: themeTokens.bgCard,
4413
+ border: `1px solid ${themeTokens.border}`,
4414
+ borderRadius: themeTokens.radiusLg,
4415
+ boxShadow: themeTokens.shadowLg,
4416
+ padding: "12px 14px 14px"
4417
+ });
4418
+ var dropdownLabelStyle = (color) => ({
4419
+ fontSize: "0.78rem",
4420
+ fontWeight: 500,
4421
+ color,
4422
+ marginBottom: 8
4423
+ });
4424
+ var dropdownInnerStyle = (themeTokens) => ({
4425
+ background: themeTokens.bgInput,
4426
+ border: `1px solid ${themeTokens.border}`,
4427
+ borderRadius: themeTokens.radiusLg,
4428
+ overflow: "hidden"
4429
+ });
4430
+ var dropdownRowStyle = (themeTokens, isSelected, isLast) => ({
4483
4431
  display: "flex",
4484
4432
  alignItems: "center",
4485
- gap: 4,
4486
- background: "transparent",
4433
+ justifyContent: "space-between",
4434
+ width: "100%",
4435
+ padding: "14px 16px",
4436
+ background: isSelected ? `${themeTokens.accent}18` : "transparent",
4487
4437
  border: "none",
4488
- cursor: clickable ? "pointer" : "default",
4489
- padding: 0,
4490
- flexShrink: 0
4438
+ borderBottom: isLast ? "none" : `1px solid ${themeTokens.border}`,
4439
+ cursor: "pointer",
4440
+ fontFamily: "inherit",
4441
+ textAlign: "left",
4442
+ outline: "none"
4491
4443
  });
4492
- var tokenIconWrapStyle = {
4493
- position: "relative",
4444
+ var dropdownRowLeftStyle = {
4445
+ display: "flex",
4446
+ alignItems: "center",
4447
+ gap: 12,
4448
+ minWidth: 0,
4449
+ flex: 1
4450
+ };
4451
+ var dropdownTokenIconStyle = (themeTokens, hasLogo) => ({
4494
4452
  width: 36,
4495
- height: 36
4453
+ height: 36,
4454
+ borderRadius: "50%",
4455
+ border: hasLogo ? "none" : `1.5px solid ${themeTokens.border}`,
4456
+ display: "flex",
4457
+ alignItems: "center",
4458
+ justifyContent: "center",
4459
+ flexShrink: 0,
4460
+ overflow: "hidden"
4461
+ });
4462
+ var dropdownTokenLogoStyle = {
4463
+ width: 36,
4464
+ height: 36,
4465
+ borderRadius: "50%",
4466
+ objectFit: "cover"
4496
4467
  };
4468
+ var dropdownTokenFallbackStyle = (color) => ({
4469
+ fontSize: "1rem",
4470
+ fontWeight: 700,
4471
+ color
4472
+ });
4473
+ var dropdownTokenInfoStyle = {
4474
+ display: "flex",
4475
+ flexDirection: "column",
4476
+ gap: 2,
4477
+ minWidth: 0
4478
+ };
4479
+ var dropdownTokenNameRowStyle = {
4480
+ display: "flex",
4481
+ alignItems: "center",
4482
+ gap: 4
4483
+ };
4484
+ var dropdownTokenSymbolStyle = (color) => ({
4485
+ fontSize: "0.92rem",
4486
+ fontWeight: 600,
4487
+ color
4488
+ });
4489
+ var dropdownTokenDotStyle = (color) => ({
4490
+ fontSize: "0.8rem",
4491
+ color
4492
+ });
4493
+ var dropdownTokenChainStyle = (color) => ({
4494
+ fontSize: "0.84rem",
4495
+ fontWeight: 400,
4496
+ color
4497
+ });
4498
+ var dropdownTokenBalanceStyle = (color) => ({
4499
+ fontSize: "0.78rem",
4500
+ color
4501
+ });
4502
+ var dropdownRadioEmptyStyle = (borderColor) => ({
4503
+ width: 22,
4504
+ height: 22,
4505
+ borderRadius: "50%",
4506
+ border: `2px solid ${borderColor}`,
4507
+ flexShrink: 0
4508
+ });
4497
4509
  var presetsRowStyle = {
4498
4510
  display: "flex",
4511
+ justifyContent: "center",
4499
4512
  gap: 10,
4500
4513
  marginBottom: 24
4501
4514
  };
@@ -4528,10 +4541,10 @@ function SetupStatusScreen({
4528
4541
  if (complete) {
4529
4542
  return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { footer: /* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {}), children: [
4530
4543
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack: onContinue }),
4531
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle4, children: [
4532
- /* @__PURE__ */ jsxRuntime.jsx("img", { src: BLINK_LOGO, alt: "Blink", style: mascotStyle2 }),
4544
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle5, children: [
4545
+ /* @__PURE__ */ jsxRuntime.jsx("img", { src: BLINK_LOGO, alt: "Blink", style: mascotStyle3 }),
4533
4546
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle6(tokens.text), children: "Done!" }),
4534
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle4(tokens.textSecondary), children: "Return to the app to try one-tap deposits." })
4547
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle6(tokens.textSecondary), children: "Return to the app to try one-tap deposits." })
4535
4548
  ] })
4536
4549
  ] });
4537
4550
  }
@@ -4541,16 +4554,16 @@ function SetupStatusScreen({
4541
4554
  ];
4542
4555
  return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { children: [
4543
4556
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
4544
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle4, children: [
4557
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle5, children: [
4545
4558
  /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 48 }),
4546
4559
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle6(tokens.text), children: "Setting up One-Tap..." }),
4547
- error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle4(tokens), children: error }),
4560
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle5(tokens), children: error }),
4548
4561
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: stepsWrapStyle, children: /* @__PURE__ */ jsxRuntime.jsx(StepList, { steps }) }),
4549
4562
  /* @__PURE__ */ jsxRuntime.jsx("p", { style: waitHintStyle(tokens.textMuted), children: "Usually takes a few seconds" })
4550
4563
  ] })
4551
4564
  ] });
4552
4565
  }
4553
- var contentStyle4 = {
4566
+ var contentStyle5 = {
4554
4567
  flex: 1,
4555
4568
  display: "flex",
4556
4569
  flexDirection: "column",
@@ -4559,7 +4572,7 @@ var contentStyle4 = {
4559
4572
  textAlign: "center",
4560
4573
  padding: "0 24px 32px"
4561
4574
  };
4562
- var mascotStyle2 = {
4575
+ var mascotStyle3 = {
4563
4576
  width: 56,
4564
4577
  height: 56
4565
4578
  };
@@ -4570,14 +4583,14 @@ var headingStyle6 = (color) => ({
4570
4583
  color,
4571
4584
  margin: "20px 0 8px"
4572
4585
  });
4573
- var subtitleStyle4 = (color) => ({
4586
+ var subtitleStyle6 = (color) => ({
4574
4587
  fontSize: "0.9rem",
4575
4588
  color,
4576
4589
  margin: "0 0 28px",
4577
4590
  lineHeight: 1.5,
4578
4591
  maxWidth: 260
4579
4592
  });
4580
- var errorBannerStyle4 = (tokens) => ({
4593
+ var errorBannerStyle5 = (tokens) => ({
4581
4594
  background: tokens.errorBg,
4582
4595
  border: `1px solid ${tokens.error}66`,
4583
4596
  borderRadius: 16,
@@ -4657,7 +4670,7 @@ function DepositScreen({
4657
4670
  /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: pickerRef, style: depositCardWrapStyle, children: [
4658
4671
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4659
4672
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: depositLabelStyle(tokens.textMuted), children: "Depositing" }),
4660
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: amountRowStyle2, children: [
4673
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: amountRowStyle, children: [
4661
4674
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: amountValueStyle(tokens.text), children: [
4662
4675
  "$",
4663
4676
  amount.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
@@ -4667,7 +4680,7 @@ function DepositScreen({
4667
4680
  {
4668
4681
  type: "button",
4669
4682
  onClick: onSelectToken,
4670
- style: tokenIconButtonStyle2(!!onSelectToken),
4683
+ style: tokenIconButtonStyle(!!onSelectToken),
4671
4684
  children: [
4672
4685
  /* @__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: [
4673
4686
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "18", cy: "18", r: "18", fill: "#2DB84B" }),
@@ -4782,7 +4795,7 @@ function DepositScreen({
4782
4795
  minDepositFloor.toFixed(2),
4783
4796
  " to deposit via One-Tap."
4784
4797
  ] }),
4785
- error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle5(tokens), children: error })
4798
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle6(tokens), children: error })
4786
4799
  ]
4787
4800
  }
4788
4801
  );
@@ -4797,7 +4810,7 @@ var depositLabelStyle = (color) => ({
4797
4810
  color,
4798
4811
  marginBottom: 4
4799
4812
  });
4800
- var amountRowStyle2 = {
4813
+ var amountRowStyle = {
4801
4814
  display: "flex",
4802
4815
  alignItems: "center",
4803
4816
  justifyContent: "space-between",
@@ -4809,7 +4822,7 @@ var amountValueStyle = (color) => ({
4809
4822
  letterSpacing: "-0.02em",
4810
4823
  color
4811
4824
  });
4812
- var tokenIconButtonStyle2 = (clickable) => ({
4825
+ var tokenIconButtonStyle = (clickable) => ({
4813
4826
  display: "flex",
4814
4827
  alignItems: "center",
4815
4828
  gap: 4,
@@ -4968,7 +4981,7 @@ var spendingLimitStyle = (color) => ({
4968
4981
  color,
4969
4982
  marginBottom: 8
4970
4983
  });
4971
- var errorBannerStyle5 = (tokens) => ({
4984
+ var errorBannerStyle6 = (tokens) => ({
4972
4985
  background: tokens.errorBg,
4973
4986
  border: `1px solid ${tokens.error}66`,
4974
4987
  borderRadius: 16,
@@ -5013,7 +5026,7 @@ function SuccessScreen({
5013
5026
  ] }),
5014
5027
  children: [
5015
5028
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
5016
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle5, children: [
5029
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle6, children: [
5017
5030
  succeeded ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5018
5031
  /* @__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("path", { d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z", fill: tokens.success }) }) }),
5019
5032
  /* @__PURE__ */ jsxRuntime.jsxs("h2", { style: headingStyle7(tokens.text), children: [
@@ -5021,14 +5034,14 @@ function SuccessScreen({
5021
5034
  amount.toFixed(2),
5022
5035
  " deposited"
5023
5036
  ] }),
5024
- merchantName && /* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle5(tokens.textSecondary), children: [
5037
+ merchantName && /* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle7(tokens.textSecondary), children: [
5025
5038
  "to ",
5026
5039
  merchantName
5027
5040
  ] })
5028
5041
  ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5029
5042
  /* @__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 }) }) }),
5030
5043
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle7(tokens.text), children: "Transfer failed" }),
5031
- error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle5(tokens.error), children: error })
5044
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle7(tokens.error), children: error })
5032
5045
  ] }),
5033
5046
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryCardStyle(tokens), children: [
5034
5047
  sourceName && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryRowStyle, children: [
@@ -5060,7 +5073,7 @@ function SuccessScreen({
5060
5073
  }
5061
5074
  );
5062
5075
  }
5063
- var contentStyle5 = {
5076
+ var contentStyle6 = {
5064
5077
  flex: 1,
5065
5078
  display: "flex",
5066
5079
  flexDirection: "column",
@@ -5074,7 +5087,7 @@ var headingStyle7 = (color) => ({
5074
5087
  color,
5075
5088
  margin: "20px 0 4px"
5076
5089
  });
5077
- var subtitleStyle5 = (color) => ({
5090
+ var subtitleStyle7 = (color) => ({
5078
5091
  fontSize: "0.9rem",
5079
5092
  color,
5080
5093
  margin: "0 0 20px"
@@ -5188,7 +5201,7 @@ function SelectSourceScreen({
5188
5201
  onLogout
5189
5202
  }
5190
5203
  ),
5191
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle6(tokens.textMuted), children: "Choose which chain and token to pay from." }),
5204
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle8(tokens.textMuted), children: "Choose which chain and token to pay from." }),
5192
5205
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle4(tokens.textSecondary), children: "Chain" }),
5193
5206
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: optionListStyle, children: choices.map((chain) => {
5194
5207
  const isSelected = chain.chainName === selectedChainName;
@@ -5249,7 +5262,7 @@ function SelectSourceScreen({
5249
5262
  }
5250
5263
  );
5251
5264
  }
5252
- var subtitleStyle6 = (color) => ({
5265
+ var subtitleStyle8 = (color) => ({
5253
5266
  fontSize: "0.85rem",
5254
5267
  color,
5255
5268
  margin: "0 0 20px",
@@ -5392,7 +5405,7 @@ function AdvancedSourceScreen({
5392
5405
  }
5393
5406
  ),
5394
5407
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle8(tokens.text), children: "Set up One-Tap deposits" }),
5395
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle7(tokens.textSecondary), children: "Select a token source for your One-Tap deposits." }),
5408
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle9(tokens.textSecondary), children: "Select a token source for your One-Tap deposits." }),
5396
5409
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle5(tokens.textSecondary), children: "Select tokens to approve" }),
5397
5410
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: chainListStyle, children: choices.map((chain) => {
5398
5411
  const isExpanded = expandedChain === chain.chainName;
@@ -5462,7 +5475,7 @@ var headingStyle8 = (color) => ({
5462
5475
  color,
5463
5476
  margin: "8px 0 4px"
5464
5477
  });
5465
- var subtitleStyle7 = (color) => ({
5478
+ var subtitleStyle9 = (color) => ({
5466
5479
  fontSize: "0.86rem",
5467
5480
  color,
5468
5481
  margin: "0 0 20px",
@@ -5590,15 +5603,15 @@ function TransferStatusScreen({
5590
5603
  const steps = buildSteps(phase);
5591
5604
  return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { footer: /* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {}), children: [
5592
5605
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
5593
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle6, children: [
5606
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle7, children: [
5594
5607
  /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 64 }),
5595
5608
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle9(tokens.text), children: "Depositing your money..." }),
5596
- error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle6(tokens), children: error }),
5609
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle7(tokens), children: error }),
5597
5610
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: stepsWrapStyle2, children: /* @__PURE__ */ jsxRuntime.jsx(StepList, { steps }) })
5598
5611
  ] })
5599
5612
  ] });
5600
5613
  }
5601
- var contentStyle6 = {
5614
+ var contentStyle7 = {
5602
5615
  flex: 1,
5603
5616
  display: "flex",
5604
5617
  flexDirection: "column",
@@ -5614,7 +5627,7 @@ var headingStyle9 = (color) => ({
5614
5627
  color,
5615
5628
  margin: "20px 0 16px"
5616
5629
  });
5617
- var errorBannerStyle6 = (tokens) => ({
5630
+ var errorBannerStyle7 = (tokens) => ({
5618
5631
  background: tokens.errorBg,
5619
5632
  border: `1px solid ${tokens.error}66`,
5620
5633
  borderRadius: 16,
@@ -5668,14 +5681,14 @@ function OpenWalletScreen({
5668
5681
  ] }),
5669
5682
  children: [
5670
5683
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
5671
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle7, children: [
5684
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle8, children: [
5672
5685
  /* @__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 }) }),
5673
5686
  /* @__PURE__ */ jsxRuntime.jsxs("h2", { style: headingStyle10(tokens.text), children: [
5674
5687
  "Setting up ",
5675
5688
  displayName,
5676
5689
  "..."
5677
5690
  ] }),
5678
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle8(tokens.textSecondary), children: "Approve the connection in your wallet extension." }),
5691
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle10(tokens.textSecondary), children: "Approve the connection in your wallet extension." }),
5679
5692
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: waitingBadgeStyle(tokens), children: [
5680
5693
  /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 14 }),
5681
5694
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Waiting for authorization..." })
@@ -5701,10 +5714,10 @@ function OpenWalletScreen({
5701
5714
  ] }),
5702
5715
  children: [
5703
5716
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack, onLogout }),
5704
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle7, children: [
5717
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle8, children: [
5705
5718
  /* @__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 }) }),
5706
5719
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle10(tokens.text), children: loading ? "Connecting..." : `Open ${displayName}` }),
5707
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle8(tokens.textSecondary), children: loading ? "Creating transfer and preparing your wallet link..." : `Continue in ${displayName} to authorize this connection.` }),
5720
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle10(tokens.textSecondary), children: loading ? "Creating transfer and preparing your wallet link..." : `Continue in ${displayName} to authorize this connection.` }),
5708
5721
  !loading && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: waitingBadgeStyle(tokens), children: [
5709
5722
  /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 14 }),
5710
5723
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Waiting for authorization..." })
@@ -5714,7 +5727,7 @@ function OpenWalletScreen({
5714
5727
  }
5715
5728
  );
5716
5729
  }
5717
- var contentStyle7 = {
5730
+ var contentStyle8 = {
5718
5731
  flex: 1,
5719
5732
  display: "flex",
5720
5733
  flexDirection: "column",
@@ -5751,7 +5764,7 @@ var headingStyle10 = (color) => ({
5751
5764
  color,
5752
5765
  margin: "20px 0 8px"
5753
5766
  });
5754
- var subtitleStyle8 = (color) => ({
5767
+ var subtitleStyle10 = (color) => ({
5755
5768
  fontSize: "0.9rem",
5756
5769
  color,
5757
5770
  margin: "0 0 24px",
@@ -5800,10 +5813,10 @@ function ConfirmSignScreen({
5800
5813
  ] }),
5801
5814
  children: [
5802
5815
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
5803
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle8, children: [
5816
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle9, children: [
5804
5817
  logoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoSrc, alt: displayName, style: logoStyle3 }) : /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 48 }),
5805
5818
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle11(tokens.text), children: "Wallet authorized" }),
5806
- /* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle9(tokens.textSecondary), children: [
5819
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle11(tokens.textSecondary), children: [
5807
5820
  displayName,
5808
5821
  " approved the connection. Tap below to confirm your payment."
5809
5822
  ] }),
@@ -5816,7 +5829,7 @@ function ConfirmSignScreen({
5816
5829
  }
5817
5830
  );
5818
5831
  }
5819
- var contentStyle8 = {
5832
+ var contentStyle9 = {
5820
5833
  flex: 1,
5821
5834
  display: "flex",
5822
5835
  flexDirection: "column",
@@ -5838,7 +5851,7 @@ var headingStyle11 = (color) => ({
5838
5851
  color,
5839
5852
  margin: "20px 0 8px"
5840
5853
  });
5841
- var subtitleStyle9 = (color) => ({
5854
+ var subtitleStyle11 = (color) => ({
5842
5855
  fontSize: "0.9rem",
5843
5856
  color,
5844
5857
  margin: "0 0 24px",
@@ -5922,7 +5935,7 @@ function TokenPickerScreen({
5922
5935
  {
5923
5936
  type: "button",
5924
5937
  onClick: onBack,
5925
- style: tokenIconButtonStyle3,
5938
+ style: tokenIconButtonStyle2,
5926
5939
  children: [
5927
5940
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenIconWrapStyle3, 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: [
5928
5941
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "18", cy: "18", r: "18", fill: "#2DB84B" }),
@@ -5985,7 +5998,7 @@ var depositAmountStyle = (color) => ({
5985
5998
  letterSpacing: "-0.02em",
5986
5999
  color
5987
6000
  });
5988
- var tokenIconButtonStyle3 = {
6001
+ var tokenIconButtonStyle2 = {
5989
6002
  display: "flex",
5990
6003
  alignItems: "center",
5991
6004
  gap: 4,
@@ -6108,60 +6121,243 @@ var selectCircleSelectedStyle = (color) => ({
6108
6121
  justifyContent: "center",
6109
6122
  flexShrink: 0
6110
6123
  });
6124
+ function entryKey(entry) {
6125
+ return `${entry.sourceChainId}-${entry.tokenAddress.toLowerCase()}`;
6126
+ }
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
+ }
6111
6150
  function GuestTokenPickerScreen({
6112
6151
  entries,
6113
6152
  loading,
6114
6153
  setting,
6115
6154
  depositAmount,
6116
6155
  error,
6156
+ pendingEntry,
6157
+ quoteFee,
6158
+ quoteLoading,
6117
6159
  onSelect,
6118
- onBack
6160
+ onConfirm,
6161
+ onBack,
6162
+ defaultTokenListExpanded = false
6119
6163
  }) {
6120
6164
  const { tokens: t } = useBlinkConfig();
6165
+ const pendingKey = pendingEntry ? entryKey(pendingEntry) : null;
6166
+ const [tokenListOpen, setTokenListOpen] = react.useState(defaultTokenListExpanded);
6167
+ const pickerRef = react.useRef(null);
6168
+ react.useEffect(() => {
6169
+ if (!tokenListOpen) return;
6170
+ const handleMouseDown = (e) => {
6171
+ if (pickerRef.current && !pickerRef.current.contains(e.target)) {
6172
+ setTokenListOpen(false);
6173
+ }
6174
+ };
6175
+ document.addEventListener("mousedown", handleMouseDown);
6176
+ return () => document.removeEventListener("mousedown", handleMouseDown);
6177
+ }, [tokenListOpen]);
6121
6178
  if (loading) {
6122
6179
  return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { children: [
6123
- /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { title: "Select Token", onBack }),
6180
+ /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack }),
6124
6181
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: loadingWrapStyle, children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { label: "Loading balances..." }) })
6125
6182
  ] });
6126
6183
  }
6127
- return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { footer: /* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {}), children: [
6128
- /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { title: "Select Token", onBack }),
6129
- depositAmount != null && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: depositHeaderStyle, children: [
6130
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: depositLabelStyle3(t.textMuted), children: "Depositing" }),
6131
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: depositAmountStyle2(t.text), children: [
6132
- "$",
6133
- depositAmount.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
6134
- ] })
6135
- ] }),
6136
- error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: errorStyle3(t.error), children: error }),
6137
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: sectionLabelStyle2(t.textMuted), children: "Choose token to pay with" }),
6138
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenListStyle3, children: entries.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs(
6139
- "button",
6140
- {
6141
- type: "button",
6142
- onClick: () => onSelect(entry),
6143
- disabled: setting,
6144
- style: tokenRowStyle3(t, setting),
6145
- children: [
6146
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenIconCircleStyle3(t, !!TOKEN_LOGOS[entry.tokenSymbol]), children: TOKEN_LOGOS[entry.tokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: TOKEN_LOGOS[entry.tokenSymbol], alt: entry.tokenSymbol, style: tokenLogoImgStyle3 }) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenIconTextStyle3(t.textMuted), children: "$" }) }),
6147
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenInfoStyle3, children: [
6148
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenNameRowStyle2, children: [
6149
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenSymbolTextStyle2(t.text), children: entry.tokenSymbol }),
6150
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenChainDotStyle2(t.textMuted), children: "\xB7" }),
6151
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenChainTextStyle2(t.textMuted), children: entry.chainName })
6152
- ] }),
6153
- /* @__PURE__ */ jsxRuntime.jsxs("span", { style: tokenBalanceStyle2(t.textMuted), children: [
6154
- "$",
6155
- entry.balance.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
6184
+ const rowBusy = setting || quoteLoading;
6185
+ const displayEntry = pendingEntry ?? entries[0] ?? null;
6186
+ const canConfirm = Boolean(quoteFee && pendingEntry && !quoteLoading);
6187
+ const feeLine = (() => {
6188
+ if (quoteLoading && pendingEntry) {
6189
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: feeRowContainerStyle, "aria-live": "polite", children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: feeRowLabelStyle(t.textMuted), children: "Getting fee estimate\u2026" }) });
6190
+ }
6191
+ if (quoteFee) {
6192
+ const feeText = isPreciseMoneyNonPositive(quoteFee) ? formatNonPositiveFeeDisplay(quoteFee) : formatPreciseMoneyForDisplay(quoteFee);
6193
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: feeRowContainerStyle, "aria-live": "polite", children: [
6194
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: feeRowLabelStyle(t.textMuted), children: "Fee estimate: " }),
6195
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: feeRowAmountStyle(t.textSecondary), children: feeText })
6196
+ ] });
6197
+ }
6198
+ return null;
6199
+ })();
6200
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6201
+ ScreenLayout,
6202
+ {
6203
+ footer: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6204
+ canConfirm && /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: () => void onConfirm(), loading: setting, disabled: setting, children: "Continue" }),
6205
+ /* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {})
6206
+ ] }),
6207
+ children: [
6208
+ /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack }),
6209
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: pickerRef, children: [
6210
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: depositCardSurfaceStyle(t, tokenListOpen), children: [
6211
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: depositLabelStyle3(t.textMuted), children: "Deposit" }),
6212
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: amountBandStyle, children: [
6213
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: amountLeftColStyle, children: [
6214
+ depositAmount != null && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: depositAmountStyle2(t.text), children: [
6215
+ "$",
6216
+ depositAmount.toLocaleString("en-US", {
6217
+ minimumFractionDigits: 0,
6218
+ maximumFractionDigits: 2
6219
+ })
6220
+ ] }),
6221
+ feeLine
6222
+ ] }),
6223
+ /* @__PURE__ */ jsxRuntime.jsxs(
6224
+ "button",
6225
+ {
6226
+ type: "button",
6227
+ onClick: () => entries.length > 0 && setTokenListOpen((o) => !o),
6228
+ disabled: entries.length === 0 || rowBusy,
6229
+ style: tokenTriggerStyle(t, entries.length > 0 && !rowBusy),
6230
+ "aria-expanded": tokenListOpen,
6231
+ "aria-haspopup": "listbox",
6232
+ children: [
6233
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenTriggerIconsStyle, children: pendingEntry && TOKEN_LOGOS[pendingEntry.tokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsx(
6234
+ "img",
6235
+ {
6236
+ src: TOKEN_LOGOS[pendingEntry.tokenSymbol],
6237
+ alt: "",
6238
+ width: 28,
6239
+ height: 28,
6240
+ style: triggerLogoStyle(0)
6241
+ }
6242
+ ) : entries[0] && entries[1] && TOKEN_LOGOS[entries[0].tokenSymbol] && TOKEN_LOGOS[entries[1].tokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6243
+ /* @__PURE__ */ jsxRuntime.jsx(
6244
+ "img",
6245
+ {
6246
+ src: TOKEN_LOGOS[entries[0].tokenSymbol],
6247
+ alt: "",
6248
+ width: 28,
6249
+ height: 28,
6250
+ style: triggerLogoStyle(0)
6251
+ }
6252
+ ),
6253
+ /* @__PURE__ */ jsxRuntime.jsx(
6254
+ "img",
6255
+ {
6256
+ src: TOKEN_LOGOS[entries[1].tokenSymbol],
6257
+ alt: "",
6258
+ width: 28,
6259
+ height: 28,
6260
+ style: triggerLogoStyle(14)
6261
+ }
6262
+ )
6263
+ ] }) : displayEntry && TOKEN_LOGOS[displayEntry.tokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsx(
6264
+ "img",
6265
+ {
6266
+ src: TOKEN_LOGOS[displayEntry.tokenSymbol],
6267
+ alt: "",
6268
+ width: 28,
6269
+ height: 28,
6270
+ style: triggerLogoStyle(0)
6271
+ }
6272
+ ) : null }),
6273
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", style: { opacity: 0.5 }, children: tokenListOpen ? /* @__PURE__ */ jsxRuntime.jsx(
6274
+ "path",
6275
+ {
6276
+ d: "M18 15l-6-6-6 6",
6277
+ stroke: t.textMuted,
6278
+ strokeWidth: "2.5",
6279
+ strokeLinecap: "round",
6280
+ strokeLinejoin: "round"
6281
+ }
6282
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
6283
+ "path",
6284
+ {
6285
+ d: "M6 9l6 6 6-6",
6286
+ stroke: t.textMuted,
6287
+ strokeWidth: "2.5",
6288
+ strokeLinecap: "round",
6289
+ strokeLinejoin: "round"
6290
+ }
6291
+ ) })
6292
+ ]
6293
+ }
6294
+ )
6156
6295
  ] })
6157
6296
  ] }),
6158
- /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: chevronStyle, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z", fill: t.textMuted }) })
6159
- ]
6160
- },
6161
- `${entry.chainId}-${entry.tokenAddress}`
6162
- )) }),
6163
- entries.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { style: emptyStyle(t.textMuted), children: "No supported tokens found in your wallet. Please ensure you have USDC or USDT." })
6164
- ] });
6297
+ tokenListOpen && entries.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenDropdownOuterStyle(t), children: [
6298
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: accountDropdownLabelStyle2(t.textMuted), children: "Choose token" }),
6299
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenDropdownInnerStyle(t), children: entries.map((entry, index) => {
6300
+ const selected = pendingKey === entryKey(entry);
6301
+ const isLast = index === entries.length - 1;
6302
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6303
+ "button",
6304
+ {
6305
+ type: "button",
6306
+ onClick: () => {
6307
+ void onSelect(entry);
6308
+ },
6309
+ disabled: rowBusy,
6310
+ style: pickerRowStyle(t, selected, isLast),
6311
+ children: [
6312
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: pickerRowLeftStyle, children: [
6313
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenIconCircleStyle3(t, !!TOKEN_LOGOS[entry.tokenSymbol]), children: TOKEN_LOGOS[entry.tokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsx(
6314
+ "img",
6315
+ {
6316
+ src: TOKEN_LOGOS[entry.tokenSymbol],
6317
+ alt: entry.tokenSymbol,
6318
+ style: tokenLogoImgStyle3
6319
+ }
6320
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenIconTextStyle3(t.textMuted), children: "$" }) }),
6321
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: pickerRowInfoStyle, children: [
6322
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenNameRowStyle2, children: [
6323
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenSymbolTextStyle2(t.text), children: entry.tokenSymbol }),
6324
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenChainDotStyle2(t.textMuted), children: "\xB7" }),
6325
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenChainTextStyle2(t.textMuted), children: entry.chainName })
6326
+ ] }),
6327
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: tokenBalanceStyle2(t.textMuted), children: [
6328
+ "$",
6329
+ entry.balance.toLocaleString("en-US", {
6330
+ minimumFractionDigits: 2,
6331
+ maximumFractionDigits: 2
6332
+ })
6333
+ ] })
6334
+ ] })
6335
+ ] }),
6336
+ selected ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "22", height: "22", viewBox: "0 0 22 22", fill: "none", children: [
6337
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "11", fill: t.success }),
6338
+ /* @__PURE__ */ jsxRuntime.jsx(
6339
+ "path",
6340
+ {
6341
+ d: "M7 11l3 3 5-5",
6342
+ stroke: "#fff",
6343
+ strokeWidth: "2",
6344
+ strokeLinecap: "round",
6345
+ strokeLinejoin: "round"
6346
+ }
6347
+ )
6348
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: radioEmptyStyle2(t.border) })
6349
+ ]
6350
+ },
6351
+ entryKey(entry)
6352
+ );
6353
+ }) })
6354
+ ] })
6355
+ ] }),
6356
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: errorStyle3(t.error), children: error }),
6357
+ entries.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { style: emptyStyle(t.textMuted), children: "No supported tokens found in your wallet. Please ensure you have USDC or USDT." })
6358
+ ]
6359
+ }
6360
+ );
6165
6361
  }
6166
6362
  var loadingWrapStyle = {
6167
6363
  textAlign: "center",
@@ -6171,52 +6367,133 @@ var loadingWrapStyle = {
6171
6367
  alignItems: "center",
6172
6368
  justifyContent: "center"
6173
6369
  };
6174
- var depositHeaderStyle = {
6175
- marginBottom: 20
6176
- };
6370
+ var depositCardSurfaceStyle = (tokens, listOpen) => ({
6371
+ background: tokens.bgCard,
6372
+ border: `1px solid ${tokens.border}`,
6373
+ borderRadius: tokens.radiusLg,
6374
+ padding: "16px 20px",
6375
+ marginBottom: listOpen ? 4 : 16
6376
+ });
6177
6377
  var depositLabelStyle3 = (color) => ({
6178
6378
  fontSize: "0.75rem",
6179
6379
  fontWeight: 500,
6180
6380
  color,
6181
6381
  marginBottom: 4
6182
6382
  });
6383
+ var amountBandStyle = {
6384
+ display: "flex",
6385
+ alignItems: "flex-start",
6386
+ justifyContent: "space-between",
6387
+ gap: 12
6388
+ };
6389
+ var amountLeftColStyle = {
6390
+ flex: 1,
6391
+ minWidth: 0
6392
+ };
6183
6393
  var depositAmountStyle2 = (color) => ({
6184
6394
  fontSize: "2.4rem",
6185
6395
  fontWeight: 700,
6186
6396
  letterSpacing: "-0.02em",
6187
- color
6188
- });
6189
- var errorStyle3 = (color) => ({
6190
- fontSize: "0.84rem",
6191
6397
  color,
6192
- margin: "0 0 12px",
6193
- lineHeight: 1.5
6398
+ lineHeight: 1.05
6194
6399
  });
6195
- var sectionLabelStyle2 = (color) => ({
6400
+ var feeRowContainerStyle = {
6196
6401
  fontSize: "0.84rem",
6197
6402
  fontWeight: 500,
6403
+ marginTop: 6
6404
+ };
6405
+ var feeRowLabelStyle = (color) => ({ color });
6406
+ var feeRowAmountStyle = (color) => ({
6198
6407
  color,
6199
- marginBottom: 12
6408
+ fontVariantNumeric: "tabular-nums"
6200
6409
  });
6201
- var tokenListStyle3 = {
6410
+ var tokenTriggerStyle = (tokens, interactive) => ({
6202
6411
  display: "flex",
6203
- flexDirection: "column",
6204
- gap: 10
6412
+ alignItems: "center",
6413
+ gap: 6,
6414
+ flexShrink: 0,
6415
+ marginTop: 4,
6416
+ padding: "6px 10px",
6417
+ background: tokens.bgInput,
6418
+ border: `1px solid ${tokens.border}`,
6419
+ borderRadius: 999,
6420
+ cursor: interactive ? "pointer" : "default",
6421
+ fontFamily: "inherit"
6422
+ });
6423
+ var tokenTriggerIconsStyle = {
6424
+ position: "relative",
6425
+ width: 40,
6426
+ height: 28
6205
6427
  };
6206
- var tokenRowStyle3 = (tokens, disabled) => ({
6428
+ var triggerLogoStyle = (left) => ({
6429
+ position: "absolute",
6430
+ left,
6431
+ top: 0,
6432
+ borderRadius: "50%",
6433
+ objectFit: "cover",
6434
+ border: "2px solid rgba(255,255,255,0.9)",
6435
+ boxSizing: "content-box"
6436
+ });
6437
+ var tokenDropdownOuterStyle = (tokens) => ({
6438
+ marginTop: 4,
6439
+ marginBottom: 16,
6440
+ background: tokens.bgCard,
6441
+ border: `1px solid ${tokens.border}`,
6442
+ borderRadius: tokens.radiusLg,
6443
+ boxShadow: tokens.shadowLg,
6444
+ padding: "12px 14px 14px"
6445
+ });
6446
+ var accountDropdownLabelStyle2 = (color) => ({
6447
+ fontSize: "0.78rem",
6448
+ fontWeight: 500,
6449
+ color,
6450
+ marginBottom: 8
6451
+ });
6452
+ var tokenDropdownInnerStyle = (tokens) => ({
6453
+ background: tokens.bgInput,
6454
+ border: `1px solid ${tokens.border}`,
6455
+ borderRadius: tokens.radiusLg,
6456
+ overflow: "hidden"
6457
+ });
6458
+ var pickerRowStyle = (tokens, isSelected, isLast) => ({
6207
6459
  display: "flex",
6208
6460
  alignItems: "center",
6209
- gap: 14,
6461
+ justifyContent: "space-between",
6462
+ width: "100%",
6210
6463
  padding: "14px 16px",
6211
- background: tokens.bgInput,
6212
- border: `1px solid ${tokens.border}`,
6213
- borderRadius: 16,
6214
- cursor: disabled ? "default" : "pointer",
6464
+ background: isSelected ? `${tokens.accent}18` : "transparent",
6465
+ border: "none",
6466
+ borderBottom: isLast ? "none" : `1px solid ${tokens.border}`,
6467
+ cursor: "pointer",
6215
6468
  fontFamily: "inherit",
6216
6469
  textAlign: "left",
6217
- width: "100%",
6218
- opacity: disabled ? 0.6 : 1,
6219
- transition: "opacity 0.15s ease"
6470
+ outline: "none"
6471
+ });
6472
+ var pickerRowLeftStyle = {
6473
+ display: "flex",
6474
+ alignItems: "center",
6475
+ gap: 12,
6476
+ minWidth: 0,
6477
+ flex: 1
6478
+ };
6479
+ var pickerRowInfoStyle = {
6480
+ display: "flex",
6481
+ flexDirection: "column",
6482
+ gap: 2,
6483
+ minWidth: 0
6484
+ };
6485
+ var radioEmptyStyle2 = (borderColor) => ({
6486
+ width: 22,
6487
+ height: 22,
6488
+ borderRadius: "50%",
6489
+ border: `2px solid ${borderColor}`,
6490
+ flexShrink: 0
6491
+ });
6492
+ var errorStyle3 = (color) => ({
6493
+ fontSize: "0.84rem",
6494
+ color,
6495
+ margin: "0 0 12px",
6496
+ lineHeight: 1.5
6220
6497
  });
6221
6498
  var tokenIconCircleStyle3 = (tokens, hasLogo) => ({
6222
6499
  width: 36,
@@ -6240,13 +6517,6 @@ var tokenIconTextStyle3 = (color) => ({
6240
6517
  fontWeight: 700,
6241
6518
  color
6242
6519
  });
6243
- var tokenInfoStyle3 = {
6244
- display: "flex",
6245
- flexDirection: "column",
6246
- gap: 2,
6247
- flex: 1,
6248
- minWidth: 0
6249
- };
6250
6520
  var tokenNameRowStyle2 = {
6251
6521
  display: "flex",
6252
6522
  alignItems: "center",
@@ -6270,10 +6540,6 @@ var tokenBalanceStyle2 = (color) => ({
6270
6540
  fontSize: "0.78rem",
6271
6541
  color
6272
6542
  });
6273
- var chevronStyle = {
6274
- flexShrink: 0,
6275
- opacity: 0.4
6276
- };
6277
6543
  var emptyStyle = (color) => ({
6278
6544
  fontSize: "0.88rem",
6279
6545
  color,
@@ -6295,7 +6561,7 @@ function GuestPreauthSetupCompleteScreen({
6295
6561
  ] }),
6296
6562
  children: [
6297
6563
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
6298
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle9, children: [
6564
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle10, children: [
6299
6565
  /* @__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(
6300
6566
  "path",
6301
6567
  {
@@ -6304,13 +6570,13 @@ function GuestPreauthSetupCompleteScreen({
6304
6570
  }
6305
6571
  ) }) }),
6306
6572
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle12(tokens.text), children: "Setup complete" }),
6307
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle10(tokens.textSecondary), children: "Your account is linked and ready. You can close this window or make another deposit." })
6573
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle12(tokens.textSecondary), children: "Your account is linked and ready. You can close this window or make another deposit." })
6308
6574
  ] })
6309
6575
  ]
6310
6576
  }
6311
6577
  );
6312
6578
  }
6313
- var contentStyle9 = {
6579
+ var contentStyle10 = {
6314
6580
  display: "flex",
6315
6581
  flexDirection: "column",
6316
6582
  alignItems: "center",
@@ -6326,7 +6592,7 @@ function headingStyle12(color) {
6326
6592
  color
6327
6593
  };
6328
6594
  }
6329
- function subtitleStyle10(color) {
6595
+ function subtitleStyle12(color) {
6330
6596
  return {
6331
6597
  margin: 0,
6332
6598
  fontSize: 15,
@@ -6339,14 +6605,14 @@ function GuestPreauthLinkingScreen({ onLogout }) {
6339
6605
  const { tokens } = useBlinkConfig();
6340
6606
  return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { children: [
6341
6607
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
6342
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle10, children: [
6608
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle11, children: [
6343
6609
  /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 48 }),
6344
6610
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle13(tokens.text), children: "Setting up your account..." }),
6345
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle11(tokens.textSecondary), children: "Linking your wallet to your Blink account. This usually takes a few seconds." })
6611
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle13(tokens.textSecondary), children: "Linking your wallet to your Blink account. This usually takes a few seconds." })
6346
6612
  ] })
6347
6613
  ] });
6348
6614
  }
6349
- var contentStyle10 = {
6615
+ var contentStyle11 = {
6350
6616
  flex: 1,
6351
6617
  display: "flex",
6352
6618
  flexDirection: "column",
@@ -6364,7 +6630,7 @@ function headingStyle13(color) {
6364
6630
  color
6365
6631
  };
6366
6632
  }
6367
- function subtitleStyle11(color) {
6633
+ function subtitleStyle13(color) {
6368
6634
  return {
6369
6635
  margin: 0,
6370
6636
  fontSize: "0.9rem",
@@ -6456,6 +6722,9 @@ function StepRendererContent({
6456
6722
  guestTokenEntries,
6457
6723
  guestLoadingBalances,
6458
6724
  guestSettingSender,
6725
+ guestPendingEntry,
6726
+ guestQuoteFee,
6727
+ guestQuoteLoading,
6459
6728
  authInput,
6460
6729
  otpCode,
6461
6730
  selectSourceChainName,
@@ -6579,6 +6848,28 @@ function StepRendererContent({
6579
6848
  );
6580
6849
  const effectiveTokenCount = tokenCount > 0 ? tokenCount : selectSourceTokenCount;
6581
6850
  const effectiveSourceLabel = selectedSourceLabel ?? (selectSourceChainName && selectSourceTokenSymbol ? `${selectSourceTokenSymbol} on ${selectSourceChainName}` : void 0);
6851
+ const setupTokenOptions = selectedAccount ? selectedAccount.wallets.flatMap(
6852
+ (w) => w.sources.filter((s) => s.balance.total.amount > 0).map((s) => ({
6853
+ symbol: s.token.symbol,
6854
+ chainName: w.chain.name,
6855
+ balance: s.balance.available.amount,
6856
+ walletId: w.id
6857
+ }))
6858
+ ) : selectSourceChoices.flatMap(
6859
+ (chain) => chain.tokens.map((t) => ({
6860
+ symbol: t.tokenSymbol,
6861
+ chainName: chain.chainName,
6862
+ balance: t.balance
6863
+ }))
6864
+ );
6865
+ const handleSetupSelectToken = (symbol, chainName, walletId) => {
6866
+ if (walletId) {
6867
+ handlers.onSelectAuthorizedToken(walletId, symbol);
6868
+ } else {
6869
+ handlers.onSelectSourceChainChange(chainName);
6870
+ handlers.onSetSelectSourceTokenSymbol(symbol);
6871
+ }
6872
+ };
6582
6873
  return /* @__PURE__ */ jsxRuntime.jsx(
6583
6874
  SetupScreen,
6584
6875
  {
@@ -6592,7 +6883,9 @@ function StepRendererContent({
6592
6883
  selectedSourceLabel: effectiveSourceLabel,
6593
6884
  loading: savingOneTapLimit,
6594
6885
  error: state.error,
6595
- selectedTokenSymbol: selectedSource?.token.symbol ?? selectSourceTokenSymbol
6886
+ selectedTokenSymbol: selectedSource?.token.symbol ?? selectSourceTokenSymbol,
6887
+ tokenOptions: setupTokenOptions,
6888
+ onSelectToken: handleSetupSelectToken
6596
6889
  }
6597
6890
  );
6598
6891
  }
@@ -6693,7 +6986,11 @@ function StepRendererContent({
6693
6986
  setting: guestSettingSender,
6694
6987
  depositAmount: depositAmount ?? void 0,
6695
6988
  error: state.error,
6989
+ pendingEntry: forms.guestPendingEntry,
6990
+ quoteFee: forms.guestQuoteFee,
6991
+ quoteLoading: forms.guestQuoteLoading,
6696
6992
  onSelect: handlers.onSelectGuestToken,
6993
+ onConfirm: handlers.onConfirmGuestToken,
6697
6994
  onBack: handlers.onGuestBackFromTokenPicker
6698
6995
  }
6699
6996
  );
@@ -7578,7 +7875,7 @@ function useProviderHandlers(deps) {
7578
7875
  guestSessionToken: result.guestSessionToken
7579
7876
  });
7580
7877
  } else {
7581
- const account = getAccount(wagmiConfig2);
7878
+ const account = core.getAccount(wagmiConfig2);
7582
7879
  if (!account.isConnected) {
7583
7880
  const connector = connectors.find((c) => c.type === "injected") ?? connectors[0];
7584
7881
  if (!connector) {
@@ -7997,8 +8294,8 @@ function useProviderHandlers(deps) {
7997
8294
  }
7998
8295
 
7999
8296
  // src/guestTokens.ts
8000
- function mapBalancesToGuestTokenEntries(options) {
8001
- return options.map((opt) => ({
8297
+ function mapGuestPickerEntries(options) {
8298
+ const mapped = options.map((opt) => ({
8002
8299
  chainId: opt.chainId,
8003
8300
  sourceChainId: opt.sourceChainId,
8004
8301
  chainName: opt.chainName,
@@ -8007,7 +8304,26 @@ function mapBalancesToGuestTokenEntries(options) {
8007
8304
  decimals: opt.decimals,
8008
8305
  rawBalance: opt.rawBalance,
8009
8306
  balance: Number(opt.rawBalance) / 10 ** opt.decimals
8010
- })).filter((entry) => entry.balance > 0).sort((a, b) => b.balance - a.balance);
8307
+ }));
8308
+ const positive = mapped.filter((e) => e.balance > 0).sort((a, b) => b.balance - a.balance);
8309
+ if (positive.length > 0) return positive;
8310
+ return mapped.sort((a, b) => b.balance - a.balance);
8311
+ }
8312
+ function guestEntryMatchingRecommended(balances, recommended) {
8313
+ const raw = balances.find(
8314
+ (b) => b.sourceChainId === recommended.sourceChainId && b.tokenAddress.toLowerCase() === recommended.tokenAddress.toLowerCase()
8315
+ );
8316
+ if (!raw) return null;
8317
+ return {
8318
+ chainId: raw.chainId,
8319
+ sourceChainId: raw.sourceChainId,
8320
+ chainName: raw.chainName,
8321
+ tokenSymbol: raw.tokenSymbol,
8322
+ tokenAddress: raw.tokenAddress,
8323
+ decimals: raw.decimals,
8324
+ rawBalance: raw.rawBalance,
8325
+ balance: Number(raw.rawBalance) / 10 ** raw.decimals
8326
+ };
8011
8327
  }
8012
8328
 
8013
8329
  // src/hooks/useGuestTransferHandlers.ts
@@ -8034,40 +8350,133 @@ function useGuestTransferHandlers(deps) {
8034
8350
  const [guestTokenEntries, setGuestTokenEntries] = react.useState([]);
8035
8351
  const [loadingBalances, setLoadingBalances] = react.useState(false);
8036
8352
  const [settingSender, setSettingSender] = react.useState(false);
8353
+ const [pendingGuestEntry, setPendingGuestEntry] = react.useState(null);
8354
+ const [guestFee, setGuestFee] = react.useState(null);
8355
+ const [guestQuoteLoading, setGuestQuoteLoading] = react.useState(false);
8037
8356
  const executingBridgeRef = react.useRef(false);
8038
8357
  const fetchedRef = react.useRef(false);
8039
8358
  const selectedGuestTokenRef = react.useRef(null);
8359
+ react.useEffect(() => {
8360
+ if (guestTransferId != null) return;
8361
+ fetchedRef.current = false;
8362
+ setGuestTokenEntries([]);
8363
+ setPendingGuestEntry(null);
8364
+ setGuestFee(null);
8365
+ setGuestQuoteLoading(false);
8366
+ setLoadingBalances(false);
8367
+ }, [guestTransferId]);
8040
8368
  react.useEffect(() => {
8041
8369
  if (!isGuestFlow || !guestTransferId || !guestSessionToken || fetchedRef.current) return;
8042
- const account = getAccount(wagmiConfig2);
8370
+ const account = core.getAccount(wagmiConfig2);
8043
8371
  if (!account.address) return;
8044
8372
  fetchedRef.current = true;
8045
8373
  setLoadingBalances(true);
8046
- fetchGuestTransferBalances(apiBaseUrl, guestTransferId, guestSessionToken, account.address).then((options) => mapBalancesToGuestTokenEntries(options)).then((entries) => {
8374
+ putGuestTransferSender(apiBaseUrl, guestTransferId, guestSessionToken, {
8375
+ senderAddress: account.address
8376
+ }).then(async (res) => {
8377
+ const balances = res.source?.balances;
8378
+ if (!balances?.length) {
8379
+ dispatch({ type: "SET_ERROR", error: "No supported tokens found for this transfer." });
8380
+ return;
8381
+ }
8382
+ const entries = mapGuestPickerEntries(balances);
8047
8383
  setGuestTokenEntries(entries);
8048
8384
  if (entries.length === 0) {
8049
8385
  dispatch({ type: "SET_ERROR", error: "No supported tokens found in your wallet." });
8386
+ return;
8387
+ }
8388
+ const recommended = res.source?.recommended;
8389
+ const autoEntry = recommended ? guestEntryMatchingRecommended(balances, recommended) : null;
8390
+ const pick = autoEntry && entries.some(
8391
+ (e) => e.sourceChainId === autoEntry.sourceChainId && e.tokenAddress.toLowerCase() === autoEntry.tokenAddress.toLowerCase()
8392
+ ) ? autoEntry : entries[0];
8393
+ setPendingGuestEntry(pick);
8394
+ setGuestFee(null);
8395
+ if (res.fee?.quote != null) {
8396
+ setGuestFee(res.fee);
8397
+ return;
8398
+ }
8399
+ setGuestQuoteLoading(true);
8400
+ try {
8401
+ const quote = await postGuestTransferFeeQuote(
8402
+ apiBaseUrl,
8403
+ guestTransferId,
8404
+ guestSessionToken,
8405
+ account.address,
8406
+ pick.sourceChainId,
8407
+ pick.tokenAddress
8408
+ );
8409
+ setGuestFee(quote);
8410
+ } catch (err) {
8411
+ captureException(err);
8412
+ setPendingGuestEntry(null);
8413
+ setGuestFee(null);
8414
+ const msg = err instanceof Error ? err.message : "Failed to load fee estimate";
8415
+ dispatch({ type: "SET_ERROR", error: msg });
8416
+ onError?.(msg);
8417
+ } finally {
8418
+ setGuestQuoteLoading(false);
8050
8419
  }
8051
8420
  }).catch((err) => {
8052
8421
  captureException(err);
8053
- dispatch({ type: "SET_ERROR", error: "Failed to fetch token balances." });
8422
+ dispatch({ type: "SET_ERROR", error: "Failed to load payment sources." });
8054
8423
  }).finally(() => setLoadingBalances(false));
8055
- }, [isGuestFlow, guestTransferId, guestSessionToken, apiBaseUrl, wagmiConfig2, dispatch]);
8424
+ }, [isGuestFlow, guestTransferId, guestSessionToken, apiBaseUrl, wagmiConfig2, dispatch, onError]);
8056
8425
  react.useEffect(() => {
8057
8426
  if (!isGuestFlow) {
8058
8427
  fetchedRef.current = false;
8059
8428
  selectedGuestTokenRef.current = null;
8060
8429
  setGuestTokenEntries([]);
8430
+ setPendingGuestEntry(null);
8431
+ setGuestFee(null);
8432
+ setGuestQuoteLoading(false);
8061
8433
  }
8062
8434
  }, [isGuestFlow]);
8063
8435
  const handleSelectGuestToken = react.useCallback(async (entry) => {
8064
8436
  if (!guestTransferId || !guestSessionToken) return;
8065
- const account = getAccount(wagmiConfig2);
8437
+ const account = core.getAccount(wagmiConfig2);
8066
8438
  if (!account.address) {
8067
8439
  dispatch({ type: "SET_ERROR", error: "Wallet not connected." });
8068
8440
  return;
8069
8441
  }
8442
+ setGuestQuoteLoading(true);
8443
+ dispatch({ type: "SET_ERROR", error: null });
8444
+ setPendingGuestEntry(entry);
8445
+ setGuestFee(null);
8446
+ try {
8447
+ console.info(
8448
+ `[blink-sdk] type=guest Fee quote preview: address=${account.address}, chain=${entry.sourceChainId}, token=${entry.tokenSymbol}`
8449
+ );
8450
+ const quote = await postGuestTransferFeeQuote(
8451
+ apiBaseUrl,
8452
+ guestTransferId,
8453
+ guestSessionToken,
8454
+ account.address,
8455
+ entry.sourceChainId,
8456
+ entry.tokenAddress
8457
+ );
8458
+ setGuestFee(quote);
8459
+ } catch (err) {
8460
+ captureException(err);
8461
+ setPendingGuestEntry(null);
8462
+ setGuestFee(null);
8463
+ const msg = err instanceof Error ? err.message : "Failed to load fee estimate";
8464
+ dispatch({ type: "SET_ERROR", error: msg });
8465
+ onError?.(msg);
8466
+ } finally {
8467
+ setGuestQuoteLoading(false);
8468
+ }
8469
+ }, [guestTransferId, guestSessionToken, wagmiConfig2, apiBaseUrl, dispatch, onError]);
8470
+ const handleConfirmGuestToken = react.useCallback(async () => {
8471
+ if (!guestTransferId || !guestSessionToken || !pendingGuestEntry) return;
8472
+ const account = core.getAccount(wagmiConfig2);
8473
+ if (!account.address) {
8474
+ dispatch({ type: "SET_ERROR", error: "Wallet not connected." });
8475
+ return;
8476
+ }
8477
+ const entry = pendingGuestEntry;
8070
8478
  setSettingSender(true);
8479
+ dispatch({ type: "SET_ERROR", error: null });
8071
8480
  try {
8072
8481
  console.info(
8073
8482
  `[blink-sdk] type=guest Setting sender: address=${account.address}, chain=${entry.sourceChainId}, token=${entry.tokenSymbol}`
@@ -8089,7 +8498,15 @@ function useGuestTransferHandlers(deps) {
8089
8498
  } finally {
8090
8499
  setSettingSender(false);
8091
8500
  }
8092
- }, [guestTransferId, guestSessionToken, wagmiConfig2, apiBaseUrl, dispatch, onError]);
8501
+ }, [
8502
+ guestTransferId,
8503
+ guestSessionToken,
8504
+ pendingGuestEntry,
8505
+ wagmiConfig2,
8506
+ apiBaseUrl,
8507
+ dispatch,
8508
+ onError
8509
+ ]);
8093
8510
  react.useEffect(() => {
8094
8511
  if (!isGuestFlow || !guestTransferId || !guestSessionToken || !selectedGuestTokenRef.current) return;
8095
8512
  if (executingBridgeRef.current) return;
@@ -8122,7 +8539,7 @@ function useGuestTransferHandlers(deps) {
8122
8539
  `[blink-sdk] type=guest Bridge quote ready: ${signPayload.bridgeSteps.length} step(s), token=${signPayload.tokenSymbol}, chain=${signPayload.chainName}`
8123
8540
  );
8124
8541
  const selectedToken = selectedGuestTokenRef.current;
8125
- const account = getAccount(wagmiConfig2);
8542
+ const account = core.getAccount(wagmiConfig2);
8126
8543
  const targetChainId = selectedToken?.chainId;
8127
8544
  if (targetChainId) {
8128
8545
  const numericChainId = Number(targetChainId);
@@ -8131,7 +8548,7 @@ function useGuestTransferHandlers(deps) {
8131
8548
  await switchChainAsync({ chainId: numericChainId });
8132
8549
  }
8133
8550
  }
8134
- const walletClient = await getWalletClient(wagmiConfig2);
8551
+ const walletClient = await core.getWalletClient(wagmiConfig2);
8135
8552
  const sender = account.address;
8136
8553
  if (!sender) {
8137
8554
  dispatch({ type: "PAY_ERROR", error: "Wallet not connected." });
@@ -8153,7 +8570,7 @@ function useGuestTransferHandlers(deps) {
8153
8570
  }]
8154
8571
  });
8155
8572
  console.info(`[blink-sdk] type=guest Bridge step ${stepIdx + 1} tx sent: ${txHash}`);
8156
- await waitForTransactionReceipt(wagmiConfig2, {
8573
+ await core.waitForTransactionReceipt(wagmiConfig2, {
8157
8574
  hash: txHash
8158
8575
  });
8159
8576
  lastTxHash = txHash;
@@ -8197,13 +8614,19 @@ function useGuestTransferHandlers(deps) {
8197
8614
  execute();
8198
8615
  }, [isGuestFlow, guestTransferId, guestSessionToken, settingSender, apiBaseUrl, wagmiConfig2, switchChainAsync, dispatch, onComplete, onError]);
8199
8616
  const handleGuestBackFromTokenPicker = react.useCallback(() => {
8617
+ setPendingGuestEntry(null);
8618
+ setGuestFee(null);
8200
8619
  dispatch({ type: "GUEST_BACK_FROM_TOKEN_PICKER" });
8201
8620
  }, [dispatch]);
8202
8621
  return {
8203
8622
  guestTokenEntries,
8204
8623
  loadingBalances,
8205
8624
  settingSender,
8625
+ pendingGuestEntry,
8626
+ guestFee,
8627
+ guestQuoteLoading,
8206
8628
  handleSelectGuestToken,
8629
+ handleConfirmGuestToken,
8207
8630
  handleGuestBackFromTokenPicker
8208
8631
  };
8209
8632
  }
@@ -9953,6 +10376,7 @@ function BlinkPaymentInner({
9953
10376
  onSelectAuthorizedToken: provider.handleSelectAuthorizedToken,
9954
10377
  onAuthorizeToken: provider.handleAuthorizeToken,
9955
10378
  onSelectGuestToken: guestTransfer.handleSelectGuestToken,
10379
+ onConfirmGuestToken: guestTransfer.handleConfirmGuestToken,
9956
10380
  onGuestBackFromTokenPicker: guestTransfer.handleGuestBackFromTokenPicker,
9957
10381
  onLogin: () => dispatch({ type: "REQUEST_LOGIN" }),
9958
10382
  onPreauthorize: provider.handlePreauthorize,
@@ -10018,7 +10442,10 @@ function BlinkPaymentInner({
10018
10442
  savingOneTapLimit: oneTapSetup.savingOneTapLimit,
10019
10443
  guestTokenEntries: guestTransfer.guestTokenEntries,
10020
10444
  guestLoadingBalances: guestTransfer.loadingBalances,
10021
- guestSettingSender: guestTransfer.settingSender
10445
+ guestSettingSender: guestTransfer.settingSender,
10446
+ guestPendingEntry: guestTransfer.pendingGuestEntry,
10447
+ guestQuoteFee: guestTransfer.guestFee?.quote ?? null,
10448
+ guestQuoteLoading: guestTransfer.guestQuoteLoading
10022
10449
  },
10023
10450
  handlers
10024
10451
  }
@@ -10031,9 +10458,17 @@ exports.BLINK_MASCOT = BLINK_MASCOT;
10031
10458
  exports.BlinkLoadingScreen = BlinkLoadingScreen;
10032
10459
  exports.BlinkPayment = BlinkPayment;
10033
10460
  exports.BlinkProvider = BlinkProvider;
10461
+ exports.ConfirmSignScreen = ConfirmSignScreen;
10462
+ exports.DepositScreen = DepositScreen;
10034
10463
  exports.FlowPhaseProvider = FlowPhaseProvider;
10464
+ exports.GuestPreauthLinkingScreen = GuestPreauthLinkingScreen;
10465
+ exports.GuestPreauthSetupCompleteScreen = GuestPreauthSetupCompleteScreen;
10466
+ exports.GuestTokenPickerScreen = GuestTokenPickerScreen;
10035
10467
  exports.IconCircle = IconCircle;
10036
10468
  exports.InfoBanner = InfoBanner;
10469
+ exports.LoginScreen = LoginScreen;
10470
+ exports.OpenWalletScreen = OpenWalletScreen;
10471
+ exports.OtpVerifyScreen = OtpVerifyScreen;
10037
10472
  exports.OutlineButton = OutlineButton;
10038
10473
  exports.PasskeyIframeBlockedError = PasskeyIframeBlockedError;
10039
10474
  exports.PasskeyScreen = PasskeyScreen;
@@ -10044,9 +10479,14 @@ exports.ScreenLayout = ScreenLayout;
10044
10479
  exports.SelectSourceScreen = SelectSourceScreen;
10045
10480
  exports.SettingsMenu = SettingsMenu;
10046
10481
  exports.SetupScreen = SetupScreen;
10482
+ exports.SetupStatusScreen = SetupStatusScreen;
10047
10483
  exports.Spinner = Spinner;
10048
10484
  exports.StepList = StepList;
10485
+ exports.SuccessScreen = SuccessScreen;
10049
10486
  exports.TokenPickerScreen = TokenPickerScreen;
10487
+ exports.TransferStatusScreen = TransferStatusScreen;
10488
+ exports.VerifyPasskeyScreen = VerifyPasskeyScreen;
10489
+ exports.WalletPickerScreen = WalletPickerScreen;
10050
10490
  exports.blinkApi = api_exports;
10051
10491
  exports.buildPasskeyPopupOptions = buildPasskeyPopupOptions;
10052
10492
  exports.createPasskeyCredential = createPasskeyCredential;
@@ -10056,7 +10496,9 @@ exports.deviceHasPasskey = deviceHasPasskey;
10056
10496
  exports.findDevicePasskey = findDevicePasskey;
10057
10497
  exports.findDevicePasskeyViaPopup = findDevicePasskeyViaPopup;
10058
10498
  exports.getTheme = getTheme;
10499
+ exports.guestEntryMatchingRecommended = guestEntryMatchingRecommended;
10059
10500
  exports.lightTheme = lightTheme;
10501
+ exports.mapGuestPickerEntries = mapGuestPickerEntries;
10060
10502
  exports.resolvePasskeyRpId = resolvePasskeyRpId;
10061
10503
  exports.screenForPhase = screenForPhase;
10062
10504
  exports.useAuthorizationExecutor = useAuthorizationExecutor;