Socket
Book a DemoInstallSign in
Socket

@actalink/erc20-paymaster

Package Overview
Dependencies
Maintainers
2
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@actalink/erc20-paymaster

ERC20 Paymaster service for Acta Account Abstraction

0.0.2-alpha.14
latest
npmnpm
Version published
Weekly downloads
1
-92.31%
Maintainers
2
Weekly downloads
 
Created
Source

A service for sponsoring ERC20 token payments, and scheduling token transfers using Actalink Account Abstraction infrastructure.

Overview

The @actalink/erc20-paymaster enables smart contract wallets to pay gas fees using ERC20 tokens instead of native ETH. This package provides a paymaster service that can be integrated with Account Abstraction infrastructure to allow for a more flexible user experience.

Architecture

The ERC20 Paymaster implements a modular service architecture for handling token-based gas fee payments:

PaymasterService Architecture

Key Components

  • PaymasterService: The core class that orchestrates all components and manages the paymaster lifecycle.

    • Creates and configures the Express application server
    • Sets up authentication (SIWE based E2E Auth) and API routes
    • Spawns and manages background worker threads
    • Provides access to stored user operations to extension developers

    PaymasterService Architecture

    The PaymasterService follows microservice architecture to better manage the complexity of the system. The service is divided into several components, each responsible for a specific task:

  • Express Application: Handles HTTP requests and provides API endpoints for:

    • Sponsor User Operations
    • User operation scheduling
    • User operation cancellation
    • User operation listing
    • User operation status checking
    • Nonce key retrieval
  • API Routes: Endpoints for client interaction, mounted at /api/*.

  • Worker Thread: Background process for:

    • Monitoring pending user operations
    • Processing and submitting transactions to the blockchain
    • Managing transaction status updates
  • SQLite Database: Persistent storage designed to run within microservices for:

    • Storing signed user operations and their current status
    • Transaction history and status updates

Service Lifecycle

  • Initialize: Constructs the service with configuration options
  • Setup Middleware & Routes: Configures Express with middleware and API routes
  • Start HTTP Server: Begins listening for client requests
  • Create Worker: Spawns background worker for transaction processing (if enabled)

Authentication Flow

The ERC20 Paymaster service uses Sign-In with Ethereum (SIWE) for authentication. This provides a secure, web3-native way to authenticate users using their Ethereum wallets.

SIWE Authentication Flow

Authentication Process

  • Request Challenge

    • Client sends a POST request to /api/challenge-siwe with their wallet address
    • PaymasterService generates a unique SIWE message as challenge
    • Message includes service details, nonce, and timestamp
  • Message Signing

    • Client receives SIWE message
    • Wallet signs the message using private key
    • Returns signature to client
  • Authentication

    • Client makes authenticated requests by including:
      • Base64 encoded SIWE message in x-siwe-message header
      • Signature in x-siwe-signature header
    • PaymasterService verifies signature matches wallet address
    • If valid, grants access to protected resources

Usage Example

// 1. Get SIWE challenge
const challengeResponse = await fetch('/api/challenge-siwe', {
  method: 'POST',
  body: JSON.stringify({ walletAddress: account.address })
});
const { message } = await challengeResponse.json();

// 2. Sign message with wallet
const signature = await wallet.signMessage(message);

// 3. Make authenticated request
const response = await fetch('/api/protected-endpoint', {
  headers: {
    'x-siwe-message': Buffer.from(message).toString('base64'),
    'x-siwe-signature': signature
  }
});

Installation

npm install @actalink/erc20-paymaster

Quick Start

import { ERC20PaymasterService } from '@actalink/erc20-paymaster';

// Initialize the paymaster
const service = new PaymasterService({
  // Configuration options
  port: 4000,                    // Port to run the service on
  enableLuciaAuth: false,        // Enable Lucia authentication
  enableSIWEe2eAuth: true,       // Enable Sign-In with Ethereum authentication
  enableWorker: true,            // Enable background worker for transaction processing
  bodyLimit: "1024kb",           // Request body size limit
  logFormat: "dev",              // Morgan logging format
  onUserOpSuccess: (userOp: UserOperationAndProps) => {
    const { userOpHash, transactionHash } = userOp;
    console.log(`UserOperation ${userOpHash} succeeded with transaction ${transactionHash}`);
    // Add custom logic here (e.g., update database, notify user)
  }
});

// Start the service
await service.start();

API Documentation

The service exposes the following REST API endpoints:

ERC20 Paymaster Endpoints

POST /api/scheduleops

Schedules user operations for future execution. This endpoint allows you to schedule one or more user operations to be executed at a specific time.

Request Body:

[
  {
    "userOp": {
      // UserOperation object (RpcUserOperation<'0.7'>)
      "sender": "0x...",
      "nonce": "0x...",
      // ... other UserOperation fields
    },
    "userOpHash": "0x...",
    "entryPoint": "0x...",
    "executionTime": 1234567890000, // Unix timestamp in milliseconds
    "signerAddress": "0x..."
  }
  // ... more operations
]

Validation:

  • Execution time must be at least 2 minutes in the future
  • Valid merkle signature in the UserOperation
  • Valid entry point address

Response:

  • Success (200): "N UserOperations scheduled successfully!" where N is the number of operations scheduled
  • Error (404): Error message with details

Notes:

  • Operations are stored with initial status "pending"
  • A background worker processes pending operations near their execution time
  • Operations can be cancelled using the /cancelops endpoint before execution
  • No authentication required for this endpoint

POST /api/challenge-siwe

Generates a Sign-In with Ethereum (SIWE) challenge message for authentication.

Request Body:

{
  "walletAddress": "0x..." // The wallet address to authenticate
}

Response:

{
  "message": "service.acta.link wants you to sign in with your Ethereum account:\n0x...\n\nI accept the ServiceOrg Terms of Service: https://service.org/tos\n\nURI: https://service.org/login\nVersion: 1\nChain ID: 1\nNonce: ...\nIssued At: ..."
}

Status Codes:

  • 200: Challenge message generated successfully
  • 400: Invalid wallet address
  • 500: Server error

Usage:

  • Call this endpoint to get a SIWE challenge message
  • Sign the message using the user's wallet
  • Use the signed message and signature in subsequent authenticated requests

POST /api/sign/v2

Sponsors a user operation with ERC20 token payment.

Request Body:

{
  "method": "pm_sponsorUserOperation",
  "params": [
    userOperation,      // UserOperation object
    entryPointAddress, // Entry point contract address
    {
      "type": "sponsor" // Sponsorship type
    }
  ]
}

Response:

{
  "result": {
    ...userOperation,
    "paymasterData": "0x...",  // Signed paymaster data
    "paymasterVerificationGasLimit": "0x...",
    "paymasterPostOpGasLimit": "0x..."
  }
}

POST /api/cancelops

Cancels pending user operations for an authenticated user. Requires SIWE (Sign-In with Ethereum) authentication.

Headers:

x-siwe-message: <base64 encoded SIWE message>
x-siwe-signature: <signature>

Response:

[
  "0x...",  // Array of cancelled userOpHashes
  "0x..."
]

Authentication: This endpoint requires SIWE authentication. To authenticate:

  • Get a SIWE challenge message using /api/challenge-siwe
  • Sign the message with your wallet
  • Include the base64 encoded message and signature in the request headers

Status Codes:

  • 200: Successfully cancelled operations
  • 403: Invalid authentication or signature
  • 500: Server error

POST /api/listops

Lists all scheduled user operations for a given smart wallet address.

Request Body:

{
  "validators": ["0x..."], // Array of validator addresses
  "salt": "0x..."         // Salt for smart wallet address calculation
}

Response:

[
  {
    "userOpHash": "0x...",
    "signerAddress": "0x...",
    "userOp": {
      // UserOperation object
    },
    "entryPoint": "0x...",
    "executionTime": 1234567890000,
    "status": "pending",
    "transactionHash": ""
  }
  // ... more operations
]

Authentication: Requires user authentication. The endpoint verifies that the authenticated user owns the smart wallet.

Status Codes:

  • 200: Successfully retrieved operations
  • 403: Invalid user or address
  • 500: Server error

GET /api/listPendingOps

Lists all pending user operations for a given smart wallet address.

Request Body:

{
  "validators": ["0x..."], // Array of validator addresses
  "salt": "0x..."         // Salt for smart wallet address calculation
}

Response:

[
  {
    "userOpHash": "0x...",
    "signerAddress": "0x...",
    "userOp": {
      // UserOperation object
    },
    "entryPoint": "0x...",
    "executionTime": 1234567890000,
    "status": "pending",
    "transactionHash": ""
  }
  // ... more operations
]

Notes:

  • Only returns operations with "pending" status
  • Useful for monitoring operations that haven't been executed yet
  • Can be used in conjunction with /cancelops to manage pending operations

POST /api/getPendingNonceKeys

Retrieves a list of unique nonce keys from pending user operations for a given smart wallet address. This is useful for checking which nonce slots are currently in use by pending operations.

Request Body:

{
  "validators": ["0x..."], // Array of validator addresses
  "salt": "0x..."         // Salt for smart wallet address calculation
}

Response:

[
  "0x1234...", // Array of unique nonce keys (first 42 characters of the nonce)
  "0x5678..."
]

Notes:

  • Only considers operations with "pending" status
  • Nonce keys are extracted from the first 42 characters of each operation's nonce
  • Duplicates are automatically filtered out
  • Useful for nonce management and preventing nonce conflicts

Service Management

The PaymasterService class provides the following methods:

  • start(): Starts the HTTP server and worker thread (if enabled)
  • stop(): Stops the service and terminates the worker thread
  • getApp(): Returns the Express application instance for custom configuration

For detailed API documentation including TypeScript types and interfaces, run:

npm run docs

Then open docs/index.html in your browser.

Configuration

The PaymasterService accepts the following configuration options:

OptionTypeDescriptionDefault
portnumberPort number for the HTTP server4000
enableSIWEe2eAuthbooleanEnable Sign-In with Ethereum authenticationtrue
enableWorkerbooleanEnable background worker for transaction processingtrue
workerPathstringPath to worker thread script"build/workers/scheduler.js"
bodyLimitstringRequest body size limit"1024kb"
logFormatstringMorgan logging format"dev"
onUserOpSuccess(userOp: UserOperationAndProps) => voidOptional callback function executed by the background worker when a scheduled UserOperation is successfully mined on-chain. The function receives a single argument of type UserOperationAndProps, which includes the original userOp object, userOpHash, the final transactionHash, the updated status, and other details.undefined
appexpress.ApplicationProvide an existing Express application instanceexpress()

Environment Variables

The service requires the following environment variables:

PAYMASTER_PORT=4000           # Service port (optional, defaults to 4000)
PVT_KEY=                      # Private key for the paymaster account
PROVIDER=                     # RPC provider URL
CHAIN_ID=                    # Chain ID for the network (e.g. 137 for Polygon)

Supported Networks

The paymaster service currently supports the following networks:

  • Ethereum Mainnet (Chain ID: 1)
  • Polygon (Chain ID: 137)
  • Linea (Chain ID: 59144)
  • Hedera (Chain ID: 295)

Examples

See the examples directory for integration examples.

Advanced Usage

Extending the API

The underlying Express router used by the service is also exported as paymasterRouter. You can use this to add custom routes or middleware to the service instance:

import { PaymasterService, paymasterRouter } from '@actalink/erc20-paymaster';
import express from 'express';

const service = new PaymasterService();
const app = service.getApp(); // Get the Express app instance

// Add custom middleware
app.use('/api', (req, res, next) => {
  console.log('Custom middleware for API routes');
  next();
});

// Add a custom route
app.get('/custom-status', (req, res) => {
  res.json({ custom: 'status OK' });
});

// You can also add routes directly to the exported router
paymasterRouter.get('/custom-paymaster-route', (req, res) => {
  res.json({ message: 'Custom route within paymaster router' });
});

await service.start();

Exported Utility Functions

The package also exports several utility functions that might be useful for advanced integrations or direct database interaction. Use these with caution as they might expose internal implementation details.

  • getSignerFromMerkleSignature(root: Hex, proof: Hex[], leaf: Hex): Address

    • Recovers the signer address from a Merkle signature, root, proof, and leaf.
    • Useful for verifying Merkle-based signatures off-chain.
  • getScheduledUserOpsByHash(hashes: string[]): UserOperationAndProps[]

    • Retrieves scheduled user operations from the database based on their userOpHashes.
  • getScheduledUserOps(address: Address): UserOperationAndProps[]

    • Retrieves all scheduled user operations associated with a specific smart wallet address.
  • removeUserOpByHash(hash: string): void

    • Removes a specific user operation from the scheduling database using its userOpHash.
    • Note: This directly modifies the database state.
  • getInsertQuery(): Database.Statement

    • Returns the prepared SQLite statement used for inserting new scheduled user operations.
    • Provides direct access to the database insertion mechanism.

License

MIT

Keywords

ethereum

FAQs

Package last updated on 02 May 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.