Package Exports
- @mintpass/challenge
- @mintpass/challenge/package.json
Readme
MintPass Challenge for Plebbit-js
This directory contains the MintPass challenge implementation for plebbit-js that verifies users own a MintPass NFT.
Features
- NFT Ownership Verification: Checks if users own a MintPass NFT of the required type
- Transfer Cooldown Protection: Prevents quick NFT transfers between accounts to bypass verification
- Chain Flexibility: Supports different chains where MintPass contracts are deployed
- ENS Support: Works with ENS addresses and wallet addresses
- Type-specific Requirements: Can require specific token types (SMS=0, Email=1, etc.)
Installation
For use in plebbit-js projects, clone the mintpass repo alongside your plebbit-js project:
# Clone mintpass repo
git clone https://github.com/your-username/mintpass.git
# Build the challenge
cd mintpass
yarn install:all
yarn build:challenge
Usage
Basic Challenge Configuration
// Import via file path (not package import)
const challengeSettings = {
path: '../mintpass/challenge/dist/mintpass.js', // Relative path to built challenge
options: {
chainTicker: 'base',
contractAddress: '0x13d41d6B8EA5C86096bb7a94C3557FCF184491b9',
requiredTokenType: '0', // 0 = SMS verification
transferCooldownSeconds: '604800', // 1 week
error: 'You need a MintPass NFT to post. Visit https://mintpass.org/request/{authorAddress}'
}
};
// Set on subplebbit
subplebbit.settings.challenges = [challengeSettings];
Directory Structure
Your project should look like:
your-project/
├── plebbit-js/ # Your plebbit-js fork
└── mintpass/ # Cloned mintpass repo
└── challenge/
└── dist/
└── mintpass.js # Built challenge file
Challenge Options
Option | Type | Default | Description |
---|---|---|---|
chainTicker |
string | "base" |
Chain where MintPass contract is deployed |
contractAddress |
string | Optional on supported chains | If omitted and chainTicker is supported, defaults to the known MintPass deployment for that chain (e.g., Base Sepolia) |
requiredTokenType |
string | "0" |
Required token type (0=SMS, 1=Email, etc.) |
transferCooldownSeconds |
string | "604800" |
Cooldown period after NFT transfer (1 week) |
error |
string | Default message | Custom error message for users without NFT |
Token Types
- Type 0: SMS verification
- Type 1: Email verification
- Type 2+: Future verification methods
Transfer Cooldown
Wallet selection and EVM fallback
- When
chainTicker
is"base"
or"eth"
, the challenge first looks forauthor.wallets[chainTicker]
. - If that specific wallet is missing, it automatically falls back between
base
andeth
(e.g.,base → eth
oreth → base
). - This makes EVM wallet usage robust when clients store a single EVM wallet entry.
Default contract addresses
- If
contractAddress
is omitted andchainTicker
is supported, the challenge uses a known default for that chain (e.g., Base Sepolia reference deployment). - You can still override
contractAddress
explicitly in settings.
The challenge tracks when NFTs are used by different plebbit accounts and enforces a cooldown period to prevent:
- Quick transfers to bypass bans
- NFT sharing between multiple accounts
- Sybil attacks via NFT circulation
Development
Building
cd challenges
yarn install
yarn build
Testing
The challenge includes comprehensive automated testing that covers both the challenge logic and complete user publishing flow.
Quick Start
cd challenges
yarn test
This command automatically:
- Starts a local Hardhat blockchain node
- Deploys the MintPass contract
- Runs the full integration test suite
- Cleans up all processes when complete
Manual Testing
For situations where you need to manage the test infrastructure manually:
# Terminal 1: Start the Hardhat node
cd contracts && npx hardhat node
# Terminal 2: Run tests against the running node
cd challenges && yarn test:manual
Test Coverage
The automated test suite includes:
- NFT Ownership Verification: Tests both success and failure scenarios
- Complete Publishing Flow: Simulates real user posting experience
- Local IPFS Integration: Tests with isolated local IPFS daemon
- Challenge/Verification Exchange: Validates complete challenge workflow
For detailed testing information, see AUTOMATED_TESTING.md.
Integration with plebbit-js
The challenge exports a ChallengeFileFactory
function compatible with plebbit-js:
// In your plebbit-js fork
import mintpass from '@mintpass/challenge';
// Register the challenge
Plebbit.challenges.mintpass = mintpass;
// Use in subplebbit settings
const subplebbit = await plebbit.createSubplebbit({
settings: {
challenges: [{
name: 'mintpass',
options: {
contractAddress: '0x...',
requiredTokenType: '0'
}
}]
}
});
Architecture
The challenge follows the plebbit-js challenge pattern:
- Wallet Verification: Validates author's wallet signature
- NFT Ownership Check: Calls
ownsTokenType()
on MintPass contract - Transfer Cooldown: Tracks NFT usage across plebbit accounts
- ENS Support: Resolves ENS addresses to wallet addresses
Error Scenarios
Scenario | Error Message |
---|---|
No wallet set | "Author wallet address is not defined" |
Invalid signature | "The signature of the wallet is invalid" |
No NFT owned | Custom error with link to verification site |
NFT in cooldown | "Your MintPass NFT is in cooldown period" |
Contract call fails | "Failed to check MintPass NFT ownership" |
License
MIT License - Same as the MintPass project.