Інтеграція з Revoke.cash
Неообмежений approve — стандартна практика в DeFi для економії газу, та стандартний вектор атаки при компрометації протоколу. Користувач дає approve(spender, type(uint256).max) один раз і забуває про це. Якщо протокол взламується — атакуючий дренує гаманець повністю. Revoke.cash дозволяє керувати дозволами. Інтеграція цього функціоналу в dApp — це один день роботи, який суттєво підвищує рівень довіри до продукту.
Що таке інтеграція з Revoke.cash
Revoke.cash надає open-source компоненти та API. Ви можете інтегрувати двома способами:
-
Deeplink — кнопка «Manage Approvals» відкриває
revoke.cash/address/<userAddress>з попередньо заповненою адресою - Embedded allowance list — відображення та управління дозволами прямо в dApp через Revoke.cash SDK
Deeplink — 30 хвилин. Embedded — 1 день.
Інтеграція Deeplink
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" />
Управління дозволами
</a>
)
}
Revoke.cash підтримує параметр chainId — користувач одразу попадає на потрібну мережу.
Пряма робота з дозволами через viem
Якщо вам потрібно показувати дозволи всередину dApp без редиректу — читайте напрямо через 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],
})
}
Для 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 ? 'Скасовуємо...' : 'Скасувати дозвіл'}
</button>
)
}
Зважайте: 0n (BigInt нуль), а не 0. viem строго типізований і очікує bigint для uint256.
Де розмістити в інтерфейсі
Логічні місця для кнопки управління дозволами:
- Settings / Security сторінка dApp
- Після approve транзакції — всплаваюча підказка «Хочете обмежити дозвіл?»
- Wallet dropdown — рядом з балансом та disconnect
- Історія транзакцій — рядом з історичними approve операціями
Не показуйте це на головній сторінці — створює непотрібну занепокоєність. Але можливість повинна бути легко знаходимою.







