-
Notifications
You must be signed in to change notification settings - Fork 0
feat: ERC-721 access pass (Pattern C) 📋 #13
Copy link
Copy link
Open
Labels
Milestone
Description
Summary
Add ERC-721 (NFT) access pass model to KeyRAAccessControl. Mint an NFT that represents RPC access. Holders of the NFT have access. Passes are transferable, tradeable, and can encode metadata (rate limit tier, expiry, network).
Motivation
NFT access passes enable secondary markets for RPC access and composability with DeFi. A user can buy, sell, or delegate access without admin intervention. This is the most decentralised of the three access models.
Proposed Interface
// Separate ERC-721 contract
contract KeyRAAccessPass is ERC721 {
struct PassMetadata {
uint256 expiry; // 0 = no expiry
uint256 rateLimit; // requests per second
string network; // "mainnet", "testnet", etc.
}
mapping(uint256 => PassMetadata) public passMetadata;
function mint(address to, PassMetadata calldata metadata) external; // admin only
function hasAccess(address account) external view returns (bool);
}Key Design Considerations
- Separate contract: ERC-721 is complex enough to warrant its own contract, with
KeyRAAccessControlcalling it via interface - Transferable: standard ERC-721 transfer semantics
- Metadata on-chain: rate limit and expiry stored in contract, not off-chain
- Composable:
KeyRAAccessControl.hasAccess()checks all three sources (manual + subscription + NFT) - Burnable: admin or holder can burn expired passes
Acceptance Criteria
- ERC-721 contract with access pass minting
-
hasAccess()checksbalanceOf(account) > 0with expiry validation - Pass metadata (expiry, rate limit, network) stored on-chain
- Integration with
KeyRAAccessControl.hasAccess()as a third source - Transfer and burn functionality
- Foundry tests
- Gas analysis (NFT ownership check is more expensive than mapping lookup)
Dependencies
- feat: time-bounded subscription access control (Pattern A) 📋 #11 (Pattern A) and feat: stake-for-access model (Pattern B) 📋 #12 (Pattern B) should land first
- Multi-source
hasAccess()pattern from Pattern A is prerequisite
Reactions are currently unavailable