Skip to content

Commit

Permalink
support pfl_sendRawTransactionConditional
Browse files Browse the repository at this point in the history
  • Loading branch information
mouseless0x committed Jan 23, 2025
1 parent ae76280 commit 8faacd9
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/cli/config/bundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export const bundlerArgsSchema = z.object({
),
"refilling-wallets": z.boolean().default(true),
"aa95-gas-multiplier": z.string().transform((val) => BigInt(val)),
"enable-fastlane": z.boolean(),
"enable-instant-bundling-endpoint": z.boolean(),
"enable-experimental-7702-endpoints": z.boolean()
})
Expand Down
6 changes: 6 additions & 0 deletions src/cli/config/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,12 @@ export const bundlerOptions: CliCommandOptions<IBundlerArgsInput> = {
description: "Amount to scale the gas estimations used for bundling",
type: "string",
default: "100"
},
"enable-fastlane": {
description:
"Enable bundling v0.6 userOperations through the fastlane ERC-4337 mempool",
type: "boolean",
default: false
}
}

Expand Down
22 changes: 22 additions & 0 deletions src/executor/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
import type { SendTransactionErrorType } from "viem"
import type { AltoConfig } from "../createConfig"
import type { SendTransactionOptions } from "./types"
import { sendPflConditional } from "./fastlane"

export interface GasEstimateResult {
preverificationGas: bigint
Expand All @@ -58,6 +59,7 @@ export interface GasEstimateResult {
export type HandleOpsTxParam = {
ops: PackedUserOperation[]
isUserOpVersion06: boolean
isReplacementTx: boolean
entryPoint: Address
}

Expand Down Expand Up @@ -298,6 +300,7 @@ export class Executor {

txParam = {
isUserOpVersion06,
isReplacementTx: true,
ops: userOps,
entryPoint: transactionInfo.entryPoint
}
Expand Down Expand Up @@ -500,6 +503,24 @@ export class Executor {
// Try sending the transaction and updating relevant fields if there is an error.
while (attempts < maxAttempts) {
try {
if (
this.config.enableFastlane &&
isUserOpVersion06 &&
!txParam.isReplacementTx
) {
const serializedTransaction =
await this.config.walletClient.signTransaction(request)

transactionHash = await sendPflConditional({
serializedTransaction,
publicClient: this.config.publicClient,
walletClient: this.config.walletClient,
logger: this.logger
})

break
}

transactionHash =
await this.config.walletClient.sendTransaction(request)

Expand Down Expand Up @@ -832,6 +853,7 @@ export class Executor {
transactionHash = await this.sendHandleOpsTransaction({
txParam: {
ops: userOps,
isReplacementTx: false,
isUserOpVersion06,
entryPoint
},
Expand Down
69 changes: 69 additions & 0 deletions src/executor/fastlane.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Logger } from "@alto/utils"
import { join } from "path"
import {
Hex,
createClient,
http,
SendRawTransactionReturnType,
Hash,
WalletClient,
PublicClient,
toHex,
BaseError
} from "viem"

const pflClient = createClient({
transport: http("https://polygon-rpc.fastlane.xyz")
})

export async function sendPflConditional({
serializedTransaction,
publicClient,
walletClient,
logger
}: {
serializedTransaction: Hash
publicClient: PublicClient
walletClient: WalletClient
logger: Logger
}): Promise<SendRawTransactionReturnType> {
try {
const blockNumberMin = await publicClient.getBlockNumber()
const blockNumberMax = blockNumberMin + 25n

const timestampMin = Date.now() / 1000
const timestampMax = timestampMin + 500

const opts = {
//knownAccounts: {}
blockNumberMin: toHex(blockNumberMin),
blockNumberMax: toHex(blockNumberMax),
timestampMin: Math.floor(timestampMin),
timestampMax: Math.floor(timestampMax)
}

const txHash = (await pflClient.request({
// @ts-ignore
method: "pfl_sendRawTransactionConditional",
// @ts-ignore
params: [serializedTransaction, opts]
})) as Hex

if (!txHash) {
const error = new BaseError(
"FastLane API returned empty transaction hash"
)
error.details =
"PFL conditional transaction failed: No txHash in response"
throw error
}

return txHash
} catch (e: unknown) {
logger.error(
"Error sending through pfl_sendRawTransactionConditional ",
(e as any)?.details
)
return await walletClient.sendRawTransaction({ serializedTransaction })
}
}

0 comments on commit 8faacd9

Please sign in to comment.