> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wavynode.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Setup with template

> Step-by-step guide to set up a local development environment for your Wavy Node integration using the official template.

This guide walks you through setting up a local development environment using the [official template](https://github.com/wavy-node/integration). By the end, you'll have a running server that receives real-time compliance alerts and serves user data to Wavy Node.

<Note>
  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.
</Note>

## Prerequisites

* [Node.js](https://nodejs.org/) or [Bun](https://bun.sh/) installed
* [ngrok](https://ngrok.com/) installed (to expose your local server)
* A [Wavy Node](https://wavynode.com/dashboard) 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.com` → `WAVYNODE`).
2. **Tax IDs** — The tax identifier for each country where you have active legislation:

<Warning>
  This information is required to generate regulatory reports. Without it, reports will not be generated.
</Warning>

| Country          | Field | Example             |
| ---------------- | ----- | ------------------- |
| Mexico (MX)      | RFC   | `XAXX010101000`     |
| Colombia (CO)    | NIT   | `900123456-7`       |
| El Salvador (SV) | NIT   | `0614-123456-001-0` |
| Guatemala (GT)   | NIT   | `1234567-8`         |

## Step 1: Clone and install

```bash theme={null}
git clone https://github.com/wavy-node/integration
cd integration
bun install
```

<Note>
  You can also use `npm install` if you prefer Node.js over Bun.
</Note>

## Step 2: Configure environment variables

Copy the template and edit:

```bash theme={null}
cp .env.template .env
```

Your `.env` file needs these values:

```bash .env highlight={2} theme={null}
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:

```bash theme={null}
openssl rand -hex 16
```

This outputs something like `615d9b7ea991acfa33f823c374c3a062`. Save this value — you'll also need to configure it in the Wavy Node dashboard.

<Warning>
  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.
</Warning>

### 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_...`.

<Warning>
  When making API requests, the `x-api-key` header must include the `ApiKey` prefix:

  ```highlight={1} theme={null}
  x-api-key: ApiKey wavy_your_api_key_here
  ```

  Sending only the key without the prefix will result in an authentication error.
</Warning>

## Step 3: Implement your routes

The template includes two routes on the same server that 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:

```typescript theme={null}
// 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: "maria.guadalupe@example.com",
  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"
    }
  }
}
```

<Note>
  The `mexico` object is required only if you have Mexican legislation active in your project. See [Endpoints](/integrations/endpoints) for the full response schema.
</Note>

### `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:

```typescript theme={null}
// 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

```bash theme={null}
bun run dev
```

The server runs at `http://localhost:3001`.

## Step 5: Expose with ngrok

In a separate terminal:

```bash theme={null}
ngrok http 3001
```

This generates a public URL like `https://abc123.ngrok-free.dev`.

```mermaid theme={null}
flowchart LR
    WN[Wavy Node] -->|HTTPS| NG[ngrok URL]
    NG -->|tunnel| LS[localhost:3001]
```

## 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`). This is the single base URL for your server — Wavy Node appends `/users/{id}` and `/webhook` automatically.
* **Integration Secret** — The same 32-character secret from your `.env` file

Click **Save changes** when done.

<Warning>
  Do not include route paths in the integration URL. Use `https://abc123.ngrok-free.dev`, not `https://abc123.ngrok-free.dev/webhook`.
</Warning>

<Warning>
  The `integration_secret` must be exactly the same as the `SECRET` in your `.env` file.
</Warning>

## Step 7: Register addresses

Register the wallet addresses you want to monitor, linking them to users in your system:

```bash theme={null}
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.

<Tip>
  If the address already exists in the project, the `foreign_user_id` and `description` are updated instead of creating a duplicate.
</Tip>

## 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:

```bash theme={null}
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

```bash theme={null}
=== 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 ===
```

<Tip>
  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.
</Tip>

## Compliance reports

Once your integration is running, compliance reports are generated automatically. Here's how the report lifecycle works:

```mermaid theme={null}
flowchart TD
    A[Wavy Node monitors registered addresses] --> B[Transactions detected and stored with USD value]
    B --> C{Monthly cron - 1st of each month}
    C --> D[Group transactions by user]
    D --> E{User total > 210 UMAs?}
    E -->|Yes| F[GET /users/foreign_user_id]
    F --> G[Generate compliance XML]
    G --> H[Upload report to storage]
    H --> I[Notify project admins by email]
    E -->|No| J[No report needed]
```

<Note>
  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.
</Note>

Query your reports via the API:

```bash theme={null}
curl -H "x-api-key: $WAVYNODE_API_KEY" \
  "https://api.wavynode.com/v1/reports?projectId=$PROJECT_ID&period=2026-04&countryCode=MX"
```

## Next steps

<CardGroup cols={2}>
  <Card title="Authentication" icon="lock" href="/integrations/authentication">
    Understand how HMAC signature verification works.
  </Card>

  <Card title="Endpoints" icon="plug" href="/integrations/endpoints">
    Full reference for the user data and webhook endpoints.
  </Card>
</CardGroup>
