Token Faucet

Rate-limited token distribution faucet with cooldown periods

Deployed Anchor 0.32
Program ID GsHPNhJtQ23Nj2duABZNDAdn1ri2kjxkeTXqH6SUSN1v
Binary Size 286K
Cluster Devnet

Instructions

IX initialize_faucet

Creates a new token faucet with a configurable distribution amount and cooldown period.

ParameterTypeDescription
amount_per_claimu64Number of tokens distributed per claim
cooldowni64Cooldown period in seconds between claims per wallet
IX claim

Claims tokens from the faucet. Enforces the per-wallet cooldown period.

ParameterTypeDescription
No parameters
IX fund

Deposits additional tokens into the faucet vault to replenish supply.

ParameterTypeDescription
amountu64Number of tokens to deposit
IX update_config

Updates the faucet configuration. Only callable by the authority.

ParameterTypeDescription
amount_per_claimu64New distribution amount per claim
cooldowni64New cooldown period in seconds

Accounts

Faucet

FieldTypeDescription
authorityPubkeyFaucet creator and admin
mintPubkeyToken mint distributed by the faucet
amount_per_claimu64Tokens given per claim
cooldowni64Minimum seconds between claims per wallet
total_claimsu64Total number of claims made
bumpu8PDA bump seed

ClaimRecord

FieldTypeDescription
faucetPubkeyThe faucet this record tracks
claimerPubkeyWallet address of the claimer
last_claimi64Timestamp of the most recent claim
total_claimedu64Total tokens claimed by this wallet
bumpu8PDA bump seed

PDA Derivation

faucet
seeds = [b"faucet", authority, mint]
claim
seeds = [b"claim", faucet, claimer]
vault
seeds = [b"vault", faucet]

Error Codes

CooldownNotExpired Must wait for the cooldown period to elapse before claiming again
Overflow Arithmetic overflow in claim tracking

Usage Example

import { Program, BN } from "@coral-xyz/anchor";
import { PublicKey } from "@solana/web3.js";

// Derive PDAs
const [faucetPda] = PublicKey.findProgramAddressSync(
  [Buffer.from("faucet"), authority.publicKey.toBuffer(), mint.toBuffer()],
  program.programId
);
const [claimPda] = PublicKey.findProgramAddressSync(
  [Buffer.from("claim"), faucetPda.toBuffer(), claimer.publicKey.toBuffer()],
  program.programId
);

// Initialize faucet: 100 tokens per claim, 1 hour cooldown
await program.methods
  .initializeFaucet(new BN(100_000_000), new BN(3600))
  .accounts({
    faucet: faucetPda,
    authority: authority.publicKey,
    mint,
  })
  .signers([authority])
  .rpc();

// Claim tokens
await program.methods
  .claim()
  .accounts({
    faucet: faucetPda,
    claimRecord: claimPda,
    claimer: claimer.publicKey,
    mint,
  })
  .signers([claimer])
  .rpc();