Skip to content

Commit 223c497

Browse files
fix: ensure smart accounts are deployed before validating signatures (#5092)
1 parent 541bee5 commit 223c497

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

.changeset/smooth-walls-glow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
Ensure smart accounts are deployed before validating signatures

packages/thirdweb/src/wallets/smart/index.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,11 @@ async function createSmartAccount(
256256
account,
257257
accountContract,
258258
});
259+
// the bundler and rpc might not be in sync, so while the bundler has a transaction hash for the deployment,
260+
// the rpc might not have it yet, so we wait until the rpc confirms the contract is deployed
261+
await confirmContractDeployment({
262+
accountContract,
263+
});
259264
}
260265

261266
const originalMsgHash = hashMessage(message);
@@ -344,6 +349,11 @@ async function createSmartAccount(
344349
account,
345350
accountContract,
346351
});
352+
// the bundler and rpc might not be in sync, so while the bundler has a transaction hash for the deployment,
353+
// the rpc might not have it yet, so we wait until the rpc confirms the contract is deployed
354+
await confirmContractDeployment({
355+
accountContract,
356+
});
347357
}
348358

349359
const originalMsgHash = hashTypedData(typedData);
@@ -607,3 +617,24 @@ async function _sendUserOp(args: {
607617
transactionHash: receipt.transactionHash,
608618
};
609619
}
620+
621+
async function confirmContractDeployment(args: {
622+
accountContract: ThirdwebContract;
623+
}) {
624+
const { accountContract } = args;
625+
const startTime = Date.now();
626+
const timeout = 60000; // wait 1 minute max
627+
const { isContractDeployed } = await import(
628+
"../../utils/bytecode/is-contract-deployed.js"
629+
);
630+
let isDeployed = await isContractDeployed(accountContract);
631+
while (!isDeployed) {
632+
if (Date.now() - startTime > timeout) {
633+
throw new Error(
634+
"Timeout: Smart account deployment not confirmed after 1 minute",
635+
);
636+
}
637+
await new Promise((resolve) => setTimeout(resolve, 500));
638+
isDeployed = await isContractDeployed(accountContract);
639+
}
640+
}

packages/thirdweb/src/wallets/smart/smart-wallet-dev.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { beforeAll, describe, expect, it } from "vitest";
22
import { TEST_CLIENT } from "../../../test/src/test-clients.js";
33
import { arbitrumSepolia } from "../../chains/chain-definitions/arbitrum-sepolia.js";
44
import { type ThirdwebContract, getContract } from "../../contract/contract.js";
5-
65
import { balanceOf } from "../../extensions/erc1155/__generated__/IERC1155/read/balanceOf.js";
76
import { claimTo } from "../../extensions/erc1155/drops/write/claimTo.js";
87
import { sendAndConfirmTransaction } from "../../transaction/actions/send-and-confirm-transaction.js";
@@ -62,6 +61,12 @@ describe.runIf(process.env.TW_SECRET_KEY).skip.sequential(
6261
expect(smartWalletAddress).toHaveLength(42);
6362
});
6463

64+
it("can sign a msg", async () => {
65+
await smartAccount.signMessage({ message: "hello world" });
66+
const isDeployed = await isContractDeployed(accountContract);
67+
expect(isDeployed).toEqual(true);
68+
});
69+
6570
it("can execute a tx", async () => {
6671
const tx = await sendAndConfirmTransaction({
6772
transaction: claimTo({

0 commit comments

Comments
 (0)