Source of Truth vs. Off-Chain Mirror
Understanding state authority, indexer synchronization, and cache invalidation guarantees in TIP.
A core design objective of TIP is eliminating centralized vendor lock-in while providing ultra-fast response times. To achieve this, TIP divides protocol state into two categories: On-Chain Authority and Off-Chain Mirror.
State Classification
| Data Category | Stored On-Chain? | Stored Off-Chain? | Authority |
|---|---|---|---|
Tag Handle (e.g., alice) | Yes (PDA Seed) | Yes (Database Mirror) | Solana Blockchain |
| Tag Owner (Pubkey) | Yes (Account Field) | Yes (Database Mirror) | Solana Blockchain |
| Payment Wallet (Pubkey) | Yes (Account Field) | Yes (Database Mirror) | Solana Blockchain |
| PDA Bump (u8) | Yes (Account Field) | Yes (Database Mirror) | Solana Blockchain |
| Display Name (Text) | No | Yes (Database Mirror) | TIP API / User |
| Avatar URL (Image URL) | No | Yes (Database Mirror) | TIP API / User |
| Bio / Description (Text) | No | Yes (Database Mirror) | TIP API / User |
| Preferred Token (USDC/SOL) | No | Yes (Database Mirror) | TIP API / User |
| Moderation Status (Flag) | No | Yes (Database Mirror) | Moderation System |
Synchronisation & Indexing Guarantees
The apps/indexer service monitors the Solana cluster via WebSocket logs and RPC polling. Whenever a register_tag or update_wallet transaction executes on-chain:
- Transaction Confirmation: The indexer observes the account update at
finalizedcommitment. - PostgreSQL Mirror Update: The indexer performs an idempotent write (
UPSERT) into the PostgreSQL database mirror. - Redis Cache Invalidation: The indexer constructs the exact Redis key for
@tag(tip:devnet:resolve:alice) and issues aDELcommand.
Cache Agreement Protocol
Both apps/api and apps/indexer share the exact buildResolveCacheKey() utility from @tip/core. This guarantees that cache keys written by the API are byte-for-byte identical to the keys invalidated by the indexer.
Out-of-Order Safety
Blockchains can occasionally emit WebSocket account notifications out of order under network jitter or reconnection events.
To prevent stale state overwrites, the TIP indexer compares the Solana Slot Number attached to each account change event:
- If an incoming event has a slot number lower than or equal to the existing mirror row slot, it is silently ignored.
- Only account state with a higher slot number can update the PostgreSQL mirror.
Resilience & Degraded Modes
+-------------------------------------------------------------------+
| Normal Operating Mode |
| Client ──> API ──> Redis (Cache) ──> PostgreSQL Mirror |
+-------------------------------------------------------------------+
│
▼ (API Outage or Maintenance)
+-------------------------------------------------------------------+
| Degraded / Fallback Mode |
| Client ──> Solana RPC (Direct PDA Read via TipClient) |
+-------------------------------------------------------------------+If the TIP API or PostgreSQL mirror experiences an outage:
- Basic tag-to-wallet resolution never breaks.
- Calling
TipClient.resolveOnChain("@alice")bypasses all centralized infrastructure and fetches the verified destination wallet straight from the Solana RPC.