Skip to content

Commit a9547c5

Browse files
committed
[SDK] Fix: Use transaction-specified chain in smart account (#5865)
<!-- start pr-codex --> ## PR-Codex overview This PR focuses on fixing chain switching in smart account transactions within the `thirdweb` SDK and adding tests for sending transactions across different chains. ### Detailed summary - Updated the logic for `accountContract` in `packages/thirdweb/src/wallets/smart/index.ts` to handle chain switching. - Added a new test in `packages/thirdweb/src/wallets/smart/smart-wallet-integration.test.ts` to verify sending transactions on another chain. - Introduced similar test functionality in `packages/thirdweb/src/wallets/smart/smart-wallet-integration-v07.test.ts`. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent 6c5594b commit a9547c5

File tree

4 files changed

+53
-1
lines changed

4 files changed

+53
-1
lines changed

.changeset/fair-planes-doubt.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+
SDK: Fix chain switching in smart account transactions

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,15 +240,30 @@ async function createSmartAccount(
240240
} else {
241241
paymasterOverride = options.overrides?.paymaster;
242242
}
243+
244+
const accountContractForTransaction = (() => {
245+
// If this transaction is for a different chain than the initial one, get the account contract for that chain
246+
if (transaction.chainId !== accountContract.chain.id) {
247+
return getContract({
248+
address: account.address,
249+
chain: getCachedChain(transaction.chainId),
250+
client: options.client,
251+
});
252+
}
253+
// Default to the existing account contract
254+
return accountContract;
255+
})();
256+
243257
const executeTx = prepareExecute({
244-
accountContract,
258+
accountContract: accountContractForTransaction,
245259
transaction,
246260
executeOverride: options.overrides?.execute,
247261
});
248262
return _sendUserOp({
249263
executeTx,
250264
options: {
251265
...options,
266+
chain: getCachedChain(transaction.chainId),
252267
overrides: {
253268
...options.overrides,
254269
paymaster: paymasterOverride,

packages/thirdweb/src/wallets/smart/smart-wallet-integration-v07.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import { verifySignature } from "../../auth/verify-signature.js";
55
import { type ThirdwebContract, getContract } from "../../contract/contract.js";
66
import { parseEventLogs } from "../../event/actions/parse-logs.js";
77

8+
import { TEST_WALLET_A } from "~test/addresses.js";
89
import { verifyTypedData } from "../../auth/verify-typed-data.js";
10+
import { baseSepolia } from "../../chains/chain-definitions/base-sepolia.js";
911
import { sepolia } from "../../chains/chain-definitions/sepolia.js";
1012
import {
1113
addAdmin,
@@ -18,6 +20,7 @@ import { estimateGasCost } from "../../transaction/actions/estimate-gas-cost.js"
1820
import { sendAndConfirmTransaction } from "../../transaction/actions/send-and-confirm-transaction.js";
1921
import { sendBatchTransaction } from "../../transaction/actions/send-batch-transaction.js";
2022
import { waitForReceipt } from "../../transaction/actions/wait-for-tx-receipt.js";
23+
import { prepareTransaction } from "../../transaction/prepare-transaction.js";
2124
import { getAddress } from "../../utils/address.js";
2225
import { isContractDeployed } from "../../utils/bytecode/is-contract-deployed.js";
2326
import { sleep } from "../../utils/sleep.js";
@@ -107,6 +110,20 @@ describe.runIf(process.env.TW_SECRET_KEY)(
107110
expect(isValid).toEqual(true);
108111
});
109112

113+
it("can send a transaction on another chain", async () => {
114+
const tx = await sendAndConfirmTransaction({
115+
transaction: prepareTransaction({
116+
to: TEST_WALLET_A,
117+
client: TEST_CLIENT,
118+
chain: baseSepolia,
119+
value: 0n,
120+
}),
121+
// biome-ignore lint/style/noNonNullAssertion: Just trust me
122+
account: wallet.getAccount()!,
123+
});
124+
expect(tx.transactionHash).toHaveLength(66);
125+
});
126+
110127
it("should revert on unsuccessful transactions", async () => {
111128
const tx = sendAndConfirmTransaction({
112129
transaction: setContractURI({

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { beforeAll, describe, expect, it } from "vitest";
2+
import { TEST_WALLET_A } from "~test/addresses.js";
23
import { TEST_CLIENT } from "../../../test/src/test-clients.js";
34
import { typedData } from "../../../test/src/typed-data.js";
45
import { verifySignature } from "../../auth/verify-signature.js";
@@ -309,6 +310,20 @@ describe.runIf(process.env.TW_SECRET_KEY).sequential(
309310
expect(wallet.getChain()?.id).toEqual(baseSepolia.id);
310311
});
311312

313+
it("can send a transaction on another chain", async () => {
314+
const tx = await sendAndConfirmTransaction({
315+
transaction: prepareTransaction({
316+
to: TEST_WALLET_A,
317+
client: TEST_CLIENT,
318+
chain: baseSepolia,
319+
value: 0n,
320+
}),
321+
// biome-ignore lint/style/noNonNullAssertion: Just trust me
322+
account: wallet.getAccount()!,
323+
});
324+
expect(tx.transactionHash).toHaveLength(66);
325+
});
326+
312327
it("can execute 2 tx in parallel", async () => {
313328
const newSmartWallet = smartWallet({
314329
chain,

0 commit comments

Comments
 (0)