JSPM

  • Created
  • Published
  • Downloads 63
  • Score
    100M100P100Q53654F
  • License AGPL-3.0-only

A TypeScript library for sending user operations for ERC-4337 contracts.

Package Exports

  • sendop
  • sendop/contract-types

Readme

sendop.js

⚠️ WARNING: This project is under active development. Use at your own risk.

npm install ethers sendop

Dev Commands

bun install
docker compose up -d

bun test # bun built-in test
bun run test # vitest (isolate)
bun test -t 'test case' # test specific test case

bun run build

bun run build:contract-types

Usage (v0.4.1)

For more details, please refer to the *.test.ts files or the test folder.

import { Interface, JsonRpcProvider, Wallet } from 'ethers'
import {
    ADDRESS,
    PimlicoBundler,
    PublicPaymaster,
    randomBytes32,
    sendop,
    SimpleAccount,
    SimpleAccountCreationOptions,
} from 'sendop'

const PRIVATE_KEY = process.env.PRIVATE_KEY as string
const CLIENT_URL = process.env.sepolia as string
const PIMLICO_API_KEY = process.env.PIMLICO_API_KEY as string

const chainId = 11155111n

const client = new JsonRpcProvider(CLIENT_URL)
const signer = new Wallet(PRIVATE_KEY, client)
const bundler = new PimlicoBundler(chainId, `https://api.pimlico.io/v2/${chainId}/rpc?apikey=${PIMLICO_API_KEY}`, {
    entryPointVersion: 'v0.8',
    parseError: true,
    debug: true,
})

console.log('signer.address:', signer.address)

const creationOptions: SimpleAccountCreationOptions = {
    owner: signer.address,
    salt: randomBytes32(),
}

const accountAddress = await SimpleAccount.computeAccountAddress(client, creationOptions)
console.log('accountAddress:', accountAddress)

console.log('sending user operation...')

const op = await sendop({
    bundler,
    initCode: SimpleAccount.getInitCode(creationOptions),
    executions: [
        {
            to: ADDRESS.Counter,
            data: new Interface(['function setNumber(uint256)']).encodeFunctionData('setNumber', [
                Math.floor(Math.random() * 1000),
            ]),
            value: 0n,
        },
    ],
    opGetter: new SimpleAccount({
        address: accountAddress,
        client,
        bundler,
        signer,
    }),
    pmGetter: new PublicPaymaster(ADDRESS.PublicPaymaster),
})

console.log('waiting for user operation...')
console.log('opHash:', op.hash)

const receipt = await op.wait()
console.log('receipt.success', receipt.success)

Output

Bundler "debug" mode is enabled
signer.address: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
accountAddress: 0x1Eb4aACB9b99FF0C0d560E7e04974F8368C757c0
sending user operation...
waiting for user operation...
opHash: 0xf3613dceb7b68446f199501112740c854144ba642c40686eb2d301449fe4c150
receipt.success true