본문으로 건너뛰기
샘플 앱으로 돌아가기

Streams Webhook Signature Validator

A lightweight Express server that verifies Quicknode Streams webhook HMAC-SHA256 signatures and supports gzip-compressed request bodies.

프론트엔드 프레임워크/라이브러리:
Express
언어:
자바스크립트
빌드 도구/개발 서버:
Node.js
샘플 앱 미리 보기

개요

Quicknode Streams can sign each webhook delivery with an HMAC-SHA256 signature so you can confirm that a request originated from Quicknode and was not tampered with in transit. This sample app is a minimal Express server that shows exactly how to verify those signatures, including the edge case where Streams sends a gzip-compressed body.

The signature is computed over the concatenation of nonce + timestamp + payload (UTF-8), keyed with your Stream's security token. When compression is enabled, Streams signs the uncompressed JSON before gzipping it for transport, so the verifier must run HMAC on the decoded bytes rather than the raw gzip octets. This app uses express.raw() with body-parser's built-in gzip decompression to handle that correctly.

For a detailed walkthrough of the signature verification logic, see the companion guide: How to Validate Incoming Streams Webhook Messages.

Tech Stack

  • Runtime: Node.js (>=16)
  • Framework: Express
  • Language: JavaScript
  • Crypto: Node.js built-in crypto module (HMAC-SHA256)

주요 기능


  • HMAC-SHA256 verification: Validates the x-qn-signature header against a locally computed digest using your Stream security token.
  • Gzip body support: Correctly handles Content-Encoding: gzip requests by running HMAC on the decompressed JSON, not the raw bytes.
  • Timing-safe comparison: Uses crypto.timingSafeEqual to prevent timing attacks during signature comparison.
  • Debug logging: Prints nonce, timestamp, payload preview, and both the computed and provided signatures to aid local debugging.
  • Configurable port: Defaults to 9999; override with the PORT environment variable.

필수 조건


  • Node.js v16 or later installed on your machine.
  • A Quicknode account with at least one Stream configured.
  • The security token from your Stream's Settings tab in the Quicknode dashboard.
  • ngrok (or any tunnel tool) to expose your local server to the internet so Streams can reach it.

프로젝트 구조

streams-webhook-validate-signature/
├── .env.example # Environment variable template
├── .gitignore
├── package.json
├── package-lock.json
└── server.js # Express webhook receiver and HMAC verifier

환경 변수

복사 .env.example ~에 .env and set your Stream security token:

QN_STREAM_SECRET=your_more_than_32_bytes_security_token_here

You can find this token in your Stream's Settings tab at dashboard.quicknode.com/streams.


시작하기

1. Clone the repository

git clone https://github.com/quiknode-labs/streams-webhook-validate-signature.git
cd streams-webhook-validate-signature

2. 종속성 설치

npm 설치

3. Configure environment variables

cp .env.example .env

열기 .env 그리고 설정 QN_STREAM_SECRET to your Stream's security token.

4. Start the server

npm 시작

The server listens on http://localhost:9999/webhook by default. To use a different port:

PORT=3000 npm start

5. Expose with ngrok

Streams needs a publicly accessible URL to deliver webhooks. In a separate terminal:

ngrok http 9999

Copy the HTTPS forwarding URL (e.g. https://abc123.ngrok.io) and set it as your Stream's webhook URL with the /웹훅 path appended:

https://abc123.ngrok.io/webhook

6. Send a test payload

Once the webhook URL is saved, use the Send Payload button in the Streams dashboard to fire a signed test delivery without waiting for real on-chain activity. This works both when creating a new Stream and when editing an existing one. Check your server terminal for the signature debug output to confirm the request was received and verified.

API Endpoints

방법Path설명
게시물/웹훅Receives and verifies a Streams webhook delivery

Expected request headers

Header설명
x-qn-nonceRandom nonce included in the signature input
x-qn-timestampUnix timestamp included in the signature input
x-qn-signatureHex-encoded HMAC-SHA256 digest to verify

Responses

상태Meaning
200Signature verified successfully
400Required headers are missing
401Signature verification failed
500Server misconfiguration (missing secret) or processing error

미리 보기

미리 보기

기여 및 피드백
여러분의 의견을 듣고 싶으며, 이 샘플 앱에 대한 모든 기여를 환영합니다!
문제를 신고하거나 피드백을 공유하려면, 다음에서 GitHub 이슈를 생성해 주세요. qn-가이드-예시 저장소.
기여하시려면 다음 단계를 따르세요:
  1. 저장소를 포크하기
  2. 기능 브랜치 생성:
    git checkout -b feature/amazing-feature
  3. 변경 사항을 커밋하세요:
    git commit -m "멋진 기능 추가"
  4. 브랜치를 푸시하세요:
    git push origin feature/amazing-feature
  5. 풀 리퀘스트를 제출하세요.