Methodology / evidence

What the report is allowed to claim

VEIL Scan is a translator, not an intelligence agency. This page is the contract between the raw RPC payload and the sentences on the report. If a finding cannot point at a public field, it should not exist.

Inputs

Live scans take a validated base58 address on mainnet-beta. The server calls getSignaturesForAddress with limit: 100 and commitment confirmed, then getTransaction with jsonParsed. Demo mode skips RPC and returns a fixture so the UI can be reviewed offline. Details of retries and fallbacks are on How it works.

Findings

Each finding has an id, a severity, a title, a one-line summary, a longer detail, an audience (holder, developer, or both), and zero or more evidence rows. Evidence prefers real signatures. Empty evidence is reserved for window statements (“no signatures”, “bodies missing”, “time cluster”).

  • history-public

    The signature list itself is already a public log.

  • fee-payer

    Account zero paid the fee — usually the submitting signer.

  • counterparties

    Other keys in transfers or token balance owners.

  • amounts

    SOL in/out from pre/post lamports in the window.

  • apps

    Recognized non-system programs the address invoked.

  • memos

    Plaintext Memo program payloads — treated as critical.

  • failures

    Failed signatures still leak program and accounts.

  • timing

    UTC hour concentration, labeled as weak.

  • logs

    Program logs matching emails, URLs, UUIDs, or customer-like words.

  • empty / partial-parse

    Honest about unused addresses and RPC gaps.

Transfer edges

Edges are aggregated from parsed system transfers and token balance owner changes. Self-transfers are dropped. The report keeps edges that touch the scanned address, sorted by count, capped at 40 rows. The visual map shows at most 16 counterparties so a busy wallet remains readable. A line is not a shared owner.

Exposure score

The score starts at 0, adds the weights below, then clamps to 0–100. It is a reading aid so two reports can be compared at a glance. It is not probability of identification, not a credit score, and not advice to “de-risk” by mixing.

ConditionWeight
At least one signature+12
More than 20 signatures+8
80 or more signatures+8
Each unique counterparty+1.2, capped at 18
Any plaintext memo+18
Any token mint seen+6
More than five mints+4
Each recognized non-system app+3, capped at 14
Any failed transaction+4
Application-shaped program logs+10
Fee payer on more than 60% of txs+6
≥30–35% of txs in one UTC hour (n≥12)+6
  • 0

    No recorded trail

  • 1–24

    Limited exposure

  • 25–49

    Moderate exposure

  • 50–74

    High exposure

  • 75–100

    Severe exposure

Limits we will not hide

  • The window is the last 100 confirmed signatures, not the life of the address.
  • Public RPC can omit transaction bodies. Missing bodies reduce transfer and leak recall; they do not erase signatures.
  • Program names come from a curated catalog. Unknown ids are labeled unknown, not “suspicious.”
  • System and token programs are omitted from the “recognized apps” fingerprint so a wallet is not scored just for existing.
  • Inner instructions (CPI) are flattened. A Jupiter route still reveals the underlying AMM and token accounts when RPC returns them.
  • Balance deltas use pre/post lamports and token balances. Fees, rent, and batched routes can make crude “in/out SOL” totals messy.
  • UTC hour clustering is a weak signal. It is never treated as a passport or workplace.
  • We do not ingest CEX KYC, IP logs, or off-chain social graphs. If those appear in a memo, that is because someone wrote them on-chain.