thirdweb 5.80.1-nightly-a3f59e50e249d8b4fac765e025fc2cd102093e9c-20250105000328 → 5.81.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 (59) hide show
  1. package/dist/cjs/contract/actions/compiler-metadata.js.map +1 -1
  2. package/dist/cjs/react/core/hooks/wallets/useAutoConnect.js +28 -9
  3. package/dist/cjs/react/core/hooks/wallets/useAutoConnect.js.map +1 -1
  4. package/dist/cjs/version.js +1 -1
  5. package/dist/cjs/version.js.map +1 -1
  6. package/dist/cjs/wallets/in-app/core/wallet/in-app-core.js +9 -3
  7. package/dist/cjs/wallets/in-app/core/wallet/in-app-core.js.map +1 -1
  8. package/dist/cjs/wallets/in-app/core/wallet/index.js +8 -10
  9. package/dist/cjs/wallets/in-app/core/wallet/index.js.map +1 -1
  10. package/dist/cjs/wallets/injected/index.js +2 -1
  11. package/dist/cjs/wallets/injected/index.js.map +1 -1
  12. package/dist/cjs/wallets/smart/index.js +14 -13
  13. package/dist/cjs/wallets/smart/index.js.map +1 -1
  14. package/dist/cjs/wallets/smart/smart-wallet.js +12 -10
  15. package/dist/cjs/wallets/smart/smart-wallet.js.map +1 -1
  16. package/dist/esm/contract/actions/compiler-metadata.js.map +1 -1
  17. package/dist/esm/react/core/hooks/wallets/useAutoConnect.js +27 -9
  18. package/dist/esm/react/core/hooks/wallets/useAutoConnect.js.map +1 -1
  19. package/dist/esm/version.js +1 -1
  20. package/dist/esm/version.js.map +1 -1
  21. package/dist/esm/wallets/in-app/core/wallet/in-app-core.js +9 -3
  22. package/dist/esm/wallets/in-app/core/wallet/in-app-core.js.map +1 -1
  23. package/dist/esm/wallets/in-app/core/wallet/index.js +8 -10
  24. package/dist/esm/wallets/in-app/core/wallet/index.js.map +1 -1
  25. package/dist/esm/wallets/injected/index.js +2 -1
  26. package/dist/esm/wallets/injected/index.js.map +1 -1
  27. package/dist/esm/wallets/smart/index.js +12 -11
  28. package/dist/esm/wallets/smart/index.js.map +1 -1
  29. package/dist/esm/wallets/smart/smart-wallet.js +12 -10
  30. package/dist/esm/wallets/smart/smart-wallet.js.map +1 -1
  31. package/dist/types/contract/actions/compiler-metadata.d.ts +9 -0
  32. package/dist/types/contract/actions/compiler-metadata.d.ts.map +1 -1
  33. package/dist/types/react/core/hooks/connection/types.d.ts +4 -0
  34. package/dist/types/react/core/hooks/connection/types.d.ts.map +1 -1
  35. package/dist/types/react/core/hooks/wallets/useAutoConnect.d.ts +12 -0
  36. package/dist/types/react/core/hooks/wallets/useAutoConnect.d.ts.map +1 -1
  37. package/dist/types/version.d.ts +1 -1
  38. package/dist/types/version.d.ts.map +1 -1
  39. package/dist/types/wallets/in-app/core/wallet/in-app-core.d.ts.map +1 -1
  40. package/dist/types/wallets/in-app/core/wallet/index.d.ts +10 -2
  41. package/dist/types/wallets/in-app/core/wallet/index.d.ts.map +1 -1
  42. package/dist/types/wallets/injected/index.d.ts.map +1 -1
  43. package/dist/types/wallets/smart/index.d.ts +2 -2
  44. package/dist/types/wallets/smart/index.d.ts.map +1 -1
  45. package/package.json +1 -1
  46. package/src/adapters/eip1193/from-eip1193.test.ts +18 -0
  47. package/src/contract/actions/compiler-metadata.ts +5 -0
  48. package/src/react/core/hooks/connection/types.ts +5 -0
  49. package/src/react/core/hooks/wallets/useAutoConnect.ts +41 -12
  50. package/src/react/core/hooks/wallets/useAutoConnectCore.test.tsx +187 -0
  51. package/src/version.ts +1 -1
  52. package/src/wallets/in-app/core/wallet/in-app-core.test.ts +115 -54
  53. package/src/wallets/in-app/core/wallet/in-app-core.ts +22 -11
  54. package/src/wallets/in-app/core/wallet/index.ts +10 -13
  55. package/src/wallets/in-app/web/lib/get-url-token.test.tsx +92 -0
  56. package/src/wallets/injected/index.ts +2 -1
  57. package/src/wallets/smart/index.ts +14 -18
  58. package/src/wallets/smart/smart-wallet.ts +13 -13
  59. package/src/wallets/smart/smart.test.ts +19 -39
@@ -113,4 +113,9 @@ export type AutoConnectProps = {
113
113
  * Optional chain to autoconnect to
114
114
  */
115
115
  chain?: Chain;
116
+
117
+ /**
118
+ * Callback to be called when the connection is timeout-ed
119
+ */
120
+ onTimeout?: () => void;
116
121
  };
@@ -1,9 +1,12 @@
1
1
  "use client";
2
2
 
3
3
  import { useQuery } from "@tanstack/react-query";
4
+ import type { Chain } from "../../../../chains/types.js";
5
+ import type { ThirdwebClient } from "../../../../client/client.js";
4
6
  import type { AsyncStorage } from "../../../../utils/storage/AsyncStorage.js";
5
7
  import { isEcosystemWallet } from "../../../../wallets/ecosystem/is-ecosystem-wallet.js";
6
8
  import { ClientScopedStorage } from "../../../../wallets/in-app/core/authentication/client-scoped-storage.js";
9
+ import type { AuthStoredTokenWithCookieReturnType } from "../../../../wallets/in-app/core/authentication/types.js";
7
10
  import { getUrlToken } from "../../../../wallets/in-app/web/lib/get-url-token.js";
8
11
  import type { Wallet } from "../../../../wallets/interfaces/wallet.js";
9
12
  import {
@@ -83,14 +86,6 @@ export function useAutoConnectCore(
83
86
  const lastConnectedChain =
84
87
  (await getLastConnectedChain(storage)) || props.chain;
85
88
 
86
- async function handleWalletConnection(wallet: Wallet) {
87
- return wallet.autoConnect({
88
- client: props.client,
89
- chain: lastConnectedChain ?? undefined,
90
- authResult,
91
- });
92
- }
93
-
94
89
  const availableWallets = [...wallets, ...(getInstalledWallets?.() ?? [])];
95
90
  const activeWallet =
96
91
  lastActiveWalletId &&
@@ -100,9 +95,22 @@ export function useAutoConnectCore(
100
95
  if (activeWallet) {
101
96
  try {
102
97
  setConnectionStatus("connecting"); // only set connecting status if we are connecting the last active EOA
103
- await timeoutPromise(handleWalletConnection(activeWallet), {
104
- ms: timeout,
105
- message: `AutoConnect timeout: ${timeout}ms limit exceeded.`,
98
+ await timeoutPromise(
99
+ handleWalletConnection({
100
+ wallet: activeWallet,
101
+ client: props.client,
102
+ lastConnectedChain,
103
+ authResult,
104
+ }),
105
+ {
106
+ ms: timeout,
107
+ message: `AutoConnect timeout: ${timeout}ms limit exceeded.`,
108
+ },
109
+ ).catch((err) => {
110
+ console.warn(err.message);
111
+ if (props.onTimeout) {
112
+ props.onTimeout();
113
+ }
106
114
  });
107
115
 
108
116
  // connected wallet could be activeWallet or smart wallet
@@ -138,7 +146,12 @@ export function useAutoConnectCore(
138
146
 
139
147
  for (const wallet of otherWallets) {
140
148
  try {
141
- await handleWalletConnection(wallet);
149
+ await handleWalletConnection({
150
+ wallet,
151
+ client: props.client,
152
+ lastConnectedChain,
153
+ authResult,
154
+ });
142
155
  manager.addConnectedWallet(wallet);
143
156
  } catch {
144
157
  // no-op
@@ -158,3 +171,19 @@ export function useAutoConnectCore(
158
171
 
159
172
  return query;
160
173
  }
174
+
175
+ /**
176
+ * @internal
177
+ */
178
+ export async function handleWalletConnection(props: {
179
+ wallet: Wallet;
180
+ client: ThirdwebClient;
181
+ authResult: AuthStoredTokenWithCookieReturnType | undefined;
182
+ lastConnectedChain: Chain | undefined;
183
+ }) {
184
+ return props.wallet.autoConnect({
185
+ client: props.client,
186
+ chain: props.lastConnectedChain,
187
+ authResult: props.authResult,
188
+ });
189
+ }
@@ -0,0 +1,187 @@
1
+ import { renderHook, waitFor } from "@testing-library/react";
2
+ import type { ReactNode } from "react";
3
+ import { describe, expect, it, vi } from "vitest";
4
+ import { MockStorage } from "~test/mocks/storage.js";
5
+ import { TEST_CLIENT } from "~test/test-clients.js";
6
+ import { TEST_ACCOUNT_A } from "~test/test-wallets.js";
7
+ import { createWalletAdapter } from "../../../../adapters/wallet-adapter.js";
8
+ import { ethereum } from "../../../../chains/chain-definitions/ethereum.js";
9
+ import { isAddress } from "../../../../utils/address.js";
10
+ import { createConnectionManager } from "../../../../wallets/manager/index.js";
11
+ import type { WalletId } from "../../../../wallets/wallet-types.js";
12
+ import { ThirdwebProvider } from "../../../web/providers/thirdweb-provider.js";
13
+ import { ConnectionManagerCtx } from "../../providers/connection-manager.js";
14
+ import {
15
+ handleWalletConnection,
16
+ useAutoConnectCore,
17
+ } from "./useAutoConnect.js";
18
+
19
+ describe("useAutoConnectCore", () => {
20
+ const mockStorage = new MockStorage();
21
+ const manager = createConnectionManager(mockStorage);
22
+
23
+ // Create a wrapper component with the mocked context
24
+ const wrapper = ({ children }: { children: ReactNode }) => {
25
+ return (
26
+ <ThirdwebProvider>
27
+ <ConnectionManagerCtx.Provider value={manager}>
28
+ {children}
29
+ </ConnectionManagerCtx.Provider>
30
+ </ThirdwebProvider>
31
+ );
32
+ };
33
+
34
+ it("should return a useQuery result", async () => {
35
+ const wallet = createWalletAdapter({
36
+ adaptedAccount: TEST_ACCOUNT_A,
37
+ client: TEST_CLIENT,
38
+ chain: ethereum,
39
+ onDisconnect: () => {},
40
+ switchChain: () => {},
41
+ });
42
+ const { result } = renderHook(
43
+ () =>
44
+ useAutoConnectCore(
45
+ mockStorage,
46
+ {
47
+ wallets: [wallet],
48
+ client: TEST_CLIENT,
49
+ },
50
+ (id: WalletId) =>
51
+ createWalletAdapter({
52
+ adaptedAccount: TEST_ACCOUNT_A,
53
+ client: TEST_CLIENT,
54
+ chain: ethereum,
55
+ onDisconnect: () => {
56
+ console.warn(id);
57
+ },
58
+ switchChain: () => {},
59
+ }),
60
+ ),
61
+ { wrapper },
62
+ );
63
+ expect("data" in result.current).toBeTruthy();
64
+ await waitFor(() => {
65
+ expect(typeof result.current.data).toBe("boolean");
66
+ });
67
+ });
68
+
69
+ it("should return `false` if there's no lastConnectedWalletIds", async () => {
70
+ const wallet = createWalletAdapter({
71
+ adaptedAccount: TEST_ACCOUNT_A,
72
+ client: TEST_CLIENT,
73
+ chain: ethereum,
74
+ onDisconnect: () => {},
75
+ switchChain: () => {},
76
+ });
77
+ const { result } = renderHook(
78
+ () =>
79
+ useAutoConnectCore(
80
+ mockStorage,
81
+ {
82
+ wallets: [wallet],
83
+ client: TEST_CLIENT,
84
+ },
85
+ (id: WalletId) =>
86
+ createWalletAdapter({
87
+ adaptedAccount: TEST_ACCOUNT_A,
88
+ client: TEST_CLIENT,
89
+ chain: ethereum,
90
+ onDisconnect: () => {
91
+ console.warn(id);
92
+ },
93
+ switchChain: () => {},
94
+ }),
95
+ ),
96
+ { wrapper },
97
+ );
98
+ await waitFor(
99
+ () => {
100
+ expect(result.current.data).toBe(false);
101
+ },
102
+ { timeout: 1000 },
103
+ );
104
+ });
105
+
106
+ it("should call onTimeout on ... timeout", async () => {
107
+ const wallet = createWalletAdapter({
108
+ adaptedAccount: TEST_ACCOUNT_A,
109
+ client: TEST_CLIENT,
110
+ chain: ethereum,
111
+ onDisconnect: () => {},
112
+ switchChain: () => {},
113
+ });
114
+ mockStorage.setItem("thirdweb:active-wallet-id", wallet.id);
115
+ const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
116
+ const infoSpy = vi.spyOn(console, "info").mockImplementation(() => {});
117
+ // Purposefully mock the wallet.autoConnect method to test the timeout logic
118
+ wallet.autoConnect = () =>
119
+ new Promise((resolve) => {
120
+ setTimeout(() => {
121
+ // @ts-ignore Mock purpose
122
+ resolve("Connection successful");
123
+ }, 2100);
124
+ });
125
+ renderHook(
126
+ () =>
127
+ useAutoConnectCore(
128
+ mockStorage,
129
+ {
130
+ wallets: [wallet],
131
+ client: TEST_CLIENT,
132
+ onTimeout: () => console.info("TIMEOUTTED"),
133
+ timeout: 0,
134
+ },
135
+ (id: WalletId) =>
136
+ createWalletAdapter({
137
+ adaptedAccount: TEST_ACCOUNT_A,
138
+ client: TEST_CLIENT,
139
+ chain: ethereum,
140
+ onDisconnect: () => {
141
+ console.warn(id);
142
+ },
143
+ switchChain: () => {},
144
+ }),
145
+ ),
146
+ { wrapper },
147
+ );
148
+ await waitFor(
149
+ () => {
150
+ expect(warnSpy).toHaveBeenCalled();
151
+ expect(warnSpy).toHaveBeenCalledWith(
152
+ "AutoConnect timeout: 0ms limit exceeded.",
153
+ );
154
+ expect(infoSpy).toHaveBeenCalled();
155
+ expect(infoSpy).toHaveBeenCalledWith("TIMEOUTTED");
156
+ warnSpy.mockRestore();
157
+ },
158
+ { timeout: 2000 },
159
+ );
160
+ });
161
+ });
162
+
163
+ describe("handleWalletConnection", () => {
164
+ const wallet = createWalletAdapter({
165
+ adaptedAccount: TEST_ACCOUNT_A,
166
+ client: TEST_CLIENT,
167
+ chain: ethereum,
168
+ onDisconnect: () => {},
169
+ switchChain: () => {},
170
+ });
171
+ it("should return the correct result", async () => {
172
+ const result = await handleWalletConnection({
173
+ client: TEST_CLIENT,
174
+ lastConnectedChain: ethereum,
175
+ authResult: undefined,
176
+ wallet,
177
+ });
178
+
179
+ expect("address" in result).toBe(true);
180
+ expect(isAddress(result.address)).toBe(true);
181
+ expect("sendTransaction" in result).toBe(true);
182
+ expect(typeof result.sendTransaction).toBe("function");
183
+ expect("signMessage" in result).toBe(true);
184
+ expect("signTypedData" in result).toBe(true);
185
+ expect("signTransaction" in result).toBe(true);
186
+ });
187
+ });
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "5.80.1-nightly-a3f59e50e249d8b4fac765e025fc2cd102093e9c-20250105000328";
1
+ export const version = "5.81.0";
@@ -1,42 +1,54 @@
1
1
  import { beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { TEST_CLIENT } from "../../../../../test/src/test-clients.js";
3
+ import { TEST_ACCOUNT_A } from "../../../../../test/src/test-wallets.js";
2
4
  import { baseSepolia } from "../../../../chains/chain-definitions/base-sepolia.js";
3
- import { createThirdwebClient } from "../../../../client/client.js";
4
5
  import { getEcosystemInfo } from "../../../ecosystem/get-ecosystem-wallet-auth-options.js";
5
- import type { Account } from "../../../interfaces/wallet.js";
6
+ import { predictSmartAccountAddress } from "../../../smart/lib/calls.js";
7
+ import { DEFAULT_ACCOUNT_FACTORY_V0_6 } from "../../../smart/lib/constants.js";
8
+ import type { AuthLoginReturnType } from "../authentication/types.js";
6
9
  import type { InAppConnector } from "../interfaces/connector.js";
7
10
  import { createInAppWallet } from "./in-app-core.js";
8
- import { autoConnectInAppWallet, connectInAppWallet } from "./index.js";
11
+ import * as InAppWallet from "./index.js";
9
12
 
10
13
  vi.mock("../../../../analytics/track/connect.js", () => ({
11
14
  trackConnect: vi.fn(),
12
15
  }));
13
16
 
14
- vi.mock("./index.js", () => ({
15
- autoConnectInAppWallet: vi.fn(),
16
- connectInAppWallet: vi.fn(),
17
- }));
18
-
17
+ vi.spyOn(InAppWallet, "connectInAppWallet");
18
+ vi.spyOn(InAppWallet, "autoConnectInAppWallet");
19
19
  vi.mock("../../../ecosystem/get-ecosystem-wallet-auth-options.js", () => ({
20
20
  getEcosystemInfo: vi.fn(),
21
21
  }));
22
22
 
23
- describe("createInAppWallet", () => {
24
- const mockClient = createThirdwebClient({
25
- clientId: "test-client",
26
- });
23
+ describe.runIf(process.env.TW_SECRET_KEY)("createInAppWallet", () => {
24
+ const mockClient = TEST_CLIENT;
27
25
  const mockChain = baseSepolia;
28
- const mockAccount = { address: "0x123" } as Account;
26
+ const mockAccount = TEST_ACCOUNT_A;
27
+ const mockUser = {
28
+ status: "Logged In, Wallet Initialized",
29
+ walletAddress: TEST_ACCOUNT_A.address,
30
+ authDetails: {
31
+ userWalletId: TEST_ACCOUNT_A.address,
32
+ recoveryShareManagement: "ENCLAVE",
33
+ email: "test@test.com",
34
+ },
35
+ account: mockAccount,
36
+ } as const;
37
+ const mockAuthResult: AuthLoginReturnType = {
38
+ user: mockUser,
39
+ };
29
40
 
30
41
  const mockConnectorFactory = vi.fn(() =>
31
42
  Promise.resolve({
32
- connect: vi.fn(),
43
+ connect: vi.fn().mockResolvedValue(mockAuthResult),
33
44
  logout: vi.fn(() => Promise.resolve({ success: true })),
34
45
  authenticate: vi.fn(),
35
46
  getAccounts: vi.fn(),
36
47
  getAccount: vi.fn(),
37
48
  getProfiles: vi.fn(),
38
- getUser: vi.fn(),
49
+ getUser: vi.fn().mockResolvedValue(mockUser),
39
50
  linkProfile: vi.fn(),
51
+ unlinkProfile: vi.fn(),
40
52
  preAuthenticate: vi.fn(),
41
53
  } as InAppConnector),
42
54
  );
@@ -46,8 +58,6 @@ describe("createInAppWallet", () => {
46
58
  });
47
59
 
48
60
  it("should connect successfully", async () => {
49
- vi.mocked(connectInAppWallet).mockResolvedValue([mockAccount, mockChain]);
50
-
51
61
  const wallet = createInAppWallet({
52
62
  connectorFactory: mockConnectorFactory,
53
63
  });
@@ -61,7 +71,7 @@ describe("createInAppWallet", () => {
61
71
  });
62
72
 
63
73
  expect(result).toBe(mockAccount);
64
- expect(connectInAppWallet).toHaveBeenCalledWith(
74
+ expect(InAppWallet.connectInAppWallet).toHaveBeenCalledWith(
65
75
  expect.objectContaining({
66
76
  client: mockClient,
67
77
  chain: mockChain,
@@ -72,11 +82,6 @@ describe("createInAppWallet", () => {
72
82
  });
73
83
 
74
84
  it("should auto connect successfully", async () => {
75
- vi.mocked(autoConnectInAppWallet).mockResolvedValue([
76
- mockAccount,
77
- mockChain,
78
- ]);
79
-
80
85
  const wallet = createInAppWallet({
81
86
  connectorFactory: mockConnectorFactory,
82
87
  });
@@ -87,7 +92,7 @@ describe("createInAppWallet", () => {
87
92
  });
88
93
 
89
94
  expect(result).toBe(mockAccount);
90
- expect(autoConnectInAppWallet).toHaveBeenCalledWith(
95
+ expect(InAppWallet.autoConnectInAppWallet).toHaveBeenCalledWith(
91
96
  expect.objectContaining({
92
97
  client: mockClient,
93
98
  chain: mockChain,
@@ -102,15 +107,13 @@ describe("createInAppWallet", () => {
102
107
  smartAccountOptions: {
103
108
  defaultChainId: mockChain.id,
104
109
  sponsorGas: true,
105
- accountFactoryAddress: "0x456",
110
+ accountFactoryAddress: DEFAULT_ACCOUNT_FACTORY_V0_6,
106
111
  },
107
112
  authOptions: [],
108
113
  name: "hello world",
109
114
  slug: "test-ecosystem",
110
115
  });
111
116
 
112
- vi.mocked(connectInAppWallet).mockResolvedValue([mockAccount, mockChain]);
113
-
114
117
  const wallet = createInAppWallet({
115
118
  connectorFactory: mockConnectorFactory,
116
119
  ecosystem: { id: "ecosystem.test-ecosystem" },
@@ -124,8 +127,14 @@ describe("createInAppWallet", () => {
124
127
  verificationCode: "",
125
128
  });
126
129
 
127
- expect(result).toBe(mockAccount);
128
- expect(connectInAppWallet).toHaveBeenCalledWith(
130
+ const expectedSmartAccountAddress = await predictSmartAccountAddress({
131
+ factoryAddress: DEFAULT_ACCOUNT_FACTORY_V0_6,
132
+ chain: mockChain,
133
+ adminAddress: TEST_ACCOUNT_A.address,
134
+ client: mockClient,
135
+ });
136
+ expect(result.address).toBe(expectedSmartAccountAddress);
137
+ expect(InAppWallet.connectInAppWallet).toHaveBeenCalledWith(
129
138
  expect.objectContaining({
130
139
  client: mockClient,
131
140
  chain: mockChain,
@@ -134,7 +143,7 @@ describe("createInAppWallet", () => {
134
143
  smartAccount: expect.objectContaining({
135
144
  chain: mockChain,
136
145
  sponsorGas: true,
137
- factoryAddress: "0x456",
146
+ factoryAddress: DEFAULT_ACCOUNT_FACTORY_V0_6,
138
147
  }),
139
148
  }),
140
149
  expect.any(Object),
@@ -145,15 +154,13 @@ describe("createInAppWallet", () => {
145
154
  smartAccountOptions: {
146
155
  defaultChainId: mockChain.id,
147
156
  sponsorGas: true,
148
- accountFactoryAddress: "0x456",
157
+ accountFactoryAddress: DEFAULT_ACCOUNT_FACTORY_V0_6,
149
158
  },
150
159
  authOptions: [],
151
160
  name: "hello world",
152
161
  slug: "test-ecosystem",
153
162
  });
154
163
 
155
- vi.mocked(connectInAppWallet).mockResolvedValue([mockAccount, mockChain]);
156
-
157
164
  const wallet = createInAppWallet({
158
165
  connectorFactory: mockConnectorFactory,
159
166
  ecosystem: { id: "ecosystem.test-ecosystem" },
@@ -166,8 +173,14 @@ describe("createInAppWallet", () => {
166
173
  verificationCode: "",
167
174
  });
168
175
 
169
- expect(result).toBe(mockAccount);
170
- expect(connectInAppWallet).toHaveBeenCalledWith(
176
+ const expectedSmartAccountAddress = await predictSmartAccountAddress({
177
+ factoryAddress: DEFAULT_ACCOUNT_FACTORY_V0_6,
178
+ chain: mockChain,
179
+ adminAddress: TEST_ACCOUNT_A.address,
180
+ client: mockClient,
181
+ });
182
+ expect(result.address).toBe(expectedSmartAccountAddress);
183
+ expect(InAppWallet.connectInAppWallet).toHaveBeenCalledWith(
171
184
  expect.objectContaining({
172
185
  client: mockClient,
173
186
  }),
@@ -175,7 +188,7 @@ describe("createInAppWallet", () => {
175
188
  smartAccount: expect.objectContaining({
176
189
  chain: mockChain,
177
190
  sponsorGas: true,
178
- factoryAddress: "0x456",
191
+ factoryAddress: DEFAULT_ACCOUNT_FACTORY_V0_6,
179
192
  }),
180
193
  }),
181
194
  expect.any(Object),
@@ -187,18 +200,13 @@ describe("createInAppWallet", () => {
187
200
  smartAccountOptions: {
188
201
  defaultChainId: mockChain.id,
189
202
  sponsorGas: true,
190
- accountFactoryAddress: "0x456",
203
+ accountFactoryAddress: DEFAULT_ACCOUNT_FACTORY_V0_6,
191
204
  },
192
205
  authOptions: [],
193
206
  name: "hello world",
194
207
  slug: "test-ecosystem",
195
208
  });
196
209
 
197
- vi.mocked(autoConnectInAppWallet).mockResolvedValue([
198
- mockAccount,
199
- mockChain,
200
- ]);
201
-
202
210
  const wallet = createInAppWallet({
203
211
  connectorFactory: mockConnectorFactory,
204
212
  ecosystem: { id: "ecosystem.test-ecosystem" },
@@ -209,8 +217,14 @@ describe("createInAppWallet", () => {
209
217
  chain: mockChain,
210
218
  });
211
219
 
212
- expect(result).toBe(mockAccount);
213
- expect(autoConnectInAppWallet).toHaveBeenCalledWith(
220
+ const expectedSmartAccountAddress = await predictSmartAccountAddress({
221
+ factoryAddress: DEFAULT_ACCOUNT_FACTORY_V0_6,
222
+ chain: mockChain,
223
+ adminAddress: TEST_ACCOUNT_A.address,
224
+ client: mockClient,
225
+ });
226
+ expect(result.address).toBe(expectedSmartAccountAddress);
227
+ expect(InAppWallet.autoConnectInAppWallet).toHaveBeenCalledWith(
214
228
  expect.objectContaining({
215
229
  client: mockClient,
216
230
  chain: mockChain,
@@ -219,7 +233,7 @@ describe("createInAppWallet", () => {
219
233
  smartAccount: expect.objectContaining({
220
234
  chain: mockChain,
221
235
  sponsorGas: true,
222
- factoryAddress: "0x456",
236
+ factoryAddress: DEFAULT_ACCOUNT_FACTORY_V0_6,
223
237
  }),
224
238
  }),
225
239
  expect.any(Object),
@@ -231,18 +245,13 @@ describe("createInAppWallet", () => {
231
245
  smartAccountOptions: {
232
246
  defaultChainId: mockChain.id,
233
247
  sponsorGas: true,
234
- accountFactoryAddress: "0x456",
248
+ accountFactoryAddress: DEFAULT_ACCOUNT_FACTORY_V0_6,
235
249
  },
236
250
  authOptions: [],
237
251
  name: "hello world",
238
252
  slug: "test-ecosystem",
239
253
  });
240
254
 
241
- vi.mocked(autoConnectInAppWallet).mockResolvedValue([
242
- mockAccount,
243
- mockChain,
244
- ]);
245
-
246
255
  const wallet = createInAppWallet({
247
256
  connectorFactory: mockConnectorFactory,
248
257
  ecosystem: { id: "ecosystem.test-ecosystem" },
@@ -252,8 +261,14 @@ describe("createInAppWallet", () => {
252
261
  client: mockClient,
253
262
  });
254
263
 
255
- expect(result).toBe(mockAccount);
256
- expect(autoConnectInAppWallet).toHaveBeenCalledWith(
264
+ const expectedSmartAccountAddress = await predictSmartAccountAddress({
265
+ factoryAddress: DEFAULT_ACCOUNT_FACTORY_V0_6,
266
+ chain: mockChain,
267
+ adminAddress: TEST_ACCOUNT_A.address,
268
+ client: mockClient,
269
+ });
270
+ expect(result.address).toBe(expectedSmartAccountAddress);
271
+ expect(InAppWallet.autoConnectInAppWallet).toHaveBeenCalledWith(
257
272
  expect.objectContaining({
258
273
  client: mockClient,
259
274
  }),
@@ -261,10 +276,56 @@ describe("createInAppWallet", () => {
261
276
  smartAccount: expect.objectContaining({
262
277
  chain: mockChain,
263
278
  sponsorGas: true,
264
- factoryAddress: "0x456",
279
+ factoryAddress: DEFAULT_ACCOUNT_FACTORY_V0_6,
265
280
  }),
266
281
  }),
267
282
  expect.any(Object),
268
283
  );
269
284
  });
285
+
286
+ it("should return undefined for getAdminAccount if the account is not a smart account", () => {
287
+ const wallet = createInAppWallet({
288
+ connectorFactory: mockConnectorFactory,
289
+ });
290
+
291
+ expect(wallet.getAdminAccount?.()).toBeUndefined();
292
+ });
293
+
294
+ it("should return undefined if no account is connected", () => {
295
+ const wallet = createInAppWallet({
296
+ connectorFactory: mockConnectorFactory,
297
+ });
298
+
299
+ expect(wallet.getAdminAccount?.()).toBeUndefined();
300
+ });
301
+
302
+ it("should return the admin account for a smart account", async () => {
303
+ vi.unmock("./index.js");
304
+ vi.mocked(getEcosystemInfo).mockResolvedValue({
305
+ smartAccountOptions: {
306
+ defaultChainId: mockChain.id,
307
+ sponsorGas: true,
308
+ accountFactoryAddress: DEFAULT_ACCOUNT_FACTORY_V0_6,
309
+ },
310
+ authOptions: [],
311
+ name: "hello world",
312
+ slug: "test-ecosystem",
313
+ });
314
+
315
+ const wallet = createInAppWallet({
316
+ connectorFactory: mockConnectorFactory,
317
+ ecosystem: { id: "ecosystem.test-ecosystem" },
318
+ });
319
+
320
+ const smartAccount = await wallet.connect({
321
+ client: mockClient,
322
+ strategy: "email",
323
+ email: "",
324
+ verificationCode: "",
325
+ });
326
+
327
+ const adminAccount = wallet.getAdminAccount?.();
328
+ expect(adminAccount).toBeDefined();
329
+ expect(adminAccount?.address).not.toBe(smartAccount.address);
330
+ });
270
331
  });