Skip to content

Commit

Permalink
Merge branch 'master' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
0xSulpiride committed Sep 14, 2023
2 parents e00d1c7 + 1d6f494 commit 17744b3
Show file tree
Hide file tree
Showing 75 changed files with 3,045 additions and 1,064 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/bundler-spec-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
repository: etherspot/skandha
ref: some-fixes

- name: Setup PDM
run: curl -sSL https://raw.githubusercontent.com/pdm-project/pdm/main/install-pdm.py | python3 -
Expand Down Expand Up @@ -61,8 +58,11 @@ jobs:
- name: Deploy ERC-4337 contracts
working-directory: ./bundler-spec-tests
# checkout to 0.6.0 commit https://github.com/eth-infinitism/account-abstraction/commits/abff2aca61a8f0934e533d0d352978055fddbd96
# change this command when using new EP
run: |
cd @account-abstraction && \
git checkout abff2aca61a8f0934e533d0d352978055fddbd96 && \
yarn deploy --network localhost
- name: Fund bundler
Expand All @@ -85,6 +85,7 @@ jobs:
- name: Send Slack notification
uses: ravsamhq/notify-slack-action@v2
if: always()
continue-on-error: true
with:
status: ${{ job.status }}
notification_title: "{workflow} has {status_message}"
Expand Down
11 changes: 11 additions & 0 deletions .github/workflows/check-package-version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,26 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup NodeJS
uses: "actions/setup-node@v3"
with:
node-version: 18.15

- name: Check if version has been updated
id: check
uses: EndBug/[email protected]
with:
token: ${{ secrets.GITHUB_TOKEN }}
file-name: ./package.json

- name: Log when changed
if: steps.check.outputs.changed == 'true'
run: 'echo "Yayy!! Version change found in commit ${{ steps.check.outputs.commit }}! New version: ${{ steps.check.outputs.version }} (${{ steps.check.outputs.type }})"'

- name: Dry run Skandha build
run: yarn install && yarn build && yarn run bootstrap

- name: Log when unchanged
if: steps.check.outputs.changed == 'false'
run: echo "No version change :/ Please update version in package.json!" && exit 1
167 changes: 88 additions & 79 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,80 +1,89 @@
<div align="center">
<h1 align="center">Skandha</h1>
</div>

<!-- PROJECT LOGO -->

<div align="center">
<img src="https://public.etherspot.io/assets/etherspot.gif" width="200" height="200">
<p>
<b>
A modular, developer-friendly Typescript Bundler for Ethereum EIP-4337 Account Abstraction
</b>
</p>
</div>

### Warning! This repo/software is under active development

## ⚙️ How to run (from Source code)

Run with one-liner:

```sh
curl -fsSL https://skandha.run | bash
```
or follow steps below:

1. install all dependencies by running `yarn`
2. build `yarn build && yarn bootstrap`
3. `cp config.json.default config.json`
4. edit `config.json`
5. (optional) run local geth-node from `test/geth-dev`
6. run `./skandha`
7. Skandha will run for all chains available in `config.json`
8. Networks will be available at `http://localhost:14337/{chainId}/` (e.g. for dev `http://localhost:14337/1337/`)

## 🐳 How to run (a Docker image)

1. `cp config.json.default config.json`
2. edit `config.json`
3. `docker build -t etherspot/skandha .`
4. `docker run --mount type=bind,source="$(pwd)"/config.json,target=/usr/app/config.json,readonly -dp 14337:14337 etherspot/skandha start`


## 📜 Additional features
- [x] Unsafe mode - bypass opcode & stake validation
- [x] Redirect RPC - Redirect ETH rpc calls to the underlying execution client. This is needed if you use UserOp.js
- [x] P2P - Exchange of UserOps between all the nodes in the network. Heavily inspired by the Lodestar's implementation of p2p (https://github.com/ChainSafe/lodestar/)

### ⚡️ CLI Options
- `--unsafeMode` - enables unsafeMode
- `--redirectRpc` - enables redirecting eth rpc calls

## 🔑 Relayer Configuration

#### config.json

```json
{
"networks": {
"dev": { # network Id (check packages/types/src/networks/networks.ts)
"entryPoints": [ # supported entry points
"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"
],
"relayer": "0xprivateKey", # relayer private key, can access from here or via environment variables (SKANDHA_MUMBAI_RELAYER | SKANDHA_DEV_RELAYER | etc.)
"beneficiary": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", # fee collector, avaiable via env var (SKANDHA_MUMBAI_BENEFICIARY | etc)
"rpcEndpoint": "http://localhost:8545", # rpc provider, also available via env variable (SKANDHA_MUMBAI_RPC | etc)
"minInclusionDenominator": 10, # optional, see EIP-4337
"throttlingSlack": 10, # optional, see EIP-4337
"banSlack": 10 # optional, see EIP-4337
"minSignerBalance": 1, # optional, default is 0.1 ETH. If the relayer's balance drops lower than this, it will be selected as a fee collector
"multicall": "0x", # optional, address of multicall3 contract, default is 0xcA11bde05977b3631167028862bE2a173976CA11 (see https://github.com/mds1/multicall#multicall3-contract-addresses)
}
}
}
```

#### Mempool_ID of the canonical mempool on various networks

- Sepolia | QmdDwVFoEEcgv5qnaTB8ncnXGMnqrhnA5nYpRr4ouWe4AT | https://ipfs.io/ipfs/QmdDwVFoEEcgv5qnaTB8ncnXGMnqrhnA5nYpRr4ouWe4AT?filename=sepolia_canonical_mempool.yaml
<div align="center">
<h1 align="center">Skandha</h1>
</div>

<!-- PROJECT LOGO -->

<div align="center">
<img src="https://public.etherspot.io/assets/etherspot.gif" width="200" height="200">
<p>
<b>
A modular, developer-friendly Typescript Bundler for Ethereum EIP-4337 Account Abstraction
</b>
</p>
</div>

### Warning! This repo/software is under active development

## ⚙️ How to run (from Source code)

Run with one-liner:

```sh
curl -fsSL https://skandha.run | bash
```
or follow steps below:

1. install all dependencies by running `yarn`
2. build `yarn build && yarn bootstrap`
3. `cp config.json.default config.json`
4. edit `config.json`
5. (optional) run local geth-node from `test/geth-dev`
6. run `./skandha`
7. Skandha will run for all chains available in `config.json`
8. Networks will be available at `http://localhost:14337/{chainId}/` (e.g. for dev `http://localhost:14337/1337/`)

## 🐳 How to run (a Docker image)

1. `cp config.json.default config.json`
2. edit `config.json`
3. `docker build -t etherspot/skandha .`
4. `docker run --mount type=bind,source="$(pwd)"/config.json,target=/usr/app/config.json,readonly -dp 14337:14337 etherspot/skandha start`


## 📜 Additional features
- [x] Unsafe mode - bypass opcode & stake validation
- [x] Redirect RPC - Redirect ETH rpc calls to the underlying execution client. This is needed if you use UserOp.js
- [x] P2P - Exchange of UserOps between all the nodes in the network. Heavily inspired by the Lodestar's implementation of p2p (https://github.com/ChainSafe/lodestar/)

### ⚡️ CLI Options
- `--unsafeMode` - enables unsafeMode
- `--redirectRpc` - enables redirecting eth rpc calls

## 🔑 Relayer Configuration

#### config.json

```yaml
{
"networks": {
"dev": { # network Id (check packages/types/src/networks/networks.ts)
"entryPoints": [ # supported entry points
"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"
],
"relayer": "0xprivateKey", # relayer private key, can access from here or via environment variables (SKANDHA_MUMBAI_RELAYER | SKANDHA_DEV_RELAYER | etc.)
"beneficiary": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", # fee collector, avaiable via env var (SKANDHA_MUMBAI_BENEFICIARY | etc)
"rpcEndpoint": "http://localhost:8545", # rpc provider, also available via env variable (SKANDHA_MUMBAI_RPC | etc)
"minInclusionDenominator": 10, # optional, see EIP-4337
"throttlingSlack": 10, # optional, see EIP-4337
"banSlack": 10 # optional, see EIP-4337
"minSignerBalance": 1, # optional, default is 0.1 ETH. If the relayer's balance drops lower than this, it will be selected as a fee collector
"multicall": "0xcA11bde05977b3631167028862bE2a173976CA11", # optional, multicall3 contract (see https://github.com/mds1/multicall#multicall3-contract-addresses)
"estimationStaticBuffer": 21000, # adds certain amount of gas to callGasLimit on estimation
"validationGasLimit": 10e6, # gas limit during simulateHandleOps and simulateValidation calls
"receiptLookupRange": 1024, # limits the block range of getUserOperationByHash and getUserOperationReceipt
"etherscanApiKey": "", # etherscan api is used to fetch gas prices
"conditionalTransactions": false, # enable conditional transactions
"rpcEndpointSubmit": "", # rpc endpoint that is used only during submission of a bundle
"gasPriceMarkup": 0, # adds % markup on reported gas price via skandha_getGasPrice, 10000 = 100.00%, 500 = 5%
"enforceGasPrice": false, # do not bundle userops with low gas prices
"enforceGasPriceThreshold": 1000, # gas price threshold in bps. If set to 500, userops' gas price is allowed to be 5% lower than the network's gas price
}
}
}
```

#### Mempool_ID of the canonical mempool on various networks

- Sepolia | QmdDwVFoEEcgv5qnaTB8ncnXGMnqrhnA5nYpRr4ouWe4AT | https://ipfs.io/ipfs/QmdDwVFoEEcgv5qnaTB8ncnXGMnqrhnA5nYpRr4ouWe4AT?filename=sepolia_canonical_mempool.yaml
- Mumbai | QmQfRyE9iVTBqZ17hPSP4tuMzaez83Y5wD874ymyRtj9VE | https://ipfs.io/ipfs/QmQfRyE9iVTBqZ17hPSP4tuMzaez83Y5wD874ymyRtj9VE?filename=mumbai_canonical_mempool.yaml
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
],
"npmClient": "yarn",
"useWorkspaces": true,
"version": "0.0.24",
"version": "0.0.44",
"stream": "true",
"command": {
"version": {
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"name": "root",
"private": true,
"version": "0.0.24",
"version": "0.0.44",
"engines": {
"node": ">=18.0.0"
},
"scripts": {
"node": ">=18.0.0"
},
"scripts": {
"clean": "rm -rf ./packages/*/lib ./packages/*/*.tsbuildinfo",
"bootstrap": "lerna bootstrap & lerna link",
"prebuild": "yarn workspace types run build",
Expand Down
6 changes: 3 additions & 3 deletions packages/api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "api",
"version": "0.0.24",
"version": "0.0.44",
"description": "The API module of Etherspot bundler client",
"author": "Etherspot",
"homepage": "https://https://github.com/etherspot/skandha#readme",
Expand Down Expand Up @@ -35,12 +35,12 @@
"class-transformer": "0.5.1",
"class-validator": "0.14.0",
"ethers": "5.7.2",
"executor": "^0.0.24",
"executor": "^0.0.44",
"fastify": "4.14.1",
"pino": "8.11.0",
"pino-pretty": "10.0.0",
"reflect-metadata": "0.1.13",
"types": "^0.0.24"
"types": "^0.0.44"
},
"devDependencies": {
"@types/connect": "3.4.35"
Expand Down
47 changes: 35 additions & 12 deletions packages/api/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import logger from "./logger";
import {
BundlerRPCMethods,
CustomRPCMethods,
HttpStatus,
RedirectedRPCMethods,
} from "./constants";
import { EthAPI, DebugAPI, Web3API, RedirectAPI } from "./modules";
Expand Down Expand Up @@ -131,11 +132,10 @@ export class ApiApp {

if (this.redirectRpc && method in RedirectedRPCMethods) {
const body = await redirectApi.redirect(method, params);
return res.status(200).send({
jsonrpc,
id,
...body,
});
if (body.error) {
return res.status(HttpStatus.OK).send({ ...body, id });
}
return res.status(HttpStatus.OK).send({ jsonrpc, id, ...body });
}

if (result === undefined) {
Expand All @@ -152,12 +152,20 @@ export class ApiApp {
entryPoint: params[1],
});
break;
case BundlerRPCMethods.eth_estimateUserOperationGas:
result = await ethApi.estimateUserOperationGas({
userOp: params[0],
entryPoint: params[1],
});
break;
case BundlerRPCMethods.eth_estimateUserOperationGas: {
if (this.testingMode) {
result = await ethApi.estimateUserOpGasAndValidateSignature({
userOp: params[0],
entryPoint: params[1],
});
} else {
result = await ethApi.estimateUserOperationGas({
userOp: params[0],
entryPoint: params[1],
});
}
break;
}
case BundlerRPCMethods.eth_getUserOperationReceipt:
result = await ethApi.getUserOperationReceipt(params[0]);
break;
Expand All @@ -176,6 +184,21 @@ export class ApiApp {
case CustomRPCMethods.skandha_getGasPrice:
result = await skandhaApi.getGasPrice();
break;
case CustomRPCMethods.skandha_feeHistory:
result = await skandhaApi.getFeeHistory({
entryPoint: params[0],
blockCount: params[1],
newestBlock: params[2],
});
break;
case CustomRPCMethods.skandha_config:
result = await skandhaApi.getConfig();
// skip hexlify for this particular rpc
return res.status(HttpStatus.OK).send({
jsonrpc,
id,
result,
});
default:
throw new RpcError(
`Method ${method} is not supported`,
Expand All @@ -185,7 +208,7 @@ export class ApiApp {
}

result = deepHexlify(result);
return res.status(200).send({
return res.status(HttpStatus.OK).send({
jsonrpc,
id,
result,
Expand Down
7 changes: 7 additions & 0 deletions packages/api/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export const CustomRPCMethods = {
skandha_validateUserOperation: "skandha_validateUserOperation",
skandha_getGasPrice: "skandha_getGasPrice",
skandha_config: "skandha_config",
skandha_feeHistory: "skandha_feeHistory",
};

export const BundlerRPCMethods = {
Expand Down Expand Up @@ -59,3 +61,8 @@ export const RedirectedRPCMethods = {
eth_maxPriorityFeePerGas: "eth_maxPriorityFeePerGas",
eth_sendRawTransaction: "eth_sendRawTransaction",
};

export enum HttpStatus {
OK = 200,
INTERNAL_SERVER_ERROR = 500,
}
15 changes: 15 additions & 0 deletions packages/api/src/dto/FeeHistory.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { IsEthereumAddress, ValidateIf } from "class-validator";
import { BigNumberish } from "ethers";
import { IsBigNumber } from "../utils/is-bignumber";

export class FeeHistoryArgs {
@IsEthereumAddress()
entryPoint!: string;

@IsBigNumber()
blockCount!: BigNumberish;

@ValidateIf((o) => o.newestBlock != "latest")
@IsBigNumber()
newestBlock!: BigNumberish | string;
}
Loading

0 comments on commit 17744b3

Please sign in to comment.