Skip to content

Latest commit

 

History

History
265 lines (200 loc) · 7.76 KB

File metadata and controls

265 lines (200 loc) · 7.76 KB

Custodio.dev

On-Chain Trust Enforcement Protocol for Solana

Custodio.dev is a Solana-native protocol that assigns wallets a TrustTier (0–5) based on reputation signals and enforces permissions on-chain (not in UI).

Program ID (Devnet): 7jE8RH9vYxj44H45qvvSnG5TYoEDNsMcexeQwrxBoDHs


✅ What Is Implemented

  • On-chain TrustTier system (0–5) - Stored per-wallet in PDAs
  • Time-based decay - Inactive wallets lose trust automatically
  • assert_permission instruction - Fails transactions if tier is insufficient
  • Deployed devnet program - Fully functional on Solana devnet
  • HTTP API with API key protection - For non-Solana developers
  • Vercel-compatible backend - Deploy with npx vercel
  • FairScale integration (optional) - Fetch external reputation scores

⚠️ What Is Intentionally NOT Implemented

  • Oracle verification of scores - Users can self-report scores (demo limitation)
  • Frontend UI - Out of scope for this submission
  • ZK proofs - Design document only (docs/zk.md)
  • Rate limiting / database - Kept simple for hackathon

🏗️ Architecture

┌─────────────────────────────────────────────────────────────────┐
│                         Custodio.dev                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   ┌─────────────┐    ┌─────────────┐    ┌─────────────────┐    │
│   │  FairScale  │───▶│   Backend   │───▶│  Solana Program │    │
│   │  (optional) │    │   HTTP API  │    │   (Anchor)      │    │
│   └─────────────┘    └─────────────┘    └─────────────────┘    │
│                             │                    │              │
│                             ▼                    ▼              │
│                      ┌─────────────┐      ┌─────────────┐       │
│                      │ Read-only   │      │  UserState  │       │
│                      │ permission  │      │  PDA with   │       │
│                      │ check       │      │  TrustTier  │       │
│                      └─────────────┘      └─────────────┘       │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Key insight: The HTTP API is read-only. It reads on-chain state to check permissions. Writing to chain (init_user, update_tier) requires Solana transactions.


🚀 Quick Start

1. Check a Wallet's Permission (HTTP API)

curl -X POST https://your-api.vercel.app/api/check-permission \
  -H "Authorization: Bearer cust_test_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "wallet": "6cxXezcWW2cFCdE18qTAqLegZGL3mtXuE8ydshXsbXB4",
    "requiredTier": 3
  }'

Response:

{
  "allowed": false,
  "currentTier": 0,
  "tierName": "Untrusted",
  "effectiveScore": 0,
  "requiredTier": 3,
  "reason": "Tier 0 is below required tier 3",
  "meta": {
    "source": "on-chain",
    "program": "7jE8RH9vYxj44H45qvvSnG5TYoEDNsMcexeQwrxBoDHs",
    "network": "devnet"
  }
}

2. Deploy the API (Vercel)

cd backend
npm install
npx vercel
# Set environment variable: CUSTODIO_API_KEYS=cust_test_demo123456

3. Build the On-Chain Program

anchor build
anchor test --skip-local-validator

🔢 TrustTier Logic

Score Range TrustTier Meaning
≤ 400 0 Untrusted / New
401 – 600 1 Basic trust
601 – 800 2 Moderate trust
801 – 900 3 Good standing
901 – 950 4 High trust
951 – 1000 5 Maximum trust

⏳ Time-Decay Schedule

Inactive wallets automatically lose trust:

Inactivity Decay Factor Effective Score
≤ 3 days 100% No change
4–7 days 90% 900 → 810
8–14 days 75% 900 → 675
15–30 days 50% 900 → 450
> 30 days 25% 900 → 225

🚪 On-Chain Enforcement

The assert_permission instruction is the core innovation:

pub fn vote(ctx: Context<Vote>) -> Result<()> {
    // Transaction FAILS if tier < 3
    assert_permission(&ctx.accounts.user_state, 3)?;
    
    // Only reaches here if tier >= 3
    Ok(())
}

Why this matters: Permission is enforced at the program level. Users cannot bypass it by calling RPC directly.


📦 Project Structure

custodio.dev/
├── contracts/                   # On-chain Solana program
│   ├── custodio/src/
│   │   ├── lib.rs               # 4 instructions
│   │   ├── state.rs             # UserState PDA (92 bytes)
│   │   ├── constants.rs         # Tier thresholds, decay
│   │   ├── utils.rs             # compute_tier(), apply_decay()
│   │   └── instructions/        # init_user, update_tier, etc.
│   └── tests/custodio.ts        # Anchor tests
│
├── backend/                     # HTTP API (Vercel-ready)
│   ├── app/api/
│   │   ├── check-permission/    # POST - main endpoint
│   │   └── health/              # GET - health check
│   └── lib/
│       ├── auth.ts              # API key validation
│       ├── solana.ts            # On-chain reader
│       └── fairscale.ts         # FairScale integration
│
├── docs/zk.md                   # ZK extension design (future)
├── Anchor.toml
├── Cargo.toml
└── README.md

⚙️ Environment Variables

Backend API (.env)

# Required
CUSTODIO_API_KEYS=cust_test_key1,cust_live_key2

# Optional
SOLANA_RPC_URL=https://api.devnet.solana.com
SOLANA_NETWORK=devnet
FAIRSCALE_API_KEY=your_fairscale_key

🧪 Running Tests

# Build program
anchor build

# Run tests on devnet
anchor test --skip-local-validator

Test coverage:

  • init_user - Creates UserState PDA
  • update_tier - Score → tier mapping
  • assert_permission - Rejects insufficient tier

📡 API Reference

POST /api/check-permission

Check if a wallet meets a tier requirement.

Headers:

  • Authorization: Bearer <API_KEY> (required)
  • Content-Type: application/json

Body:

{
  "wallet": "base58-address",
  "requiredTier": 3,
  "includeFairScale": false
}

Response:

{
  "allowed": true,
  "currentTier": 4,
  "tierName": "High",
  "effectiveScore": 920,
  "requiredTier": 3
}

GET /api/health

Health check. Returns Solana connection status.


🔐 Security Notes

  1. On-chain is truth - The API reads from blockchain, not a database
  2. API keys are secrets - Never expose in frontend code
  3. Score source is NOT verified - This is a known demo limitation

📜 License

MIT License - See LICENSE


Built for the FairScale Solana Build Bounty