Skip to main content

Overview

Webhooks allow you to receive real-time notifications when events occur in the ZKScore system.

Supported Events

Score Events

  • score.updated: User score changed
  • score.calculated: New score calculated
  • score.breakdown.updated: Score breakdown changed

Achievement Events

  • achievement.claimed: User claimed an achievement
  • achievement.progress.updated: Achievement progress changed
  • achievement.created: New achievement created

Identity Events

  • identity.minted: New identity minted
  • identity.activated: Identity activated
  • identity.updated: Identity information updated

Attestation Events

  • attestation.created: New attestation created
  • attestation.revoked: Attestation revoked
  • attestation.verified: Attestation verified

Webhook Payload

All webhook payloads follow this structure:
{
  "id": "evt_123456789",
  "type": "score.updated",
  "created": "2024-01-15T10:30:00Z",
  "data": {
    "user": "alice.zks",
    "old_score": 750,
    "new_score": 800,
    "category": "defi"
  }
}

Setting Up Webhooks

// Create webhook endpoint
app.post('/webhooks/zkscore', (req, res) => {
  const { type, data } = req.body;
  
  switch (type) {
    case 'score.updated':
      handleScoreUpdate(data);
      break;
    case 'achievement.claimed':
      handleAchievementClaim(data);
      break;
  }
  
  res.status(200).send('OK');
});

function handleScoreUpdate(data) {
  console.log(`Score updated for ${data.user}: ${data.old_score}${data.new_score}`);
  // Update your application state
}

Webhook Security

Signature Verification

const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return signature === `sha256=${expectedSignature}`;
}

// In your webhook handler
app.post('/webhooks/zkscore', (req, res) => {
  const signature = req.headers['x-zkscore-signature'];
  const payload = JSON.stringify(req.body);
  
  if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process webhook
});

Best Practices

  1. Verify Signatures: Always verify webhook authenticity
  2. Handle Duplicates: Implement idempotency
  3. Process Asynchronously: Use queues for heavy processing
  4. Log Events: Keep audit trails
  5. Test Thoroughly: Use webhook testing tools