Skip to content

Commit d17c414

Browse files
Simplify userop signing flow (#711)
* Simplify userop signing flow * upgrade SDK * fix gas overrides --------- Co-authored-by: Phillip Ho <[email protected]>
1 parent 29fe845 commit d17c414

File tree

5 files changed

+84
-155
lines changed

5 files changed

+84
-155
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
"prom-client": "^15.1.3",
7575
"prool": "^0.0.16",
7676
"superjson": "^2.2.1",
77-
"thirdweb": "^5.60.1",
77+
"thirdweb": "5.61.2",
7878
"uuid": "^9.0.1",
7979
"winston": "^3.14.1",
8080
"zod": "^3.23.8"

src/utils/transaction/userOperation.ts

Lines changed: 0 additions & 134 deletions
This file was deleted.

src/worker/tasks/sendTransactionWorker.ts

Lines changed: 77 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
11
import { Worker, type Job, type Processor } from "bullmq";
22
import assert from "node:assert";
33
import superjson from "superjson";
4-
import { getAddress, toSerializableTransaction, type Hex } from "thirdweb";
4+
import {
5+
getAddress,
6+
getContract,
7+
readContract,
8+
toSerializableTransaction,
9+
type Hex,
10+
} from "thirdweb";
511
import { stringify } from "thirdweb/utils";
6-
import { bundleUserOp } from "thirdweb/wallets/smart";
12+
import {
13+
bundleUserOp,
14+
createAndSignUserOp,
15+
type UserOperation,
16+
} from "thirdweb/wallets/smart";
717
import { getContractAddress } from "viem";
818
import { TransactionDB } from "../../db/transactions/db";
919
import {
@@ -33,7 +43,6 @@ import type {
3343
QueuedTransaction,
3444
SentTransaction,
3545
} from "../../utils/transaction/types";
36-
import { generateSignedUserOperation } from "../../utils/transaction/userOperation";
3746
import { enqueueTransactionWebhook } from "../../utils/transaction/webhook";
3847
import { reportUsage } from "../../utils/usage";
3948
import { MineTransactionQueue } from "../queues/mineTransactionQueue";
@@ -130,24 +139,80 @@ const _sendUserOp = async (
130139
};
131140
}
132141

133-
const { accountAddress, to, target, chainId } = queuedTransaction;
142+
const {
143+
accountAddress,
144+
to,
145+
target,
146+
chainId,
147+
from,
148+
accountFactoryAddress: userProvidedAccountFactoryAddress,
149+
overrides,
150+
} = queuedTransaction;
134151
const chain = await getChain(chainId);
135152

136153
assert(accountAddress, "Invalid userOp parameters: accountAddress");
137154
const toAddress = to ?? target;
138155
assert(toAddress, "Invalid transaction parameters: to");
139156

140-
let populatedTransaction: PopulatedTransaction;
157+
// Resolve Admin-Account for UserOperation Signer
158+
const adminAccount = await getAccount({
159+
chainId,
160+
from,
161+
});
162+
163+
let signedUserOp: UserOperation;
141164
try {
142-
populatedTransaction = await toSerializableTransaction({
143-
from: getChecksumAddress(accountAddress),
144-
transaction: {
145-
client: thirdwebClient,
165+
// Resolve the user factory from the provided address, or from the `factory()` method if found.
166+
let accountFactoryAddress = userProvidedAccountFactoryAddress;
167+
if (!accountFactoryAddress) {
168+
// TODO: this is not a good solution since the assumption that the account has a factory function is not guaranteed
169+
// instead, we should use default account factory address or throw here.
170+
try {
171+
const smartAccountContract = getContract({
172+
client: thirdwebClient,
173+
chain,
174+
address: accountAddress,
175+
});
176+
const onchainAccountFactoryAddress = await readContract({
177+
contract: smartAccountContract,
178+
method: "function factory() view returns (address)",
179+
params: [],
180+
});
181+
accountFactoryAddress = getAddress(onchainAccountFactoryAddress);
182+
} catch {
183+
throw new Error(
184+
`Failed to find factory address for account '${accountAddress}' on chain '${chainId}'`,
185+
);
186+
}
187+
}
188+
189+
signedUserOp = (await createAndSignUserOp({
190+
client: thirdwebClient,
191+
transactions: [
192+
{
193+
client: thirdwebClient,
194+
chain,
195+
...queuedTransaction,
196+
...overrides,
197+
to: getChecksumAddress(toAddress),
198+
},
199+
],
200+
adminAccount,
201+
smartWalletOptions: {
146202
chain,
147-
...queuedTransaction,
148-
to: getChecksumAddress(toAddress),
203+
sponsorGas: true,
204+
factoryAddress: accountFactoryAddress,
205+
overrides: {
206+
accountAddress,
207+
// TODO: let user pass entrypoint address for 0.7 support
208+
},
149209
},
150-
});
210+
// don't wait for the account to be deployed between userops
211+
// making this true will cause issues since it will block this call
212+
// until the previous userop for the same account is mined
213+
// we don't want this behavior in the engine context
214+
waitForDeployment: false,
215+
})) as UserOperation; // TODO support entrypoint v0.7 accounts
151216
} catch (e) {
152217
const erroredTransaction: ErroredTransaction = {
153218
...queuedTransaction,
@@ -160,10 +225,6 @@ const _sendUserOp = async (
160225
return erroredTransaction;
161226
}
162227

163-
const signedUserOp = await generateSignedUserOperation(
164-
queuedTransaction,
165-
populatedTransaction,
166-
);
167228
job.log(`Populated userOp: ${stringify(signedUserOp)}`);
168229

169230
const userOpHash = await bundleUserOp({

test/e2e/tests/write.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ describe("Write Tests", () => {
147147
name: "setContractURI",
148148
stateMutability: "nonpayable",
149149
type: "function",
150+
// Omitted
151+
// outputs: [],
150152
},
151153
],
152154
},

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11805,10 +11805,10 @@ [email protected]:
1180511805
uqr "0.1.2"
1180611806
viem "2.10.9"
1180711807

11808-
thirdweb@^5.60.1:
11809-
version "5.60.1"
11810-
resolved "https://registry.yarnpkg.com/thirdweb/-/thirdweb-5.60.1.tgz#cd5de2492c5b2afcdd549e14692ab3873b1f95cd"
11811-
integrity sha512-5N5QZ5JmzHaMeVegcIuR/ZHIh3fmyzBsBvgXqS7MPQI6aigLEQLAh2Hz4iPv8aVTX0KhPyLeVMlAXQgtbHVbmQ==
11808+
thirdweb@5.61.2:
11809+
version "5.61.2"
11810+
resolved "https://registry.yarnpkg.com/thirdweb/-/thirdweb-5.61.2.tgz#5fdbd0797a0482b22467bb321c7d6c2d1b8150c6"
11811+
integrity sha512-g9j/e647PB/sKSfqbiUS4V260lLIlAzy09YwS/GgytQWKpQkXfpPtoy9D6raTobwmfq+zCwJDX6wX+Rw7714Rg==
1181211812
dependencies:
1181311813
"@coinbase/wallet-sdk" "4.1.0"
1181411814
"@emotion/react" "11.13.3"

0 commit comments

Comments
 (0)