FeeFlow for Nimbus

FeeFlow for Nimbus IDE

Claim pump.fun creator fees and distribute to token holders. Your private key never leaves your machine.

Quick Start

  1. Open Nimbus IDE
  2. Create a new file: feeflow-claim.mjs
  3. Paste the script below
  4. Add your private key and token mints
  5. Run: node feeflow-claim.mjs

No Trust Required

This script runs entirely on your machine in Nimbus IDE. Your private key is never sent to any server - it stays in your code and signs transactions locally. You can audit the code yourself.

The Script

Copy this entire script into Nimbus IDE. Replace the configuration values at the top.

// FeeFlow - Claim pump.fun fees & distribute to holders
// Run in Nimbus IDE: node feeflow-claim.mjs
// Your private key NEVER leaves your machine

import { Connection, Keypair, VersionedTransaction, PublicKey, SystemProgram, Transaction, LAMPORTS_PER_SOL } from '@solana/web3.js';
import bs58 from 'bs58';

// ============ CONFIGURATION ============
const PRIVATE_KEY = 'YOUR_BASE58_PRIVATE_KEY';  // Your wallet private key
const HELIUS_API_KEY = 'YOUR_HELIUS_API_KEY';   // Get free key at helius.dev

// Add your token mint addresses here
const TOKEN_MINTS = [
  // 'TokenMintAddress1...',
  // 'TokenMintAddress2...',
];

// ============ SETUP ============
const RPC_URL = `https://mainnet.helius-rpc.com/?api-key=${HELIUS_API_KEY}`;
const keypair = Keypair.fromSecretKey(bs58.decode(PRIVATE_KEY));
const wallet = keypair.publicKey.toBase58();
const connection = new Connection(RPC_URL, 'confirmed');

console.log('Wallet:', wallet);

// ============ CLAIM FEES ============
async function claimFees(mint) {
  try {
    console.log(`\nClaiming fees for ${mint}...`);

    const res = await fetch('https://pumpportal.fun/api/trade-local', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        publicKey: wallet,
        action: 'collectCreatorFee',
        mint: mint,
        priorityFee: 0.0001,
        pool: 'pump'
      })
    });

    if (!res.ok) {
      const err = await res.text();
      if (err.includes('no fees') || err.includes('nothing')) {
        console.log('  No fees to claim');
        return { success: true, noFees: true };
      }
      throw new Error(err);
    }

    const txData = await res.arrayBuffer();
    const tx = VersionedTransaction.deserialize(new Uint8Array(txData));
    tx.sign([keypair]);

    const sig = await connection.sendRawTransaction(tx.serialize());
    await connection.confirmTransaction(sig, 'confirmed');

    console.log(`  Claimed! https://solscan.io/tx/${sig}`);
    return { success: true, signature: sig };
  } catch (e) {
    console.error(`  Error: ${e.message}`);
    return { success: false, error: e.message };
  }
}

// ============ GET HOLDERS ============
async function getHolders(mint) {
  const res = await fetch(RPC_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 'holders',
      method: 'getTokenAccounts',
      params: { mint, limit: 1000, options: { showZeroBalance: false } }
    })
  });
  const data = await res.json();
  return (data.result?.token_accounts || [])
    .filter(a => a.owner !== wallet)
    .map(a => ({ address: a.owner, balance: Number(a.amount) }));
}

// ============ DISTRIBUTE TO HOLDERS ============
async function distribute(mint, amountSol) {
  console.log(`\nDistributing ${amountSol} SOL to holders of ${mint}...`);

  const holders = await getHolders(mint);
  if (!holders.length) {
    console.log('  No holders found');
    return;
  }

  const totalSupply = holders.reduce((s, h) => s + h.balance, 0);
  const { blockhash } = await connection.getLatestBlockhash();

  // Build transaction (max 20 transfers per tx)
  const tx = new Transaction();
  let recipientCount = 0;

  for (const h of holders.slice(0, 20)) {
    const share = (h.balance / totalSupply) * amountSol;
    if (share < 0.000001) continue;

    tx.add(SystemProgram.transfer({
      fromPubkey: keypair.publicKey,
      toPubkey: new PublicKey(h.address),
      lamports: Math.floor(share * LAMPORTS_PER_SOL)
    }));
    recipientCount++;
  }

  if (recipientCount === 0) {
    console.log('  No recipients (shares too small)');
    return;
  }

  tx.recentBlockhash = blockhash;
  tx.feePayer = keypair.publicKey;
  tx.sign(keypair);

  const sig = await connection.sendRawTransaction(tx.serialize());
  await connection.confirmTransaction(sig, 'confirmed');

  console.log(`  Distributed to ${recipientCount} holders! https://solscan.io/tx/${sig}`);
}

// ============ MAIN ============
async function main() {
  console.log('\n========== FeeFlow ==========\n');

  // Get initial balance
  const balanceBefore = await connection.getBalance(keypair.publicKey);
  console.log(`Balance: ${balanceBefore / LAMPORTS_PER_SOL} SOL\n`);

  // Claim fees from all tokens
  for (const mint of TOKEN_MINTS) {
    await claimFees(mint);
  }

  // Check if we claimed anything
  const balanceAfter = await connection.getBalance(keypair.publicKey);
  const claimed = (balanceAfter - balanceBefore) / LAMPORTS_PER_SOL;

  if (claimed > 0.001) {
    console.log(`\nClaimed ${claimed.toFixed(4)} SOL total\n`);

    // Distribute to holders (keep 10% for gas)
    const toDistribute = claimed * 0.9;
    for (const mint of TOKEN_MINTS) {
      await distribute(mint, toDistribute / TOKEN_MINTS.length);
    }
  }

  console.log('\n========== Done ==========\n');
}

main().catch(console.error);

Configuration

PRIVATE_KEY

Your wallet's base58 private key. Export from Phantom: Settings → Security → Export Private Key

HELIUS_API_KEY

Free RPC key from helius.dev - needed for getting token holders

TOKEN_MINTS

Array of token mint addresses you've launched on pump.fun. Find these on your token pages or Solscan.

Run Hourly (Optional)

To auto-claim every hour, set up a cron job on your machine or a VPS:

# Edit crontab
crontab -e

# Add this line (runs every hour)
0 * * * * cd /path/to/project && node feeflow-claim.mjs >> claim.log 2>&1

Or use Nimbus IDE's built-in scheduler if available.

Example Prompts for Claude

Copy these prompts to tell Claude in Nimbus IDE what to do:

Setup the script:

"Create a file called feeflow-claim.mjs with the FeeFlow script from feeflow.fly.dev/docs. Use my private key [YOUR_KEY] and add these token mints: [MINT1, MINT2]"

Run the claim:

"Run node feeflow-claim.mjs to claim my pump.fun fees and distribute to holders"

Check fees without claiming:

"Check if I have any claimable fees on my pump.fun tokens [MINT1, MINT2] without claiming them"

Set up hourly auto-claim:

"Set up the feeflow-claim.mjs script to run every hour automatically"

Just claim (no distribute):

"Claim my pump.fun creator fees but don't distribute - I want to keep the SOL"

What This Script Does

  1. Connects to Solana using your private key (locally)
  2. Calls PumpPortal API to claim creator fees for each token
  3. Signs and sends the claim transaction from your wallet
  4. Gets list of token holders from Helius
  5. Calculates pro-rata share for each holder
  6. Sends SOL to each holder proportional to their token balance