Every time you interact with a dApp, you grant token approvals β permission for smart contracts to spend your tokens. Most users approve unlimited amounts and never think about it again.
The risk? A single exploited or malicious contract can drain your entire balance through a forgotten approval.
DotSafe solves this by giving you full visibility, AI-powered risk analysis, and one-click batch revocation on Passet Hub. It also monitors XCM-connected parachains from one dashboard so you can act before stale approvals become exploitable.
|
Scans all active ERC-20 and NFT approvals for your connected wallet. Fetches on-chain events, verifies live allowances, and filters out already-revoked permissions. |
Each approval is analyzed by Google Gemini 2.0 Flash against multiple risk vectors β unverified code, unlimited allowances, contract age, proxy patterns, and more. Scores range from 0β100 with SAFE / CAUTION / DANGER ratings. |
|
Select multiple risky approvals and revoke them all in a single transaction. No more tedious one-by-one revocations. Supports both ERC-20 and NFT (ERC-721/ERC-1155) approvals. |
Monitor approvals across Polkadot parachains β Moonbeam, Astar, and Acala β via XCM (Cross-Consensus Messaging). Send risk alerts and request scans on remote chains. |
|
Real-time analytics with an animated risk meter, approval breakdown by danger level, and actionable insights β all in a sleek, dark-themed interface. |
Set per-token spending limits, time-bounded approval windows, and spender whitelists enforced on-chain through the |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Frontend (Next.js 16) β
β βββββββββββββ ββββββββββββ βββββββββββββ β
β β Dashboard β β XCM Page β β Landing β β
β βββββββ¬ββββββ ββββββ¬ββββββ βββββββββββββ β
β β β β
β βββββββΌβββββββββββββββΌββββββ βββββββββββββββββββββββ β
β β Hooks (Thirdweb SDK) β β /api/score-contract β β
β β β’ useApprovalScanner β β (Gemini AI Scoring) β β
β β β’ useBatchRevoke β ββββββββββββ¬βββββββββββ β
β β β’ useXCMGuard β β β
β β β’ useAIScoring β ββββββββΌβββββββ β
β β β’ useApprovalPolicy β β Gemini 2.0 β β
β βββββββββββ¬βββββββββββββββββ β Flash β β
β β ββββββββββββββββ β
ββββββββββββββΌββββββββββββββββββββββββ΄βββββββββββββββ΄ββββββ
β
βββββββββΌββββββββββββββββββββββββββββββββββββββββ
β Passet Hub (420420417) β
β ββββββββββββββββ ββββββββββββββ βββββββββββ β
β β Approval β β Batch β β XCM β β
β β Scanner β β Revoker β β Guard β β
β ββββββββββββββββ ββββββββββββββ βββββββββββ β
β βββββββββββββββββββββββββββββ β
β β Approval Policy β β
β βββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββΌβββββββββ
β XCM
ββββββββββββββββββββββββββΌβββββββββββββ
β Parachains β β
β βββββββββββ βββββββββββ βββββββββ β
β βMoonbeam β β Astar ββ β Acala β β
β β 2004 β β 2006 ββ β 2000 β β
β βββββββββββ βββββββββββ βββββββββ β
ββββββββββββββββββββββββββ΄βββββββββββββ
| Layer | Technology |
|---|---|
| Smart Contracts | Solidity 0.8.24 Β· Hardhat Β· OpenZeppelin 5.x |
| Frontend | Next.js 16 Β· React 19 Β· TypeScript Β· Tailwind CSS 4 |
| Web3 | ThirdWeb SDK v5 |
| AI Engine | Google Gemini 2.0 Flash |
| State | Zustand 5 |
| Animations | Framer Motion |
| Fonts | Syne Β· Manrope Β· Space Mono |
| Chains | Passet Hub (Chain ID 420420417) |
| Contract | Address |
|---|---|
ApprovalScanner |
0x723BE9931C1417Ef00B7f6f426e387Dc5099E602 |
BatchRevoker |
0xe136a28958DBd9Ad3A8c942B91e01064f95a1E8f |
XCMGuard |
0x78e0C8c7a94122211E07b14562C5d781aDA748dC |
ApprovalPolicy |
0x19eDb13a0FA86a89aC7fD14f811769230B3Bf00A |
Read-only helper to verify live approval states on-chain.
| Function | Description |
|---|---|
checkAllowance(token, owner, spender) |
Returns current ERC-20 allowance |
checkApprovalForAll(nft, owner, operator) |
Checks NFT operator approval |
batchCheckAllowances(tokens[], spenders[], wallet) |
Batch-check multiple allowances in one call |
getAtRiskValue(tokens[], spenders[], wallet) |
Sum of all token value at risk |
Execute multiple revocations atomically in a single transaction.
| Function | Description |
|---|---|
batchRevokeERC20(tokens[], spenders[]) |
Revoke multiple ERC-20 approvals |
batchRevokeNFT(nfts[], operators[]) |
Revoke NFT operator approvals |
revokeERC20(token, spender) |
Single-revoke convenience method |
Events: BatchRevoked(wallet, count) Β· SingleRevokeFailed(token, spender, index)
Cross-chain approval monitoring via Polkadot XCM.
| Function | Description |
|---|---|
sendRiskAlert(destParaId, suspicious, xcmMsg) |
Send risk alert to a parachain |
requestCrossChainScan(destParaId, wallet, xcmMsg) |
Initiate remote chain scan |
getMonitoredParachains() |
Returns monitored parachain IDs |
isMonitored(paraId) |
Check if a parachain is monitored |
User-configurable spending rules and trusted spender allowlists.
| Function | Description |
|---|---|
registerWallet() |
Registers a wallet for policy management |
setPolicy(token, maxAllowance, approvalWindow, whitelistOnly) |
Writes a token-specific approval policy |
removePolicy(token) |
Removes a token-specific approval policy |
addWhitelistEntry(spender) |
Adds a spender to the allowlist |
removeWhitelistEntry(spender) |
Removes a spender from the allowlist |
- Node.js β₯ 18
- npm or yarn
- A wallet with Passet Hub configured (Chain ID:
420420417) - Gemini API Key β Get one at ai.google.dev
git clone https://github.com/Shikhyy/DotSafe.git
cd DotSafecd contracts
npm install
# Compile contracts & generate TypeChain types
npm run compile
# Run tests
npm run test
# Deploy to Passet Hub
npm run deploy:testnetcd frontend
npm install
# Create environment file
cat > .env.local << EOF
GEMINI_API_KEY=your_gemini_api_key_here
NEXT_PUBLIC_THIRDWEB_CLIENT_ID=your_thirdweb_client_id
EOF
# Start development server
npm run devOpen http://localhost:3000 and connect your wallet.
| Variable | Required | Description |
|---|---|---|
GEMINI_API_KEY |
β | Google Gemini API key for AI risk scoring |
NEXT_PUBLIC_THIRDWEB_CLIENT_ID |
β | ThirdWeb client ID for wallet connection |
DEPLOYER_PRIVATE_KEY |
β * | Deployer wallet private key (*for contract deployment only) |
POLKADOT_TESTNET_RPC |
β | Custom RPC endpoint for Passet Hub |
| Network | Chain ID | Currency | Explorer |
|---|---|---|---|
| Passet Hub | 420420417 | PAS (18 decimals) | Subscan |
| Parachain | Para ID | Status |
|---|---|---|
| Moonbeam | 2004 | β Active |
| Astar | 2006 | β Active |
| Acala | 2000 | β Active |
cd contracts
npm run test73/73 tests passing β β Test coverage includes:
- ApprovalScanner (7 tests) β Allowance checks, batch operations, at-risk value calculations
- BatchRevoker (13 tests) β Single/batch revocations, event emissions, input validation
- XCMGuard (32 tests) β Parachain monitoring, cross-chain alerts, access control
- ApprovalPolicy (21 tests) β Policy management, whitelist updates, registration flow
| Route | Method | Description |
|---|---|---|
/api/score-contract |
POST | AI risk scoring via Gemini β returns risk level, score, and reasoning |
/api/resolve-spender |
GET | Resolve spender contract address to protocol name |
/api/token-metadata |
GET | Fetch token symbol, name, and decimals from on-chain |
DotSafe uses Google Gemini 2.0 Flash to analyze each approved contract against multiple risk vectors:
| Risk Factor | Score Impact |
|---|---|
| Unverified source code | +30 |
| Unlimited allowance | +25 |
| Contract age < 30 days | +20 |
| Upgradeable proxy pattern | +15 |
| Approval idle > 90 days | +10 |
| Known audited contract | β15 |
Risk Levels:
| Level | Score Range | Action |
|---|---|---|
| π’ SAFE | 0 β 29 | No action needed |
| π‘ CAUTION | 30 β 59 | Review recommended |
| π΄ DANGER | 60 β 100 | Revoke immediately |
DotSafe/
βββ contracts/ # Hardhat smart contract workspace
β βββ contracts/ # Solidity source files
β β βββ ApprovalScanner.sol # On-chain approval verification
β β βββ BatchRevoker.sol # Atomic batch revocation
β β βββ XCMGuard.sol # Cross-chain XCM monitoring
β β βββ ApprovalPolicy.sol # On-chain approval rules
β β βββ mocks/ # Test mock contracts
β βββ test/ # Contract test suite
β βββ ignition/ # Deployment modules
β βββ typechain-types/ # Auto-generated TypeScript types
β βββ hardhat.config.ts # Hardhat configuration
β
βββ frontend/ # Next.js frontend application
β βββ app/ # App router pages
β β βββ page.tsx # Landing page
β β βββ dashboard/ # Main scanning dashboard
β β βββ policy/ # Approval policy manager
β β βββ history/ # Revocation history
β β βββ xcm/ # XCM cross-chain monitor
β β βββ api/ # AI scoring API route
β βββ components/ # React components
β β βββ scanner/ # Approval list & risk cards
β β βββ stats/ # Risk meter analytics
β β βββ wallet/ # Wallet connection
β β βββ xcm/ # Parachain cards
β βββ hooks/ # Custom React hooks
β βββ lib/ # Chains, ABIs, types, config
β βββ store/ # Zustand global state
β
βββ README.md
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Commit your changes:
git commit -m 'feat: add my feature' - Push to the branch:
git push origin feature/my-feature - Open a Pull Request
See DEMO.md for a step-by-step guide to test DotSafe, including:
- Connecting a wallet on Passet Hub testnet
- Scanning approvals and viewing AI risk scores
- Batch revoking dangerous approvals
- Managing approval policies
- Exploring XCM cross-chain monitoring
Contract addresses on Passet Hub Testnet (420420417):
| Contract | Subscan Link |
|---|---|
| ApprovalScanner | 0x723B...9602 |
| BatchRevoker | 0xe136...8f |
| XCMGuard | 0x78e0...8dC |
| ApprovalPolicy | 0x19eD...00A |
This project is licensed under the MIT License β see the LICENSE file for details.
Built for the Polkadot ecosystem π£
Protecting wallets, one approval at a time.