Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aura evm bundler #7

Merged
merged 1 commit into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading