thirdweb 5.88.5-nightly-0574eac02c832c382972fd545df79c36e11796e1-20250217000342 → 5.88.6-nightly-b182302f590e75c9881cebd0ca1cc8b1425d50b8-20250218000338

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.
Files changed (141) hide show
  1. package/dist/cjs/contract/deployment/zksync/zkDeployDeterministic.js +5 -1
  2. package/dist/cjs/contract/deployment/zksync/zkDeployDeterministic.js.map +1 -1
  3. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js +53 -71
  4. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js.map +1 -1
  5. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js +2 -2
  6. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js.map +1 -1
  7. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js +1 -1
  8. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js.map +1 -1
  9. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.js +1 -1
  10. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.js.map +1 -1
  11. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.js +4 -14
  12. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.js.map +1 -1
  13. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js +2 -32
  14. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js.map +1 -1
  15. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js +9 -3
  16. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js.map +1 -1
  17. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js +15 -8
  18. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js.map +1 -1
  19. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.js +39 -0
  20. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.js.map +1 -0
  21. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js +58 -53
  22. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js.map +1 -1
  23. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js +3 -10
  24. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js.map +1 -1
  25. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.js +35 -0
  26. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.js.map +1 -0
  27. package/dist/cjs/react/web/ui/ConnectWallet/screens/TokenSelector.js +1 -2
  28. package/dist/cjs/react/web/ui/ConnectWallet/screens/TokenSelector.js.map +1 -1
  29. package/dist/cjs/react/web/ui/ConnectWallet/screens/nativeToken.js +4 -2
  30. package/dist/cjs/react/web/ui/ConnectWallet/screens/nativeToken.js.map +1 -1
  31. package/dist/cjs/react/web/ui/components/token/TokenRow.js +11 -4
  32. package/dist/cjs/react/web/ui/components/token/TokenRow.js.map +1 -1
  33. package/dist/cjs/utils/any-evm/compute-deployment-address.js +4 -1
  34. package/dist/cjs/utils/any-evm/compute-deployment-address.js.map +1 -1
  35. package/dist/cjs/utils/any-evm/compute-published-contract-deploy-info.js +1 -0
  36. package/dist/cjs/utils/any-evm/compute-published-contract-deploy-info.js.map +1 -1
  37. package/dist/cjs/utils/any-evm/get-init-bytecode-with-salt.js +3 -1
  38. package/dist/cjs/utils/any-evm/get-init-bytecode-with-salt.js.map +1 -1
  39. package/dist/cjs/utils/any-evm/zksync/computeDeploymentAddress.js +6 -1
  40. package/dist/cjs/utils/any-evm/zksync/computeDeploymentAddress.js.map +1 -1
  41. package/dist/cjs/version.js +1 -1
  42. package/dist/cjs/wallets/connection/autoConnect.js +3 -4
  43. package/dist/cjs/wallets/connection/autoConnect.js.map +1 -1
  44. package/dist/esm/contract/deployment/zksync/zkDeployDeterministic.js +6 -2
  45. package/dist/esm/contract/deployment/zksync/zkDeployDeterministic.js.map +1 -1
  46. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js +55 -73
  47. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js.map +1 -1
  48. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js +1 -1
  49. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js.map +1 -1
  50. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js +1 -1
  51. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js.map +1 -1
  52. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.js +1 -1
  53. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.js.map +1 -1
  54. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.js +4 -14
  55. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.js.map +1 -1
  56. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js +4 -34
  57. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js.map +1 -1
  58. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js +9 -3
  59. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js.map +1 -1
  60. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js +15 -8
  61. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js.map +1 -1
  62. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.js +36 -0
  63. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.js.map +1 -0
  64. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js +59 -53
  65. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js.map +1 -1
  66. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js +4 -11
  67. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js.map +1 -1
  68. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.js +32 -0
  69. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.js.map +1 -0
  70. package/dist/esm/react/web/ui/ConnectWallet/screens/TokenSelector.js +1 -2
  71. package/dist/esm/react/web/ui/ConnectWallet/screens/TokenSelector.js.map +1 -1
  72. package/dist/esm/react/web/ui/ConnectWallet/screens/nativeToken.js +4 -2
  73. package/dist/esm/react/web/ui/ConnectWallet/screens/nativeToken.js.map +1 -1
  74. package/dist/esm/react/web/ui/components/token/TokenRow.js +11 -4
  75. package/dist/esm/react/web/ui/components/token/TokenRow.js.map +1 -1
  76. package/dist/esm/utils/any-evm/compute-deployment-address.js +4 -1
  77. package/dist/esm/utils/any-evm/compute-deployment-address.js.map +1 -1
  78. package/dist/esm/utils/any-evm/compute-published-contract-deploy-info.js +1 -0
  79. package/dist/esm/utils/any-evm/compute-published-contract-deploy-info.js.map +1 -1
  80. package/dist/esm/utils/any-evm/get-init-bytecode-with-salt.js +4 -2
  81. package/dist/esm/utils/any-evm/get-init-bytecode-with-salt.js.map +1 -1
  82. package/dist/esm/utils/any-evm/zksync/computeDeploymentAddress.js +6 -1
  83. package/dist/esm/utils/any-evm/zksync/computeDeploymentAddress.js.map +1 -1
  84. package/dist/esm/version.js +1 -1
  85. package/dist/esm/wallets/connection/autoConnect.js +2 -2
  86. package/dist/esm/wallets/connection/autoConnect.js.map +1 -1
  87. package/dist/types/contract/deployment/zksync/zkDeployDeterministic.d.ts.map +1 -1
  88. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.d.ts.map +1 -1
  89. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.d.ts.map +1 -1
  90. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.d.ts +2 -2
  91. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.d.ts.map +1 -1
  92. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.d.ts.map +1 -1
  93. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.d.ts +2 -2
  94. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.d.ts.map +1 -1
  95. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.d.ts +2 -2
  96. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.d.ts.map +1 -1
  97. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.d.ts +15 -0
  98. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.d.ts.map +1 -0
  99. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.d.ts +2 -16
  100. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.d.ts.map +1 -1
  101. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.d.ts.map +1 -1
  102. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.d.ts +9 -0
  103. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.d.ts.map +1 -0
  104. package/dist/types/react/web/ui/ConnectWallet/screens/TokenSelector.d.ts.map +1 -1
  105. package/dist/types/react/web/ui/ConnectWallet/screens/nativeToken.d.ts +1 -1
  106. package/dist/types/react/web/ui/ConnectWallet/screens/nativeToken.d.ts.map +1 -1
  107. package/dist/types/react/web/ui/components/token/TokenRow.d.ts +2 -2
  108. package/dist/types/react/web/ui/components/token/TokenRow.d.ts.map +1 -1
  109. package/dist/types/utils/any-evm/compute-deployment-address.d.ts.map +1 -1
  110. package/dist/types/utils/any-evm/compute-published-contract-deploy-info.d.ts +3 -0
  111. package/dist/types/utils/any-evm/compute-published-contract-deploy-info.d.ts.map +1 -1
  112. package/dist/types/utils/any-evm/get-init-bytecode-with-salt.d.ts.map +1 -1
  113. package/dist/types/utils/any-evm/zksync/computeDeploymentAddress.d.ts +1 -1
  114. package/dist/types/utils/any-evm/zksync/computeDeploymentAddress.d.ts.map +1 -1
  115. package/dist/types/version.d.ts +1 -1
  116. package/dist/types/wallets/connection/autoConnect.d.ts +2 -2
  117. package/dist/types/wallets/connection/autoConnect.d.ts.map +1 -1
  118. package/package.json +1 -1
  119. package/src/contract/deployment/deploy-deterministic.test.ts +45 -2
  120. package/src/contract/deployment/zksync/zkDeployDeterministic.ts +10 -2
  121. package/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx +70 -157
  122. package/src/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.tsx +1 -1
  123. package/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.tsx +1 -0
  124. package/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.tsx +1 -1
  125. package/src/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.ts +4 -18
  126. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.tsx +20 -161
  127. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.tsx +25 -14
  128. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.tsx +58 -34
  129. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.tsx +134 -0
  130. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.tsx +134 -128
  131. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.tsx +18 -48
  132. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx +70 -0
  133. package/src/react/web/ui/ConnectWallet/screens/TokenSelector.tsx +1 -3
  134. package/src/react/web/ui/ConnectWallet/screens/nativeToken.ts +5 -3
  135. package/src/react/web/ui/components/token/TokenRow.tsx +38 -14
  136. package/src/utils/any-evm/compute-deployment-address.ts +4 -1
  137. package/src/utils/any-evm/compute-published-contract-deploy-info.ts +1 -0
  138. package/src/utils/any-evm/get-init-bytecode-with-salt.ts +5 -2
  139. package/src/utils/any-evm/zksync/computeDeploymentAddress.ts +6 -2
  140. package/src/version.ts +1 -1
  141. package/src/wallets/connection/autoConnect.ts +3 -3
@@ -1,10 +1,14 @@
1
1
  import styled from "@emotion/styled";
2
+ import {
3
+ CardStackIcon,
4
+ ChevronRightIcon,
5
+ Cross2Icon,
6
+ } from "@radix-ui/react-icons";
2
7
  import { useQuery } from "@tanstack/react-query";
3
8
  import type { Chain } from "../../../../../../../chains/types.js";
4
9
  import { getCachedChain } from "../../../../../../../chains/utils.js";
5
10
  import type { ThirdwebClient } from "../../../../../../../client/client.js";
6
11
  import { NATIVE_TOKEN_ADDRESS } from "../../../../../../../constants/addresses.js";
7
- import { shortenAddress } from "../../../../../../../utils/address.js";
8
12
  import type { Wallet } from "../../../../../../../wallets/interfaces/wallet.js";
9
13
  import {
10
14
  type GetWalletBalanceResult,
@@ -13,7 +17,6 @@ import {
13
17
  import type { WalletId } from "../../../../../../../wallets/wallet-types.js";
14
18
  import { useCustomTheme } from "../../../../../../core/design-system/CustomThemeProvider.js";
15
19
  import {
16
- type fontSize,
17
20
  iconSize,
18
21
  radius,
19
22
  spacing,
@@ -25,28 +28,23 @@ import {
25
28
  } from "../../../../../../core/hooks/others/useChainQuery.js";
26
29
  import { useActiveAccount } from "../../../../../../core/hooks/wallets/useActiveAccount.js";
27
30
  import { useConnectedWallets } from "../../../../../../core/hooks/wallets/useConnectedWallets.js";
31
+ import { useDisconnect } from "../../../../../../core/hooks/wallets/useDisconnect.js";
28
32
  import type {
29
33
  SupportedTokens,
30
34
  TokenInfo,
31
35
  } from "../../../../../../core/utils/defaultTokens.js";
32
- import {
33
- useEnsAvatar,
34
- useEnsName,
35
- } from "../../../../../../core/utils/wallet.js";
36
36
  import { LoadingScreen } from "../../../../../wallets/shared/LoadingScreen.js";
37
- import { Img } from "../../../../components/Img.js";
37
+ import { Spacer } from "../../../../components/Spacer.js";
38
38
  import { TextDivider } from "../../../../components/TextDivider.js";
39
39
  import { TokenIcon } from "../../../../components/TokenIcon.js";
40
- import { WalletImage } from "../../../../components/WalletImage.js";
41
- import { Container, Line, ModalHeader } from "../../../../components/basic.js";
40
+ import { Container } from "../../../../components/basic.js";
42
41
  import { Button } from "../../../../components/buttons.js";
43
42
  import { Text } from "../../../../components/text.js";
44
- import { Blobbie } from "../../../Blobbie.js";
45
43
  import { OutlineWalletIcon } from "../../../icons/OutlineWalletIcon.js";
46
- import type { ConnectLocale } from "../../../locale/types.js";
47
44
  import { formatTokenBalance } from "../../formatTokenBalance.js";
48
45
  import { type ERC20OrNativeToken, isNativeToken } from "../../nativeToken.js";
49
46
  import { FiatValue } from "./FiatValue.js";
47
+ import { WalletRow } from "./WalletRow.js";
50
48
 
51
49
  type TokenBalance = {
52
50
  balance: GetWalletBalanceResult;
@@ -54,28 +52,28 @@ type TokenBalance = {
54
52
  token: TokenInfo;
55
53
  };
56
54
 
55
+ type WalletKey = {
56
+ id: WalletId;
57
+ address: string;
58
+ };
59
+
57
60
  export function TokenSelectorScreen(props: {
58
61
  client: ThirdwebClient;
59
62
  sourceTokens: SupportedTokens | undefined;
60
63
  sourceSupportedTokens: SupportedTokens | undefined;
61
64
  toChain: Chain;
62
65
  toToken: ERC20OrNativeToken;
63
- fromToken: ERC20OrNativeToken;
64
- fromChain: Chain;
65
66
  tokenAmount: string;
66
67
  mode: PayUIOptions["mode"];
67
68
  hiddenWallets?: WalletId[];
68
- onSelect: (wallet: Wallet, token: TokenInfo, chain: Chain) => void;
69
- onBack: () => void;
69
+ onSelectToken: (wallet: Wallet, token: TokenInfo, chain: Chain) => void;
70
70
  onConnect: () => void;
71
- modalTitle?: string;
72
- connectLocale: ConnectLocale;
71
+ onPayWithFiat: () => void;
73
72
  }) {
74
73
  const connectedWallets = useConnectedWallets();
75
74
  const activeAccount = useActiveAccount();
76
75
  const chainInfo = useChainMetadata(props.toChain);
77
76
  const theme = useCustomTheme();
78
- const locale = props.connectLocale.sendFundsScreen;
79
77
 
80
78
  const walletsAndBalances = useQuery({
81
79
  queryKey: [
@@ -90,12 +88,16 @@ export function TokenSelectorScreen(props: {
90
88
  ],
91
89
  queryFn: async () => {
92
90
  // in parallel, get the balances of all the wallets on each of the sourceSupportedTokens
93
- const walletBalanceMap = new Map<Wallet, TokenBalance[]>();
91
+ const walletBalanceMap = new Map<WalletKey, TokenBalance[]>();
94
92
 
95
93
  const balancePromises = connectedWallets.flatMap((wallet) => {
96
94
  const account = wallet.getAccount();
97
95
  if (!account) return [];
98
- walletBalanceMap.set(wallet, []);
96
+ const walletKey: WalletKey = {
97
+ id: wallet.id,
98
+ address: account.address,
99
+ };
100
+ walletBalanceMap.set(walletKey, []);
99
101
 
100
102
  // inject the destination token too since it can be used as well to pay/transfer
101
103
  const toToken = isNativeToken(props.toToken)
@@ -139,7 +141,7 @@ export function TokenSelectorScreen(props: {
139
141
  : balance.value > 0n;
140
142
 
141
143
  if (shouldInclude) {
142
- const existingBalances = walletBalanceMap.get(wallet) || [];
144
+ const existingBalances = walletBalanceMap.get(walletKey) || [];
143
145
  existingBalances.push({ balance, chain, token });
144
146
  existingBalances.sort((a, b) => {
145
147
  if (
@@ -188,47 +190,44 @@ export function TokenSelectorScreen(props: {
188
190
  <Container
189
191
  animate="fadein"
190
192
  style={{
191
- minHeight: "300px",
193
+ minHeight: "200px",
192
194
  }}
193
195
  >
194
- <Container py="md" px="lg">
195
- <ModalHeader
196
- onBack={props.onBack}
197
- title={props.modalTitle || locale.selectTokenTitle}
198
- />
199
- </Container>
200
-
201
- <Line />
202
-
196
+ {filteredWallets.length === 0 ? (
197
+ <Container flex="column" gap="xs" py="lg">
198
+ <Text size="xs" color="secondaryText" center>
199
+ No suitable payment token found
200
+ <br />
201
+ in connected wallets
202
+ </Text>
203
+ </Container>
204
+ ) : (
205
+ <Container flex="column" gap="xs">
206
+ <Text size="sm">Select payment token</Text>
207
+ <Spacer y="xs" />
208
+ </Container>
209
+ )}
203
210
  <Container
204
211
  scrollY
205
212
  style={{
206
- maxHeight: "450px",
213
+ maxHeight: "350px",
207
214
  }}
208
215
  >
209
- <Container flex="column" gap="sm" p="lg">
210
- {filteredWallets.length === 0 && (
211
- <Container flex="column" gap="xs" py="md">
212
- <Text size="xs" color="secondaryText" center>
213
- <i>
214
- No suitable payment token found
215
- <br />
216
- in connected wallets
217
- </i>
218
- </Text>
219
- </Container>
220
- )}
216
+ <Container flex="column" gap="sm">
221
217
  {filteredWallets.map(([w, balances]) => {
222
- const address = w.getAccount()?.address;
223
- if (!address) return null;
218
+ const address = w.address;
219
+ const wallet = connectedWallets.find(
220
+ (w) => w.getAccount()?.address === address,
221
+ );
222
+ if (!wallet) return null;
224
223
  return (
225
224
  <WalletRowWithBalances
226
225
  key={w.id}
227
- wallet={w}
226
+ wallet={wallet}
228
227
  balances={balances}
229
228
  client={props.client}
230
229
  address={address}
231
- onClick={props.onSelect}
230
+ onClick={props.onSelectToken}
232
231
  />
233
232
  );
234
233
  })}
@@ -237,10 +236,8 @@ export function TokenSelectorScreen(props: {
237
236
  variant="secondary"
238
237
  fullWidth
239
238
  onClick={props.onConnect}
240
- gap="xs"
241
239
  bg="tertiaryBg"
242
240
  style={{
243
- borderRadius: radius.md,
244
241
  border: `1px solid ${theme.colors.borderColor}`,
245
242
  padding: spacing.sm,
246
243
  }}
@@ -254,7 +251,30 @@ export function TokenSelectorScreen(props: {
254
251
  >
255
252
  <OutlineWalletIcon size={iconSize.md} />
256
253
  <Text size="sm" color="primaryText">
257
- Connect another wallet
254
+ Pay with another wallet
255
+ </Text>
256
+ </Container>
257
+ </Button>
258
+ <Button
259
+ variant="secondary"
260
+ fullWidth
261
+ onClick={props.onPayWithFiat}
262
+ bg="tertiaryBg"
263
+ style={{
264
+ border: `1px solid ${theme.colors.borderColor}`,
265
+ padding: spacing.sm,
266
+ }}
267
+ >
268
+ <Container
269
+ flex="row"
270
+ gap="sm"
271
+ center="y"
272
+ expand
273
+ color="secondaryIconColor"
274
+ >
275
+ <CardStackIcon width={iconSize.md} height={iconSize.md} />
276
+ <Text size="sm" color="primaryText">
277
+ Pay with credit card
258
278
  </Text>
259
279
  </Container>
260
280
  </Button>
@@ -272,28 +292,74 @@ function WalletRowWithBalances(props: {
272
292
  onClick: (wallet: Wallet, token: TokenInfo, chain: Chain) => void;
273
293
  hideConnectButton?: boolean;
274
294
  }) {
295
+ const theme = useCustomTheme();
275
296
  const displayedBalances = props.balances;
297
+ const activeAccount = useActiveAccount();
298
+ const { disconnect } = useDisconnect();
299
+ const isActiveAccount = activeAccount?.address === props.address;
276
300
 
277
301
  return (
278
- <Container flex="column" gap="sm">
279
- <Container px="sm">
302
+ <Container
303
+ flex="column"
304
+ style={{
305
+ borderRadius: radius.lg,
306
+ border: `1px solid ${theme.colors.borderColor}`,
307
+ }}
308
+ >
309
+ <Container
310
+ flex="row"
311
+ gap="sm"
312
+ bg="tertiaryBg"
313
+ style={{
314
+ justifyContent: "space-between",
315
+ borderTopRightRadius: radius.lg,
316
+ borderTopLeftRadius: radius.lg,
317
+ padding: spacing.sm,
318
+ paddingRight: spacing.xs,
319
+ borderBottom: `1px solid ${theme.colors.borderColor}`,
320
+ }}
321
+ >
280
322
  <WalletRow {...props} />
323
+ {!isActiveAccount && (
324
+ <Button
325
+ variant="ghost"
326
+ onClick={() => disconnect(props.wallet)}
327
+ style={{
328
+ padding: spacing.xxs,
329
+ color: theme.colors.secondaryText,
330
+ }}
331
+ >
332
+ <Cross2Icon width={iconSize.sm} height={iconSize.sm} />
333
+ </Button>
334
+ )}
281
335
  </Container>
282
- <Container flex="column" gap="sm">
336
+ <Container flex="column">
283
337
  {props.balances.length > 0 ? (
284
- displayedBalances.map((b) => (
338
+ displayedBalances.map((b, idx) => (
285
339
  <TokenBalanceRow
286
340
  client={props.client}
287
341
  onClick={() => props.onClick(props.wallet, b.token, b.chain)}
288
342
  key={`${b.token.address}-${b.chain.id}`}
289
343
  tokenBalance={b}
290
344
  wallet={props.wallet}
345
+ style={{
346
+ borderTopLeftRadius: 0,
347
+ borderTopRightRadius: 0,
348
+ borderBottomRightRadius:
349
+ idx === displayedBalances.length - 1 ? radius.lg : 0,
350
+ borderBottomLeftRadius:
351
+ idx === displayedBalances.length - 1 ? radius.lg : 0,
352
+ borderBottom:
353
+ idx === displayedBalances.length - 1
354
+ ? "none"
355
+ : `1px solid ${theme.colors.borderColor}`,
356
+ }}
291
357
  />
292
358
  ))
293
359
  ) : (
294
360
  <Container style={{ padding: spacing.sm }}>
295
361
  <Text size="sm" color="secondaryText">
296
- Not enough funds
362
+ Insufficient funds
297
363
  </Text>
298
364
  </Container>
299
365
  )}
@@ -307,33 +373,35 @@ function TokenBalanceRow(props: {
307
373
  tokenBalance: TokenBalance;
308
374
  wallet: Wallet;
309
375
  onClick: (token: TokenInfo, wallet: Wallet) => void;
376
+ style?: React.CSSProperties;
310
377
  }) {
311
- const { tokenBalance, wallet, onClick, client } = props;
378
+ const { tokenBalance, wallet, onClick, client, style } = props;
312
379
  const chainInfo = useChainName(tokenBalance.chain);
313
380
  return (
314
381
  <StyledButton
315
382
  onClick={() => onClick(tokenBalance.token, wallet)}
316
383
  variant="secondary"
384
+ style={style}
317
385
  >
318
- <Container flex="row" center="y" gap="md">
386
+ <Container flex="row" center="y" gap="sm">
319
387
  <TokenIcon
320
388
  token={tokenBalance.token}
321
389
  chain={tokenBalance.chain}
322
390
  size="md"
323
391
  client={client}
324
392
  />
325
- <Container flex="column" gap="3xs">
393
+ <Container flex="column" gap="4xs">
326
394
  <Text size="xs" color="primaryText">
327
395
  {tokenBalance.token.symbol}
328
396
  </Text>
329
397
  {chainInfo && <Text size="xs">{chainInfo.name}</Text>}
330
398
  </Container>
331
399
  </Container>
332
- <Container flex="row" center="y" gap="3xs" color="secondaryText">
400
+ <Container flex="row" center="y" gap="4xs" color="secondaryText">
333
401
  <Container
334
402
  flex="column"
335
403
  color="secondaryText"
336
- gap="3xs"
404
+ gap="4xs"
337
405
  style={{
338
406
  justifyContent: "flex-end",
339
407
  alignItems: "flex-end",
@@ -350,88 +418,26 @@ function TokenBalanceRow(props: {
350
418
  size="xs"
351
419
  />
352
420
  </Container>
353
- {/* <ChevronRightIcon width={iconSize.md} height={iconSize.md} /> */}
421
+ <ChevronRightIcon width={iconSize.md} height={iconSize.md} />
354
422
  </Container>
355
423
  </StyledButton>
356
424
  );
357
425
  }
358
426
 
359
- export function WalletRow(props: {
360
- client: ThirdwebClient;
361
- address: string;
362
- iconSize?: keyof typeof iconSize;
363
- textSize?: keyof typeof fontSize;
364
- walletId?: WalletId;
365
- wallet?: Wallet;
366
- }) {
367
- const { client, address } = props;
368
- const walletId = props.walletId;
369
- const theme = useCustomTheme();
370
- const ensNameQuery = useEnsName({
371
- client,
372
- address,
373
- });
374
- const addressOrENS = ensNameQuery.data || shortenAddress(address);
375
- const ensAvatarQuery = useEnsAvatar({
376
- client,
377
- ensName: ensNameQuery.data,
378
- });
379
- return (
380
- <Container flex="row" style={{ justifyContent: "space-between" }}>
381
- <Container flex="row" center="y" gap="sm" color="secondaryText">
382
- {ensAvatarQuery.data ? (
383
- <Img
384
- src={ensAvatarQuery.data}
385
- width={props.iconSize ? iconSize[props.iconSize] : iconSize.md}
386
- height={props.iconSize ? iconSize[props.iconSize] : iconSize.md}
387
- style={{
388
- borderRadius: radius.sm,
389
- overflow: "hidden",
390
- border: `1px solid ${theme.colors.borderColor}`,
391
- }}
392
- client={props.client}
393
- />
394
- ) : walletId ? (
395
- <WalletImage
396
- id={walletId}
397
- size={props.iconSize || iconSize.md}
398
- client={props.client}
399
- />
400
- ) : (
401
- <Container
402
- style={{
403
- width: iconSize.md,
404
- height: iconSize.md,
405
- borderRadius: radius.sm,
406
- overflow: "hidden",
407
- border: `1px solid ${theme.colors.borderColor}`,
408
- }}
409
- >
410
- <Blobbie address={props.address} size={Number(iconSize.md)} />
411
- </Container>
412
- )}
413
-
414
- <Text size={props.textSize || "sm"} color="primaryText">
415
- {addressOrENS || shortenAddress(props.address)}
416
- </Text>
417
- </Container>
418
- </Container>
419
- );
420
- }
421
-
422
- const StyledButton = /* @__PURE__ */ styled(Button)((_) => {
427
+ const StyledButton = /* @__PURE__ */ styled(Button)((props) => {
423
428
  const theme = useCustomTheme();
424
429
  return {
425
- background: theme.colors.tertiaryBg,
430
+ background: "transparent",
426
431
  justifyContent: "space-between",
427
432
  flexDirection: "row",
428
433
  padding: spacing.sm,
429
- border: `1px solid ${theme.colors.borderColor}`,
434
+ paddingRight: spacing.xs,
430
435
  gap: spacing.sm,
431
436
  "&:hover": {
432
437
  background: theme.colors.secondaryButtonBg,
433
438
  transform: "scale(1.01)",
434
439
  },
435
440
  transition: "background 200ms ease, transform 150ms ease",
441
+ ...props.style,
436
442
  };
437
443
  });
@@ -16,20 +16,18 @@ import type { Address } from "../../../../../../../utils/address.js";
16
16
  import { toWei } from "../../../../../../../utils/units.js";
17
17
  import { iconSize } from "../../../../../../core/design-system/index.js";
18
18
  import type { PayUIOptions } from "../../../../../../core/hooks/connection/ConnectButtonProps.js";
19
- import { useChainSymbol } from "../../../../../../core/hooks/others/useChainQuery.js";
20
19
  import { Spacer } from "../../../../components/Spacer.js";
21
20
  import { Spinner } from "../../../../components/Spinner.js";
22
21
  import { StepBar } from "../../../../components/StepBar.js";
23
22
  import { SwitchNetworkButton } from "../../../../components/SwitchNetwork.js";
24
- import { Container, Line, ModalHeader } from "../../../../components/basic.js";
23
+ import { Container, ModalHeader } from "../../../../components/basic.js";
25
24
  import { Button } from "../../../../components/buttons.js";
26
25
  import { Text } from "../../../../components/text.js";
27
26
  import { type ERC20OrNativeToken, isNativeToken } from "../../nativeToken.js";
28
27
  import { Step } from "../Stepper.js";
29
- import { TokenInfoRow } from "../pay-transactions/TokenInfoRow.js";
30
28
  import type { PayerInfo } from "../types.js";
31
29
  import { ConnectorLine } from "./ConfirmationScreen.js";
32
- import { WalletRow } from "./TokenSelectorScreen.js";
30
+ import { SwapSummary } from "./SwapSummary.js";
33
31
 
34
32
  type TransferConfirmationScreenProps = {
35
33
  title: string;
@@ -72,14 +70,13 @@ export function TransferConfirmationScreen(
72
70
  | { id: "error"; error: string }
73
71
  | { id: "done" }
74
72
  >({ id: "idle" });
75
- const { symbol } = useChainSymbol(chain);
76
73
 
77
74
  return (
78
75
  <Container p="lg">
79
76
  <ModalHeader title={title} onBack={onBack} />
80
77
  <Spacer y="xl" />
81
78
 
82
- {transactionMode && (
79
+ {transactionMode ? (
83
80
  <>
84
81
  <StepBar steps={2} currentStep={step === "transfer" ? 1 : 2} />
85
82
  <Spacer y="sm" />
@@ -88,52 +85,25 @@ export function TransferConfirmationScreen(
88
85
  ? "Step 1 of 2 - Transfer funds"
89
86
  : "Step 2 of 2 - Finalize transaction"}
90
87
  </Text>
91
- <Spacer y="xl" />
88
+ <Spacer y="md" />
89
+ </>
90
+ ) : (
91
+ <>
92
+ <Text size="sm">Confirm payment</Text>
93
+ <Spacer y="md" />
92
94
  </>
93
95
  )}
94
96
 
95
- {/* Sender Address */}
96
- <Container
97
- flex="row"
98
- center="y"
99
- style={{
100
- justifyContent: "space-between",
101
- }}
102
- >
103
- <Text size="sm">From</Text>
104
- <WalletRow address={payer.account.address} client={client} />
105
- </Container>
106
-
107
- <Spacer y="md" />
108
- <Line />
109
- <Spacer y="md" />
110
-
111
- {/* Receiver Address */}
112
- <Container
113
- flex="row"
114
- center="y"
115
- style={{
116
- justifyContent: "space-between",
117
- }}
118
- >
119
- <Text size="sm">To</Text>
120
- <WalletRow address={receiverAddress} client={client} />
121
- </Container>
122
-
123
- <Spacer y="md" />
124
- <Line />
125
- <Spacer y="md" />
126
-
127
- {/* Token Info */}
128
- <TokenInfoRow
129
- chainId={chain.id}
97
+ <SwapSummary
98
+ sender={payer.account.address}
99
+ receiver={receiverAddress}
130
100
  client={client}
131
- label="Amount"
132
- tokenAmount={tokenAmount}
133
- tokenSymbol={isNativeToken(token) ? symbol || "" : token.symbol}
134
- tokenAddress={
135
- isNativeToken(token) ? NATIVE_TOKEN_ADDRESS : token.address
136
- }
101
+ fromToken={token}
102
+ fromChain={chain}
103
+ toToken={token}
104
+ toChain={chain}
105
+ fromAmount={tokenAmount}
106
+ toAmount={tokenAmount}
137
107
  />
138
108
 
139
109
  <Spacer y="lg" />
@@ -0,0 +1,70 @@
1
+ import type { ThirdwebClient } from "../../../../../../../client/client.js";
2
+ import { shortenAddress } from "../../../../../../../utils/address.js";
3
+ import { isEcosystemWallet } from "../../../../../../../wallets/ecosystem/is-ecosystem-wallet.js";
4
+ import { isSmartWallet } from "../../../../../../../wallets/smart/index.js";
5
+ import {
6
+ fontSize,
7
+ iconSize,
8
+ } from "../../../../../../core/design-system/index.js";
9
+ import { useConnectedWallets } from "../../../../../../core/hooks/wallets/useConnectedWallets.js";
10
+ import {
11
+ useEnsName,
12
+ useWalletInfo,
13
+ } from "../../../../../../core/utils/wallet.js";
14
+ import { useProfiles } from "../../../../../hooks/wallets/useProfiles.js";
15
+ import { Skeleton } from "../../../../components/Skeleton.js";
16
+ import { WalletImage } from "../../../../components/WalletImage.js";
17
+ import { Container } from "../../../../components/basic.js";
18
+ import { Text } from "../../../../components/text.js";
19
+
20
+ export function WalletRow(props: {
21
+ client: ThirdwebClient;
22
+ address: string;
23
+ iconSize?: keyof typeof iconSize;
24
+ textSize?: keyof typeof fontSize;
25
+ }) {
26
+ const { client, address } = props;
27
+ const connectedWallets = useConnectedWallets();
28
+ const profile = useProfiles({ client });
29
+ const wallet = connectedWallets.find(
30
+ (w) => w.getAccount()?.address?.toLowerCase() === address.toLowerCase(),
31
+ );
32
+ const email =
33
+ wallet &&
34
+ (wallet.id === "inApp" ||
35
+ isEcosystemWallet(wallet) ||
36
+ isSmartWallet(wallet))
37
+ ? profile.data?.find((p) => !!p.details.email)?.details.email
38
+ : undefined;
39
+ const walletInfo = useWalletInfo(wallet?.id);
40
+ const ensNameQuery = useEnsName({
41
+ client,
42
+ address,
43
+ });
44
+ const addressOrENS = ensNameQuery.data || shortenAddress(address);
45
+ return (
46
+ <Container flex="row" style={{ justifyContent: "space-between" }}>
47
+ <Container flex="row" center="y" gap="sm" color="secondaryText">
48
+ {wallet ? (
49
+ <WalletImage
50
+ id={wallet.id}
51
+ size={iconSize[props.iconSize || "md"]}
52
+ client={props.client}
53
+ />
54
+ ) : null}
55
+ <Container flex="column" gap="4xs">
56
+ <Text size={props.textSize || "xs"} color="primaryText">
57
+ {addressOrENS || shortenAddress(props.address)}
58
+ </Text>
59
+ {profile.isLoading ? (
60
+ <Skeleton width="100px" height={fontSize.sm} />
61
+ ) : email || walletInfo?.data?.name ? (
62
+ <Text size="xs" color="secondaryText">
63
+ {email || walletInfo?.data?.name}
64
+ </Text>
65
+ ) : null}
66
+ </Container>
67
+ </Container>
68
+ </Container>
69
+ );
70
+ }
@@ -214,7 +214,6 @@ export function TokenSelector(props: {
214
214
  style={{
215
215
  paddingTop: 0,
216
216
  paddingBottom: spacing.lg,
217
- // maxHeight: props.chainSelection ? "300px" : "400px",
218
217
  }}
219
218
  >
220
219
  {!input && (
@@ -284,7 +283,6 @@ export function TokenSelector(props: {
284
283
  }
285
284
 
286
285
  function SelectTokenButton(props: {
287
- // token?: TokenInfo;
288
286
  token: ERC20OrNativeToken;
289
287
  chain: Chain;
290
288
  onClick: () => void;
@@ -310,7 +308,7 @@ function SelectTokenButton(props: {
310
308
  client={props.client}
311
309
  />
312
310
 
313
- <Container flex="column" gap="xxs">
311
+ <Container flex="column" gap="4xs">
314
312
  {tokenName ? (
315
313
  <Text size="sm" color="primaryText">
316
314
  {tokenName}
@@ -10,11 +10,13 @@ export const NATIVE_TOKEN: NativeToken = { nativeToken: true };
10
10
  * @internal
11
11
  */
12
12
  export function isNativeToken(
13
- token: Partial<TokenInfo> | NativeToken,
13
+ token?: Partial<TokenInfo> | NativeToken,
14
14
  ): token is NativeToken {
15
15
  return (
16
- "nativeToken" in token ||
17
- token.address?.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase()
16
+ (token &&
17
+ ("nativeToken" in token ||
18
+ token.address?.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase())) ||
19
+ false
18
20
  );
19
21
  }
20
22