Polls API Integration Example

1 Scope & Goal

Enable a client application to surface live Polls data that originates in Common.

  • Read-only access to Poll objects

  • Periodic refresh of results for live tallies


2 Commonwealth API โ€“ Polls Contract

Purpose
Sample API Path
Core Fields Returned

Get polls for a thread

POST /api/v1/GetPolls

id, prompt, options[], ends_at, created_at, updated_at, votes[]

Get votes for a specific poll

POST /api/v1/GetPollVotes

id, poll_id, option, address, user_id, weight, created_at

Create a new poll

POST /api/v1/CreatePoll

id, prompt, options[], ends_at, thread_id, community_id

Vote on a poll

POST /api/v1/CreatePollVote

Vote object: poll_id, option, address, community_id

Details:

  • Protocol: tRPC over HTTP

  • Authentication: API Key (x-api-key) + Address (address)

  • Rate Limits:

    • Tier 1: 10 req/min

    • Tier 2: 60 req/min

    • Headers: RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

  • Base URL: /api/v1/

  • Version: 2.0.0


3 Data Models

interface Poll {
  id: number;
  community_id: string;
  thread_id: number;
  prompt: string;
  options: string[];
  ends_at: Date | null;
  created_at: Date;
  updated_at: Date;
  votes?: Vote[];
}

interface Vote {
  id: number;
  poll_id: number;
  option: string;
  address: string;
  user_id: number;
  author_community_id?: string;
  community_id: string;
  calculated_voting_weight?: string;
  created_at: Date;
  updated_at: Date;
}

Notes:

  • Polls are thread-scoped

  • Vote weights calculated server-side

  • ends_at null = infinite


4 Polling Strategy

  1. Bootstrap

    • On startup, call GetPolls for target threads

    • Cache by poll.id

  2. Periodic Refresh

    • Every 60s: re-fetch GetPolls

    • Compare updated_at to detect changes

  3. Vote Fetch

    • On change or first load, call GetPollVotes

    • Aggregate client-side

  4. Rate-Limit Handling

    • On 429, back off exponentially: 60 โ†’ 120 โ†’ 240 โ†’ 300s

  5. Merge & Emit

    • Update cache and fire polls.updated event

  6. Housekeeping

    • Stop polling when polls closed and view hidden

No incremental endpoint available; rely on updated_at diffing.


5 Authentication & Headers

const headers = {
  'x-api-key': 'YOUR_API_KEY',
  'address': 'USER_WALLET_ADDRESS',
  'Content-Type': 'application/json'
};

Include both headers on every call.


6 Example Client Data Model

interface PollOption {
  id: string;
  text: string;
  count: number;
  weight: string;
}

interface ExamplePoll {
  pollId: number;
  threadId: number;
  communityId: string;
  prompt: string;
  options: PollOption[];
  startTime: string;
  endTime: string | null;
  state: 'active' | 'closed';
  totalVotes: number;
  totalWeight: string;
  updatedAt: string;
}

Aggregation Logic:

function aggregateVotes(votes: Vote[]): PollOption[] {
  const map = new Map<string, {count: number; weight: bigint}>();
  votes.forEach(v => {
    const cur = map.get(v.option) || {count: 0, weight: 0n};
    const w = v.calculated_voting_weight ? BigInt(v.calculated_voting_weight) : 1n;
    map.set(v.option, {count: cur.count + 1, weight: cur.weight + w});
  });
  return Array.from(map.entries()).map(([text, data], i) => ({
    id: `${i}`, text, count: data.count, weight: data.weight.toString()
  }));
}

Cache in IndexedDB/localStorage for fast cold starts.


7 UX Hooks

Event
UI Behavior

polls.loading

Show skeleton/shimmer

polls.updated

Animate count change; toast optional

Poll expired

Mark closed, disable voting

Rate limited

Show back-off indicator


8 Testing Checklist

  1. Unit: Mock tRPC, test aggregation & back-off

  2. Integration: Staging API keys, multiple poll states

  3. Load: Simulate 10+ clients @60s intervals

  4. Auth: Invalid/missing headers โ†’ 401

  5. Offline/Online: Cache persists; first refresh uses cache


9 Sample Implementation

Extract core patterns into service and manager classes.

CommonwealthPollService

// Handles tRPC calls with rate-limit error handling

PollManager

// Coordinates periodic refresh, back-off, caching, and events

10 Action Items

  1. Backend: Obtain API keys; identify thread IDs

  2. Frontend: Build tRPC wrapper & aggregation utils

  3. DevOps: Monitor errors, rate limits, latency

  4. Docs: Publish API key guide & thread discovery

Last updated

Was this helpful?