thirdweb 5.88.5-nightly-52cbcd2d57abf4d69ee417fe98fca815e19f2f34-20250216000400 → 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 (117) hide show
  1. package/dist/cjs/adapters/eip1193/to-eip1193.js +16 -0
  2. package/dist/cjs/adapters/eip1193/to-eip1193.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/version.js +1 -1
  34. package/dist/cjs/version.js.map +1 -1
  35. package/dist/cjs/wallets/connection/autoConnect.js +3 -4
  36. package/dist/cjs/wallets/connection/autoConnect.js.map +1 -1
  37. package/dist/esm/adapters/eip1193/to-eip1193.js +16 -0
  38. package/dist/esm/adapters/eip1193/to-eip1193.js.map +1 -1
  39. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js +55 -73
  40. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js.map +1 -1
  41. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js +1 -1
  42. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js.map +1 -1
  43. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js +1 -1
  44. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js.map +1 -1
  45. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.js +1 -1
  46. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.js.map +1 -1
  47. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.js +4 -14
  48. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.js.map +1 -1
  49. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js +4 -34
  50. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js.map +1 -1
  51. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js +9 -3
  52. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js.map +1 -1
  53. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js +15 -8
  54. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js.map +1 -1
  55. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.js +36 -0
  56. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.js.map +1 -0
  57. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js +59 -53
  58. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js.map +1 -1
  59. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js +4 -11
  60. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js.map +1 -1
  61. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.js +32 -0
  62. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.js.map +1 -0
  63. package/dist/esm/react/web/ui/ConnectWallet/screens/TokenSelector.js +1 -2
  64. package/dist/esm/react/web/ui/ConnectWallet/screens/TokenSelector.js.map +1 -1
  65. package/dist/esm/react/web/ui/ConnectWallet/screens/nativeToken.js +4 -2
  66. package/dist/esm/react/web/ui/ConnectWallet/screens/nativeToken.js.map +1 -1
  67. package/dist/esm/react/web/ui/components/token/TokenRow.js +11 -4
  68. package/dist/esm/react/web/ui/components/token/TokenRow.js.map +1 -1
  69. package/dist/esm/version.js +1 -1
  70. package/dist/esm/version.js.map +1 -1
  71. package/dist/esm/wallets/connection/autoConnect.js +2 -2
  72. package/dist/esm/wallets/connection/autoConnect.js.map +1 -1
  73. package/dist/types/adapters/eip1193/to-eip1193.d.ts.map +1 -1
  74. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.d.ts.map +1 -1
  75. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.d.ts.map +1 -1
  76. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.d.ts +2 -2
  77. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.d.ts.map +1 -1
  78. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.d.ts.map +1 -1
  79. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.d.ts +2 -2
  80. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.d.ts.map +1 -1
  81. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.d.ts +2 -2
  82. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.d.ts.map +1 -1
  83. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.d.ts +15 -0
  84. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.d.ts.map +1 -0
  85. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.d.ts +2 -16
  86. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.d.ts.map +1 -1
  87. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.d.ts.map +1 -1
  88. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.d.ts +9 -0
  89. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.d.ts.map +1 -0
  90. package/dist/types/react/web/ui/ConnectWallet/screens/TokenSelector.d.ts.map +1 -1
  91. package/dist/types/react/web/ui/ConnectWallet/screens/nativeToken.d.ts +1 -1
  92. package/dist/types/react/web/ui/ConnectWallet/screens/nativeToken.d.ts.map +1 -1
  93. package/dist/types/react/web/ui/components/token/TokenRow.d.ts +2 -2
  94. package/dist/types/react/web/ui/components/token/TokenRow.d.ts.map +1 -1
  95. package/dist/types/version.d.ts +1 -1
  96. package/dist/types/version.d.ts.map +1 -1
  97. package/dist/types/wallets/connection/autoConnect.d.ts +2 -2
  98. package/dist/types/wallets/connection/autoConnect.d.ts.map +1 -1
  99. package/package.json +1 -1
  100. package/src/adapters/eip1193/to-eip1193.ts +18 -0
  101. package/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx +70 -157
  102. package/src/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.tsx +1 -1
  103. package/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.tsx +1 -0
  104. package/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.tsx +1 -1
  105. package/src/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.ts +4 -18
  106. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.tsx +20 -161
  107. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.tsx +25 -14
  108. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.tsx +58 -34
  109. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapSummary.tsx +134 -0
  110. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.tsx +134 -128
  111. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.tsx +18 -48
  112. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx +70 -0
  113. package/src/react/web/ui/ConnectWallet/screens/TokenSelector.tsx +1 -3
  114. package/src/react/web/ui/ConnectWallet/screens/nativeToken.ts +5 -3
  115. package/src/react/web/ui/components/token/TokenRow.tsx +38 -14
  116. package/src/version.ts +1 -1
  117. package/src/wallets/connection/autoConnect.ts +3 -3
@@ -62,7 +62,7 @@ export function OnRampTxDetailsTable(props: {
62
62
  justifyContent: "space-between",
63
63
  }}
64
64
  >
65
- <Text>Pay</Text>
65
+ <Text size="sm">Pay</Text>
66
66
  <Container
67
67
  flex="column"
68
68
  gap="xxs"
@@ -76,14 +76,9 @@ export function useFromTokenSelectionStates(options: {
76
76
  payOptions: PayUIOptions;
77
77
  supportedSources: SupportedSourcesInputData[];
78
78
  }) {
79
- const { payOptions, supportedSources } = options;
79
+ const { payOptions } = options;
80
80
 
81
- // --------------------------------------------------------------------------
82
- const firstSupportedSource = supportedSources?.length
83
- ? supportedSources.length === 1
84
- ? supportedSources[0]
85
- : supportedSources.find((x) => x.chain.id !== 1) // dont use mainnet as a default source, unless its the only source
86
- : undefined;
81
+ // TODO (pay) - auto select token based on connected wallet balances
87
82
 
88
83
  // Source token and chain selection ---------------------------------------------------
89
84
  const [fromChain_, setFromChain] = useState<Chain>();
@@ -95,12 +90,7 @@ export function useFromTokenSelectionStates(options: {
95
90
  (payOptions.mode === "transaction" && payOptions.transaction?.chain) ||
96
91
  (payOptions.mode === "direct_payment" && payOptions.paymentInfo?.chain);
97
92
 
98
- const fromChainFromApi = firstSupportedSource?.chain
99
- ? firstSupportedSource.chain
100
- : undefined;
101
-
102
- const fromChain =
103
- fromChain_ || fromChainDevSpecified || fromChainFromApi || polygon;
93
+ const fromChain = fromChain_ || fromChainDevSpecified || undefined;
104
94
 
105
95
  const [fromToken_, setFromToken] = useState<ERC20OrNativeToken>();
106
96
 
@@ -110,12 +100,8 @@ export function useFromTokenSelectionStates(options: {
110
100
  payOptions.buyWithCrypto?.prefillSource?.token) ||
111
101
  (payOptions.mode === "direct_payment" && payOptions.paymentInfo.token);
112
102
 
113
- // May be updated in the future
114
- const fromTokenFromApi = NATIVE_TOKEN;
115
-
116
103
  // supported tokens query in here
117
- const fromToken =
118
- fromToken_ || fromTokenDevSpecified || fromTokenFromApi || NATIVE_TOKEN;
104
+ const fromToken = fromToken_ || fromTokenDevSpecified || undefined;
119
105
 
120
106
  return {
121
107
  fromChain,
@@ -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
+ }