Run a Resolver
Resolvers execute user actions after assets have been indexed on the destination chain. They earn resolver fees for each successful execution.
What Resolvers Do
1. MONITOR INDEXED MESSAGES
└── Watch for messages with pending actions
2. VALIDATE PROFITABILITY
└── Check: resolver fee > gas cost + profit margin
3. EXECUTE ACTION
└── Call Smart Account with user's signed action
4. EARN FEE
└── Resolver fee paid upon successful execution
Requirements
| Requirement | Minimum | Recommended |
|---|---|---|
| CPU | 2 cores | 4 cores |
| RAM | 2 GB | 4 GB |
| Storage | 10 GB | 20 GB |
| Network | 10 Mbps | 100 Mbps |
| ETH (destination) | 0.1 ETH | 0.5 ETH |
| Tokens (optional) | 0 | Variable |
Note: Some actions require resolvers to provide ETH or tokens upfront, reimbursed from fees. This requires liquidity.
Quick Start
1. Clone Repository
git clone https://github.com/pons-network/resolver
cd resolver
npm install
2. Configure Environment
cp .env.example .env
Edit .env:
# Mode
OPERATOR_MODE=executor
# Wallet (NEVER use your main wallet)
PRIVATE_KEY=your_private_key_here
# Chain Configuration
DESTINATION_CHAIN_ID=88991
# RPC Endpoints
DESTINATION_RPC_URL=https://rpc.testnet.arc.network
# Fee Configuration
MIN_RESOLVER_FEE=150000 # Minimum fee (in token units)
MIN_PROFIT_BPS=10 # 0.1% minimum profit margin
3. Run Resolver
# Development
npm run start -- --mode executor
# Production (with PM2)
pm2 start npm --name "pons-resolver" -- run start -- --mode executor
# Docker
docker-compose up -d resolver
Configuration Reference
Core Settings
# Required
PRIVATE_KEY= # Operator wallet
DESTINATION_RPC_URL= # Destination chain RPC
# Chain ID
DESTINATION_CHAIN_ID=88991 # Arc Testnet
Fee Settings
# Minimum fee to process
MIN_RESOLVER_FEE=150000 # Minimum fee (in token units)
# Minimum profit margin
MIN_PROFIT_BPS=10 # 0.1% of transaction
# Skip unprofitable transactions
SKIP_UNPROFITABLE=true
Funding Settings
Some actions require the resolver to provide ETH or tokens:
# Maximum ETH to provide per transaction
MAX_ETH_FUNDING=0.1 # 0.1 ETH max
# Maximum token reimbursement to accept
MAX_REIMBURSEMENT=500 # Max reimbursement amount
# Enable/disable funding
ENABLE_FUNDING=true
Performance Settings
# Concurrent processing
MAX_CONCURRENT_JOBS=5
# How often to check for new messages
POLL_INTERVAL_MS=5000
Docker Deployment
docker-compose.yml
version: '3.8'
services:
resolver:
build: .
command: ["npm", "run", "start", "--", "--mode", "executor"]
env_file:
- .env
restart: unless-stopped
deploy:
resources:
limits:
cpus: '2'
memory: 2G
Run
docker-compose up -d resolver
docker-compose logs -f resolver
Running Both Indexer + Resolver
For maximum earnings, run both:
# Using --mode both
npm run start -- --mode both
# Or separate processes
pm2 start npm --name "pons-indexer" -- run start -- --mode indexer
pm2 start npm --name "pons-resolver" -- run start -- --mode executor
Funding Requirements
Simple Actions (No Funding)
Most cross-chain transfers only need gas:
User action: Bridge tokens
Resolver needs: Gas only (~0.002 ETH)
Advanced Actions (With Funding)
Some actions require the resolver to provide tokens:
User action: Bridge tokens and swap for WETH
Resolver provides: Gas + DEX swap execution
Resolver reimbursed: From user's Smart Account fees
Funding Configuration
# Only resolve actions within your liquidity
MAX_ETH_FUNDING=0.1 # Cap ETH exposure
MAX_REIMBURSEMENT=500 # Cap token reimbursement
# Disable if you don't want to provide liquidity
ENABLE_FUNDING=false # Only resolve simple actions
Profitability Calculation
The resolver checks profitability before executing:
Profit = resolver_fee - gas_cost
If Profit > MIN_PROFIT:
→ Execute action
Else:
→ Skip (let other resolvers handle it)
Example
Resolver fee: $0.15 equivalent
Gas cost: 0.002 ETH (~$5)
Profit = 0.15 - 5 = -$4.85 (unprofitable)
→ Skip (unprofitable)
With higher fee:
Resolver fee: $6 equivalent
Gas cost: 0.002 ETH (~$5)
Profit = 6 - 5 = $1
→ Execute!
Monitoring
Health Check
# Check process status
pm2 status pons-resolver
# View logs
pm2 logs pons-resolver --lines 100
Key Metrics
| Metric | Healthy | Action if Unhealthy |
|---|---|---|
| Actions executed/hour | >0 | Check for indexed messages |
| Success rate | >95% | Check gas, review errors |
| Wallet balance | >0.05 ETH | Refill wallet |
| Profit per action | >$0 | Increase MIN_RESOLVER_FEE |
Log Messages
✅ Good:
[INFO] Resolver started
[INFO] Found pending action for Smart Account 0xabc...
[INFO] Action executed successfully, earned resolver fee
⚠️ Warning:
[WARN] Skipping unprofitable action: fee 0.05 < gas 0.1
[WARN] Low wallet balance: 0.04 ETH
❌ Error:
[ERROR] Action execution failed: revert
[ERROR] Insufficient gas for execution
Troubleshooting
"Action execution failed"
# Check the specific error in logs
# Common causes:
# - Slippage too high (for swaps)
# - Deadline expired
# - Contract reverted
# Review transaction on block explorer
cast call --trace <tx_hash> --rpc-url $DESTINATION_RPC_URL
"Unprofitable - skipping"
- This is normal behavior
- Means fee is less than gas cost
- User set fees too low
- Let other resolvers handle or wait for fee market adjustment
"Already executed"
- Another resolver processed this action first
- Normal competition behavior
- Increase uptime to catch more
"Funding exceeds limit"
# Action requires more ETH than your MAX_ETH_FUNDING
# Either:
# 1. Increase MAX_ETH_FUNDING (requires more capital)
# 2. Skip these actions (current behavior)
Profitability
Costs
| Item | Estimated Cost |
|---|---|
| Gas per execution | ~0.002 ETH |
| Server (VPS) | ~$10-50/month |
| Capital (optional) | Variable |
Revenue
| Volume | Monthly Transactions | Earnings Potential |
|---|---|---|
| Low | ~3,000/month | Covers server + gas |
| Medium | ~15,000/month | Profitable |
| High | ~30,000/month | Strong returns |
Combined (Indexer + Resolver)
Running both roles maximizes earnings per transaction. Actual returns depend on fee rates and network volume.
Best Practices
Wallet Management
- Use dedicated wallets
- Separate operational wallet from profit storage
- Set up balance alerts
- Regularly withdraw earnings
Risk Management
- Start with small MAX_ETH_FUNDING
- Monitor profit margins
- Don't over-extend capital
- Keep emergency ETH reserve
Competition
- Higher uptime = more opportunities
- Faster execution = win more races
- Better RPC = faster detection
- Consider running multiple instances
Next Steps
- Security Guide: Production security best practices
- Operators Overview: Economics and architecture