Architecture
Understanding the Range verification flow and state machines
Range is designed around a simple principle: verify backend-signed messages on-chain without requiring the backend to co-sign transactions.
Complete Verification Flow
Section titled “Complete Verification Flow”The full flow involves the user, backend, an optional compliance service (Range.org), and the Solana network:
Step-by-Step
Section titled “Step-by-Step”- User Authentication: User signs a message with their wallet to prove ownership
- Compliance Check: Backend queries Range.org (or your compliance service) to verify the pubkey
- Compliance Response: Service returns PASS or FAIL
- Message Signing: If compliant, backend creates and signs
{timestamp}_{pubkey} - Return to User: Backend sends signature and message to user
- Transaction Submission: User includes signature in their Solana transaction
- On-chain Verification: Range program verifies signature, timestamp, and pubkey
- Result: Transaction succeeds or fails with specific error
Settings Account State Machine
Section titled “Settings Account State Machine”Each admin can create their own Settings account. The account lifecycle:
Key Points:
- Any user can create their own Settings by calling
initialize_settingsas admin - Settings PDA derived from:
["settings", admin_pubkey] - Only the current admin can update settings or transfer ownership
- Transferring admin changes who controls the account but keeps the same PDA
Verification State Machine
Section titled “Verification State Machine”When verify_range or verify_range_with_callback is called:
CPI Patterns
Section titled “CPI Patterns”Range supports two CPI patterns:
Pattern A: External Program → Range
Section titled “Pattern A: External Program → Range”Another program calls Range for verification:
Pattern B: Range → Callback (Atomic)
Section titled “Pattern B: Range → Callback (Atomic)”Range verifies then calls your program:
CPI-Only Enforcement
Section titled “CPI-Only Enforcement”The on_verify instruction in your program should only be callable via CPI from Range:
This is enforced by checking the instruction sysvar to verify the previous instruction was from the Range program.
Account Structure
Section titled “Account Structure”Settings Account
Section titled “Settings Account”| Field | Type | Description |
|---|---|---|
bump | u8 | PDA bump seed |
admin | Pubkey | Owner who can modify settings |
window_size | u64 | Time window in seconds for timestamp validation |
range_signer | Pubkey | Public key of trusted backend signer |
PDA Seeds: ["settings", admin.key()]
Message Format
Section titled “Message Format”The standard message format is:
{timestamp}_{pubkey}timestamp: Unix timestamp (seconds) when message was signedpubkey: Base58-encoded public key of the user
Example: 1704067200_7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU