CRITICAL COMMUNICATION RULES:
- 1. Language: Always respond in the SAME language as the user's question. If in English, respond in English.
- Data Loading: BEFORE executing any operations, FIRST request and load ALL required data from user or configuration files. Use OpenClaw's memory/session storage to save loaded data so you don't need to ask again.
- Telegram Integration:
- Send detailed reports to Telegram after each trading cycle
- If Telegram bot connection is not established, request user to start conversation with bot first
- Include position status, P&L, new opportunities found, trades executed
- 4. Initial Setup: When first invoked, ask user for:
- MMIND
TOKENADDRESS (or load from .env)
- MONAD
PRIVATEKEY (or load from .env)
- MONAD
RPCURL (or load from .env)
- MONAD_NETWORK (or load from .env)
- Telegram user ID for notifications
Save all this data in OpenClaw memory for future use.
- 5. Missing variables: If
.env is missing or any required variable (MONADPRIVATEKEY, MONADRPCURL, MMINDTOKENADDRESS, MONAD_NETWORK) is not set, ask the user to provide it before running trading or scripts. Do not proceed with buy/sell or execute-bonding-v2 until config is complete.
Nad.fun Autonomous Trading Agent
Autonomous trading agent that scans Nad.fun markets, analyzes tokens using momentum strategies, executes trades, and distributes profits to MMIND token holders.
Prerequisites
- -
monad-development skill installed (for wallet and RPC setup) - INLINECODE2 skill installed (for buy/sell operations), or use the
trading/ folder from this repo - INLINECODE4 skill installed (for querying events)
- INLINECODE5 skill installed (for market data)
- Network configured (mainnet only for this skill)
- MMIND token address configured
Paths (clean install): Config is read from NADFUN_ENV_PATH if set, else $HOME/nadfunagent/.env. Positions report: POSITIONS_REPORT_PATH or $HOME/nadfunagent/positions_report.json. Scripts from nadfun-trading may be at ~/.openclaw/workspace/skills/nadfun-trading or at <this-repo>/trading. See DEPENDENCIES.md.
Configuration
CRITICAL: Load environment variables from .env file (default path: $HOME/nadfunagent/.env; override with NADFUN_ENV_PATH):
- -
MMIND_TOKEN_ADDRESS: Address of MMIND token for profit distribution (required) - INLINECODE18 : Private key for trading wallet (required)
- INLINECODE19 : RPC endpoint URL (required)
- INLINECODE20 : Network type - "mainnet" or "testnet" (required)
- INLINECODE21 : Maximum position size in MON (default: 0.1)
- INLINECODE22 : Take-profit threshold (default: 20%)
- INLINECODE23 : Stop-loss threshold (default: 10%)
- INLINECODE24 : % of profit to distribute (default: 30%)
Before starting trading cycle:
- 1. Read
.env file (path: NADFUN_ENV_PATH or $HOME/nadfunagent/.env). If the file is missing or any required variable is empty, ask the user to provide MMINDTOKENADDRESS, MONADPRIVATEKEY, MONADRPCURL, MONAD_NETWORK — do not run trading until config is complete. - Load
MMIND_TOKEN_ADDRESS - use this for profit distribution - Load
MONAD_PRIVATE_KEY - use this for wallet operations - Load
MONAD_RPC_URL - use this for blockchain queries - Load
MONAD_NETWORK - determines API endpoints (mainnet: api.nadapp.net, testnet: dev-api.nad.fun)
Workflow
EXECUTION SUMMARY - READ THIS FIRST:
- 1. Load config from
$HOME/nadfunagent/.env (MMINDTOKENADDRESS, MONADPRIVATEKEY, MONADRPCURL, MONAD_NETWORK) - Execute ONLY 3 methods (from HAR file analysis): Method 5 (New Events API), Method 6 (Market Cap API), Method 7 (Creation Time API)
- Combine results - merge all token addresses from 3 methods, count frequency (how many methods found each token, max 3)
- Prioritize - sort tokens by frequency (tokens found in 2-3 methods = higher priority)
- Save tokens - save ALL found tokens (up to top 50 for storage) to
$HOME/nadfunagent/found_tokens.json for manual review - Analyze - get token info, market data, metrics via Agent API, calculate scores
- Filter - keep only tokens with min liquidity 5 MON, min holders 5
- Trade - execute trades if score >= 60
- Distribute - distribute profits to MMIND holders if profit >= 0.1 MON
1. Market Scanning (NEW + TRENDING)
CRITICAL INSTRUCTIONS: You MUST scan tokens using ALL 7 methods below. Execute each method step-by-step and collect ALL found token addresses.
EXECUTION ORDER:
- 1. Method 1: CurveCreate events (Indexer) - NEW tokens
- Method 2: CurveBuy events (Indexer) - TRENDING by volume
- Method 3: Swap History (Agent API) - TRENDING by 24h volume
- Method 4: Holdings (Agent API) - ACTIVE tokens from large traders
- Method 5: New Events API - REAL-TIME BUY/CREATE events
- Method 6: Market Cap API - TOP tokens by capitalization
- Method 7: Creation Time API - NEWEST tokens
STEP-BY-STEP EXECUTION:
CRITICAL LOGGING REQUIREMENT:
After executing EACH method, you MUST log:
- 1. Print: "✅ Method X executed: Found N tokens"
- Print: "Method X token addresses: ..."
- If method failed: Print: "❌ Method X failed: "
- This helps track which methods are working and debug issues
NOTE: Only Methods 5, 6, and 7 are used (from HAR file analysis). Methods 1-4 are disabled.
STATUS CHECK: This method requires RPC access. You MUST execute it, don't skip it!
What to do:
- 1. Read
$HOME/nadfunagent/.env to get MONAD_RPC_URL and INLINECODE36 - Get current block number using RPC: INLINECODE37
- Calculate:
safeLatest = currentBlock - 10 (safety margin) - Scan last 900 blocks in chunks of 100 blocks (RPC limit)
- For each chunk, query CurveCreate events using
nadfun-indexer skill
How to execute:
- - Use
nadfun-indexer skill with parameters: event=CurveCreate, fromBlock=<start>, INLINECODE43 - Extract token addresses from events:
event.args.token or event.args[1] (token is second argument) - Collect all unique token addresses
Example command structure:
CODEBLOCK0
Expected result: Array of token addresses (0x...) from newly created tokens
Method 2: Trending Tokens via Indexer (CurveBuy volume analysis)
STATUS CHECK: This method requires RPC access. You MUST execute it, don't skip it!
What to do:
- 1. Query CurveBuy events from last 900 blocks (same pagination as Method 1)
- For each event, extract: token address and amountIn (MON spent)
- Sum volume per token address
- Sort tokens by total volume (descending)
- Take top 20 tokens with highest volume
How to execute:
- 1. Use same RPC setup as Method 1: Get publicClient from monad-development skill
- Query CurveBuy events: For each 100-block chunk:
- Use
nadfun-indexer skill:
event=CurveBuy,
fromBlock=<start>,
toBlock=<end>
- OR use viem:
publicClient.getContractEvents({ address: CURVE_ADDRESS, eventName: "CurveBuy", fromBlock, toBlock })
- 3. Extract data: From each event:
-
token = event.args.token or
event.args[1]
-
amountIn = event.args.amountIn or
event.args[2] (amount in MON)
- 4. Calculate volume: Group by token address, sum all amountIn values
- Sort and filter: Sort by total volume DESC, take top 20
- Log results: Print "✅ Method 2: Found top 20 trending tokens by volume"
Example:
CODEBLOCK1
Expected result: Top 20 token addresses sorted by trading volume
Method 3: Trending Tokens via Agent API (Swap History Analysis)
What to do:
- 1. Take top 10 tokens from Method 2 (highest volume)
- For each token, query swap history via Agent API
- Calculate 24h volume from swap history
- Keep tokens with >= 1 MON volume in last 24 hours
How to execute:
- - Determine API URL: if
MONAD_NETWORK=mainnet then https://api.nadapp.net, else INLINECODE57 - For each token, make GET request: INLINECODE58
- Parse response JSON
- For each swap in
response.swaps:
- Check
swap.swap_info.timestamp - if within last 24 hours
- Sum
swap.swap_info.native_amount (in wei, convert to MON: divide by 1e18)
- - Keep tokens with total 24h volume >= 1 MON
- Add 1-2 second delay between API calls to avoid rate limits
Example:
CODEBLOCK2
Expected result: List of tokens with high 24h trading volume
Method 4: Get All Active Tokens (via Holdings of Large Accounts)
STATUS CHECK: Don't skip this method! Execute it with rate limit delays.
What to do:
- 1. From Method 2 CurveBuy events, find buyers who spent >1 MON
- Extract their addresses (sender field)
- Query holdings for first 5 large buyers (to avoid rate limits)
- Extract all token addresses they hold (balance > 0)
How to execute:
- 1. From Method 2 results: Use CurveBuy events already queried
- Filter large buyers:
- Filter events where
amountIn > 1000000000000000000 (1 MON in wei = 1e18)
- Extract
sender address:
event.args.sender or
event.args[0]
- Get unique addresses, take first 5
- 3. Query holdings: For each of 5 addresses:
- GET:
${API_URL}/agent/holdings/${address}?limit=50
- Headers:
Accept: application/json
- Wait 2 seconds between requests
- 4. Parse and extract:
- Parse JSON response
- For each
holding in
response.tokens:
- Check
holding.balance_info.balance - if > 0
- Extract
holding.token_info.address or
holding.token_info.token_id
- 5. Log results: Print "✅ Method 4: Found N active tokens from large trader holdings"
Example:
CODEBLOCK3
Expected result: Set of token addresses held by active large traders
Method 5: New Events API (Real-time BUY/SELL/CREATE events)
STATUS: ✅ This method is WORKING! Found 7 tokens in last scan.
What to do:
- 1. Make GET request to
/api/token/new-event endpoint - Parse JSON response (array of events)
- Extract token addresses from CREATE and BUY events
- Add all unique token addresses to collection
How to execute:
- 1. Determine base URL: Read MONAD_NETWORK from .env:
- If
MONAD_NETWORK=mainnet:
baseUrl = 'https://nad.fun'
- Else:
baseUrl = 'https://dev.nad.fun'
- 2. Make GET request:
- URL:
${baseUrl}/api/token/new-event
- Headers:
Accept: application/json,
User-Agent: OpenClaw-Agent/1.0
- 3. Parse response: JSON array of event objects
- Extract tokens:
- For each event in response:
- If
event.type === 'CREATE': extract
event.token_info.token_id
- If
event.type === 'BUY': extract
event.token_info.token_id
- If
event.type === 'SELL': optionally extract (indicates active trading)
- 5. Log results: Print "✅ Method 5: Found N tokens from new events API"
Example:
CODEBLOCK4
Expected result: Array of token addresses from recent CREATE and BUY events
Response structure:
- -
type: "BUY" | "SELL" | "CREATE" - INLINECODE86 : Event amount (string)
- INLINECODE87 : Complete token information (token_id, name, symbol, description, creator, etc.)
- INLINECODE88 : Account that performed the action
Method 6: Market Cap API (Top tokens by market cap)
STATUS CHECK: Previous error: base64 decoding failed. Fix: Use proper decoding method.
What to do:
- 1. GET request to market cap endpoint
- Response is base64-encoded JSON - decode it PROPERLY
- Extract token addresses from response
- Add all token addresses to collection
How to execute:
- 1. API URL: INLINECODE89
- Where
API_URL = MONAD_NETWORK === 'mainnet' ? 'https://api.nadapp.net' : 'https://dev-api.nad.fun'
- 2. GET request:
- Headers:
Accept: application/json,
User-Agent: OpenClaw-Agent/1.0
- Get response as text (not JSON)
- 3. Decode base64 PROPERLY:
- Response body is base64 string
- Use Python:
import base64; decoded = base64.b64decode(response_text).decode('utf-8')
- OR use command:
echo "$response_text" | base64 -d
- CRITICAL: Make sure response_text is the raw base64 string, not wrapped in JSON
- 4. Parse decoded JSON:
- Parse decoded string as JSON
- Structure:
{ "tokens": [...], "total_count": N }
- 5. Extract tokens WITH FULL DATA:
- For each token in
data.tokens:
- Extract
token.token_info.token_id (token address)
-
CRITICAL: Store FULL token object with both
token_info AND
market_info
- Structure:
{token_info: {...}, market_info: {...}, percent: ...}
- Add to topMarketCapTokens array (store full objects, not just addresses)
- 6. Log results: Print "✅ Method 6: Found N tokens with market data from market cap API"
Example:
CODEBLOCK5
Expected result: Array of full token objects (with tokeninfo + marketinfo) sorted by market cap
Response structure:
- -
tokens: Array of token objects with token_info and INLINECODE103 - INLINECODE104 : Total number of tokens
- Each token includes:
token_info (tokenid, name, symbol, creator, etc.) and market_info (markettype, price, volume, holder_count, etc.)
Method 7: Creation Time API (Newest tokens)
CRITICAL: Include BOTH bonding curve AND DEX tokens! Do NOT filter by is_graduated.
What to do:
- 1. GET request to creation time endpoint (newest first)
- Decode base64 response PROPERLY (same as Method 6)
- Extract token addresses - include ALL tokens (both bonding curve AND DEX)
- Add to collection WITH FULL DATA
How to execute:
- - API URL: INLINECODE107
- GET request, decode base64 response (same as Method 6)
- Parse JSON:
data.tokens array - For each token:
- Extract
token.token_info.token_id (token address)
-
CRITICAL: Store FULL token object with both
token_info AND
market_info
-
DO NOT filter by isgraduated - include both bonding curve (isgraduated=false) AND DEX (is_graduated=true) tokens
- Add to newestTokens array (store full objects, not just addresses)
Example:
CODEBLOCK6
Expected result: Array of full token objects (with tokeninfo + marketinfo) - newest tokens including both bonding curve AND DEX
Response structure:
- - Same as Method 6:
tokens array with token_info and INLINECODE114 - INLINECODE115 returns newest first
- CRITICAL: Include ALL tokens (both bonding curve AND DEX) - do NOT filter by is_graduated
Combine All Methods - CRITICAL STEP
What to do:
- 1. Collect ALL token addresses from Methods 5, 6, and 7 into one set (removes duplicates)
- Count how many times each token appears across methods
- Sort tokens by frequency (tokens found in more methods = higher priority/confidence)
- Log summary of combination results
How to execute:
- 1. Create collections:
-
allTokens = new Set() or
allTokens = [] (use Set to avoid duplicates)
-
tokenFrequency = new Map() or
{} to count occurrences
- 2. Add tokens from each method:
- Method 5: Add all token addresses from tokensFromEvents (New Events API) - these are just addresses
- Method 6: Add all tokens from topMarketCapTokens (Market Cap API) - these are FULL objects with token
info + marketinfo
- Method 7: Add all tokens from newestTokens (Creation Time API) - these are FULL objects with token
info + marketinfo
IMPORTANT: For Methods 6 & 7, store the FULL token objects (not just addresses) so you can use market_info directly for analysis!
- 3. Count frequency and preserve full data:
- Use a Map/object:
allTokensMap = {} where key = token address, value = token object with metadata
- For Method 5 (addresses only):
allTokensMap[address] = {address, source: 'method5', data: null}
- For Method 6 (full objects):
allTokensMap[address] = {address, source: 'method6', data: fullTokenObject}
- For Method 7 (full objects):
allTokensMap[address] = {address, source: 'method7', data: fullTokenObject}
- Count frequency:
tokenFrequency[address] = (tokenFrequency[address] || 0) + 1
-
CRITICAL: Preserve full token objects from Methods 6 & 7 - they contain market_info!
- 4. Convert and sort:
-
candidateTokens = Object.values(allTokensMap) or
Array.from(allTokensMap.values())
- Sort by frequency DESC, then by data availability:
candidateTokens.sort((a, b) => {
const freqA = tokenFrequency[a.address] || 0
const freqB = tokenFrequency[b.address] || 0
if (freqB !== freqA) return freqB - freqA // Higher frequency first
// Prefer tokens with full data (market_info)
const hasDataA = a.data && a.data.market_info ? 1 : 0
const hasDataB = b.data && b.data.market_info ? 1 : 0
return hasDataB - hasDataA
})
- INLINECODE127
- 5. Log summary:
- Print: "📊 Combined results: Total unique tokens: N"
- Print: "Tokens found in 2+ methods: X"
- Print: "Tokens found in all 3 methods: Y"
- Print: "Tokens with full market data: Z"
- Print: "Top 10 prioritized tokens:
"
Example:
CODEBLOCK8
Expected result: Prioritized array of token objects, each containing:
- -
address: token address - INLINECODE129 : which method(s) found it
- INLINECODE130 : full token object with tokeninfo + marketinfo (if available from Methods 6 or 7)
- INLINECODE131 : count from tokenFrequency
Save Found Tokens - CRITICAL STEP
What to do:
After combining all methods and getting prioritizedTokens, you MUST save them to file $HOME/nadfunagent/found_tokens.json for manual review.
How to execute:
- 1. Prepare token list:
- Take top 50 tokens from prioritizedTokens
- For each token, create object: {address: token, foundInMethods: frequency_count}
- Create scan entry with timestamp, totalFound count, and tokens array
- 2. Read existing file:
- File: $HOME/nadfunagent/found_tokens.json
- If file doesn't exist or is empty: start with []
- If exists: parse JSON, get array
- 3. Append and save:
- Add new scan entry to array
- Keep only last 100 scans (remove oldest if > 100)
- Write back as formatted JSON
Example using Node.js script (RECOMMENDED):
# From skill root or repo root: print token addresses (one per line) and pipe to script
# prioritizedTokens is the array of token addresses; take first 50 and pass to script
echo -e "0x...\n0x..." | node scripts/save_tokens.js
Or from the agent: write the list of addresses to a temp file or stdin and run node scripts/save_tokens.js (script reads from stdin). Data dir: NADFUNAGENT_DATA_DIR or $HOME/nadfunagent.
Expected result: File $HOME/nadfunagent/found_tokens.json updated with latest scan results
2. Token Analysis - CRITICAL: Use Data from Methods 6 & 7 Directly
IMPORTANT: Methods 6 (Market Cap API) and Method 7 (Creation Time API) already return COMPLETE token data with market_info. Use this data directly for analysis - DO NOT make additional API calls unless absolutely necessary!
Data Structure from Methods 6 & 7:
Each token in the response has this structure:
CODEBLOCK10
Analysis Steps:
- 1. Extract data from Methods 6 & 7:
- For each token in data.tokens array from Methods 6 & 7:
- Extract token_info.token_id (token address)
- Extract market_info.reserve_native (liquidity in wei, convert to MON: divide by 1e18)
- Extract market_info.holder_count (number of holders)
- Extract market_info.volume (total volume in wei, convert to MON: divide by 1e18)
- Extract market_info.market_type ("DEX" or "BONDING_CURVE")
- Extract token_info.is_graduated (true if graduated to DEX)
- Extract percent (market cap change percentage)
- 2. For Method 5 tokens (new-event API):
- This API returns only basic event data without full market_info
- For tokens from Method 5, you can optionally query /agent/market/:token_id to get market_info
- BUT prioritize tokens from Methods 6 & 7 first (they already have complete data)
- 3. Calculate Liquidity Score (30% weight):
CODEBLOCK11
- 4. Calculate Momentum Score (25% weight):
CODEBLOCK12
- 5. Calculate Volume Score (20% weight):
CODEBLOCK13
- 6. Calculate Holder Score (15% weight):
CODEBLOCK14
- 7. Calculate Progress Score (10% weight):
CODEBLOCK15
- 8. Calculate Authority Score (Bonus - up to +10 points):
CODEBLOCK16
- 9. Calculate Total Score:
CODEBLOCK17
- 9. Store Analysis Results:
For each token, store:
CODEBLOCK18
CRITICAL INSTRUCTIONS:
- - Use data from Methods 6 & 7 DIRECTLY - they already contain all needed information
- DO NOT make additional API calls to
/agent/market/:token_id for tokens from Methods 6 & 7 - Only for Method 5 tokens (if needed) make additional API calls
- Calculate scores immediately after combining methods, before filtering
- Check authority (social media presence): Check
token_info.twitter, token_info.telegram, token_info.website - add bonus points - Log analysis results: Print "📊 Analysis: Token X has score Y (liquidity: A, momentum: B, volume: C, holders: D, progress: E, authority: +F)"
3. Filtering Criteria
Filter tokens based on:
- - Minimum liquidity: 5 MON
- Minimum holders: 5
- Bonding curve progress: >= 10%
- Score calculation:
- Liquidity: 30% weight
- Momentum: 25% weight
- Volume trend: 20% weight
- Holder distribution: 15% weight
- Bonding curve progress: 10% weight
4. Position Management - CRITICAL: Check Existing Positions FIRST
BEFORE analyzing new tokens, you MUST check and manage existing positions!
Step 1: Get Current Holdings
What to do:
- 1. Get trading wallet address from
MONAD_PRIVATE_KEY in .env (derive address from private key) - Query current token holdings using Agent API: INLINECODE156
- Filter tokens where
balance > 0 (exclude zero balances) - For each token with balance > 0, get current market data
How to execute:
CODEBLOCK19
Step 2: Calculate P&L for Each Position
CRITICAL: Always use the check-pnl.js script from nadfun-trading skill for proper P&L calculation. This script:
- - Reads entry price (
entryValueMON) from $HOME/nadfunagent/positions_report.json (automatically recorded by buy-token.js when you purchase) - Gets current value on-chain via nad.fun quote contract (or falls back to Agent API)
- Calculates P&L: INLINECODE163
What to do:
- 1. Use the script: Run
check-pnl.js from nadfun-trading skill directory - The script reads entry prices from JSON (set by
buy-token.js after purchases) - Gets current value on-chain via nad.fun quote contract
- Calculates real P&L based on actual entry price
How to execute:
CODEBLOCK20
Manual calculation (if script unavailable):
CODEBLOCK21
Entry Price Tracking:
- - Entry price is automatically recorded by
buy-token.js after successful purchase - Stored in
$HOME/nadfunagent/positions_report.json as INLINECODE168 - If entry price not found,
check-pnl.js uses current value as fallback (P&L = 0%)
Step 3: Make Sell Decisions
What to do:
For each position, check sell conditions:
- 1. Stop-Loss Check:
CODEBLOCK22
- 2. Take-Profit Check:
CODEBLOCK23
- 3. Trailing Stop (Optional):
CODEBLOCK24
How to execute:
CODEBLOCK25
Step 4: Execute Sell Orders
What to do:
For each sell decision:
- 1. Use
nadfun-trading skill with action INLINECODE171 - Parameters: token address, amount (from decision)
- The skill handles: balance check, quote, approve, execution
How to execute:
CODEBLOCK26
5. Trading Execution - Buy New Tokens
CRITICAL: Only buy new tokens AFTER managing existing positions!
Buy Decision Logic:
- 1. Prioritize tokens with authority (social media presence):
- Tokens with Twitter + Telegram + Website get priority
- These are more legitimate and have better community support
- 2. Consider both early-stage AND established tokens:
- Early-stage (5-50 MON liquidity): Higher risk, higher potential
- Established (50k+ MON liquidity): Lower risk, steady growth
- Both can be profitable if they meet score criteria
- 3. Buy Criteria:
- Score >= 60 (or >= 55 if has social media)
- Liquidity >= 5 MON
- Holders >= 5
- NOT already in portfolio (check existing positions first)
- 4. Position Sizing:
- For tokens with authority (social media): up to 0.15 MON
- For tokens without authority: up to 0.1 MON
- Maximum total position per token: 0.15 MON
CRITICAL: Always use the buy-token.js script from nadfun-trading skill. This script:
- - Automatically detects bonding curve vs DEX via nad.fun quote contract
- Handles DEX: wraps MON→WMON, approves, swaps
- Automatically records entry price in
$HOME/nadfunagent/positions_report.json after successful purchase - Works on bonding curve (MON) or DEX (MON) - all trading uses MON
Buy tokens:
CODEBLOCK27
Example:
CODEBLOCK28
After purchase:
- - Entry price (
entryValueMON) is automatically recorded in INLINECODE176 - This entry price is used by
check-pnl.js for P&L calculation - No manual tracking needed - everything is automated
Risk management:
- - CRITICAL: Buy tokens on BOTH bonding curve AND DEX (don't filter by markettype)
- The
nadfun-trading skill automatically detects market type and uses correct contract - For all trades, use MON balance (no wrapping needed - all trading uses MON)
- Set slippage tolerance: 2-3% (increased for better execution, especially on DEX)
- Set deadline: 5 minutes from now
- Don't exceed MAXPOSITION_SIZE per token
6. Profit Distribution
CRITICAL: Use MMIND_TOKEN_ADDRESS from $HOME/nadfunagent/.env file.
When profit >= 0.1 MON:
CODEBLOCK29
Autonomous Trading Loop
The agent runs continuously:
- 1. Position Management FIRST (CRITICAL - do this before scanning)
- Get wallet address from MONAD_PRIVATE_KEY
- Query current holdings: /agent/holdings/${walletAddress}?limit=100
- Filter tokens with balance > 0
- For each position: use check-pnl.js to get real P&L (reads entry price from $HOME/nadfunagent/positions_report.json, gets current value on-chain via nad.fun quote contract)
- Execute sell orders: use sell-token.js or check-pnl.js --auto-sell for stop-loss (P&L <= -10%) or take-profit (P&L >= +5%)
- Log: "📊 Positions: N checked, X sold; entry prices tracked in positions_report.json"
- 2. Scan market (after managing positions, every 10 minutes to avoid rate limits)
- Method 5: Fetch new events API (/api/token/new-event) for real-time BUY/CREATE events
- Method 6: Fetch top tokens by market cap (api.nadapp.net/order/market_cap, base64 decoded)
- Method 7: Fetch newest tokens (api.nadapp.net/order/creation_time, base64 decoded)
- Combine all methods and prioritize tokens found in multiple sources
- Add 2-3 second delays between API calls to respect rate limits (CRITICAL to avoid HTTP 429)
- 2. Analyze opportunities
- Use data DIRECTLY from Methods 6 & 7 (already contains complete market_info)
- Calculate scores using market_info: liquidity (30%), momentum (25%), volume (20%), holders (15%), progress (10%)
- Convert wei values to MON: reserve_native / 1e18, volume / 1e18
- Filter by criteria (min liquidity 5 MON, min holders 5, min score 60)
- Sort by score DESC, then by methods count, then by liquidity
- Take top 20 candidates
- Generate buy/sell signals
- 3. Execute trades
- Buy on bonding curve (MON) or DEX (MON) - all trading uses MON
- Monitor positions
- Stop-loss and take-profit
- 4. Distribute profits
- Calculate total profit
- Get MMIND holders via Indexer (Transfer events)
- Distribute proportionally (30% of profit) in MON
Risk Management
- - Position sizing: Based on confidence score (max 0.1 MON)
- Stop-loss: -10% (automatic sell)
- Take-profit: +20% (sell half position)
- Slippage protection: 1-2% tolerance
- Minimum liquidity: 5 MON required
Usage Examples
Start autonomous trading:
CODEBLOCK30
Check agent status:
CODEBLOCK31
View found tokens: (data dir: NADFUNAGENT_DATA_DIR, default $HOME/nadfunagent)
CODEBLOCK32
Manual trade:
CODEBLOCK33
Integration with OpenClaw
This skill integrates with:
- - Cron Jobs: Schedule autonomous trading cycles
- Skills: Uses nadfun-trading, nadfun-indexer, nadfun-agent-api
- Gateway: Runs via OpenClaw Gateway
- Channels: Can send notifications via Telegram/WhatsApp/etc.
Error Handling
- - All errors are logged but don't stop the agent
- Failed trades are retried with exponential backoff
- API failures fall back to Indexer queries
- Network errors trigger fallback RPC providers
Rate Limit Handling
CRITICAL: Handle rate limits gracefully to avoid HTTP 429 errors.
API Rate Limits
Nad.fun Agent API:
- - Without API Key: 10 requests/minute (IP-based)
- With API Key: 100 requests/minute (Key-based)
- Solution: Add delays between requests (min 2 seconds between calls)
Nad.fun Public APIs (nad.fun/api/* and api.nadapp.net/*):
- - Rate limits are not publicly documented but appear to be IP-based
- Solution: Add 2-3 second delays between calls, especially for base64-decoded endpoints
- Handle HTTP 429 errors gracefully with exponential backoff
Anthropic/Claude API (CRITICAL - This is the main source of HTTP 429):
- - Rate limits vary by tier (typically 50-200 requests per minute)
- Problem: Each agent execution makes multiple requests to Claude
- Solution:
- Cron job runs every 10 minutes (*/10 * * * *) to reduce frequency
- Optimize agent logic to minimize token usage
- Batch operations when possible
- If still hitting limits, increase to 15 minutes (*/15 * * * *)
Rate Limit Strategy
- 1. Add delays between API calls (CRITICAL):
CODEBLOCK34
- 2. Limit parallel requests:
- Process tokens sequentially or in small batches (max 5 at a time)
- Add delays between batches
- Don't make all 7 methods run simultaneously - stagger them
- 3. Handle 429 errors gracefully:
CODEBLOCK35
- 4. Optimize agent execution:
- Use Indexer methods (1-2) first (they're faster and don't hit API limits)
- Only use API methods (3-7) if Indexer doesn't find enough tokens
- Analyze ALL tokens that pass filters (no limit)
- Skip detailed analysis if token doesn't meet basic filters
- 5. Cron frequency:
- Current: every 10 minutes (*/10 * * * *)
- If still hitting Claude API limits, increase to 15 minutes (*/15 * * * *)
关键沟通规则:
- 1. 语言:始终使用与用户问题相同的语言回复。如果用户使用英文,则用英文回复。
- 数据加载:在执行任何操作之前,首先请求并从用户或配置文件中加载所有必需的数据。使用OpenClaw的内存/会话存储来保存已加载的数据,这样你就不需要再次询问。
- Telegram集成:
- 在每个交易周期后向Telegram发送详细报告
- 如果Telegram机器人连接未建立,请用户先与机器人开始对话
- 报告内容包括持仓状态、盈亏、发现的新机会、已执行的交易
- 4. 初始设置:首次调用时,向用户询问:
- MMIND
TOKENADDRESS(或从.env加载)
- MONAD
PRIVATEKEY(或从.env加载)
- MONAD
RPCURL(或从.env加载)
- MONAD_NETWORK(或从.env加载)
- 用于通知的Telegram用户ID
将所有数据保存在OpenClaw内存中供将来使用。
- 5. 缺失变量:如果 .env 文件缺失或任何必需变量(MONADPRIVATEKEY, MONADRPCURL, MMINDTOKENADDRESS, MONAD_NETWORK)未设置,请用户提供后再运行交易或脚本。在配置完成之前,不要进行买入/卖出或执行 execute-bonding-v2。
Nad.fun 自主交易代理
自主交易代理,扫描Nad.fun市场,使用动量策略分析代币,执行交易,并将利润分配给MMIND代币持有者。
前提条件
- - 已安装 monad-development 技能(用于钱包和RPC设置)
- 已安装 nadfun-trading 技能(用于买入/卖出操作),或使用本仓库的 trading/ 文件夹
- 已安装 nadfun-indexer 技能(用于查询事件)
- 已安装 nadfun-agent-api 技能(用于获取市场数据)
- 网络已配置(此技能仅限主网)
- MMIND代币地址已配置
路径(全新安装): 如果设置了 NADFUNENVPATH,则从中读取配置,否则从 $HOME/nadfunagent/.env 读取。持仓报告:POSITIONSREPORTPATH 或 $HOME/nadfunagent/positions_report.json。来自 nadfun-trading 的脚本可能位于 ~/.openclaw/workspace/skills/nadfun-trading 或 <此仓库>/trading。参见 DEPENDENCIES.md。
配置
关键:从 .env 文件加载环境变量(默认路径:$HOME/nadfunagent/.env;可通过 NADFUNENVPATH 覆盖):
- - MMINDTOKENADDRESS:用于利润分配的MMIND代币地址(必需)
- MONADPRIVATEKEY:交易钱包的私钥(必需)
- MONADRPCURL:RPC端点URL(必需)
- MONADNETWORK:网络类型 - mainnet 或 testnet(必需)
- MAXPOSITIONSIZE:最大持仓规模(以MON计,默认:0.1)
- PROFITTARGETPERCENT:止盈阈值(默认:20%)
- STOPLOSSPERCENT:止损阈值(默认:10%)
- PNLDISTRIBUTION_PERCENT:利润分配百分比(默认:30%)
在开始交易周期之前:
- 1. 读取 .env 文件(路径:NADFUNENVPATH 或 $HOME/nadfunagent/.env)。如果文件缺失或任何必需变量为空,请用户提供 MMINDTOKENADDRESS、MONADPRIVATEKEY、MONADRPCURL、MONADNETWORK — 在配置完成之前不要运行交易。
- 加载 MMINDTOKENADDRESS - 用于利润分配
- 加载 MONADPRIVATEKEY - 用于钱包操作
- 加载 MONADRPCURL - 用于区块链查询
- 加载 MONADNETWORK - 决定API端点(主网:api.nadapp.net,测试网:dev-api.nad.fun)
工作流程
执行摘要 - 请先阅读:
- 1. 加载配置 从 $HOME/nadfunagent/.env(MMINDTOKENADDRESS, MONADPRIVATEKEY, MONADRPCURL, MONADNETWORK)
- 仅执行3个方法(根据HAR文件分析):方法5(新事件API),方法6(市值API),方法7(创建时间API)
- 合并结果 - 合并来自3个方法的所有代币地址,计算频率(每个代币被多少个方法发现,最多3个)
- 排序优先级 - 按频率对代币排序(在2-3个方法中发现的代币 = 更高优先级)
- 保存代币 - 将所有发现的代币(最多保存前50个)保存到 $HOME/nadfunagent/foundtokens.json 供人工审查
- 分析 - 通过Agent API获取代币信息、市场数据、指标,计算评分
- 过滤 - 仅保留最低流动性5 MON、最低持有者5人的代币
- 交易 - 如果评分 >= 60,则执行交易
- 分配 - 如果利润 >= 0.1 MON,则向MMIND持有者分配利润
1. 市场扫描(新 + 趋势)
关键指令:你必须使用以下所有7种方法扫描代币。逐步执行每种方法并收集所有发现的代币地址。
执行顺序:
- 1. 方法1:CurveCreate事件(索引器) - 新代币
- 方法2:CurveBuy事件(索引器) - 按交易量趋势
- 方法3:交换历史(Agent API) - 按24小时交易量趋势
- 方法4:持仓(Agent API) - 来自大户的活跃代币
- 方法5:新事件API - 实时买入/创建事件
- 方法6:市值API - 按市值排名前列的代币
- 方法7:创建时间API - 最新代币
逐步执行:
关键日志记录要求:
执行每种方法后,你必须记录:
- 1. 打印:✅ 方法X已执行:发现N个代币
- 打印:方法X的代币地址:<地址1> <地址2> ...
- 如果方法失败:打印:❌ 方法X失败:<错误原因>
- 这有助于跟踪哪些方法有效并进行调试
注意: 仅使用方法5、6和7(根据HAR文件分析)。方法1-4已禁用。
状态检查: 此方法需要RPC访问。你必须执行它,不要跳过!
要做什么:
- 1. 读取 $HOME/nadfunagent/.env 以获取 MONADRPCURL 和 MONADNETWORK
- 使用RPC获取当前区块号:ethblockNumber
- 计算:safeLatest = currentBlock - 10(安全边际)
- 以每100个区块为一块,扫描最后900个区块(RPC限制)
- 对于每个区块块,使用 nadfun-indexer 技能查询CurveCreate事件
如何执行:
- - 使用 nadfun-indexer 技能,参数:event=CurveCreate,fromBlock=<开始>,toBlock=<结束>
- 从事件中提取代币地址:event.args.token 或 event.args[1](代币是第二个参数)
- 收集所有唯一的代币地址
示例命令结构:
使用技能:nadfun-indexer
参数:event=CurveCreate, fromBlock=<计算出的开始>, toBlock=<计算出的结束>
提取:每个事件中的代币地址
预期结果: 来自新创建代币的代币地址数组(0x...)
方法2:通过索引器发现趋势代币(CurveBuy交易量分析)
状态检查: 此方法需要RPC访问。你必须执行它,不要跳过!
要做什么:
- 1. 查询最后900个区块的CurveBuy事件(与方法1相同的分页)
- 对于每个事件,提取:代币地址和amountIn(花费的MON)
- 按代币地址汇总交易量
- 按总交易量对代币排序(降序)
- 取交易量最高的前20个代币
如何执行:
- 1. 使用与方法1相同的RPC设置: 从monad-development技能获取publicClient
- 查询CurveBuy事件: 对于每个100区块块:
- 使用 nadfun-indexer 技能:event=Curve