revoke.cash: Seeing Which Contracts Can Spend Your Tokens
❌ Revoke or update your token approvals
At a glance
- What is it?
- revoke.cash is an MIT licensed TypeScript application that lists the contracts a wallet has approved to spend tokens and lets you revoke or lower those allowances, across Ethereum and more than a hundred other networks. It suits anyone who has signed unlimited token approvals and forgotten which ones are still live.
- Who is it for?
- revoke.cash fits a wallet holder who has accumulated unlimited ERC-20 allowances across many decentralised applications and wants a single list to act on. It is the wrong tool if you have never granted an approval, since there is then nothing to revoke, and the wrong tool for a custodial setup where the key is not yours to move.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem is unlimited allowances nobody remembers
The readme opens with a joke that is the actual security problem: do you want to swap 10 DAI for ETH, and the app needs your approval to spend a billion dollars. That is what an unlimited token approval is. When you sign a decentralised exchange or a decentralised finance protocol, you often grant a spending allowance that is not capped, and it stays live until you revoke it. The site's own summary of the problem is whether you feel worried about the different apps that have access to the tokens in your wallet. The answer is that you should be, because an approval you forgot about is a standing permission for a contract you no longer trust. The project also links an article by the author on unlimited ERC-20 allowances considered harmful, which is where the reasoning behind the tool is written up.
What the tool does, and what it deliberately does not do
revoke.cash allows you to inspect all the contracts you have approved to spend money on your behalf, and revoke their access for the ones you no longer need. The second half of that sentence matters as much as the first: if you do not want to completely revoke access, it is also possible to update the amount they are allowed to spend instead. That is a distinction many similar tools get wrong, because reducing an allowance is a different transaction from revoking one, and in some protocols only one of the two is supported. A revoke is a transaction that removes the approval, and a reduction is a transaction that sets a new cap. Both leave the contract unable to move more than you allow, but a reduction keeps the approval alive, which matters if you still use the application.
Running it locally, and the environment file that decides what works
The local setup is three commands.
git clone [email protected]:RevokeCash/revoke.cash.git
cd revoke.cash
yarn
yarn devThe environment is where the difficulty lies, and the documentation is honest that each key decides which chains work at all. An `.example.env` file has to be copied into a `.env` file and filled out. `NEXT_PUBLIC_ALCHEMY_API_KEY` is used for reading data from Ethereum, Polygon, Optimism and many other chains, and Alchemy is also used for ENS and UNS name resolutions, so if it is omitted those resolutions will not work. `COVALENT_API_KEY` and `COVALENT_RATE_LIMIT` cover chains such as Ronin, and `ETHERSCAN_API_KEYS` with `ETHERSCAN_RATE_LIMITS` cover many others such as BNB Chain or Avalanche. `NODE_URLS` overrides RPC URLs for server-side services and `NEXT_PUBLIC_NODE_URLS` for the frontend, and `NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID` is needed for WalletConnect to work at all. The summary is blunt: if you omit any of these variables, Revoke.cash will not work for the chains you omitted.
The optional variables, and why serverless needs a queue
Three groups of variables are less essential. `IRON_SESSION_PASSWORD` encrypts the session cookies and can be any random 32-character string, but if it is omitted many chains will not work, so it is optional in name only. `NEXT_PUBLIC_MIXPANEL_API_KEY` is for analytics, and without it no analytics are collected, which is the one omission here that changes nothing about function. The third is the interesting one. `UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN` are used for queueing third-party API calls, and they are only necessary when hosting in a serverless environment such as Vercel. The reason is visible in the HTTP/2 note: the premium multichain dashboard sends two API requests per network, and without a queue those third-party calls run inside a request that has a short execution budget. On a long-running server you can call the APIs directly. On a serverless function you cannot, so the work is pushed to a queue.
Why the dev server needs a reverse proxy
There is a specific local development problem worth knowing about. The dev server only supports HTTP/1.1, where browsers allow six connections per host, and the premium multichain dashboard sends two API requests per network, so other requests including the JavaScript chunks can wait in the browser queue for close to a minute. In production this is not an issue because Vercel serves HTTP/2. The fix for local work is to run Caddy as a reverse proxy in front of the dev server and open https://localhost:3443 instead of http://localhost:3000.
brew install caddy
caddy reverse-proxy --from localhost:3443 --to localhost:3000The first run asks for your password to add Caddy's local certificate authority to the system trust store. Both can also be started with a single command, `yarn dev:caddy`, which the package manifest defines as the Caddy reverse proxy running in the background alongside the dev server. The point of the whole exercise is that HTTP/2 multiplexing removes the six-connection limit, so the browser stops queueing chunks behind the dashboard's API calls.
Adding a network, and the four requirements a new chain must meet
Adding a network is described as relatively straightforward, since only a few files change: the chain ids and configuration in the core package, the Cypress chain fixtures in the web app, and the networks locale file. The prerequisites are the interesting part, because one of four sources has to be available. You need a public or private RPC endpoint that supports `eth_getLogs` requests for the entire history of the network, or support in GoldRush, or a block explorer with an exposed API compatible with the Etherscan API such as Blockscout, or a HyperSync instance with at least a Bronze tier. On top of that the project requires a publicly available RPC endpoint with rate limits that are not too restrictive. The reason the `eth_getLogs` requirement dominates is that reading your approvals means reconstructing them from the approval events in the chain's history, and a node that cannot serve logs for the whole history cannot answer the question.
The repository layout and the workspace behind the app
The root is a yarn workspace with apps/* and packages/*, and the package manifest shows a monorepo with a web app and several internal packages, including a core package, a backend package, an indexer package, an auto-revoke-executor package and a video package. The scripts show the shape of the project: a dev script that runs the web workspace, a build and start that do the same, a lint using biome, a typecheck that runs across six workspaces in sequence, and database scripts for generate, migrate, push, studio and drop on the core package. The test setup is split into a mocha suite and a Cypress suite, and there is a separate exploits:update script, which is a good sign of how seriously the project takes the contracts it interacts with. The application also has a render.yaml at the root, which is the configuration for deploying on Render, and a DEVELOPMENT.md alongside the AGENTS.md.
Editorial conclusion
revoke.cash fits a wallet holder who has accumulated unlimited ERC-20 allowances across many decentralised applications and wants a single list to act on. It is the wrong tool if you have never granted an approval, since there is then nothing to revoke, and the wrong tool for a custodial setup where the key is not yours to move. Before you use it on a large balance, start with one approval, confirm the transaction in your wallet, and check that the revoked contract disappears from the list rather than assuming it did.
Frequently asked questions
What does revoke.cash do?
It shows the contracts you have approved to spend your tokens and lets you revoke those approvals, or lower the amount they are allowed to spend if you would rather keep the approval alive. It works on Ethereum and more than a hundred other networks.
Which environment variables does revoke.cash need to work?
The key ones are NEXT_PUBLIC_ALCHEMY_API_KEY for reading data on Ethereum, Polygon, Optimism and others as well as ENS name resolution, COVALENT_API_KEY with COVALENT_RATE_LIMIT for chains such as Ronin, ETHERSCAN_API_KEYS with ETHERSCAN_RATE_LIMITS for chains such as BNB Chain and Avalanche, and NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID for WalletConnect. Each omission means the affected chains do not work.
Why do I need Caddy to run revoke.cash locally?
The dev server only speaks HTTP/1.1, where browsers allow six connections per host, and the multichain dashboard sends two API requests per network, so other requests including JavaScript chunks can queue for close to a minute. Running Caddy in front of it gives HTTP/2 locally, and yarn dev:caddy starts both together.
What does adding a new network to revoke.cash require?
One of four data sources has to be available: an RPC endpoint supporting eth_getLogs over the entire chain history, support in GoldRush, a block explorer with an Etherscan compatible API such as Blockscout, or a HyperSync instance on at least the Bronze tier. The network data is then maintained by hand in the core package, with a chain data script to print a draft configuration.
Can revoke.cash work without the Redis queue variables?
Yes, unless you are hosting in a serverless environment such as Vercel. UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN are used for queueing third-party API calls, which is necessary on serverless because those calls cannot run inside a short request.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/revokecash-revoke-cash)Was this useful?