Skip to content

Commit

Permalink
Simplify userop signing flow (#711)
Browse files Browse the repository at this point in the history
* Simplify userop signing flow

* upgrade SDK

* fix gas overrides

---------

Co-authored-by: Phillip Ho <[email protected]>
  • Loading branch information
joaquim-verges and arcoraven authored Oct 9, 2024
1 parent 29fe845 commit d17c414
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 155 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
"prom-client": "^15.1.3",
"prool": "^0.0.16",
"superjson": "^2.2.1",
"thirdweb": "^5.60.1",
"thirdweb": "5.61.2",
"uuid": "^9.0.1",
"winston": "^3.14.1",
"zod": "^3.23.8"
Expand Down
134 changes: 0 additions & 134 deletions src/utils/transaction/userOperation.ts

This file was deleted.

93 changes: 77 additions & 16 deletions src/worker/tasks/sendTransactionWorker.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { Worker, type Job, type Processor } from "bullmq";
import assert from "node:assert";
import superjson from "superjson";
import { getAddress, toSerializableTransaction, type Hex } from "thirdweb";
import {
getAddress,
getContract,
readContract,
toSerializableTransaction,
type Hex,
} from "thirdweb";
import { stringify } from "thirdweb/utils";
import { bundleUserOp } from "thirdweb/wallets/smart";
import {
bundleUserOp,
createAndSignUserOp,
type UserOperation,
} from "thirdweb/wallets/smart";
import { getContractAddress } from "viem";
import { TransactionDB } from "../../db/transactions/db";
import {
Expand Down Expand Up @@ -33,7 +43,6 @@ import type {
QueuedTransaction,
SentTransaction,
} from "../../utils/transaction/types";
import { generateSignedUserOperation } from "../../utils/transaction/userOperation";
import { enqueueTransactionWebhook } from "../../utils/transaction/webhook";
import { reportUsage } from "../../utils/usage";
import { MineTransactionQueue } from "../queues/mineTransactionQueue";
Expand Down Expand Up @@ -130,24 +139,80 @@ const _sendUserOp = async (
};
}

const { accountAddress, to, target, chainId } = queuedTransaction;
const {
accountAddress,
to,
target,
chainId,
from,
accountFactoryAddress: userProvidedAccountFactoryAddress,
overrides,
} = queuedTransaction;
const chain = await getChain(chainId);

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

let populatedTransaction: PopulatedTransaction;
// Resolve Admin-Account for UserOperation Signer
const adminAccount = await getAccount({
chainId,
from,
});

let signedUserOp: UserOperation;
try {
populatedTransaction = await toSerializableTransaction({
from: getChecksumAddress(accountAddress),
transaction: {
client: thirdwebClient,
// Resolve the user factory from the provided address, or from the `factory()` method if found.
let accountFactoryAddress = userProvidedAccountFactoryAddress;
if (!accountFactoryAddress) {
// TODO: this is not a good solution since the assumption that the account has a factory function is not guaranteed
// instead, we should use default account factory address or throw here.
try {
const smartAccountContract = getContract({
client: thirdwebClient,
chain,
address: accountAddress,
});
const onchainAccountFactoryAddress = await readContract({
contract: smartAccountContract,
method: "function factory() view returns (address)",
params: [],
});
accountFactoryAddress = getAddress(onchainAccountFactoryAddress);
} catch {
throw new Error(
`Failed to find factory address for account '${accountAddress}' on chain '${chainId}'`,
);
}
}

signedUserOp = (await createAndSignUserOp({
client: thirdwebClient,
transactions: [
{
client: thirdwebClient,
chain,
...queuedTransaction,
...overrides,
to: getChecksumAddress(toAddress),
},
],
adminAccount,
smartWalletOptions: {
chain,
...queuedTransaction,
to: getChecksumAddress(toAddress),
sponsorGas: true,
factoryAddress: accountFactoryAddress,
overrides: {
accountAddress,
// TODO: let user pass entrypoint address for 0.7 support
},
},
});
// don't wait for the account to be deployed between userops
// making this true will cause issues since it will block this call
// until the previous userop for the same account is mined
// we don't want this behavior in the engine context
waitForDeployment: false,
})) as UserOperation; // TODO support entrypoint v0.7 accounts
} catch (e) {
const erroredTransaction: ErroredTransaction = {
...queuedTransaction,
Expand All @@ -160,10 +225,6 @@ const _sendUserOp = async (
return erroredTransaction;
}

const signedUserOp = await generateSignedUserOperation(
queuedTransaction,
populatedTransaction,
);
job.log(`Populated userOp: ${stringify(signedUserOp)}`);

const userOpHash = await bundleUserOp({
Expand Down
2 changes: 2 additions & 0 deletions test/e2e/tests/write.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ describe("Write Tests", () => {
name: "setContractURI",
stateMutability: "nonpayable",
type: "function",
// Omitted
// outputs: [],
},
],
},
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11805,10 +11805,10 @@ [email protected]:
uqr "0.1.2"
viem "2.10.9"

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

0 comments on commit d17c414

Please sign in to comment.