thirdweb 5.64.2 → 5.64.3

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 (134) hide show
  1. package/dist/cjs/react/core/hooks/transaction/useSendTransaction.js +19 -1
  2. package/dist/cjs/react/core/hooks/transaction/useSendTransaction.js.map +1 -1
  3. package/dist/cjs/react/core/utils/isSmartWallet.js +4 -2
  4. package/dist/cjs/react/core/utils/isSmartWallet.js.map +1 -1
  5. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js +27 -78
  6. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js.map +1 -1
  7. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js +27 -13
  8. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js.map +1 -1
  9. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/WalletSelectorButton.js +50 -19
  10. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/WalletSelectorButton.js.map +1 -1
  11. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/main/useEnabledPaymentMethods.js +0 -2
  12. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/main/useEnabledPaymentMethods.js.map +1 -1
  13. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js +21 -32
  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/PaymentSelectionScreen.js +138 -0
  16. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/PaymentSelectionScreen.js.map +1 -0
  17. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/useSwapSupportedChains.js +1 -0
  18. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/useSwapSupportedChains.js.map +1 -1
  19. package/dist/cjs/react/web/ui/ConnectWallet/screens/formatTokenBalance.js +2 -2
  20. package/dist/cjs/react/web/ui/ConnectWallet/screens/formatTokenBalance.js.map +1 -1
  21. package/dist/cjs/react/web/wallets/shared/ConnectWalletSocialOptions.js +1 -1
  22. package/dist/cjs/react/web/wallets/shared/ConnectWalletSocialOptions.js.map +1 -1
  23. package/dist/cjs/version.js +1 -1
  24. package/dist/cjs/wallets/ecosystem/get-ecosystem-wallet-auth-options.js +23 -17
  25. package/dist/cjs/wallets/ecosystem/get-ecosystem-wallet-auth-options.js.map +1 -1
  26. package/dist/cjs/wallets/ecosystem/get-ecosystem-wallet-info.js +4 -13
  27. package/dist/cjs/wallets/ecosystem/get-ecosystem-wallet-info.js.map +1 -1
  28. package/dist/cjs/wallets/in-app/core/wallet/in-app-core.js +56 -4
  29. package/dist/cjs/wallets/in-app/core/wallet/in-app-core.js.map +1 -1
  30. package/dist/cjs/wallets/in-app/core/wallet/index.js +2 -50
  31. package/dist/cjs/wallets/in-app/core/wallet/index.js.map +1 -1
  32. package/dist/cjs/wallets/smart/lib/bundler.js +3 -1
  33. package/dist/cjs/wallets/smart/lib/bundler.js.map +1 -1
  34. package/dist/esm/react/core/hooks/transaction/useSendTransaction.js +19 -1
  35. package/dist/esm/react/core/hooks/transaction/useSendTransaction.js.map +1 -1
  36. package/dist/esm/react/core/utils/isSmartWallet.js +4 -2
  37. package/dist/esm/react/core/utils/isSmartWallet.js.map +1 -1
  38. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js +29 -80
  39. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js.map +1 -1
  40. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js +28 -14
  41. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js.map +1 -1
  42. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/WalletSelectorButton.js +50 -19
  43. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/WalletSelectorButton.js.map +1 -1
  44. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/main/useEnabledPaymentMethods.js +0 -2
  45. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/main/useEnabledPaymentMethods.js.map +1 -1
  46. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js +21 -32
  47. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js.map +1 -1
  48. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/PaymentSelectionScreen.js +135 -0
  49. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/PaymentSelectionScreen.js.map +1 -0
  50. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/useSwapSupportedChains.js +1 -1
  51. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/useSwapSupportedChains.js.map +1 -1
  52. package/dist/esm/react/web/ui/ConnectWallet/screens/formatTokenBalance.js +2 -2
  53. package/dist/esm/react/web/ui/ConnectWallet/screens/formatTokenBalance.js.map +1 -1
  54. package/dist/esm/react/web/wallets/shared/ConnectWalletSocialOptions.js +2 -2
  55. package/dist/esm/react/web/wallets/shared/ConnectWalletSocialOptions.js.map +1 -1
  56. package/dist/esm/version.js +1 -1
  57. package/dist/esm/wallets/ecosystem/get-ecosystem-wallet-auth-options.js +22 -16
  58. package/dist/esm/wallets/ecosystem/get-ecosystem-wallet-auth-options.js.map +1 -1
  59. package/dist/esm/wallets/ecosystem/get-ecosystem-wallet-info.js +4 -13
  60. package/dist/esm/wallets/ecosystem/get-ecosystem-wallet-info.js.map +1 -1
  61. package/dist/esm/wallets/in-app/core/wallet/in-app-core.js +56 -4
  62. package/dist/esm/wallets/in-app/core/wallet/in-app-core.js.map +1 -1
  63. package/dist/esm/wallets/in-app/core/wallet/index.js +2 -50
  64. package/dist/esm/wallets/in-app/core/wallet/index.js.map +1 -1
  65. package/dist/esm/wallets/smart/lib/bundler.js +3 -1
  66. package/dist/esm/wallets/smart/lib/bundler.js.map +1 -1
  67. package/dist/types/react/core/hooks/transaction/useSendTransaction.d.ts.map +1 -1
  68. package/dist/types/react/core/utils/isSmartWallet.d.ts.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/TransactionModeScreen.d.ts +1 -1
  71. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.d.ts.map +1 -1
  72. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/WalletSelectorButton.d.ts +12 -8
  73. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/WalletSelectorButton.d.ts.map +1 -1
  74. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/types.d.ts +1 -1
  75. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/types.d.ts.map +1 -1
  76. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/useEnabledPaymentMethods.d.ts +0 -1
  77. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/useEnabledPaymentMethods.d.ts.map +1 -1
  78. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.d.ts +1 -2
  79. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.d.ts.map +1 -1
  80. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/PaymentSelectionScreen.d.ts +30 -0
  81. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/PaymentSelectionScreen.d.ts.map +1 -0
  82. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/useSwapSupportedChains.d.ts +1 -0
  83. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/useSwapSupportedChains.d.ts.map +1 -1
  84. package/dist/types/react/web/ui/ConnectWallet/screens/formatTokenBalance.d.ts +1 -1
  85. package/dist/types/react/web/ui/ConnectWallet/screens/formatTokenBalance.d.ts.map +1 -1
  86. package/dist/types/react/web/ui/components/token/TokenSymbol.d.ts +1 -1
  87. package/dist/types/react/web/ui/components/token/TokenSymbol.d.ts.map +1 -1
  88. package/dist/types/version.d.ts +1 -1
  89. package/dist/types/wallets/ecosystem/get-ecosystem-wallet-auth-options.d.ts +5 -1
  90. package/dist/types/wallets/ecosystem/get-ecosystem-wallet-auth-options.d.ts.map +1 -1
  91. package/dist/types/wallets/ecosystem/get-ecosystem-wallet-info.d.ts.map +1 -1
  92. package/dist/types/wallets/in-app/core/wallet/in-app-core.d.ts.map +1 -1
  93. package/dist/types/wallets/in-app/core/wallet/index.d.ts +2 -3
  94. package/dist/types/wallets/in-app/core/wallet/index.d.ts.map +1 -1
  95. package/dist/types/wallets/smart/lib/bundler.d.ts.map +1 -1
  96. package/dist/types/wallets/smart/types.d.ts +1 -1
  97. package/dist/types/wallets/smart/types.d.ts.map +1 -1
  98. package/package.json +11 -11
  99. package/src/extensions/unstoppable-domains/read/resolveName.test.ts +20 -17
  100. package/src/react/core/hooks/transaction/useSendTransaction.ts +34 -4
  101. package/src/react/core/utils/isSmartWallet.ts +4 -2
  102. package/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx +35 -148
  103. package/src/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.tsx +62 -31
  104. package/src/react/web/ui/ConnectWallet/screens/Buy/WalletSelectorButton.tsx +136 -48
  105. package/src/react/web/ui/ConnectWallet/screens/Buy/main/types.ts +1 -1
  106. package/src/react/web/ui/ConnectWallet/screens/Buy/main/useEnabledPaymentMethods.ts +0 -4
  107. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.tsx +57 -71
  108. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/PaymentSelectionScreen.tsx +251 -0
  109. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/useSwapSupportedChains.ts +1 -1
  110. package/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts +2 -1
  111. package/src/react/web/ui/components/token/TokenSymbol.tsx +2 -2
  112. package/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx +2 -2
  113. package/src/version.ts +1 -1
  114. package/src/wallets/ecosystem/get-ecosystem-wallet-auth-options.ts +36 -23
  115. package/src/wallets/ecosystem/get-ecosystem-wallet-info.ts +5 -21
  116. package/src/wallets/in-app/core/wallet/in-app-core.ts +62 -4
  117. package/src/wallets/in-app/core/wallet/index.ts +0 -59
  118. package/src/wallets/smart/lib/bundler.ts +4 -1
  119. package/src/wallets/smart/smart-wallet-dev.test.ts +23 -4
  120. package/src/wallets/smart/types.ts +1 -1
  121. package/dist/cjs/react/web/ui/ConnectWallet/icons/GenericWalletIcon.js +0 -12
  122. package/dist/cjs/react/web/ui/ConnectWallet/icons/GenericWalletIcon.js.map +0 -1
  123. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/WalletSwitcherDrawerContent.js +0 -34
  124. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/WalletSwitcherDrawerContent.js.map +0 -1
  125. package/dist/esm/react/web/ui/ConnectWallet/icons/GenericWalletIcon.js +0 -8
  126. package/dist/esm/react/web/ui/ConnectWallet/icons/GenericWalletIcon.js.map +0 -1
  127. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/WalletSwitcherDrawerContent.js +0 -31
  128. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/WalletSwitcherDrawerContent.js.map +0 -1
  129. package/dist/types/react/web/ui/ConnectWallet/icons/GenericWalletIcon.d.ts +0 -6
  130. package/dist/types/react/web/ui/ConnectWallet/icons/GenericWalletIcon.d.ts.map +0 -1
  131. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/WalletSwitcherDrawerContent.d.ts +0 -14
  132. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/WalletSwitcherDrawerContent.d.ts.map +0 -1
  133. package/src/react/web/ui/ConnectWallet/icons/GenericWalletIcon.tsx +0 -22
  134. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletSwitcherDrawerContent.tsx +0 -83
@@ -0,0 +1,251 @@
1
+ import { IdCardIcon } from "@radix-ui/react-icons";
2
+ import { useQuery } from "@tanstack/react-query";
3
+ import type { Chain } from "../../../../../../../chains/types.js";
4
+ import { getCachedChain } from "../../../../../../../chains/utils.js";
5
+ import type { ThirdwebClient } from "../../../../../../../client/client.js";
6
+ import { NATIVE_TOKEN_ADDRESS } from "../../../../../../../constants/addresses.js";
7
+ import type { Wallet } from "../../../../../../../wallets/interfaces/wallet.js";
8
+ import {
9
+ type GetWalletBalanceResult,
10
+ getWalletBalance,
11
+ } from "../../../../../../../wallets/utils/getWalletBalance.js";
12
+ import type { WalletId } from "../../../../../../../wallets/wallet-types.js";
13
+ import { useCustomTheme } from "../../../../../../core/design-system/CustomThemeProvider.js";
14
+ import {
15
+ iconSize,
16
+ radius,
17
+ spacing,
18
+ } from "../../../../../../core/design-system/index.js";
19
+ import type { PayUIOptions } from "../../../../../../core/hooks/connection/ConnectButtonProps.js";
20
+ import { useChainMetadata } from "../../../../../../core/hooks/others/useChainQuery.js";
21
+ import { useActiveAccount } from "../../../../../../core/hooks/wallets/useActiveAccount.js";
22
+ import { useConnectedWallets } from "../../../../../../core/hooks/wallets/useConnectedWallets.js";
23
+ import type {
24
+ SupportedTokens,
25
+ TokenInfo,
26
+ } from "../../../../../../core/utils/defaultTokens.js";
27
+ import { LoadingScreen } from "../../../../../wallets/shared/LoadingScreen.js";
28
+ import { Spacer } from "../../../../components/Spacer.js";
29
+ import { Container } from "../../../../components/basic.js";
30
+ import { Button } from "../../../../components/buttons.js";
31
+ import { Text } from "../../../../components/text.js";
32
+ import { OutlineWalletIcon } from "../../../icons/OutlineWalletIcon.js";
33
+ import { type ERC20OrNativeToken, isNativeToken } from "../../nativeToken.js";
34
+ import { WalletRowWithBalances } from "../WalletSelectorButton.js";
35
+
36
+ export type TokenBalance = {
37
+ balance: GetWalletBalanceResult;
38
+ chain: Chain;
39
+ token: TokenInfo;
40
+ };
41
+
42
+ export function PaymentSelectionScreen(props: {
43
+ client: ThirdwebClient;
44
+ mode: PayUIOptions["mode"];
45
+ showAllWallets: boolean;
46
+ sourceSupportedTokens: SupportedTokens | undefined;
47
+ toChain: Chain;
48
+ toToken: ERC20OrNativeToken;
49
+ tokenAmount: string;
50
+ wallets: Wallet[] | undefined;
51
+ onSelect: (wallet: Wallet, token: TokenInfo, chain: Chain) => void;
52
+ onSelectFiat: () => void;
53
+ onBack: () => void;
54
+ onConnect: () => void;
55
+ hiddenWallets?: WalletId[];
56
+ payWithFiatEnabled: boolean;
57
+ }) {
58
+ const theme = useCustomTheme();
59
+ const connectedWallets = useConnectedWallets();
60
+
61
+ // if all wallets are connected and showAll wallets is disabled, hide the connect button
62
+ const hideConnectButton =
63
+ !props.showAllWallets &&
64
+ props.wallets?.every((w) => connectedWallets.includes(w));
65
+
66
+ const chainInfo = useChainMetadata(props.toChain);
67
+ const activeAccount = useActiveAccount();
68
+
69
+ const walletsAndBalances = useQuery({
70
+ queryKey: [
71
+ "wallets-and-balances",
72
+ connectedWallets.map((w) => w.getAccount()?.address),
73
+ props.sourceSupportedTokens,
74
+ props.toChain.id,
75
+ props.toToken,
76
+ props.tokenAmount,
77
+ props.mode,
78
+ activeAccount?.address,
79
+ ],
80
+ queryFn: async () => {
81
+ // in parallel, get the balances of all the wallets on each of the sourceSupportedTokens
82
+ const walletBalanceMap = new Map<Wallet, TokenBalance[]>();
83
+
84
+ const balancePromises = connectedWallets.flatMap((wallet) => {
85
+ const account = wallet.getAccount();
86
+ if (!account) return [];
87
+ walletBalanceMap.set(wallet, []);
88
+
89
+ // inject the destination token too since it can be used as well to pay/transfer
90
+ const toToken = isNativeToken(props.toToken)
91
+ ? {
92
+ address: NATIVE_TOKEN_ADDRESS,
93
+ name: chainInfo.data?.nativeCurrency.name || "",
94
+ symbol: chainInfo.data?.nativeCurrency.symbol || "",
95
+ icon: chainInfo.data?.icon?.url,
96
+ }
97
+ : props.toToken;
98
+
99
+ const tokens = {
100
+ ...props.sourceSupportedTokens,
101
+ [props.toChain.id]: [
102
+ toToken,
103
+ ...(props.sourceSupportedTokens?.[props.toChain.id] || []),
104
+ ],
105
+ };
106
+
107
+ return Object.entries(tokens).flatMap(([chainId, tokens]) => {
108
+ return tokens.map(async (token) => {
109
+ try {
110
+ const chain = getCachedChain(Number(chainId));
111
+ const balance = await getWalletBalance({
112
+ address: account.address,
113
+ chain,
114
+ tokenAddress: isNativeToken(token) ? undefined : token.address,
115
+ client: props.client,
116
+ });
117
+
118
+ // show the token if:
119
+ // - its not the destination token and balance is greater than 0
120
+ // - its the destination token and balance is greater than the token amount AND we the account is not the default account in fund_wallet mode
121
+ const shouldInclude =
122
+ token.address === toToken.address &&
123
+ chain.id === props.toChain.id
124
+ ? props.mode === "fund_wallet" &&
125
+ account.address === activeAccount?.address
126
+ ? false
127
+ : Number(balance.displayValue) > Number(props.tokenAmount)
128
+ : balance.value > 0n;
129
+
130
+ if (shouldInclude) {
131
+ const existingBalances = walletBalanceMap.get(wallet) || [];
132
+ existingBalances.push({ balance, chain, token });
133
+ existingBalances.sort((a, b) => {
134
+ if (
135
+ a.chain.id === props.toChain.id &&
136
+ a.token.address === toToken.address
137
+ )
138
+ return -1;
139
+ if (
140
+ b.chain.id === props.toChain.id &&
141
+ b.token.address === toToken.address
142
+ )
143
+ return 1;
144
+ if (a.chain.id === props.toChain.id) return -1;
145
+ if (b.chain.id === props.toChain.id) return 1;
146
+ return a.chain.id > b.chain.id ? 1 : -1;
147
+ });
148
+ }
149
+ } catch (error) {
150
+ console.error(
151
+ `Failed to fetch balance for wallet ${wallet.id} on chain ${chainId} for token ${token.symbol}:`,
152
+ error,
153
+ );
154
+ }
155
+ });
156
+ });
157
+ });
158
+
159
+ await Promise.all(balancePromises);
160
+ return walletBalanceMap;
161
+ },
162
+ enabled: !!props.sourceSupportedTokens && !!chainInfo.data,
163
+ });
164
+
165
+ if (walletsAndBalances.isLoading || !walletsAndBalances.data) {
166
+ return <LoadingScreen />;
167
+ }
168
+
169
+ return (
170
+ <Container>
171
+ <Container flex="column" gap="xs">
172
+ {Array.from(walletsAndBalances.data?.entries() || [])
173
+ .filter(([w]) => !props.hiddenWallets?.includes(w.id))
174
+ .map(([w, balances]) => {
175
+ const address = w.getAccount()?.address;
176
+ if (!address) return null;
177
+ return (
178
+ <WalletRowWithBalances
179
+ key={w.id}
180
+ wallet={w}
181
+ balances={balances}
182
+ client={props.client}
183
+ address={address}
184
+ onClick={props.onSelect}
185
+ />
186
+ );
187
+ })}
188
+ {!hideConnectButton && (
189
+ <Button
190
+ variant="secondary"
191
+ fullWidth
192
+ onClick={props.onConnect}
193
+ gap="xs"
194
+ bg="tertiaryBg"
195
+ style={{
196
+ borderRadius: radius.lg,
197
+ border: `1px solid ${theme.colors.borderColor}`,
198
+ padding: spacing.sm,
199
+ }}
200
+ >
201
+ <Container
202
+ flex="row"
203
+ gap="sm"
204
+ center="y"
205
+ expand
206
+ color="secondaryIconColor"
207
+ >
208
+ <OutlineWalletIcon size={iconSize.md} />
209
+ <Text size="sm" color="primaryText">
210
+ Pay with another wallet
211
+ </Text>
212
+ </Container>
213
+ </Button>
214
+ )}
215
+ {props.payWithFiatEnabled && (
216
+ <Button
217
+ variant="secondary"
218
+ fullWidth
219
+ gap="xs"
220
+ bg="tertiaryBg"
221
+ onClick={props.onSelectFiat}
222
+ style={{
223
+ borderRadius: radius.lg,
224
+ border: `1px solid ${theme.colors.borderColor}`,
225
+ padding: spacing.sm,
226
+ }}
227
+ >
228
+ <Container
229
+ flex="row"
230
+ gap="sm"
231
+ center="y"
232
+ expand
233
+ color="secondaryIconColor"
234
+ >
235
+ <IdCardIcon
236
+ style={{
237
+ width: iconSize.md,
238
+ height: iconSize.md,
239
+ }}
240
+ />
241
+ <Text size="sm" color="primaryText">
242
+ Pay with credit card
243
+ </Text>
244
+ </Container>
245
+ </Button>
246
+ )}
247
+ </Container>
248
+ <Spacer y="sm" />
249
+ </Container>
250
+ );
251
+ }
@@ -34,7 +34,7 @@ export type SupportedChainAndTokens = Array<{
34
34
  }>;
35
35
  }>;
36
36
 
37
- async function fetchBuySupportedDestinations(
37
+ export async function fetchBuySupportedDestinations(
38
38
  client: ThirdwebClient,
39
39
  isTestMode?: boolean,
40
40
  ): Promise<SupportedChainAndTokens> {
@@ -13,9 +13,10 @@ export function formatTokenBalance(
13
13
  displayValue: string;
14
14
  },
15
15
  showSymbol = true,
16
+ decimals = 5,
16
17
  ) {
17
18
  return (
18
- formatNumber(Number(balanceData.displayValue), 5) +
19
+ formatNumber(Number(balanceData.displayValue), decimals) +
19
20
  (showSymbol ? ` ${balanceData.symbol}` : "")
20
21
  );
21
22
  }
@@ -15,7 +15,7 @@ import { Text } from "../text.js";
15
15
  export function TokenSymbol(props: {
16
16
  token: ERC20OrNativeToken;
17
17
  chain: Chain;
18
- size: "sm" | "md" | "lg";
18
+ size: "xs" | "sm" | "md" | "lg";
19
19
  color?: keyof Theme["colors"];
20
20
  inline?: boolean;
21
21
  }) {
@@ -43,7 +43,7 @@ export function TokenSymbol(props: {
43
43
 
44
44
  function NativeTokenSymbol(props: {
45
45
  chain: Chain;
46
- size: "sm" | "md" | "lg";
46
+ size: "xs" | "sm" | "md" | "lg";
47
47
  color?: keyof Theme["colors"];
48
48
  inline?: boolean;
49
49
  }) {
@@ -5,7 +5,7 @@ import { useMemo, useState } from "react";
5
5
  import type { Chain } from "../../../../chains/types.js";
6
6
  import type { ThirdwebClient } from "../../../../client/client.js";
7
7
  import { webLocalStorage } from "../../../../utils/storage/webStorage.js";
8
- import { getEcosystemOptions } from "../../../../wallets/ecosystem/get-ecosystem-wallet-auth-options.js";
8
+ import { getEcosystemInfo } from "../../../../wallets/ecosystem/get-ecosystem-wallet-auth-options.js";
9
9
  import { isEcosystemWallet } from "../../../../wallets/ecosystem/is-ecosystem-wallet.js";
10
10
  import type { Profile } from "../../../../wallets/in-app/core/authentication/types.js";
11
11
  import { linkProfile } from "../../../../wallets/in-app/web/lib/auth/index.js";
@@ -123,7 +123,7 @@ export const ConnectWalletSocialOptions = (
123
123
  queryKey: ["auth-options", wallet.id],
124
124
  queryFn: async () => {
125
125
  if (isEcosystemWallet(wallet)) {
126
- const options = await getEcosystemOptions(wallet.id);
126
+ const options = await getEcosystemInfo(wallet.id);
127
127
  return options?.authOptions ?? null;
128
128
  }
129
129
  return null;
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "5.64.2";
1
+ export const version = "5.64.3";
@@ -1,8 +1,13 @@
1
1
  import { getThirdwebBaseUrl } from "../../utils/domains.js";
2
+ import { withCache } from "../../utils/promise/withCache.js";
2
3
  import type { AuthOption } from "../types.js";
3
4
  import type { EcosystemWalletId } from "../wallet-types.js";
4
5
 
5
6
  export type EcosystemOptions = {
7
+ name: string;
8
+ imageUrl?: string;
9
+ slug: string;
10
+ homepage?: string;
6
11
  authOptions: AuthOption[];
7
12
  smartAccountOptions: SmartAccountOptions;
8
13
  };
@@ -19,32 +24,40 @@ type SmartAccountOptions = {
19
24
  * @returns {AuthOption[] | undefined} The auth options for the ecosystem wallet.
20
25
  * @internal
21
26
  */
22
- export async function getEcosystemOptions(
27
+ export async function getEcosystemInfo(
23
28
  walletId: EcosystemWalletId,
24
- ): Promise<EcosystemOptions | null> {
25
- const res = await fetch(
26
- `${getThirdwebBaseUrl("inAppWallet")}/api/2024-05-05/ecosystem-wallet`,
27
- {
28
- headers: {
29
- "x-ecosystem-id": walletId,
30
- },
31
- },
32
- );
29
+ ): Promise<EcosystemOptions> {
30
+ return withCache(
31
+ async () => {
32
+ const res = await fetch(
33
+ `${getThirdwebBaseUrl("inAppWallet")}/api/2024-05-05/ecosystem-wallet`,
34
+ {
35
+ headers: {
36
+ "x-ecosystem-id": walletId,
37
+ },
38
+ },
39
+ );
33
40
 
34
- const data = await res.json();
41
+ const data = await res.json();
35
42
 
36
- if (!data || data.code === "UNAUTHORIZED") {
37
- throw new Error(
38
- data.message ||
39
- `Could not find ecosystem wallet with id ${walletId}, please check your ecosystem wallet configuration.`,
40
- );
41
- }
43
+ if (!data || data.code === "UNAUTHORIZED") {
44
+ throw new Error(
45
+ data.message ||
46
+ `Could not find ecosystem wallet with id ${walletId}, please check your ecosystem wallet configuration.`,
47
+ );
48
+ }
42
49
 
43
- // siwe is the auth option in the backend, but we want to use wallet as the auth option in the frontend
44
- if (data.authOptions?.includes("siwe")) {
45
- data.authOptions = data.authOptions.filter((o: string) => o !== "siwe");
46
- data.authOptions.push("wallet");
47
- }
50
+ // siwe is the auth option in the backend, but we want to use wallet as the auth option in the frontend
51
+ if (data.authOptions?.includes("siwe")) {
52
+ data.authOptions = data.authOptions.filter((o: string) => o !== "siwe");
53
+ data.authOptions.push("wallet");
54
+ }
48
55
 
49
- return data ?? null;
56
+ return data;
57
+ },
58
+ {
59
+ cacheKey: `ecosystem-wallet-options-${walletId}`,
60
+ cacheTime: 1000 * 60 * 5, // 5 mins
61
+ },
62
+ );
50
63
  }
@@ -1,7 +1,7 @@
1
- import { getThirdwebBaseUrl } from "../../utils/domains.js";
2
1
  import type { Prettify } from "../../utils/type-utils.js";
3
2
  import type { WalletInfo } from "../wallet-info.js";
4
3
  import type { EcosystemWalletId } from "../wallet-types.js";
4
+ import { getEcosystemInfo } from "./get-ecosystem-wallet-auth-options.js";
5
5
 
6
6
  /**
7
7
  * Fetches metadata for a given ecosystem wallet.
@@ -14,29 +14,13 @@ import type { EcosystemWalletId } from "../wallet-types.js";
14
14
  export async function getEcosystemWalletInfo(
15
15
  walletId: EcosystemWalletId,
16
16
  ): Promise<Prettify<WalletInfo>> {
17
- const res = await fetch(
18
- `${getThirdwebBaseUrl("inAppWallet")}/api/2024-05-05/ecosystem-wallet`,
19
- {
20
- headers: {
21
- "x-ecosystem-id": walletId,
22
- },
23
- },
24
- );
25
-
26
- const data = await res.json();
27
-
28
- if (!data || data.code === "UNAUTHORIZED") {
29
- throw new Error(
30
- data.message ||
31
- `Could not find ecosystem wallet with id ${walletId}, please check your ecosystem wallet configuration.`,
32
- );
33
- }
17
+ const data = await getEcosystemInfo(walletId);
34
18
 
35
19
  return {
36
20
  id: walletId,
37
- name: data.name as string,
38
- image_id: data.imageUrl as string,
39
- homepage: data.homepage as string,
21
+ name: data.name,
22
+ image_id: data.imageUrl || "",
23
+ homepage: data.homepage || "",
40
24
  rdns: null,
41
25
  app: {
42
26
  browser: null,
@@ -2,6 +2,7 @@ import { trackConnect } from "../../../../analytics/track/connect.js";
2
2
  import type { Chain } from "../../../../chains/types.js";
3
3
  import { getCachedChainIfExists } from "../../../../chains/utils.js";
4
4
  import type { ThirdwebClient } from "../../../../client/client.js";
5
+ import { getEcosystemInfo } from "../../../ecosystem/get-ecosystem-wallet-auth-options.js";
5
6
  import type { Account, Wallet } from "../../../interfaces/wallet.js";
6
7
  import { createWalletEmitter } from "../../../wallet-emitter.js";
7
8
  import type {
@@ -38,9 +39,10 @@ export function createInAppWallet(args: {
38
39
  connectorFactory: (client: ThirdwebClient) => Promise<InAppConnector>;
39
40
  ecosystem?: Ecosystem;
40
41
  }): Wallet<"inApp" | EcosystemWalletId> {
41
- const { createOptions, connectorFactory, ecosystem } = args;
42
+ const { createOptions: _createOptions, connectorFactory, ecosystem } = args;
42
43
  const walletId = ecosystem ? ecosystem.id : "inApp";
43
44
  const emitter = createWalletEmitter<"inApp">();
45
+ let createOptions = _createOptions;
44
46
  let account: Account | undefined = undefined;
45
47
  let chain: Chain | undefined = undefined;
46
48
  let client: ThirdwebClient | undefined;
@@ -66,11 +68,32 @@ export function createInAppWallet(args: {
66
68
  connectorFactory,
67
69
  ecosystem,
68
70
  );
71
+
72
+ if (ecosystem) {
73
+ const ecosystemOptions = await getEcosystemInfo(ecosystem.id);
74
+ const smartAccountOptions = ecosystemOptions?.smartAccountOptions;
75
+ if (smartAccountOptions) {
76
+ const preferredChain = options.chain;
77
+ if (!preferredChain) {
78
+ throw new Error(
79
+ "Chain is required for ecosystem smart accounts, pass it via connect() or via UI components",
80
+ );
81
+ }
82
+ createOptions = {
83
+ ...createOptions,
84
+ smartAccount: {
85
+ chain: preferredChain,
86
+ sponsorGas: smartAccountOptions.sponsorGas,
87
+ factoryAddress: smartAccountOptions.accountFactoryAddress,
88
+ },
89
+ };
90
+ }
91
+ }
92
+
69
93
  const [connectedAccount, connectedChain] = await autoConnectInAppWallet(
70
94
  options,
71
95
  createOptions,
72
96
  connector,
73
- ecosystem,
74
97
  );
75
98
 
76
99
  // set the states
@@ -94,11 +117,31 @@ export function createInAppWallet(args: {
94
117
  ecosystem,
95
118
  );
96
119
 
120
+ if (ecosystem) {
121
+ const ecosystemOptions = await getEcosystemInfo(ecosystem.id);
122
+ const smartAccountOptions = ecosystemOptions?.smartAccountOptions;
123
+ if (smartAccountOptions) {
124
+ const preferredChain = options.chain;
125
+ if (!preferredChain) {
126
+ throw new Error(
127
+ "Chain is required for ecosystem smart accounts, pass it via connect() or via UI components",
128
+ );
129
+ }
130
+ createOptions = {
131
+ ...createOptions,
132
+ smartAccount: {
133
+ chain: preferredChain,
134
+ sponsorGas: smartAccountOptions.sponsorGas,
135
+ factoryAddress: smartAccountOptions.accountFactoryAddress,
136
+ },
137
+ };
138
+ }
139
+ }
140
+
97
141
  const [connectedAccount, connectedChain] = await connectInAppWallet(
98
142
  options,
99
143
  createOptions,
100
144
  connector,
101
- ecosystem,
102
145
  );
103
146
  // set the states
104
147
  client = options.client;
@@ -139,6 +182,22 @@ export function createInAppWallet(args: {
139
182
  connectorFactory,
140
183
  ecosystem,
141
184
  );
185
+
186
+ if (ecosystem) {
187
+ const ecosystemOptions = await getEcosystemInfo(ecosystem.id);
188
+ const smartAccountOptions = ecosystemOptions?.smartAccountOptions;
189
+ if (smartAccountOptions) {
190
+ createOptions = {
191
+ ...createOptions,
192
+ smartAccount: {
193
+ chain: newChain,
194
+ sponsorGas: smartAccountOptions.sponsorGas,
195
+ factoryAddress: smartAccountOptions.accountFactoryAddress,
196
+ },
197
+ };
198
+ }
199
+ }
200
+
142
201
  const [connectedAccount, connectedChain] = await autoConnectInAppWallet(
143
202
  {
144
203
  chain: newChain,
@@ -146,7 +205,6 @@ export function createInAppWallet(args: {
146
205
  },
147
206
  createOptions,
148
207
  connector,
149
- ecosystem,
150
208
  );
151
209
  account = connectedAccount;
152
210
  chain = connectedChain;
@@ -1,12 +1,10 @@
1
1
  import { ethereum } from "../../../../chains/chain-definitions/ethereum.js";
2
2
  import type { Chain } from "../../../../chains/types.js";
3
- import { getCachedChain } from "../../../../chains/utils.js";
4
3
  import type { ThirdwebClient } from "../../../../client/client.js";
5
4
  import {
6
5
  type SocialAuthOption,
7
6
  socialAuthOptions,
8
7
  } from "../../../../wallets/types.js";
9
- import { getEcosystemOptions } from "../../../ecosystem/get-ecosystem-wallet-auth-options.js";
10
8
  import type { Account, Wallet } from "../../../interfaces/wallet.js";
11
9
  import type { EcosystemWalletId, WalletId } from "../../../wallet-types.js";
12
10
  import type {
@@ -15,7 +13,6 @@ import type {
15
13
  WalletConnectionOption,
16
14
  } from "../../../wallet-types.js";
17
15
  import type { InAppConnector } from "../interfaces/connector.js";
18
- import type { Ecosystem } from "./types.js";
19
16
 
20
17
  /**
21
18
  * Checks if the provided wallet is an in-app wallet.
@@ -40,7 +37,6 @@ export async function connectInAppWallet(
40
37
  | CreateWalletArgs<"inApp">[1]
41
38
  | CreateWalletArgs<EcosystemWalletId>[1],
42
39
  connector: InAppConnector,
43
- ecosystem: Ecosystem | undefined,
44
40
  ): Promise<[Account, Chain]> {
45
41
  if (
46
42
  // if auth mode is not specified, the default is popup
@@ -77,33 +73,6 @@ export async function connectInAppWallet(
77
73
  });
78
74
  }
79
75
 
80
- if (ecosystem) {
81
- const ecosystemOptions = await getEcosystemOptions(ecosystem.id);
82
- const smartAccountOptions = ecosystemOptions?.smartAccountOptions;
83
- if (smartAccountOptions) {
84
- const allowedChains = smartAccountOptions.chainIds;
85
- const firstAllowedChain = allowedChains[0];
86
- if (!firstAllowedChain) {
87
- throw new Error(
88
- "At least one chain must be allowed for ecosystem smart account",
89
- );
90
- }
91
- const preferredChain =
92
- options.chain && allowedChains.includes(options.chain.id)
93
- ? options.chain
94
- : getCachedChain(firstAllowedChain);
95
- return convertToSmartAccount({
96
- client: options.client,
97
- authAccount,
98
- smartAccountOptions: {
99
- chain: preferredChain,
100
- sponsorGas: smartAccountOptions.sponsorGas,
101
- factoryAddress: smartAccountOptions.accountFactoryAddress,
102
- },
103
- });
104
- }
105
- }
106
-
107
76
  return [authAccount, options.chain || ethereum] as const;
108
77
  }
109
78
 
@@ -118,7 +87,6 @@ export async function autoConnectInAppWallet(
118
87
  | CreateWalletArgs<"inApp">[1]
119
88
  | CreateWalletArgs<EcosystemWalletId>[1],
120
89
  connector: InAppConnector,
121
- ecosystem: Ecosystem | undefined,
122
90
  ): Promise<[Account, Chain]> {
123
91
  if (options.authResult && connector.loginWithAuthToken) {
124
92
  await connector.loginWithAuthToken(options.authResult);
@@ -144,33 +112,6 @@ export async function autoConnectInAppWallet(
144
112
  });
145
113
  }
146
114
 
147
- if (ecosystem) {
148
- const ecosystemOptions = await getEcosystemOptions(ecosystem.id);
149
- const smartAccountOptions = ecosystemOptions?.smartAccountOptions;
150
- if (smartAccountOptions) {
151
- const allowedChains = smartAccountOptions.chainIds;
152
- const firstAllowedChain = allowedChains[0];
153
- if (!firstAllowedChain) {
154
- throw new Error(
155
- "At least one chain must be allowed for ecosystem smart account",
156
- );
157
- }
158
- const preferredChain =
159
- options.chain && allowedChains.includes(options.chain.id)
160
- ? options.chain
161
- : getCachedChain(firstAllowedChain);
162
- return convertToSmartAccount({
163
- client: options.client,
164
- authAccount,
165
- smartAccountOptions: {
166
- chain: preferredChain,
167
- sponsorGas: smartAccountOptions.sponsorGas,
168
- factoryAddress: smartAccountOptions.accountFactoryAddress,
169
- },
170
- });
171
- }
172
- }
173
-
174
115
  return [authAccount, options.chain || ethereum] as const;
175
116
  }
176
117
 
@@ -84,7 +84,10 @@ export async function estimateUserOpGas(args: {
84
84
  // add gas buffer for managed account factory delegate calls
85
85
  return {
86
86
  preVerificationGas: hexToBigInt(res.preVerificationGas),
87
- verificationGas: hexToBigInt(res.verificationGas),
87
+ verificationGas:
88
+ res.verificationGas !== undefined
89
+ ? hexToBigInt(res.verificationGas)
90
+ : undefined,
88
91
  verificationGasLimit: hexToBigInt(res.verificationGasLimit),
89
92
  callGasLimit: hexToBigInt(res.callGasLimit) + MANAGED_ACCOUNT_GAS_BUFFER,
90
93
  paymasterVerificationGasLimit: