Skip to main content
This guide walks you through setting up a local development environment using the official template. By the end, you’ll have a running server that receives real-time compliance alerts and serves user data to Wavy Node.
This setup is intended for local development and testing. For production deployments, replace ngrok with your own publicly accessible server and use environment-specific secrets.

Prerequisites

  • Node.js or Bun installed
  • ngrok installed (to expose your local server)
  • A Wavy Node account with a project created
  • An API key from your project

Organization compliance data

Before anything else, configure your organization’s compliance data in the dashboard. Navigate to Management → Organization in the sidebar and fill in the Compliance Data section:
  1. Platform domain — Your platform’s domain. It’s auto-formatted to uppercase (e.g., wavynode.comWAVYNODE).
  2. Tax IDs — The tax identifier for each country where you have active legislation:
This information is required to generate regulatory reports. Without it, reports will not be generated.
CountryFieldExample
Mexico (MX)RFCXAXX010101000
Colombia (CO)NIT900123456-7
El Salvador (SV)NIT0614-123456-001-0
Guatemala (GT)NIT1234567-8

Step 1: Clone and install

git clone https://github.com/wavy-node/integration
cd integration
bun install
You can also use npm install if you prefer Node.js over Bun.

Step 2: Configure environment variables

Copy the template and edit:
cp .env.template .env
Your .env file needs these values:
.env
SECRET=your_32_character_hex_secret
WAVYNODE_API_KEY=ApiKey wavy_your_api_key_here
PROJECT_ID=1
PORT=3001

Generate the SECRET

The SECRET is a 32-character hex string used to sign requests between Wavy Node and your integration. Generate one with:
openssl rand -hex 16
This outputs something like 615d9b7ea991acfa33f823c374c3a062. Save this value — you’ll also need to configure it in the Wavy Node dashboard.
The SECRET in your .env must match the integration_secret configured in your Wavy Node project. If they don’t match, all requests will fail signature verification.

Get your API key

Find your API key in the Wavy Node dashboard under your project’s API Keys section. The format is ApiKey wavy_....
When making API requests, the x-api-key header must include the ApiKey prefix:
x-api-key: ApiKey wavy_your_api_key_here
Sending only the key without the prefix will result in an authentication error.

Step 3: Implement your endpoints

The template includes two endpoints you need to customize:

GET /users/{userId}

Wavy Node calls this endpoint to get user data for compliance reports. Return a JSON object with the user’s information:
// Return user data from your database
{
  givenName: "Maria Guadalupe",
  maternalSurname: "Sánchez",
  paternalSurname: "Rodríguez",
  birthdate: "1992-05-15",
  nationality: "MX",
  phoneNumber: {
    countryCode: "+52",
    phoneNumber: 5512345678
  },
  email: "[email protected]",
  address: {
    country: "MX",
    region: "CDMX",
    city: "Ciudad de México",
    street: "Avenida Insurgentes Sur",
    colonia: "Condesa",
    exteriorNumber: "123",
    interiorNumber: "4B",
    postalCode: "06100"
  },
  mexico: {
    rfc: "ROSM920515XXX",
    curp: "ROSM920515MDFRXXXX",
    actividadEconomica: 612012,
    cuentaRelacionada: "1234567890",
    monedaCuentaRelacionada: 1,
    documentoIdentificacion: {
      tipoIdentificacion: 1,
      numeroIdentificacion: "IDMEX12345678"
    }
  }
}
The mexico object is required only if you have Mexican legislation active in your project. See Endpoints for the full response schema.

POST /webhook

Wavy Node sends real-time notifications when suspicious activity is detected. The template already handles signature verification — you just need to add your business logic:
// Notification payload
{
  type: "notification",
  data: {
    id: 1,
    projectId: 1,
    chainId: 42161,
    address: { userId: "user-123", address: "0x..." },
    txHash: "0x...",
    amount: { value: 1000000000000000000, usd: 3000 },
    inflictedLaws: [{ name: "...", risk: "warn", countryCode: "MX" }]
  }
}

Step 4: Start the server

bun run dev
The server runs at http://localhost:3001.

Step 5: Expose with ngrok

In a separate terminal:
ngrok http 3001
This generates a public URL like https://abc123.ngrok-free.dev.

Step 6: Configure your project in Wavy Node

Update your project with the integration URL and secret. In the dashboard, go to Settings → Integración and fill in:
  • Integration URL — Your ngrok public URL (e.g., https://abc123.ngrok-free.dev)
  • Integration Secret — The same 32-character secret from your .env file
Click Save changes when done.
The integration_secret must be exactly the same as the SECRET in your .env file.

Step 7: Register addresses

Register the wallet addresses you want to monitor, linking them to users in your system:
curl -X POST "https://api.wavynode.com/v1/projects/$PROJECT_ID/addresses" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $WAVYNODE_API_KEY" \
  -d '{
    "address": "0x2c63bbbcc4b40ca0f149717195fea66a8f1a0395",
    "description": "Main wallet",
    "foreign_user_id": "user-123"
  }'
The foreign_user_id is the user’s ID in your system. When Wavy Node needs data for this user, it calls GET /users/user-123 on your integration.
If the address already exists in the project, the foreign_user_id and description are updated instead of creating a duplicate.

Step 8: Test the integration

The template includes a test script that simulates the calls Wavy Node makes to your server. With the server running and ngrok active:
bun run test-integration.ts
The script runs three tests:
  1. GET /users/user-123 — verifies your user data endpoint responds correctly with a valid HMAC signature
  2. POST /webhook — sends a simulated notification with a sample transaction and inflicted laws
  3. Invalid signature — sends a request with a fake signature to verify your middleware rejects it with 401
=== WavyNode Integration Test ===
Server: http://localhost:3001
Secret: 615d9b7e...

--- Testing GET /users/user-123 ---
Status: 200 OK
 GET /users passed

--- Testing POST /webhook ---
Status: 200 OK
 POST /webhook passed

--- Testing invalid signature (should fail with 401) ---
Status: 401 Unauthorized
 Invalid signature correctly rejected

=== Results: 3 passed, 0 failed ===
The third test shows ✅ even though the server returned 401. This is a negative test — it verifies your server correctly rejects unauthorized requests. If it returned 200 instead, that would mean your server accepts any request, which is a security issue.

Compliance reports

Once your integration is running, compliance reports are generated automatically. Here’s how the report lifecycle works:
For Mexican legislation, reports are generated when a user’s monthly transaction total exceeds 210 UMAs (~$24,635 MXN). The threshold is updated automatically based on the current UMA value.
Query your reports via the API:
curl -H "x-api-key: $WAVYNODE_API_KEY" \
  "https://api.wavynode.com/v1/reports?projectId=$PROJECT_ID&period=2026-04&countryCode=MX"

Next steps

Authentication

Understand how HMAC signature verification works.

Endpoints

Full reference for the user data and webhook endpoints.