195 lines
4.1 KiB
Markdown
195 lines
4.1 KiB
Markdown
|
|
# KRAIKEN Ponder Indexer
|
||
|
|
|
||
|
|
A high-performance blockchain indexer for the KRAIKEN protocol using Ponder framework, providing 10-15x faster indexing than The Graph with superior developer experience.
|
||
|
|
|
||
|
|
## Features
|
||
|
|
|
||
|
|
- ✅ **Multi-network support**: Local (Anvil fork), Base Sepolia, Base mainnet
|
||
|
|
- ✅ **Hot reload**: Instant updates during development
|
||
|
|
- ✅ **Type safety**: Full TypeScript support with auto-completion
|
||
|
|
- ✅ **Ring buffer**: 7-day hourly metrics with projections
|
||
|
|
- ✅ **GraphQL API**: Auto-generated from schema
|
||
|
|
- ✅ **Efficient indexing**: In-memory operations during sync
|
||
|
|
|
||
|
|
## Quick Start
|
||
|
|
|
||
|
|
### 1. Install Dependencies
|
||
|
|
|
||
|
|
```bash
|
||
|
|
npm install
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Configure Environment
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cp .env.example .env
|
||
|
|
```
|
||
|
|
|
||
|
|
Edit `.env` to select your network:
|
||
|
|
- `PONDER_NETWORK=local` - Local Anvil fork
|
||
|
|
- `PONDER_NETWORK=baseSepolia` - Base Sepolia testnet
|
||
|
|
- `PONDER_NETWORK=base` - Base mainnet
|
||
|
|
|
||
|
|
### 3. Local Development (Anvil Fork)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Terminal 1: Start Anvil fork of Base mainnet
|
||
|
|
anvil --fork-url https://base.llamarpc.com
|
||
|
|
|
||
|
|
# Terminal 2: Start Ponder indexer
|
||
|
|
PONDER_NETWORK=local npm run dev
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4. Testnet Deployment (Base Sepolia)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
PONDER_NETWORK=baseSepolia npm run dev
|
||
|
|
```
|
||
|
|
|
||
|
|
### 5. Production Deployment (Base Mainnet)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
PONDER_NETWORK=base npm run start
|
||
|
|
```
|
||
|
|
|
||
|
|
## GraphQL Queries
|
||
|
|
|
||
|
|
Once running, access the GraphQL playground at `http://localhost:42069/graphql`
|
||
|
|
|
||
|
|
### Example Queries
|
||
|
|
|
||
|
|
#### Get Protocol Stats
|
||
|
|
```graphql
|
||
|
|
{
|
||
|
|
stats(id: "0x01") {
|
||
|
|
kraikenTotalSupply
|
||
|
|
stakeTotalSupply
|
||
|
|
outstandingStake
|
||
|
|
mintedLastWeek
|
||
|
|
mintedLastDay
|
||
|
|
mintNextHourProjected
|
||
|
|
burnedLastWeek
|
||
|
|
burnedLastDay
|
||
|
|
burnNextHourProjected
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Get All Positions
|
||
|
|
```graphql
|
||
|
|
{
|
||
|
|
positions(where: { status: "Active" }) {
|
||
|
|
items {
|
||
|
|
id
|
||
|
|
owner
|
||
|
|
share
|
||
|
|
taxRate
|
||
|
|
kraikenDeposit
|
||
|
|
taxPaid
|
||
|
|
createdAt
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Get User Positions
|
||
|
|
```graphql
|
||
|
|
{
|
||
|
|
positions(where: { owner: "0x..." }) {
|
||
|
|
items {
|
||
|
|
id
|
||
|
|
share
|
||
|
|
taxRate
|
||
|
|
kraikenDeposit
|
||
|
|
stakeDeposit
|
||
|
|
taxPaid
|
||
|
|
status
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
### Schema (`ponder.schema.ts`)
|
||
|
|
- **stats**: Global protocol metrics with ring buffer
|
||
|
|
- **hourlyData**: 168-hour circular buffer for time-series
|
||
|
|
- **positions**: Harberger tax staking positions
|
||
|
|
|
||
|
|
### Event Handlers
|
||
|
|
- **kraiken.ts**: Handles Transfer events for minting, burning, tax, UBI
|
||
|
|
- **stake.ts**: Handles position lifecycle events
|
||
|
|
|
||
|
|
### Ring Buffer Implementation
|
||
|
|
- 168 hourly slots (7 days)
|
||
|
|
- Automatic hourly rollover
|
||
|
|
- Projection calculation using median smoothing
|
||
|
|
- Rolling 24h and 7d aggregations
|
||
|
|
|
||
|
|
## Comparison with Subgraph
|
||
|
|
|
||
|
|
| Feature | Subgraph | Ponder |
|
||
|
|
|---------|----------|---------|
|
||
|
|
| Sync Speed | 1x | 10-15x faster |
|
||
|
|
| Hot Reload | ❌ | ✅ |
|
||
|
|
| Language | AssemblyScript | TypeScript |
|
||
|
|
| Setup | Complex (PostgreSQL, IPFS, Graph Node) | Simple (Node.js) |
|
||
|
|
| NPM Packages | ❌ | ✅ |
|
||
|
|
| Type Safety | Requires codegen | Automatic |
|
||
|
|
|
||
|
|
## Deployment Options
|
||
|
|
|
||
|
|
### Railway (Recommended)
|
||
|
|
```bash
|
||
|
|
npm run build
|
||
|
|
# Deploy to Railway with DATABASE_URL configured
|
||
|
|
```
|
||
|
|
|
||
|
|
### Self-Hosted
|
||
|
|
```bash
|
||
|
|
DATABASE_URL=postgresql://... npm run start
|
||
|
|
```
|
||
|
|
|
||
|
|
### Docker
|
||
|
|
```dockerfile
|
||
|
|
FROM node:20-alpine
|
||
|
|
WORKDIR /app
|
||
|
|
COPY package*.json ./
|
||
|
|
RUN npm ci --only=production
|
||
|
|
COPY . .
|
||
|
|
ENV PONDER_NETWORK=base
|
||
|
|
CMD ["npm", "run", "start"]
|
||
|
|
```
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### Issue: "No chain configured"
|
||
|
|
**Solution**: Ensure `PONDER_NETWORK` is set correctly in `.env`
|
||
|
|
|
||
|
|
### Issue: Slow initial sync
|
||
|
|
**Solution**: Provide a faster RPC URL via environment variables
|
||
|
|
|
||
|
|
### Issue: Database errors
|
||
|
|
**Solution**: For production, use PostgreSQL instead of SQLite:
|
||
|
|
```bash
|
||
|
|
DATABASE_URL=postgresql://user:pass@host:5432/db npm run start
|
||
|
|
```
|
||
|
|
|
||
|
|
## Migration from Subgraph
|
||
|
|
|
||
|
|
This Ponder implementation maintains complete parity with the original subgraph:
|
||
|
|
- Same entity structure (Stats, Positions)
|
||
|
|
- Identical ring buffer logic
|
||
|
|
- Same tax rate mappings
|
||
|
|
- Compatible GraphQL queries
|
||
|
|
|
||
|
|
Key improvements:
|
||
|
|
- 10-15x faster indexing
|
||
|
|
- No Docker/Graph Node required
|
||
|
|
- Hot reload for development
|
||
|
|
- Direct SQL access for complex queries
|
||
|
|
- Full Node.js ecosystem access
|
||
|
|
|
||
|
|
## License
|
||
|
|
|
||
|
|
GPL-3.0-or-later
|