thirdweb 5.88.5-nightly-0574eac02c832c382972fd545df79c36e11796e1-20250217000342 → 5.88.5

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 (111) hide show
  1. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js +53 -71
  2. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js.map +1 -1
  3. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js +2 -2
  4. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js.map +1 -1
  5. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js +1 -1
  6. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js.map +1 -1
  7. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.js +1 -1
  8. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.js.map +1 -1
  9. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.js +4 -14
  10. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.js.map +1 -1
  11. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js +2 -32
  12. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js.map +1 -1
  13. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js +9 -3
  14. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js.map +1 -1
  15. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js +15 -8
  16. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js.map +1 -1
  17. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.js +39 -0
  18. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.js.map +1 -0
  19. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js +58 -53
  20. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js.map +1 -1
  21. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js +3 -10
  22. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js.map +1 -1
  23. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.js +35 -0
  24. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.js.map +1 -0
  25. package/dist/cjs/react/web/ui/ConnectWallet/screens/TokenSelector.js +1 -2
  26. package/dist/cjs/react/web/ui/ConnectWallet/screens/TokenSelector.js.map +1 -1
  27. package/dist/cjs/react/web/ui/ConnectWallet/screens/nativeToken.js +4 -2
  28. package/dist/cjs/react/web/ui/ConnectWallet/screens/nativeToken.js.map +1 -1
  29. package/dist/cjs/react/web/ui/components/token/TokenRow.js +11 -4
  30. package/dist/cjs/react/web/ui/components/token/TokenRow.js.map +1 -1
  31. package/dist/cjs/version.js +1 -1
  32. package/dist/cjs/version.js.map +1 -1
  33. package/dist/cjs/wallets/connection/autoConnect.js +3 -4
  34. package/dist/cjs/wallets/connection/autoConnect.js.map +1 -1
  35. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js +55 -73
  36. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js.map +1 -1
  37. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js +1 -1
  38. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js.map +1 -1
  39. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js +1 -1
  40. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js.map +1 -1
  41. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.js +1 -1
  42. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.js.map +1 -1
  43. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.js +4 -14
  44. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.js.map +1 -1
  45. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js +4 -34
  46. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js.map +1 -1
  47. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js +9 -3
  48. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js.map +1 -1
  49. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js +15 -8
  50. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js.map +1 -1
  51. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.js +36 -0
  52. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.js.map +1 -0
  53. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js +59 -53
  54. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js.map +1 -1
  55. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js +4 -11
  56. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js.map +1 -1
  57. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.js +32 -0
  58. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.js.map +1 -0
  59. package/dist/esm/react/web/ui/ConnectWallet/screens/TokenSelector.js +1 -2
  60. package/dist/esm/react/web/ui/ConnectWallet/screens/TokenSelector.js.map +1 -1
  61. package/dist/esm/react/web/ui/ConnectWallet/screens/nativeToken.js +4 -2
  62. package/dist/esm/react/web/ui/ConnectWallet/screens/nativeToken.js.map +1 -1
  63. package/dist/esm/react/web/ui/components/token/TokenRow.js +11 -4
  64. package/dist/esm/react/web/ui/components/token/TokenRow.js.map +1 -1
  65. package/dist/esm/version.js +1 -1
  66. package/dist/esm/version.js.map +1 -1
  67. package/dist/esm/wallets/connection/autoConnect.js +2 -2
  68. package/dist/esm/wallets/connection/autoConnect.js.map +1 -1
  69. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.d.ts.map +1 -1
  70. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.d.ts.map +1 -1
  71. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.d.ts +2 -2
  72. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.d.ts.map +1 -1
  73. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.d.ts.map +1 -1
  74. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.d.ts +2 -2
  75. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.d.ts.map +1 -1
  76. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.d.ts +2 -2
  77. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.d.ts.map +1 -1
  78. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.d.ts +15 -0
  79. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.d.ts.map +1 -0
  80. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.d.ts +2 -16
  81. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.d.ts.map +1 -1
  82. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.d.ts.map +1 -1
  83. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.d.ts +9 -0
  84. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.d.ts.map +1 -0
  85. package/dist/types/react/web/ui/ConnectWallet/screens/TokenSelector.d.ts.map +1 -1
  86. package/dist/types/react/web/ui/ConnectWallet/screens/nativeToken.d.ts +1 -1
  87. package/dist/types/react/web/ui/ConnectWallet/screens/nativeToken.d.ts.map +1 -1
  88. package/dist/types/react/web/ui/components/token/TokenRow.d.ts +2 -2
  89. package/dist/types/react/web/ui/components/token/TokenRow.d.ts.map +1 -1
  90. package/dist/types/version.d.ts +1 -1
  91. package/dist/types/version.d.ts.map +1 -1
  92. package/dist/types/wallets/connection/autoConnect.d.ts +2 -2
  93. package/dist/types/wallets/connection/autoConnect.d.ts.map +1 -1
  94. package/package.json +1 -1
  95. package/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx +70 -157
  96. package/src/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.tsx +1 -1
  97. package/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.tsx +1 -0
  98. package/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.tsx +1 -1
  99. package/src/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.ts +4 -18
  100. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.tsx +20 -161
  101. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.tsx +25 -14
  102. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.tsx +58 -34
  103. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.tsx +134 -0
  104. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.tsx +134 -128
  105. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.tsx +18 -48
  106. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx +70 -0
  107. package/src/react/web/ui/ConnectWallet/screens/TokenSelector.tsx +1 -3
  108. package/src/react/web/ui/ConnectWallet/screens/nativeToken.ts +5 -3
  109. package/src/react/web/ui/components/token/TokenRow.tsx +38 -14
  110. package/src/version.ts +1 -1
  111. package/src/wallets/connection/autoConnect.ts +3 -3
@@ -12,29 +12,20 @@ import {
12
12
  type WaitForReceiptOptions,
13
13
  waitForReceipt,
14
14
  } from "../../../../../../../transaction/actions/wait-for-tx-receipt.js";
15
- import { shortenAddress } from "../../../../../../../utils/address.js";
16
- import { formatNumber } from "../../../../../../../utils/formatNumber.js";
17
15
  import { useCustomTheme } from "../../../../../../core/design-system/CustomThemeProvider.js";
18
- import {
19
- fontSize,
20
- iconSize,
21
- } from "../../../../../../core/design-system/index.js";
22
- import { useChainName } from "../../../../../../core/hooks/others/useChainQuery.js";
23
- import { useEnsName } from "../../../../../../core/utils/wallet.js";
24
- import { Skeleton } from "../../../../components/Skeleton.js";
16
+ import { iconSize } from "../../../../../../core/design-system/index.js";
25
17
  import { Spacer } from "../../../../components/Spacer.js";
26
18
  import { Spinner } from "../../../../components/Spinner.js";
27
19
  import { StepBar } from "../../../../components/StepBar.js";
28
20
  import { SwitchNetworkButton } from "../../../../components/SwitchNetwork.js";
29
- import { Container, Line, ModalHeader } from "../../../../components/basic.js";
21
+ import { Container, ModalHeader } from "../../../../components/basic.js";
30
22
  import { Button } from "../../../../components/buttons.js";
31
23
  import { Text } from "../../../../components/text.js";
32
24
  import { StyledDiv } from "../../../../design-system/elements.js";
33
25
  import type { ERC20OrNativeToken } from "../../nativeToken.js";
34
- import { PayTokenIcon } from "../PayTokenIcon.js";
35
26
  import { Step } from "../Stepper.js";
36
27
  import type { PayerInfo } from "../types.js";
37
- import { formatSeconds } from "./formatSeconds.js";
28
+ import { SwapSummary } from "./SwapSummary.js";
38
29
  import { addPendingTx } from "./pendingSwapTx.js";
39
30
 
40
31
  /**
@@ -74,9 +65,6 @@ export function SwapConfirmationScreen(props: {
74
65
 
75
66
  const receiver = props.quote.swapDetails.toAddress;
76
67
  const sender = props.quote.swapDetails.fromAddress;
77
- const isDifferentRecipient = receiver.toLowerCase() !== sender.toLowerCase();
78
-
79
- const ensName = useEnsName({ client: props.client, address: receiver });
80
68
 
81
69
  return (
82
70
  <Container p="lg">
@@ -94,58 +82,26 @@ export function SwapConfirmationScreen(props: {
94
82
  <Spacer y="md" />
95
83
  </>
96
84
  ) : (
97
- <Spacer y="lg" />
98
- )}
99
-
100
- {/* Pay */}
101
- <ConfirmItem label="Pay">
102
- <RenderTokenInfo
103
- chain={props.fromChain}
104
- amount={String(formatNumber(Number(props.fromAmount), 6))}
105
- symbol={props.fromTokenSymbol || ""}
106
- token={props.fromToken}
107
- client={props.client}
108
- />
109
- </ConfirmItem>
110
-
111
- {/* Receive */}
112
- {!isDifferentRecipient && (
113
- <ConfirmItem label="Receive">
114
- <RenderTokenInfo
115
- chain={props.toChain}
116
- amount={String(formatNumber(Number(props.toAmount), 6))}
117
- symbol={props.toTokenSymbol}
118
- token={props.toToken}
119
- client={props.client}
120
- />
121
- </ConfirmItem>
85
+ <>
86
+ <Spacer y="lg" />
87
+ <Text size="sm">Confirm payment</Text>
88
+ <Spacer y="md" />
89
+ </>
122
90
  )}
123
91
 
124
- {/* Fees */}
125
- <ConfirmItem label="Fees">
126
- <SwapFeesRightAligned quote={props.quote} />
127
- </ConfirmItem>
128
-
129
- {/* Time */}
130
- <ConfirmItem label="Time">
131
- <Text size="sm" color="primaryText">
132
- ~
133
- {formatSeconds(
134
- props.quote.swapDetails.estimated.durationSeconds || 0,
135
- )}
136
- </Text>
137
- </ConfirmItem>
138
-
139
- {/* Send to */}
140
- {isDifferentRecipient && (
141
- <ConfirmItem label="Receiver">
142
- <Text color="primaryText" size="sm">
143
- {ensName.data || shortenAddress(receiver)}
144
- </Text>
145
- </ConfirmItem>
146
- )}
92
+ <SwapSummary
93
+ sender={sender}
94
+ receiver={receiver}
95
+ client={props.client}
96
+ fromToken={props.fromToken}
97
+ fromChain={props.fromChain}
98
+ toToken={props.toToken}
99
+ toChain={props.toChain}
100
+ fromAmount={props.fromAmount}
101
+ toAmount={props.toAmount}
102
+ />
147
103
 
148
- <Spacer y="xl" />
104
+ <Spacer y="md" />
149
105
 
150
106
  {/* Show 2 steps - Approve and confirm */}
151
107
  {needsApprovalStep && (
@@ -348,100 +304,3 @@ export const ConnectorLine = /* @__PURE__ */ StyledDiv(() => {
348
304
  flex: 1,
349
305
  };
350
306
  });
351
-
352
- function RenderTokenInfo(props: {
353
- chain: Chain;
354
- token: ERC20OrNativeToken;
355
- amount: string;
356
- symbol: string;
357
- client: ThirdwebClient;
358
- }) {
359
- const { name } = useChainName(props.chain);
360
- return (
361
- <Container
362
- flex="column"
363
- gap="xxs"
364
- style={{
365
- alignItems: "flex-end",
366
- }}
367
- >
368
- <Container flex="row" center="y" gap="xs">
369
- <Text color="primaryText" size="sm">
370
- {props.amount} {props.symbol}
371
- </Text>
372
- <PayTokenIcon
373
- token={props.token}
374
- chain={props.chain}
375
- size="xs"
376
- client={props.client}
377
- />
378
- </Container>
379
-
380
- {name ? (
381
- <Text size="xs">{name}</Text>
382
- ) : (
383
- <Skeleton width="100px" height={fontSize.xs} />
384
- )}
385
- </Container>
386
- );
387
- }
388
-
389
- function ConfirmItem(props: {
390
- label: string;
391
- children: React.ReactNode;
392
- }) {
393
- return (
394
- <>
395
- <Container
396
- flex="row"
397
- gap="md"
398
- py="md"
399
- style={{
400
- justifyContent: "space-between",
401
- }}
402
- >
403
- <Text size="sm" color="secondaryText">
404
- {props.label}
405
- </Text>
406
- {props.children}
407
- </Container>
408
- <Line />
409
- </>
410
- );
411
- }
412
-
413
- /**
414
- * @internal
415
- */
416
- function SwapFeesRightAligned(props: {
417
- quote: BuyWithCryptoQuote;
418
- }) {
419
- return (
420
- <Container
421
- flex="column"
422
- gap="xs"
423
- style={{
424
- alignItems: "flex-end",
425
- }}
426
- >
427
- {props.quote.processingFees.map((fee) => {
428
- const feeAmount = formatNumber(Number(fee.amount), 6);
429
- return (
430
- <Container
431
- key={`${fee.token.chainId}_${fee.token.tokenAddress}_${feeAmount}`}
432
- flex="row"
433
- gap="xxs"
434
- >
435
- <Text color="primaryText" size="sm">
436
- {feeAmount === 0 ? "~" : ""}
437
- {feeAmount} {fee.token.symbol}
438
- </Text>
439
- <Text color="secondaryText" size="sm">
440
- (${(fee.amountUSDCents / 100).toFixed(2)})
441
- </Text>
442
- </Container>
443
- );
444
- })}
445
- </Container>
446
- );
447
- }
@@ -16,7 +16,7 @@ import { TokenRow } from "../../../../components/token/TokenRow.js";
16
16
  import { TokenSymbol } from "../../../../components/token/TokenSymbol.js";
17
17
  import { formatTokenBalance } from "../../formatTokenBalance.js";
18
18
  import { type NativeToken, isNativeToken } from "../../nativeToken.js";
19
- import { WalletRow } from "./TokenSelectorScreen.js";
19
+ import { WalletRow } from "./WalletRow.js";
20
20
 
21
21
  /**
22
22
  * Shows an amount "value" and renders the selected token and chain
@@ -26,8 +26,8 @@ import { WalletRow } from "./TokenSelectorScreen.js";
26
26
  */
27
27
  export function PayWithCryptoQuoteInfo(props: {
28
28
  value: string;
29
- chain: Chain;
30
- token: TokenInfo | NativeToken;
29
+ chain: Chain | undefined;
30
+ token: TokenInfo | NativeToken | undefined;
31
31
  isLoading: boolean;
32
32
  client: ThirdwebClient;
33
33
  freezeChainAndTokenSelection?: boolean;
@@ -36,12 +36,19 @@ export function PayWithCryptoQuoteInfo(props: {
36
36
  onSelectToken: () => void;
37
37
  }) {
38
38
  const theme = useCustomTheme();
39
- const balanceQuery = useWalletBalance({
40
- address: props.payerAccount.address,
41
- chain: props.chain,
42
- tokenAddress: isNativeToken(props.token) ? undefined : props.token.address,
43
- client: props.client,
44
- });
39
+ const balanceQuery = useWalletBalance(
40
+ {
41
+ address: props.payerAccount.address,
42
+ chain: props.chain,
43
+ tokenAddress: isNativeToken(props.token)
44
+ ? undefined
45
+ : props.token?.address,
46
+ client: props.client,
47
+ },
48
+ {
49
+ enabled: !!props.chain && !!props.token,
50
+ },
51
+ );
45
52
 
46
53
  return (
47
54
  <Container
@@ -69,10 +76,10 @@ export function PayWithCryptoQuoteInfo(props: {
69
76
  }}
70
77
  >
71
78
  <WalletRow client={props.client} address={props.payerAccount.address} />
72
- {balanceQuery.data ? (
79
+ {props.token && props.chain && balanceQuery.data ? (
73
80
  <Container flex="row" gap="3xs" center="y">
74
81
  <Text size="xs" color="secondaryText" weight={500}>
75
- {formatTokenBalance(balanceQuery.data, false)}
82
+ {formatTokenBalance(balanceQuery.data, false, 4)}
76
83
  </Text>
77
84
  <TokenSymbol
78
85
  token={props.token}
@@ -81,11 +88,11 @@ export function PayWithCryptoQuoteInfo(props: {
81
88
  color="secondaryText"
82
89
  />
83
90
  </Container>
84
- ) : (
91
+ ) : props.token && props.chain && balanceQuery.isLoading ? (
85
92
  <Skeleton width="70px" height={fontSize.xs} />
86
- )}
93
+ ) : null}
87
94
  </Container>
88
- {/* Quoted price */}
95
+ {/* Quoted price & token selector */}
89
96
  <TokenRow
90
97
  token={props.token}
91
98
  chain={props.chain}
@@ -96,6 +103,10 @@ export function PayWithCryptoQuoteInfo(props: {
96
103
  style={{
97
104
  border: "none",
98
105
  borderRadius: 0,
106
+ borderBottomLeftRadius:
107
+ !props.token || !props.chain || !props.swapRequired ? radius.lg : 0,
108
+ borderBottomRightRadius:
109
+ !props.token || !props.chain || !props.swapRequired ? radius.lg : 0,
99
110
  }}
100
111
  />
101
112
  </Container>
@@ -42,8 +42,8 @@ export function SwapScreenContent(props: {
42
42
  tokenAmount: string;
43
43
  toToken: ERC20OrNativeToken;
44
44
  toChain: Chain;
45
- fromChain: Chain;
46
- fromToken: ERC20OrNativeToken;
45
+ fromChain: Chain | undefined;
46
+ fromToken: ERC20OrNativeToken | undefined;
47
47
  showFromTokenSelector: () => void;
48
48
  payer: PayerInfo;
49
49
  client: ThirdwebClient;
@@ -81,42 +81,50 @@ export function SwapScreenContent(props: {
81
81
  "fees" | "receiver" | "payer"
82
82
  >("fees");
83
83
 
84
- const fromTokenBalanceQuery = useWalletBalance({
85
- address: payer.account.address,
86
- chain: fromChain,
87
- tokenAddress: isNativeToken(fromToken) ? undefined : fromToken.address,
88
- client,
89
- });
84
+ const fromTokenBalanceQuery = useWalletBalance(
85
+ {
86
+ address: payer.account.address,
87
+ chain: fromChain,
88
+ tokenAddress: isNativeToken(fromToken) ? undefined : fromToken?.address,
89
+ client,
90
+ },
91
+ {
92
+ enabled: !!fromChain && !!fromToken,
93
+ },
94
+ );
90
95
 
91
96
  const fromTokenId = isNativeToken(fromToken)
92
97
  ? NATIVE_TOKEN_ADDRESS
93
- : fromToken.address.toLowerCase();
98
+ : fromToken?.address?.toLowerCase();
94
99
  const toTokenId = isNativeToken(toToken)
95
100
  ? NATIVE_TOKEN_ADDRESS
96
101
  : toToken.address.toLowerCase();
97
102
  const swapRequired =
98
103
  !!tokenAmount &&
99
- !(fromChain.id === toChain.id && fromTokenId === toTokenId);
100
- const quoteParams: GetBuyWithCryptoQuoteParams | undefined = swapRequired
101
- ? {
102
- // wallets
103
- fromAddress: payer.account.address,
104
- toAddress: receiverAddress,
105
- // from
106
- fromChainId: fromChain.id,
107
- fromTokenAddress: isNativeToken(fromToken)
108
- ? NATIVE_TOKEN_ADDRESS
109
- : fromToken.address,
110
- // to
111
- toChainId: toChain.id,
112
- toTokenAddress: isNativeToken(toToken)
113
- ? NATIVE_TOKEN_ADDRESS
114
- : toToken.address,
115
- toAmount: tokenAmount,
116
- client,
117
- purchaseData: payOptions.purchaseData,
118
- }
119
- : undefined;
104
+ !!fromChain &&
105
+ !!fromTokenId &&
106
+ !(fromChain?.id === toChain.id && fromTokenId === toTokenId);
107
+ const quoteParams: GetBuyWithCryptoQuoteParams | undefined =
108
+ fromChain && fromToken && swapRequired
109
+ ? {
110
+ // wallets
111
+ fromAddress: payer.account.address,
112
+ toAddress: receiverAddress,
113
+ // from
114
+ fromChainId: fromChain.id,
115
+ fromTokenAddress: isNativeToken(fromToken)
116
+ ? NATIVE_TOKEN_ADDRESS
117
+ : fromToken.address,
118
+ // to
119
+ toChainId: toChain.id,
120
+ toTokenAddress: isNativeToken(toToken)
121
+ ? NATIVE_TOKEN_ADDRESS
122
+ : toToken.address,
123
+ toAmount: tokenAmount,
124
+ client,
125
+ purchaseData: payOptions.purchaseData,
126
+ }
127
+ : undefined;
120
128
 
121
129
  const quoteQuery = useBuyWithCryptoQuote(quoteParams, {
122
130
  // refetch every 30 seconds
@@ -159,11 +167,13 @@ export function SwapScreenContent(props: {
159
167
  Number(fromTokenBalanceQuery.data.displayValue) < Number(sourceTokenAmount);
160
168
 
161
169
  const disableContinue =
170
+ !fromChain ||
171
+ !fromToken ||
162
172
  (swapRequired && !quoteQuery.data) ||
163
173
  isNotEnoughBalance ||
164
174
  allowanceQuery.isLoading;
165
175
  const switchChainRequired =
166
- props.payer.wallet.getChain()?.id !== fromChain.id;
176
+ props.payer.wallet.getChain()?.id !== fromChain?.id;
167
177
 
168
178
  const errorMsg =
169
179
  !quoteQuery.isLoading && quoteQuery.error
@@ -240,6 +250,19 @@ export function SwapScreenContent(props: {
240
250
 
241
251
  {/* Quote info */}
242
252
  <Container flex="column" gap="sm">
253
+ <Container flex="row" gap="xxs" center="y">
254
+ <Text size="sm">Pay with</Text>
255
+ {fromToken && fromChain ? (
256
+ <TokenSymbol
257
+ token={fromToken}
258
+ chain={fromChain}
259
+ size="sm"
260
+ color="secondaryText"
261
+ />
262
+ ) : (
263
+ "crypto"
264
+ )}
265
+ </Container>
243
266
  <div>
244
267
  <PayWithCryptoQuoteInfo
245
268
  value={sourceTokenAmount || ""}
@@ -252,7 +275,7 @@ export function SwapScreenContent(props: {
252
275
  swapRequired={swapRequired}
253
276
  onSelectToken={props.showFromTokenSelector}
254
277
  />
255
- {swapRequired && (
278
+ {swapRequired && fromChain && fromToken && (
256
279
  <EstimatedTimeAndFees
257
280
  quoteIsLoading={quoteQuery.isLoading}
258
281
  estimatedSeconds={
@@ -288,7 +311,7 @@ export function SwapScreenContent(props: {
288
311
  {!errorMsg && isNotEnoughBalance && (
289
312
  <div>
290
313
  <Text color="danger" size="xs" center multiline>
291
- Not enough funds.
314
+ Insufficient funds
292
315
  </Text>
293
316
  </div>
294
317
  )}
@@ -317,9 +340,10 @@ export function SwapScreenContent(props: {
317
340
  fullWidth
318
341
  onClick={() => props.showFromTokenSelector()}
319
342
  >
320
- Select another token
343
+ Pay with another token
321
344
  </Button>
322
345
  ) : switchChainRequired &&
346
+ fromChain &&
323
347
  !quoteQuery.isLoading &&
324
348
  !allowanceQuery.isLoading &&
325
349
  !isNotEnoughBalance &&
@@ -0,0 +1,134 @@
1
+ import { ChevronDownIcon } from "@radix-ui/react-icons";
2
+ import type { Chain } from "../../../../../../../chains/types.js";
3
+ import type { ThirdwebClient } from "../../../../../../../client/client.js";
4
+ import { useCustomTheme } from "../../../../../../core/design-system/CustomThemeProvider.js";
5
+ import {
6
+ iconSize,
7
+ radius,
8
+ } from "../../../../../../core/design-system/index.js";
9
+ import { Container } from "../../../../components/basic.js";
10
+ import { TokenRow } from "../../../../components/token/TokenRow.js";
11
+ import type { ERC20OrNativeToken } from "../../nativeToken.js";
12
+ import { WalletRow } from "./WalletRow.js";
13
+
14
+ export function SwapSummary(props: {
15
+ sender: string;
16
+ receiver: string;
17
+ client: ThirdwebClient;
18
+ fromToken: ERC20OrNativeToken;
19
+ fromChain: Chain;
20
+ toToken: ERC20OrNativeToken;
21
+ toChain: Chain;
22
+ fromAmount: string;
23
+ toAmount: string;
24
+ }) {
25
+ const theme = useCustomTheme();
26
+ const isDifferentRecipient =
27
+ props.receiver.toLowerCase() !== props.sender.toLowerCase();
28
+ return (
29
+ <Container>
30
+ {/* Sell */}
31
+ <Container
32
+ bg="tertiaryBg"
33
+ flex="column"
34
+ style={{
35
+ borderRadius: radius.lg,
36
+ border: `1px solid ${theme.colors.borderColor}`,
37
+ }}
38
+ >
39
+ {isDifferentRecipient && (
40
+ <Container
41
+ flex="row"
42
+ gap="sm"
43
+ p="sm"
44
+ style={{
45
+ borderBottom: `1px solid ${theme.colors.borderColor}`,
46
+ }}
47
+ >
48
+ <WalletRow
49
+ address={props.sender}
50
+ client={props.client}
51
+ iconSize="md"
52
+ textSize="sm"
53
+ />
54
+ </Container>
55
+ )}
56
+ <TokenRow
57
+ token={props.fromToken}
58
+ chain={props.fromChain}
59
+ client={props.client}
60
+ isLoading={false}
61
+ value={props.fromAmount}
62
+ freezeChainAndToken={true}
63
+ onSelectToken={() => {}}
64
+ style={{
65
+ background: "transparent",
66
+ borderRadius: 0,
67
+ border: "none",
68
+ }}
69
+ />
70
+ </Container>
71
+ {/* Connector Icon */}
72
+ <Container flex="row" center="both" py="xxs">
73
+ <Container flex="column" center="both">
74
+ <ChevronDownIcon
75
+ width={iconSize.md}
76
+ height={iconSize.md}
77
+ style={{
78
+ color: theme.colors.secondaryIconColor,
79
+ }}
80
+ />
81
+ <ChevronDownIcon
82
+ width={iconSize.md}
83
+ height={iconSize.md}
84
+ style={{
85
+ color: theme.colors.secondaryIconColor,
86
+ marginTop: "-17px",
87
+ }}
88
+ />
89
+ </Container>
90
+ </Container>
91
+ {/* Buy */}
92
+ <Container
93
+ flex="column"
94
+ bg="tertiaryBg"
95
+ style={{
96
+ borderRadius: radius.lg,
97
+ border: `1px solid ${theme.colors.borderColor}`,
98
+ }}
99
+ >
100
+ {isDifferentRecipient && (
101
+ <Container
102
+ flex="row"
103
+ gap="sm"
104
+ p="sm"
105
+ style={{
106
+ borderBottom: `1px solid ${theme.colors.borderColor}`,
107
+ }}
108
+ >
109
+ <WalletRow
110
+ address={props.receiver}
111
+ client={props.client}
112
+ iconSize="md"
113
+ textSize="sm"
114
+ />
115
+ </Container>
116
+ )}
117
+ <TokenRow
118
+ token={props.toToken}
119
+ chain={props.toChain}
120
+ client={props.client}
121
+ isLoading={false}
122
+ value={props.toAmount}
123
+ freezeChainAndToken={true}
124
+ onSelectToken={() => {}}
125
+ style={{
126
+ background: "transparent",
127
+ borderRadius: 0,
128
+ border: "none",
129
+ }}
130
+ />
131
+ </Container>
132
+ </Container>
133
+ );
134
+ }