@swype-org/react-sdk 0.2.364 → 0.2.375
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 +331 -99
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -1
- package/dist/index.d.ts +43 -1
- package/dist/index.js +330 -100
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -523,6 +523,14 @@ function isVisibleUsdAmountAtTwoDecimals(amount) {
|
|
|
523
523
|
function isSelectableDepositSourceAmountUsd(amount, minTransferAmountUsd = DEFAULT_MIN_SEND_AMOUNT_USD) {
|
|
524
524
|
return Number.isFinite(amount) && amount >= minTransferAmountUsd;
|
|
525
525
|
}
|
|
526
|
+
function buildNativeUnsupportedEntries(options) {
|
|
527
|
+
return options.map((option) => ({
|
|
528
|
+
tokenSymbol: option.tokenSymbol,
|
|
529
|
+
chainName: option.chainName,
|
|
530
|
+
amount: parseRawBalance(option.rawBalance, option.decimals),
|
|
531
|
+
logoURI: option.logoURI ?? null
|
|
532
|
+
})).filter((entry) => entry.amount > 0);
|
|
533
|
+
}
|
|
526
534
|
function buildSelectSourceChoices(options, minTransferAmountUsd = DEFAULT_MIN_SEND_AMOUNT_USD) {
|
|
527
535
|
const chainChoices = [];
|
|
528
536
|
const chainIndexByName = /* @__PURE__ */ new Map();
|
|
@@ -636,6 +644,21 @@ function resolveSelectSourceOption(choices, options, chainName, tokenSymbol, rec
|
|
|
636
644
|
));
|
|
637
645
|
}
|
|
638
646
|
|
|
647
|
+
// src/walletFlow.ts
|
|
648
|
+
var MOBILE_USER_AGENT_PATTERN = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
|
|
649
|
+
function isMobileUserAgent(userAgent) {
|
|
650
|
+
if (!userAgent) {
|
|
651
|
+
return false;
|
|
652
|
+
}
|
|
653
|
+
return MOBILE_USER_AGENT_PATTERN.test(userAgent);
|
|
654
|
+
}
|
|
655
|
+
function shouldUseWalletConnector(options) {
|
|
656
|
+
return options.useWalletConnector ?? !isMobileUserAgent(options.userAgent);
|
|
657
|
+
}
|
|
658
|
+
function resolveCoinbasePreferenceOptions(userAgent) {
|
|
659
|
+
return isMobileUserAgent(userAgent) ? "all" : "eoaOnly";
|
|
660
|
+
}
|
|
661
|
+
|
|
639
662
|
// src/walletBridge/protocol.ts
|
|
640
663
|
var BRIDGE_PROTOCOL_VERSION = 1;
|
|
641
664
|
function parseBridgeMessage(data) {
|
|
@@ -1001,23 +1024,29 @@ var BLINK_PRIVY_APP_ID = "cmlil87uv004n0ck0blwumwek";
|
|
|
1001
1024
|
var BLINK_WC_PROJECT_ID = "f6c60234412f94ef9108dc8f67f4362c";
|
|
1002
1025
|
var BLINK_FINGERPRINT_API_KEY = "nr4FvTsZ6M5z2141FqrM";
|
|
1003
1026
|
var BLINK_FINGERPRINT_REGION = "us";
|
|
1004
|
-
function FingerprintVisitorPing() {
|
|
1005
|
-
react$1.useVisitorData({ immediate: true });
|
|
1006
|
-
return null;
|
|
1007
|
-
}
|
|
1008
1027
|
function buildStaticConnectors() {
|
|
1028
|
+
const userAgent = typeof navigator === "undefined" ? null : navigator.userAgent;
|
|
1009
1029
|
return [
|
|
1010
1030
|
// `unstable_shimAsyncInject` covers wallets whose content scripts wire
|
|
1011
1031
|
// up after page load (Phantom, Trust, MetaMask in the iframe).
|
|
1012
1032
|
connectors.injected({ unstable_shimAsyncInject: 2e3 }),
|
|
1013
|
-
//
|
|
1014
|
-
//
|
|
1015
|
-
//
|
|
1016
|
-
//
|
|
1017
|
-
//
|
|
1018
|
-
//
|
|
1019
|
-
//
|
|
1020
|
-
|
|
1033
|
+
// Coinbase Wallet SDK connection preference is platform-specific
|
|
1034
|
+
// (see `resolveCoinbasePreferenceOptions`):
|
|
1035
|
+
// • Desktop → `eoaOnly`: in smart-wallet mode the Base extension hands
|
|
1036
|
+
// the dapp a separate, often-empty smart-wallet account instead of the
|
|
1037
|
+
// user's funded EOA → "no assets". `eoaOnly` binds the funded EOA.
|
|
1038
|
+
// • Mobile (Base in-app WebView) → `all`: signing must use the injected
|
|
1039
|
+
// `window.ethereum`; the SDK path reloads the iOS WKWebView after each
|
|
1040
|
+
// signature.
|
|
1041
|
+
//
|
|
1042
|
+
// Exactly ONE Coinbase connector: two `@coinbase/wallet-sdk` instances in
|
|
1043
|
+
// one page collide on shared `window` listeners + the Communicator (Privy
|
|
1044
|
+
// connector-init timeout, listener leaks, duplicated `client-project-name`
|
|
1045
|
+
// that 400s the connect), so we never register a second one.
|
|
1046
|
+
connectors.coinbaseWallet({
|
|
1047
|
+
appName: "Blink",
|
|
1048
|
+
preference: { options: resolveCoinbasePreferenceOptions(userAgent) }
|
|
1049
|
+
})
|
|
1021
1050
|
];
|
|
1022
1051
|
}
|
|
1023
1052
|
function buildWagmiConfig(bridgedWallets) {
|
|
@@ -1103,30 +1132,30 @@ function BlinkProvider({
|
|
|
1103
1132
|
);
|
|
1104
1133
|
return (
|
|
1105
1134
|
// Outermost wrapper: loads the Fingerprint browser agent once per
|
|
1106
|
-
// provider mount, independent of wagmi/privy/query state.
|
|
1107
|
-
//
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
intl: {
|
|
1120
|
-
defaultCountry: "US"
|
|
1121
|
-
},
|
|
1122
|
-
embeddedWallets: {
|
|
1123
|
-
showWalletUIs: false
|
|
1124
|
-
}
|
|
1135
|
+
// provider mount, independent of wagmi/privy/query state. The agent loads
|
|
1136
|
+
// here (including during the hidden preload warm-up), but identification is
|
|
1137
|
+
// deferred to explicit flow events fired from `BlinkPayment` — see
|
|
1138
|
+
// `useFingerprintFlowEvents` — so a preload that never opens is never
|
|
1139
|
+
// identified.
|
|
1140
|
+
/* @__PURE__ */ jsxRuntime.jsx(react$1.FingerprintProvider, { apiKey: BLINK_FINGERPRINT_API_KEY, region: BLINK_FINGERPRINT_REGION, children: /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClientRef.current, children: /* @__PURE__ */ jsxRuntime.jsx(wagmi.WagmiProvider, { config: wagmiConfig, reconnectOnMount: false, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1141
|
+
reactAuth.PrivyProvider,
|
|
1142
|
+
{
|
|
1143
|
+
appId: privyAppId ?? BLINK_PRIVY_APP_ID,
|
|
1144
|
+
config: {
|
|
1145
|
+
appearance: {
|
|
1146
|
+
theme: getThemeBase(theme),
|
|
1147
|
+
accentColor: getTheme(theme).accent
|
|
1125
1148
|
},
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1149
|
+
intl: {
|
|
1150
|
+
defaultCountry: "US"
|
|
1151
|
+
},
|
|
1152
|
+
embeddedWallets: {
|
|
1153
|
+
showWalletUIs: false
|
|
1154
|
+
}
|
|
1155
|
+
},
|
|
1156
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(BlinkContext.Provider, { value, children })
|
|
1157
|
+
}
|
|
1158
|
+
) }) }) })
|
|
1130
1159
|
);
|
|
1131
1160
|
}
|
|
1132
1161
|
function useBlinkConfig() {
|
|
@@ -1167,9 +1196,10 @@ function buildTargetMatchers(target) {
|
|
|
1167
1196
|
aliases.add("io.metamask");
|
|
1168
1197
|
}
|
|
1169
1198
|
if (value === "base" || value === "base account" || value === "base app" || value.includes("coinbase")) {
|
|
1170
|
-
aliases.add("base");
|
|
1171
1199
|
aliases.add("coinbase");
|
|
1172
1200
|
aliases.add("coinbasewalletsdk");
|
|
1201
|
+
aliases.add("com.coinbase.wallet");
|
|
1202
|
+
aliases.add("baseaccount");
|
|
1173
1203
|
}
|
|
1174
1204
|
if (value.includes("trust")) {
|
|
1175
1205
|
aliases.add("trust");
|
|
@@ -1243,19 +1273,70 @@ async function withTimeout(promise, ms, label) {
|
|
|
1243
1273
|
if (timer !== void 0) clearTimeout(timer);
|
|
1244
1274
|
}
|
|
1245
1275
|
}
|
|
1246
|
-
function
|
|
1276
|
+
function isCoinbaseSdkConnector(connector) {
|
|
1247
1277
|
if (!connector) return false;
|
|
1248
1278
|
return connectorMatchesWallet(
|
|
1249
1279
|
{ id: connector.id, name: connector.name ?? "" },
|
|
1250
1280
|
{ wagmiConnectorId: "coinbaseWalletSDK" }
|
|
1251
1281
|
);
|
|
1252
1282
|
}
|
|
1283
|
+
var COINBASE_SDK_STORAGE_PREFIXES = ["-CBWSDK", "-walletlink"];
|
|
1284
|
+
var COINBASE_SIGNER_TYPE_STORAGE_KEY = "-CBWSDK:SignerConfigurator:SignerType";
|
|
1285
|
+
function loadCoinbaseSignerType() {
|
|
1286
|
+
if (typeof window === "undefined" || !window.localStorage) return null;
|
|
1287
|
+
try {
|
|
1288
|
+
return window.localStorage.getItem(COINBASE_SIGNER_TYPE_STORAGE_KEY);
|
|
1289
|
+
} catch {
|
|
1290
|
+
return null;
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
function clearCoinbaseWalletSdkSession() {
|
|
1294
|
+
if (typeof window === "undefined" || !window.localStorage) return;
|
|
1295
|
+
try {
|
|
1296
|
+
const store = window.localStorage;
|
|
1297
|
+
const keysToRemove = [];
|
|
1298
|
+
for (let i = 0; i < store.length; i += 1) {
|
|
1299
|
+
const key = store.key(i);
|
|
1300
|
+
if (key && COINBASE_SDK_STORAGE_PREFIXES.some((prefix) => key.startsWith(prefix))) {
|
|
1301
|
+
keysToRemove.push(key);
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
keysToRemove.forEach((key) => store.removeItem(key));
|
|
1305
|
+
console.info("[blink-sdk][disconnect] cleared Coinbase Wallet SDK session", {
|
|
1306
|
+
clearedKeys: keysToRemove.length
|
|
1307
|
+
});
|
|
1308
|
+
} catch (err) {
|
|
1309
|
+
console.info("[blink-sdk][disconnect] failed to clear Coinbase Wallet SDK session", err);
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
function resetWagmiConnectionInMemory(wagmiConfig, connector) {
|
|
1313
|
+
if (!connector) return;
|
|
1314
|
+
try {
|
|
1315
|
+
const target = connector;
|
|
1316
|
+
const connections = [...wagmiConfig.state.connections.values()];
|
|
1317
|
+
const match = connections.find((conn) => {
|
|
1318
|
+
const live2 = conn.connector;
|
|
1319
|
+
if (target.uid && live2.uid) return live2.uid === target.uid;
|
|
1320
|
+
return live2.id === target.id;
|
|
1321
|
+
});
|
|
1322
|
+
const live = match?.connector;
|
|
1323
|
+
if (!live?.emitter) return;
|
|
1324
|
+
live.emitter.emit("disconnect");
|
|
1325
|
+
console.info("[blink-sdk][disconnect] reset wagmi in-memory connection via emitter", {
|
|
1326
|
+
connectorId: live.id
|
|
1327
|
+
});
|
|
1328
|
+
} catch (err) {
|
|
1329
|
+
console.info("[blink-sdk][disconnect] failed to reset wagmi in-memory connection", err);
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1253
1332
|
async function safeDisconnect(wagmiConfig, connector) {
|
|
1254
|
-
if (
|
|
1333
|
+
if (isCoinbaseSdkConnector(connector)) {
|
|
1255
1334
|
console.info(
|
|
1256
|
-
"[blink-sdk][disconnect]
|
|
1335
|
+
"[blink-sdk][disconnect] clearing Coinbase Wallet SDK session instead of wagmi disconnect",
|
|
1257
1336
|
{ connectorId: connector?.id }
|
|
1258
1337
|
);
|
|
1338
|
+
clearCoinbaseWalletSdkSession();
|
|
1339
|
+
resetWagmiConnectionInMemory(wagmiConfig, connector);
|
|
1259
1340
|
return;
|
|
1260
1341
|
}
|
|
1261
1342
|
await core.disconnect(wagmiConfig, { connector }).catch(() => {
|
|
@@ -3909,6 +3990,23 @@ function isUserRejection(msg) {
|
|
|
3909
3990
|
const lower = msg.toLowerCase();
|
|
3910
3991
|
return lower.includes("rejected") || lower.includes("denied");
|
|
3911
3992
|
}
|
|
3993
|
+
var EmptyConnectionAccountError = class extends Error {
|
|
3994
|
+
constructor(message = "Wallet connected but returned no account address.") {
|
|
3995
|
+
super(message);
|
|
3996
|
+
this.name = "EmptyConnectionAccountError";
|
|
3997
|
+
}
|
|
3998
|
+
};
|
|
3999
|
+
var EVM_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
|
|
4000
|
+
function assertNonEmptyConnectedAddress(address, ctx) {
|
|
4001
|
+
if (typeof address === "string" && EVM_ADDRESS_RE.test(address)) {
|
|
4002
|
+
return;
|
|
4003
|
+
}
|
|
4004
|
+
appendDebug("error", "OPEN_PROVIDER: empty-or-invalid-connected-address", {
|
|
4005
|
+
...ctx,
|
|
4006
|
+
address: address ?? null
|
|
4007
|
+
});
|
|
4008
|
+
throw new EmptyConnectionAccountError();
|
|
4009
|
+
}
|
|
3912
4010
|
function requiresExplicitEvmNonce(account) {
|
|
3913
4011
|
return connectorMatchesWallet(account?.connector, { providerName: "trust" }) || connectorMatchesWallet(account?.connector, { providerName: "phantom" });
|
|
3914
4012
|
}
|
|
@@ -4142,7 +4240,8 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
|
|
|
4142
4240
|
accountConnectorId: account.connector?.id ?? null,
|
|
4143
4241
|
accountConnectorName: account.connector?.name ?? null,
|
|
4144
4242
|
targetId: targetId ?? null,
|
|
4145
|
-
resolvedConnectorId: connector?.id ?? null
|
|
4243
|
+
resolvedConnectorId: connector?.id ?? null,
|
|
4244
|
+
availableConnectorIds: connectors.map((c) => c.id)
|
|
4146
4245
|
};
|
|
4147
4246
|
let disconnectedMismatchedConnector = false;
|
|
4148
4247
|
if (account.isConnected && account.address) {
|
|
@@ -4150,6 +4249,7 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
|
|
|
4150
4249
|
if (connectorMatchesTarget) {
|
|
4151
4250
|
const hexChainId2 = account.chainId ? `0x${account.chainId.toString(16)}` : void 0;
|
|
4152
4251
|
const branch = !targetId ? "early-return-no-target" : "early-return-connector-match";
|
|
4252
|
+
assertNonEmptyConnectedAddress(account.address, { ...logContext, branch });
|
|
4153
4253
|
console.info("[blink-sdk][open-provider] Skipping connectAsync; wagmi already connected.", {
|
|
4154
4254
|
...logContext,
|
|
4155
4255
|
branch
|
|
@@ -4173,6 +4273,20 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
|
|
|
4173
4273
|
disconnectedMismatchedConnector = true;
|
|
4174
4274
|
}
|
|
4175
4275
|
if (!disconnectedMismatchedConnector) {
|
|
4276
|
+
const targetIsCoinbase = connectorMatchesWallet(connector, {
|
|
4277
|
+
wagmiConnectorId: "coinbaseWalletSDK"
|
|
4278
|
+
});
|
|
4279
|
+
const isDesktopUa = !isMobileUserAgent(
|
|
4280
|
+
typeof navigator === "undefined" ? null : navigator.userAgent
|
|
4281
|
+
);
|
|
4282
|
+
if (targetIsCoinbase && isDesktopUa && loadCoinbaseSignerType() === "scw") {
|
|
4283
|
+
console.info(
|
|
4284
|
+
"[blink-sdk][open-provider] Clearing stale Coinbase Smart Wallet (scw) session before reconnect so eoaOnly binds the EOA.",
|
|
4285
|
+
logContext
|
|
4286
|
+
);
|
|
4287
|
+
appendDebug("info", "OPEN_PROVIDER: clearing stale scw session before reconnect", logContext);
|
|
4288
|
+
clearCoinbaseWalletSdkSession();
|
|
4289
|
+
}
|
|
4176
4290
|
console.info("[blink-sdk][open-provider] Attempting silent reconnect.", logContext);
|
|
4177
4291
|
appendDebug("info", "OPEN_PROVIDER: attempting silent reconnect", logContext);
|
|
4178
4292
|
const reconnections = await core.reconnect(wagmiConfig).catch(() => []);
|
|
@@ -4187,6 +4301,7 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
|
|
|
4187
4301
|
reconnectedConnectorId: reconnectedAccount.connector?.id ?? null,
|
|
4188
4302
|
reconnectionCount: reconnections.length
|
|
4189
4303
|
};
|
|
4304
|
+
assertNonEmptyConnectedAddress(reconnectedAccount.address, reconnectLogContext);
|
|
4190
4305
|
console.info(
|
|
4191
4306
|
"[blink-sdk][open-provider] Silent reconnect succeeded; skipping connectAsync.",
|
|
4192
4307
|
reconnectLogContext
|
|
@@ -4254,6 +4369,10 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
|
|
|
4254
4369
|
});
|
|
4255
4370
|
const result = await connectAsync({ connector });
|
|
4256
4371
|
const hexChainId = `0x${result.chainId.toString(16)}`;
|
|
4372
|
+
assertNonEmptyConnectedAddress(result.accounts[0], {
|
|
4373
|
+
...logContext,
|
|
4374
|
+
branch: "connectAsync-result"
|
|
4375
|
+
});
|
|
4257
4376
|
return actionSuccess(
|
|
4258
4377
|
action,
|
|
4259
4378
|
`Connected to ${connector.name}. Account: ${result.accounts[0]}, Chain: ${hexChainId}`,
|
|
@@ -4261,15 +4380,23 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
|
|
|
4261
4380
|
);
|
|
4262
4381
|
} catch (err) {
|
|
4263
4382
|
const msg = err instanceof Error ? err.message : "Failed to connect wallet";
|
|
4264
|
-
|
|
4265
|
-
|
|
4383
|
+
const emptyAccount = err instanceof EmptyConnectionAccountError;
|
|
4384
|
+
if (options?.externalAuthorizationAvailable && (isUserRejection(msg) || emptyAccount) && action.metadata?.chainFamily !== "svm") {
|
|
4385
|
+
appendDebug("info", "OPEN_PROVIDER: soft-halt", {
|
|
4266
4386
|
actionId: action.id,
|
|
4267
|
-
externalAuthorizationAvailable: true
|
|
4387
|
+
externalAuthorizationAvailable: true,
|
|
4388
|
+
reason: emptyAccount ? "empty-account" : "user-rejection"
|
|
4268
4389
|
});
|
|
4269
4390
|
return actionPending(
|
|
4270
4391
|
action,
|
|
4271
4392
|
"awaiting-external-authorization",
|
|
4272
|
-
"Wallet connection prompt dismissed \u2014 awaiting completion via cross-device authorization."
|
|
4393
|
+
emptyAccount ? "Wallet returned no account \u2014 awaiting completion via cross-device authorization." : "Wallet connection prompt dismissed \u2014 awaiting completion via cross-device authorization."
|
|
4394
|
+
);
|
|
4395
|
+
}
|
|
4396
|
+
if (emptyAccount) {
|
|
4397
|
+
return actionError(
|
|
4398
|
+
action,
|
|
4399
|
+
"We couldn't read an address from that wallet. Please reconnect and make sure an account is selected."
|
|
4273
4400
|
);
|
|
4274
4401
|
}
|
|
4275
4402
|
if (action.metadata?.chainFamily === "svm") {
|
|
@@ -6975,18 +7102,6 @@ function updateTrackedSession(sessions, ownerSessionId, reportedSession, actionS
|
|
|
6975
7102
|
}
|
|
6976
7103
|
}
|
|
6977
7104
|
|
|
6978
|
-
// src/walletFlow.ts
|
|
6979
|
-
var MOBILE_USER_AGENT_PATTERN = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
|
|
6980
|
-
function isMobileUserAgent(userAgent) {
|
|
6981
|
-
if (!userAgent) {
|
|
6982
|
-
return false;
|
|
6983
|
-
}
|
|
6984
|
-
return MOBILE_USER_AGENT_PATTERN.test(userAgent);
|
|
6985
|
-
}
|
|
6986
|
-
function shouldUseWalletConnector(options) {
|
|
6987
|
-
return options.useWalletConnector ?? !isMobileUserAgent(options.userAgent);
|
|
6988
|
-
}
|
|
6989
|
-
|
|
6990
7105
|
// src/enterAmountInput.ts
|
|
6991
7106
|
var MAX_FRACTION_DIGITS = 2;
|
|
6992
7107
|
function isDigit(value) {
|
|
@@ -8586,6 +8701,52 @@ var buttonStyle = (color, hovered) => ({
|
|
|
8586
8701
|
flexShrink: 0,
|
|
8587
8702
|
transition: "background 0.15s ease"
|
|
8588
8703
|
});
|
|
8704
|
+
var INTERCOM_HELP_URL = "https://intercom.help/blinkcash/en/";
|
|
8705
|
+
var TERMS_URL = "https://blink.cash/terms";
|
|
8706
|
+
function SupportFooter() {
|
|
8707
|
+
const { tokens } = useBlinkConfig();
|
|
8708
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle2(tokens.textMuted), children: [
|
|
8709
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8710
|
+
"a",
|
|
8711
|
+
{
|
|
8712
|
+
href: INTERCOM_HELP_URL,
|
|
8713
|
+
target: "_blank",
|
|
8714
|
+
rel: "noopener noreferrer",
|
|
8715
|
+
style: linkStyle(tokens.textMuted),
|
|
8716
|
+
children: "Help"
|
|
8717
|
+
}
|
|
8718
|
+
),
|
|
8719
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", style: dotStyle(tokens.textTertiary), children: "\u2022" }),
|
|
8720
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8721
|
+
"a",
|
|
8722
|
+
{
|
|
8723
|
+
href: TERMS_URL,
|
|
8724
|
+
target: "_blank",
|
|
8725
|
+
rel: "noopener noreferrer",
|
|
8726
|
+
style: linkStyle(tokens.textMuted),
|
|
8727
|
+
children: "Terms"
|
|
8728
|
+
}
|
|
8729
|
+
)
|
|
8730
|
+
] });
|
|
8731
|
+
}
|
|
8732
|
+
var containerStyle2 = (color) => ({
|
|
8733
|
+
display: "flex",
|
|
8734
|
+
alignItems: "center",
|
|
8735
|
+
justifyContent: "center",
|
|
8736
|
+
gap: 10,
|
|
8737
|
+
fontSize: "0.8rem",
|
|
8738
|
+
color,
|
|
8739
|
+
padding: "4px 0"
|
|
8740
|
+
});
|
|
8741
|
+
var linkStyle = (color) => ({
|
|
8742
|
+
color,
|
|
8743
|
+
fontWeight: 500,
|
|
8744
|
+
textDecoration: "none"
|
|
8745
|
+
});
|
|
8746
|
+
var dotStyle = (color) => ({
|
|
8747
|
+
color,
|
|
8748
|
+
fontSize: "0.8rem"
|
|
8749
|
+
});
|
|
8589
8750
|
function SettingsMenu({ onLogout }) {
|
|
8590
8751
|
const { tokens } = useBlinkConfig();
|
|
8591
8752
|
const [open, setOpen] = react.useState(false);
|
|
@@ -8601,7 +8762,7 @@ function SettingsMenu({ onLogout }) {
|
|
|
8601
8762
|
document.addEventListener("mousedown", handleClickOutside);
|
|
8602
8763
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
8603
8764
|
}, [open]);
|
|
8604
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: menuRef, style:
|
|
8765
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: menuRef, style: containerStyle3, children: [
|
|
8605
8766
|
/* @__PURE__ */ jsxRuntime.jsx(IconButton, { onClick: toggle, "aria-label": "Settings", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", children: [
|
|
8606
8767
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "5", r: "2", fill: "currentColor" }),
|
|
8607
8768
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "2", fill: "currentColor" }),
|
|
@@ -8611,7 +8772,7 @@ function SettingsMenu({ onLogout }) {
|
|
|
8611
8772
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
8612
8773
|
"a",
|
|
8613
8774
|
{
|
|
8614
|
-
href:
|
|
8775
|
+
href: INTERCOM_HELP_URL,
|
|
8615
8776
|
target: "_blank",
|
|
8616
8777
|
rel: "noopener noreferrer",
|
|
8617
8778
|
onClick: () => setOpen(false),
|
|
@@ -8648,7 +8809,7 @@ function SettingsMenu({ onLogout }) {
|
|
|
8648
8809
|
] })
|
|
8649
8810
|
] });
|
|
8650
8811
|
}
|
|
8651
|
-
var
|
|
8812
|
+
var containerStyle3 = {
|
|
8652
8813
|
position: "relative"
|
|
8653
8814
|
};
|
|
8654
8815
|
var dropdownStyle = (tokens) => ({
|
|
@@ -8738,7 +8899,7 @@ var badgeStyle = (color) => ({
|
|
|
8738
8899
|
});
|
|
8739
8900
|
function PoweredByFooter() {
|
|
8740
8901
|
const { tokens } = useBlinkConfig();
|
|
8741
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
8902
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: containerStyle4(tokens.textMuted), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
|
|
8742
8903
|
/* @__PURE__ */ jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8743
8904
|
"path",
|
|
8744
8905
|
{
|
|
@@ -8749,7 +8910,7 @@ function PoweredByFooter() {
|
|
|
8749
8910
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Powered by Blink" })
|
|
8750
8911
|
] }) });
|
|
8751
8912
|
}
|
|
8752
|
-
var
|
|
8913
|
+
var containerStyle4 = (color) => ({
|
|
8753
8914
|
display: "flex",
|
|
8754
8915
|
flexDirection: "column",
|
|
8755
8916
|
alignItems: "center",
|
|
@@ -9169,6 +9330,7 @@ var TETHER_LOGO = svgToDataUri(TETHER_SVG);
|
|
|
9169
9330
|
var USDH_LOGO = svgToDataUri(USDH_SVG);
|
|
9170
9331
|
var ETH_LOGO = "https://assets.relay.link/icons/currencies/eth.png";
|
|
9171
9332
|
var SOL_LOGO = "https://assets.relay.link/icons/currencies/sol.png";
|
|
9333
|
+
var MON_LOGO = "https://assets.relay.link/icons/currencies/mon.png";
|
|
9172
9334
|
var KNOWN_LOGOS = {
|
|
9173
9335
|
metamask: METAMASK_LOGO,
|
|
9174
9336
|
base: BASE_LOGO,
|
|
@@ -9186,7 +9348,8 @@ var TOKEN_LOGOS = {
|
|
|
9186
9348
|
USDM: USDM_LOGO,
|
|
9187
9349
|
USDH: USDH_LOGO,
|
|
9188
9350
|
ETH: ETH_LOGO,
|
|
9189
|
-
SOL: SOL_LOGO
|
|
9351
|
+
SOL: SOL_LOGO,
|
|
9352
|
+
MON: MON_LOGO
|
|
9190
9353
|
};
|
|
9191
9354
|
var CHAIN_LOGOS = {
|
|
9192
9355
|
base: BASE_CHAIN_LOGO,
|
|
@@ -9459,12 +9622,12 @@ var defaultIcon = /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "18", height: "
|
|
|
9459
9622
|
) });
|
|
9460
9623
|
function InfoBanner({ children, icon }) {
|
|
9461
9624
|
const { tokens } = useBlinkConfig();
|
|
9462
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
9625
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle5(tokens.accent), children: [
|
|
9463
9626
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: iconStyle, children: icon ?? defaultIcon }),
|
|
9464
9627
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: textStyle, children })
|
|
9465
9628
|
] });
|
|
9466
9629
|
}
|
|
9467
|
-
var
|
|
9630
|
+
var containerStyle5 = (accent) => ({
|
|
9468
9631
|
display: "flex",
|
|
9469
9632
|
alignItems: "flex-start",
|
|
9470
9633
|
gap: 10,
|
|
@@ -9482,7 +9645,7 @@ var iconStyle = {
|
|
|
9482
9645
|
};
|
|
9483
9646
|
var textStyle = { flex: 1 };
|
|
9484
9647
|
function WarningBanner({ title, children }) {
|
|
9485
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
9648
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle6, children: [
|
|
9486
9649
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyle2, children: [
|
|
9487
9650
|
/* @__PURE__ */ jsxRuntime.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", style: iconStyle2, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z", fill: "#F57C00" }) }),
|
|
9488
9651
|
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: title })
|
|
@@ -9490,7 +9653,7 @@ function WarningBanner({ title, children }) {
|
|
|
9490
9653
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: bodyStyle2, children })
|
|
9491
9654
|
] });
|
|
9492
9655
|
}
|
|
9493
|
-
var
|
|
9656
|
+
var containerStyle6 = {
|
|
9494
9657
|
padding: "14px 16px",
|
|
9495
9658
|
background: "#FFF8E1",
|
|
9496
9659
|
border: "1px solid #FFE082",
|
|
@@ -9540,7 +9703,7 @@ function NotificationBanner({
|
|
|
9540
9703
|
}) {
|
|
9541
9704
|
const { tokens } = useBlinkConfig();
|
|
9542
9705
|
const color = variant === "negative" ? NEGATIVE_FG : tokens.text;
|
|
9543
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
9706
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle7(tokens.bgRecessed), children: [
|
|
9544
9707
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...iconWrapStyle2, color }, children: icon ?? defaultIcon2 }),
|
|
9545
9708
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { ...textColStyle, color }, children: [
|
|
9546
9709
|
/* @__PURE__ */ jsxRuntime.jsx("p", { style: titleStyle3, children: title }),
|
|
@@ -9548,7 +9711,7 @@ function NotificationBanner({
|
|
|
9548
9711
|
] })
|
|
9549
9712
|
] });
|
|
9550
9713
|
}
|
|
9551
|
-
var
|
|
9714
|
+
var containerStyle7 = (bg) => ({
|
|
9552
9715
|
display: "flex",
|
|
9553
9716
|
alignItems: "flex-start",
|
|
9554
9717
|
gap: 16,
|
|
@@ -9643,7 +9806,7 @@ function OtpInput({ value, onChange, length = 6, disabled }) {
|
|
|
9643
9806
|
onChange(pasted);
|
|
9644
9807
|
focusInput(Math.min(pasted.length, length - 1));
|
|
9645
9808
|
}, [onChange, length, focusInput]);
|
|
9646
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
9809
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: containerStyle8, children: digits.map((digit, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
9647
9810
|
"input",
|
|
9648
9811
|
{
|
|
9649
9812
|
ref: (el) => {
|
|
@@ -9664,7 +9827,7 @@ function OtpInput({ value, onChange, length = 6, disabled }) {
|
|
|
9664
9827
|
i
|
|
9665
9828
|
)) });
|
|
9666
9829
|
}
|
|
9667
|
-
var
|
|
9830
|
+
var containerStyle8 = {
|
|
9668
9831
|
display: "flex",
|
|
9669
9832
|
gap: 8,
|
|
9670
9833
|
justifyContent: "center",
|
|
@@ -10211,6 +10374,7 @@ function TokenSourceRow({
|
|
|
10211
10374
|
chainName,
|
|
10212
10375
|
tokenLogoUri,
|
|
10213
10376
|
balance,
|
|
10377
|
+
balanceLabel,
|
|
10214
10378
|
selected,
|
|
10215
10379
|
requiresAuth,
|
|
10216
10380
|
notSupported,
|
|
@@ -10219,9 +10383,10 @@ function TokenSourceRow({
|
|
|
10219
10383
|
const { tokens } = useBlinkConfig();
|
|
10220
10384
|
const [hovered, setHovered] = react.useState(false);
|
|
10221
10385
|
const tokenLogo = tokenLogoUri ?? TOKEN_LOGOS[symbol];
|
|
10386
|
+
const balanceText = balanceLabel ?? (balance != null ? `$${formatUsdTwoDecimals2(balance)}` : null);
|
|
10222
10387
|
const ariaLabel = [
|
|
10223
10388
|
`${symbol} on ${chainName}`,
|
|
10224
|
-
|
|
10389
|
+
balanceText != null ? `${balanceText} balance` : null,
|
|
10225
10390
|
requiresAuth ? "authorisation required" : null,
|
|
10226
10391
|
notSupported ? NOT_SUPPORTED_LABEL.toLowerCase() : null
|
|
10227
10392
|
].filter(Boolean).join(", ");
|
|
@@ -10255,15 +10420,12 @@ function TokenSourceRow({
|
|
|
10255
10420
|
selected && /* @__PURE__ */ jsxRuntime.jsx(SelectedBadge, { accent: tokens.accent, fill: tokens.textInverse })
|
|
10256
10421
|
] }),
|
|
10257
10422
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: textColStyle2, children: [
|
|
10258
|
-
|
|
10259
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: symbolStyle(tokens.textMuted), children: symbol }),
|
|
10260
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: notSupportedTagStyle(tokens.bgInput, tokens.border, tokens.textMuted), children: NOT_SUPPORTED_BADGE_TEXT })
|
|
10261
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: symbolStyle(tokens.text), children: symbol }),
|
|
10423
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: symbolStyle(notSupported ? tokens.textMuted : tokens.text), children: symbol }),
|
|
10262
10424
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: chainStyle(tokens.textMuted), children: chainName })
|
|
10263
10425
|
] }),
|
|
10264
|
-
|
|
10265
|
-
"
|
|
10266
|
-
|
|
10426
|
+
(balanceText != null || notSupported) && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: balanceColStyle, children: [
|
|
10427
|
+
balanceText != null && /* @__PURE__ */ jsxRuntime.jsx("span", { style: balanceStyle2(tokens.textMuted), children: balanceText }),
|
|
10428
|
+
notSupported && /* @__PURE__ */ jsxRuntime.jsx("span", { style: notSupportedTagStyle(tokens.bgInput, tokens.border, tokens.textMuted), children: NOT_SUPPORTED_BADGE_TEXT })
|
|
10267
10429
|
] })
|
|
10268
10430
|
]
|
|
10269
10431
|
}
|
|
@@ -10372,11 +10534,12 @@ var balanceStyle2 = (color) => ({
|
|
|
10372
10534
|
whiteSpace: "nowrap",
|
|
10373
10535
|
flexShrink: 0
|
|
10374
10536
|
});
|
|
10375
|
-
var
|
|
10537
|
+
var balanceColStyle = {
|
|
10376
10538
|
display: "flex",
|
|
10377
|
-
|
|
10378
|
-
|
|
10379
|
-
|
|
10539
|
+
flexDirection: "column",
|
|
10540
|
+
alignItems: "flex-end",
|
|
10541
|
+
gap: 4,
|
|
10542
|
+
flexShrink: 0
|
|
10380
10543
|
};
|
|
10381
10544
|
var notSupportedTagStyle = (bg, borderColor, color) => ({
|
|
10382
10545
|
fontSize: 11,
|
|
@@ -11130,7 +11293,8 @@ function LoginScreen({
|
|
|
11130
11293
|
style: secondaryTextStyle(tokens, loading),
|
|
11131
11294
|
children: secondaryLabel
|
|
11132
11295
|
}
|
|
11133
|
-
)
|
|
11296
|
+
),
|
|
11297
|
+
/* @__PURE__ */ jsxRuntime.jsx(SupportFooter, {})
|
|
11134
11298
|
] }),
|
|
11135
11299
|
children: [
|
|
11136
11300
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack, right: headerRight }),
|
|
@@ -11302,7 +11466,7 @@ function DepositOptionsScreen({
|
|
|
11302
11466
|
const { tokens, promoTagText } = useBlinkConfig();
|
|
11303
11467
|
const [manualHovered, setManualHovered] = react.useState(false);
|
|
11304
11468
|
const [manualPressed, setManualPressed] = react.useState(false);
|
|
11305
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { hideScrollbar: true, children: [
|
|
11469
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { hideScrollbar: true, footer: /* @__PURE__ */ jsxRuntime.jsx(SupportFooter, {}), children: [
|
|
11306
11470
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11307
11471
|
ScreenHeader,
|
|
11308
11472
|
{
|
|
@@ -11457,7 +11621,7 @@ function WelcomeBackScreen({
|
|
|
11457
11621
|
const [depositPressed, setDepositPressed] = react.useState(false);
|
|
11458
11622
|
const [manualHovered, setManualHovered] = react.useState(false);
|
|
11459
11623
|
const [manualPressed, setManualPressed] = react.useState(false);
|
|
11460
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { children: [
|
|
11624
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { footer: /* @__PURE__ */ jsxRuntime.jsx(SupportFooter, {}), children: [
|
|
11461
11625
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11462
11626
|
ScreenHeader,
|
|
11463
11627
|
{
|
|
@@ -13217,7 +13381,7 @@ function LinkTokensScreen({
|
|
|
13217
13381
|
}
|
|
13218
13382
|
),
|
|
13219
13383
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle10, children: [
|
|
13220
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle7(t.text), children: "Pick your
|
|
13384
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle7(t.text), children: "Pick your stablecoin for passkey deposits" }),
|
|
13221
13385
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "blink-link-tokens-list", style: listCardStyle(t.bgRecessed), children: [
|
|
13222
13386
|
showShimmer ? Array.from({ length: SHIMMER_ROWS }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
13223
13387
|
"div",
|
|
@@ -13240,7 +13404,9 @@ function LinkTokensScreen({
|
|
|
13240
13404
|
{
|
|
13241
13405
|
symbol: entry.tokenSymbol,
|
|
13242
13406
|
chainName: entry.chainName,
|
|
13243
|
-
|
|
13407
|
+
tokenLogoUri: entry.tokenLogoUri,
|
|
13408
|
+
balance: entry.balanceLabel == null ? entry.balanceUsd : void 0,
|
|
13409
|
+
balanceLabel: entry.balanceLabel,
|
|
13244
13410
|
selected: i === selectedIndex,
|
|
13245
13411
|
notSupported: entry.notSupported,
|
|
13246
13412
|
onClick: () => onSelect(i)
|
|
@@ -15170,7 +15336,7 @@ function DepositAddressScreen({
|
|
|
15170
15336
|
const waitingForQr = !!depositAddress && !qrReady;
|
|
15171
15337
|
const awaitingSession = !!selectedOption && !session && !loading;
|
|
15172
15338
|
const showShimmer = loadingSources || showLoading || waitingForQr || awaitingSession;
|
|
15173
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { children: [
|
|
15339
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { footer: /* @__PURE__ */ jsxRuntime.jsx(SupportFooter, {}), children: [
|
|
15174
15340
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15175
15341
|
ScreenHeader,
|
|
15176
15342
|
{
|
|
@@ -16852,6 +17018,14 @@ var genericStackStyle = {
|
|
|
16852
17018
|
gap: 14
|
|
16853
17019
|
};
|
|
16854
17020
|
|
|
17021
|
+
// src/feeFormat.ts
|
|
17022
|
+
function formatNativeAmount(value, maxDecimals = 4) {
|
|
17023
|
+
if (!Number.isFinite(value) || value <= 0) return "0";
|
|
17024
|
+
const rounded = Number(value.toFixed(maxDecimals));
|
|
17025
|
+
if (rounded === 0) return `< ${(10 ** -maxDecimals).toFixed(maxDecimals)}`;
|
|
17026
|
+
return rounded.toLocaleString("en-US", { maximumFractionDigits: maxDecimals }).replace(/,/g, "");
|
|
17027
|
+
}
|
|
17028
|
+
|
|
16855
17029
|
// src/screenViewModels.ts
|
|
16856
17030
|
function findSelectedWallet(selectedAccount, selectedWalletId) {
|
|
16857
17031
|
return selectedAccount?.wallets.find((w) => w.id === selectedWalletId);
|
|
@@ -17018,7 +17192,11 @@ function buildLinkTokensScreenProps({
|
|
|
17018
17192
|
walletId: rawOption?.walletId,
|
|
17019
17193
|
tokenAddress: rawOption?.tokenAddress,
|
|
17020
17194
|
chainId: rawOption?.chainId != null ? Number(rawOption.chainId) : void 0,
|
|
17021
|
-
notSupported: false
|
|
17195
|
+
notSupported: false,
|
|
17196
|
+
// Server-provided token logo (token_addresses.logo_uri). The component
|
|
17197
|
+
// falls back to the bundled TOKEN_LOGOS map by symbol, so tokens without
|
|
17198
|
+
// a bundled asset (e.g. CASH) rely on this DB-driven URI.
|
|
17199
|
+
tokenLogoUri: t.logoURI ?? void 0
|
|
17022
17200
|
};
|
|
17023
17201
|
})
|
|
17024
17202
|
);
|
|
@@ -17028,19 +17206,32 @@ function buildLinkTokensScreenProps({
|
|
|
17028
17206
|
symbol: t.tokenSymbol,
|
|
17029
17207
|
chainName: chain.chainName,
|
|
17030
17208
|
balanceUsd: t.balance ?? 0,
|
|
17031
|
-
|
|
17032
|
-
|
|
17033
|
-
chainId: void 0,
|
|
17034
|
-
notSupported: true
|
|
17209
|
+
notSupported: true,
|
|
17210
|
+
tokenLogoUri: t.logoURI ?? void 0
|
|
17035
17211
|
}))
|
|
17036
17212
|
)
|
|
17037
17213
|
);
|
|
17038
|
-
|
|
17039
|
-
|
|
17040
|
-
|
|
17041
|
-
|
|
17042
|
-
|
|
17043
|
-
|
|
17214
|
+
rowContexts.push(
|
|
17215
|
+
...derived.selectSourceNativeChoices.map((native) => ({
|
|
17216
|
+
symbol: native.tokenSymbol,
|
|
17217
|
+
chainName: native.chainName,
|
|
17218
|
+
balanceUsd: 0,
|
|
17219
|
+
notSupported: true,
|
|
17220
|
+
tokenLogoUri: native.logoURI ?? void 0,
|
|
17221
|
+
balanceLabel: `${formatNativeAmount(native.amount)} ${native.tokenSymbol}`
|
|
17222
|
+
}))
|
|
17223
|
+
);
|
|
17224
|
+
const entries2 = rowContexts.map(
|
|
17225
|
+
({ symbol, chainName, balanceUsd, notSupported, tokenLogoUri, balanceLabel }) => ({
|
|
17226
|
+
tokenSymbol: symbol,
|
|
17227
|
+
chainName,
|
|
17228
|
+
balanceUsd,
|
|
17229
|
+
notSupported,
|
|
17230
|
+
// Only present on native rows — keeps stablecoin / WC entries unchanged.
|
|
17231
|
+
...tokenLogoUri != null ? { tokenLogoUri } : {},
|
|
17232
|
+
...balanceLabel != null ? { balanceLabel } : {}
|
|
17233
|
+
})
|
|
17234
|
+
);
|
|
17044
17235
|
const firstSupportedIndex = rowContexts.findIndex((row) => !row.notSupported);
|
|
17045
17236
|
const selectedTokenSymbol = flow.state.setupDepositToken?.symbol ?? derived.selectSourceRecommended?.tokenSymbol;
|
|
17046
17237
|
const selectedChainName = flow.state.setupDepositToken?.chainName ?? derived.selectSourceRecommended?.chainName;
|
|
@@ -18043,6 +18234,11 @@ function useSourceSelectionHandlers(_dispatch, orchestrator, options) {
|
|
|
18043
18234
|
const unsupportedOptions = pendingSelectSourceAction.metadata?.unsupportedOptions ?? [];
|
|
18044
18235
|
return buildSelectSourceChoices(unsupportedOptions, minTransferAmountUsd);
|
|
18045
18236
|
}, [pendingSelectSourceAction, minTransferAmountUsd]);
|
|
18237
|
+
const selectSourceNativeChoices = react.useMemo(() => {
|
|
18238
|
+
if (!pendingSelectSourceAction) return [];
|
|
18239
|
+
const nativeOptions = pendingSelectSourceAction.metadata?.nativeUnsupportedOptions ?? [];
|
|
18240
|
+
return buildNativeUnsupportedEntries(nativeOptions);
|
|
18241
|
+
}, [pendingSelectSourceAction]);
|
|
18046
18242
|
const selectSourceRecommended = react.useMemo(() => {
|
|
18047
18243
|
if (!pendingSelectSourceAction) return null;
|
|
18048
18244
|
return pendingSelectSourceAction.metadata?.recommended ?? null;
|
|
@@ -18094,6 +18290,7 @@ function useSourceSelectionHandlers(_dispatch, orchestrator, options) {
|
|
|
18094
18290
|
setSelectSourceTokenSymbol,
|
|
18095
18291
|
selectSourceChoices,
|
|
18096
18292
|
selectSourceUnsupportedChoices,
|
|
18293
|
+
selectSourceNativeChoices,
|
|
18097
18294
|
selectSourceRecommended,
|
|
18098
18295
|
selectSourceAvailableBalance,
|
|
18099
18296
|
handleSelectSourceChainChange,
|
|
@@ -20625,6 +20822,33 @@ function usePersistAmountToActiveSession({
|
|
|
20625
20822
|
});
|
|
20626
20823
|
}, [apiBaseUrl, sessionId, effectiveDepositAmount]);
|
|
20627
20824
|
}
|
|
20825
|
+
function useFingerprintFlowEvents(deps) {
|
|
20826
|
+
const { ready, authenticated, merchantId } = deps;
|
|
20827
|
+
const { getData } = react$1.useVisitorData({ immediate: false });
|
|
20828
|
+
const openedSentRef = react.useRef(false);
|
|
20829
|
+
const authenticatedSentRef = react.useRef(false);
|
|
20830
|
+
react.useEffect(() => {
|
|
20831
|
+
if (openedSentRef.current) return;
|
|
20832
|
+
openedSentRef.current = true;
|
|
20833
|
+
void getData({
|
|
20834
|
+
tag: { event: "blink_opened", ...merchantId ? { merchantId } : {} },
|
|
20835
|
+
...merchantId ? { linkedId: merchantId } : {}
|
|
20836
|
+
}).catch((error) => {
|
|
20837
|
+
console.error("Fingerprint blink_opened event failed", error);
|
|
20838
|
+
});
|
|
20839
|
+
}, [getData, merchantId]);
|
|
20840
|
+
react.useEffect(() => {
|
|
20841
|
+
if (authenticatedSentRef.current) return;
|
|
20842
|
+
if (!ready || !authenticated) return;
|
|
20843
|
+
authenticatedSentRef.current = true;
|
|
20844
|
+
void getData({
|
|
20845
|
+
tag: { event: "blink_authenticated", ...merchantId ? { merchantId } : {} },
|
|
20846
|
+
...merchantId ? { linkedId: merchantId } : {}
|
|
20847
|
+
}).catch((error) => {
|
|
20848
|
+
console.error("Fingerprint blink_authenticated event failed", error);
|
|
20849
|
+
});
|
|
20850
|
+
}, [getData, ready, authenticated, merchantId]);
|
|
20851
|
+
}
|
|
20628
20852
|
var NoMatchingExtensionError = class extends Error {
|
|
20629
20853
|
constructor() {
|
|
20630
20854
|
super("No installed EIP-6963 extension matches the selected wallet");
|
|
@@ -20663,6 +20887,11 @@ function BlinkPaymentInner({
|
|
|
20663
20887
|
return true;
|
|
20664
20888
|
})();
|
|
20665
20889
|
const effectiveAuthenticated = authenticated || popupAuthValid;
|
|
20890
|
+
useFingerprintFlowEvents({
|
|
20891
|
+
ready,
|
|
20892
|
+
authenticated: effectiveAuthenticated,
|
|
20893
|
+
merchantId: merchantAuthorization?.merchantId
|
|
20894
|
+
});
|
|
20666
20895
|
const effectiveGetAccessToken = react.useCallback(async () => {
|
|
20667
20896
|
if (popupAuthRef.current) {
|
|
20668
20897
|
if (isPopupAuthExpired(popupAuthRef.current.accessToken)) {
|
|
@@ -21271,6 +21500,7 @@ function BlinkPaymentInner({
|
|
|
21271
21500
|
selectedSource: derived.selectedSource,
|
|
21272
21501
|
selectSourceChoices: sourceSelection.selectSourceChoices,
|
|
21273
21502
|
selectSourceUnsupportedChoices: sourceSelection.selectSourceUnsupportedChoices,
|
|
21503
|
+
selectSourceNativeChoices: sourceSelection.selectSourceNativeChoices,
|
|
21274
21504
|
selectSourceRecommended: sourceSelection.selectSourceRecommended,
|
|
21275
21505
|
selectSourceAvailableBalance: sourceSelection.selectSourceAvailableBalance,
|
|
21276
21506
|
walletConnectChainIdsByAccount
|
|
@@ -21341,6 +21571,7 @@ exports.WalletPickerScreen = WalletPickerScreen;
|
|
|
21341
21571
|
exports.WelcomeBackScreen = WelcomeBackScreen;
|
|
21342
21572
|
exports.appendDebug = appendDebug;
|
|
21343
21573
|
exports.blinkApi = api_exports;
|
|
21574
|
+
exports.buildNativeUnsupportedEntries = buildNativeUnsupportedEntries;
|
|
21344
21575
|
exports.clearDebugEntries = clearDebugEntries;
|
|
21345
21576
|
exports.createInitialState = createInitialState;
|
|
21346
21577
|
exports.credentialIdBase64ToBytes = credentialIdBase64ToBytes;
|
|
@@ -21352,6 +21583,7 @@ exports.deviceHasPasskey = deviceHasPasskey;
|
|
|
21352
21583
|
exports.encodePermit2ApproveCalldata = encodePermit2ApproveCalldata;
|
|
21353
21584
|
exports.findDevicePasskey = findDevicePasskey;
|
|
21354
21585
|
exports.findDevicePasskeyViaPopup = findDevicePasskeyViaPopup;
|
|
21586
|
+
exports.formatNativeAmount = formatNativeAmount;
|
|
21355
21587
|
exports.getAtomicBatchSupportDebugInfo = getAtomicBatchSupportDebugInfo;
|
|
21356
21588
|
exports.getDebugEntries = getDebugEntries;
|
|
21357
21589
|
exports.getDeviceBiometricUnlockText = getDeviceBiometricUnlockText;
|