Webhook handling SDK for the Floyd Blockchain API
npm install @tormentalabs/floyd-webhooks

Webhook handling SDK for the Floyd Blockchain API.
- Signature verification - HMAC-SHA256 validation
- Timestamp validation - Replay attack prevention
- Type-safe events - Full TypeScript support
- Framework adapters - Express, raw Node.js HTTP
- Event routing - Subscribe to specific event types
- Testing utilities - Generate signed test events
``bash`
npm install @tormentalabs/floyd-webhooks
`typescript
import express from 'express';
import { WebhookHandler } from '@tormentalabs/floyd-webhooks';
const app = express();
const webhooks = new WebhookHandler({
secret: process.env.FLOYD_WEBHOOK_SECRET,
});
// Type-safe event handlers
webhooks.on('asset.created', async (event) => {
console.log(New asset: ${event.data.name});
});
webhooks.on('asset.blockchain.confirmed', async (event) => {
console.log(Confirmed: ${event.data.transactionHash});
});
webhooks.on('asset.transferred', async (event) => {
console.log(Transferred from ${event.data.previousOwner});
});
// Handle all events
webhooks.onAny(async (event) => {
await logToAuditTrail(event);
});
// Express middleware
app.post('/webhooks',
express.raw({ type: 'application/json' }),
async (req, res) => {
try {
await webhooks.handleRequest(
req.body,
req.headers['x-floyd-signature'] as string
);
res.json({ received: true });
} catch (err) {
res.status(400).json({ error: err.message });
}
}
);
`
`typescript
import { createExpressMiddleware } from '@tormentalabs/floyd-webhooks';
app.post('/webhooks',
express.raw({ type: 'application/json' }),
createExpressMiddleware({
secret: process.env.FLOYD_WEBHOOK_SECRET,
onEvent: async (event, req, res) => {
console.log(Received: ${event.type});`
},
onError: async (error, req, res) => {
console.error('Webhook error:', error);
},
})
);
`typescript
import { createServer } from 'node:http';
import { createNodeHttpHandler } from '@tormentalabs/floyd-webhooks';
const handler = createNodeHttpHandler({
secret: process.env.FLOYD_WEBHOOK_SECRET,
onEvent: async (event) => {
console.log(Received: ${event.type});
},
});
const server = createServer(handler);
server.listen(3000);
`
`typescript
import { verifySignature, parseSignatureHeader } from '@tormentalabs/floyd-webhooks';
// Parse signature header
const { timestamp, signature } = parseSignatureHeader(
req.headers['x-floyd-signature']
);
// Verify manually
verifySignature(
{ payload: req.body, signature, timestamp },
secret,
{ tolerance: 300 } // 5 minutes
);
`
`typescript`
type WebhookEventType =
| 'asset.created'
| 'asset.updated'
| 'asset.deleted'
| 'asset.transferred'
| 'asset.blockchain.pending'
| 'asset.blockchain.processing'
| 'asset.blockchain.confirmed'
| 'asset.blockchain.failed'
| 'asset.accessory.attached'
| 'asset.accessory.detached'
| 'wallet.created'
| 'wallet.suspended'
| 'wallet.activated'
| 'wallet.revoked';
`typescript
import {
SignatureVerificationError,
TimestampError,
PayloadParseError,
} from '@tormentalabs/floyd-webhooks';
try {
await webhooks.handleRequest(payload, signature);
} catch (error) {
if (error instanceof SignatureVerificationError) {
// Invalid signature
} else if (error instanceof TimestampError) {
// Timestamp too old (possible replay attack)
} else if (error instanceof PayloadParseError) {
// Invalid JSON
}
}
`
`typescript
import {
generateSignedPayload,
generateAssetCreatedEvent,
generateBlockchainConfirmedEvent,
} from '@tormentalabs/floyd-webhooks/testing';
// Generate signed payload for supertest
const { body, headers } = generateSignedPayload(
'asset.created',
{ id: 'test-123', name: 'Test Asset' },
'test-secret'
);
const response = await request(app)
.post('/webhooks')
.set(headers)
.send(body);
// Generate typed events
const event = generateAssetCreatedEvent({
name: 'Custom Asset',
});
const confirmedEvent = generateBlockchainConfirmedEvent({
transactionHash: '0x123...',
});
``
- @tormentalabs/floyd-sdk - Main API client
- @tormentalabs/floyd-types - TypeScript definitions
MIT