prool
v0.0.16
Published
HTTP testing instances for Ethereum
Downloads
5,616
Readme
Introduction
Prool is a library that provides programmatic HTTP testing instances for Ethereum. It is designed to be used in testing environments (e.g. Vitest) where you need to interact with an Ethereum server instance (e.g. Execution Node, 4337 Bundler, Indexer, etc) over HTTP or WebSocket.
Prool contains a set of pre-configured instances that can be used to simulate Ethereum server environments, being:
⚠️ = soon
You can also create your own custom instances by using the defineInstance
function.
Table of Contents
Install
npm i prool
pnpm add prool
bun i prool
Getting Started
Anvil (Execution Node)
Requirements
- Foundry binary installed
- Download:
curl -L https://foundry.paradigm.xyz | bash
- Download:
Usage
import { createServer } from 'prool'
import { anvil } from 'prool/instances'
const server = createServer({
instance: anvil(),
})
await server.start()
// Instances accessible at:
// "http://localhost:8545/1"
// "http://localhost:8545/2"
// "http://localhost:8545/3"
// "http://localhost:8545/n"
Parameters
See AnvilParameters
.
Alto (Bundler Node)
Requirements
@pimlico/alto
:npm i @pimlico/alto
Usage
import { createServer } from 'prool'
import { anvil, alto } from 'prool/instances'
const executionServer = createServer({
instance: anvil(),
port: 8545
})
await executionServer.start()
// Instances accessible at:
// "http://localhost:8545/1"
// "http://localhost:8545/2"
// "http://localhost:8545/3"
// "http://localhost:8545/n"
const bundlerServer = createServer({
instance: (key) => alto({
entrypoints: ['0x0000000071727De22E5E9d8BAf0edAc6f37da032'],
rpcUrl: `http://localhost:8545/${key}`,
executorPrivateKeys: ['0x...'],
})
})
await bundlerServer.start()
// Instances accessible at:
// "http://localhost:3000/1" (→ http://localhost:8545/1)
// "http://localhost:3000/2" (→ http://localhost:8545/2)
// "http://localhost:3000/3" (→ http://localhost:8545/3)
// "http://localhost:3000/n" (→ http://localhost:8545/n)
Parameters
See AltoParameters
.
Rundler (Bundler Node)
Requirements
Usage
import { createServer } from 'prool'
import { anvil, rundler } from 'prool/instances'
const executionServer = createServer({
instance: anvil(),
port: 8545
})
await executionServer.start()
// Instances accessible at:
// "http://localhost:8545/1"
// "http://localhost:8545/2"
// "http://localhost:8545/3"
// "http://localhost:8545/n"
const bundlerServer = createServer({
instance: (key) => rundler({
nodeHttp: `http://localhost:8545/${key}`,
})
})
await bundlerServer.start()
// Instances accessible at:
// "http://localhost:3000/1" (→ http://localhost:8545/1)
// "http://localhost:3000/2" (→ http://localhost:8545/2)
// "http://localhost:3000/3" (→ http://localhost:8545/3)
// "http://localhost:3000/n" (→ http://localhost:8545/n)
Parameters
See RundlerParameters.
Silius (Bundler Node)
Requirements
- Docker
- Silius Docker Image:
docker pull silius-rs/silius
Usage
import { createServer } from 'prool'
import { anvil, silius } from 'prool/instances'
const executionServer = createServer({
instance: anvil(),
port: 8545
})
await executionServer.start()
// Instances accessible at:
// "http://localhost:8545/1"
// "http://localhost:8545/2"
// "http://localhost:8545/3"
// "http://localhost:8545/n"
const bundlerServer = createServer({
instance: (key) => silius({
ethClientAddress: `http://localhost:8545/${key}`,
mnemonicPath: './keys/0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
})
})
await bundlerServer.start()
// Instances accessible at:
// "http://localhost:4000/1" (→ http://localhost:8545/1)
// "http://localhost:4000/2" (→ http://localhost:8545/2)
// "http://localhost:4000/3" (→ http://localhost:8545/3)
// "http://localhost:4000/n" (→ http://localhost:8545/n)
Parameters
See SiliusParameters
.
Stackup (Bundler Node)
Requirements
- Docker
- Stackup Docker Image:
docker pull stackupwallet/stackup-bundler:latest
Usage
import { createServer } from 'prool'
import { anvil, stackup } from 'prool/instances'
const executionServer = createServer({
instance: anvil(),
port: 8545
})
await executionServer.start()
// Instances accessible at:
// "http://localhost:8545/1"
// "http://localhost:8545/2"
// "http://localhost:8545/3"
// "http://localhost:8545/n"
const bundlerServer = createServer({
instance: (key) => stackup({
ethClientUrl: `http://localhost:8545/${key}`,
privateKey: '0x...',
})
})
await bundlerServer.start()
// Instances accessible at:
// "http://localhost:4337/1" (→ http://localhost:8545/1)
// "http://localhost:4337/2" (→ http://localhost:8545/2)
// "http://localhost:4337/3" (→ http://localhost:8545/3)
// "http://localhost:4337/n" (→ http://localhost:8545/n)
Parameters
See StackupParameters
.
Reference
createServer
Creates a server that manages a pool of instances via a proxy.
Usage
import { createServer } from 'prool'
import { anvil } from 'prool/instances'
const executionServer = createServer({
instance: anvil(),
})
await executionServer.start()
// Instances accessible at:
// "http://localhost:8545/1"
// "http://localhost:8545/2"
// "http://localhost:8545/3"
// "http://localhost:8545/n"
// "http://localhost:8545/n/start"
// "http://localhost:8545/n/stop"
// "http://localhost:8545/n/restart"
// "http://localhost:8545/healthcheck"
Endpoints:
/:key
: Proxy to instance atkey
./:key/start
: Start instance atkey
./:key/stop
: Stop instance atkey
./:key/restart
: Restart instance atkey
./healthcheck
: Healthcheck endpoint.
API
| Name | Description | Type |
| ---------- | -------------------------------------------------------- | --------------------------------------- |
| instance
| Instance for the server. | Instance \| (key: number) => Instance
|
| limit
| Number of instances that can be instantiated in the pool | number
|
| host
| Host for the server. | string
|
| port
| Port for the server. | number
|
| returns | Server | CreateServerReturnType
|
defineInstance
Creates an instance definition, that can be used with createServer
or definePool
.
Usage
import { defineInstance } from 'prool'
const foo = defineInstance((parameters: FooParameters) => {
return {
name: 'foo',
host: 'localhost',
port: 3000,
async start() {
// ...
},
async stop() {
// ...
},
}
})
API
| Name | Description | Type |
| ------- | -------------------- | ------------------ |
| fn
| Instance definition. | DefineInstanceFn
|
| returns | Instance. | Instance
|
definePool
Defines a pool of instances. Instances can be started, cached, and stopped against an identifier.
Usage
import { definePool } from 'prool'
import { anvil } from 'prool/instances'
const pool = definePool({
instance: anvil(),
})
const instance_1 = await pool.start(1)
const instance_2 = await pool.start(2)
const instance_3 = await pool.start(3)
API
| Name | Description | Type |
| ---------- | -------------------------------------------------------- | ---------- |
| instance
| Instance for the pool. | Instance
|
| limit
| Number of instances that can be instantiated in the pool | number
|
| returns | Pool. | Pool
|
Authors
License
MIT License