@swype-org/react-sdk 0.1.287 → 0.1.293

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
@@ -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()}`);
@@ -3513,10 +3519,15 @@ function LoginScreen({
3513
3519
  error,
3514
3520
  onBack,
3515
3521
  merchantInitials,
3516
- onSocialLogin
3522
+ onSocialLogin,
3523
+ heroTitle,
3524
+ heroSubtitle,
3525
+ inputPlaceholder
3517
3526
  }) {
3518
3527
  const { tokens } = useBlinkConfig();
3519
3528
  const disabled = authInput.trim().length === 0 || sending;
3529
+ const heading = heroTitle ?? "Your Money. Any App.\nOne Tap.";
3530
+ const placeholder = inputPlaceholder ?? "Email or phone number";
3520
3531
  return /* @__PURE__ */ jsxRuntime.jsxs(
3521
3532
  ScreenLayout,
3522
3533
  {
@@ -3551,7 +3562,8 @@ function LoginScreen({
3551
3562
  ),
3552
3563
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle, children: [
3553
3564
  /* @__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." }),
3565
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle(tokens.text), children: heading }),
3566
+ heroSubtitle ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle(tokens.textMuted), children: heroSubtitle }) : null,
3555
3567
  error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorStyle(tokens), children: error }),
3556
3568
  /* @__PURE__ */ jsxRuntime.jsx(
3557
3569
  "input",
@@ -3560,7 +3572,7 @@ function LoginScreen({
3560
3572
  type: "text",
3561
3573
  inputMode: "text",
3562
3574
  autoComplete: "username",
3563
- placeholder: "Email or phone number",
3575
+ placeholder,
3564
3576
  value: authInput,
3565
3577
  onChange: (e) => onAuthInputChange(e.target.value),
3566
3578
  onKeyDown: (e) => {
@@ -3605,6 +3617,14 @@ var headingStyle = (color) => ({
3605
3617
  margin: "20px 0 8px",
3606
3618
  whiteSpace: "pre-line"
3607
3619
  });
3620
+ var subtitleStyle = (color) => ({
3621
+ fontSize: "0.9rem",
3622
+ fontWeight: 500,
3623
+ lineHeight: 1.45,
3624
+ color,
3625
+ margin: "0 0 16px",
3626
+ maxWidth: 320
3627
+ });
3608
3628
  var inputStyle2 = (tokens) => ({
3609
3629
  width: "100%",
3610
3630
  padding: "15px 16px",
@@ -3727,7 +3747,7 @@ function OtpVerifyScreen({
3727
3747
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack }),
3728
3748
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle2, children: [
3729
3749
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle2(tokens.text), children: "Confirm it is you" }),
3730
- /* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle(tokens.textSecondary), children: [
3750
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle2(tokens.textSecondary), children: [
3731
3751
  "We sent a 6-digit code to",
3732
3752
  "\n",
3733
3753
  /* @__PURE__ */ jsxRuntime.jsx("strong", { children: maskedIdentifier })
@@ -3763,7 +3783,7 @@ var headingStyle2 = (color) => ({
3763
3783
  color,
3764
3784
  margin: "20px 0 8px"
3765
3785
  });
3766
- var subtitleStyle = (color) => ({
3786
+ var subtitleStyle2 = (color) => ({
3767
3787
  fontSize: "0.88rem",
3768
3788
  color,
3769
3789
  margin: "0 0 28px",
@@ -3816,7 +3836,7 @@ function PasskeyScreen({
3816
3836
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack, onLogout }),
3817
3837
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle3, children: [
3818
3838
  /* @__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" }),
3839
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle3(tokens.textSecondary), children: "This enables secure one-tap deposits on this device" }),
3820
3840
  error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle2(tokens), children: error })
3821
3841
  ] })
3822
3842
  ]
@@ -3838,7 +3858,7 @@ var headingStyle3 = (color) => ({
3838
3858
  color,
3839
3859
  margin: "24px 0 8px"
3840
3860
  });
3841
- var subtitleStyle2 = (color) => ({
3861
+ var subtitleStyle3 = (color) => ({
3842
3862
  fontSize: "0.86rem",
3843
3863
  color,
3844
3864
  margin: "0 0 20px",
@@ -3856,6 +3876,72 @@ var errorBannerStyle2 = (tokens) => ({
3856
3876
  width: "100%",
3857
3877
  textAlign: "left"
3858
3878
  });
3879
+ function VerifyPasskeyScreen({
3880
+ onVerify,
3881
+ onBack,
3882
+ verifying,
3883
+ error
3884
+ }) {
3885
+ const { tokens } = useBlinkConfig();
3886
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3887
+ ScreenLayout,
3888
+ {
3889
+ footer: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3890
+ /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: onVerify, disabled: verifying, loading: verifying, children: "Verify passkey" }),
3891
+ /* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {})
3892
+ ] }),
3893
+ children: [
3894
+ /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack }),
3895
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle4, children: [
3896
+ /* @__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: [
3897
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "4", y: "4", width: "16", height: "16", rx: "3", stroke: tokens.accent, strokeWidth: "1.5", strokeDasharray: "3 2" }),
3898
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "9", cy: "10", r: "1", fill: tokens.accent }),
3899
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "15", cy: "10", r: "1", fill: tokens.accent }),
3900
+ /* @__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" })
3901
+ ] }) }),
3902
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle4(tokens.text), children: "Verify your passkey" }),
3903
+ /* @__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." }),
3904
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle3(tokens), children: error }),
3905
+ /* @__PURE__ */ jsxRuntime.jsx(InfoBanner, { children: "Your passkey is stored securely on your device. Blink never sees your biometric data." })
3906
+ ] })
3907
+ ]
3908
+ }
3909
+ );
3910
+ }
3911
+ var contentStyle4 = {
3912
+ textAlign: "center",
3913
+ flex: 1,
3914
+ display: "flex",
3915
+ flexDirection: "column",
3916
+ alignItems: "center",
3917
+ paddingTop: 32
3918
+ };
3919
+ var headingStyle4 = (color) => ({
3920
+ fontSize: "1.45rem",
3921
+ fontWeight: 700,
3922
+ letterSpacing: "-0.02em",
3923
+ color,
3924
+ margin: "24px 0 8px"
3925
+ });
3926
+ var subtitleStyle4 = (color) => ({
3927
+ fontSize: "0.9rem",
3928
+ color,
3929
+ margin: "0 0 28px",
3930
+ lineHeight: 1.5,
3931
+ maxWidth: 280
3932
+ });
3933
+ var errorBannerStyle3 = (tokens) => ({
3934
+ background: tokens.errorBg,
3935
+ border: `1px solid ${tokens.error}66`,
3936
+ borderRadius: 16,
3937
+ padding: "11px 14px",
3938
+ color: tokens.error,
3939
+ fontSize: "0.84rem",
3940
+ marginBottom: 14,
3941
+ lineHeight: 1.5,
3942
+ width: "100%",
3943
+ textAlign: "left"
3944
+ });
3859
3945
  function Spinner({ size = 40, label }) {
3860
3946
  const { tokens } = useBlinkConfig();
3861
3947
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -3999,8 +4085,8 @@ function WalletPickerScreen({
3999
4085
  children: [
4000
4086
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { title: "Set up Blink", onBack, onLogout }),
4001
4087
  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" }),
4088
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle5(tokens.text), children: "Continue where you left off" }),
4089
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle5(tokens.textSecondary), children: "You have a wallet that still needs setup" }),
4004
4090
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: pendingListStyle, children: pendingConnections.map((acct) => {
4005
4091
  const wallet = acct.wallets[0];
4006
4092
  const address = wallet ? truncateAddress(wallet.name) : void 0;
@@ -4039,7 +4125,7 @@ function WalletPickerScreen({
4039
4125
  }) }),
4040
4126
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: dividerStyle2(tokens.border), children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: dividerTextStyle(tokens.textMuted), children: "Or connect a new wallet" }) })
4041
4127
  ] }),
4042
- !hasPending && /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle4(tokens.text), children: "Where is your money?" }),
4128
+ !hasPending && /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle5(tokens.text), children: "Where is your money?" }),
4043
4129
  /* @__PURE__ */ jsxRuntime.jsxs(
4044
4130
  "button",
4045
4131
  {
@@ -4110,14 +4196,14 @@ function WalletPickerScreen({
4110
4196
  }
4111
4197
  );
4112
4198
  }
4113
- var headingStyle4 = (color) => ({
4199
+ var headingStyle5 = (color) => ({
4114
4200
  fontSize: "1.35rem",
4115
4201
  fontWeight: 700,
4116
4202
  letterSpacing: "-0.02em",
4117
4203
  color,
4118
4204
  margin: "8px 0 4px"
4119
4205
  });
4120
- var subtitleStyle3 = (color) => ({
4206
+ var subtitleStyle5 = (color) => ({
4121
4207
  fontSize: "0.88rem",
4122
4208
  color,
4123
4209
  margin: "0 0 24px"
@@ -4353,8 +4439,8 @@ function SetupScreen({
4353
4439
  ] }),
4354
4440
  children: [
4355
4441
  /* @__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 }),
4442
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle6(tokens.text), children: "Set Spending Limit" }),
4443
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle4(tokens), children: error }),
4358
4444
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: amountRowStyle, children: [
4359
4445
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1 }, children: editing ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: limitValueStyle(tokens.text), children: [
4360
4446
  "$",
@@ -4429,7 +4515,7 @@ function SetupScreen({
4429
4515
  }
4430
4516
  );
4431
4517
  }
4432
- var headingStyle5 = (color) => ({
4518
+ var headingStyle6 = (color) => ({
4433
4519
  fontSize: "1.1rem",
4434
4520
  fontWeight: 700,
4435
4521
  letterSpacing: "-0.02em",
@@ -4437,7 +4523,7 @@ var headingStyle5 = (color) => ({
4437
4523
  margin: "8px 0 24px",
4438
4524
  textAlign: "center"
4439
4525
  });
4440
- var errorBannerStyle3 = (tokens) => ({
4526
+ var errorBannerStyle4 = (tokens) => ({
4441
4527
  background: tokens.errorBg,
4442
4528
  border: `1px solid ${tokens.error}66`,
4443
4529
  borderRadius: 16,
@@ -4528,10 +4614,10 @@ function SetupStatusScreen({
4528
4614
  if (complete) {
4529
4615
  return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { footer: /* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {}), children: [
4530
4616
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack: onContinue }),
4531
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle4, children: [
4617
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle5, children: [
4532
4618
  /* @__PURE__ */ jsxRuntime.jsx("img", { src: BLINK_LOGO, alt: "Blink", style: mascotStyle2 }),
4533
- /* @__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." })
4619
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle7(tokens.text), children: "Done!" }),
4620
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle6(tokens.textSecondary), children: "Return to the app to try one-tap deposits." })
4535
4621
  ] })
4536
4622
  ] });
4537
4623
  }
@@ -4541,16 +4627,16 @@ function SetupStatusScreen({
4541
4627
  ];
4542
4628
  return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { children: [
4543
4629
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
4544
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle4, children: [
4630
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle5, children: [
4545
4631
  /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 48 }),
4546
- /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle6(tokens.text), children: "Setting up One-Tap..." }),
4547
- error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle4(tokens), children: error }),
4632
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle7(tokens.text), children: "Setting up One-Tap..." }),
4633
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle5(tokens), children: error }),
4548
4634
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: stepsWrapStyle, children: /* @__PURE__ */ jsxRuntime.jsx(StepList, { steps }) }),
4549
4635
  /* @__PURE__ */ jsxRuntime.jsx("p", { style: waitHintStyle(tokens.textMuted), children: "Usually takes a few seconds" })
4550
4636
  ] })
4551
4637
  ] });
4552
4638
  }
4553
- var contentStyle4 = {
4639
+ var contentStyle5 = {
4554
4640
  flex: 1,
4555
4641
  display: "flex",
4556
4642
  flexDirection: "column",
@@ -4563,21 +4649,21 @@ var mascotStyle2 = {
4563
4649
  width: 56,
4564
4650
  height: 56
4565
4651
  };
4566
- var headingStyle6 = (color) => ({
4652
+ var headingStyle7 = (color) => ({
4567
4653
  fontSize: "1.45rem",
4568
4654
  fontWeight: 700,
4569
4655
  letterSpacing: "-0.02em",
4570
4656
  color,
4571
4657
  margin: "20px 0 8px"
4572
4658
  });
4573
- var subtitleStyle4 = (color) => ({
4659
+ var subtitleStyle6 = (color) => ({
4574
4660
  fontSize: "0.9rem",
4575
4661
  color,
4576
4662
  margin: "0 0 28px",
4577
4663
  lineHeight: 1.5,
4578
4664
  maxWidth: 260
4579
4665
  });
4580
- var errorBannerStyle4 = (tokens) => ({
4666
+ var errorBannerStyle5 = (tokens) => ({
4581
4667
  background: tokens.errorBg,
4582
4668
  border: `1px solid ${tokens.error}66`,
4583
4669
  borderRadius: 16,
@@ -4782,7 +4868,7 @@ function DepositScreen({
4782
4868
  minDepositFloor.toFixed(2),
4783
4869
  " to deposit via One-Tap."
4784
4870
  ] }),
4785
- error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle5(tokens), children: error })
4871
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle6(tokens), children: error })
4786
4872
  ]
4787
4873
  }
4788
4874
  );
@@ -4968,7 +5054,7 @@ var spendingLimitStyle = (color) => ({
4968
5054
  color,
4969
5055
  marginBottom: 8
4970
5056
  });
4971
- var errorBannerStyle5 = (tokens) => ({
5057
+ var errorBannerStyle6 = (tokens) => ({
4972
5058
  background: tokens.errorBg,
4973
5059
  border: `1px solid ${tokens.error}66`,
4974
5060
  borderRadius: 16,
@@ -5013,22 +5099,22 @@ function SuccessScreen({
5013
5099
  ] }),
5014
5100
  children: [
5015
5101
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
5016
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle5, children: [
5102
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle6, children: [
5017
5103
  succeeded ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5018
5104
  /* @__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
- /* @__PURE__ */ jsxRuntime.jsxs("h2", { style: headingStyle7(tokens.text), children: [
5105
+ /* @__PURE__ */ jsxRuntime.jsxs("h2", { style: headingStyle8(tokens.text), children: [
5020
5106
  "$",
5021
5107
  amount.toFixed(2),
5022
5108
  " deposited"
5023
5109
  ] }),
5024
- merchantName && /* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle5(tokens.textSecondary), children: [
5110
+ merchantName && /* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle7(tokens.textSecondary), children: [
5025
5111
  "to ",
5026
5112
  merchantName
5027
5113
  ] })
5028
5114
  ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5029
5115
  /* @__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
- /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle7(tokens.text), children: "Transfer failed" }),
5031
- error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle5(tokens.error), children: error })
5116
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle8(tokens.text), children: "Transfer failed" }),
5117
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle7(tokens.error), children: error })
5032
5118
  ] }),
5033
5119
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryCardStyle(tokens), children: [
5034
5120
  sourceName && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryRowStyle, children: [
@@ -5060,21 +5146,21 @@ function SuccessScreen({
5060
5146
  }
5061
5147
  );
5062
5148
  }
5063
- var contentStyle5 = {
5149
+ var contentStyle6 = {
5064
5150
  flex: 1,
5065
5151
  display: "flex",
5066
5152
  flexDirection: "column",
5067
5153
  alignItems: "center",
5068
5154
  paddingTop: 16
5069
5155
  };
5070
- var headingStyle7 = (color) => ({
5156
+ var headingStyle8 = (color) => ({
5071
5157
  fontSize: "1.5rem",
5072
5158
  fontWeight: 700,
5073
5159
  letterSpacing: "-0.02em",
5074
5160
  color,
5075
5161
  margin: "20px 0 4px"
5076
5162
  });
5077
- var subtitleStyle5 = (color) => ({
5163
+ var subtitleStyle7 = (color) => ({
5078
5164
  fontSize: "0.9rem",
5079
5165
  color,
5080
5166
  margin: "0 0 20px"
@@ -5188,7 +5274,7 @@ function SelectSourceScreen({
5188
5274
  onLogout
5189
5275
  }
5190
5276
  ),
5191
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle6(tokens.textMuted), children: "Choose which chain and token to pay from." }),
5277
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle8(tokens.textMuted), children: "Choose which chain and token to pay from." }),
5192
5278
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle4(tokens.textSecondary), children: "Chain" }),
5193
5279
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: optionListStyle, children: choices.map((chain) => {
5194
5280
  const isSelected = chain.chainName === selectedChainName;
@@ -5249,7 +5335,7 @@ function SelectSourceScreen({
5249
5335
  }
5250
5336
  );
5251
5337
  }
5252
- var subtitleStyle6 = (color) => ({
5338
+ var subtitleStyle8 = (color) => ({
5253
5339
  fontSize: "0.85rem",
5254
5340
  color,
5255
5341
  margin: "0 0 20px",
@@ -5391,8 +5477,8 @@ function AdvancedSourceScreen({
5391
5477
  right: /* @__PURE__ */ jsxRuntime.jsx("span", { style: advancedBadgeStyle(tokens.accent), children: "Advanced" })
5392
5478
  }
5393
5479
  ),
5394
- /* @__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." }),
5480
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle9(tokens.text), children: "Set up One-Tap deposits" }),
5481
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle9(tokens.textSecondary), children: "Select a token source for your One-Tap deposits." }),
5396
5482
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle5(tokens.textSecondary), children: "Select tokens to approve" }),
5397
5483
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: chainListStyle, children: choices.map((chain) => {
5398
5484
  const isExpanded = expandedChain === chain.chainName;
@@ -5455,14 +5541,14 @@ var advancedBadgeStyle = (color) => ({
5455
5541
  padding: "3px 10px",
5456
5542
  letterSpacing: "0.02em"
5457
5543
  });
5458
- var headingStyle8 = (color) => ({
5544
+ var headingStyle9 = (color) => ({
5459
5545
  fontSize: "1.3rem",
5460
5546
  fontWeight: 700,
5461
5547
  letterSpacing: "-0.02em",
5462
5548
  color,
5463
5549
  margin: "8px 0 4px"
5464
5550
  });
5465
- var subtitleStyle7 = (color) => ({
5551
+ var subtitleStyle9 = (color) => ({
5466
5552
  fontSize: "0.86rem",
5467
5553
  color,
5468
5554
  margin: "0 0 20px",
@@ -5590,15 +5676,15 @@ function TransferStatusScreen({
5590
5676
  const steps = buildSteps(phase);
5591
5677
  return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { footer: /* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {}), children: [
5592
5678
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
5593
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle6, children: [
5679
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle7, children: [
5594
5680
  /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 64 }),
5595
- /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle9(tokens.text), children: "Depositing your money..." }),
5596
- error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle6(tokens), children: error }),
5681
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle10(tokens.text), children: "Depositing your money..." }),
5682
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle7(tokens), children: error }),
5597
5683
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: stepsWrapStyle2, children: /* @__PURE__ */ jsxRuntime.jsx(StepList, { steps }) })
5598
5684
  ] })
5599
5685
  ] });
5600
5686
  }
5601
- var contentStyle6 = {
5687
+ var contentStyle7 = {
5602
5688
  flex: 1,
5603
5689
  display: "flex",
5604
5690
  flexDirection: "column",
@@ -5607,14 +5693,14 @@ var contentStyle6 = {
5607
5693
  textAlign: "center",
5608
5694
  padding: "0 24px"
5609
5695
  };
5610
- var headingStyle9 = (color) => ({
5696
+ var headingStyle10 = (color) => ({
5611
5697
  fontSize: "1.45rem",
5612
5698
  fontWeight: 700,
5613
5699
  letterSpacing: "-0.02em",
5614
5700
  color,
5615
5701
  margin: "20px 0 16px"
5616
5702
  });
5617
- var errorBannerStyle6 = (tokens) => ({
5703
+ var errorBannerStyle7 = (tokens) => ({
5618
5704
  background: tokens.errorBg,
5619
5705
  border: `1px solid ${tokens.error}66`,
5620
5706
  borderRadius: 16,
@@ -5668,14 +5754,14 @@ function OpenWalletScreen({
5668
5754
  ] }),
5669
5755
  children: [
5670
5756
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
5671
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle7, children: [
5757
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle8, children: [
5672
5758
  /* @__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
- /* @__PURE__ */ jsxRuntime.jsxs("h2", { style: headingStyle10(tokens.text), children: [
5759
+ /* @__PURE__ */ jsxRuntime.jsxs("h2", { style: headingStyle11(tokens.text), children: [
5674
5760
  "Setting up ",
5675
5761
  displayName,
5676
5762
  "..."
5677
5763
  ] }),
5678
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle8(tokens.textSecondary), children: "Approve the connection in your wallet extension." }),
5764
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle10(tokens.textSecondary), children: "Approve the connection in your wallet extension." }),
5679
5765
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: waitingBadgeStyle(tokens), children: [
5680
5766
  /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 14 }),
5681
5767
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Waiting for authorization..." })
@@ -5701,10 +5787,10 @@ function OpenWalletScreen({
5701
5787
  ] }),
5702
5788
  children: [
5703
5789
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack, onLogout }),
5704
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle7, children: [
5790
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle8, children: [
5705
5791
  /* @__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
- /* @__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.` }),
5792
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle11(tokens.text), children: loading ? "Connecting..." : `Open ${displayName}` }),
5793
+ /* @__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
5794
  !loading && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: waitingBadgeStyle(tokens), children: [
5709
5795
  /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 14 }),
5710
5796
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Waiting for authorization..." })
@@ -5714,7 +5800,7 @@ function OpenWalletScreen({
5714
5800
  }
5715
5801
  );
5716
5802
  }
5717
- var contentStyle7 = {
5803
+ var contentStyle8 = {
5718
5804
  flex: 1,
5719
5805
  display: "flex",
5720
5806
  flexDirection: "column",
@@ -5744,14 +5830,14 @@ var logoStyle2 = {
5744
5830
  borderRadius: 12,
5745
5831
  objectFit: "contain"
5746
5832
  };
5747
- var headingStyle10 = (color) => ({
5833
+ var headingStyle11 = (color) => ({
5748
5834
  fontSize: "1.45rem",
5749
5835
  fontWeight: 700,
5750
5836
  letterSpacing: "-0.02em",
5751
5837
  color,
5752
5838
  margin: "20px 0 8px"
5753
5839
  });
5754
- var subtitleStyle8 = (color) => ({
5840
+ var subtitleStyle10 = (color) => ({
5755
5841
  fontSize: "0.9rem",
5756
5842
  color,
5757
5843
  margin: "0 0 24px",
@@ -5800,10 +5886,10 @@ function ConfirmSignScreen({
5800
5886
  ] }),
5801
5887
  children: [
5802
5888
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
5803
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle8, children: [
5889
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle9, children: [
5804
5890
  logoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoSrc, alt: displayName, style: logoStyle3 }) : /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 48 }),
5805
- /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle11(tokens.text), children: "Wallet authorized" }),
5806
- /* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle9(tokens.textSecondary), children: [
5891
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle12(tokens.text), children: "Wallet authorized" }),
5892
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle11(tokens.textSecondary), children: [
5807
5893
  displayName,
5808
5894
  " approved the connection. Tap below to confirm your payment."
5809
5895
  ] }),
@@ -5816,7 +5902,7 @@ function ConfirmSignScreen({
5816
5902
  }
5817
5903
  );
5818
5904
  }
5819
- var contentStyle8 = {
5905
+ var contentStyle9 = {
5820
5906
  flex: 1,
5821
5907
  display: "flex",
5822
5908
  flexDirection: "column",
@@ -5831,14 +5917,14 @@ var logoStyle3 = {
5831
5917
  borderRadius: 14,
5832
5918
  objectFit: "contain"
5833
5919
  };
5834
- var headingStyle11 = (color) => ({
5920
+ var headingStyle12 = (color) => ({
5835
5921
  fontSize: "1.45rem",
5836
5922
  fontWeight: 700,
5837
5923
  letterSpacing: "-0.02em",
5838
5924
  color,
5839
5925
  margin: "20px 0 8px"
5840
5926
  });
5841
- var subtitleStyle9 = (color) => ({
5927
+ var subtitleStyle11 = (color) => ({
5842
5928
  fontSize: "0.9rem",
5843
5929
  color,
5844
5930
  margin: "0 0 24px",
@@ -6108,60 +6194,232 @@ var selectCircleSelectedStyle = (color) => ({
6108
6194
  justifyContent: "center",
6109
6195
  flexShrink: 0
6110
6196
  });
6197
+ function entryKey(entry) {
6198
+ return `${entry.sourceChainId}-${entry.tokenAddress.toLowerCase()}`;
6199
+ }
6200
+ function formatPreciseMoneyForDisplay(fee) {
6201
+ const raw = fee.value.trim();
6202
+ if (fee.currency === "USD") {
6203
+ if (!/^\d+(\.\d*)?$/.test(raw)) {
6204
+ return `$${raw}`;
6205
+ }
6206
+ const [whole, frac = ""] = raw.split(".");
6207
+ const dec = `${frac}00`.slice(0, 2);
6208
+ const intFmt = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
6209
+ return `$${intFmt}.${dec}`;
6210
+ }
6211
+ return `${raw} ${fee.currency}`;
6212
+ }
6111
6213
  function GuestTokenPickerScreen({
6112
6214
  entries,
6113
6215
  loading,
6114
6216
  setting,
6115
6217
  depositAmount,
6116
6218
  error,
6219
+ pendingEntry,
6220
+ quoteFee,
6221
+ quoteLoading,
6117
6222
  onSelect,
6118
- onBack
6223
+ onConfirm,
6224
+ onBack,
6225
+ defaultTokenListExpanded = false
6119
6226
  }) {
6120
6227
  const { tokens: t } = useBlinkConfig();
6228
+ const pendingKey = pendingEntry ? entryKey(pendingEntry) : null;
6229
+ const [tokenListOpen, setTokenListOpen] = react.useState(defaultTokenListExpanded);
6230
+ const pickerRef = react.useRef(null);
6231
+ react.useEffect(() => {
6232
+ if (!tokenListOpen) return;
6233
+ const handleMouseDown = (e) => {
6234
+ if (pickerRef.current && !pickerRef.current.contains(e.target)) {
6235
+ setTokenListOpen(false);
6236
+ }
6237
+ };
6238
+ document.addEventListener("mousedown", handleMouseDown);
6239
+ return () => document.removeEventListener("mousedown", handleMouseDown);
6240
+ }, [tokenListOpen]);
6121
6241
  if (loading) {
6122
6242
  return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { children: [
6123
- /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { title: "Select Token", onBack }),
6243
+ /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack }),
6124
6244
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: loadingWrapStyle, children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { label: "Loading balances..." }) })
6125
6245
  ] });
6126
6246
  }
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 })
6247
+ const rowBusy = setting || quoteLoading;
6248
+ const displayEntry = pendingEntry ?? entries[0] ?? null;
6249
+ const canConfirm = Boolean(quoteFee && pendingEntry && !quoteLoading);
6250
+ const feeLine = (() => {
6251
+ if (quoteLoading && pendingEntry) {
6252
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: feeRowStyle(t.textMuted), "aria-live": "polite", children: "Estimating fee\u2026" });
6253
+ }
6254
+ if (quoteFee) {
6255
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: feeRowStyle(t.textMuted), "aria-live": "polite", children: [
6256
+ "Estimated fee ",
6257
+ formatPreciseMoneyForDisplay(quoteFee)
6258
+ ] });
6259
+ }
6260
+ return null;
6261
+ })();
6262
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6263
+ ScreenLayout,
6264
+ {
6265
+ footer: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6266
+ canConfirm && /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: () => void onConfirm(), loading: setting, disabled: setting, children: "Continue" }),
6267
+ /* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {})
6268
+ ] }),
6269
+ children: [
6270
+ /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack }),
6271
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: pickerRef, children: [
6272
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: depositCardSurfaceStyle(t, tokenListOpen), children: [
6273
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: depositLabelStyle3(t.textMuted), children: "Deposit" }),
6274
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: amountBandStyle, children: [
6275
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: amountLeftColStyle, children: [
6276
+ depositAmount != null && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: depositAmountStyle2(t.text), children: [
6277
+ "$",
6278
+ depositAmount.toLocaleString("en-US", {
6279
+ minimumFractionDigits: 0,
6280
+ maximumFractionDigits: 2
6281
+ })
6282
+ ] }),
6283
+ feeLine
6284
+ ] }),
6285
+ /* @__PURE__ */ jsxRuntime.jsxs(
6286
+ "button",
6287
+ {
6288
+ type: "button",
6289
+ onClick: () => entries.length > 0 && setTokenListOpen((o) => !o),
6290
+ disabled: entries.length === 0 || rowBusy,
6291
+ style: tokenTriggerStyle(t, entries.length > 0 && !rowBusy),
6292
+ "aria-expanded": tokenListOpen,
6293
+ "aria-haspopup": "listbox",
6294
+ children: [
6295
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenTriggerIconsStyle, children: pendingEntry && TOKEN_LOGOS[pendingEntry.tokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsx(
6296
+ "img",
6297
+ {
6298
+ src: TOKEN_LOGOS[pendingEntry.tokenSymbol],
6299
+ alt: "",
6300
+ width: 28,
6301
+ height: 28,
6302
+ style: triggerLogoStyle(0)
6303
+ }
6304
+ ) : entries[0] && entries[1] && TOKEN_LOGOS[entries[0].tokenSymbol] && TOKEN_LOGOS[entries[1].tokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6305
+ /* @__PURE__ */ jsxRuntime.jsx(
6306
+ "img",
6307
+ {
6308
+ src: TOKEN_LOGOS[entries[0].tokenSymbol],
6309
+ alt: "",
6310
+ width: 28,
6311
+ height: 28,
6312
+ style: triggerLogoStyle(0)
6313
+ }
6314
+ ),
6315
+ /* @__PURE__ */ jsxRuntime.jsx(
6316
+ "img",
6317
+ {
6318
+ src: TOKEN_LOGOS[entries[1].tokenSymbol],
6319
+ alt: "",
6320
+ width: 28,
6321
+ height: 28,
6322
+ style: triggerLogoStyle(14)
6323
+ }
6324
+ )
6325
+ ] }) : displayEntry && TOKEN_LOGOS[displayEntry.tokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsx(
6326
+ "img",
6327
+ {
6328
+ src: TOKEN_LOGOS[displayEntry.tokenSymbol],
6329
+ alt: "",
6330
+ width: 28,
6331
+ height: 28,
6332
+ style: triggerLogoStyle(0)
6333
+ }
6334
+ ) : null }),
6335
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", style: { opacity: 0.5 }, children: tokenListOpen ? /* @__PURE__ */ jsxRuntime.jsx(
6336
+ "path",
6337
+ {
6338
+ d: "M18 15l-6-6-6 6",
6339
+ stroke: t.textMuted,
6340
+ strokeWidth: "2.5",
6341
+ strokeLinecap: "round",
6342
+ strokeLinejoin: "round"
6343
+ }
6344
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
6345
+ "path",
6346
+ {
6347
+ d: "M6 9l6 6 6-6",
6348
+ stroke: t.textMuted,
6349
+ strokeWidth: "2.5",
6350
+ strokeLinecap: "round",
6351
+ strokeLinejoin: "round"
6352
+ }
6353
+ ) })
6354
+ ]
6355
+ }
6356
+ )
6156
6357
  ] })
6157
6358
  ] }),
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
- ] });
6359
+ tokenListOpen && entries.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenDropdownOuterStyle(t), children: [
6360
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: accountDropdownLabelStyle2(t.textMuted), children: "Choose token" }),
6361
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenDropdownInnerStyle(t), children: entries.map((entry, index) => {
6362
+ const selected = pendingKey === entryKey(entry);
6363
+ const isLast = index === entries.length - 1;
6364
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6365
+ "button",
6366
+ {
6367
+ type: "button",
6368
+ onClick: () => {
6369
+ void onSelect(entry);
6370
+ },
6371
+ disabled: rowBusy,
6372
+ style: pickerRowStyle(t, selected, isLast),
6373
+ children: [
6374
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: pickerRowLeftStyle, children: [
6375
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenIconCircleStyle3(t, !!TOKEN_LOGOS[entry.tokenSymbol]), children: TOKEN_LOGOS[entry.tokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsx(
6376
+ "img",
6377
+ {
6378
+ src: TOKEN_LOGOS[entry.tokenSymbol],
6379
+ alt: entry.tokenSymbol,
6380
+ style: tokenLogoImgStyle3
6381
+ }
6382
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenIconTextStyle3(t.textMuted), children: "$" }) }),
6383
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: pickerRowInfoStyle, children: [
6384
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenNameRowStyle2, children: [
6385
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenSymbolTextStyle2(t.text), children: entry.tokenSymbol }),
6386
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenChainDotStyle2(t.textMuted), children: "\xB7" }),
6387
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenChainTextStyle2(t.textMuted), children: entry.chainName })
6388
+ ] }),
6389
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: tokenBalanceStyle2(t.textMuted), children: [
6390
+ "$",
6391
+ entry.balance.toLocaleString("en-US", {
6392
+ minimumFractionDigits: 2,
6393
+ maximumFractionDigits: 2
6394
+ })
6395
+ ] })
6396
+ ] })
6397
+ ] }),
6398
+ selected ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "22", height: "22", viewBox: "0 0 22 22", fill: "none", children: [
6399
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "11", fill: t.success }),
6400
+ /* @__PURE__ */ jsxRuntime.jsx(
6401
+ "path",
6402
+ {
6403
+ d: "M7 11l3 3 5-5",
6404
+ stroke: "#fff",
6405
+ strokeWidth: "2",
6406
+ strokeLinecap: "round",
6407
+ strokeLinejoin: "round"
6408
+ }
6409
+ )
6410
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: radioEmptyStyle2(t.border) })
6411
+ ]
6412
+ },
6413
+ entryKey(entry)
6414
+ );
6415
+ }) })
6416
+ ] })
6417
+ ] }),
6418
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: errorStyle3(t.error), children: error }),
6419
+ 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." })
6420
+ ]
6421
+ }
6422
+ );
6165
6423
  }
6166
6424
  var loadingWrapStyle = {
6167
6425
  textAlign: "center",
@@ -6171,52 +6429,129 @@ var loadingWrapStyle = {
6171
6429
  alignItems: "center",
6172
6430
  justifyContent: "center"
6173
6431
  };
6174
- var depositHeaderStyle = {
6175
- marginBottom: 20
6176
- };
6432
+ var depositCardSurfaceStyle = (tokens, listOpen) => ({
6433
+ background: tokens.bgCard,
6434
+ border: `1px solid ${tokens.border}`,
6435
+ borderRadius: tokens.radiusLg,
6436
+ padding: "16px 20px",
6437
+ marginBottom: listOpen ? 4 : 16
6438
+ });
6177
6439
  var depositLabelStyle3 = (color) => ({
6178
6440
  fontSize: "0.75rem",
6179
6441
  fontWeight: 500,
6180
6442
  color,
6181
6443
  marginBottom: 4
6182
6444
  });
6445
+ var amountBandStyle = {
6446
+ display: "flex",
6447
+ alignItems: "flex-start",
6448
+ justifyContent: "space-between",
6449
+ gap: 12
6450
+ };
6451
+ var amountLeftColStyle = {
6452
+ flex: 1,
6453
+ minWidth: 0
6454
+ };
6183
6455
  var depositAmountStyle2 = (color) => ({
6184
6456
  fontSize: "2.4rem",
6185
6457
  fontWeight: 700,
6186
6458
  letterSpacing: "-0.02em",
6187
- color
6188
- });
6189
- var errorStyle3 = (color) => ({
6190
- fontSize: "0.84rem",
6191
6459
  color,
6192
- margin: "0 0 12px",
6193
- lineHeight: 1.5
6460
+ lineHeight: 1.05
6194
6461
  });
6195
- var sectionLabelStyle2 = (color) => ({
6462
+ var feeRowStyle = (color) => ({
6196
6463
  fontSize: "0.84rem",
6197
6464
  fontWeight: 500,
6198
6465
  color,
6199
- marginBottom: 12
6466
+ marginTop: 6
6200
6467
  });
6201
- var tokenListStyle3 = {
6468
+ var tokenTriggerStyle = (tokens, interactive) => ({
6202
6469
  display: "flex",
6203
- flexDirection: "column",
6204
- gap: 10
6470
+ alignItems: "center",
6471
+ gap: 6,
6472
+ flexShrink: 0,
6473
+ marginTop: 4,
6474
+ padding: "6px 10px",
6475
+ background: tokens.bgInput,
6476
+ border: `1px solid ${tokens.border}`,
6477
+ borderRadius: 999,
6478
+ cursor: interactive ? "pointer" : "default",
6479
+ fontFamily: "inherit"
6480
+ });
6481
+ var tokenTriggerIconsStyle = {
6482
+ position: "relative",
6483
+ width: 40,
6484
+ height: 28
6205
6485
  };
6206
- var tokenRowStyle3 = (tokens, disabled) => ({
6486
+ var triggerLogoStyle = (left) => ({
6487
+ position: "absolute",
6488
+ left,
6489
+ top: 0,
6490
+ borderRadius: "50%",
6491
+ objectFit: "cover",
6492
+ border: "2px solid rgba(255,255,255,0.9)",
6493
+ boxSizing: "content-box"
6494
+ });
6495
+ var tokenDropdownOuterStyle = (tokens) => ({
6496
+ marginTop: 4,
6497
+ marginBottom: 16,
6498
+ background: tokens.bgCard,
6499
+ border: `1px solid ${tokens.border}`,
6500
+ borderRadius: tokens.radiusLg,
6501
+ boxShadow: tokens.shadowLg,
6502
+ padding: "12px 14px 14px"
6503
+ });
6504
+ var accountDropdownLabelStyle2 = (color) => ({
6505
+ fontSize: "0.78rem",
6506
+ fontWeight: 500,
6507
+ color,
6508
+ marginBottom: 8
6509
+ });
6510
+ var tokenDropdownInnerStyle = (tokens) => ({
6511
+ background: tokens.bgInput,
6512
+ border: `1px solid ${tokens.border}`,
6513
+ borderRadius: tokens.radiusLg,
6514
+ overflow: "hidden"
6515
+ });
6516
+ var pickerRowStyle = (tokens, isSelected, isLast) => ({
6207
6517
  display: "flex",
6208
6518
  alignItems: "center",
6209
- gap: 14,
6519
+ justifyContent: "space-between",
6520
+ width: "100%",
6210
6521
  padding: "14px 16px",
6211
- background: tokens.bgInput,
6212
- border: `1px solid ${tokens.border}`,
6213
- borderRadius: 16,
6214
- cursor: disabled ? "default" : "pointer",
6522
+ background: isSelected ? `${tokens.accent}18` : "transparent",
6523
+ border: "none",
6524
+ borderBottom: isLast ? "none" : `1px solid ${tokens.border}`,
6525
+ cursor: "pointer",
6215
6526
  fontFamily: "inherit",
6216
6527
  textAlign: "left",
6217
- width: "100%",
6218
- opacity: disabled ? 0.6 : 1,
6219
- transition: "opacity 0.15s ease"
6528
+ outline: "none"
6529
+ });
6530
+ var pickerRowLeftStyle = {
6531
+ display: "flex",
6532
+ alignItems: "center",
6533
+ gap: 12,
6534
+ minWidth: 0,
6535
+ flex: 1
6536
+ };
6537
+ var pickerRowInfoStyle = {
6538
+ display: "flex",
6539
+ flexDirection: "column",
6540
+ gap: 2,
6541
+ minWidth: 0
6542
+ };
6543
+ var radioEmptyStyle2 = (borderColor) => ({
6544
+ width: 22,
6545
+ height: 22,
6546
+ borderRadius: "50%",
6547
+ border: `2px solid ${borderColor}`,
6548
+ flexShrink: 0
6549
+ });
6550
+ var errorStyle3 = (color) => ({
6551
+ fontSize: "0.84rem",
6552
+ color,
6553
+ margin: "0 0 12px",
6554
+ lineHeight: 1.5
6220
6555
  });
6221
6556
  var tokenIconCircleStyle3 = (tokens, hasLogo) => ({
6222
6557
  width: 36,
@@ -6240,13 +6575,6 @@ var tokenIconTextStyle3 = (color) => ({
6240
6575
  fontWeight: 700,
6241
6576
  color
6242
6577
  });
6243
- var tokenInfoStyle3 = {
6244
- display: "flex",
6245
- flexDirection: "column",
6246
- gap: 2,
6247
- flex: 1,
6248
- minWidth: 0
6249
- };
6250
6578
  var tokenNameRowStyle2 = {
6251
6579
  display: "flex",
6252
6580
  alignItems: "center",
@@ -6270,10 +6598,6 @@ var tokenBalanceStyle2 = (color) => ({
6270
6598
  fontSize: "0.78rem",
6271
6599
  color
6272
6600
  });
6273
- var chevronStyle = {
6274
- flexShrink: 0,
6275
- opacity: 0.4
6276
- };
6277
6601
  var emptyStyle = (color) => ({
6278
6602
  fontSize: "0.88rem",
6279
6603
  color,
@@ -6295,7 +6619,7 @@ function GuestPreauthSetupCompleteScreen({
6295
6619
  ] }),
6296
6620
  children: [
6297
6621
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
6298
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle9, children: [
6622
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle10, children: [
6299
6623
  /* @__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
6624
  "path",
6301
6625
  {
@@ -6303,14 +6627,14 @@ function GuestPreauthSetupCompleteScreen({
6303
6627
  fill: tokens.success
6304
6628
  }
6305
6629
  ) }) }),
6306
- /* @__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." })
6630
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle13(tokens.text), children: "Setup complete" }),
6631
+ /* @__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
6632
  ] })
6309
6633
  ]
6310
6634
  }
6311
6635
  );
6312
6636
  }
6313
- var contentStyle9 = {
6637
+ var contentStyle10 = {
6314
6638
  display: "flex",
6315
6639
  flexDirection: "column",
6316
6640
  alignItems: "center",
@@ -6318,7 +6642,7 @@ var contentStyle9 = {
6318
6642
  gap: 12,
6319
6643
  paddingTop: 8
6320
6644
  };
6321
- function headingStyle12(color) {
6645
+ function headingStyle13(color) {
6322
6646
  return {
6323
6647
  margin: 0,
6324
6648
  fontSize: 22,
@@ -6326,7 +6650,7 @@ function headingStyle12(color) {
6326
6650
  color
6327
6651
  };
6328
6652
  }
6329
- function subtitleStyle10(color) {
6653
+ function subtitleStyle12(color) {
6330
6654
  return {
6331
6655
  margin: 0,
6332
6656
  fontSize: 15,
@@ -6339,14 +6663,14 @@ function GuestPreauthLinkingScreen({ onLogout }) {
6339
6663
  const { tokens } = useBlinkConfig();
6340
6664
  return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { children: [
6341
6665
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onLogout }),
6342
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle10, children: [
6666
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle11, children: [
6343
6667
  /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 48 }),
6344
- /* @__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." })
6668
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle14(tokens.text), children: "Setting up your account..." }),
6669
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle13(tokens.textSecondary), children: "Linking your wallet to your Blink account. This usually takes a few seconds." })
6346
6670
  ] })
6347
6671
  ] });
6348
6672
  }
6349
- var contentStyle10 = {
6673
+ var contentStyle11 = {
6350
6674
  flex: 1,
6351
6675
  display: "flex",
6352
6676
  flexDirection: "column",
@@ -6355,7 +6679,7 @@ var contentStyle10 = {
6355
6679
  textAlign: "center",
6356
6680
  padding: "0 24px 32px"
6357
6681
  };
6358
- function headingStyle13(color) {
6682
+ function headingStyle14(color) {
6359
6683
  return {
6360
6684
  margin: "20px 0 8px",
6361
6685
  fontSize: "1.45rem",
@@ -6364,7 +6688,7 @@ function headingStyle13(color) {
6364
6688
  color
6365
6689
  };
6366
6690
  }
6367
- function subtitleStyle11(color) {
6691
+ function subtitleStyle13(color) {
6368
6692
  return {
6369
6693
  margin: 0,
6370
6694
  fontSize: "0.9rem",
@@ -6456,6 +6780,9 @@ function StepRendererContent({
6456
6780
  guestTokenEntries,
6457
6781
  guestLoadingBalances,
6458
6782
  guestSettingSender,
6783
+ guestPendingEntry,
6784
+ guestQuoteFee,
6785
+ guestQuoteLoading,
6459
6786
  authInput,
6460
6787
  otpCode,
6461
6788
  selectSourceChainName,
@@ -6693,7 +7020,11 @@ function StepRendererContent({
6693
7020
  setting: guestSettingSender,
6694
7021
  depositAmount: depositAmount ?? void 0,
6695
7022
  error: state.error,
7023
+ pendingEntry: forms.guestPendingEntry,
7024
+ quoteFee: forms.guestQuoteFee,
7025
+ quoteLoading: forms.guestQuoteLoading,
6696
7026
  onSelect: handlers.onSelectGuestToken,
7027
+ onConfirm: handlers.onConfirmGuestToken,
6697
7028
  onBack: handlers.onGuestBackFromTokenPicker
6698
7029
  }
6699
7030
  );
@@ -6798,7 +7129,7 @@ var PaymentErrorBoundary = class extends react.Component {
6798
7129
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 8v5", stroke: "#ef4444", strokeWidth: "1.5", strokeLinecap: "round" }),
6799
7130
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "16", r: "0.75", fill: "#ef4444" })
6800
7131
  ] }) }),
6801
- /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle14, children: "Something went wrong" }),
7132
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle15, children: "Something went wrong" }),
6802
7133
  /* @__PURE__ */ jsxRuntime.jsx("p", { style: messageStyle, children: "An unexpected error occurred. Please try again." }),
6803
7134
  /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: this.handleReset, style: buttonStyle3, children: "Try again" })
6804
7135
  ] });
@@ -6818,7 +7149,7 @@ var containerStyle9 = {
6818
7149
  var iconStyle3 = {
6819
7150
  marginBottom: 20
6820
7151
  };
6821
- var headingStyle14 = {
7152
+ var headingStyle15 = {
6822
7153
  fontSize: "1.25rem",
6823
7154
  fontWeight: 700,
6824
7155
  color: "#1a1a1a",
@@ -7997,8 +8328,8 @@ function useProviderHandlers(deps) {
7997
8328
  }
7998
8329
 
7999
8330
  // src/guestTokens.ts
8000
- function mapBalancesToGuestTokenEntries(options) {
8001
- return options.map((opt) => ({
8331
+ function mapGuestPickerEntries(options) {
8332
+ const mapped = options.map((opt) => ({
8002
8333
  chainId: opt.chainId,
8003
8334
  sourceChainId: opt.sourceChainId,
8004
8335
  chainName: opt.chainName,
@@ -8007,7 +8338,26 @@ function mapBalancesToGuestTokenEntries(options) {
8007
8338
  decimals: opt.decimals,
8008
8339
  rawBalance: opt.rawBalance,
8009
8340
  balance: Number(opt.rawBalance) / 10 ** opt.decimals
8010
- })).filter((entry) => entry.balance > 0).sort((a, b) => b.balance - a.balance);
8341
+ }));
8342
+ const positive = mapped.filter((e) => e.balance > 0).sort((a, b) => b.balance - a.balance);
8343
+ if (positive.length > 0) return positive;
8344
+ return mapped.sort((a, b) => b.balance - a.balance);
8345
+ }
8346
+ function guestEntryMatchingRecommended(balances, recommended) {
8347
+ const raw = balances.find(
8348
+ (b) => b.sourceChainId === recommended.sourceChainId && b.tokenAddress.toLowerCase() === recommended.tokenAddress.toLowerCase()
8349
+ );
8350
+ if (!raw) return null;
8351
+ return {
8352
+ chainId: raw.chainId,
8353
+ sourceChainId: raw.sourceChainId,
8354
+ chainName: raw.chainName,
8355
+ tokenSymbol: raw.tokenSymbol,
8356
+ tokenAddress: raw.tokenAddress,
8357
+ decimals: raw.decimals,
8358
+ rawBalance: raw.rawBalance,
8359
+ balance: Number(raw.rawBalance) / 10 ** raw.decimals
8360
+ };
8011
8361
  }
8012
8362
 
8013
8363
  // src/hooks/useGuestTransferHandlers.ts
@@ -8034,6 +8384,9 @@ function useGuestTransferHandlers(deps) {
8034
8384
  const [guestTokenEntries, setGuestTokenEntries] = react.useState([]);
8035
8385
  const [loadingBalances, setLoadingBalances] = react.useState(false);
8036
8386
  const [settingSender, setSettingSender] = react.useState(false);
8387
+ const [pendingGuestEntry, setPendingGuestEntry] = react.useState(null);
8388
+ const [guestFee, setGuestFee] = react.useState(null);
8389
+ const [guestQuoteLoading, setGuestQuoteLoading] = react.useState(false);
8037
8390
  const executingBridgeRef = react.useRef(false);
8038
8391
  const fetchedRef = react.useRef(false);
8039
8392
  const selectedGuestTokenRef = react.useRef(null);
@@ -8043,21 +8396,65 @@ function useGuestTransferHandlers(deps) {
8043
8396
  if (!account.address) return;
8044
8397
  fetchedRef.current = true;
8045
8398
  setLoadingBalances(true);
8046
- fetchGuestTransferBalances(apiBaseUrl, guestTransferId, guestSessionToken, account.address).then((options) => mapBalancesToGuestTokenEntries(options)).then((entries) => {
8399
+ putGuestTransferSender(apiBaseUrl, guestTransferId, guestSessionToken, {
8400
+ senderAddress: account.address
8401
+ }).then(async (res) => {
8402
+ const balances = res.source?.balances;
8403
+ if (!balances?.length) {
8404
+ dispatch({ type: "SET_ERROR", error: "No supported tokens found for this transfer." });
8405
+ return;
8406
+ }
8407
+ const entries = mapGuestPickerEntries(balances);
8047
8408
  setGuestTokenEntries(entries);
8048
8409
  if (entries.length === 0) {
8049
8410
  dispatch({ type: "SET_ERROR", error: "No supported tokens found in your wallet." });
8411
+ return;
8412
+ }
8413
+ const recommended = res.source?.recommended;
8414
+ const autoEntry = recommended ? guestEntryMatchingRecommended(balances, recommended) : null;
8415
+ const pick = autoEntry && entries.some(
8416
+ (e) => e.sourceChainId === autoEntry.sourceChainId && e.tokenAddress.toLowerCase() === autoEntry.tokenAddress.toLowerCase()
8417
+ ) ? autoEntry : entries[0];
8418
+ setPendingGuestEntry(pick);
8419
+ setGuestFee(null);
8420
+ if (res.fee?.quote != null) {
8421
+ setGuestFee(res.fee);
8422
+ return;
8423
+ }
8424
+ setGuestQuoteLoading(true);
8425
+ try {
8426
+ const quote = await postGuestTransferFeeQuote(
8427
+ apiBaseUrl,
8428
+ guestTransferId,
8429
+ guestSessionToken,
8430
+ account.address,
8431
+ pick.sourceChainId,
8432
+ pick.tokenAddress
8433
+ );
8434
+ setGuestFee(quote);
8435
+ } catch (err) {
8436
+ captureException(err);
8437
+ setPendingGuestEntry(null);
8438
+ setGuestFee(null);
8439
+ const msg = err instanceof Error ? err.message : "Failed to load fee estimate";
8440
+ dispatch({ type: "SET_ERROR", error: msg });
8441
+ onError?.(msg);
8442
+ } finally {
8443
+ setGuestQuoteLoading(false);
8050
8444
  }
8051
8445
  }).catch((err) => {
8052
8446
  captureException(err);
8053
- dispatch({ type: "SET_ERROR", error: "Failed to fetch token balances." });
8447
+ dispatch({ type: "SET_ERROR", error: "Failed to load payment sources." });
8054
8448
  }).finally(() => setLoadingBalances(false));
8055
- }, [isGuestFlow, guestTransferId, guestSessionToken, apiBaseUrl, wagmiConfig2, dispatch]);
8449
+ }, [isGuestFlow, guestTransferId, guestSessionToken, apiBaseUrl, wagmiConfig2, dispatch, onError]);
8056
8450
  react.useEffect(() => {
8057
8451
  if (!isGuestFlow) {
8058
8452
  fetchedRef.current = false;
8059
8453
  selectedGuestTokenRef.current = null;
8060
8454
  setGuestTokenEntries([]);
8455
+ setPendingGuestEntry(null);
8456
+ setGuestFee(null);
8457
+ setGuestQuoteLoading(false);
8061
8458
  }
8062
8459
  }, [isGuestFlow]);
8063
8460
  const handleSelectGuestToken = react.useCallback(async (entry) => {
@@ -8067,7 +8464,44 @@ function useGuestTransferHandlers(deps) {
8067
8464
  dispatch({ type: "SET_ERROR", error: "Wallet not connected." });
8068
8465
  return;
8069
8466
  }
8467
+ setGuestQuoteLoading(true);
8468
+ dispatch({ type: "SET_ERROR", error: null });
8469
+ setPendingGuestEntry(entry);
8470
+ setGuestFee(null);
8471
+ try {
8472
+ console.info(
8473
+ `[blink-sdk] type=guest Fee quote preview: address=${account.address}, chain=${entry.sourceChainId}, token=${entry.tokenSymbol}`
8474
+ );
8475
+ const quote = await postGuestTransferFeeQuote(
8476
+ apiBaseUrl,
8477
+ guestTransferId,
8478
+ guestSessionToken,
8479
+ account.address,
8480
+ entry.sourceChainId,
8481
+ entry.tokenAddress
8482
+ );
8483
+ setGuestFee(quote);
8484
+ } catch (err) {
8485
+ captureException(err);
8486
+ setPendingGuestEntry(null);
8487
+ setGuestFee(null);
8488
+ const msg = err instanceof Error ? err.message : "Failed to load fee estimate";
8489
+ dispatch({ type: "SET_ERROR", error: msg });
8490
+ onError?.(msg);
8491
+ } finally {
8492
+ setGuestQuoteLoading(false);
8493
+ }
8494
+ }, [guestTransferId, guestSessionToken, wagmiConfig2, apiBaseUrl, dispatch, onError]);
8495
+ const handleConfirmGuestToken = react.useCallback(async () => {
8496
+ if (!guestTransferId || !guestSessionToken || !pendingGuestEntry) return;
8497
+ const account = getAccount(wagmiConfig2);
8498
+ if (!account.address) {
8499
+ dispatch({ type: "SET_ERROR", error: "Wallet not connected." });
8500
+ return;
8501
+ }
8502
+ const entry = pendingGuestEntry;
8070
8503
  setSettingSender(true);
8504
+ dispatch({ type: "SET_ERROR", error: null });
8071
8505
  try {
8072
8506
  console.info(
8073
8507
  `[blink-sdk] type=guest Setting sender: address=${account.address}, chain=${entry.sourceChainId}, token=${entry.tokenSymbol}`
@@ -8089,7 +8523,15 @@ function useGuestTransferHandlers(deps) {
8089
8523
  } finally {
8090
8524
  setSettingSender(false);
8091
8525
  }
8092
- }, [guestTransferId, guestSessionToken, wagmiConfig2, apiBaseUrl, dispatch, onError]);
8526
+ }, [
8527
+ guestTransferId,
8528
+ guestSessionToken,
8529
+ pendingGuestEntry,
8530
+ wagmiConfig2,
8531
+ apiBaseUrl,
8532
+ dispatch,
8533
+ onError
8534
+ ]);
8093
8535
  react.useEffect(() => {
8094
8536
  if (!isGuestFlow || !guestTransferId || !guestSessionToken || !selectedGuestTokenRef.current) return;
8095
8537
  if (executingBridgeRef.current) return;
@@ -8197,13 +8639,19 @@ function useGuestTransferHandlers(deps) {
8197
8639
  execute();
8198
8640
  }, [isGuestFlow, guestTransferId, guestSessionToken, settingSender, apiBaseUrl, wagmiConfig2, switchChainAsync, dispatch, onComplete, onError]);
8199
8641
  const handleGuestBackFromTokenPicker = react.useCallback(() => {
8642
+ setPendingGuestEntry(null);
8643
+ setGuestFee(null);
8200
8644
  dispatch({ type: "GUEST_BACK_FROM_TOKEN_PICKER" });
8201
8645
  }, [dispatch]);
8202
8646
  return {
8203
8647
  guestTokenEntries,
8204
8648
  loadingBalances,
8205
8649
  settingSender,
8650
+ pendingGuestEntry,
8651
+ guestFee,
8652
+ guestQuoteLoading,
8206
8653
  handleSelectGuestToken,
8654
+ handleConfirmGuestToken,
8207
8655
  handleGuestBackFromTokenPicker
8208
8656
  };
8209
8657
  }
@@ -9953,6 +10401,7 @@ function BlinkPaymentInner({
9953
10401
  onSelectAuthorizedToken: provider.handleSelectAuthorizedToken,
9954
10402
  onAuthorizeToken: provider.handleAuthorizeToken,
9955
10403
  onSelectGuestToken: guestTransfer.handleSelectGuestToken,
10404
+ onConfirmGuestToken: guestTransfer.handleConfirmGuestToken,
9956
10405
  onGuestBackFromTokenPicker: guestTransfer.handleGuestBackFromTokenPicker,
9957
10406
  onLogin: () => dispatch({ type: "REQUEST_LOGIN" }),
9958
10407
  onPreauthorize: provider.handlePreauthorize,
@@ -10018,7 +10467,10 @@ function BlinkPaymentInner({
10018
10467
  savingOneTapLimit: oneTapSetup.savingOneTapLimit,
10019
10468
  guestTokenEntries: guestTransfer.guestTokenEntries,
10020
10469
  guestLoadingBalances: guestTransfer.loadingBalances,
10021
- guestSettingSender: guestTransfer.settingSender
10470
+ guestSettingSender: guestTransfer.settingSender,
10471
+ guestPendingEntry: guestTransfer.pendingGuestEntry,
10472
+ guestQuoteFee: guestTransfer.guestFee?.quote ?? null,
10473
+ guestQuoteLoading: guestTransfer.guestQuoteLoading
10022
10474
  },
10023
10475
  handlers
10024
10476
  }
@@ -10031,9 +10483,17 @@ exports.BLINK_MASCOT = BLINK_MASCOT;
10031
10483
  exports.BlinkLoadingScreen = BlinkLoadingScreen;
10032
10484
  exports.BlinkPayment = BlinkPayment;
10033
10485
  exports.BlinkProvider = BlinkProvider;
10486
+ exports.ConfirmSignScreen = ConfirmSignScreen;
10487
+ exports.DepositScreen = DepositScreen;
10034
10488
  exports.FlowPhaseProvider = FlowPhaseProvider;
10489
+ exports.GuestPreauthLinkingScreen = GuestPreauthLinkingScreen;
10490
+ exports.GuestPreauthSetupCompleteScreen = GuestPreauthSetupCompleteScreen;
10491
+ exports.GuestTokenPickerScreen = GuestTokenPickerScreen;
10035
10492
  exports.IconCircle = IconCircle;
10036
10493
  exports.InfoBanner = InfoBanner;
10494
+ exports.LoginScreen = LoginScreen;
10495
+ exports.OpenWalletScreen = OpenWalletScreen;
10496
+ exports.OtpVerifyScreen = OtpVerifyScreen;
10037
10497
  exports.OutlineButton = OutlineButton;
10038
10498
  exports.PasskeyIframeBlockedError = PasskeyIframeBlockedError;
10039
10499
  exports.PasskeyScreen = PasskeyScreen;
@@ -10044,9 +10504,14 @@ exports.ScreenLayout = ScreenLayout;
10044
10504
  exports.SelectSourceScreen = SelectSourceScreen;
10045
10505
  exports.SettingsMenu = SettingsMenu;
10046
10506
  exports.SetupScreen = SetupScreen;
10507
+ exports.SetupStatusScreen = SetupStatusScreen;
10047
10508
  exports.Spinner = Spinner;
10048
10509
  exports.StepList = StepList;
10510
+ exports.SuccessScreen = SuccessScreen;
10049
10511
  exports.TokenPickerScreen = TokenPickerScreen;
10512
+ exports.TransferStatusScreen = TransferStatusScreen;
10513
+ exports.VerifyPasskeyScreen = VerifyPasskeyScreen;
10514
+ exports.WalletPickerScreen = WalletPickerScreen;
10050
10515
  exports.blinkApi = api_exports;
10051
10516
  exports.buildPasskeyPopupOptions = buildPasskeyPopupOptions;
10052
10517
  exports.createPasskeyCredential = createPasskeyCredential;
@@ -10056,7 +10521,9 @@ exports.deviceHasPasskey = deviceHasPasskey;
10056
10521
  exports.findDevicePasskey = findDevicePasskey;
10057
10522
  exports.findDevicePasskeyViaPopup = findDevicePasskeyViaPopup;
10058
10523
  exports.getTheme = getTheme;
10524
+ exports.guestEntryMatchingRecommended = guestEntryMatchingRecommended;
10059
10525
  exports.lightTheme = lightTheme;
10526
+ exports.mapGuestPickerEntries = mapGuestPickerEntries;
10060
10527
  exports.resolvePasskeyRpId = resolvePasskeyRpId;
10061
10528
  exports.screenForPhase = screenForPhase;
10062
10529
  exports.useAuthorizationExecutor = useAuthorizationExecutor;