thirdweb 5.83.1 → 5.83.2-nightly-42a313f3b2d89696d5374e5a705e9f144bf46ebe-20250111000322

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 (45) hide show
  1. package/dist/cjs/extensions/prebuilts/deploy-marketplace.js +2 -1
  2. package/dist/cjs/extensions/prebuilts/deploy-marketplace.js.map +1 -1
  3. package/dist/cjs/extensions/prebuilts/deploy-pack.js +1 -1
  4. package/dist/cjs/extensions/prebuilts/deploy-pack.js.map +1 -1
  5. package/dist/cjs/extensions/prebuilts/deploy-published.js +2 -0
  6. package/dist/cjs/extensions/prebuilts/deploy-published.js.map +1 -1
  7. package/dist/cjs/extensions/prebuilts/get-required-transactions.js +3 -1
  8. package/dist/cjs/extensions/prebuilts/get-required-transactions.js.map +1 -1
  9. package/dist/cjs/react/web/ui/ConnectWallet/screens/SignatureScreen.js +9 -3
  10. package/dist/cjs/react/web/ui/ConnectWallet/screens/SignatureScreen.js.map +1 -1
  11. package/dist/cjs/version.js +1 -1
  12. package/dist/cjs/version.js.map +1 -1
  13. package/dist/cjs/wallets/smart/index.js +41 -37
  14. package/dist/cjs/wallets/smart/index.js.map +1 -1
  15. package/dist/esm/extensions/prebuilts/deploy-marketplace.js +2 -1
  16. package/dist/esm/extensions/prebuilts/deploy-marketplace.js.map +1 -1
  17. package/dist/esm/extensions/prebuilts/deploy-pack.js +1 -1
  18. package/dist/esm/extensions/prebuilts/deploy-pack.js.map +1 -1
  19. package/dist/esm/extensions/prebuilts/deploy-published.js +2 -0
  20. package/dist/esm/extensions/prebuilts/deploy-published.js.map +1 -1
  21. package/dist/esm/extensions/prebuilts/get-required-transactions.js +3 -1
  22. package/dist/esm/extensions/prebuilts/get-required-transactions.js.map +1 -1
  23. package/dist/esm/react/web/ui/ConnectWallet/screens/SignatureScreen.js +9 -3
  24. package/dist/esm/react/web/ui/ConnectWallet/screens/SignatureScreen.js.map +1 -1
  25. package/dist/esm/version.js +1 -1
  26. package/dist/esm/version.js.map +1 -1
  27. package/dist/esm/wallets/smart/index.js +41 -37
  28. package/dist/esm/wallets/smart/index.js.map +1 -1
  29. package/dist/types/extensions/prebuilts/deploy-marketplace.d.ts +2 -0
  30. package/dist/types/extensions/prebuilts/deploy-marketplace.d.ts.map +1 -1
  31. package/dist/types/extensions/prebuilts/deploy-published.d.ts.map +1 -1
  32. package/dist/types/extensions/prebuilts/get-required-transactions.d.ts +1 -0
  33. package/dist/types/extensions/prebuilts/get-required-transactions.d.ts.map +1 -1
  34. package/dist/types/react/web/ui/ConnectWallet/screens/SignatureScreen.d.ts.map +1 -1
  35. package/dist/types/version.d.ts +1 -1
  36. package/dist/types/version.d.ts.map +1 -1
  37. package/package.json +1 -1
  38. package/src/extensions/prebuilts/deploy-marketplace.ts +4 -1
  39. package/src/extensions/prebuilts/deploy-pack.ts +1 -1
  40. package/src/extensions/prebuilts/deploy-published.ts +2 -0
  41. package/src/extensions/prebuilts/get-required-transactions.ts +6 -1
  42. package/src/react/web/ui/ConnectWallet/screens/SignatureScreen.test.tsx +221 -170
  43. package/src/react/web/ui/ConnectWallet/screens/SignatureScreen.tsx +12 -3
  44. package/src/version.ts +1 -1
  45. package/src/wallets/smart/index.ts +40 -38
@@ -1,10 +1,10 @@
1
1
  import { userEvent } from "@testing-library/user-event";
2
2
  import { beforeEach, describe, expect, it, vi } from "vitest";
3
3
  import { TEST_ACCOUNT_A } from "~test/test-wallets.js";
4
+ import { ANVIL_CHAIN } from "../../../../../../test/src/chains.js";
4
5
  import { render, waitFor } from "../../../../../../test/src/react-render.js";
5
6
  import { TEST_CLIENT } from "../../../../../../test/src/test-clients.js";
6
7
  import { createWallet } from "../../../../../wallets/create-wallet.js";
7
- import { useActiveWallet } from "../../../../core/hooks/wallets/useActiveWallet.js";
8
8
  import type { ConnectLocale } from "../locale/types.js";
9
9
  import { SignatureScreen } from "./SignatureScreen.js";
10
10
 
@@ -15,12 +15,18 @@ const mockAuth = vi.hoisted(() => ({
15
15
  isLoggedIn: vi.fn().mockResolvedValue(true),
16
16
  }));
17
17
 
18
+ const useActiveWalletMock = vi.hoisted(() =>
19
+ vi.fn().mockReturnValue(undefined),
20
+ );
21
+
22
+ const useAdminWalletMock = vi.hoisted(() => vi.fn().mockReturnValue(undefined));
23
+
18
24
  vi.mock("../../../../core/hooks/auth/useSiweAuth", () => ({
19
25
  useSiweAuth: () => mockAuth,
20
26
  }));
21
27
 
22
28
  vi.mock("../../../../core/hooks/wallets/useActiveWallet", () => ({
23
- useActiveWallet: vi.fn().mockReturnValue(createWallet("io.metamask")),
29
+ useActiveWallet: useActiveWalletMock,
24
30
  }));
25
31
 
26
32
  vi.mock("../../../../core/hooks/wallets/useActiveAccount", () => ({
@@ -28,7 +34,7 @@ vi.mock("../../../../core/hooks/wallets/useActiveAccount", () => ({
28
34
  }));
29
35
 
30
36
  vi.mock("../../../../core/hooks/wallets/useAdminWallet", () => ({
31
- useAdminWallet: () => vi.fn().mockReturnValue(null),
37
+ useAdminWallet: useAdminWalletMock,
32
38
  }));
33
39
 
34
40
  const mockConnectLocale = {
@@ -56,105 +62,17 @@ const mockConnectLocale = {
56
62
  },
57
63
  } as unknown as ConnectLocale;
58
64
 
59
- describe("SignatureScreen", () => {
60
- beforeEach(() => {
61
- vi.clearAllMocks();
62
- mockAuth.doLogin.mockResolvedValue(undefined);
63
- });
64
-
65
- it("renders initial state correctly", () => {
66
- const { getByTestId } = render(
67
- <SignatureScreen
68
- onDone={() => {}}
69
- modalSize="wide"
70
- connectLocale={mockConnectLocale}
71
- client={TEST_CLIENT}
72
- auth={mockAuth}
73
- />,
74
- { setConnectedWallet: true },
75
- );
76
-
77
- expect(getByTestId("sign-in-button")).toBeInTheDocument();
78
- expect(getByTestId("disconnect-button")).toBeInTheDocument();
79
- });
80
-
81
- it("handles signing flow", async () => {
82
- const onDoneMock = vi.fn();
83
- const { getByRole, getByText } = render(
84
- <SignatureScreen
85
- onDone={onDoneMock}
86
- modalSize="wide"
87
- connectLocale={mockConnectLocale}
88
- client={TEST_CLIENT}
89
- auth={mockAuth}
90
- />,
91
- { setConnectedWallet: true },
92
- );
93
-
94
- const signInButton = getByRole("button", { name: "Sign In" });
95
- await userEvent.click(signInButton);
96
-
97
- // Should show signing in progress
98
- await waitFor(() => {
99
- expect(getByText("Signing in progress...")).toBeInTheDocument();
100
- });
101
- });
102
-
103
- it("shows loading state when wallet is undefined", async () => {
104
- vi.mocked(useActiveWallet).mockReturnValueOnce(undefined);
105
-
106
- const { queryByTestId } = render(
107
- <SignatureScreen
108
- onDone={() => {}}
109
- modalSize="wide"
110
- connectLocale={mockConnectLocale}
111
- client={TEST_CLIENT}
112
- auth={mockAuth}
113
- />,
114
- { setConnectedWallet: true },
115
- );
116
-
117
- expect(queryByTestId("sign-in-button")).not.toBeInTheDocument();
118
- });
119
-
120
- it("handles error state", async () => {
121
- mockAuth.doLogin.mockRejectedValueOnce(new Error("Signing failed"));
122
- const { getByTestId, getByRole, getByText } = render(
123
- <SignatureScreen
124
- onDone={() => {}}
125
- modalSize="wide"
126
- connectLocale={mockConnectLocale}
127
- client={TEST_CLIENT}
128
- auth={mockAuth}
129
- />,
130
- { setConnectedWallet: true },
131
- );
132
-
133
- const signInButton = await waitFor(() => {
134
- return getByTestId("sign-in-button");
135
- });
136
- await userEvent.click(signInButton);
137
-
138
- // Should show error state
139
- await waitFor(
140
- () => {
141
- expect(getByText("Signing failed")).toBeInTheDocument();
142
- expect(getByRole("button", { name: "Try Again" })).toBeInTheDocument();
143
- },
144
- {
145
- timeout: 2000,
146
- },
147
- );
148
- });
149
-
150
- describe("HeadlessSignIn", () => {
151
- const mockWallet = createWallet("inApp");
65
+ describe("Signature screen", () => {
66
+ describe("Signature prompt screen", () => {
152
67
  beforeEach(() => {
153
- vi.mocked(useActiveWallet).mockReturnValue(mockWallet);
68
+ const metamaskWallet = createWallet("io.metamask");
69
+ useActiveWalletMock.mockReturnValue(metamaskWallet);
70
+ vi.clearAllMocks();
71
+ mockAuth.doLogin.mockResolvedValue(undefined);
154
72
  });
155
73
 
156
- it("automatically triggers sign in on mount", async () => {
157
- render(
74
+ it("renders initial state correctly", () => {
75
+ const { getByTestId } = render(
158
76
  <SignatureScreen
159
77
  onDone={() => {}}
160
78
  modalSize="wide"
@@ -165,15 +83,15 @@ describe("SignatureScreen", () => {
165
83
  { setConnectedWallet: true },
166
84
  );
167
85
 
168
- await waitFor(() => {
169
- expect(mockAuth.doLogin).toHaveBeenCalledTimes(1);
170
- });
86
+ expect(getByTestId("sign-in-button")).toBeInTheDocument();
87
+ expect(getByTestId("disconnect-button")).toBeInTheDocument();
171
88
  });
172
89
 
173
- it("shows signing message during signing state", async () => {
174
- const { getByText } = render(
90
+ it("handles signing flow", async () => {
91
+ const onDoneMock = vi.fn();
92
+ const { getByRole, getByText } = render(
175
93
  <SignatureScreen
176
- onDone={() => {}}
94
+ onDone={onDoneMock}
177
95
  modalSize="wide"
178
96
  connectLocale={mockConnectLocale}
179
97
  client={TEST_CLIENT}
@@ -182,17 +100,18 @@ describe("SignatureScreen", () => {
182
100
  { setConnectedWallet: true },
183
101
  );
184
102
 
103
+ const signInButton = getByRole("button", { name: "Sign In" });
104
+ await userEvent.click(signInButton);
105
+
106
+ // Should show signing in progress
185
107
  await waitFor(() => {
186
- expect(getByText("Signing")).toBeInTheDocument();
108
+ expect(getByText("Signing in progress...")).toBeInTheDocument();
187
109
  });
188
110
  });
189
111
 
190
- it("shows error and retry button when signing fails", async () => {
191
- mockAuth.doLogin.mockRejectedValueOnce(
192
- new Error("Headless signing failed"),
193
- );
194
-
195
- const { getByText, getByRole } = render(
112
+ it("handles error state", async () => {
113
+ mockAuth.doLogin.mockRejectedValueOnce(new Error("Signing failed"));
114
+ const { getByTestId, getByRole, getByText } = render(
196
115
  <SignatureScreen
197
116
  onDone={() => {}}
198
117
  modalSize="wide"
@@ -203,85 +122,217 @@ describe("SignatureScreen", () => {
203
122
  { setConnectedWallet: true },
204
123
  );
205
124
 
125
+ const signInButton = await waitFor(() => {
126
+ return getByTestId("sign-in-button");
127
+ });
128
+ await userEvent.click(signInButton);
129
+
130
+ // Should show error state
206
131
  await waitFor(
207
132
  () => {
208
- expect(getByText("Headless signing failed")).toBeInTheDocument();
133
+ expect(getByText("Signing failed")).toBeInTheDocument();
209
134
  expect(
210
135
  getByRole("button", { name: "Try Again" }),
211
136
  ).toBeInTheDocument();
212
137
  },
213
- { timeout: 2000 },
138
+ {
139
+ timeout: 2000,
140
+ },
214
141
  );
215
142
  });
143
+ });
216
144
 
217
- it("allows retry after failure", async () => {
218
- mockAuth.doLogin
219
- .mockRejectedValueOnce(new Error("Failed first time"))
220
- .mockResolvedValueOnce(undefined);
145
+ it("Shows loading state when wallet is disconnected", async () => {
146
+ useActiveWalletMock.mockReturnValueOnce(undefined);
221
147
 
222
- const { getByRole, getByText } = render(
223
- <SignatureScreen
224
- onDone={() => {}}
225
- modalSize="wide"
226
- connectLocale={mockConnectLocale}
227
- client={TEST_CLIENT}
228
- auth={mockAuth}
229
- />,
230
- { setConnectedWallet: true },
231
- );
148
+ const { queryByTestId } = render(
149
+ <SignatureScreen
150
+ onDone={() => {}}
151
+ modalSize="wide"
152
+ connectLocale={mockConnectLocale}
153
+ client={TEST_CLIENT}
154
+ auth={mockAuth}
155
+ />,
156
+ { setConnectedWallet: true },
157
+ );
232
158
 
233
- // Wait for initial failure
234
- await waitFor(
235
- () => {
236
- expect(getByText("Failed first time")).toBeInTheDocument();
237
- },
238
- { timeout: 2000 },
239
- );
159
+ expect(queryByTestId("sign-in-button")).not.toBeInTheDocument();
160
+ });
240
161
 
241
- // Click retry
242
- const retryButton = getByRole("button", { name: "Try Again" });
243
- await userEvent.click(retryButton);
162
+ describe("Headless signature screen", () => {
163
+ function headlessTests() {
164
+ it("automatically triggers sign in on mount", async () => {
165
+ render(
166
+ <SignatureScreen
167
+ onDone={() => {}}
168
+ modalSize="wide"
169
+ connectLocale={mockConnectLocale}
170
+ client={TEST_CLIENT}
171
+ auth={mockAuth}
172
+ />,
173
+ { setConnectedWallet: true },
174
+ );
175
+
176
+ await waitFor(() => {
177
+ expect(mockAuth.doLogin).toHaveBeenCalledTimes(1);
178
+ });
179
+ });
244
180
 
245
- // Should show loading again
246
- await waitFor(() => {
247
- expect(getByText("Signing")).toBeInTheDocument();
181
+ it("shows signing message during signing state", async () => {
182
+ const { getByText } = render(
183
+ <SignatureScreen
184
+ onDone={() => {}}
185
+ modalSize="wide"
186
+ connectLocale={mockConnectLocale}
187
+ client={TEST_CLIENT}
188
+ auth={mockAuth}
189
+ />,
190
+ { setConnectedWallet: true },
191
+ );
192
+
193
+ await waitFor(() => {
194
+ expect(getByText("Signing")).toBeInTheDocument();
195
+ });
248
196
  });
249
197
 
250
- // Should have called login twice
251
- expect(mockAuth.doLogin).toHaveBeenCalledTimes(2);
252
- });
198
+ it("shows error and retry button when signing fails", async () => {
199
+ mockAuth.doLogin.mockRejectedValueOnce(
200
+ new Error("Headless signing failed"),
201
+ );
202
+
203
+ const { getByText, getByRole } = render(
204
+ <SignatureScreen
205
+ onDone={() => {}}
206
+ modalSize="wide"
207
+ connectLocale={mockConnectLocale}
208
+ client={TEST_CLIENT}
209
+ auth={mockAuth}
210
+ />,
211
+ { setConnectedWallet: true },
212
+ );
213
+
214
+ await waitFor(
215
+ () => {
216
+ expect(getByText("Headless signing failed")).toBeInTheDocument();
217
+ expect(
218
+ getByRole("button", { name: "Try Again" }),
219
+ ).toBeInTheDocument();
220
+ },
221
+ { timeout: 2000 },
222
+ );
223
+ });
253
224
 
254
- it("allows disconnecting wallet after failure", async () => {
255
- const mockDisconnect = vi.fn().mockResolvedValue(undefined);
256
- mockAuth.doLogin.mockRejectedValueOnce(new Error("Failed"));
257
- vi.mocked(useActiveWallet).mockReturnValueOnce({
258
- ...createWallet("io.metamask"),
259
- disconnect: mockDisconnect,
225
+ it("allows retry after failure", async () => {
226
+ mockAuth.doLogin
227
+ .mockRejectedValueOnce(new Error("Failed first time"))
228
+ .mockResolvedValueOnce(undefined);
229
+
230
+ const { getByRole, getByText } = render(
231
+ <SignatureScreen
232
+ onDone={() => {}}
233
+ modalSize="wide"
234
+ connectLocale={mockConnectLocale}
235
+ client={TEST_CLIENT}
236
+ auth={mockAuth}
237
+ />,
238
+ { setConnectedWallet: true },
239
+ );
240
+
241
+ // Wait for initial failure
242
+ await waitFor(
243
+ () => {
244
+ expect(getByText("Failed first time")).toBeInTheDocument();
245
+ },
246
+ { timeout: 2000 },
247
+ );
248
+
249
+ // Click retry
250
+ const retryButton = getByRole("button", { name: "Try Again" });
251
+ await userEvent.click(retryButton);
252
+
253
+ // Should show loading again
254
+ await waitFor(() => {
255
+ expect(getByText("Signing")).toBeInTheDocument();
256
+ });
257
+
258
+ // Should have called login twice
259
+ expect(mockAuth.doLogin).toHaveBeenCalledTimes(2);
260
260
  });
261
261
 
262
- const { getByTestId } = render(
263
- <SignatureScreen
264
- onDone={() => {}}
265
- modalSize="wide"
266
- connectLocale={mockConnectLocale}
267
- client={TEST_CLIENT}
268
- auth={mockAuth}
269
- />,
270
- { setConnectedWallet: true },
271
- );
262
+ it("allows disconnecting wallet after failure", async () => {
263
+ const mockDisconnect = vi.fn().mockResolvedValue(undefined);
264
+ mockAuth.doLogin.mockRejectedValueOnce(new Error("Failed"));
265
+ useActiveWalletMock.mockReturnValueOnce({
266
+ ...createWallet("io.metamask"),
267
+ disconnect: mockDisconnect,
268
+ });
269
+
270
+ const { getByTestId } = render(
271
+ <SignatureScreen
272
+ onDone={() => {}}
273
+ modalSize="wide"
274
+ connectLocale={mockConnectLocale}
275
+ client={TEST_CLIENT}
276
+ auth={mockAuth}
277
+ />,
278
+ { setConnectedWallet: true },
279
+ );
280
+
281
+ // Wait for failure and click disconnect
282
+ await waitFor(
283
+ () => {
284
+ return getByTestId("disconnect-button");
285
+ },
286
+ { timeout: 2000 },
287
+ ).then((button) => userEvent.click(button));
288
+
289
+ // Should have attempted to disconnect
290
+ await waitFor(() => {
291
+ expect(mockDisconnect).toHaveBeenCalled();
292
+ });
293
+ });
294
+ }
272
295
 
273
- // Wait for failure and click disconnect
274
- await waitFor(
275
- () => {
276
- return getByTestId("disconnect-button");
277
- },
278
- { timeout: 2000 },
279
- ).then((button) => userEvent.click(button));
296
+ describe("InApp wallet", () => {
297
+ const inAppWallet = createWallet("inApp");
298
+ beforeEach(() => {
299
+ useActiveWalletMock.mockReturnValue(inAppWallet);
300
+ });
301
+ headlessTests();
302
+ });
280
303
 
281
- // Should have attempted to disconnect
282
- await waitFor(() => {
283
- expect(mockDisconnect).toHaveBeenCalled();
304
+ describe("Ecosystem wallet", () => {
305
+ const ecosystemWallet = createWallet("ecosystem.foo");
306
+ beforeEach(() => {
307
+ useActiveWalletMock.mockReturnValue(ecosystemWallet);
308
+ });
309
+ headlessTests();
310
+ });
311
+
312
+ describe("Smart Wallet (active) + Ecosystem wallet (admin)", () => {
313
+ const ecosystemWallet = createWallet("ecosystem.foo");
314
+ const smartWallet = createWallet("smart", {
315
+ chain: ANVIL_CHAIN,
316
+ sponsorGas: false,
317
+ });
318
+ beforeEach(() => {
319
+ useActiveWalletMock.mockReturnValue(smartWallet);
320
+ useAdminWalletMock.mockReturnValue(ecosystemWallet);
321
+ });
322
+ headlessTests();
323
+ });
324
+
325
+ describe("Smart Wallet (active) + InApp wallet (admin)", () => {
326
+ const ecosystemWallet = createWallet("inApp");
327
+ const smartWallet = createWallet("smart", {
328
+ chain: ANVIL_CHAIN,
329
+ sponsorGas: false,
330
+ });
331
+ beforeEach(() => {
332
+ useActiveWalletMock.mockReturnValue(smartWallet);
333
+ useAdminWalletMock.mockReturnValue(ecosystemWallet);
284
334
  });
335
+ headlessTests();
285
336
  });
286
337
  });
287
338
  });
@@ -74,9 +74,10 @@ export const SignatureScreen: React.FC<{
74
74
  }
75
75
 
76
76
  if (
77
- wallet.id === "inApp" ||
78
- wallet.id === "embedded" ||
79
- (wallet.id === "smart" && adminWallet?.id === "inApp")
77
+ isHeadlessSignSupported(wallet.id) ||
78
+ (wallet.id === "smart" &&
79
+ adminWallet &&
80
+ isHeadlessSignSupported(adminWallet.id))
80
81
  ) {
81
82
  return (
82
83
  <HeadlessSignIn
@@ -227,6 +228,14 @@ export const SignatureScreen: React.FC<{
227
228
  );
228
229
  };
229
230
 
231
+ function isHeadlessSignSupported(walletId: Wallet["id"]) {
232
+ return (
233
+ walletId === "inApp" ||
234
+ walletId === "embedded" ||
235
+ walletId.startsWith("ecosystem")
236
+ );
237
+ }
238
+
230
239
  function HeadlessSignIn({
231
240
  signIn,
232
241
  error,
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "5.83.1";
1
+ export const version = "5.83.2-nightly-42a313f3b2d89696d5374e5a705e9f144bf46ebe-20250111000322";
@@ -463,45 +463,47 @@ async function _sendUserOp(args: {
463
463
  options: SmartAccountOptions;
464
464
  }): Promise<WaitForReceiptOptions> {
465
465
  const { executeTx, options } = args;
466
- const unsignedUserOp = await createUnsignedUserOp({
467
- transaction: executeTx,
468
- factoryContract: options.factoryContract,
469
- accountContract: options.accountContract,
470
- adminAddress: options.personalAccount.address,
471
- sponsorGas: options.sponsorGas,
472
- overrides: options.overrides,
473
- });
474
- const signedUserOp = await signUserOp({
475
- client: options.client,
476
- chain: options.chain,
477
- adminAccount: options.personalAccount,
478
- entrypointAddress: options.overrides?.entrypointAddress,
479
- userOp: unsignedUserOp,
480
- });
481
- const bundlerOptions: BundlerOptions = {
482
- chain: options.chain,
483
- client: options.client,
484
- bundlerUrl: options.overrides?.bundlerUrl,
485
- entrypointAddress: options.overrides?.entrypointAddress,
486
- };
487
- const userOpHash = await bundleUserOp({
488
- options: bundlerOptions,
489
- userOp: signedUserOp,
490
- });
491
- // wait for tx receipt rather than return the userOp hash
492
- const receipt = await waitForUserOpReceipt({
493
- ...bundlerOptions,
494
- userOpHash,
495
- });
496
-
497
- // reset the isDeploying flag after every transaction
498
- clearAccountDeploying(options.accountContract);
466
+ try {
467
+ const unsignedUserOp = await createUnsignedUserOp({
468
+ transaction: executeTx,
469
+ factoryContract: options.factoryContract,
470
+ accountContract: options.accountContract,
471
+ adminAddress: options.personalAccount.address,
472
+ sponsorGas: options.sponsorGas,
473
+ overrides: options.overrides,
474
+ });
475
+ const signedUserOp = await signUserOp({
476
+ client: options.client,
477
+ chain: options.chain,
478
+ adminAccount: options.personalAccount,
479
+ entrypointAddress: options.overrides?.entrypointAddress,
480
+ userOp: unsignedUserOp,
481
+ });
482
+ const bundlerOptions: BundlerOptions = {
483
+ chain: options.chain,
484
+ client: options.client,
485
+ bundlerUrl: options.overrides?.bundlerUrl,
486
+ entrypointAddress: options.overrides?.entrypointAddress,
487
+ };
488
+ const userOpHash = await bundleUserOp({
489
+ options: bundlerOptions,
490
+ userOp: signedUserOp,
491
+ });
492
+ // wait for tx receipt rather than return the userOp hash
493
+ const receipt = await waitForUserOpReceipt({
494
+ ...bundlerOptions,
495
+ userOpHash,
496
+ });
499
497
 
500
- return {
501
- client: options.client,
502
- chain: options.chain,
503
- transactionHash: receipt.transactionHash,
504
- };
498
+ return {
499
+ client: options.client,
500
+ chain: options.chain,
501
+ transactionHash: receipt.transactionHash,
502
+ };
503
+ } finally {
504
+ // reset the isDeploying flag after every transaction or error
505
+ clearAccountDeploying(options.accountContract);
506
+ }
505
507
  }
506
508
 
507
509
  async function getEntrypointFromFactory(