Agent skill
Helius Webhooks Skill
Receive and authenticate Helius Solana webhooks. Use when setting up Helius webhook handlers, checking the authHeader (Authorization header) on incoming requests, or handling enhanced transaction events like NFT_SALE, SWAP and TRANSFER.
Install this skill
npx skills add hookdeck/webhook-skills --skill helius-webhooks
When to Use This Skill
- How do I receive Helius webhooks?
- How do I authenticate Helius webhook requests? (Helius does not sign payloads)
- How do I use the Helius
authHeaderand check theAuthorizationheader? - How do I handle
NFT_SALE,SWAPorTRANSFERenhanced transaction events? - Why am I receiving duplicate Helius webhook events, or why was my webhook auto-disabled?
Authentication (core)
Helius webhooks have no signature: there is no HMAC, no timestamp and no signing secret. The optional authHeader you set when creating the webhook (for example Bearer your-secret-token) is sent verbatim as the Authorization header on every delivery. Compare the whole header value in constant time. The signature field in the payload is the Solana transaction signature, not a webhook signature.
const crypto = require('crypto');
// Hash both sides so timingSafeEqual always gets equal-length buffers
function verifyHeliusAuth(received, expected) {
if (!received || !expected) return false;
const a = crypto.createHash('sha256').update(received).digest();
const b = crypto.createHash('sha256').update(expected).digest();
return crypto.timingSafeEqual(a, b);
}
// Authorization header must equal the authHeader you registered, exactly
verifyHeliusAuth(req.headers.authorization, process.env.HELIUS_AUTH_HEADER);
The body is an array of transactions. Enhanced webhooks give each item a type (NFT_SALE, SWAP, TRANSFER, ...); raw webhooks omit type. Respond 200 quickly (Helius expects it within 1 second) and process asynchronously, and de-duplicate on the transaction signature because deliveries can repeat.
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Common Event Types
Enhanced webhooks label each transaction with a type you choose in transactionTypes (or ANY):
Event (type) | Triggered When | Common Use Cases |
|---|---|---|
NFT_SALE | An NFT is sold on a marketplace | Sales feeds, analytics |
SWAP | A token swap executes | Trading bots, portfolio tracking |
TRANSFER | SOL or tokens move between accounts | Deposit detection, wallet monitoring |
NFT_LISTING | An NFT is listed for sale | Listing alerts |
NFT_MINT | An NFT is minted | Mint tracking |
TOKEN_MINT | A token is minted (limited programs) | Token launch monitoring |
See references/overview.md for the full picture and Helius's transaction types list for every value.
Environment Variables
# Must match the authHeader set on the Helius webhook exactly, e.g. "Bearer <random-token>"
HELIUS_AUTH_HEADER=Bearer your-secret-token
Local Development
For local webhook testing, use Hookdeck CLI:
npx hookdeck-cli listen 3000 helius --path /webhooks/helius
No account required. Provides local tunnel + web UI for inspecting requests. Helius can't reach localhost, so point the webhook at the Hookdeck URL.
Reference Materials
- Overview - What Helius webhooks are, webhook types, common transaction types, payload shape
- Setup - Create a webhook in the Helius dashboard or API and set
authHeader - Verification - Authorization header check, gotchas, retries
Examples
- Express Example - Complete Express.js implementation with tests
- Next.js Example - Next.js App Router implementation with tests
- FastAPI Example - Python FastAPI implementation with tests