NFT Gated
Token-gated access control with usage tracking
Deployed
Anchor 0.32
Program ID
F17Fg2ZHx1UZqNCBeueuuiDiVJwBLP8NqrLCPJPFQ4Pg
Repository
ExpertVagabond/solana-nft-gated
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.
| Parameter | Type | Description |
|---|---|---|
name | String | Name 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.
| Parameter | Type | Description |
|---|---|---|
| No parameters | ||
IX
re_access
Records a subsequent access, incrementing the usage counter on an existing access record.
| Parameter | Type | Description |
|---|---|---|
| No parameters | ||
IX
revoke_access
Revokes access for a specific wallet. Only callable by the gate authority.
| Parameter | Type | Description |
|---|---|---|
| No parameters | ||
Accounts
Gate
| Field | Type | Description |
|---|---|---|
authority | Pubkey | Gate creator and admin |
required_mint | Pubkey | NFT mint required for access |
name | String | Name of the gated resource |
total_accesses | u64 | Total number of access events recorded |
bump | u8 | PDA bump seed |
AccessRecord
| Field | Type | Description |
|---|---|---|
gate | Pubkey | The gate this record belongs to |
wallet | Pubkey | Wallet address with access |
mint_used | Pubkey | The NFT mint used to gain access |
first_access | i64 | Timestamp of the first access |
access_count | u64 | Number of times access has been used |
bump | u8 | PDA 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();