YOUR KEYS. YOUR CAPITAL.

EXPLORE

OverviewFind walletLiquidity poolsTokenNew pool radarWatchlist

YOUR CAPITAL

Wallet profileTransactionsAutomationSwap

ECOSYSTEM

Network statusDocumentationGuidesArticlesDevelopersSettings
BANIPOOL/Documentation

Search pools

Paste or type a pool address, pool ID, token address, or token symbol. All networks are searched at once.

A token address shows pools that use that token.

Create new pool

Connect wallet

Choose a wallet on this device or connect your phone wallet with a QR code.

Detected wallets

No browser wallet detected. Use WalletConnect for a wallet on your phone.

Signing in to view your portfolio does not authorize transactions.

Documentation

Webhook

Receive the same events as SSE via HTTP POST to your server, signed with HMAC-SHA256.

Registering an endpoint

  • Developer Portal → Webhooks → Add subscription: a public HTTPS URL (port 443) and the subscribed events.
  • The secret is shown once; store it in your server environment.
  • A 2xx response = accepted. Failure → retried up to 8 times with backoff; after that the status is dead. Redirects are not followed.

Verifying the signature

Headers: x-webhook-id (event ID, for deduplication), x-webhook-timestamp (Unix seconds), x-webhook-signature (v1=<hex>). Signature = HMAC-SHA256 with the secret over timestamp + "." + raw body. Compare in constant time and reject timestamps outside ±5 minutes.

ts
import { createHmac, timingSafeEqual } from 'node:crypto';
import express from 'express';

const app = express();
app.post('/banipool-webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const ts = req.header('x-webhook-timestamp') ?? '';
  const sig = (req.header('x-webhook-signature') ?? '').replace(/^v1=/, '');
  const expected = createHmac('sha256', process.env.BANIPOOL_WEBHOOK_SECRET!)
    .update(`${ts}.${req.body.toString('utf8')}`).digest('hex');
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
  const ok = fresh && sig.length === expected.length && timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
  if (!ok) return res.status(401).end();
  const event = JSON.parse(req.body.toString('utf8')); // { id, type, data, createdAt }
  // Deduplikasi: simpan event.id yang sudah diproses
  console.log(event.type, event.data);
  res.status(204).end();
});
app.listen(3000);
python
import hmac, hashlib, os, time, json
from flask import Flask, request, abort

app = Flask(__name__)
SECRET = os.environ["BANIPOOL_WEBHOOK_SECRET"].encode()

@app.post("/banipool-webhook")
def webhook():
    ts = request.headers.get("x-webhook-timestamp", "")
    sig = request.headers.get("x-webhook-signature", "").removeprefix("v1=")
    raw = request.get_data()
    expected = hmac.new(SECRET, f"{ts}.".encode() + raw, hashlib.sha256).hexdigest()
    if abs(time.time() - int(ts or 0)) > 300 or not hmac.compare_digest(sig, expected):
        abort(401)
    event = json.loads(raw)  # {id, type, data, createdAt}
    print(event["type"], event["data"])
    return "", 204