Skip to content

Upgrading v2 Accounts to Nexus after the shutdown of the Biconomy Bundler service

Notifications You must be signed in to change notification settings

bcnmy/upgrade-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Upgrade Bico API

Lightweight stateless API for upgrading Biconomy V2 accounts to Nexus via signed UserOperations.

Setup

  1. Install dependencies:
npm install
  1. Create .env file:
# Private key for the bundler/executor account (with 0x prefix)
PRIVATE_KEY=0x...

# RPC URL for the target chain
RPC_URL=https://polygon-mainnet.g.alchemy.com/v2/YOUR_API_KEY

# Optional: Server port (defaults to 3000)
PORT=3000
  1. Run the server:
# Development (with hot reload)
npm run dev

# Production
npm run build
npm start

⚠️ Important: Fund the Bundler EOA

The private key in your .env file corresponds to an EOA (Externally Owned Account) that acts as the bundler. This account must be funded with native gas tokens (e.g., MATIC on Polygon) to pay for transaction fees when calling the EntryPoint.

The bundler EOA pays for:

  • The handleOps transaction to the EntryPoint contract
  • All gas costs for executing the UserOperation on-chain

Make sure to:

  1. Check the bundler address logged on server startup
  2. Fund it with sufficient gas tokens for your expected volume
  3. Monitor the balance to avoid failed transactions

🔒 Security: Restrict Access

This API should NOT be exposed publicly without access control. Anyone who can call /execute can drain your bundler's gas funds by submitting operations.

Implement access control before deploying to production:

  • API Key Authentication: Add middleware to validate API keys in request headers
  • IP Allowlisting: Restrict access to known client IPs
  • JWT/Session Auth: Integrate with your existing user authentication system
  • Rate Limiting: Prevent abuse by limiting requests per user/IP

Example: Add API key middleware in src/index.ts:

app.use('*', async (c, next) => {
  const apiKey = c.req.header('X-API-Key');
  if (apiKey !== process.env.API_KEY) {
    return c.json({ error: 'Unauthorized' }, 401);
  }
  await next();
});

API Endpoints

GET /

Health check endpoint.

Response:

{
  "status": "ok",
  "message": "Upgrade API is running"
}

POST /generate-userop

Generates an unsigned UserOperation for upgrading a smart account.

Request:

{
  "smartAccountAddress": "0x1234...5678",
  "ownerAddress": "0xabcd...efgh"
}

Response:

{
  "userOp": {
    "sender": "0x1234...5678",
    "nonce": "0",
    "initCode": "0x",
    "callData": "0x...",
    "callGasLimit": "800000",
    "verificationGasLimit": "500000",
    "preVerificationGas": "100000",
    "maxFeePerGas": "20000000",
    "maxPriorityFeePerGas": "1000000",
    "paymasterAndData": "0x",
    "signature": "0x"
  },
  "userOpHash": "0x..."
}

POST /execute

Executes a signed UserOperation via the EntryPoint contract.

Request:

{
  "userOp": {
    "sender": "0x1234...5678",
    "nonce": "0",
    "initCode": "0x",
    "callData": "0x...",
    "callGasLimit": "800000",
    "verificationGasLimit": "500000",
    "preVerificationGas": "100000",
    "maxFeePerGas": "20000000",
    "maxPriorityFeePerGas": "1000000",
    "paymasterAndData": "0x",
    "signature": "0x..." 
  }
}

Response:

{
  "transactionHash": "0x..."
}

Usage Flow

  1. Client calls /generate-userop with the smart account address and owner address
  2. Client receives the unsigned userOp and userOpHash
  3. Client signs the userOpHash using their smart account's signing mechanism
  4. Client attaches the signature to userOp.signature
  5. Client calls /execute with the signed userOp
  6. Server submits the UserOp to the EntryPoint and returns the transaction hash

Configuration

Contract addresses can be modified in src/config.ts:

  • implementationAddress: Nexus implementation contract
  • bootStrapAddress: Bootstrap contract for initialization
  • ENTRY_POINT_ADDRESS: ERC-4337 EntryPoint v0.6

Gas limits can be adjusted in GAS_CONFIG within the same file.

Architecture

This API is stateless - no database or session storage is needed. The client is responsible for:

  • Storing the generated userOp between calls
  • Signing the userOpHash
  • Submitting the complete signed userOp to execute

The server simply generates the upgrade calldata and acts as a bundler to submit signed operations.

About

Upgrading v2 Accounts to Nexus after the shutdown of the Biconomy Bundler service

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published