This is a submission for the Hacktoberfest Open-Source AI Challenge: Week 4.
What I built
Most crypto wallet drains are not hacks. Someone signs something they could not read: a gasless Permit, a Permit2 batch, a Seaport listing for 0 ETH, a setApprovalForAll, or a blind 32-byte hash. The wallet shows hex, and people tap Sign.
signread takes that payload and turns it into one verdict (HIGH, MEDIUM or LOW), the facts behind it, and a short explanation in plain language from a local open-weight model. It also has a page mode that scans mint pages, airdrop posts and AI-agent skill.md files for traps: seed-phrase asks, curl | sh, prompt injection aimed at agents, blanket approvals, hidden fees and refund-later schemes.
I do not own a laptop. I built and run this from my phone, so the main way to use it is a GitHub Actions button: paste the payload, and read the result in the run summary.
Demo
Repo: https://github.com/DaddyUnikii/signread
Release: https://github.com/DaddyUnikii/signread/releases/tag/v0.1.0
Example: a Seaport order that lists an NFT and pays the owner nothing.
HIGH Seaport order: you list items for sale
you give ERC721 #1234 x1
paid out 1 wei to someone else
order end time never expires
HIGH you receive nothing for these items (classic free-listing drain)
AI (qwen2.5:1.5b): If you sign this, anyone can take NFT #1234 without paying you, and the permission never expires. Do not sign.
How open-source AI is at the core
The runner installs Ollama, pulls Qwen 2.5 1.5B (Apache-2.0, open weights) and runs it on CPU. No API key, no account, and the payload never leaves the runner. You can swap in llama3.2:3b, gemma2:2b or any OpenAI-compatible local server (llama.cpp, vLLM, LM Studio).
The key design choice: the AI explains, the rules decide.
A deterministic decoder, covered by tests, computes the verdict. The model only gets the structured findings, is told to treat quoted text as untrusted data, and is not allowed to change the verdict. So a prompt-injected page or a sweet-talking message cannot talk the model into saying "safe". The open model does what it is good at, explaining in the user's own language (English or Indonesian), and stays out of the part that has to be exact.
Why open beat closed here
- Privacy: what you are about to sign is sensitive, and it stays on a machine you control.
- Cost: free to run on a GitHub runner, so anyone can fork it and use it from a phone.
- Control: a small local model with a fixed job is predictable, and the verdict never depends on a hosted API changing behind you.
Tech
- Zero dependencies, Node 18+
- Decodes EIP-2612 and DAI permits, Permit2, Seaport, generic EIP-712, personal_sign (including SIWE domain checks) and common approval calldata
- 16 tests, CI on Node 18, 20 and 22
- --fail-on HIGH for bots and CI
What's next
A browser-extension front end, more marketplaces, and a poisoned-address checker for your transaction history.
Thanks for reading. Don't sign what you can't read.
Top comments (1)
Love that the rules decide and the model only explains, that's the right split. One payload I'd add: Safe transactions. A SafeTx is EIP-712 too, and the field that matters is operation. 1 means delegatecall, so the Safe runs the target's code as itself and can rewrite its own storage, including which implementation it uses. That's how Bybit lost about 1.5B in February 2025, the signers approved what looked like a routine transfer. From a quick look at decode.js the generic path flags an unknown
tobut not operation. Would you make operation 1 HIGH on its own?