Community reports
Let users report scam, phishing, address-poisoning and rug-pull addresses with a wallet signature, and show the count as a warning without ever blocking a swap.
Anyone with a wallet can report an address or token as a scam. Reports are counted immediately and shown as "Community reports: N" with categories; the notes people write show only after a LayerHop admin approved them. A report is a signal, never a verdict: LayerHop never shows "confirmed scam", reports never block a swap and never change a token's risk level.
In the LayerHop app the count appears in the recipient check before a send, next to the token risk badge, on the transaction preview and in wallet health.
Only approved reports can raise a risk level: the transaction preview flags community_reports (caution, or danger from 3 approved reports) for reports approved by a LayerHop admin and filed on the preview's chain. Reports not reviewed yet are shown as information only, so a few fresh wallets can't brand an address a scam.
Look up reports#
curl "https://api.layerhop.com/v1/reports/0x5ca1ab1e00000000000000000000000000000bad"{
"reports": {
"target": "0x5ca1ab1e00000000000000000000000000000bad",
"count": 3,
"approved": 1,
"categories": { "poisoning": 2, "phishing": 1 },
"chainIds": [1, 8453],
"notes": [{ "category": "poisoning", "note": "Zero-value transfer from a look-alike of my exchange address", "chainId": 8453, "createdAt": "2026-10-28T09:00:00.000Z" }],
"lastReportedAt": "2026-10-28T09:00:00.000Z"
}
}GET /v1/reports?targets=a,b,c answers up to 25 addresses at once. count includes reports not reviewed yet; approved is how many of them an admin approved. EVM addresses match in any case and across EVM chains (chainIds says where they were reported); Solana addresses match exactly. Lookups are public, cached for 30 seconds and limited to 120 per minute per key or IP.
File a report#
The reporting wallet signs a plain text message (EIP-191 personal_sign on EVM, signMessage on Solana). It's free and can't move funds, and it isn't a sign-in: there's no session or cookie. Build the exact text with buildReportMessage from @layerhop/shared; the API rebuilds it from the fields you send, so every field, the note included, is covered by the signature.
import { buildReportMessage } from "@layerhop/shared";
const fields = {
vm: "evm", reporter: account.address.toLowerCase(), chainId: 8453,
target: "0x5ca1ab1e00000000000000000000000000000bad", kind: "address",
category: "poisoning", note: "Look-alike of my exchange deposit address",
issuedAt: new Date().toISOString(),
} as const;
const signature = await walletClient.signMessage({ account, message: buildReportMessage(fields) });
const { chainId, ...rest } = fields;
await fetch("https://api.layerhop.com/v1/reports", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ ...rest, chain: chainId, signature }),
});Categories: scam, phishing (drainer sites, malicious approvals), poisoning (look-alike addresses, zero-value transfers) and rug. kind is address or token; txHash and note (up to 500 characters) are optional.
Abuse rules#
| Rule | Error |
|---|---|
The signature must match the fields and the reporter wallet |
UNAUTHORIZED |
issuedAt at most 10 minutes old |
INVALID_PARAMS |
| One report per wallet and target | CONFLICT |
| 5 reports per wallet per hour, 20 per day; 20 per IP per hour | RATE_LIMITED |
| The wallet needs history: a LayerHop swap, or at least 3 transactions on the report's chain or Ethereum (when no RPC can answer, the report is refused; try again later) | FORBIDDEN |
| A wallet can't report itself | INVALID_PARAMS |
| Permit2, the routers and approval targets LayerHop's routes use, and listed tokens can't be reported | INVALID_PARAMS |
Admins review notes at dashboard.layerhop.com/admin/reports (or GET /v1/admin/reports): Approve makes a note public, Hide removes a report from the counts (spam, abuse, a wrong address).
Last updated