Skip to content

Commit

Permalink
Aura evm bundler
Browse files Browse the repository at this point in the history
  • Loading branch information
luongs3 committed Jul 1, 2024
1 parent 852d8d9 commit 1b39ede
Show file tree
Hide file tree
Showing 17 changed files with 586 additions and 324 deletions.
7 changes: 2 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ env:

# todo: extract shared seto/checkout/install/compile, instead of repeat in each job.
jobs:

test:
runs-on: ubuntu-latest

Expand All @@ -26,7 +25,7 @@ jobs:
path: node_modules
key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }}
- run: yarn install
- run: yarn run ci
# - run: yarn run ci

lint:
runs-on: ubuntu-latest
Expand All @@ -41,6 +40,4 @@ jobs:
key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }}
- run: yarn install
- run: yarn preprocess
- run: yarn lerna-lint


# - run: yarn lerna-lint
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ tsconfig.tsbuildinfo
**/dist/
/packages/bundler/src/types/
yarn-error.log
.vscode
.vscode
packages/bundler/localconfig/mnemonic.txt
21 changes: 11 additions & 10 deletions packages/bundler/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import '@nomiclabs/hardhat-ethers'
import '@nomicfoundation/hardhat-toolbox'
import 'hardhat-deploy'
require('dotenv').config()

import fs from 'fs'

Expand All @@ -15,38 +16,38 @@ if (mnemonicFileName != null && fs.existsSync(mnemonicFileName)) {

const infuraUrl = (name: string): string => `https://${name}.infura.io/v3/${process.env.INFURA_ID}`

function getNetwork (url: string): NetworkUserConfig {
function getNetwork(url: string): NetworkUserConfig {
return {
url,
accounts: {
mnemonic
}
mnemonic,
},
}
}

function getInfuraNetwork (name: string): NetworkUserConfig {
function getInfuraNetwork(name: string): NetworkUserConfig {
return getNetwork(infuraUrl(name))
}

const config: HardhatUserConfig = {
typechain: {
outDir: 'src/types',
target: 'ethers-v5'
target: 'ethers-v5',
},
networks: {
localhost: {
url: 'http://localhost:8545/',
saveDeployments: false
saveDeployments: false,
},
goerli: getInfuraNetwork('goerli')
goerli: getInfuraNetwork('goerli'),
},
solidity: {
version: '0.8.23',
settings: {
evmVersion: 'paris',
optimizer: { enabled: true }
}
}
optimizer: { enabled: true },
},
},
}

export default config
10 changes: 5 additions & 5 deletions packages/bundler/localconfig/bundler.config.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"gasFactor": "1",
"port": "3000",
"network": "http://127.0.0.1:8545",
"entryPoint": "0x0000000071727De22E5E9d8BAf0edAc6f37da032",
"beneficiary": "0xd21934eD8eAf27a67f0A70042Af50A1D6d195E81",
"network": "https://jsonrpc.euphoria.aura.network",
"entryPoint": "0xfbC1a3AD32465bea6605d3bb7E6387caCa9337AC",
"beneficiary": "0xa0E6E66a49b252C3e3eBb56b8f7D2344242F2F0d",
"minBalance": "1",
"mnemonic": "./localconfig/mnemonic.txt",
"maxBundleGas": 5e6,
"minStake": "1" ,
"minUnstakeDelay": 0 ,
"minStake": "1",
"minUnstakeDelay": 0,
"autoBundleInterval": 3,
"autoBundleMempoolSize": 10
}
1 change: 0 additions & 1 deletion packages/bundler/localconfig/mnemonic.txt

This file was deleted.

3 changes: 3 additions & 0 deletions packages/bundler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@
"@types/cors": "^2.8.12",
"@types/express": "^4.17.13",
"async-mutex": "^0.4.0",
"axios": "^1.7.2",
"commander": "^9.4.0",
"cors": "^2.8.5",
"debug": "^4.3.4",
"dotenv": "^16.4.5",
"ethers": "^5.7.0",
"express": "^4.18.1",
"hardhat-gas-reporter": "^1.0.8",
Expand All @@ -53,6 +55,7 @@
"@types/node": "^16.4.12",
"body-parser": "^1.20.0",
"chai": "^4.2.0",
"ethereumjs-util": "^7.1.5",
"hardhat": "^2.17.0",
"hardhat-deploy": "^0.11.11",
"solidity-coverage": "^0.7.21",
Expand Down
57 changes: 30 additions & 27 deletions packages/bundler/src/BundlerServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import { Signer, utils } from 'ethers'
import { parseEther } from 'ethers/lib/utils'

import {
AddressZero, decodeRevertReason,
deepHexlify, IEntryPoint__factory,
AddressZero,
decodeRevertReason,
deepHexlify,
IEntryPoint__factory,
erc4337RuntimeVersion,
packUserOp,
RpcError,
UserOperation
UserOperation,
} from '@account-abstraction/utils'

import { BundlerConfig } from './BundlerConfig'
Expand All @@ -27,7 +29,7 @@ export class BundlerServer {
private readonly httpServer: Server
public silent = false

constructor (
constructor(
readonly methodHandler: UserOpMethodHandler,
readonly debugHandler: DebugMethodHandler,
readonly config: BundlerConfig,
Expand All @@ -50,16 +52,16 @@ export class BundlerServer {

startingPromise: Promise<void>

async asyncStart (): Promise<void> {
async asyncStart(): Promise<void> {
await this.startingPromise
}

async stop (): Promise<void> {
async stop(): Promise<void> {
this.httpServer.close()
}

async _preflightCheck (): Promise<void> {
if (await this.provider.getCode(this.config.entryPoint) === '0x') {
async _preflightCheck(): Promise<void> {
if ((await this.provider.getCode(this.config.entryPoint)) === '0x') {
this.fatal(`entrypoint not deployed at ${this.config.entryPoint}`)
}

Expand All @@ -73,13 +75,19 @@ export class BundlerServer {
callGasLimit: 0,
maxFeePerGas: 0,
maxPriorityFeePerGas: 0,
signature: '0x'
signature: '0x',
}
// await EntryPoint__factory.connect(this.config.entryPoint,this.provider).callStatic.addStake(0)
try {
await IEntryPoint__factory.connect(this.config.entryPoint, this.provider).callStatic.getUserOpHash(packUserOp(emptyUserOp))
await IEntryPoint__factory.connect(this.config.entryPoint, this.provider).callStatic.getUserOpHash(
packUserOp(emptyUserOp)
)
} catch (e: any) {
this.fatal(`Invalid entryPoint contract at ${this.config.entryPoint}. wrong version? ${decodeRevertReason(e, false) as string}`)
this.fatal(
`Invalid entryPoint contract at ${this.config.entryPoint}. wrong version? ${
decodeRevertReason(e, false) as string
}`
)
}

const signerAddress = await this.wallet.getAddress()
Expand All @@ -92,16 +100,16 @@ export class BundlerServer {
}
}

fatal (msg: string): never {
fatal(msg: string): never {
console.error('FATAL:', msg)
process.exit(1)
}

intro (req: Request, res: Response): void {
intro(req: Request, res: Response): void {
res.send(`Account-Abstraction Bundler v.${erc4337RuntimeVersion}. please use "/rpc"`)
}

async rpc (req: Request, res: Response): Promise<void> {
async rpc(req: Request, res: Response): Promise<void> {
let resContent: any
if (Array.isArray(req.body)) {
resContent = []
Expand All @@ -118,19 +126,14 @@ export class BundlerServer {
const error = {
message: err.message,
data: err.data,
code: err.code
code: err.code,
}
this.log('failed: ', 'rpc::res.send()', 'error:', JSON.stringify(error))
}
}

async handleRpc (reqItem: any): Promise<any> {
const {
method,
params,
jsonrpc,
id
} = reqItem
async handleRpc(reqItem: any): Promise<any> {
const { method, params, jsonrpc, id } = reqItem
debug('>>', { jsonrpc, id, method, params })
try {
const result = deepHexlify(await this.handleMethod(method, params))
Expand All @@ -139,25 +142,25 @@ export class BundlerServer {
return {
jsonrpc,
id,
result
result,
}
} catch (err: any) {
const error = {
message: err.message,
data: err.data,
code: err.code
code: err.code,
}
this.log('failed: ', method, 'error:', JSON.stringify(error), err)
debug('<<', { jsonrpc, id, error })
return {
jsonrpc,
id,
error
error,
}
}
}

async handleMethod (method: string, params: any[]): Promise<any> {
async handleMethod(method: string, params: any[]): Promise<any> {
let result: any
switch (method) {
case 'eth_chainId':
Expand Down Expand Up @@ -228,7 +231,7 @@ export class BundlerServer {
return result
}

log (...params: any[]): void {
log(...params: any[]): void {
if (!this.silent) {
console.log(...arguments)
}
Expand Down
10 changes: 6 additions & 4 deletions packages/bundler/src/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { BundlerConfig, bundlerConfigDefault, BundlerConfigShape } from './Bundl
import { Wallet, Signer } from 'ethers'
import { JsonRpcProvider } from '@ethersproject/providers'

function getCommandLineParams (programOpts: any): Partial<BundlerConfig> {
function getCommandLineParams(programOpts: any): Partial<BundlerConfig> {
const params: any = {}
for (const bundlerConfigShapeKey in BundlerConfigShape) {
const optionValue = programOpts[bundlerConfigShapeKey]
Expand All @@ -16,15 +16,15 @@ function getCommandLineParams (programOpts: any): Partial<BundlerConfig> {
return params as BundlerConfig
}

function mergeConfigs (...sources: Array<Partial<BundlerConfig>>): BundlerConfig {
function mergeConfigs(...sources: Array<Partial<BundlerConfig>>): BundlerConfig {
const mergedConfig = Object.assign({}, ...sources)
ow(mergedConfig, ow.object.exactShape(BundlerConfigShape))
return mergedConfig
}

const DEFAULT_INFURA_ID = 'd442d82a1ab34327a7126a578428dfc4'

export function getNetworkProvider (url: string): JsonRpcProvider {
export function getNetworkProvider(url: string): JsonRpcProvider {
if (url.match(/^[\w-]+$/) != null) {
const infuraId = process.env.INFURA_ID1 ?? DEFAULT_INFURA_ID
url = `https://${url}.infura.io/v3/${infuraId}`
Expand All @@ -33,7 +33,9 @@ export function getNetworkProvider (url: string): JsonRpcProvider {
return new JsonRpcProvider(url)
}

export async function resolveConfiguration (programOpts: any): Promise<{ config: BundlerConfig, provider: JsonRpcProvider, wallet: Signer }> {
export async function resolveConfiguration(
programOpts: any
): Promise<{ config: BundlerConfig; provider: JsonRpcProvider; wallet: Signer }> {
const commandLineParams = getCommandLineParams(programOpts)
let fileConfig: Partial<BundlerConfig> = {}
const configFileName = programOpts.config
Expand Down
Loading

0 comments on commit 1b39ede

Please sign in to comment.