NFT Gated

Token-gated access control with usage tracking

Deployed Anchor 0.32
Program ID F17Fg2ZHx1UZqNCBeueuuiDiVJwBLP8NqrLCPJPFQ4Pg
Binary Size 243K
Cluster Devnet

Instructions

IX create_gate

Creates a new access gate that requires holders of a specific NFT mint to access a resource.

ParameterTypeDescription
nameStringName of the gated resource (max 32 characters)
IX access

Requests initial access to the gated resource. Verifies the caller holds the required NFT and creates an access record.

ParameterTypeDescription
No parameters
IX re_access

Records a subsequent access, incrementing the usage counter on an existing access record.

ParameterTypeDescription
No parameters
IX revoke_access

Revokes access for a specific wallet. Only callable by the gate authority.

ParameterTypeDescription
No parameters

Accounts

Gate

FieldTypeDescription
authorityPubkeyGate creator and admin
required_mintPubkeyNFT mint required for access
nameStringName of the gated resource
total_accessesu64Total number of access events recorded
bumpu8PDA bump seed

AccessRecord

FieldTypeDescription
gatePubkeyThe gate this record belongs to
walletPubkeyWallet address with access
mint_usedPubkeyThe NFT mint used to gain access
first_accessi64Timestamp of the first access
access_countu64Number of times access has been used
bumpu8PDA bump seed

PDA Derivation

gate
seeds = [b"gate", authority, required_mint]
access
seeds = [b"access", gate, holder]

Error Codes

NameTooLong Gate name exceeds the maximum 32 character limit
NoNftHeld The wallet does not hold the required NFT for access
Overflow Arithmetic overflow in access counting

Usage Example

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

// Derive the gate PDA
const [gatePda] = PublicKey.findProgramAddressSync(
  [Buffer.from("gate"), authority.publicKey.toBuffer(), requiredMint.toBuffer()],
  program.programId
);

// Create an access gate
await program.methods
  .createGate("VIP Lounge")
  .accounts({
    gate: gatePda,
    authority: authority.publicKey,
    requiredMint,
  })
  .signers([authority])
  .rpc();

// Request access (must hold the NFT)
const [accessPda] = PublicKey.findProgramAddressSync(
  [Buffer.from("access"), gatePda.toBuffer(), holder.publicKey.toBuffer()],
  program.programId
);

await program.methods
  .access()
  .accounts({
    gate: gatePda,
    accessRecord: accessPda,
    holder: holder.publicKey,
    nftTokenAccount: holderNftAta,
  })
  .signers([holder])
  .rpc();