https://github.com/dozyio/js-libp2p-middleware-evm
https://github.com/dozyio/js-libp2p-middleware-evm
Last synced: about 1 month ago
JSON representation
- Host: GitHub
- URL: https://github.com/dozyio/js-libp2p-middleware-evm
- Owner: dozyio
- Created: 2025-03-09T17:56:40.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2025-08-06T10:52:49.000Z (2 months ago)
- Last Synced: 2025-08-09T09:52:37.471Z (2 months ago)
- Language: TypeScript
- Size: 918 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
# js-libp2p-middleware-evm
Requires https://github.com/libp2p/js-libp2p/pull/3204. Uses https://github.com/dozyio/evm-rule-engine
## Example
An slightly contrived example of 2 js-libp2p peers using a EVM blockchain to
validate that each peer is holding 1 Eth.The middleware is run after connection setup and encryption / multiplexing is
negotiated but before another stream is setup. The middleware is mutual i.e.
both sides run middleware checks, so it should run twice per connection.If the middleware fails, i.e. a peer isn't holding 1 Eth, the connection closes.
### Example Source
```typescript
// evm.ts
import { tcp } from "@libp2p/tcp"
import { createLibp2p } from "libp2p"
import { noise } from "@chainsafe/libp2p-noise"
import { identify } from '@libp2p/identify'
import { ping } from '@libp2p/ping'
import { yamux } from "@chainsafe/libp2p-yamux"
import { ethers, Wallet } from 'ethers'
import { prefixLogger } from '@libp2p/logger'
import { MiddlewareRegistrar } from 'libp2p-middleware-registrar'
import { middlewareEVM } from 'libp2p-middleware-evm'
import { EVMRuleEngine, createRulesFromDefinitions } from 'evm-rule-engine'
import type { Networks } from 'evm-rule-engine'const networks: Networks = [
{
provider: new ethers.JsonRpcProvider('http://127.0.0.1:8545'),
chainId: '31337'
}
]const engine = new EVMRuleEngine({ networks })
const ruleDefinitions = [
{
type: 'walletBalance',
chainId: '31337',
params: {
value: ethers.parseEther('1'),
compareType: 'gte'
}
},
]const rules = createRulesFromDefinitions(networks, ruleDefinitions)
engine.addRules(rules)async function newNode(port: string, nickname: string) {
let signer: Wallet
if (nickname === 'n1') {
signer = new Wallet('0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80')
} else if (nickname === 'n2') {
signer = new Wallet('0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d')
}
const node = await createLibp2p({
logger: prefixLogger(nickname),
addresses: {
listen: [
`/ip6/::/tcp/${port}`
]
},
transports: [
tcp(),
],
connectionEncrypters: [noise()],
streamMuxers: [yamux()],
services: {
identify: identify(),
ping: ping()
},
registrar: (components) => {
const middleware = middlewareEVM({ signer, evmRuleEngine: engine })return new MiddlewareRegistrar(components.registrar, middleware(components), components.logger)
}
})await node.start()
console.log(`Node started with id ${node.peerId.toString()}`)
console.log('Mutliaddrs', node.getMultiaddrs())return node
}const n1 = await newNode('12345', 'n1')
const n2 = await newNode('12346', 'n2')const rtt1 = await n1.services.ping.ping(n2.getMultiaddrs()[0])
console.log('rtt1', rtt1)
```### Running Example
Run anvil in a terminal window
```sh
anvil --port 8545 --chain-id 31337
```Run the example with logging (note: use node 23 to run typescript)
```sh
DEBUG=* node evm.ts
```