@swype-org/react-sdk 0.2.372 → 0.2.377

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.js CHANGED
@@ -11,6 +11,7 @@ import { getAccount, reconnect, disconnect, getWalletClient, getConnectors } fro
11
11
  import { encodeFunctionData, recoverTypedDataAddress, decodeAbiParameters } from 'viem';
12
12
  import { parseErc6492Signature } from 'viem/utils';
13
13
  import * as QRCode from 'qrcode';
14
+ import posthog from 'posthog-js';
14
15
  import * as Select from '@radix-ui/react-select';
15
16
 
16
17
  var __defProp = Object.defineProperty;
@@ -499,6 +500,14 @@ function isVisibleUsdAmountAtTwoDecimals(amount) {
499
500
  function isSelectableDepositSourceAmountUsd(amount, minTransferAmountUsd = DEFAULT_MIN_SEND_AMOUNT_USD) {
500
501
  return Number.isFinite(amount) && amount >= minTransferAmountUsd;
501
502
  }
503
+ function buildNativeUnsupportedEntries(options) {
504
+ return options.map((option) => ({
505
+ tokenSymbol: option.tokenSymbol,
506
+ chainName: option.chainName,
507
+ amount: parseRawBalance(option.rawBalance, option.decimals),
508
+ logoURI: option.logoURI ?? null
509
+ })).filter((entry) => entry.amount > 0);
510
+ }
502
511
  function buildSelectSourceChoices(options, minTransferAmountUsd = DEFAULT_MIN_SEND_AMOUNT_USD) {
503
512
  const chainChoices = [];
504
513
  const chainIndexByName = /* @__PURE__ */ new Map();
@@ -992,10 +1001,6 @@ var BLINK_PRIVY_APP_ID = "cmlil87uv004n0ck0blwumwek";
992
1001
  var BLINK_WC_PROJECT_ID = "f6c60234412f94ef9108dc8f67f4362c";
993
1002
  var BLINK_FINGERPRINT_API_KEY = "nr4FvTsZ6M5z2141FqrM";
994
1003
  var BLINK_FINGERPRINT_REGION = "us";
995
- function FingerprintVisitorPing() {
996
- useVisitorData({ immediate: true });
997
- return null;
998
- }
999
1004
  function buildStaticConnectors() {
1000
1005
  const userAgent = typeof navigator === "undefined" ? null : navigator.userAgent;
1001
1006
  return [
@@ -1104,30 +1109,30 @@ function BlinkProvider({
1104
1109
  );
1105
1110
  return (
1106
1111
  // Outermost wrapper: loads the Fingerprint browser agent once per
1107
- // provider mount, independent of wagmi/privy/query state. Visitor data
1108
- // collection starts here; no hook is exposed yet (see SDK barrel).
1109
- /* @__PURE__ */ jsxs(FingerprintProvider, { apiKey: BLINK_FINGERPRINT_API_KEY, region: BLINK_FINGERPRINT_REGION, children: [
1110
- /* @__PURE__ */ jsx(FingerprintVisitorPing, {}),
1111
- /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClientRef.current, children: /* @__PURE__ */ jsx(WagmiProvider, { config: wagmiConfig, reconnectOnMount: false, children: /* @__PURE__ */ jsx(
1112
- PrivyProvider,
1113
- {
1114
- appId: privyAppId ?? BLINK_PRIVY_APP_ID,
1115
- config: {
1116
- appearance: {
1117
- theme: getThemeBase(theme),
1118
- accentColor: getTheme(theme).accent
1119
- },
1120
- intl: {
1121
- defaultCountry: "US"
1122
- },
1123
- embeddedWallets: {
1124
- showWalletUIs: false
1125
- }
1112
+ // provider mount, independent of wagmi/privy/query state. The agent loads
1113
+ // here (including during the hidden preload warm-up), but identification is
1114
+ // deferred to explicit flow events fired from `BlinkPayment` see
1115
+ // `useFingerprintFlowEvents` so a preload that never opens is never
1116
+ // identified.
1117
+ /* @__PURE__ */ jsx(FingerprintProvider, { apiKey: BLINK_FINGERPRINT_API_KEY, region: BLINK_FINGERPRINT_REGION, children: /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClientRef.current, children: /* @__PURE__ */ jsx(WagmiProvider, { config: wagmiConfig, reconnectOnMount: false, children: /* @__PURE__ */ jsx(
1118
+ PrivyProvider,
1119
+ {
1120
+ appId: privyAppId ?? BLINK_PRIVY_APP_ID,
1121
+ config: {
1122
+ appearance: {
1123
+ theme: getThemeBase(theme),
1124
+ accentColor: getTheme(theme).accent
1126
1125
  },
1127
- children: /* @__PURE__ */ jsx(BlinkContext.Provider, { value, children })
1128
- }
1129
- ) }) })
1130
- ] })
1126
+ intl: {
1127
+ defaultCountry: "US"
1128
+ },
1129
+ embeddedWallets: {
1130
+ showWalletUIs: false
1131
+ }
1132
+ },
1133
+ children: /* @__PURE__ */ jsx(BlinkContext.Provider, { value, children })
1134
+ }
1135
+ ) }) }) })
1131
1136
  );
1132
1137
  }
1133
1138
  function useBlinkConfig() {
@@ -1549,11 +1554,11 @@ function detachAccountChangeListeners() {
1549
1554
  accountChangeBinding = null;
1550
1555
  }
1551
1556
  function providerKey(selection) {
1552
- const providerName = selection.providerName?.trim();
1553
- if (!providerName) {
1557
+ const providerName2 = selection.providerName?.trim();
1558
+ if (!providerName2) {
1554
1559
  throw new Error("Solana wallet metadata is missing providerName.");
1555
1560
  }
1556
- return `${selection.providerId ?? ""}:${providerName.toLowerCase()}`;
1561
+ return `${selection.providerId ?? ""}:${providerName2.toLowerCase()}`;
1557
1562
  }
1558
1563
  function assertSupportedProvider(selection) {
1559
1564
  const name = selection.providerName?.trim().toLowerCase();
@@ -4121,14 +4126,14 @@ function isBatchableAction(action) {
4121
4126
  return BATCHABLE_ACTION_TYPES.has(action.type);
4122
4127
  }
4123
4128
  function getSolanaWalletSelection(action) {
4124
- const providerName = action.metadata?.providerName;
4125
- if (typeof providerName !== "string" || providerName.trim() === "") {
4129
+ const providerName2 = action.metadata?.providerName;
4130
+ if (typeof providerName2 !== "string" || providerName2.trim() === "") {
4126
4131
  throw new Error(`${action.type} metadata is missing providerName.`);
4127
4132
  }
4128
4133
  const providerId = action.metadata?.providerId;
4129
4134
  return {
4130
4135
  ...typeof providerId === "string" && providerId.trim() !== "" ? { providerId } : {},
4131
- providerName
4136
+ providerName: providerName2
4132
4137
  };
4133
4138
  }
4134
4139
  function isPhantomEvmProviderAvailable() {
@@ -8439,6 +8444,209 @@ function applyAction(state, action) {
8439
8444
  return state;
8440
8445
  }
8441
8446
  }
8447
+ var BLOCKED_SUBSTRINGS = [
8448
+ "bearer",
8449
+ "signature",
8450
+ "signedpayload",
8451
+ "userop",
8452
+ "jwt",
8453
+ "secret",
8454
+ "password",
8455
+ "privatekey",
8456
+ "mnemonic",
8457
+ "seedphrase"
8458
+ ];
8459
+ function isBlockedKey(key) {
8460
+ const lower = key.toLowerCase();
8461
+ if (lower === "token" || lower.endsWith("token")) return true;
8462
+ return BLOCKED_SUBSTRINGS.some((blocked) => lower.includes(blocked));
8463
+ }
8464
+ function isReady() {
8465
+ return typeof posthog !== "undefined" && posthog.__loaded === true;
8466
+ }
8467
+ function sanitizeProps(props) {
8468
+ if (!props) return props;
8469
+ const clean = {};
8470
+ for (const [key, value] of Object.entries(props)) {
8471
+ if (isBlockedKey(key)) continue;
8472
+ if (value === void 0) continue;
8473
+ clean[key] = value;
8474
+ }
8475
+ return clean;
8476
+ }
8477
+ function registerSuperProps(props) {
8478
+ if (!isReady()) return;
8479
+ try {
8480
+ posthog.register(sanitizeProps(props) ?? {});
8481
+ } catch {
8482
+ }
8483
+ }
8484
+ function track(event, props) {
8485
+ if (!isReady()) return;
8486
+ try {
8487
+ posthog.capture(event, sanitizeProps(props));
8488
+ } catch {
8489
+ }
8490
+ }
8491
+ function identifyUser(privyUserId, props) {
8492
+ if (!isReady() || !privyUserId) return;
8493
+ try {
8494
+ posthog.identify(privyUserId, sanitizeProps(props));
8495
+ } catch {
8496
+ }
8497
+ }
8498
+ function resolveAnalyticsEnvironment(opts) {
8499
+ const explicit = opts.explicit?.trim();
8500
+ if (explicit) return explicit;
8501
+ const raw = opts.apiBaseUrl ?? "";
8502
+ let host = raw;
8503
+ try {
8504
+ host = new URL(raw).hostname;
8505
+ } catch {
8506
+ }
8507
+ const h = host.toLowerCase();
8508
+ if (h === "" || h.includes("localhost") || h.startsWith("127.")) return "development";
8509
+ if (h.includes("smokebox")) return "smokebox";
8510
+ if (h.includes("sandbox")) return "sandbox";
8511
+ if (h.includes("staging")) return "staging";
8512
+ return "production";
8513
+ }
8514
+ function resetUser() {
8515
+ if (!isReady()) return;
8516
+ try {
8517
+ posthog.reset();
8518
+ } catch {
8519
+ }
8520
+ }
8521
+
8522
+ // src/analyticsEvents.ts
8523
+ function providerName(state, providerId) {
8524
+ return state.providers.find((p) => p.id === providerId)?.name;
8525
+ }
8526
+ function amountUsd(transfer) {
8527
+ return transfer.amount?.currency === "USD" ? transfer.amount.amount : transfer.amount?.amount;
8528
+ }
8529
+ function sourceChain(transfer) {
8530
+ return transfer.sources?.[0]?.provider?.chainFamily;
8531
+ }
8532
+ function trackAction(action, state, ctx) {
8533
+ const device = ctx.device;
8534
+ switch (action.type) {
8535
+ case "PASSKEY_ACTIVATED":
8536
+ track("auth_succeeded", { method: "passkey", device });
8537
+ break;
8538
+ case "SELECT_PROVIDER":
8539
+ track("wallet_provider_selected", {
8540
+ device,
8541
+ providerId: action.providerId,
8542
+ providerName: providerName(state, action.providerId),
8543
+ transport: device === "desktop" ? "inline" : "deeplink"
8544
+ });
8545
+ break;
8546
+ case "MOBILE_DEEPLINK_READY":
8547
+ track("wallet_deeplink_opened", { device });
8548
+ break;
8549
+ case "SET_SETUP_DEPOSIT_TOKEN":
8550
+ track("token_selected", {
8551
+ device,
8552
+ tokenSymbol: action.symbol,
8553
+ chainName: action.chainName
8554
+ });
8555
+ break;
8556
+ case "FINALIZE_AMOUNT": {
8557
+ const parsed = Number(state.amount);
8558
+ track("amount_entered", {
8559
+ device,
8560
+ amountUsd: Number.isFinite(parsed) ? parsed : void 0
8561
+ });
8562
+ break;
8563
+ }
8564
+ case "PAY_STARTED":
8565
+ track("deposit_clicked", { device });
8566
+ break;
8567
+ case "TRANSFER_CREATED":
8568
+ track("transfer_created", {
8569
+ device,
8570
+ chainFamily: sourceChain(action.transfer)
8571
+ });
8572
+ break;
8573
+ case "TRANSFER_SIGNED":
8574
+ track("transfer_signed", { device });
8575
+ break;
8576
+ case "TRANSFER_COMPLETED":
8577
+ track("transfer_completed", {
8578
+ device,
8579
+ amountUsd: amountUsd(action.transfer),
8580
+ chainFamily: sourceChain(action.transfer)
8581
+ });
8582
+ break;
8583
+ case "CONFIRM_SIGN_SUCCESS":
8584
+ track("confirm_sign_success", { device });
8585
+ break;
8586
+ case "MOBILE_SETUP_COMPLETE":
8587
+ track("wallet_setup_complete", { device });
8588
+ break;
8589
+ case "TRANSFER_FAILED":
8590
+ track("transfer_error", {
8591
+ device,
8592
+ type: "transfer_failed",
8593
+ stage: "processing",
8594
+ message: action.error
8595
+ });
8596
+ break;
8597
+ case "PROCESSING_TIMEOUT":
8598
+ track("transfer_error", {
8599
+ device,
8600
+ type: "processing_timeout",
8601
+ stage: "processing",
8602
+ message: action.error
8603
+ });
8604
+ break;
8605
+ case "SIGN_PAYLOAD_EXPIRED":
8606
+ track("transfer_error", {
8607
+ device,
8608
+ type: "sign_payload_expired",
8609
+ stage: "signing",
8610
+ message: action.error
8611
+ });
8612
+ break;
8613
+ case "PAY_ERROR":
8614
+ track("transfer_error", {
8615
+ device,
8616
+ type: "pay_error",
8617
+ stage: "creation",
8618
+ message: action.error
8619
+ });
8620
+ break;
8621
+ }
8622
+ }
8623
+ function useAnalyticsScreenView(phase, device) {
8624
+ const lastScreenRef = useRef(null);
8625
+ const screen = screenForPhase(phase);
8626
+ useEffect(() => {
8627
+ if (lastScreenRef.current === screen) return;
8628
+ lastScreenRef.current = screen;
8629
+ track("screen_viewed", { screen, phase: phase.step, device });
8630
+ }, [screen, phase.step, device]);
8631
+ }
8632
+ function usePostHogIdentify() {
8633
+ const { ready, authenticated, user } = usePrivy();
8634
+ const identifiedIdRef = useRef(null);
8635
+ useEffect(() => {
8636
+ if (!ready) return;
8637
+ if (authenticated && user?.id) {
8638
+ if (identifiedIdRef.current !== user.id) {
8639
+ identifyUser(user.id);
8640
+ identifiedIdRef.current = user.id;
8641
+ }
8642
+ return;
8643
+ }
8644
+ if (identifiedIdRef.current !== null) {
8645
+ resetUser();
8646
+ identifiedIdRef.current = null;
8647
+ }
8648
+ }, [ready, authenticated, user?.id]);
8649
+ }
8442
8650
 
8443
8651
  // src/setupDepositConfirmation.ts
8444
8652
  function deriveEffectiveSetupSource(setupDepositToken, setupSelectedSourceOption) {
@@ -9302,6 +9510,8 @@ var TETHER_LOGO = svgToDataUri(TETHER_SVG);
9302
9510
  var USDH_LOGO = svgToDataUri(USDH_SVG);
9303
9511
  var ETH_LOGO = "https://assets.relay.link/icons/currencies/eth.png";
9304
9512
  var SOL_LOGO = "https://assets.relay.link/icons/currencies/sol.png";
9513
+ var MON_LOGO = "https://assets.relay.link/icons/currencies/mon.png";
9514
+ var BNB_LOGO = "https://assets.relay.link/icons/currencies/bnb.png";
9305
9515
  var KNOWN_LOGOS = {
9306
9516
  metamask: METAMASK_LOGO,
9307
9517
  base: BASE_LOGO,
@@ -9319,7 +9529,9 @@ var TOKEN_LOGOS = {
9319
9529
  USDM: USDM_LOGO,
9320
9530
  USDH: USDH_LOGO,
9321
9531
  ETH: ETH_LOGO,
9322
- SOL: SOL_LOGO
9532
+ SOL: SOL_LOGO,
9533
+ MON: MON_LOGO,
9534
+ BNB: BNB_LOGO
9323
9535
  };
9324
9536
  var CHAIN_LOGOS = {
9325
9537
  base: BASE_CHAIN_LOGO,
@@ -10344,6 +10556,7 @@ function TokenSourceRow({
10344
10556
  chainName,
10345
10557
  tokenLogoUri,
10346
10558
  balance,
10559
+ balanceLabel,
10347
10560
  selected,
10348
10561
  requiresAuth,
10349
10562
  notSupported,
@@ -10352,9 +10565,10 @@ function TokenSourceRow({
10352
10565
  const { tokens } = useBlinkConfig();
10353
10566
  const [hovered, setHovered] = useState(false);
10354
10567
  const tokenLogo = tokenLogoUri ?? TOKEN_LOGOS[symbol];
10568
+ const balanceText = balanceLabel ?? (balance != null ? `$${formatUsdTwoDecimals2(balance)}` : null);
10355
10569
  const ariaLabel = [
10356
10570
  `${symbol} on ${chainName}`,
10357
- balance != null ? `$${formatUsdTwoDecimals2(balance)} balance` : null,
10571
+ balanceText != null ? `${balanceText} balance` : null,
10358
10572
  requiresAuth ? "authorisation required" : null,
10359
10573
  notSupported ? NOT_SUPPORTED_LABEL.toLowerCase() : null
10360
10574
  ].filter(Boolean).join(", ");
@@ -10388,15 +10602,12 @@ function TokenSourceRow({
10388
10602
  selected && /* @__PURE__ */ jsx(SelectedBadge, { accent: tokens.accent, fill: tokens.textInverse })
10389
10603
  ] }),
10390
10604
  /* @__PURE__ */ jsxs("span", { style: textColStyle2, children: [
10391
- notSupported ? /* @__PURE__ */ jsxs("span", { style: symbolLineStyle, children: [
10392
- /* @__PURE__ */ jsx("span", { style: symbolStyle(tokens.textMuted), children: symbol }),
10393
- /* @__PURE__ */ jsx("span", { style: notSupportedTagStyle(tokens.bgInput, tokens.border, tokens.textMuted), children: NOT_SUPPORTED_BADGE_TEXT })
10394
- ] }) : /* @__PURE__ */ jsx("span", { style: symbolStyle(tokens.text), children: symbol }),
10605
+ /* @__PURE__ */ jsx("span", { style: symbolStyle(notSupported ? tokens.textMuted : tokens.text), children: symbol }),
10395
10606
  /* @__PURE__ */ jsx("span", { style: chainStyle(tokens.textMuted), children: chainName })
10396
10607
  ] }),
10397
- balance != null && /* @__PURE__ */ jsxs("span", { style: balanceStyle2(tokens.textMuted), children: [
10398
- "$",
10399
- formatUsdTwoDecimals2(balance)
10608
+ (balanceText != null || notSupported) && /* @__PURE__ */ jsxs("span", { style: balanceColStyle, children: [
10609
+ balanceText != null && /* @__PURE__ */ jsx("span", { style: balanceStyle2(tokens.textMuted), children: balanceText }),
10610
+ notSupported && /* @__PURE__ */ jsx("span", { style: notSupportedTagStyle(tokens.bgInput, tokens.border, tokens.textMuted), children: NOT_SUPPORTED_BADGE_TEXT })
10400
10611
  ] })
10401
10612
  ]
10402
10613
  }
@@ -10505,11 +10716,12 @@ var balanceStyle2 = (color) => ({
10505
10716
  whiteSpace: "nowrap",
10506
10717
  flexShrink: 0
10507
10718
  });
10508
- var symbolLineStyle = {
10719
+ var balanceColStyle = {
10509
10720
  display: "flex",
10510
- alignItems: "center",
10511
- gap: 6,
10512
- minWidth: 0
10721
+ flexDirection: "column",
10722
+ alignItems: "flex-end",
10723
+ gap: 4,
10724
+ flexShrink: 0
10513
10725
  };
10514
10726
  var notSupportedTagStyle = (bg, borderColor, color) => ({
10515
10727
  fontSize: 11,
@@ -13093,7 +13305,7 @@ var lockBannerTextStyle = (color) => ({
13093
13305
  function ManualTransferPasskeyScreen({
13094
13306
  onCreatePasskey,
13095
13307
  onNoThanks,
13096
- amountUsd,
13308
+ amountUsd: amountUsd2,
13097
13309
  loading = false,
13098
13310
  error,
13099
13311
  onBack,
@@ -13351,7 +13563,7 @@ function LinkTokensScreen({
13351
13563
  }
13352
13564
  ),
13353
13565
  /* @__PURE__ */ jsxs("div", { style: contentStyle10, children: [
13354
- /* @__PURE__ */ jsx("h2", { style: headingStyle7(t.text), children: "Pick your asset for passkey deposits" }),
13566
+ /* @__PURE__ */ jsx("h2", { style: headingStyle7(t.text), children: "Pick your stablecoin for passkey deposits" }),
13355
13567
  /* @__PURE__ */ jsxs("div", { className: "blink-link-tokens-list", style: listCardStyle(t.bgRecessed), children: [
13356
13568
  showShimmer ? Array.from({ length: SHIMMER_ROWS }).map((_, i) => /* @__PURE__ */ jsxs(
13357
13569
  "div",
@@ -13374,7 +13586,9 @@ function LinkTokensScreen({
13374
13586
  {
13375
13587
  symbol: entry.tokenSymbol,
13376
13588
  chainName: entry.chainName,
13377
- balance: entry.balanceUsd,
13589
+ tokenLogoUri: entry.tokenLogoUri,
13590
+ balance: entry.balanceLabel == null ? entry.balanceUsd : void 0,
13591
+ balanceLabel: entry.balanceLabel,
13378
13592
  selected: i === selectedIndex,
13379
13593
  notSupported: entry.notSupported,
13380
13594
  onClick: () => onSelect(i)
@@ -16986,6 +17200,14 @@ var genericStackStyle = {
16986
17200
  gap: 14
16987
17201
  };
16988
17202
 
17203
+ // src/feeFormat.ts
17204
+ function formatNativeAmount(value, maxDecimals = 4) {
17205
+ if (!Number.isFinite(value) || value <= 0) return "0";
17206
+ const rounded = Number(value.toFixed(maxDecimals));
17207
+ if (rounded === 0) return `< ${(10 ** -maxDecimals).toFixed(maxDecimals)}`;
17208
+ return rounded.toLocaleString("en-US", { maximumFractionDigits: maxDecimals }).replace(/,/g, "");
17209
+ }
17210
+
16989
17211
  // src/screenViewModels.ts
16990
17212
  function findSelectedWallet(selectedAccount, selectedWalletId) {
16991
17213
  return selectedAccount?.wallets.find((w) => w.id === selectedWalletId);
@@ -17152,7 +17374,11 @@ function buildLinkTokensScreenProps({
17152
17374
  walletId: rawOption?.walletId,
17153
17375
  tokenAddress: rawOption?.tokenAddress,
17154
17376
  chainId: rawOption?.chainId != null ? Number(rawOption.chainId) : void 0,
17155
- notSupported: false
17377
+ notSupported: false,
17378
+ // Server-provided token logo (token_addresses.logo_uri). The component
17379
+ // falls back to the bundled TOKEN_LOGOS map by symbol, so tokens without
17380
+ // a bundled asset (e.g. CASH) rely on this DB-driven URI.
17381
+ tokenLogoUri: t.logoURI ?? void 0
17156
17382
  };
17157
17383
  })
17158
17384
  );
@@ -17162,19 +17388,32 @@ function buildLinkTokensScreenProps({
17162
17388
  symbol: t.tokenSymbol,
17163
17389
  chainName: chain.chainName,
17164
17390
  balanceUsd: t.balance ?? 0,
17165
- walletId: void 0,
17166
- tokenAddress: void 0,
17167
- chainId: void 0,
17168
- notSupported: true
17391
+ notSupported: true,
17392
+ tokenLogoUri: t.logoURI ?? void 0
17169
17393
  }))
17170
17394
  )
17171
17395
  );
17172
- const entries2 = rowContexts.map(({ symbol, chainName, balanceUsd, notSupported }) => ({
17173
- tokenSymbol: symbol,
17174
- chainName,
17175
- balanceUsd,
17176
- notSupported
17177
- }));
17396
+ rowContexts.push(
17397
+ ...derived.selectSourceNativeChoices.map((native) => ({
17398
+ symbol: native.tokenSymbol,
17399
+ chainName: native.chainName,
17400
+ balanceUsd: 0,
17401
+ notSupported: true,
17402
+ tokenLogoUri: native.logoURI ?? void 0,
17403
+ balanceLabel: `${formatNativeAmount(native.amount)} ${native.tokenSymbol}`
17404
+ }))
17405
+ );
17406
+ const entries2 = rowContexts.map(
17407
+ ({ symbol, chainName, balanceUsd, notSupported, tokenLogoUri, balanceLabel }) => ({
17408
+ tokenSymbol: symbol,
17409
+ chainName,
17410
+ balanceUsd,
17411
+ notSupported,
17412
+ // Only present on native rows — keeps stablecoin / WC entries unchanged.
17413
+ ...tokenLogoUri != null ? { tokenLogoUri } : {},
17414
+ ...balanceLabel != null ? { balanceLabel } : {}
17415
+ })
17416
+ );
17178
17417
  const firstSupportedIndex = rowContexts.findIndex((row) => !row.notSupported);
17179
17418
  const selectedTokenSymbol = flow.state.setupDepositToken?.symbol ?? derived.selectSourceRecommended?.tokenSymbol;
17180
17419
  const selectedChainName = flow.state.setupDepositToken?.chainName ?? derived.selectSourceRecommended?.chainName;
@@ -17770,6 +18009,7 @@ function useAuthHandlers(dispatch, apiBaseUrl, popupAuthRef) {
17770
18009
  dispatch({ type: "PASSKEY_ACTIVATED", credentialId: result.credentialId, publicKey: result.publicKey });
17771
18010
  dispatch({ type: "SYNC_PRIVY_SESSION", ready: true, authenticated: true });
17772
18011
  window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, result.credentialId);
18012
+ track("login_succeeded", { method: "passkey", popup: true });
17773
18013
  } catch (err) {
17774
18014
  captureException(err);
17775
18015
  dispatch({
@@ -17782,6 +18022,7 @@ function useAuthHandlers(dispatch, apiBaseUrl, popupAuthRef) {
17782
18022
  }, [dispatch, popupAuthRef]);
17783
18023
  const { loginWithPasskey, state: loginState } = useLoginWithPasskey({
17784
18024
  onComplete: (params) => {
18025
+ track("login_succeeded", { method: "passkey", popup: false });
17785
18026
  handleAuthComplete(params.user);
17786
18027
  },
17787
18028
  onError: (error) => {
@@ -17810,6 +18051,7 @@ function useAuthHandlers(dispatch, apiBaseUrl, popupAuthRef) {
17810
18051
  dispatch({ type: "PASSKEY_ACTIVATED", credentialId: result.credentialId, publicKey: result.publicKey });
17811
18052
  dispatch({ type: "SYNC_PRIVY_SESSION", ready: true, authenticated: true });
17812
18053
  window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, result.credentialId);
18054
+ track("signup_succeeded", { method: "passkey", popup: true });
17813
18055
  } catch (err) {
17814
18056
  captureException(err);
17815
18057
  dispatch({
@@ -17822,6 +18064,7 @@ function useAuthHandlers(dispatch, apiBaseUrl, popupAuthRef) {
17822
18064
  }, [dispatch, popupAuthRef]);
17823
18065
  const { signupWithPasskey, state: signupState } = useSignupWithPasskey({
17824
18066
  onComplete: (params) => {
18067
+ track("signup_succeeded", { method: "passkey", popup: false });
17825
18068
  handleAuthComplete(params.user);
17826
18069
  },
17827
18070
  onError: (error) => {
@@ -18177,6 +18420,11 @@ function useSourceSelectionHandlers(_dispatch, orchestrator, options) {
18177
18420
  const unsupportedOptions = pendingSelectSourceAction.metadata?.unsupportedOptions ?? [];
18178
18421
  return buildSelectSourceChoices(unsupportedOptions, minTransferAmountUsd);
18179
18422
  }, [pendingSelectSourceAction, minTransferAmountUsd]);
18423
+ const selectSourceNativeChoices = useMemo(() => {
18424
+ if (!pendingSelectSourceAction) return [];
18425
+ const nativeOptions = pendingSelectSourceAction.metadata?.nativeUnsupportedOptions ?? [];
18426
+ return buildNativeUnsupportedEntries(nativeOptions);
18427
+ }, [pendingSelectSourceAction]);
18180
18428
  const selectSourceRecommended = useMemo(() => {
18181
18429
  if (!pendingSelectSourceAction) return null;
18182
18430
  return pendingSelectSourceAction.metadata?.recommended ?? null;
@@ -18228,6 +18476,7 @@ function useSourceSelectionHandlers(_dispatch, orchestrator, options) {
18228
18476
  setSelectSourceTokenSymbol,
18229
18477
  selectSourceChoices,
18230
18478
  selectSourceUnsupportedChoices,
18479
+ selectSourceNativeChoices,
18231
18480
  selectSourceRecommended,
18232
18481
  selectSourceAvailableBalance,
18233
18482
  handleSelectSourceChainChange,
@@ -18586,7 +18835,7 @@ function useProviderHandlers(deps) {
18586
18835
  return null;
18587
18836
  }
18588
18837
  const provider = providers.find((p) => p.id === providerId);
18589
- const providerName = provider?.name ?? "Wallet";
18838
+ const providerName2 = provider?.name ?? "Wallet";
18590
18839
  try {
18591
18840
  const token = await getAccessToken();
18592
18841
  if (!token) throw new Error("Not authenticated");
@@ -18594,7 +18843,7 @@ function useProviderHandlers(deps) {
18594
18843
  const accountId = crypto.randomUUID();
18595
18844
  const account = await createAccount(apiBaseUrl, token, {
18596
18845
  id: accountId,
18597
- name: providerName,
18846
+ name: providerName2,
18598
18847
  credentialId: activeCredentialId,
18599
18848
  providerId,
18600
18849
  ...merchantAuthorization ? {
@@ -18643,7 +18892,7 @@ function useProviderHandlers(deps) {
18643
18892
  return;
18644
18893
  }
18645
18894
  const provider = providers.find((p) => p.id === providerId);
18646
- const providerName = provider?.name ?? "Wallet";
18895
+ const providerName2 = provider?.name ?? "Wallet";
18647
18896
  let shouldRestoreDesktopSelectionOnError = shouldSnapshotDesktopSelection;
18648
18897
  try {
18649
18898
  await resetWalletConnect();
@@ -18666,7 +18915,7 @@ function useProviderHandlers(deps) {
18666
18915
  const newAccountId = crypto.randomUUID();
18667
18916
  const account = await createAccount(apiBaseUrl, token, {
18668
18917
  id: newAccountId,
18669
- name: providerName,
18918
+ name: providerName2,
18670
18919
  credentialId: activeCredentialId,
18671
18920
  providerId,
18672
18921
  ...merchantAuthorization ? {
@@ -20759,6 +21008,33 @@ function usePersistAmountToActiveSession({
20759
21008
  });
20760
21009
  }, [apiBaseUrl, sessionId, effectiveDepositAmount]);
20761
21010
  }
21011
+ function useFingerprintFlowEvents(deps) {
21012
+ const { ready, authenticated, merchantId } = deps;
21013
+ const { getData } = useVisitorData({ immediate: false });
21014
+ const openedSentRef = useRef(false);
21015
+ const authenticatedSentRef = useRef(false);
21016
+ useEffect(() => {
21017
+ if (openedSentRef.current) return;
21018
+ openedSentRef.current = true;
21019
+ void getData({
21020
+ tag: { event: "blink_opened", ...merchantId ? { merchantId } : {} },
21021
+ ...merchantId ? { linkedId: merchantId } : {}
21022
+ }).catch((error) => {
21023
+ console.error("Fingerprint blink_opened event failed", error);
21024
+ });
21025
+ }, [getData, merchantId]);
21026
+ useEffect(() => {
21027
+ if (authenticatedSentRef.current) return;
21028
+ if (!ready || !authenticated) return;
21029
+ authenticatedSentRef.current = true;
21030
+ void getData({
21031
+ tag: { event: "blink_authenticated", ...merchantId ? { merchantId } : {} },
21032
+ ...merchantId ? { linkedId: merchantId } : {}
21033
+ }).catch((error) => {
21034
+ console.error("Fingerprint blink_authenticated event failed", error);
21035
+ });
21036
+ }, [getData, ready, authenticated, merchantId]);
21037
+ }
20762
21038
  var NoMatchingExtensionError = class extends Error {
20763
21039
  constructor() {
20764
21040
  super("No installed EIP-6963 extension matches the selected wallet");
@@ -20797,6 +21073,11 @@ function BlinkPaymentInner({
20797
21073
  return true;
20798
21074
  })();
20799
21075
  const effectiveAuthenticated = authenticated || popupAuthValid;
21076
+ useFingerprintFlowEvents({
21077
+ ready,
21078
+ authenticated: effectiveAuthenticated,
21079
+ merchantId: merchantAuthorization?.merchantId
21080
+ });
20800
21081
  const effectiveGetAccessToken = useCallback(async () => {
20801
21082
  if (popupAuthRef.current) {
20802
21083
  if (isPopupAuthExpired(popupAuthRef.current.accessToken)) {
@@ -20812,7 +21093,7 @@ function BlinkPaymentInner({
20812
21093
  useWalletConnector: useWalletConnectorProp,
20813
21094
  userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
20814
21095
  });
20815
- const [state, dispatch] = useReducer(
21096
+ const [state, rawDispatch] = useReducer(
20816
21097
  paymentReducer,
20817
21098
  {
20818
21099
  depositAmount,
@@ -20822,6 +21103,30 @@ function BlinkPaymentInner({
20822
21103
  },
20823
21104
  createInitialState
20824
21105
  );
21106
+ const device = isDesktop ? "desktop" : "mobile";
21107
+ const stateRef = useRef(state);
21108
+ stateRef.current = state;
21109
+ const dispatch = useCallback(
21110
+ (action) => {
21111
+ trackAction(action, stateRef.current, { device });
21112
+ rawDispatch(action);
21113
+ },
21114
+ [device]
21115
+ );
21116
+ usePostHogIdentify();
21117
+ useAnalyticsScreenView(state.phase, device);
21118
+ const flowOpenedRef = useRef(false);
21119
+ useEffect(() => {
21120
+ if (flowOpenedRef.current) return;
21121
+ flowOpenedRef.current = true;
21122
+ registerSuperProps({ device });
21123
+ track("flow_opened", {
21124
+ device,
21125
+ isMobileApp: isMobileApp ?? false,
21126
+ fullWidget: enableFullWidget ?? false,
21127
+ hasAmount: depositAmount != null
21128
+ });
21129
+ }, []);
20825
21130
  const polling = useTransferPolling(3e3, effectiveGetAccessToken);
20826
21131
  const transferSigning = useTransferSigning(2e3, { getAccessToken: effectiveGetAccessToken });
20827
21132
  const mobileFlowRefs = {
@@ -21405,6 +21710,7 @@ function BlinkPaymentInner({
21405
21710
  selectedSource: derived.selectedSource,
21406
21711
  selectSourceChoices: sourceSelection.selectSourceChoices,
21407
21712
  selectSourceUnsupportedChoices: sourceSelection.selectSourceUnsupportedChoices,
21713
+ selectSourceNativeChoices: sourceSelection.selectSourceNativeChoices,
21408
21714
  selectSourceRecommended: sourceSelection.selectSourceRecommended,
21409
21715
  selectSourceAvailableBalance: sourceSelection.selectSourceAvailableBalance,
21410
21716
  walletConnectChainIdsByAccount
@@ -21424,6 +21730,6 @@ function BlinkPaymentInner({
21424
21730
  ) });
21425
21731
  }
21426
21732
 
21427
- export { ACCOUNT_SWITCH_CONFLICT_MESSAGE, AdvancedSourceScreen, ApprovingInWalletScreen, AuthorizationSessionCancelledError, BLINK_ERROR_ILLUSTRATION, BLINK_LOGO, BLINK_MASCOT, BLINK_PASSKEY_ILLUSTRATION, BLINK_SUCCESS_ILLUSTRATION, BlinkDepositButton, BlinkErrorScreen, BlinkInitialLoadingScreen, BlinkLoadingScreen, BlinkPayment, BlinkProvider, ConfirmSignScreen, DepositCompleteScreen, DepositOptionsScreen, DepositScreen, DepositTransferStatusScreen, GuestTokenPickerScreen, IconCircle, InfoBanner, LOGIN_KEY_ILLUSTRATION, LinkTokensScreen, LoginScreen, ManualTransferPasskeyScreen, OpenWalletScreen, OtpVerifyScreen, OutlineButton, PasskeyIframeBlockedError, PasskeyPopupWelcomeScreen, PasskeyScreen, PoweredByFooter, PrimaryButton, ScreenHeader, ScreenLayout, SecondaryButton, SelectDepositSourceScreen, SelectSourceScreen, SettingsMenu, Spinner, StepList, StepRenderer, SuccessScreen, TokenPickerScreen, VerifyPasskeyScreen, WalletPickerScreen, WelcomeBackScreen, appendDebug, api_exports as blinkApi, clearDebugEntries, createInitialState, credentialIdBase64ToBytes, darkTheme, darkThemeNew, darkTransparentTheme, darkTransparentThemeNew, deviceHasPasskey, encodePermit2ApproveCalldata, findDevicePasskey, findDevicePasskeyViaPopup, getAtomicBatchSupportDebugInfo, getDebugEntries, getDeviceBiometricUnlockText, getTheme, getThemeBase, getWalletCapabilities, isAuthorizationSessionCancelled, isExpectedAuthorizationCancellation, isTerminalTransferStatus, isTransferAwaitingCompletion, isTransparentTheme, isUserDismissedAuthorizationError, isVisibleUsdAmountAtTwoDecimals, lightTheme, lightThemeNew, lightTransparentTheme, lightTransparentThemeNew, mapGuestPickerEntries, replaceOpenProviderForAccountSwitch, resolvePasskeyRpId, screenForPhase, subscribeDebug, supportsAtomicBatch, supportsPaymasterService, useAuthorizationExecutor, useAuthorizationOrchestrator, useBlinkConfig, useBlinkDebugLog, useBlinkDepositAmount, useSolanaAccountSwitchEffect, useTransferPolling, useTransferSigning };
21733
+ export { ACCOUNT_SWITCH_CONFLICT_MESSAGE, AdvancedSourceScreen, ApprovingInWalletScreen, AuthorizationSessionCancelledError, BLINK_ERROR_ILLUSTRATION, BLINK_LOGO, BLINK_MASCOT, BLINK_PASSKEY_ILLUSTRATION, BLINK_SUCCESS_ILLUSTRATION, BlinkDepositButton, BlinkErrorScreen, BlinkInitialLoadingScreen, BlinkLoadingScreen, BlinkPayment, BlinkProvider, ConfirmSignScreen, DepositCompleteScreen, DepositOptionsScreen, DepositScreen, DepositTransferStatusScreen, GuestTokenPickerScreen, IconCircle, InfoBanner, LOGIN_KEY_ILLUSTRATION, LinkTokensScreen, LoginScreen, ManualTransferPasskeyScreen, OpenWalletScreen, OtpVerifyScreen, OutlineButton, PasskeyIframeBlockedError, PasskeyPopupWelcomeScreen, PasskeyScreen, PoweredByFooter, PrimaryButton, ScreenHeader, ScreenLayout, SecondaryButton, SelectDepositSourceScreen, SelectSourceScreen, SettingsMenu, Spinner, StepList, StepRenderer, SuccessScreen, TokenPickerScreen, VerifyPasskeyScreen, WalletPickerScreen, WelcomeBackScreen, appendDebug, api_exports as blinkApi, buildNativeUnsupportedEntries, clearDebugEntries, createInitialState, credentialIdBase64ToBytes, darkTheme, darkThemeNew, darkTransparentTheme, darkTransparentThemeNew, deviceHasPasskey, encodePermit2ApproveCalldata, findDevicePasskey, findDevicePasskeyViaPopup, formatNativeAmount, getAtomicBatchSupportDebugInfo, getDebugEntries, getDeviceBiometricUnlockText, getTheme, getThemeBase, getWalletCapabilities, identifyUser, isAuthorizationSessionCancelled, isExpectedAuthorizationCancellation, isTerminalTransferStatus, isTransferAwaitingCompletion, isTransparentTheme, isUserDismissedAuthorizationError, isVisibleUsdAmountAtTwoDecimals, lightTheme, lightThemeNew, lightTransparentTheme, lightTransparentThemeNew, mapGuestPickerEntries, replaceOpenProviderForAccountSwitch, resetUser, resolveAnalyticsEnvironment, resolvePasskeyRpId, sanitizeProps, screenForPhase, subscribeDebug, supportsAtomicBatch, supportsPaymasterService, track, useAuthorizationExecutor, useAuthorizationOrchestrator, useBlinkConfig, useBlinkDebugLog, useBlinkDepositAmount, useSolanaAccountSwitchEffect, useTransferPolling, useTransferSigning };
21428
21734
  //# sourceMappingURL=index.js.map
21429
21735
  //# sourceMappingURL=index.js.map