一键导入
uniswap-v4-lp
Manage Uniswap V4 LP positions on Base. Add, remove, monitor, auto-compound, and harvest fees — including Clanker protocol fee claims.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Manage Uniswap V4 LP positions on Base. Add, remove, monitor, auto-compound, and harvest fees — including Clanker protocol fee claims.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Encode EVM function calls and constructor args from signature + values. Zero deps.
Find Uniswap V2/V3 liquidity pools for any token on Base or Ethereum — reserves, pricing, TVL
Inspect Uniswap Permit2 sub-approvals for any wallet on Base or Ethereum
Resolve EVM function selectors (4-byte) and event topic hashes to human-readable signatures. Queries openchain.xyz + 4byte.directory with a built-in fallback DB of 50+ common signatures. Batch mode, bytecode scanning, stdin pipe. Zero dependencies.
Resolve Basenames (.base.eth) to addresses and back on Base
Turn raw EVM revert data into a readable error. Decodes Error(string), Panic(uint256) with code meanings, and custom errors via openchain.xyz selector lookup. Zero dependencies. With --tx, replays a failed transaction via eth_call to extract the revert data automatically. Use when an agent's tx reverted and the only signal is an opaque 0x… blob.
| name | uniswap-v4-lp |
| description | Manage Uniswap V4 LP positions on Base. Add, remove, monitor, auto-compound, and harvest fees — including Clanker protocol fee claims. |
| triggers | ["uniswap","v4","liquidity","LP position","add liquidity","remove liquidity","clanker","harvest","compound","claim fees"] |
| version | 0.2.0 |
| author | Axiom (@AxiomBot) |
| license | MIT |
| chain | base |
Manage concentrated liquidity positions on Uniswap V4 (Base chain).
PRIVATE_KEY or NET_PRIVATE_KEY)# Install dependencies
cd scripts && npm install
# Add liquidity ($20 test position)
node add-liquidity.mjs --amount 20 --range 25
# Check position
node check-position.mjs --token-id <ID>
# Monitor if in range
node monitor-position.mjs --token-id <ID>
# Collect fees (without removing liquidity)
node collect-fees.mjs --token-id <ID>
# Auto-compound fees → liquidity
# Two strategies: DOLLAR (default) or TIME
# Dollar strategy: compound when fees exceed $5 (default)
node auto-compound.mjs --token-id <ID>
node auto-compound.mjs --token-id <ID> --min-usd 20 # custom threshold
# Time strategy: compound on schedule (skip only if fees < gas)
node auto-compound.mjs --token-id <ID> --strategy time
# Loop mode: run continuously
node auto-compound.mjs --token-id <ID> --strategy dollar --loop --interval 3600 --min-usd 50
node auto-compound.mjs --token-id <ID> --strategy time --loop --interval 14400
# Preview
node auto-compound.mjs --token-id <ID> --dry-run
# Compound & Harvest: split fees — compound some, harvest rest as USDC
node compound-and-harvest.mjs --token-id <ID> \
--harvest-address 0xYOUR_ADDRESS --compound-pct 50
node compound-and-harvest.mjs --token-id <ID> \
--harvest-address 0xYOUR_ADDRESS --compound-pct 70 --slippage 3
node compound-and-harvest.mjs --token-id <ID> \
--harvest-address 0xYOUR_ADDRESS --dry-run
# Remove liquidity (partial)
node remove-liquidity.mjs --token-id <ID> --percent 50
# Burn position (100% removal + burn NFT)
node burn-position.mjs --token-id <ID>
# Rebalance (remove + re-add at current price)
node rebalance.mjs --token-id <ID> --range 25
| Contract | Address |
|---|---|
| PoolManager | 0x498581ff718922c3f8e6a244956af099b2652b2b |
| PositionManager | 0x7c5f5a4bbd8fd63184577525326123b519429bdc |
| StateView | 0xa3c0c9b65bad0b08107aa264b0f3db444b867a71 |
| Permit2 | 0x000000000022D473030F116dDEE9F6B43aC78BA3 |
const AXIOM_WETH_POOL = {
poolId: '0x10a0b8eba9d4e0f772c8c47968ee819bb4609ef4454409157961570cdce9a735',
token0: '0x4200000000000000000000000000000000000006', // WETH
token1: '0xf3Ce5dDAAb6C133F9875a4a46C55cf0b58111B07', // AXIOM
fee: 0x800000, // ⚠️ DYNAMIC_FEE_FLAG - Clanker hook controls fee
tickSpacing: 200,
hooks: '0xb429d62f8f3bffb98cdb9569533ea23bf0ba28cc' // Clanker hook
};
Many V4 pools (especially Clanker-deployed) use dynamic fees. The fee in PoolKey is 0x800000 (bit 23 = DYNAMIC_FEE_FLAG), NOT a percentage.
How to verify:
// Hash your PoolKey and compare to known poolId
const poolId = keccak256(abi.encode(currency0, currency1, fee, tickSpacing, hooks));
If your hash doesn't match, check if the pool uses 0x800000 as fee.
--strategy dollar, default)Accumulate fees in wallet, only compound when they hit a USD threshold. Best for: low-volume pools, expensive chains, or patient LPs.
# Compound when fees reach $50
node auto-compound.mjs --token-id <ID> --strategy dollar --loop --interval 3600 --min-usd 50
| Flag | Default | Description |
|---|---|---|
--min-usd | 5 | Min USD fee value to trigger compound |
--min-gas-multiple | 3 | Fees must be ≥ Nx gas cost |
--interval | 3600 | Seconds between checks in loop mode |
--strategy time)Compound on a fixed schedule. Skips only if fees < gas cost. Best for: high-volume pools where fees accumulate quickly.
# Compound every 4 hours
node auto-compound.mjs --token-id <ID> --strategy time --loop --interval 14400
| Flag | Default | Description |
|---|---|---|
--min-gas-multiple | 3 | Fees must be ≥ Nx gas cost (safety floor) |
--interval | 3600 | Seconds between compounds in loop mode |
| Pool Volume | Strategy | Interval | Min USD |
|---|---|---|---|
| >$1M/day | time | 4-6h | n/a |
| $100K-$1M/day | dollar | 1h | $10-25 |
| <$100K/day | dollar | 4h | $50+ |
Both strategies always enforce a gas floor — you'll never burn money on gas.
Split LP fees: compound a percentage back into the position and harvest the rest as USDC.
# Preview (dry run)
node compound-and-harvest.mjs --token-id 1078751 \
--harvest-address 0xcbC7E8A39A0Ec84d6B0e8e0dd98655F348ECD44F --dry-run
# 50/50 split (default)
node compound-and-harvest.mjs --token-id 1078751 \
--harvest-address 0xcbC7E8A39A0Ec84d6B0e8e0dd98655F348ECD44F
# 70% compound, 30% harvest
node compound-and-harvest.mjs --token-id 1078751 \
--harvest-address 0xcbC7E8A39A0Ec84d6B0e8e0dd98655F348ECD44F \
--compound-pct 70
# 100% harvest (take all fees as USDC, no compounding)
node compound-and-harvest.mjs --token-id 1078751 \
--harvest-address 0xcbC7E8A39A0Ec84d6B0e8e0dd98655F348ECD44F \
--compound-pct 0
# Custom slippage
node compound-and-harvest.mjs --token-id 1078751 \
--harvest-address 0xcbC7E8A39A0Ec84d6B0e8e0dd98655F348ECD44F \
--slippage 3
| Flag | Default | Description |
|---|---|---|
--token-id | required | LP NFT token ID |
--harvest-address | required | Address to receive harvested USDC |
--compound-pct | 50 | Percentage to compound (0-100) |
--slippage | 1 | Slippage tolerance for swaps (%) |
--dry-run | false | Preview without executing |
--rpc | env/default | Base RPC URL |
0x2626664c2603336E57B271c5C0b26F421741e481)exactInputSingle with 500 (0.05%) fee tierexactInput multi-hop through WETH, auto-tries fee tiers 10000/3000/500The killer feature: a complete fee management pipeline for any Clanker-launched token.
Clanker tokens have two fee sources:
clanker-harvest.mjs handles both in a single modular pipeline.
# Just claim Clanker protocol fees (no LP, no swap)
node clanker-harvest.mjs --token 0xTOKEN
# Claim + compound 100% into LP
node clanker-harvest.mjs --token 0xTOKEN --token-id 12345 --compound-pct 100
# Claim + harvest 100% as USDC to vault
node clanker-harvest.mjs --token 0xTOKEN --harvest-address 0xVAULT --compound-pct 0
# 50/50 split — compound half, harvest half
node clanker-harvest.mjs --token 0xTOKEN --token-id 12345 \
--harvest-address 0xVAULT --compound-pct 50
# 80% compound / 20% harvest, only if fees > $10
node clanker-harvest.mjs --token 0xTOKEN --token-id 12345 \
--harvest-address 0xVAULT --compound-pct 80 --min-usd 10
# Use a config file (perfect for cron)
node clanker-harvest.mjs --config harvest-config.json
| Step | What | When |
|---|---|---|
| 1. Claim | Claim WETH + token from Clanker fee contract | Always (unless --skip-claim) |
| 2. Collect LP | Collect accrued fees from V4 position | If --token-id set (unless --skip-lp) |
| 3. Threshold | Check total USD value against --min-usd | If threshold set |
| 4. Compound | Add X% back into LP position | If --compound-pct > 0 and --token-id set |
| 5. Swap | Swap remaining WETH to USDC | If --compound-pct < 100 and --harvest-address set |
| 6. Transfer | Send USDC to vault address | If USDC was swapped |
| Flag | Default | Description |
|---|---|---|
--token | required | Clanker token address |
--token-id | optional | V4 LP position NFT ID (needed for compound/LP) |
--harvest-address | optional | Vault address for USDC (needed for harvest) |
--compound-pct | 100 | % to compound back (0 = all harvest, 100 = all compound) |
--min-usd | 0 | Min USD fee value to act (0 = always) |
--slippage | 1 | Swap slippage % |
--fee-contract | 0xf362... | Clanker fee storage contract |
--skip-claim | false | Skip Clanker fee claim |
--skip-lp | false | Skip LP fee collection |
--config | optional | JSON config file path |
--dry-run | false | Simulate without executing |
For cron jobs, use a JSON config:
{
"token": "0xYOUR_TOKEN",
"tokenId": "12345",
"harvestAddress": "0xYOUR_VAULT",
"compoundPct": 50,
"minUsd": 10,
"slippage": 1
}
| Function | Description |
|---|---|
claim(feeOwner, token) | Claim fees for a specific token |
availableFees(feeOwner, token) | Check pending fee balance |
Contract: 0xf3622742b1e446d92e45e22923ef11c2fcd55d68
Two separate claims needed (WETH + token) — the script handles both automatically.
For simpler use cases, claim-clanker-fees.mjs just claims without any LP operations:
# Check available fees (dry run)
node claim-clanker-fees.mjs --token 0xTOKEN --dry-run
# Claim both WETH and token fees
node claim-clanker-fees.mjs --token 0xTOKEN
The core idea: agents launched on Clanker can fund their own infrastructure from LP yield.
LP Fees + Clanker Fees
↓
┌────┴────┐
│ │
Compound Harvest
(grow LP) (→ USDC → pay for LLM, RPC, hosting)
Set up a cron job with --min-usd threshold and the agent only acts when it's profitable to do so.
Monitor your positions and get alerted when price moves near or out of range.
# Check single position
node lp-range-alert.mjs --positions 1078751
# Check multiple positions
node lp-range-alert.mjs --positions 1078751,1078720,1078695
# Dry run (check without saving state)
node lp-range-alert.mjs --positions 1078751 --dry-run
# JSON output (for cron/automation)
node lp-range-alert.mjs --positions 1078751 --json
# Custom alert threshold (alert at 20% from edge instead of 15%)
node lp-range-alert.mjs --positions 1078751 --near-edge-pct 20
# Force alert even if status unchanged
node lp-range-alert.mjs --positions 1078751 --force
For cron jobs, use a JSON config (lp-alert-config.example.json):
{
"positions": ["1078751", "1078720", "1078695"],
"telegramChat": "YOUR_CHAT_ID",
"nearEdgePercent": 15,
"rpcUrl": "https://mainnet.base.org"
}
Run with: node lp-range-alert.mjs --config lp-alert-config.json
| Status | Meaning | Action |
|---|---|---|
OK | In range, healthy | None needed |
NEAR_LOWER_EDGE | Within 15% of lower bound | Monitor, prepare to rebalance down |
NEAR_UPPER_EDGE | Within 15% of upper bound | Monitor, prepare to rebalance up |
OUT_OF_RANGE | Price outside position range | Rebalance immediately (not earning fees!) |
State is saved to ~/.lp-alert-state.json to prevent duplicate alerts.
--force to alert regardless of previous state| Flag | Default | Description |
|---|---|---|
--positions | required | Comma-separated token IDs |
--config | optional | JSON config file path |
--telegram-chat | optional | Chat ID for Telegram alerts |
--near-edge-pct | 15 | Alert threshold (% from edge) |
--dry-run | false | Check without saving state |
--json | false | JSON output |
--force | false | Alert even if status unchanged |
--rpc | env/default | Custom RPC URL |
# Check every 30 minutes
*/30 * * * * cd /path/to/scripts && node lp-range-alert.mjs --config lp-alert-config.json >> /tmp/lp-alerts.log 2>&1
For ~$20-1000 positions: