Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hookah

Hookah is a Radix DLT event monitoring and webhook delivery platform. It lets developers authenticate with Radix ROLA, register event triggers, and receive webhook deliveries when matching on-ledger events appear in the transaction stream.

What Is In This Repo

This is a TypeScript monorepo managed with pnpm and Turborepo.

Path Purpose
apps/dashboard Next.js app for authentication, trigger management, webhooks, and JSON-RPC/tRPC endpoints
apps/streamer Long-running worker that follows Radix transactions and dispatches matching webhook deliveries
apps/webhook-test-server Local helper for testing webhook delivery
packages/api Effect-based application services, tRPC routers, auth, trigger matching, webhook execution, and transaction-stream handling
packages/db Drizzle schema and migrations
packages/domain Shared domain schemas and auth payload types
packages/radix Local Radix utility scripts built on radix-web3.js
packages/sdk Public TypeScript SDK for Hookah clients
packages/sbor-ez-mode SBOR helper package used by Radix event tooling
www Docusaurus documentation site
e2e End-to-end utilities and tests

Architecture

Hookah has two primary runtime processes:

  • Dashboard: serves the web app, auth routes, tRPC, and JSON-RPC endpoints. It also runs database migrations during deployment startup.
  • Streamer: reads Radix transaction pages, transforms events, finds matching triggers, executes webhooks directly, writes execution logs, and advances stream checkpoints only after processing succeeds.

Shared infrastructure:

  • PostgreSQL stores users, sessions, webhooks, triggers, logs, and stream checkpoints.
  • Redis stores the trigger registry used by the transaction stream handler.
  • Radix Gateway and radix-web3.js provide network reads, ROLA support, and local script transaction helpers.

Diagrams

System Architecture

flowchart LR
  browser["Dashboard browser"]
  sdk["External app using hookah-sdk"]
  jsonrpc["JSON-RPC client"]

  dashboard["Next.js dashboard app"]
  api["tRPC and JSON-RPC routes"]
  effects["Effect application services"]
  db[(PostgreSQL)]
  redis[(Redis trigger registry)]
  streamer["Streamer worker"]
  gateway["Radix Gateway"]
  webhook["External webhook endpoints"]

  browser --> dashboard
  dashboard --> api
  sdk --> api
  jsonrpc --> api

  api --> effects
  effects --> db
  effects --> redis
  effects --> gateway

  streamer -->|read transaction pages| gateway
  streamer -->|load webhooks and write logs| db
  streamer -->|load active triggers| redis
  streamer -->|POST event payloads| webhook
  streamer -->|advance checkpoints| db
Loading

Authentication Flow

sequenceDiagram
  actor User
  participant Dashboard
  participant Wallet as Radix wallet
  participant API as Auth route
  participant Auth as AuthService
  participant Rola as RolaService
  participant DB as PostgreSQL

  User->>Dashboard: Open login
  Dashboard->>API: auth.generateChallenge
  API->>Auth: createChallenge
  Auth->>DB: Store challenge
  API-->>Dashboard: Challenge
  Dashboard->>Wallet: Request ROLA proof
  Wallet-->>Dashboard: Signed persona proof
  Dashboard->>API: auth.signInWithRola
  API->>Auth: Verify challenge and proof
  Auth->>DB: Read and consume challenge
  Auth->>Rola: Verify signed challenge
  Auth->>DB: Upsert user and create session
  API-->>Dashboard: Set session cookie
Loading

Create Webhook Flow

sequenceDiagram
  actor User
  participant Dashboard
  participant Action as Server action
  participant API as Webhook router
  participant Service as CreateWebhookService
  participant DB as PostgreSQL

  User->>Dashboard: Submit webhook form
  Dashboard->>Action: createWebhook form action
  Action->>Action: Validate form fields
  Action->>API: webhook.create
  API->>Service: createWebhookProgram
  Service->>Service: Normalize URL and headers
  Service->>DB: Insert webhook definition
  DB-->>Service: Stored webhook
  Service-->>API: Public webhook
  API-->>Action: Success
  Action-->>Dashboard: Revalidate dashboard data
Loading

Webhook Trigger Flow

sequenceDiagram
  participant Gateway as Radix Gateway
  participant Streamer
  participant Redis as Redis trigger registry
  participant Matcher as TriggerMatcherService
  participant DB as PostgreSQL
  participant Executor as WebhookExecuterService
  participant Webhook as External webhook

  Streamer->>Gateway: Read transactions from checkpoint
  Gateway-->>Streamer: Transaction page
  Streamer->>Streamer: Transform transaction events
  Streamer->>Redis: Load candidate triggers by event rules
  Redis-->>Streamer: Active triggers
  Streamer->>Matcher: Match events and conditions
  Matcher-->>Streamer: Event matches
  Streamer->>DB: Load webhook definitions
  Streamer->>Executor: Execute matching webhooks
  Executor->>Webhook: POST event payload
  Webhook-->>Executor: Delivery response
  Streamer->>DB: Write execution logs
  Streamer->>DB: Advance stream checkpoint after processing
Loading

SDK Usage Flow

sequenceDiagram
  participant App as SDK consumer app
  participant SDK as hookah-sdk
  participant Rola as SDK ROLA service
  participant API as Hookah tRPC API
  participant DB as PostgreSQL

  App->>SDK: createHookahSdk with public key and signer
  App->>SDK: auth
  SDK->>API: auth.generateChallenge
  API->>DB: Store challenge
  API-->>SDK: Challenge
  SDK->>Rola: Build persona and sign challenge
  Rola-->>SDK: Signed ROLA proof
  SDK->>API: auth.signInWithRola
  API->>DB: Upsert user and create session
  API-->>SDK: Auth success and session cookie
  App->>SDK: getTrpcClient
  SDK-->>App: Authenticated tRPC client
  App->>API: Manage webhooks, triggers, and logs
Loading

Requirements

  • Node.js 20.9.0 or newer
  • pnpm 11.7.0
  • PostgreSQL for local persistence
  • Redis for trigger registry and runtime cache

Local Setup

Install dependencies:

pnpm install

Create a local environment file:

cp .env.example .env

Fill in the local values you need. Keep real credentials out of committed files. pnpm dev loads .env before starting the local processes. For one-off commands outside the root dev script, load the file into your shell first:

set -a
source .env
set +a

Start local infrastructure:

docker compose up -d postgres redis
pnpm db:migrate

Run the dashboard and streamer dev servers:

pnpm dev

The dashboard runs at http://localhost:3000. The streamer runs in the same terminal through Turborepo and processes live Radix transaction streams.

Run individual processes when needed:

pnpm dev:dashboard
pnpm dev:streamer

Run the docs site at http://localhost:3003:

pnpm dev:docs

Useful local commands:

pnpm dev
pnpm dev:dashboard
pnpm dev:streamer
pnpm dev:docs
pnpm run check-types
pnpm run test
pnpm run build
pnpm run ci

Database commands:

pnpm db:generate
pnpm db:migrate
pnpm db:studio

Radix utility commands:

pnpm radix:setup
pnpm radix:get-xrd
pnpm radix:send-early
pnpm radix:generate-mnemonic

Environment

Start from .env.example. The core runtime variables are:

Variable Purpose
DATABASE_URL PostgreSQL connection string used by dashboard, streamer, and db scripts
REDIS_URL Redis connection string used by trigger registry and streamer runtime
HOOKAH_URL Public dashboard/API base URL used by server-side services and SDK config
NEXT_PUBLIC_APP_URL Browser-facing dashboard origin
EXPECTED_ORIGIN Optional explicit origin for auth and CORS checks
RADIX_NETWORK_ID 1 for Mainnet, 2 for Stokenet
DAPP_DEFINITION_ADDRESS Server-side Radix dApp definition address for the selected network
NEXT_PUBLIC_RADIX_NETWORK_ID Browser-side Radix network id for Radix Connect
NEXT_PUBLIC_DAPP_DEFINITION_ADDRESS Browser-side dApp definition address for Radix Connect
AUTH_SECRET Session/authentication secret; required in production
REINDEX_TRIGGERS_ON_STARTUP Set to true to rebuild the Redis trigger index when streamer starts

Docker deployment helpers also read DATABASE_URL_DEV, REDIS_URL_DEV, DATABASE_URL_PROD, and REDIS_URL_PROD. E2E and Radix utility variables are documented in .env.example next to the commands that need them.

Production secrets should live in your deployment secret store, not in this repository.

Testing And Quality Gates

The main gate is:

pnpm run ci

It runs formatting checks, linting, type checks, non-e2e tests, and builds. E2E tests are kept separate because they require configured external services and Radix test accounts.

Local E2E runs load .envrc and .env before starting tests:

pnpm e2e:local

For a full local E2E run, configure Radix test keys and a public webhook receiver. SDK webhook delivery tests require NGROK_AUTH_TOKEN so the test webhook server can be exposed through ngrok, or SDK_TEST_WEBHOOK_URL pointing at another public HTTPS receiver. Without one of those values, the SDK webhook delivery tests are skipped because localhost webhook URLs are rejected by the API safety checks.

GitHub Actions runs the same gate on pushes and pull requests, plus pnpm audit --audit-level moderate.

Security

See SECURITY.md. Do not commit real private keys, session secrets, database credentials, Redis passwords, npm tokens, or webhook credentials. Use .env.example for names and blank placeholders only.

Contributing

See CONTRIBUTING.md.

License

MIT. See LICENSE.

About

Resources

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages