5.3 KiB
5.3 KiB
title, tags, created
| title | tags | created | |||
|---|---|---|---|---|---|
| ScannerIntent (Scanner DB model) |
|
2026-05-30 |
ScannerIntent
SQLite row in the AMN Pay Scanner's intents table. One row per payment intent registered by the backend. This is internal scanner state — it is not a Mongoose model and lives in a separate SQLite database (/data/scanner.db).
Schema
CREATE TABLE intents (
intent_id TEXT PRIMARY KEY,
chain_id INTEGER NOT NULL,
chain_type TEXT NOT NULL DEFAULT 'evm',
token_address TEXT NOT NULL,
destination TEXT NOT NULL,
amount TEXT NOT NULL,
payment_reference TEXT NOT NULL,
topic_ref TEXT,
status TEXT NOT NULL DEFAULT 'pending',
callback_url TEXT NOT NULL,
callback_secret TEXT NOT NULL,
confirmations_required INTEGER NOT NULL DEFAULT 12,
tx_hash TEXT,
log_index INTEGER,
block_number INTEGER,
confirmations INTEGER NOT NULL DEFAULT 0,
salt TEXT NOT NULL,
webhook_delivered_at TEXT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
Fields
| Field | Type | Description |
|---|---|---|
intent_id |
TEXT PK | Caller-supplied unique ID (typically the backend Payment _id) |
chain_id |
INTEGER | Numeric chain ID. EVM standard (56, 137, 1, 42161, 8453), Tron (728126428), TON (1100) |
chain_type |
TEXT | evm / tron / ton. Determines which worker handles this intent |
token_address |
TEXT | ERC20 / TRC20 contract address. EVM/Tron: lowercase 0x hex. TON: exact base64url |
destination |
TEXT | Recipient wallet address. EVM/Tron: lowercase 0x hex. TON: base64url (case-sensitive) |
amount |
TEXT | Required amount in smallest token unit (wei / 10^decimals), stored as base-10 integer string |
payment_reference |
TEXT | 8-byte hex EVM payment reference (0x + 16 hex chars). Derived as last8(keccak256(intentId + salt + destination)) |
topic_ref |
TEXT | keccak256(paymentReferenceBytes) — matches Topics[1] in EVM logs. Pre-computed for indexed DB lookup. NULL for Tron/TON |
status |
TEXT | Intent lifecycle state (see below) |
callback_url |
TEXT | URL the scanner POSTs to on confirmation |
callback_secret |
TEXT | HMAC-SHA256 key for webhook signature. Never returned in API responses |
confirmations_required |
INTEGER | Accepted confirmation floor for the intent. Defaults to chain config and cannot be lowered below the chain floor by the create-intent request |
tx_hash |
TEXT NULL | Transaction hash once a matching transfer is detected |
log_index |
INTEGER NULL | Log position within the transaction (EVM only; 0 for Tron/TON) |
block_number |
INTEGER NULL | Block number (EVM/Tron) or Unix timestamp seconds (TON) when the tx was seen |
confirmations |
INTEGER | Current confirmation depth while confirming; capped at confirmations_required once the intent is confirmed |
salt |
TEXT | 32-byte random hex. Combined with intent_id and destination to derive payment_reference. Prevents reference collisions across retried payments |
webhook_delivered_at |
TEXT NULL | RFC3339 timestamp when the webhook was successfully delivered. Used for startup crash recovery |
created_at / updated_at |
DATETIME | UTC timestamps |
Status values
| Status | Description |
|---|---|
pending |
Registered; scanner is watching for a matching on-chain transfer |
confirming |
EVM only — matching tx seen, waiting for confirmations_required blocks |
confirmed |
Payment confirmed; webhook delivery attempted |
expired |
TTL exceeded while still in pending or confirming |
webhook_failed |
All webhook delivery retries exhausted; manual retry or periodic auto-retry needed |
Indexes
CREATE INDEX idx_intents_status ON intents(status);
CREATE INDEX idx_intents_chain_status ON intents(chain_id, status);
CREATE INDEX idx_intents_payment_ref ON intents(payment_reference);
CREATE INDEX idx_intents_topic_ref ON intents(topic_ref);
CREATE UNIQUE INDEX idx_intents_tx_log ON intents(tx_hash, log_index)
WHERE tx_hash IS NOT NULL;
idx_intents_topic_ref is the performance-critical index — the EVM scanner's inner loop does a single indexed lookup per log entry.
The unique index on (tx_hash, log_index) prevents two intents being confirmed from the same on-chain event (double-spend protection).
Migrations
Three additive migrations run at startup (idempotent):
ADD COLUMN topic_ref TEXT— added after initial schemaADD COLUMN chain_type TEXT NOT NULL DEFAULT 'evm'— added for Tron/TON supportADD COLUMN webhook_delivered_at TEXT— added for crash recovery
A backfill pass recomputes topic_ref for existing EVM intents that had it as NULL.
Related
- Scanner Architecture
- Scanner API
- Payment Flow - Scanner
- Payment — the backend MongoDB model that triggers intent creation