Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Nadfun Token Tool

BSecurity

**The Monad token launchpad with bonding curves.** Trade tokens, launch your own, monitor events—all with pure viem.

19 stars
0 votes
0 copies
1 views
Added 9/19/2026
developmentjavascripttypescriptgojavabashapidocumentation

Works with

cliapi

Security Analysis

B80/100
mediumUses curl or wget to download content
mediumInstalls packages at runtime which could introduce malicious dependencies
mediumInstalls packages at runtime which could introduce malicious dependencies
mediumInstalls packages at runtime which could introduce malicious dependencies

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add rondoflow/rondoflow --skill nadfun-token-tool --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Nadfun Token Tool?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Nadfun Token Tool
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/rondoflow-nadfun-token-tool/badge)](https://www.skillsdirectory.com/skills/rondoflow-nadfun-token-tool)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: nadfun-token-tool
description: "**The Monad token launchpad with bonding curves.** Trade tokens, launch your own, monitor events—all with pure viem."
category: "Finance & Crypto"
author: community
version: "1.0.0"
icon: coins
---

# SKILL.md - NadFun Integration Guide

**The Monad token launchpad with bonding curves.** Trade tokens, launch your own, monitor events—all with pure viem.

## What is NadFun?

NadFun is a decentralized token launchpad on the Monad blockchain. Key features:

- **Bonding Curve Trading**: Tokens start on a bonding curve. Price increases as more people buy.
- **Graduation**: When curve reaches target reserves, token graduates to DEX (Uniswap V3).
- **Token Creation**: Anyone can launch a token with image, metadata, and optional initial buy.
- **Real-time Events**: Stream token trades, creations, and DEX swaps as they happen.
- **Historical Data**: Query past events for analytics and monitoring.

## Skills Documentation

This skill guide is split into focused modules. Start with the overview, then dive into specific guides:

| Module                   | Purpose                               | Audience              |
| ------------------------ | ------------------------------------- | --------------------- |
| **SKILL.md** (this file) | Architecture, constants, setup        | Everyone              |
| **QUOTE.md**             | Price quotes, curve state             | Traders, analyzers    |
| **TRADING.md**           | Buy, sell, permit signatures          | Traders, bots         |
| **TOKEN.md**             | Balances, metadata, transfers         | App developers        |
| **CREATE.md**            | Token creation, image upload          | Token creators        |
| **INDEXER.md**           | Historical event querying             | Analytics, dashboards |
| **AGENT-API.md**         | REST API for trading data, token info | AI agents, bots       |

For API download/endpoints/header usage, see **AGENT-API.md**.

> **Note:** To obtain an API key, you must first login to [nad.fun](https://nad.fun) via wallet signature. See the [Authentication](#authentication-login-flow) section below for the login flow, then use the session cookie to create an API key via `POST /api-key`.

## Skill Files

| File         | URL                          |
| ------------ | ---------------------------- |
| ABI.md       | https://nad.fun/abi.md       |
| AGENT-API.md | https://nad.fun/agent-api.md |
| CREATE.md    | https://nad.fun/create.md    |
| INDEXER.md   | https://nad.fun/indexer.md   |
| QUOTE.md     | https://nad.fun/quote.md     |
| TOKEN.md     | https://nad.fun/token.md     |
| TRADING.md   | https://nad.fun/trading.md   |
| WALLET.md    | https://nad.fun/wallet.md    |

mkdir -p ~/.nadfun/skills
curl -s https://nad.fun/skill.md > ~/.nadfun/skills/SKILL.md
curl -s https://nad.fun/abi.md > ~/.nadfun/skills/ABI.md
curl -s https://nad.fun/agent-api.md > ~/.nadfun/skills/AGENT-API.md
curl -s https://nad.fun/create.md > ~/.nadfun/skills/CREATE.md
curl -s https://nad.fun/indexer.md > ~/.nadfun/skills/INDEXER.md
curl -s https://nad.fun/quote.md > ~/.nadfun/skills/QUOTE.md
curl -s https://nad.fun/token.md > ~/.nadfun/skills/TOKEN.md
curl -s https://nad.fun/trading.md > ~/.nadfun/skills/TRADING.md
curl -s https://nad.fun/wallet.md > ~/.nadfun/skills/WALLET.md

## Quick Facts

- **Network**: Testnet (chain 10143) or Mainnet (chain 143)
- **Language**: TypeScript/JavaScript
- **Pure viem**: All examples use direct contract calls with viem
- **Fees**: Check API for deploy fees via REST endpoint

## Network Constants

All addresses and endpoints are here. Update this when network changes.

```typescript
const NETWORK = "testnet" // 'testnet' | 'mainnet'

const CONFIG = {
  testnet: {
    chainId: 10143,
    rpcUrl: "https://monad-testnet.drpc.org",
    apiUrl: "https://dev-api.nad.fun", // For token creation

    // Contract addresses
    DEX_ROUTER: "0x5D4a4f430cA3B1b2dB86B9cFE48a5316800F5fb2",
    BONDING_CURVE_ROUTER: "0x865054F0F6A288adaAc30261731361EA7E908003",
    LENS: "0xB056d79CA5257589692699a46623F901a3BB76f1",
    CURVE: "0x1228b0dc9481C11D3071E7A924B794CfB038994e",
    WMON: "0x5a4E0bFDeF88C9032CB4d24338C5EB3d3870BfDd",
    V3_FACTORY: "0xd0a37cf728CE2902eB8d4F6f2afc76854048253b",
    CREATOR_TREASURY: "0x24dFf9B68fA36f8400302e2babC3e049eA19459E",
  },
  mainnet: {
    chainId: 143,
    rpcUrl: "https://monad-mainnet.drpc.org",
    apiUrl: "https://api.nadapp.net",

    // Contract addresses
    DEX_ROUTER: "0x0B79d71AE99528D1dB24A4148b5f4F865cc2b137",
    BONDING_CURVE_ROUTER: "0x6F6B8F1a20703309951a5127c45B49b1CD981A22",
    LENS: "0x7e78A8DE94f21804F7a17F4E8BF9EC2c872187ea",
    CURVE: "0xA7283d07812a02AFB7C09B60f8896bCEA3F90aCE",
    WMON: "0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A",
    V3_FACTORY: "0x6B5F564339DbAD6b780249827f2198a841FEB7F3",
    CREATOR_TREASURY: "0x42e75B4B96d7000E7Da1e0c729Cec8d2049B9731",
  },
}[NETWORK]
```

## Basic Setup

Every skill guide assumes you start with viem. Here's the foundation:

```typescript
import { createPublicClient, createWalletClient, http, privateKeyToAccount } from "viem"

const NETWORK = "testnet"
const CONFIG = {
  /* from above */
}[NETWORK]

// Create clients
const publicClient = createPublicClient({
  chain: {
    id: CONFIG.chainId,
    name: "Monad",
    nativeCurrency: { name: "MON", symbol: "MON", decimals: 18 },
    rpcUrls: { default: { http: [CONFIG.rpcUrl] } },
  },
  transport: http(CONFIG.rpcUrl),
})

const account = privateKeyToAccount("0x...")
const walletClient = createWalletClient({
  account,
  chain: publicClient.chain,
  transport: http(CONFIG.rpcUrl),
})
```

This is your foundation. All other modules build on top of this.

## Authentication (Login Flow)

To access session-protected endpoints (API key management, account settings, etc.), you need to authenticate via wallet signature.

### Login Flow

```typescript
import { createWalletClient, http, privateKeyToAccount } from "viem"

const account = privateKeyToAccount("0x...")
const walletClient = createWalletClient({
  account,
  chain: {
    id: CONFIG.chainId,
    name: "Monad",
    nativeCurrency: { name: "MON", symbol: "MON", decimals: 18 },
    rpcUrls: { default: { http: [CONFIG.rpcUrl] } },
  },
  transport: http(CONFIG.rpcUrl),
})

// Step 1: Request nonce
const nonceRes = await fetch(`${CONFIG.apiUrl}/auth/nonce`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ address: account.address }),
})
const { nonce } = await nonceRes.json()

// Step 2: Sign the nonce
const signature = await walletClient.signMessage({ message: nonce })

// Step 3: Create session
const sessionRes = await fetch(`${CONFIG.apiUrl}/auth/session`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    signature,
    nonce,
    chain_id: CONFIG.chainId,
  }),
})

// Extract session cookie from response headers
const sessionCookie = sessionRes.headers.get("set-cookie")
const { account_info } = await sessionRes.json()

console.log("Logged in as:", account_info.account_id)
```

### Using Session Cookie

```typescript
// Use session cookie for authenticated requests
const headers = { Cookie: sessionCookie }

// Example: Create API Key (requires session)
const apiKeyRes = await fetch(`${CONFIG.apiUrl}/api-key`, {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json" },
  body: JSON.stringify({ name: "My Bot", expires_in_days: 365 }),
})
const { api_key } = await apiKeyRes.json()
console.log("API Key:", api_key) // Store this securely!
```

### Logout

```typescript
await fetch(`${CONFIG.apiUrl}/auth/delete_session`, {
  method: "DELETE",
  headers: { Cookie: sessionCookie },
})
```

### TypeScript Interfaces

```typescript
interface AuthNonceRequest {
  address: string
}

interface AuthNonceResponse {
  nonce: string
}

interface AuthSessionRequest {
  signature: string
  nonce: string
  chain_id: number
  wallet_address?: string // Optional
}

interface AuthSessionResponse {
  account_info: {
    account_id: string
    nickname: string
    bio: string
    image_uri: string
  }
}
```

## Core Concepts

### Bonding Curve

Tokens on NadFun start on a bonding curve. The curve defines price and availability:

- **Real reserves**: Actual MON and tokens in the pool
- **Virtual reserves**: Initial pseudo-reserves for curve math
- **K constant**: Maintains x\*y=k formula for price
- **Target**: How many tokens must be sold to graduate

Get curve state with `getCurveState(token)` → see **QUOTE.md**

### Graduation

When enough tokens are bought:

1. Curve reaches target reserve
2. Liquidity moves to Uniswap V3 pool
3. Token transitions from bonding curve to DEX
4. `isGraduated(token)` returns true

Check progress with `getProgress(token)` (0-10000 = 0-100%)

### Action IDs

The `actionId` parameter in token creation identifies the type of action:

| actionId | Description    |
| -------- | -------------- |
| 1        | Token Creation |

Always use `actionId: 1` when calling the `create` function.

### Permit Signatures

EIP-2612 lets wallets sign approval transactions instead of sending separate approve() calls:

1. Generate signature: `generatePermitSignature(token, spender, amount, deadline)`
2. Use in trade: `sellPermit({ ...params, ...signature })`
3. No separate approve needed—saves gas

See **TRADING.md** for details.

## Common Patterns

### Pattern 1: Simple Trade

```typescript
// Get quote (3 args: token, amountIn, isBuy)
const [router, amountOut] = await publicClient.readContract({
  address: LENS,
  abi: lensAbi,
  functionName: "getAmountOut",
  args: [token, amountIn, true], // true = buy
})

// Buy with slippage protection (1 tuple arg)
const minOut = (amountOut * BigInt(995)) / BigInt(1000) // 0.5% slippage
const deadline = BigInt(Math.floor(Date.now() / 1000) + 300)
const tx = await walletClient.writeContract({
  address: router, // Use router returned from getAmountOut
  abi: bondingCurveRouterAbi,
  functionName: "buy",
  args: [
    {
      amountOutMin: minOut,
      token: token,
      to: account.address,
      deadline: deadline,
    },
  ],
  value: amountIn,
})
```

See **TRADING.md** for full examples.

### Pattern 2: Launch Token

```typescript
import { bondingCurveRouterAbi } from "./abis/router"

// Requires API_KEY and deployFeeAmount (see CREATE.md for feeConfig())

// 1. Upload image to Agent API (raw binary, NOT formData)
const imageRes = await fetch(`${CONFIG.apiUrl}/agent/token/image`, {
  method: "POST",
  headers: {
    "X-API-Key": API_KEY,
    "Content-Type": "image/png", // or 'image/jpeg', 'image/webp', 'image/svg+xml'
  },
  body: imageBuffer, // raw binary data (Buffer, Blob, or ArrayBuffer)
})
const { image_uri: imageUri } = await imageRes.json()

// 2. Upload metadata to Agent API
const metadataRes = await fetch(`${CONFIG.apiUrl}/agent/token/metadata`, {
  method: "POST",
  headers: { "Content-Type": "application/json", "X-API-Key": API_KEY },
  body: JSON.stringify({
    name: "My Token",
    symbol: "MTK",
    description: "My awesome token",
    image_uri: imageUri,
  }),
})
const { metadata_uri: metadataUri } = await metadataRes.json()

// 3. Mine salt via Agent API
const saltRes = await fetch(`${CONFIG.apiUrl}/agent/salt`, {
  method: "POST",
  headers: { "Content-Type": "application/json", "X-API-Key": API_KEY },
  body: JSON.stringify({
    creator: account.address,
    name: "My Token",
    symbol: "MTK",
    metadata_uri: metadataUri,
  }),
})
const { salt } = await saltRes.json()

// 4. Create token on-chain
const tx = await walletClient.writeContract({
  address: BONDING_CURVE_ROUTER,
  abi: bondingCurveRouterAbi,
  functionName: "create",
  args: [
    {
      name: "My Token",
      symbol: "MTK",
      tokenURI: metadataUri,
      amountOut: 0n, // Set > 0n for initial buy amount (in tokens)
      salt: salt,
      actionId: 1, // Token creation action identifier (always 1 for create)
    },
  ],
  value: deployFeeAmount, // plus optional initial buy MON if amountOut > 0
  gas, // Use estimated gas (see below)
})

console.log("Transaction:", tx)

// Gas estimation (recommended over hardcoded values)
const gasEstimate = await publicClient.estimateContractGas({
  address: CONFIG.BONDING_CURVE_ROUTER,
  abi: bondingCurveRouterAbi,
  functionName: "create",
  args: [
    { name: "My Token", symbol: "MTK", tokenURI: metadataUri, amountOut: 0n, salt, actionId: 1 },
  ],
  value: deployFeeAmount,
  account: account.address,
})
const gas = (gasEstimate * 120n) / 100n // 20% buffer for safety
```

See **CREATE.md** for step-by-step.

## Prompts for AI Agents

Use these prompts to guide your work:

### Trading

- "Get a price quote for token X with 0.1 MON"
- "Buy 0.1 MON of token X with 1% slippage"
- "Sell all tokens with permit signature"
- "Check if token has graduated"

### Token Info

- "Get metadata for token address X"
- "Check my MON balance"
- "Get available tokens to buy before graduation"

### Creation

- "Launch a token called MyToken (MTK) with this image"
- "Mine a vanity address for my token"
- "Check token creation fees"

### Analysis

- "Calculate graduation progress for token X"
- "Get the bonding curve state for token X"
- "Track all swaps on the graduated token"
- "Analyze token creation rate"

## Required Files

For integration, you'll need:

```
abis/
├── curve.ts              # Bonding curve contract ABI
├── lens.ts               # Price quote ABI
├── router.ts             # DEX router ABI
├── token.ts              # ERC20 token ABI
└── v3*.ts                # Uniswap V3 ABIs

constants.ts              # Network configs, contract addresses
```

All ABIs are documented in **ABI.md**.

### ABI Import Guide

Each ABI can be copied from **ABI.md**. Reference the correct section:

| ABI                     | ABI.md Section                                    | Purpose                          |
| ----------------------- | ------------------------------------------------- | -------------------------------- |
| `bondingCurveRouterAbi` | [BondingCurveRouter ABI](#bondingcurverouter-abi) | Token creation, buy/sell         |
| `lensAbi`               | [Lens ABI](#lens-abi)                             | Price quotes, getAmountOut       |
| `curveAbi`              | [Curve ABI](#curve-abi)                           | Curve state, graduation check    |
| `tokenAbi`              | [Token ABI](#token-abi)                           | ERC20 operations, permit signing |

Example import pattern:

```typescript
// Copy the ABI from ABI.md into your project
import { bondingCurveRouterAbi } from "./abis/router"
import { lensAbi } from "./abis/lens"
```

## Installation

```bash
npm install viem
# or
pnpm add viem
# or
yarn add viem
```

## Dependencies

```json
{
  "viem": "^2.0.0"
}
```

Pure viem. No other blockchain libraries needed.

## Troubleshooting

### "No such contract"

You're on the wrong network. Check NETWORK constant matches your setup.

### "Token not graduated yet"

Query `getProgress()` via Lens contract. Returns 0-10000. Need 10000 (100%) to graduate.

### "Transaction reverted"

1. Check amountOutMin—slippage might be too high or curve moved
2. Verify deadline—transaction took too long
3. Check allowance—approve token before sell

## Next Steps

Pick a guide based on what you need:

- **Building a dex bot?** → TRADING.md
- **Creating a dashboard?** → INDEXER.md + QUOTE.md
- **Launching tokens?** → CREATE.md
- **Token info queries?** → TOKEN.md

Each guide has complete examples ready to copy.

## General Development Practices & Troubleshooting

### Type Safety Tips

Always use the `as const` assertion when working with ABIs in viem. All ABIs in this module are pre-declared with `as const` for full type inference:

```typescript
// Types are automatically narrowed
const result = await contract.read.getAmountOut([...])
// result type is precisely bigint (not bigint | undefined)
```

Use viem type helpers for type-safe conversions:

```typescript
import { Address, Hex } from "viem"
import { parseEther, formatEther } from "viem"

// Amounts
const wei = parseEther("1") // string -> bigint
const eth = formatEther(1000000000000000000n) // bigint -> string

// Addresses
const addr: Address = "0x..." // Validated address type

// Signatures
const sig: Hex = "0x..." // Hex string type
```

### Common ABI Errors

When interacting with smart contracts, you might encounter specific errors. Here's a table of common ABI-related errors and how to approach them:

| Error                   | Meaning                                                    |
| ----------------------- | ---------------------------------------------------------- |
| `InsufficientAmount`    | Output less than amountOutMin                              |
| `InsufficientAmountOut` | Insufficient output amount                                 |
| `DeadlineExpired`       | Deadline has passed                                        |
| `Unauthorized`          | Caller not authorized                                      |
| `AlreadyGraduated`      | Token already graduated to DEX                             |
| `BondingCurveLocked`    | Curve locked during graduation                             |
| `InvalidProof`          | Merkle proof verification failed (specific to claims)      |
| `AlreadyClaimed`        | Amount already claimed for this proof (specific to claims) |
| `NotClaimable`          | Token not eligible for claims yet (specific to claims)     |
| `InsufficientBalance`   | Treasury has insufficient MON balance (specific to claims) |

Check error types in viem with:

```typescript
import { ContractFunctionExecutionError } from 'viem'

try {
  await contract.write.buy([...]) // or any contract interaction
} catch (error) {
  if (error instanceof ContractFunctionExecutionError) {
    console.log(error.shortMessage) // "InsufficientAmount", etc.
  }
}
```

Attribution

rondoflowrondoflow
View sourceMore from rondoflow →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

284722 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2192 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →