thirdweb 5.116.2-nightly-7ebc32a0c4e3fa71167255ee5a517143c3ea3a0a-20251218000730 → 5.117.0-nightly-9c04b3f18042b162de24cb7cf5c296a38a9af4f0-20251220000345

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 (155) hide show
  1. package/dist/cjs/bridge/Chains.js +15 -1
  2. package/dist/cjs/bridge/Chains.js.map +1 -1
  3. package/dist/cjs/react/web/ui/Bridge/DirectPayment.js +1 -2
  4. package/dist/cjs/react/web/ui/Bridge/DirectPayment.js.map +1 -1
  5. package/dist/cjs/react/web/ui/Bridge/FundWallet.js +15 -4
  6. package/dist/cjs/react/web/ui/Bridge/FundWallet.js.map +1 -1
  7. package/dist/cjs/react/web/ui/Bridge/TransactionPayment.js +6 -1
  8. package/dist/cjs/react/web/ui/Bridge/TransactionPayment.js.map +1 -1
  9. package/dist/cjs/react/web/ui/Bridge/common/TokenBalanceRow.js +1 -1
  10. package/dist/cjs/react/web/ui/Bridge/payment-details/PaymentDetails.js +12 -12
  11. package/dist/cjs/react/web/ui/Bridge/payment-details/PaymentDetails.js.map +1 -1
  12. package/dist/cjs/react/web/ui/Bridge/payment-details/PaymentOverview.js +7 -7
  13. package/dist/cjs/react/web/ui/Bridge/payment-details/PaymentOverview.js.map +1 -1
  14. package/dist/cjs/react/web/ui/Bridge/swap-widget/SwapWidget.js +1 -1
  15. package/dist/cjs/react/web/ui/Bridge/swap-widget/SwapWidget.js.map +1 -1
  16. package/dist/cjs/react/web/ui/Bridge/swap-widget/select-chain.js +13 -5
  17. package/dist/cjs/react/web/ui/Bridge/swap-widget/select-chain.js.map +1 -1
  18. package/dist/cjs/react/web/ui/Bridge/swap-widget/select-token-ui.js +9 -7
  19. package/dist/cjs/react/web/ui/Bridge/swap-widget/select-token-ui.js.map +1 -1
  20. package/dist/cjs/react/web/ui/Bridge/swap-widget/swap-ui.js +35 -10
  21. package/dist/cjs/react/web/ui/Bridge/swap-widget/swap-ui.js.map +1 -1
  22. package/dist/cjs/react/web/ui/Bridge/swap-widget/use-bridge-chains.js +38 -3
  23. package/dist/cjs/react/web/ui/Bridge/swap-widget/use-bridge-chains.js.map +1 -1
  24. package/dist/cjs/react/web/ui/ConnectWallet/constants.js +1 -1
  25. package/dist/cjs/react/web/ui/ConnectWallet/icons/OutlineWalletIcon.js +1 -1
  26. package/dist/cjs/react/web/ui/ConnectWallet/icons/OutlineWalletIcon.js.map +1 -1
  27. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/StepConnector.js +7 -7
  28. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/StepConnector.js.map +1 -1
  29. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.js +11 -1
  30. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.js.map +1 -1
  31. package/dist/cjs/react/web/ui/ConnectWallet/screens/WalletSwitcherConnectionScreen.js +0 -1
  32. package/dist/cjs/react/web/ui/ConnectWallet/screens/WalletSwitcherConnectionScreen.js.map +1 -1
  33. package/dist/cjs/stories/Bridge/BridgeWidget/bridge-widget.stories.js +55 -0
  34. package/dist/cjs/stories/Bridge/BridgeWidget/bridge-widget.stories.js.map +1 -0
  35. package/dist/cjs/stories/Bridge/PaymentDetails.stories.js +14 -7
  36. package/dist/cjs/stories/Bridge/PaymentDetails.stories.js.map +1 -1
  37. package/dist/cjs/stories/Bridge/Swap/SelectChain.stories.js +16 -4
  38. package/dist/cjs/stories/Bridge/Swap/SelectChain.stories.js.map +1 -1
  39. package/dist/cjs/stories/Bridge/Swap/SwapWidget.stories.js +7 -0
  40. package/dist/cjs/stories/Bridge/Swap/SwapWidget.stories.js.map +1 -1
  41. package/dist/cjs/stories/Bridge/Transaction/TransactionWidget.stories.js +10 -1
  42. package/dist/cjs/stories/Bridge/Transaction/TransactionWidget.stories.js.map +1 -1
  43. package/dist/cjs/stories/BuyWidget.stories.js +7 -0
  44. package/dist/cjs/stories/BuyWidget.stories.js.map +1 -1
  45. package/dist/cjs/version.js +1 -1
  46. package/dist/cjs/wallets/defaultWallets.js +18 -0
  47. package/dist/cjs/wallets/defaultWallets.js.map +1 -1
  48. package/dist/esm/bridge/Chains.js +15 -1
  49. package/dist/esm/bridge/Chains.js.map +1 -1
  50. package/dist/esm/react/web/ui/Bridge/DirectPayment.js +1 -2
  51. package/dist/esm/react/web/ui/Bridge/DirectPayment.js.map +1 -1
  52. package/dist/esm/react/web/ui/Bridge/FundWallet.js +16 -5
  53. package/dist/esm/react/web/ui/Bridge/FundWallet.js.map +1 -1
  54. package/dist/esm/react/web/ui/Bridge/TransactionPayment.js +6 -1
  55. package/dist/esm/react/web/ui/Bridge/TransactionPayment.js.map +1 -1
  56. package/dist/esm/react/web/ui/Bridge/common/TokenBalanceRow.js +1 -1
  57. package/dist/esm/react/web/ui/Bridge/payment-details/PaymentDetails.js +13 -13
  58. package/dist/esm/react/web/ui/Bridge/payment-details/PaymentDetails.js.map +1 -1
  59. package/dist/esm/react/web/ui/Bridge/payment-details/PaymentOverview.js +7 -7
  60. package/dist/esm/react/web/ui/Bridge/payment-details/PaymentOverview.js.map +1 -1
  61. package/dist/esm/react/web/ui/Bridge/swap-widget/SwapWidget.js +1 -1
  62. package/dist/esm/react/web/ui/Bridge/swap-widget/SwapWidget.js.map +1 -1
  63. package/dist/esm/react/web/ui/Bridge/swap-widget/select-chain.js +14 -6
  64. package/dist/esm/react/web/ui/Bridge/swap-widget/select-chain.js.map +1 -1
  65. package/dist/esm/react/web/ui/Bridge/swap-widget/select-token-ui.js +10 -8
  66. package/dist/esm/react/web/ui/Bridge/swap-widget/select-token-ui.js.map +1 -1
  67. package/dist/esm/react/web/ui/Bridge/swap-widget/swap-ui.js +36 -11
  68. package/dist/esm/react/web/ui/Bridge/swap-widget/swap-ui.js.map +1 -1
  69. package/dist/esm/react/web/ui/Bridge/swap-widget/use-bridge-chains.js +36 -3
  70. package/dist/esm/react/web/ui/Bridge/swap-widget/use-bridge-chains.js.map +1 -1
  71. package/dist/esm/react/web/ui/ConnectWallet/constants.js +1 -1
  72. package/dist/esm/react/web/ui/ConnectWallet/icons/OutlineWalletIcon.js +1 -1
  73. package/dist/esm/react/web/ui/ConnectWallet/icons/OutlineWalletIcon.js.map +1 -1
  74. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/StepConnector.js +7 -7
  75. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/StepConnector.js.map +1 -1
  76. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.js +12 -2
  77. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.js.map +1 -1
  78. package/dist/esm/react/web/ui/ConnectWallet/screens/WalletSwitcherConnectionScreen.js +0 -1
  79. package/dist/esm/react/web/ui/ConnectWallet/screens/WalletSwitcherConnectionScreen.js.map +1 -1
  80. package/dist/esm/stories/Bridge/BridgeWidget/bridge-widget.stories.js +48 -0
  81. package/dist/esm/stories/Bridge/BridgeWidget/bridge-widget.stories.js.map +1 -0
  82. package/dist/esm/stories/Bridge/PaymentDetails.stories.js +14 -7
  83. package/dist/esm/stories/Bridge/PaymentDetails.stories.js.map +1 -1
  84. package/dist/esm/stories/Bridge/Swap/SelectChain.stories.js +16 -4
  85. package/dist/esm/stories/Bridge/Swap/SelectChain.stories.js.map +1 -1
  86. package/dist/esm/stories/Bridge/Swap/SwapWidget.stories.js +6 -0
  87. package/dist/esm/stories/Bridge/Swap/SwapWidget.stories.js.map +1 -1
  88. package/dist/esm/stories/Bridge/Transaction/TransactionWidget.stories.js +9 -0
  89. package/dist/esm/stories/Bridge/Transaction/TransactionWidget.stories.js.map +1 -1
  90. package/dist/esm/stories/BuyWidget.stories.js +6 -0
  91. package/dist/esm/stories/BuyWidget.stories.js.map +1 -1
  92. package/dist/esm/version.js +1 -1
  93. package/dist/esm/wallets/defaultWallets.js +17 -0
  94. package/dist/esm/wallets/defaultWallets.js.map +1 -1
  95. package/dist/scripts/bridge-widget.js +83 -83
  96. package/dist/types/bridge/Chains.d.ts +21 -1
  97. package/dist/types/bridge/Chains.d.ts.map +1 -1
  98. package/dist/types/react/web/ui/Bridge/DirectPayment.d.ts.map +1 -1
  99. package/dist/types/react/web/ui/Bridge/FundWallet.d.ts.map +1 -1
  100. package/dist/types/react/web/ui/Bridge/TransactionPayment.d.ts.map +1 -1
  101. package/dist/types/react/web/ui/Bridge/payment-details/PaymentDetails.d.ts.map +1 -1
  102. package/dist/types/react/web/ui/Bridge/swap-widget/select-chain.d.ts +5 -0
  103. package/dist/types/react/web/ui/Bridge/swap-widget/select-chain.d.ts.map +1 -1
  104. package/dist/types/react/web/ui/Bridge/swap-widget/select-token-ui.d.ts +5 -0
  105. package/dist/types/react/web/ui/Bridge/swap-widget/select-token-ui.d.ts.map +1 -1
  106. package/dist/types/react/web/ui/Bridge/swap-widget/swap-ui.d.ts.map +1 -1
  107. package/dist/types/react/web/ui/Bridge/swap-widget/use-bridge-chains.d.ts +21 -1
  108. package/dist/types/react/web/ui/Bridge/swap-widget/use-bridge-chains.d.ts.map +1 -1
  109. package/dist/types/react/web/ui/ConnectWallet/icons/OutlineWalletIcon.d.ts +5 -2
  110. package/dist/types/react/web/ui/ConnectWallet/icons/OutlineWalletIcon.d.ts.map +1 -1
  111. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/StepConnector.d.ts.map +1 -1
  112. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.d.ts.map +1 -1
  113. package/dist/types/react/web/ui/ConnectWallet/screens/WalletSwitcherConnectionScreen.d.ts.map +1 -1
  114. package/dist/types/stories/Bridge/BridgeWidget/bridge-widget.stories.d.ts +10 -0
  115. package/dist/types/stories/Bridge/BridgeWidget/bridge-widget.stories.d.ts.map +1 -0
  116. package/dist/types/stories/Bridge/PaymentDetails.stories.d.ts.map +1 -1
  117. package/dist/types/stories/Bridge/Swap/SelectChain.stories.d.ts.map +1 -1
  118. package/dist/types/stories/Bridge/Swap/SwapWidget.stories.d.ts +1 -0
  119. package/dist/types/stories/Bridge/Swap/SwapWidget.stories.d.ts.map +1 -1
  120. package/dist/types/stories/Bridge/Transaction/TransactionWidget.stories.d.ts +1 -0
  121. package/dist/types/stories/Bridge/Transaction/TransactionWidget.stories.d.ts.map +1 -1
  122. package/dist/types/stories/BuyWidget.stories.d.ts +1 -0
  123. package/dist/types/stories/BuyWidget.stories.d.ts.map +1 -1
  124. package/dist/types/version.d.ts +1 -1
  125. package/dist/types/wallets/defaultWallets.d.ts +8 -0
  126. package/dist/types/wallets/defaultWallets.d.ts.map +1 -1
  127. package/package.json +1 -1
  128. package/src/bridge/Chains.ts +46 -3
  129. package/src/react/web/ui/Bridge/DirectPayment.tsx +1 -22
  130. package/src/react/web/ui/Bridge/FundWallet.tsx +19 -6
  131. package/src/react/web/ui/Bridge/TransactionPayment.tsx +8 -0
  132. package/src/react/web/ui/Bridge/common/TokenBalanceRow.tsx +1 -1
  133. package/src/react/web/ui/Bridge/payment-details/PaymentDetails.tsx +24 -15
  134. package/src/react/web/ui/Bridge/payment-details/PaymentOverview.tsx +7 -7
  135. package/src/react/web/ui/Bridge/swap-widget/SwapWidget.tsx +1 -1
  136. package/src/react/web/ui/Bridge/swap-widget/select-chain.tsx +23 -7
  137. package/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx +27 -7
  138. package/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx +48 -9
  139. package/src/react/web/ui/Bridge/swap-widget/use-bridge-chains.ts +52 -3
  140. package/src/react/web/ui/ConnectWallet/constants.ts +1 -1
  141. package/src/react/web/ui/ConnectWallet/icons/OutlineWalletIcon.tsx +6 -3
  142. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/StepConnector.tsx +10 -7
  143. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx +22 -1
  144. package/src/react/web/ui/ConnectWallet/screens/WalletSwitcherConnectionScreen.tsx +0 -1
  145. package/src/stories/Bridge/BridgeWidget/bridge-widget.stories.tsx +98 -0
  146. package/src/stories/Bridge/PaymentDetails.stories.tsx +37 -34
  147. package/src/stories/Bridge/Swap/SelectChain.stories.tsx +20 -0
  148. package/src/stories/Bridge/Swap/SwapWidget.stories.tsx +14 -0
  149. package/src/stories/Bridge/Transaction/TransactionWidget.stories.tsx +10 -0
  150. package/src/stories/BuyWidget.stories.tsx +12 -0
  151. package/src/version.ts +1 -1
  152. package/src/wallets/defaultWallets.ts +22 -0
  153. package/src/wallets/smart/smart-wallet-integration-v07.test.ts +3 -3
  154. package/src/wallets/smart/smart-wallet-integration.test.ts +4 -4
  155. package/src/wallets/smart/smart-wallet-modular.test.ts +1 -1
@@ -47,7 +47,7 @@ export function PaymentOverview(props: {
47
47
  flex="column"
48
48
  style={{
49
49
  border: `1px solid ${theme.colors.borderColor}`,
50
- borderRadius: radius.lg,
50
+ borderRadius: radius.xl,
51
51
  }}
52
52
  >
53
53
  {sender && (
@@ -55,9 +55,9 @@ export function PaymentOverview(props: {
55
55
  flex="row"
56
56
  gap="sm"
57
57
  px="md"
58
- py="sm"
58
+ py="md"
59
59
  style={{
60
- borderBottom: `1px solid ${theme.colors.borderColor}`,
60
+ borderBottom: `1px dashed ${theme.colors.borderColor}`,
61
61
  }}
62
62
  >
63
63
  <WalletRow
@@ -88,7 +88,7 @@ export function PaymentOverview(props: {
88
88
  flex="row"
89
89
  gap="sm"
90
90
  px="md"
91
- py="sm"
91
+ py="md"
92
92
  style={{ justifyContent: "space-between" }}
93
93
  >
94
94
  {/* left */}
@@ -122,7 +122,7 @@ export function PaymentOverview(props: {
122
122
  flex="column"
123
123
  style={{
124
124
  border: `1px solid ${theme.colors.borderColor}`,
125
- borderRadius: radius.lg,
125
+ borderRadius: radius.xl,
126
126
  }}
127
127
  >
128
128
  {isDifferentRecipient && (
@@ -130,9 +130,9 @@ export function PaymentOverview(props: {
130
130
  flex="row"
131
131
  gap="sm"
132
132
  px="md"
133
- py="sm"
133
+ py="md"
134
134
  style={{
135
- borderBottom: `1px solid ${theme.colors.borderColor}`,
135
+ borderBottom: `1px dashed ${theme.colors.borderColor}`,
136
136
  }}
137
137
  >
138
138
  <WalletRow
@@ -366,7 +366,7 @@ function SwapWidgetContent(
366
366
  }, [buyToken, sellToken, isPersistEnabled]);
367
367
 
368
368
  // preload requests
369
- useBridgeChains(props.client);
369
+ useBridgeChains({ client: props.client });
370
370
 
371
371
  // if wallet suddenly disconnects, show screen 1
372
372
  if (screen.id === "1:swap-ui" || !activeWalletInfo) {
@@ -15,7 +15,7 @@ import { Skeleton } from "../../components/Skeleton.js";
15
15
  import { Spacer } from "../../components/Spacer.js";
16
16
  import { Text } from "../../components/text.js";
17
17
  import { SearchInput } from "./SearchInput.js";
18
- import { useBridgeChains } from "./use-bridge-chains.js";
18
+ import { useBridgeChainsWithFilters } from "./use-bridge-chains.js";
19
19
  import { cleanedChainName } from "./utils.js";
20
20
 
21
21
  type SelectBuyTokenProps = {
@@ -24,13 +24,23 @@ type SelectBuyTokenProps = {
24
24
  onSelectChain: (chain: BridgeChain) => void;
25
25
  selectedChain: BridgeChain | undefined;
26
26
  isMobile: boolean;
27
+ type: "buy" | "sell";
28
+ selections: {
29
+ buyChainId: number | undefined;
30
+ sellChainId: number | undefined;
31
+ };
27
32
  };
28
33
 
29
34
  /**
30
35
  * @internal
31
36
  */
32
37
  export function SelectBridgeChain(props: SelectBuyTokenProps) {
33
- const chainQuery = useBridgeChains(props.client);
38
+ const chainQuery = useBridgeChainsWithFilters({
39
+ client: props.client,
40
+ type: props.type,
41
+ buyChainId: props.selections.buyChainId,
42
+ sellChainId: props.selections.sellChainId,
43
+ });
34
44
 
35
45
  return (
36
46
  <SelectBridgeChainUI
@@ -126,7 +136,7 @@ export function SelectBridgeChainUI(
126
136
  {props.isPending &&
127
137
  new Array(20).fill(0).map(() => (
128
138
  // biome-ignore lint/correctness/useJsxKeyInIterable: ok
129
- <ChainButtonSkeleton />
139
+ <ChainButtonSkeleton isMobile={props.isMobile} />
130
140
  ))}
131
141
 
132
142
  {filteredChains.length === 0 && !props.isPending && (
@@ -148,18 +158,24 @@ export function SelectBridgeChainUI(
148
158
  );
149
159
  }
150
160
 
151
- function ChainButtonSkeleton() {
161
+ function ChainButtonSkeleton(props: { isMobile: boolean }) {
162
+ const iconSizeValue = props.isMobile ? iconSize.lg : iconSize.md;
152
163
  return (
153
164
  <div
154
165
  style={{
155
166
  display: "flex",
156
167
  alignItems: "center",
157
168
  gap: spacing.sm,
158
- padding: `${spacing.sm} ${spacing.sm}`,
169
+ padding: props.isMobile
170
+ ? `${spacing.sm} ${spacing.sm}`
171
+ : `${spacing.xs} ${spacing.xs}`,
159
172
  }}
160
173
  >
161
- <Skeleton height={`${iconSize.lg}px`} width={`${iconSize.lg}px`} />
162
- <Skeleton height={fontSize.md} width="160px" />
174
+ <Skeleton height={`${iconSizeValue}px`} width={`${iconSizeValue}px`} />
175
+ <Skeleton
176
+ height={props.isMobile ? fontSize.md : fontSize.sm}
177
+ width="160px"
178
+ />
163
179
  </div>
164
180
  );
165
181
  }
@@ -26,7 +26,7 @@ import { SearchInput } from "./SearchInput.js";
26
26
  import { SelectChainButton } from "./SelectChainButton.js";
27
27
  import { SelectBridgeChain } from "./select-chain.js";
28
28
  import type { ActiveWalletInfo, TokenSelection } from "./types.js";
29
- import { useBridgeChains } from "./use-bridge-chains.js";
29
+ import { useBridgeChainsWithFilters } from "./use-bridge-chains.js";
30
30
  import {
31
31
  type TokenBalance,
32
32
  useTokenBalances,
@@ -43,6 +43,11 @@ type SelectTokenUIProps = {
43
43
  selectedToken: TokenSelection | undefined;
44
44
  setSelectedToken: (token: TokenSelection) => void;
45
45
  activeWalletInfo: ActiveWalletInfo | undefined;
46
+ type: "buy" | "sell";
47
+ selections: {
48
+ buyChainId: number | undefined;
49
+ sellChainId: number | undefined;
50
+ };
46
51
  };
47
52
 
48
53
  function findChain(chains: BridgeChain[], activeChainId: number | undefined) {
@@ -58,7 +63,13 @@ const INITIAL_LIMIT = 100;
58
63
  * @internal
59
64
  */
60
65
  export function SelectToken(props: SelectTokenUIProps) {
61
- const chainQuery = useBridgeChains(props.client);
66
+ const chainQuery = useBridgeChainsWithFilters({
67
+ client: props.client,
68
+ type: props.type,
69
+ buyChainId: props.selections.buyChainId,
70
+ sellChainId: props.selections.sellChainId,
71
+ });
72
+
62
73
  const [search, _setSearch] = useState("");
63
74
  const debouncedSearch = useDebouncedValue(search, 500);
64
75
  const [limit, setLimit] = useState(INITIAL_LIMIT);
@@ -146,6 +157,11 @@ function SelectTokenUI(
146
157
  selectedToken: TokenSelection | undefined;
147
158
  setSelectedToken: (token: TokenSelection) => void;
148
159
  showMore: (() => void) | undefined;
160
+ type: "buy" | "sell";
161
+ selections: {
162
+ buyChainId: number | undefined;
163
+ sellChainId: number | undefined;
164
+ };
149
165
  },
150
166
  ) {
151
167
  const isMobile = useIsMobile();
@@ -203,6 +219,8 @@ function SelectTokenUI(
203
219
  >
204
220
  <LeftContainer>
205
221
  <SelectBridgeChain
222
+ type={props.type}
223
+ selections={props.selections}
206
224
  onBack={() => setScreen("select-token")}
207
225
  client={props.client}
208
226
  isMobile={false}
@@ -269,6 +287,8 @@ function SelectTokenUI(
269
287
  setScreen("select-token");
270
288
  }}
271
289
  selectedChain={props.selectedChain}
290
+ type={props.type}
291
+ selections={props.selections}
272
292
  />
273
293
  );
274
294
  }
@@ -467,16 +487,16 @@ function TokenSelectionScreen(props: {
467
487
  </Container>
468
488
 
469
489
  {!props.selectedChain && (
470
- <div
490
+ <Container
491
+ flex="column"
492
+ center="both"
493
+ expand
471
494
  style={{
472
- display: "flex",
473
- alignItems: "center",
474
- justifyContent: "center",
475
495
  minHeight: "300px",
476
496
  }}
477
497
  >
478
498
  <Spinner color="secondaryText" size="xl" />
479
- </div>
499
+ </Container>
480
500
  )}
481
501
 
482
502
  {props.selectedChain && (
@@ -11,6 +11,7 @@ import { getToken } from "../../../../../pay/convert/get-token.js";
11
11
  import type { SupportedFiatCurrency } from "../../../../../pay/convert/type.js";
12
12
  import { getAddress } from "../../../../../utils/address.js";
13
13
  import { toTokens, toUnits } from "../../../../../utils/units.js";
14
+ import { getDefaultWalletsForBridgeComponents } from "../../../../../wallets/defaultWallets.js";
14
15
  import { useCustomTheme } from "../../../../core/design-system/CustomThemeProvider.js";
15
16
  import {
16
17
  fontSize,
@@ -21,6 +22,7 @@ import {
21
22
  } from "../../../../core/design-system/index.js";
22
23
  import type { BridgePrepareRequest } from "../../../../core/hooks/useBridgePrepare.js";
23
24
  import { ConnectButton } from "../../ConnectWallet/ConnectButton.js";
25
+ import { onModalUnmount } from "../../ConnectWallet/constants.js";
24
26
  import { DetailsModal } from "../../ConnectWallet/Details.js";
25
27
  import { ArrowUpDownIcon } from "../../ConnectWallet/icons/ArrowUpDownIcon.js";
26
28
  import connectLocaleEn from "../../ConnectWallet/locale/en.js";
@@ -48,7 +50,7 @@ import type {
48
50
  SwapWidgetConnectOptions,
49
51
  TokenSelection,
50
52
  } from "./types.js";
51
- import { useBridgeChains } from "./use-bridge-chains.js";
53
+ import { useBridgeChain } from "./use-bridge-chains.js";
52
54
 
53
55
  type SwapUIProps = {
54
56
  activeWalletInfo: ActiveWalletInfo | undefined;
@@ -225,8 +227,14 @@ export function SwapUI(props: SwapUIProps) {
225
227
  }
226
228
  }}
227
229
  >
230
+ {/* buy token modal */}
228
231
  {modalState.screen === "select-buy-token" && (
229
232
  <SelectToken
233
+ type="buy"
234
+ selections={{
235
+ buyChainId: props.buyToken?.chainId,
236
+ sellChainId: props.sellToken?.chainId,
237
+ }}
230
238
  activeWalletInfo={props.activeWalletInfo}
231
239
  onClose={() => {
232
240
  setModalState((v) => ({
@@ -263,6 +271,7 @@ export function SwapUI(props: SwapUIProps) {
263
271
  />
264
272
  )}
265
273
 
274
+ {/* sell token modal */}
266
275
  {modalState.screen === "select-sell-token" && (
267
276
  <SelectToken
268
277
  onClose={() => {
@@ -291,13 +300,22 @@ export function SwapUI(props: SwapUIProps) {
291
300
  token.tokenAddress.toLowerCase() !==
292
301
  NATIVE_TOKEN_ADDRESS.toLowerCase()
293
302
  ) {
294
- props.setBuyToken({
295
- tokenAddress: getAddress(NATIVE_TOKEN_ADDRESS),
296
- chainId: token.chainId,
303
+ // set the buy token after a delay to avoid updating the "selections" prop passed to the <SelectToken> component and trigger unnecessay fetch of chains query that will never be used
304
+ // we have to do this because the modal does not close immediately onClose - it has a fade out animation
305
+ onModalUnmount(() => {
306
+ props.setBuyToken({
307
+ tokenAddress: getAddress(NATIVE_TOKEN_ADDRESS),
308
+ chainId: token.chainId,
309
+ });
297
310
  });
298
311
  }
299
312
  }}
300
313
  activeWalletInfo={props.activeWalletInfo}
314
+ type="sell"
315
+ selections={{
316
+ buyChainId: props.buyToken?.chainId,
317
+ sellChainId: props.sellToken?.chainId,
318
+ }}
301
319
  />
302
320
  )}
303
321
  </Modal>
@@ -319,8 +337,12 @@ export function SwapUI(props: SwapUIProps) {
319
337
  />
320
338
  )}
321
339
 
322
- {/* Sell */}
340
+ {/* Sell token */}
323
341
  <TokenSection
342
+ selection={{
343
+ buyChainId: props.buyToken?.chainId,
344
+ sellChainId: props.sellToken?.chainId,
345
+ }}
324
346
  onMaxClick={() => {
325
347
  if (sellTokenBalanceQuery.data) {
326
348
  props.setAmountSelection({
@@ -381,6 +403,10 @@ export function SwapUI(props: SwapUIProps) {
381
403
 
382
404
  {/* Buy */}
383
405
  <TokenSection
406
+ selection={{
407
+ buyChainId: props.buyToken?.chainId,
408
+ sellChainId: props.sellToken?.chainId,
409
+ }}
384
410
  onMaxClick={undefined}
385
411
  onWalletClick={() => {
386
412
  setDetailsModalOpen(true);
@@ -456,6 +482,13 @@ export function SwapUI(props: SwapUIProps) {
456
482
  }}
457
483
  theme={props.theme}
458
484
  {...props.connectOptions}
485
+ wallets={
486
+ props.connectOptions?.wallets ||
487
+ getDefaultWalletsForBridgeComponents({
488
+ appMetadata: props.connectOptions?.appMetadata,
489
+ chains: props.connectOptions?.chains,
490
+ })
491
+ }
459
492
  />
460
493
  ) : (
461
494
  <Button
@@ -655,6 +688,10 @@ function useSwapQuote(params: {
655
688
 
656
689
  function TokenSection(props: {
657
690
  type: "buy" | "sell";
691
+ selection: {
692
+ buyChainId: number | undefined;
693
+ sellChainId: number | undefined;
694
+ };
658
695
  amount: {
659
696
  data: string;
660
697
  isFetching: boolean;
@@ -680,10 +717,12 @@ function TokenSection(props: {
680
717
  onMaxClick: (() => void) | undefined;
681
718
  }) {
682
719
  const theme = useCustomTheme();
683
- const chainQuery = useBridgeChains(props.client);
684
- const chain = chainQuery.data?.find(
685
- (chain) => chain.chainId === props.selectedToken?.data?.chainId,
686
- );
720
+
721
+ const chainQuery = useBridgeChain({
722
+ chainId: props.selectedToken?.data?.chainId,
723
+ client: props.client,
724
+ });
725
+ const chain = chainQuery.data;
687
726
 
688
727
  const fiatPricePerToken = props.selectedToken?.data?.prices[props.currency];
689
728
  const totalFiatValue = !props.amount.data
@@ -2,11 +2,11 @@ import { useQuery } from "@tanstack/react-query";
2
2
  import { chains } from "../../../../../bridge/index.js";
3
3
  import type { ThirdwebClient } from "../../../../../client/client.js";
4
4
 
5
- export function useBridgeChains(client: ThirdwebClient) {
5
+ export function useBridgeChains(options: chains.Options) {
6
6
  return useQuery({
7
- queryKey: ["bridge-chains"],
7
+ queryKey: ["bridge-chains", options],
8
8
  queryFn: async () => {
9
- const data = await chains({ client });
9
+ const data = await chains(options);
10
10
  const dataCopy = [...data];
11
11
  // sort by name, but if name starts with number, put it at the end
12
12
 
@@ -29,3 +29,52 @@ export function useBridgeChains(client: ThirdwebClient) {
29
29
  refetchOnWindowFocus: false,
30
30
  });
31
31
  }
32
+
33
+ export function useBridgeChain({
34
+ chainId,
35
+ client,
36
+ }: {
37
+ chainId: number | undefined;
38
+ client: ThirdwebClient;
39
+ }) {
40
+ const chainQuery = useBridgeChains({ client });
41
+ return {
42
+ data: chainQuery.data?.find((chain) => chain.chainId === chainId),
43
+ isPending: chainQuery.isPending,
44
+ };
45
+ }
46
+
47
+ /**
48
+ * type=origin: Returns all chains that can be used as origin
49
+ * type=destination: Returns all chains that can be used as destination
50
+ * originChainId=X: Returns destination chains reachable from chain X
51
+ * destinationChainId=X: Returns origin chains that can reach chain X
52
+ */
53
+
54
+ // for fetching "buy" (destination) chains:
55
+ // if a "sell" (origin) chain is selected, set originChainId to fetch all "buy" (destination) chains that support given originChainId
56
+ // else - set type="destination"
57
+
58
+ // for fetching "sell" (origin) chains:
59
+ // if a "buy" (destination) chain is selected, set destinationChainId to fetch all "sell" (origin) chains that support given destinationChainId
60
+ // else - set type="origin"
61
+
62
+ export function useBridgeChainsWithFilters(options: {
63
+ client: ThirdwebClient;
64
+ buyChainId: number | undefined;
65
+ sellChainId: number | undefined;
66
+ type: "buy" | "sell";
67
+ }) {
68
+ return useBridgeChains({
69
+ client: options.client,
70
+ ...(options.type === "buy"
71
+ ? // type = buy
72
+ options.sellChainId
73
+ ? { originChainId: options.sellChainId }
74
+ : { type: "destination" }
75
+ : // type = sell
76
+ options.buyChainId
77
+ ? { destinationChainId: options.buyChainId }
78
+ : { type: "origin" }),
79
+ });
80
+ }
@@ -20,5 +20,5 @@ export const modalCloseFadeOutDuration = 250;
20
20
  * @internal
21
21
  */
22
22
  export function onModalUnmount(cb: () => void) {
23
- setTimeout(cb, modalCloseFadeOutDuration + 100);
23
+ setTimeout(cb, modalCloseFadeOutDuration + 200);
24
24
  }
@@ -1,9 +1,11 @@
1
- import type { IconFC } from "./types.js";
2
-
3
1
  /**
4
2
  * @internal
5
3
  */
6
- export const OutlineWalletIcon: IconFC = (props) => {
4
+ export const OutlineWalletIcon = (props: {
5
+ size?: string;
6
+ color?: string;
7
+ style?: React.CSSProperties;
8
+ }) => {
7
9
  return (
8
10
  <svg
9
11
  fill="none"
@@ -12,6 +14,7 @@ export const OutlineWalletIcon: IconFC = (props) => {
12
14
  viewBox="0 0 24 24"
13
15
  width={props.size}
14
16
  xmlns="http://www.w3.org/2000/svg"
17
+ style={props.style}
15
18
  >
16
19
  <path
17
20
  d="M19 7V4C19 3.73478 18.8946 3.48043 18.7071 3.29289C18.5196 3.10536 18.2652 3 18 3H5C4.46957 3 3.96086 3.21071 3.58579 3.58579C3.21071 3.96086 3 4.46957 3 5C3 5.53043 3.21071 6.03914 3.58579 6.41421C3.96086 6.78929 4.46957 7 5 7H20C20.2652 7 20.5196 7.10536 20.7071 7.29289C20.8946 7.48043 21 7.73478 21 8V12M21 12H18C17.4696 12 16.9609 12.2107 16.5858 12.5858C16.2107 12.9609 16 13.4696 16 14C16 14.5304 16.2107 15.0391 16.5858 15.4142C16.9609 15.7893 17.4696 16 18 16H21C21.2652 16 21.5196 15.8946 21.7071 15.7071C21.8946 15.5196 22 15.2652 22 15V13C22 12.7348 21.8946 12.4804 21.7071 12.2929C21.5196 12.1054 21.2652 12 21 12Z"
@@ -1,5 +1,9 @@
1
1
  import { ChevronDownIcon } from "@radix-ui/react-icons";
2
2
  import { useCustomTheme } from "../../../../../../core/design-system/CustomThemeProvider.js";
3
+ import {
4
+ iconSize,
5
+ radius,
6
+ } from "../../../../../../core/design-system/index.js";
3
7
  import { Container } from "../../../../components/basic.js";
4
8
 
5
9
  export function StepConnectorArrow() {
@@ -9,8 +13,8 @@ export function StepConnectorArrow() {
9
13
  center="both"
10
14
  flex="row"
11
15
  style={{
12
- marginBottom: "-10px",
13
- marginTop: "-10px",
16
+ marginBottom: "-12px",
17
+ marginTop: "-12px",
14
18
  position: "relative",
15
19
  width: "100%",
16
20
  zIndex: 1000,
@@ -18,17 +22,16 @@ export function StepConnectorArrow() {
18
22
  >
19
23
  <Container
20
24
  center="both"
21
- color="primaryText"
25
+ color="secondaryText"
22
26
  flex="row"
23
27
  style={{
24
28
  backgroundColor: theme.colors.modalBg,
25
29
  border: `1px solid ${theme.colors.borderColor}`,
26
- borderRadius: "100%",
27
- height: "30px",
28
- width: "30px",
30
+ borderRadius: radius.full,
31
+ padding: "6px",
29
32
  }}
30
33
  >
31
- <ChevronDownIcon height={16} width={16} />
34
+ <ChevronDownIcon height={iconSize["sm+"]} width={iconSize["sm+"]} />
32
35
  </Container>
33
36
  </Container>
34
37
  );
@@ -5,6 +5,7 @@ import { isSmartWallet } from "../../../../../../../wallets/smart/index.js";
5
5
  import {
6
6
  fontSize,
7
7
  iconSize,
8
+ radius,
8
9
  } from "../../../../../../core/design-system/index.js";
9
10
  import { useConnectedWallets } from "../../../../../../core/hooks/wallets/useConnectedWallets.js";
10
11
  import {
@@ -58,7 +59,27 @@ export function WalletRow(props: {
58
59
  size={iconSizeValue}
59
60
  />
60
61
  ) : (
61
- <OutlineWalletIcon size={iconSizeValue} />
62
+ <Container
63
+ borderColor="borderColor"
64
+ bg="modalBg"
65
+ flex="row"
66
+ center="both"
67
+ style={{
68
+ borderStyle: "solid",
69
+ borderWidth: "1px",
70
+ borderRadius: radius.full,
71
+ width: `${iconSizeValue}px`,
72
+ height: `${iconSizeValue}px`,
73
+ position: "relative",
74
+ }}
75
+ >
76
+ <OutlineWalletIcon
77
+ style={{
78
+ position: "absolute",
79
+ inset: "25%",
80
+ }}
81
+ />
82
+ </Container>
62
83
  )}
63
84
  <Container flex="column" gap="3xs">
64
85
  {props.label ? (
@@ -70,7 +70,6 @@ export function WalletSwitcherConnectionScreen(
70
70
  onClose={() => {}}
71
71
  onConnect={(w) => {
72
72
  props.onSelect(w);
73
- props.onBack();
74
73
  }}
75
74
  recommendedWallets={props.recommendedWallets}
76
75
  screenSetup={screenSetup}
@@ -0,0 +1,98 @@
1
+ import type { Meta } from "@storybook/react";
2
+ import { lightTheme } from "../../../react/core/design-system/index.js";
3
+ import {
4
+ BridgeWidget,
5
+ type BridgeWidgetProps,
6
+ } from "../../../react/web/ui/Bridge/bridge-widget/bridge-widget.js";
7
+ import { createWallet } from "../../../wallets/create-wallet.js";
8
+ import { storyClient } from "../../utils.js";
9
+
10
+ const meta: Meta<typeof BridgeWidget> = {
11
+ title: "Bridge/BridgeWidget",
12
+ };
13
+ export default meta;
14
+
15
+ export function BasicUsage() {
16
+ return (
17
+ <Variant client={storyClient} buy={{ chainId: 8453, amount: "0.1" }} />
18
+ );
19
+ }
20
+
21
+ export function CurrencySet() {
22
+ return (
23
+ <Variant
24
+ client={storyClient}
25
+ currency="JPY"
26
+ buy={{ chainId: 8453, amount: "0.1" }}
27
+ />
28
+ );
29
+ }
30
+
31
+ export function NoThirdwebBranding() {
32
+ return (
33
+ <Variant
34
+ client={storyClient}
35
+ theme="light"
36
+ buy={{ chainId: 8453, amount: "0.1" }}
37
+ showThirdwebBranding={false}
38
+ />
39
+ );
40
+ }
41
+
42
+ export function CustomTheme() {
43
+ return (
44
+ <div
45
+ style={{
46
+ display: "flex",
47
+ flexDirection: "column",
48
+ gap: "40px",
49
+ alignItems: "center",
50
+ }}
51
+ >
52
+ <BridgeWidget
53
+ client={storyClient}
54
+ currency="JPY"
55
+ buy={{ chainId: 8453, amount: "0.1" }}
56
+ showThirdwebBranding={false}
57
+ theme={lightTheme({
58
+ colors: {
59
+ modalBg: "#FFFFF0",
60
+ tertiaryBg: "#DBE4C9",
61
+ borderColor: "#8AA624",
62
+ secondaryText: "#3E3F29",
63
+ accentText: "#E43636",
64
+ },
65
+ })}
66
+ />
67
+ </div>
68
+ );
69
+ }
70
+
71
+ export function CustomWallets() {
72
+ return (
73
+ <Variant
74
+ client={storyClient}
75
+ currency="JPY"
76
+ buy={{ chainId: 8453, amount: "0.1" }}
77
+ connectOptions={{
78
+ wallets: [createWallet("io.metamask"), createWallet("me.rainbow")],
79
+ }}
80
+ />
81
+ );
82
+ }
83
+
84
+ function Variant(props: BridgeWidgetProps) {
85
+ return (
86
+ <div
87
+ style={{
88
+ display: "flex",
89
+ flexDirection: "column",
90
+ gap: "40px",
91
+ alignItems: "center",
92
+ }}
93
+ >
94
+ <BridgeWidget {...props} theme="dark" />
95
+ <BridgeWidget {...props} theme="light" />
96
+ </div>
97
+ );
98
+ }