Skip to main content

Overview

Every transaction is scored by a deterministic risk engine — no LLM in the verdict path. The engine is a pure function: the same transaction, the same behavioral snapshot, and the same timestamp always produce the same score, verdict, and reasons, on any machine. It lives in a shared package (zhentan-screening) and runs inside the agent runtime — the same service that holds the signing key, which is why an unscreened transaction can never be signed. The flow: the server assembles your behavioral snapshot (learned patterns + your limits + your rules), attaches it to the transaction as a screening job, and the runtime computes the verdict. With the runtime co-located this completes in milliseconds — the propose response is still synchronous.

How a score is built

A score starts at 0 and signals add (or subtract) points. The total is clamped to 0–100 and mapped through your thresholds: Both thresholds are yours to tune per wallet — with one guardrail: the approve threshold is capped at 40 server-side, so the signals below that carry 40+ points can never be configured into auto-approving.

Every scoring signal

Recipient

Time windows

Hour and day checks are independent — a Sunday 3 AM transaction collects both.

Limits and velocity

Token and behavior

Swaps, approvals, and wallet changes

Swaps and token approvals have no payment recipient (the target is a router or token contract), so recipient signals are skipped and kind-specific ones apply instead:

Your custom rules

Rules you set with the agent (amount caps per token, address blocks/allows, time restrictions) each add their own configured delta — positive or negative — when they match.

Hard floors

Scores are arithmetic, and arithmetic can be gamed — a generous rule delta or a loose threshold could otherwise cancel a serious signal. Three outcomes are therefore enforced on the verdict itself, after all math, and no configuration can relax them:
  1. A blocked recipient always BLOCKs — even if rule deltas drag the score to 0.
  2. An unvalidated owner/configuration change never auto-approves — rewriting who controls the wallet always gets a human look.
  3. A transfer with unknown USD value never auto-approves — if the dollar checks couldn’t run, a human (or your Telegram confirmation) must.

Dollars, not tokens

The engine scores USD value, never raw token amounts — 0.5 BNB is not “$0.50”. The server prices every transaction at intake from your wallet’s own portfolio data, before screening runs; a value claimed by the app is never trusted. If no reliable price exists (unsupported token, pricing outage), the value is treated as unknown and the transaction lands in at least REVIEW — pricing gaps degrade to over-review, never under-review.

Deep analysis on REVIEW

For REVIEW-tier transactions the conversational agent adds context the engine can’t see:
  • GoPlus Security — recipient reputation, sanctions, phishing and scam detection
  • Honeypot.is — token security: honeypot detection, mintable supply, buy/sell taxes
The agent’s assessment can raise the engine’s score, never lower or replace it — the deterministic engine always wins on its own turf.

Your configuration

All limits are per wallet, with sensible defaults until you change them:

Changing configuration — the proposal flow

Your screening policy is what the agent enforces, so the app alone can never loosen it — a compromised browser session must not be able to raise your limits and then drain past them. Configuration writes are agent-only, and the app’s role is to propose:
  1. Edit in the app — Settings → Screening limits: sliders for the ceilings, a two-handle risk band for the thresholds, chips for active hours/days, plus a reset-to-defaults.
  2. Saving files a proposal — nothing applies yet. One proposal can be pending per wallet, and it expires in 15 minutes if unconfirmed.
  3. Confirm on Telegram — your agent shows the exact old → new diff and asks. Telegram is a different device and session from the web login: that’s the second factor. There is no email fallback and nothing auto-applies on a timer — no positive confirmation, no change.
  4. Applied atomically — confirmation, the settings write, and the audit record commit together; you get an “applied” message with the diff, and any transaction mid-screening is automatically re-scored under the new policy.
Two shortcuts that skip the proposal, safely:
  • Asking the agent directly in Telegram (“raise my daily limit to $50k”) applies immediately — the chat itself is the trusted channel.
  • The screening on/off toggle stays directly controllable in the app: turning screening off doesn’t weaken the agent — it removes the agent’s signature entirely, so your own two keys are required instead.
A proposal you didn’t make is a red flag. The agent will refuse to confirm anything you didn’t ask for — if one appears, reject it and treat your web session as possibly compromised.

Learning over time

After every executed transaction the engine’s baselines update: recipient averages and typical payment hours, per-token familiarity, hour×day activity windows, and the rolling volume counters. Two properties keep this trustworthy:
  • Only USD-priced amounts enter the dollar baselines — an unpriced execution still counts, but can’t distort your averages with token units.
  • Learning is pausable (the learning setting) and rejections never teach the profile that a pattern is normal.

Auditability and replay

Every verdict is stored on the transaction with its score and full reason list, every applied configuration change lands in the behavioral event log with its old → new diff, and the runtime keeps its own append-only decision record. Because the engine is deterministic and the evaluation timestamp is an explicit input, any historical decision can be replayed bit-for-bit from its stored inputs. Decisions are also version-bound: if anything that influenced a verdict changes — the payload, a signature, your limits, even the USD price — the transaction’s version bumps and any in-flight decision is invalidated and recomputed.