Розробка гаманця з Social Recovery
12-словна seed-фраза — це найгірший UX у історії фінансів. Користувач зобов'язаний надійно зберігати послідовність слів, яку неможливо ні сфотографувати, ні втратити, ні показати комусь. В результаті: один записав на папір в ящик стола, інший зберіг в нотатках телефону, третій взагалі не зберіг. За оцінками Chainalysis, 20–25% усіх біткоїнів безповоротно втрачені саме так.
Social recovery — це механізм, при якому втрата ключів не означає втрату активів. Ідея Виталика Бутерина, реалізована в Argent, Loopring, а тепер нативно доступна через ERC-4337 Account Abstraction. Суть: гаманець належить смарт-контракту, який має два режими управління — owner key для повсякденних транзакцій та guardian set для recovery.
Архітектура: як Social Recovery працює на рівні контракту
Guardian Set та Threshold Recovery
Guardians — це адреси (EOA або інші смарт-контракти), які колективно можуть змінити owner key гаманця. Власник наперед призначає N guardians-ів та встановлює threshold — мінімальне число підтверджень для recovery. Класика: 3 з 5.
Guardians ніколи не торкаються активів безпосередньо. Їхня єдина функція — виклик initiateRecovery та finalizeRecovery. Це принципове обмеження: якщо guardian скомпрометований, він не може вкрасти кошти, лише запустити процес зміни ключа.
contract SocialRecoveryWallet {
address public owner;
mapping(address => bool) public isGuardian;
uint256 public guardianCount;
uint256 public threshold;
uint256 public recoveryDelay; // timelock у секундах
struct RecoveryRequest {
address proposedOwner;
uint256 approvalCount;
uint256 initiatedAt;
mapping(address => bool) approvals;
}
RecoveryRequest public pendingRecovery;
function initiateRecovery(address _proposedOwner) external onlyGuardian {
require(pendingRecovery.initiatedAt == 0, "Recovery already pending");
pendingRecovery.proposedOwner = _proposedOwner;
pendingRecovery.initiatedAt = block.timestamp;
pendingRecovery.approvalCount = 1;
pendingRecovery.approvals[msg.sender] = true;
}
function approveRecovery() external onlyGuardian {
require(pendingRecovery.initiatedAt != 0, "No pending recovery");
require(!pendingRecovery.approvals[msg.sender], "Already approved");
pendingRecovery.approvals[msg.sender] = true;
pendingRecovery.approvalCount++;
}
function finalizeRecovery() external {
require(pendingRecovery.approvalCount >= threshold, "Insufficient approvals");
require(
block.timestamp >= pendingRecovery.initiatedAt + recoveryDelay,
"Timelock not expired"
);
owner = pendingRecovery.proposedOwner;
delete pendingRecovery;
}
}
Timelock — ключовий елемент безпеки
recoveryDelay — обов'язковий параметр. Якщо guardians змовились або були скомпрометовані, у власника є вікно для скасування (cancelRecovery). Argent використовує 24-48 годин. Для institutional гаманців має сенс 72 години або більше.
Без timelock: guardian threshold скомпрометований → миттєва втрата контролю. З timelock: власник бачить pending recovery у інтерфейсі, встигає скасувати, якщо це він не ініціював.
Guardian Management
Додавання та видалення guardians має також проходити через timelock — інакше owner може замінити всіх guardians на контрольовані адреси прямо перед продажем. Патерн: pendingGuardianAdd з затримкою, подібно до recovery.
mapping(address => uint256) public pendingGuardianAdditions;
uint256 public guardianAddDelay;
function scheduleAddGuardian(address _guardian) external onlyOwner {
pendingGuardianAdditions[_guardian] = block.timestamp + guardianAddDelay;
}
function confirmAddGuardian(address _guardian) external {
require(pendingGuardianAdditions[_guardian] != 0, "Not scheduled");
require(block.timestamp >= pendingGuardianAdditions[_guardian], "Timelock active");
isGuardian[_guardian] = true;
guardianCount++;
delete pendingGuardianAdditions[_guardian];
}
Хто може бути guardian-ом
Вибір guardians — задача не технічна, а соціальна та архітектурна. Варіанти:
Довірені особи. Три близькі люди. Кожен зберігає guardian private key у своєму гаманці. Найпростіша схема, достатня для більшості користувачів.
Hardware wallet + телефон + guardian сервіс. Резервний Ledger у сейфі + особистий телефон + Guardian сервіс типу Argent або кастомний. При втраті двох з трьох — recovery.
Multisig як guardian. Safe{Wallet} — guardian гаманця. Для recovery потрібно зібрати quorum у Safe. Підходить для корпоративних гаманців, де HR-процедура замінює ключі.
Smart contract guardian. Guardian — це timelock контракт організації. Recovery ініціюється через governance голосування. Крайній випадок, але дозволяє повністю формалізувати процедуру.
| Тип Guardian | Зручність | Децентралізація | Підходить для |
|---|---|---|---|
| Trusted persons (3-of-5) | Висока | Висока | Роздрібні користувачі |
| Hardware + mobile + service | Середня | Середня | Power users |
| Corporate multisig | Низька | Висока | Корпоративні |
| DAO governance | Дуже низька | Максимальна | Protocol-owned |
ERC-4337 та Social Recovery
Account Abstraction (ERC-4337) робить social recovery першокласним патерном. Гаманець — це смарт-контракт з самого початку, жодної конверсії від EOA не потрібно. UserOperation замість транзакції дозволяє:
- Gasless recovery: Paymaster платить газ за guardians та користувача
- Batched approvals: кілька guardian одобрень в одному bundled batch
- Social login як guardian: guardian key зберігається в passkey/WebAuthn на телефоні користувача, не потребує знання crypto
Реалізація через Kernel (ZeroDev) або Biconomy Smart Account v2: обидві мають plugin/module системи, де social recovery — підключуваний модуль, не core логіка.
ERC-4337 Recovery Flow
// Guardian підписує UserOperation для approveRecovery
const userOp = await guardianSmartAccount.buildUserOperation({
target: walletAddress,
data: wallet.interface.encodeFunctionData('approveRecovery', [])
});
// Paymaster спонсирує газ — guardian не потребує ETH
const sponsoredOp = await paymasterClient.sponsorUserOperation(userOp);
await bundlerClient.sendUserOperation(sponsoredOp);
Це принципово змінює UX: guardians не потребують тримати ETH для газу. Вони просто підписують approval на телефоні, Paymaster покриває вартість.
Захист від атак
Griefing через spam recovery
Будь-який guardian може ініціювати recovery — і таким чином заблокувати нормальну роботу гаманця (pending recovery перешкоджає транзакціям у деяких реалізаціях). Рішення: лише пороговий number guardians можуть коллективно ініціювати recovery, або recovery не блокує транзакції owner-а.
Social Engineering на guardians
Зловмисник переконує кількох guardians, що користувач втратив ключ та потрібне recovery. Захист: timelock дає вікно реакції, моніторинг pending recovery через нотифікації (email/push/telegram bot), обов'язкова верифікація через out-of-band канал.
Front-Running finalizeRecovery
Атакуючий бачить в мемпулі finalizeRecovery з proposedOwner = легітимна адреса та front-run-ить з іншою адресою. Захист: commit-reveal схема або використання flashbots/private mempool для фінальної транзакції.
Off-Chain Guardian Coordination
Guardians потребують способу координуватися без on-chain газу. Варіанти:
Centralized guardian service. Argent зберігає guardian signature off-chain, користувач запрашує через сервіс. Зручно, але центральна точка відмови.
IPFS + signature aggregation. Guardians публікують підписи в IPFS, aggregator збирає threshold підписів та відправляє один batchApprove виклик. Потребує UI.
E2E encrypted messaging. Guardians обмінюються через Signal/Matrix, підписи передаються вручну. Low-tech, максимальна незалежність.
Для production рекомендуємо гібрид: кастомний notification сервер сповіщує guardians-ів, вони одобрюють через dApp, aggregator батчить підписи.
Stack та інструменти
Solidity 0.8.x + OpenZeppelin — базова реалізація контракту. Foundry — тестування, особливо timelock та recovery edge cases. ERC-4337 SDK (ZeroDev / Biconomy) — якщо будуємо AA гаманець. wagmi + viem — frontend. WalletConnect v2 — підключення guardians з різних пристроїв.
Процес розробки
Аналітика (3–5 днів). Цільова аудиторія, хто буде guardians-ами, потрібна ли AA, gasless чи ні, multichain чи single chain.
Проектування контракту (3–5 днів). Guardian management схема, timelock параметри, recovery flow, інтеграція з ERC-4337 Account якщо потрібна.
Розробка (4–8 тижнів). Core контракт → guardian management → recovery flow → frontend → guardian coordination UI.
Аудит. Обов'язковий: контракт управляє коштами, recovery — критична функція. Спеціальна увага: reentrancy в execute, коректність timelock, guardian griefing vectors.
Тестування. Fork-тести на mainnet, симуляція повного recovery flow, тест кожного attack vector.
Базовий гаманець без AA — 3–5 тижнів. З ERC-4337, gasless recovery та guardian coordination UI — 8–12 тижнів.







