Skip to content

Commit cfdd16e

Browse files
[SDK] Fallback to onchain nonce in 7702 execution
1 parent 882ed83 commit cfdd16e

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

.changeset/silly-bugs-clean.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+
Fallback to onchain nonce in 7702 execution

packages/thirdweb/src/wallets/in-app/core/eip7702/minimal-account.ts

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Definition, TypedData } from "ox/TypedData";
22
import type { Hex, SignableMessage } from "viem";
3+
import type { Chain } from "../../../../chains/types.js";
34
import { getCachedChain } from "../../../../chains/utils.js";
45
import type { ThirdwebClient } from "../../../../client/client.js";
56
import { getBytecode } from "../../../../contract/actions/get-bytecode.js";
@@ -8,6 +9,7 @@ import {
89
type ThirdwebContract,
910
} from "../../../../contract/contract.js";
1011
import { execute } from "../../../../extensions/erc7702/__generated__/MinimalAccount/write/execute.js";
12+
import { getRpcClient } from "../../../../rpc/rpc.js";
1113
import type { SignedAuthorization } from "../../../../transaction/actions/eip7702/authorization.js";
1214
import { toSerializableTransaction } from "../../../../transaction/actions/to-serializable-transaction.js";
1315
import type { SendTransactionResult } from "../../../../transaction/types.js";
@@ -49,9 +51,16 @@ export const create7702MinimalAccount = (args: {
4951
const isMinimalAccount = await is7702MinimalAccount(eoaContract);
5052
if (!isMinimalAccount) {
5153
// if not, sign authorization
52-
const nonce = firstTx.nonce
53-
? BigInt(firstTx.nonce) + (sponsorGas ? 0n : 1n)
54-
: 0n; // TODO (7702): get remote nonce if not provided, should be in the tx though
54+
let nonce = firstTx.nonce
55+
? BigInt(firstTx.nonce)
56+
: BigInt(
57+
await getNonce({
58+
client,
59+
address: adminAccount.address,
60+
chain: getCachedChain(firstTx.chainId),
61+
}),
62+
);
63+
nonce += sponsorGas ? 0n : 1n;
5564
const auth = await adminAccount.signAuthorization?.({
5665
address: MINIMAL_ACCOUNT_IMPLEMENTATION_ADDRESS,
5766
chainId: firstTx.chainId,
@@ -170,6 +179,27 @@ export const create7702MinimalAccount = (args: {
170179
return minimalAccount;
171180
};
172181

182+
async function getNonce(args: {
183+
client: ThirdwebClient;
184+
address: string;
185+
chain: Chain;
186+
}): Promise<number> {
187+
const { client, address, chain } = args;
188+
const rpcRequest = getRpcClient({
189+
chain,
190+
client,
191+
});
192+
const nonce = await import(
193+
"../../../../rpc/actions/eth_getTransactionCount.js"
194+
).then(({ eth_getTransactionCount }) =>
195+
eth_getTransactionCount(rpcRequest, {
196+
address,
197+
blockTag: "pending",
198+
}),
199+
);
200+
return nonce;
201+
}
202+
173203
async function is7702MinimalAccount(
174204
eoaContract: ThirdwebContract,
175205
): Promise<boolean> {

0 commit comments

Comments
 (0)