NOTIFY Tier Policies: Silent Monitoring for Your Trading Bot's Risky Moves

NOTIFY Tier Policies: Silent Monitoring for Your Trading Bot's Risky Moves

Your trading bot spotted the opportunity — but does your wallet infrastructure know when to let it run and when to quietly flag a move for review? For developers building automated trading bots, arbitrage systems, or algorithmic strategies, the challenge isn't just execution speed. It's knowing which trades should fire instantly, which ones deserve a second look, and which ones should never happen without a human in the loop. WAIaaS's NOTIFY tier policy gives you exactly that middle layer: transactions execute immediately, but you get notified in real time.

The Problem With All-or-Nothing Risk Controls

Most wallet setups for trading bots are binary. Either the bot has full autonomy — which is terrifying at 3am when something misbehaves — or you've locked everything down so tightly that the bot misses opportunities while waiting for manual approval. Neither extreme is workable for serious algo trading.

What you actually want is graduated control. Small, routine trades? Fire instantly, no noise. A swap that's 10x your usual size? Execute it, but ping me right now so I can watch the position. An attempted transfer well above any reasonable threshold? Stop it cold and demand explicit approval before a single satoshi moves.

This is exactly what WAIaaS's 4-tier policy engine is designed for, and the NOTIFY tier is the unsung workhorse of the system.

How the 4-Tier Security Model Works

WAIaaS enforces a SPENDING_LIMIT policy with four tiers that map to transaction value:

INSTANT   — Execute immediately, no notification
NOTIFY    — Execute immediately, send notification
DELAY     — Queue for delay_seconds, then execute (cancellable)
APPROVAL  — Require human approval via WalletConnect/Telegram/Push

The tier is determined automatically based on the transaction amount versus your configured thresholds. Here's what a realistic trading bot policy looks like:

curl -X POST http://localhost:3100/v1/policies \
  -H 'Content-Type: application/json' \
  -H 'X-Master-Password: <password>' \
  -d '{
    "walletId": "<wallet-uuid>",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 10,
      "notify_max_usd": 100,
      "delay_max_usd": 1000,
      "delay_seconds": 300,
      "daily_limit_usd": 500,
      "monthly_limit_usd": 5000
    }
  }'

With this configuration:

The NOTIFY tier is your surveillance layer. Your bot keeps running at full speed, but you have eyes on every move that matters.

Why NOTIFY Matters More Than You Think

When you're running an arb bot or an algorithmic strategy across multiple protocols, unusual transaction sizes are your earliest signal that something is wrong. Maybe your position sizing logic has a bug. Maybe a price oracle fed in a bad value. Maybe someone is replaying a transaction.

The NOTIFY tier catches these situations without interrupting execution. The transaction still goes through — you're not adding latency to your hot path — but you get an immediate alert so you can intervene before the next trade compounds the problem.

This is meaningfully different from the DELAY tier. With DELAY, you've added a 5-minute queue to every transaction in that bracket, which is fine for large, deliberate position changes but completely unworkable for a bot that needs to respond to market conditions in real time. NOTIFY gives you observability without the latency penalty.

The Full Policy Stack for a Trading Bot

A SPENDING_LIMIT policy handles your size-based tiers, but a production trading bot needs more layers. WAIaaS gives you 21 policy types, and several of them are specifically designed for DeFi trading scenarios.

Lock down which tokens can move:

{
  "type": "ALLOWED_TOKENS",
  "rules": {
    "tokens": [
      {
        "address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
        "symbol": "USDC",
        "chain": "solana"
      },
      {
        "address": "So11111111111111111111111111111111111111112",
        "symbol": "SOL",
        "chain": "solana"
      }
    ]
  }
}

ALLOWED_TOKENS is default-deny. If your bot tries to transfer any token not on this list — even accidentally — the transaction is blocked before it reaches the pipeline. This is your first line of defense against logic bugs that try to touch tokens you never intended to trade.

Whitelist the contracts your bot is allowed to call:

{
  "type": "CONTRACT_WHITELIST",
  "rules": {
    "contracts": [
      {
        "address": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",
        "name": "Jupiter",
        "chain": "solana"
      }
    ]
  }
}

Again, default-deny. Your bot can only interact with contracts you've explicitly approved. If a compromised dependency or a buggy trade router tries to call an unknown contract, it's blocked.

Cap perpetual futures leverage and position size:

{
  "type": "PERP_MAX_LEVERAGE",
  "rules": { "maxLeverage": 10 }
}
{
  "type": "PERP_MAX_POSITION_USD",
  "rules": { "maxPositionUsd": 5000 }
}

These are specifically built for strategies running on Hyperliquid or Drift, both of which are integrated as DeFi protocol providers in WAIaaS.

Restrict which markets you're allowed to trade:

{
  "type": "PERP_ALLOWED_MARKETS",
  "rules": { "markets": ["SOL-PERP", "ETH-PERP"] }
}

Executing Trades Through the Pipeline

Every transaction your bot submits goes through WAIaaS's 7-stage pipeline: validate → auth → policy → wait → execute → confirm. The policy stage is where your SPENDING_LIMIT thresholds are evaluated and tier assignment happens. If the transaction hits NOTIFY, it continues through the pipeline immediately while the notification fires asynchronously.

Here's what a typical Jupiter swap looks like from your bot's perspective:

curl -X POST http://127.0.0.1:3100/v1/actions/jupiter-swap/swap \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer wai_sess_<token>" \
  -d '{
    "inputMint": "So11111111111111111111111111111111111111112",
    "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "amount": "1000000000"
  }'

Your bot sends the request. The pipeline validates the session, checks your token whitelist and contract whitelist, evaluates the USD value against your spending tiers, assigns NOTIFY if it's in that bracket, and fires the swap. The notification goes out in parallel. From your bot's perspective, this is functionally identical to an INSTANT transaction — same response time, same execution path.

If the policy engine denies the transaction instead, you get a structured error you can handle cleanly in your code:

{
  "error": {
    "code": "POLICY_DENIED",
    "message": "Transaction denied by SPENDING_LIMIT policy",
    "domain": "POLICY",
    "retryable": false
  }
}

Before You Execute: Dry Run Mode

For a trading bot, testing your logic against real market conditions without actually moving funds is essential. WAIaaS has a dry-run mode built directly into the transaction endpoint:

curl -X POST http://127.0.0.1:3100/v1/transactions/send \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer wai_sess_<token>" \
  -d '{
    "type": "TRANSFER",
    "to": "recipient-address",
    "amount": "0.1",
    "dryRun": true
  }'

Add "dryRun": true to any transaction payload and WAIaaS simulates the full pipeline — including policy evaluation — without submitting anything to the network. This lets you verify that your SPENDING_LIMIT thresholds are behaving as expected and that your NOTIFY tier is triggering at the right amounts before you go live.

Setting Up the Bot Wallet

Getting a trading bot wallet running takes about five minutes:

Step 1: Install the CLI and start the daemon

npm install -g @waiaas/cli
waiaas init
waiaas start

Step 2: Create a wallet and get a session token

curl -X POST http://127.0.0.1:3100/v1/wallets \
  -H "Content-Type: application/json" \
  -H "X-Master-Password: my-secret-password" \
  -d '{"name": "trading-wallet", "chain": "solana", "environment": "mainnet"}'

curl -X POST http://127.0.0.1:3100/v1/sessions \
  -H "Content-Type: application/json" \
  -H "X-Master-Password: my-secret-password" \
  -d '{"walletId": "<wallet-uuid>"}'

Step 3: Apply your SPENDING_LIMIT policy

curl -X POST http://127.0.0.1:3100/v1/policies \
  -H "Content-Type: application/json" \
  -H "X-Master-Password: my-secret-password" \
  -d '{
    "walletId": "<wallet-uuid>",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 10,
      "notify_max_usd": 100,
      "delay_max_usd": 1000,
      "delay_seconds": 300,
      "daily_limit_usd": 500,
      "monthly_limit_usd": 5000
    }
  }'

Step 4: Add your token and contract whitelists (use the JSON examples above, same endpoint, same master auth)

Step 5: Start trading with the session token

import { WAIaaSClient } from '@waiaas/sdk';

const client = new WAIaaSClient({
  baseUrl: 'http://127.0.0.1:3100',
  sessionToken: process.env.WAIAAS_SESSION_TOKEN,
});

const balance = await client.getBalance();
console.log(`${balance.balance} ${balance.symbol}`);

The session token is what your bot uses. The master password stays out of the hot path entirely.

Deploy with Docker for Production

When you're ready to run this in production, Docker handles the infrastructure:

docker run -d \
  --name waiaas \
  -p 127.0.0.1:3100:3100 \
  -v waiaas-data:/data \
  -e WAIAAS_AUTO_PROVISION=true \
  ghcr.io/minhoyoo-iotrust/waiaas:latest

docker exec waiaas cat /data/recovery.key

The daemon binds to 127.0.0.1:3100 by default — not exposed to the public internet. Your bot talks to it over localhost. The data volume persists your wallets, sessions, and policy configuration across container restarts.

The Protocols Your Bot Can Access

WAIaaS integrates 15 DeFi protocol providers, which means your bot can interact with a serious range of venues through a single authenticated session. On Solana: Jupiter for swaps, Drift for perpetuals, Kamino for lending, Jito for staking. Cross-chain bridging through LI.FI and Across. Prediction markets via Polymarket. Yield via Pendle. Perpetuals on Hyperliquid. All of them accessible through the same session token, all of them subject to the same policy engine.

That means your SPENDING_LIMIT policy applies uniformly whether your bot is swapping on Jupiter, opening a position on Drift, or bridging assets via LI.FI. One policy layer covers the entire surface.

What's Next

The NOTIFY tier is one piece of a larger risk management architecture. As you push more volume through your bot, you'll want to layer in RATE_LIMIT to cap transaction frequency, LENDING_LTV_LIMIT if you're using DeFi lending as part of your strategy, and PERP_ALLOWED_MARKETS to prevent any edge case from opening positions in markets you're not tracking.

The full OpenAPI spec is available at http://127.0.0.1:3100/reference once your daemon is running — interactive, explorable, and worth spending time with before you go live.


Explore the codebase and deploy your trading bot wallet: