Revoke.cash Integration
Unlimited approve is standard practice in DeFi to save gas, and a standard attack vector when a protocol is compromised. A user gives approve(spender, type(uint256).max) once and forgets about it. If the protocol is hacked — the attacker drains the wallet completely. Revoke.cash lets you manage allowances. Integrating this functionality into your dApp is a day's work that significantly increases product trustworthiness.
What Revoke.cash integration is
Revoke.cash provides open-source components and an API. You can integrate in two ways:
-
Deeplink — "Manage Approvals" button opens
revoke.cash/address/<userAddress>with pre-filled address - Embedded allowance list — display and manage allowances directly in the dApp via Revoke.cash SDK
Deeplink — 30 minutes. Embedded — 1 day.
Deeplink integration
import { useAccount } from 'wagmi'
function ManageApprovalsButton() {
const { address, chainId } = useAccount()
const revokeUrl = address
? `https://revoke.cash/${address}?chainId=${chainId ?? 1}`
: 'https://revoke.cash'
return (
<a
href={revokeUrl}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-2 text-sm text-yellow-400 hover:text-yellow-300"
>
<ShieldAlert className="h-4 w-4" />
Manage permissions
</a>
)
}
Revoke.cash supports a chainId parameter — the user goes directly to the right network.
Direct work with allowances via viem
If you need to show allowances inside your dApp without redirecting — read directly via ERC-20 allowance():
import { createPublicClient, http, erc20Abi } from 'viem'
async function getAllowance(
tokenAddress: `0x${string}`,
owner: `0x${string}`,
spender: `0x${string}`,
chainId: number
): Promise<bigint> {
const client = createPublicClient({ chain: getChain(chainId), transport: http() })
return client.readContract({
address: tokenAddress,
abi: erc20Abi,
functionName: 'allowance',
args: [owner, spender],
})
}
For revoke — approve(spender, 0):
import { useWriteContract } from 'wagmi'
import { erc20Abi } from 'viem'
function RevokeButton({ tokenAddress, spender }: { tokenAddress: `0x${string}`, spender: `0x${string}` }) {
const { writeContract, isPending } = useWriteContract()
return (
<button
onClick={() => writeContract({
address: tokenAddress,
abi: erc20Abi,
functionName: 'approve',
args: [spender, 0n],
})}
disabled={isPending}
>
{isPending ? 'Revoking...' : 'Revoke permission'}
</button>
)
}
Note: 0n (BigInt zero), not 0. viem is strictly typed and expects bigint for uint256.
Where to place in the interface
Logical places for the allowances management button:
- Settings / Security page of the dApp
- After approve transaction — popup hint "Want to limit the permission?"
- Wallet dropdown — next to balance and disconnect
- Transaction history — next to historical approve operations
Don't show this on the homepage — creates unnecessary anxiety. But the ability should be easy to find.







