thirdweb 5.111.10 → 5.112.0

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 (91) hide show
  1. package/dist/cjs/bridge/Webhook.js +62 -1
  2. package/dist/cjs/bridge/Webhook.js.map +1 -1
  3. package/dist/cjs/exports/react.js.map +1 -1
  4. package/dist/cjs/exports/react.native.js.map +1 -1
  5. package/dist/cjs/react/core/hooks/connection/types.js +3 -0
  6. package/dist/cjs/react/core/hooks/connection/types.js.map +1 -0
  7. package/dist/cjs/react/core/hooks/wallets/useAuthToken.js +11 -10
  8. package/dist/cjs/react/core/hooks/wallets/useAuthToken.js.map +1 -1
  9. package/dist/cjs/react/web/ui/ConnectWallet/Modal/ConnectEmbed.js.map +1 -1
  10. package/dist/cjs/react/web/ui/ConnectWallet/Modal/ConnectModal.js.map +1 -1
  11. package/dist/cjs/react/web/ui/ConnectWallet/Modal/ConnectModalContent.js +1 -1
  12. package/dist/cjs/react/web/ui/ConnectWallet/Modal/ConnectModalContent.js.map +1 -1
  13. package/dist/cjs/react/web/ui/ConnectWallet/useConnectModal.js.map +1 -1
  14. package/dist/cjs/version.js +1 -1
  15. package/dist/cjs/version.js.map +1 -1
  16. package/dist/cjs/wallets/connection/autoConnect.js +3 -2
  17. package/dist/cjs/wallets/connection/autoConnect.js.map +1 -1
  18. package/dist/cjs/wallets/connection/autoConnectCore.js +15 -13
  19. package/dist/cjs/wallets/connection/autoConnectCore.js.map +1 -1
  20. package/dist/cjs/wallets/manager/index.js +2 -2
  21. package/dist/cjs/wallets/manager/index.js.map +1 -1
  22. package/dist/esm/bridge/Webhook.js +62 -1
  23. package/dist/esm/bridge/Webhook.js.map +1 -1
  24. package/dist/esm/exports/react.js.map +1 -1
  25. package/dist/esm/exports/react.native.js.map +1 -1
  26. package/dist/esm/react/core/hooks/connection/types.js +2 -0
  27. package/dist/esm/react/core/hooks/connection/types.js.map +1 -0
  28. package/dist/esm/react/core/hooks/wallets/useAuthToken.js +11 -10
  29. package/dist/esm/react/core/hooks/wallets/useAuthToken.js.map +1 -1
  30. package/dist/esm/react/web/ui/ConnectWallet/Modal/ConnectEmbed.js.map +1 -1
  31. package/dist/esm/react/web/ui/ConnectWallet/Modal/ConnectModal.js.map +1 -1
  32. package/dist/esm/react/web/ui/ConnectWallet/Modal/ConnectModalContent.js +1 -1
  33. package/dist/esm/react/web/ui/ConnectWallet/Modal/ConnectModalContent.js.map +1 -1
  34. package/dist/esm/react/web/ui/ConnectWallet/useConnectModal.js.map +1 -1
  35. package/dist/esm/version.js +1 -1
  36. package/dist/esm/version.js.map +1 -1
  37. package/dist/esm/wallets/connection/autoConnect.js +3 -2
  38. package/dist/esm/wallets/connection/autoConnect.js.map +1 -1
  39. package/dist/esm/wallets/connection/autoConnectCore.js +15 -13
  40. package/dist/esm/wallets/connection/autoConnectCore.js.map +1 -1
  41. package/dist/esm/wallets/manager/index.js +2 -2
  42. package/dist/esm/wallets/manager/index.js.map +1 -1
  43. package/dist/scripts/bridge-widget.js +4 -4
  44. package/dist/types/bridge/Webhook.d.ts +22 -1
  45. package/dist/types/bridge/Webhook.d.ts.map +1 -1
  46. package/dist/types/exports/react.d.ts +1 -0
  47. package/dist/types/exports/react.d.ts.map +1 -1
  48. package/dist/types/exports/react.native.d.ts +3 -1
  49. package/dist/types/exports/react.native.d.ts.map +1 -1
  50. package/dist/types/react/core/hooks/connection/ConnectButtonProps.d.ts +5 -3
  51. package/dist/types/react/core/hooks/connection/ConnectButtonProps.d.ts.map +1 -1
  52. package/dist/types/react/core/hooks/connection/ConnectEmbedProps.d.ts +5 -3
  53. package/dist/types/react/core/hooks/connection/ConnectEmbedProps.d.ts.map +1 -1
  54. package/dist/types/react/core/hooks/connection/types.d.ts +3 -0
  55. package/dist/types/react/core/hooks/connection/types.d.ts.map +1 -0
  56. package/dist/types/react/core/hooks/wallets/useAuthToken.d.ts.map +1 -1
  57. package/dist/types/react/web/ui/ConnectWallet/Modal/ConnectEmbed.d.ts.map +1 -1
  58. package/dist/types/react/web/ui/ConnectWallet/Modal/ConnectModal.d.ts +2 -1
  59. package/dist/types/react/web/ui/ConnectWallet/Modal/ConnectModal.d.ts.map +1 -1
  60. package/dist/types/react/web/ui/ConnectWallet/Modal/ConnectModalContent.d.ts +2 -1
  61. package/dist/types/react/web/ui/ConnectWallet/Modal/ConnectModalContent.d.ts.map +1 -1
  62. package/dist/types/react/web/ui/ConnectWallet/useConnectModal.d.ts.map +1 -1
  63. package/dist/types/version.d.ts +1 -1
  64. package/dist/types/version.d.ts.map +1 -1
  65. package/dist/types/wallets/connection/autoConnect.d.ts +3 -2
  66. package/dist/types/wallets/connection/autoConnect.d.ts.map +1 -1
  67. package/dist/types/wallets/connection/autoConnectCore.d.ts.map +1 -1
  68. package/dist/types/wallets/connection/types.d.ts +4 -3
  69. package/dist/types/wallets/connection/types.d.ts.map +1 -1
  70. package/dist/types/wallets/manager/index.d.ts +2 -1
  71. package/dist/types/wallets/manager/index.d.ts.map +1 -1
  72. package/package.json +3 -3
  73. package/src/bridge/Webhook.test.ts +157 -0
  74. package/src/bridge/Webhook.ts +107 -0
  75. package/src/exports/react.native.ts +7 -0
  76. package/src/exports/react.ts +1 -0
  77. package/src/react/core/hooks/connection/ConnectButtonProps.ts +5 -3
  78. package/src/react/core/hooks/connection/ConnectEmbedProps.ts +5 -3
  79. package/src/react/core/hooks/connection/types.ts +6 -0
  80. package/src/react/core/hooks/wallets/useAuthToken.ts +19 -12
  81. package/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx +2 -1
  82. package/src/react/web/ui/ConnectWallet/Modal/ConnectModal.tsx +2 -1
  83. package/src/react/web/ui/ConnectWallet/Modal/ConnectModalContent.tsx +3 -2
  84. package/src/react/web/ui/ConnectWallet/useConnectModal.tsx +2 -1
  85. package/src/version.ts +1 -1
  86. package/src/wallets/connection/autoConnect.ts +3 -2
  87. package/src/wallets/connection/autoConnectCore.test.ts +26 -19
  88. package/src/wallets/connection/autoConnectCore.ts +15 -11
  89. package/src/wallets/connection/types.ts +4 -3
  90. package/src/wallets/manager/connection-manager.test.ts +1 -1
  91. package/src/wallets/manager/index.ts +4 -3
@@ -118,6 +118,28 @@ export async function parse(
118
118
  * The tolerance in seconds for the timestamp verification.
119
119
  */
120
120
  tolerance = 300, // Default to 5 minutes if not specified
121
+
122
+ /**
123
+ * Add various validations to the parsed payload to ensure it matches the expected values. Throws error if any validation fails.
124
+ */
125
+ verify?: {
126
+ /**
127
+ * Verify that the payload's the destination token amount (in wei) is greater than `minDestinationAmount` value
128
+ */
129
+ minDestinationAmount?: bigint;
130
+ /**
131
+ * Verify that the payload's destination token address is the same as `destinationTokenAddress` value
132
+ */
133
+ destinationTokenAddress?: string;
134
+ /**
135
+ * Verify that the payload's destination chain id is the same as `destinationChainId` value
136
+ */
137
+ destinationChainId?: number;
138
+ /**
139
+ * Verify that the payload's receiver address is the same as `receiverAddress` value.
140
+ */
141
+ receiverAddress?: string;
142
+ },
121
143
  ): Promise<WebhookPayload> {
122
144
  // Get the signature and timestamp from headers
123
145
  const receivedSignature =
@@ -183,5 +205,90 @@ export async function parse(
183
205
  );
184
206
  }
185
207
 
208
+ if (verify) {
209
+ // verify receiver address
210
+ if (verify.receiverAddress) {
211
+ if (
212
+ parsedPayload.data.receiver.toLowerCase() !==
213
+ verify.receiverAddress.toLowerCase()
214
+ ) {
215
+ throw new Error(
216
+ `Verification Failed: receiverAddress mismatch, Expected: ${verify.receiverAddress}, Received: ${parsedPayload.data.receiver}`,
217
+ );
218
+ }
219
+ }
220
+
221
+ // verify destination token address
222
+ if (verify.destinationTokenAddress) {
223
+ // onchain transaction
224
+ if ("destinationToken" in parsedPayload.data) {
225
+ if (
226
+ parsedPayload.data.destinationToken.address.toLowerCase() !==
227
+ verify.destinationTokenAddress.toLowerCase()
228
+ ) {
229
+ throw new Error(
230
+ `Verification Failed: destinationTokenAddress mismatch, Expected: ${verify.destinationTokenAddress}, Received: ${parsedPayload.data.destinationToken.address}`,
231
+ );
232
+ }
233
+ }
234
+ // onramp transaction
235
+ else if ("onramp" in parsedPayload.data) {
236
+ if (
237
+ parsedPayload.data.token.address.toLowerCase() !==
238
+ verify.destinationTokenAddress.toLowerCase()
239
+ ) {
240
+ throw new Error(
241
+ `Verification Failed: destinationTokenAddress mismatch, Expected: ${verify.destinationTokenAddress}, Received: ${parsedPayload.data.token.address}`,
242
+ );
243
+ }
244
+ }
245
+ }
246
+
247
+ // verify destination chain id
248
+ if (verify.destinationChainId) {
249
+ // onchain tx
250
+ if ("destinationToken" in parsedPayload.data) {
251
+ if (
252
+ parsedPayload.data.destinationToken.chainId !==
253
+ verify.destinationChainId
254
+ ) {
255
+ throw new Error(
256
+ `Verification Failed: destinationChainId mismatch, Expected: ${verify.destinationChainId}, Received: ${parsedPayload.data.destinationToken.chainId}`,
257
+ );
258
+ }
259
+ }
260
+ // onramp tx
261
+ else if ("onramp" in parsedPayload.data) {
262
+ if (parsedPayload.data.token.chainId !== verify.destinationChainId) {
263
+ throw new Error(
264
+ `Verification Failed: destinationChainId mismatch, Expected: ${verify.destinationChainId}, Received: ${parsedPayload.data.token.chainId}`,
265
+ );
266
+ }
267
+ }
268
+ }
269
+
270
+ // verify amount
271
+ if (verify.minDestinationAmount) {
272
+ // onchain tx
273
+ if ("destinationAmount" in parsedPayload.data) {
274
+ if (
275
+ parsedPayload.data.destinationAmount < verify.minDestinationAmount
276
+ ) {
277
+ throw new Error(
278
+ `Verification Failed: minDestinationAmount, Expected minimum amount to be ${verify.minDestinationAmount}, Received: ${parsedPayload.data.destinationAmount}`,
279
+ );
280
+ }
281
+ }
282
+ // onramp tx
283
+ else if ("onramp" in parsedPayload.data) {
284
+ if (parsedPayload.data.amount < verify.minDestinationAmount) {
285
+ throw new Error(
286
+ `Verification Failed: minDestinationAmount, Expected minimum amount to be ${verify.minDestinationAmount}, Received: ${parsedPayload.data.amount}`,
287
+ );
288
+ }
289
+ }
290
+ }
291
+ }
292
+
186
293
  return parsedPayload satisfies WebhookPayload;
187
294
  }
@@ -17,7 +17,14 @@ export type {
17
17
  ConnectButton_detailsButtonOptions,
18
18
  ConnectButton_detailsModalOptions,
19
19
  ConnectButtonProps,
20
+ DirectPaymentOptions,
21
+ FundWalletOptions,
22
+ PaymentInfo,
23
+ PayUIOptions,
24
+ TransactionOptions,
20
25
  } from "../react/core/hooks/connection/ConnectButtonProps.js";
26
+ export type { ConnectEmbedProps } from "../react/core/hooks/connection/ConnectEmbedProps.js";
27
+ export type { OnConnectCallback } from "../react/core/hooks/connection/types.js";
21
28
  export { useContractEvents } from "../react/core/hooks/contract/useContractEvents.js";
22
29
  // contract
23
30
  export { useReadContract } from "../react/core/hooks/contract/useReadContract.js";
@@ -23,6 +23,7 @@ export type {
23
23
  TransactionOptions,
24
24
  } from "../react/core/hooks/connection/ConnectButtonProps.js";
25
25
  export type { ConnectEmbedProps } from "../react/core/hooks/connection/ConnectEmbedProps.js";
26
+ export type { OnConnectCallback } from "../react/core/hooks/connection/types.js";
26
27
  export { useContractEvents } from "../react/core/hooks/contract/useContractEvents.js";
27
28
  // contract
28
29
  export { useReadContract } from "../react/core/hooks/contract/useReadContract.js";
@@ -25,6 +25,7 @@ import type {
25
25
  TokenInfo,
26
26
  } from "../../utils/defaultTokens.js";
27
27
  import type { SiweAuthOptions } from "../auth/useSiweAuth.js";
28
+ import type { OnConnectCallback } from "./types.js";
28
29
 
29
30
  export type PaymentInfo = Prettify<
30
31
  {
@@ -937,13 +938,14 @@ export type ConnectButtonProps = {
937
938
  *
938
939
  * ```tsx
939
940
  * <ConnectButton
940
- * onConnect={(wallet) => {
941
- * console.log("connected to", wallet)
941
+ * onConnect={(activeWallet, allConnectedWallets) => {
942
+ * console.log("connected to", activeWallet)
943
+ * console.log("all connected wallets", allConnectedWallets)
942
944
  * }}
943
945
  * />
944
946
  * ```
945
947
  */
946
- onConnect?: (wallet: Wallet) => void;
948
+ onConnect?: OnConnectCallback;
947
949
 
948
950
  /**
949
951
  * Called when the user disconnects the wallet by clicking on the "Disconnect Wallet" button in the `ConnectButton`'s Details Modal.
@@ -8,6 +8,7 @@ import type { WelcomeScreen } from "../../../web/ui/ConnectWallet/screens/types.
8
8
  import type { LocaleId } from "../../../web/ui/types.js";
9
9
  import type { Theme } from "../../design-system/index.js";
10
10
  import type { SiweAuthOptions } from "../auth/useSiweAuth.js";
11
+ import type { OnConnectCallback } from "./types.js";
11
12
 
12
13
  export type ConnectEmbedProps = {
13
14
  /**
@@ -213,14 +214,15 @@ export type ConnectEmbedProps = {
213
214
  *
214
215
  * ```tsx
215
216
  * <ConnectEmbed
216
- * onConnect={(wallet) => {
217
- * console.log("connected to", wallet)
217
+ * onConnect={(activeWallet, allConnectedWallets) => {
218
+ * console.log("connected to", activeWallet)
219
+ * console.log("all connected wallets", allConnectedWallets)
218
220
  * }}
219
221
  * />
220
222
  * ```
221
223
  * ```
222
224
  */
223
- onConnect?: (wallet: Wallet) => void;
225
+ onConnect?: OnConnectCallback;
224
226
 
225
227
  /**
226
228
  * By default, A "Powered by Thirdweb" branding is shown at the bottom of the embed.
@@ -0,0 +1,6 @@
1
+ import type { Wallet } from "../../../../wallets/interfaces/wallet.js";
2
+
3
+ export type OnConnectCallback = (
4
+ activeWallet: Wallet,
5
+ allConnectedWallets: Wallet[],
6
+ ) => void;
@@ -1,5 +1,8 @@
1
- import { useActiveAccount } from "./useActiveAccount.js";
2
- import { useActiveWallet } from "./useActiveWallet.js";
1
+ import type {
2
+ EcosystemWallet,
3
+ InAppWallet,
4
+ } from "../../../../wallets/in-app/core/wallet/types.js";
5
+ import { useConnectedWallets } from "./useConnectedWallets.js";
3
6
 
4
7
  /**
5
8
  * A hook that returns the authentication token (JWT) for the currently active wallet.
@@ -26,16 +29,20 @@ import { useActiveWallet } from "./useActiveWallet.js";
26
29
  * @wallet
27
30
  */
28
31
  export function useAuthToken() {
29
- const activeWallet = useActiveWallet();
30
- const activeAccount = useActiveAccount();
31
- // if the active wallet is an in-app wallet and the active account is the same as the active wallet's account, return the auth token for the in-app wallet
32
- if (
33
- activeWallet?.getAuthToken &&
34
- activeAccount &&
35
- activeAccount.address === activeWallet.getAccount()?.address
36
- ) {
37
- return activeWallet.getAuthToken();
32
+ const walletWithAuthToken = useWalletWithAuthToken();
33
+ // if any connected wallet has an auth token, return it
34
+ if (walletWithAuthToken) {
35
+ return walletWithAuthToken.getAuthToken();
38
36
  }
39
- // all other wallets don't expose an auth token for now
37
+ // no wallet with an auth token found
40
38
  return null;
41
39
  }
40
+
41
+ function useWalletWithAuthToken(): InAppWallet | EcosystemWallet | undefined {
42
+ const wallets = useConnectedWallets();
43
+ const wallet = wallets.find((w) => !!w.getAuthToken) as
44
+ | InAppWallet
45
+ | EcosystemWallet
46
+ | undefined;
47
+ return wallet ?? undefined;
48
+ }
@@ -16,6 +16,7 @@ import {
16
16
  useSiweAuth,
17
17
  } from "../../../../core/hooks/auth/useSiweAuth.js";
18
18
  import type { ConnectEmbedProps } from "../../../../core/hooks/connection/ConnectEmbedProps.js";
19
+ import type { OnConnectCallback } from "../../../../core/hooks/connection/types.js";
19
20
  import { useActiveAccount } from "../../../../core/hooks/wallets/useActiveAccount.js";
20
21
  import { useActiveWallet } from "../../../../core/hooks/wallets/useActiveWallet.js";
21
22
  import { useIsAutoConnecting } from "../../../../core/hooks/wallets/useIsAutoConnecting.js";
@@ -354,7 +355,7 @@ const ConnectEmbedContent = (props: {
354
355
  | true
355
356
  | undefined;
356
357
  localeId: LocaleId;
357
- onConnect: ((wallet: Wallet) => void) | undefined;
358
+ onConnect: OnConnectCallback | undefined;
358
359
  recommendedWallets: Wallet[] | undefined;
359
360
  showAllWallets: boolean | undefined;
360
361
  hiddenWallets: WalletId[] | undefined;
@@ -6,6 +6,7 @@ import type { Wallet } from "../../../../../wallets/interfaces/wallet.js";
6
6
  import type { SmartWalletOptions } from "../../../../../wallets/smart/types.js";
7
7
  import type { WalletId } from "../../../../../wallets/wallet-types.js";
8
8
  import type { SiweAuthOptions } from "../../../../core/hooks/auth/useSiweAuth.js";
9
+ import type { OnConnectCallback } from "../../../../core/hooks/connection/types.js";
9
10
  import { useActiveAccount } from "../../../../core/hooks/wallets/useActiveAccount.js";
10
11
  import {
11
12
  useIsWalletModalOpen,
@@ -26,7 +27,7 @@ type ConnectModalOptions = {
26
27
  wallets: Wallet[];
27
28
  accountAbstraction: SmartWalletOptions | undefined;
28
29
  auth: SiweAuthOptions | undefined;
29
- onConnect: ((wallet: Wallet) => void) | undefined;
30
+ onConnect: OnConnectCallback | undefined;
30
31
  size: "compact" | "wide";
31
32
  welcomeScreen: WelcomeScreen | undefined;
32
33
  meta: {
@@ -9,6 +9,7 @@ import {
9
9
  type SiweAuthOptions,
10
10
  useSiweAuth,
11
11
  } from "../../../../core/hooks/auth/useSiweAuth.js";
12
+ import type { OnConnectCallback } from "../../../../core/hooks/connection/types.js";
12
13
  import { useActiveAccount } from "../../../../core/hooks/wallets/useActiveAccount.js";
13
14
  import { useActiveWallet } from "../../../../core/hooks/wallets/useActiveWallet.js";
14
15
  import { useSetActiveWallet } from "../../../../core/hooks/wallets/useSetActiveWallet.js";
@@ -43,7 +44,7 @@ export const ConnectModalContent = (props: {
43
44
  wallets: Wallet[];
44
45
  accountAbstraction: SmartWalletOptions | undefined;
45
46
  auth: SiweAuthOptions | undefined;
46
- onConnect: ((wallet: Wallet) => void) | undefined;
47
+ onConnect: OnConnectCallback | undefined;
47
48
  size: "compact" | "wide";
48
49
  meta: {
49
50
  title?: string;
@@ -93,7 +94,7 @@ export const ConnectModalContent = (props: {
93
94
  }
94
95
 
95
96
  if (props.onConnect) {
96
- props.onConnect(wallet);
97
+ props.onConnect(wallet, connectionManager.connectedWallets.getValue());
97
98
  }
98
99
 
99
100
  onModalUnmount(() => {
@@ -8,6 +8,7 @@ import type { AppMetadata } from "../../../../wallets/types.js";
8
8
  import type { WalletId } from "../../../../wallets/wallet-types.js";
9
9
  import type { Theme } from "../../../core/design-system/index.js";
10
10
  import type { SiweAuthOptions } from "../../../core/hooks/auth/useSiweAuth.js";
11
+ import type { OnConnectCallback } from "../../../core/hooks/connection/types.js";
11
12
  import { SetRootElementContext } from "../../../core/providers/RootElementContext.js";
12
13
  import { WalletUIStatesProvider } from "../../providers/wallet-ui-states-provider.js";
13
14
  import { canFitWideModal } from "../../utils/canFitWideModal.js";
@@ -90,7 +91,7 @@ export function useConnectModal() {
90
91
 
91
92
  function Modal(
92
93
  props: UseConnectModalOptions & {
93
- onConnect: (wallet: Wallet) => void;
94
+ onConnect: OnConnectCallback;
94
95
  onClose: () => void;
95
96
  connectLocale: ConnectLocale;
96
97
  },
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "5.111.10";
1
+ export const version = "5.112.0";
@@ -17,8 +17,9 @@ import type { AutoConnectProps } from "./types.js";
17
17
  *
18
18
  * const autoConnected = await autoConnect({
19
19
  * client,
20
- * onConnect: (wallet) => {
21
- * console.log("wallet", wallet);
20
+ * onConnect: (activeWallet, allConnectedWallets) => {
21
+ * console.log("active wallet", activeWallet);
22
+ * console.log("all connected wallets", allConnectedWallets);
22
23
  * },
23
24
  * });
24
25
  * ```
@@ -19,6 +19,23 @@ describe("useAutoConnectCore", () => {
19
19
  const mockStorage = new MockStorage();
20
20
  const manager = createConnectionManager(mockStorage);
21
21
 
22
+ const wallet1 = createWalletAdapter({
23
+ adaptedAccount: TEST_ACCOUNT_A,
24
+ chain: ethereum,
25
+ client: TEST_CLIENT,
26
+ onDisconnect: () => {},
27
+ switchChain: () => {},
28
+ });
29
+
30
+ const wallet2 = createWalletAdapter({
31
+ adaptedAccount: { ...TEST_ACCOUNT_A, address: "0x123" },
32
+ chain: ethereum,
33
+ client: TEST_CLIENT,
34
+ onDisconnect: () => {},
35
+ switchChain: () => {},
36
+ });
37
+ wallet2.id = "io.metamask" as unknown as "adapter";
38
+
22
39
  afterEach(() => {
23
40
  vi.restoreAllMocks();
24
41
  });
@@ -161,23 +178,6 @@ describe("useAutoConnectCore", () => {
161
178
  });
162
179
 
163
180
  it("should connect multiple wallets correctly", async () => {
164
- const wallet1 = createWalletAdapter({
165
- adaptedAccount: TEST_ACCOUNT_A,
166
- chain: ethereum,
167
- client: TEST_CLIENT,
168
- onDisconnect: () => {},
169
- switchChain: () => {},
170
- });
171
-
172
- const wallet2 = createWalletAdapter({
173
- adaptedAccount: { ...TEST_ACCOUNT_A, address: "0x123" },
174
- chain: ethereum,
175
- client: TEST_CLIENT,
176
- onDisconnect: () => {},
177
- switchChain: () => {},
178
- });
179
- wallet2.id = "io.metamask" as unknown as "adapter";
180
-
181
181
  mockStorage.setItem("thirdweb:active-wallet-id", wallet1.id);
182
182
  mockStorage.setItem(
183
183
  "thirdweb:connected-wallet-ids",
@@ -228,7 +228,10 @@ describe("useAutoConnectCore", () => {
228
228
  storage: mockStorage,
229
229
  });
230
230
 
231
- expect(mockOnConnect).toHaveBeenCalledWith(wallet);
231
+ expect(mockOnConnect).toHaveBeenCalledWith(
232
+ wallet,
233
+ manager.connectedWallets.getValue(),
234
+ );
232
235
  });
233
236
 
234
237
  it("should continue even if onConnect callback throws", async () => {
@@ -262,7 +265,10 @@ describe("useAutoConnectCore", () => {
262
265
  storage: mockStorage,
263
266
  });
264
267
 
265
- expect(mockOnConnect).toHaveBeenCalledWith(wallet);
268
+ expect(mockOnConnect).toHaveBeenCalledWith(
269
+ wallet,
270
+ manager.connectedWallets.getValue(),
271
+ );
266
272
  });
267
273
 
268
274
  it("should call setLastAuthProvider if authProvider is present", async () => {
@@ -300,6 +306,7 @@ describe("useAutoConnectCore", () => {
300
306
  });
301
307
 
302
308
  it("should set connection status to disconnect if no connectedWallet is returned", async () => {
309
+ manager.activeWalletStore.setValue(undefined);
303
310
  const wallet = createWalletAdapter({
304
311
  adaptedAccount: TEST_ACCOUNT_A,
305
312
  chain: ethereum,
@@ -152,22 +152,12 @@ const _autoConnectCore = async ({
152
152
 
153
153
  try {
154
154
  // connected wallet could be activeWallet or smart wallet
155
- const connectedWallet = await (connectOverride
155
+ await (connectOverride
156
156
  ? connectOverride(activeWallet)
157
157
  : manager.connect(activeWallet, {
158
158
  accountAbstraction: props.accountAbstraction,
159
159
  client: props.client,
160
160
  }));
161
- if (connectedWallet) {
162
- autoConnected = true;
163
- try {
164
- onConnect?.(connectedWallet);
165
- } catch {
166
- // ignore
167
- }
168
- } else {
169
- manager.activeWalletConnectionStatusStore.setValue("disconnected");
170
- }
171
161
  } catch (e) {
172
162
  if (e instanceof Error) {
173
163
  console.warn("Error auto connecting wallet:", e.message);
@@ -216,6 +206,20 @@ const _autoConnectCore = async ({
216
206
  });
217
207
  }
218
208
  manager.isAutoConnecting.setValue(false);
209
+
210
+ const connectedActiveWallet = manager.activeWalletStore.getValue();
211
+ const allConnectedWallets = manager.connectedWallets.getValue();
212
+ if (connectedActiveWallet) {
213
+ autoConnected = true;
214
+ try {
215
+ onConnect?.(connectedActiveWallet, allConnectedWallets);
216
+ } catch (e) {
217
+ console.error("Error calling onConnect callback:", e);
218
+ }
219
+ } else {
220
+ manager.activeWalletConnectionStatusStore.setValue("disconnected");
221
+ }
222
+
219
223
  return autoConnected; // useQuery needs a return value
220
224
  };
221
225
 
@@ -101,13 +101,14 @@ export type AutoConnectProps = {
101
101
  *
102
102
  * ```tsx
103
103
  * <AutoConnect
104
- * onConnect={(wallet) => {
105
- * console.log("auto connected to", wallet)
104
+ * onConnect={(activeWallet, otherWallets) => {
105
+ * console.log("auto connected to", activeWallet)
106
+ * console.log("other wallets that were also connected", otherWallets)
106
107
  * }}
107
108
  * />
108
109
  * ```
109
110
  */
110
- onConnect?: (wallet: Wallet) => void;
111
+ onConnect?: (activeWallet: Wallet, otherWallets: Wallet[]) => void;
111
112
 
112
113
  /**
113
114
  * Optional chain to autoconnect to
@@ -49,7 +49,7 @@ describe.runIf(process.env.TW_SECRET_KEY)("Connection Manager", () => {
49
49
 
50
50
  await manager.connect(wallet, { client, onConnect });
51
51
 
52
- expect(onConnect).toHaveBeenCalledWith(wallet);
52
+ expect(onConnect).toHaveBeenCalledWith(wallet, [wallet]);
53
53
  expect(storage.setItem).toHaveBeenCalled();
54
54
  });
55
55
 
@@ -1,6 +1,7 @@
1
1
  import type { Chain } from "../../chains/types.js";
2
2
  import { cacheChains } from "../../chains/utils.js";
3
3
  import type { ThirdwebClient } from "../../client/client.js";
4
+ import type { OnConnectCallback } from "../../react/core/hooks/connection/types.js";
4
5
  import { computedStore } from "../../reactive/computedStore.js";
5
6
  import { effect } from "../../reactive/effect.js";
6
7
  import { createStore } from "../../reactive/store.js";
@@ -29,7 +30,7 @@ export type ConnectManagerOptions = {
29
30
  client: ThirdwebClient;
30
31
  accountAbstraction?: SmartWalletOptions;
31
32
  setWalletAsActive?: boolean;
32
- onConnect?: (wallet: Wallet) => void;
33
+ onConnect?: OnConnectCallback;
33
34
  };
34
35
 
35
36
  /**
@@ -158,7 +159,7 @@ export function createConnectionManager(storage: AsyncStorage) {
158
159
  wallet.subscribe("accountChanged", async () => {
159
160
  // We reimplement connect here to prevent memory leaks
160
161
  const newWallet = await handleConnection(wallet, options);
161
- options?.onConnect?.(newWallet);
162
+ options?.onConnect?.(newWallet, connectedWallets.getValue());
162
163
  });
163
164
 
164
165
  return activeWallet;
@@ -167,7 +168,7 @@ export function createConnectionManager(storage: AsyncStorage) {
167
168
  const connect = async (wallet: Wallet, options?: ConnectManagerOptions) => {
168
169
  // connectedWallet can be either wallet or smartWallet
169
170
  const connectedWallet = await handleConnection(wallet, options);
170
- options?.onConnect?.(connectedWallet);
171
+ options?.onConnect?.(connectedWallet, connectedWallets.getValue());
171
172
  return connectedWallet;
172
173
  };
173
174