Интеграция с Safe{Wallet} (Gnosis Safe)
Safe (бывший Gnosis Safe) — де-факто стандарт мультисиг кошелька в EVM экосистеме. Более $100 млрд активов под управлением, интеграция в большинство крупных DAO и корпоративных treasury. Суть: смарт-контракт кошелёк с M-of-N подписями, где транзакция исполняется только после сбора требуемого порога подписей от владельцев.
Интеграция с Safe нужна в нескольких сценариях: DAO treasury management, корпоративный контроль над смарт-контрактами, multisig для протоколов DeFi, кастомный интерфейс управления активами команды.
Архитектура Safe
Safe контракт — GnosisSafe.sol с модульной архитектурой. Ключевые компоненты:
Owners и threshold. Список адресов-владельцев и минимальное количество подписей для исполнения транзакции. Изменение этих параметров само требует threshold подписей.
Modules. Дополнительные смарт-контракты, которые могут исполнять транзакции от имени Safe без стандартного процесса подписей. Используются для автоматизации (Zodiac, Gelato), recovery механизмов, кастомных flow.
Guards. Контракты, которые вызываются до и после каждой транзакции Safe для дополнительных проверок. Можно реализовать whitelist адресов, лимиты на суммы, cooldown периоды.
Fallback handler. Обрабатывает вызовы неизвестных функций и receive(). Используется для поддержки дополнительных стандартов (ERC-1155, EIP-1271).
Safe Transaction Service и API
Safe поддерживает офлайн сбор подписей через Safe Transaction Service — hosted API от команды Safe. Флоу:
- Proposer (любой owner) создаёт транзакцию и отправляет её в Transaction Service
- Остальные owners видят pending транзакцию в интерфейсе, проверяют и подписывают
- После сбора threshold подписей — любой может исполнить транзакцию on-chain (оплатив газ)
import SafeApiKit from '@safe-global/api-kit'
import Safe from '@safe-global/protocol-kit'
const apiKit = new SafeApiKit({
chainId: 1n // Ethereum mainnet
})
// Создать pending транзакцию
const safeTransaction = await safeSdk.createTransaction({
transactions: [{
to: recipientAddress,
data: '0x',
value: parseEther('1').toString()
}]
})
const safeTxHash = await safeSdk.getTransactionHash(safeTransaction)
const senderSignature = await safeSdk.signHash(safeTxHash)
await apiKit.proposeTransaction({
safeAddress,
safeTransactionData: safeTransaction.data,
safeTxHash,
senderAddress,
senderSignature: senderSignature.data
})
Для кастомного frontend: @safe-global/protocol-kit и @safe-global/api-kit — официальные SDK. Работают в браузере и Node.js.
Safe Apps SDK: встраивание dApps
Safe Apps — dApps, которые запускаются внутри Safe интерфейса как iframes. Ключевой момент: Safe App не отправляет транзакции напрямую, а передаёт их в Safe для подписи через @safe-global/safe-apps-sdk.
import SafeAppsSDK from '@safe-global/safe-apps-sdk'
const sdk = new SafeAppsSDK()
// Вместо обычного wallet.sendTransaction
const txs = [{
to: contractAddress,
data: contract.interface.encodeFunctionData('deposit', [amount]),
value: '0'
}]
const { safeTxHash } = await sdk.txs.send({ txs })
Если нужно встроить существующий dApp в Safe экосистему или создать кастомное приложение управления treasury — это основной путь.
Zodiac: модульная расширяемость
Zodiac — фреймворк от Gnosis Guild для расширения Safe через модули. Готовые модули:
Reality Module — выполняет транзакции по результатам on-chain голосования через Kleros или Reality.eth. Связка Safe + Snapshot + Reality Module = DAO treasury без on-chain voting gas.
Delay Module — добавляет timelock для транзакций. Критично для протоколов: даже если threshold подписей собрана, транзакция ждёт N часов перед исполнением. Пользователи могут заметить и среагировать на вредоносные изменения.
Roles Module — гранулярный контроль доступа. Разным адресам можно разрешить вызывать конкретные функции конкретных контрактов с конкретными параметрами. Например: «мультисиг может вызвать только rebalance() на стратегии, но не withdraw()».
Кастомные Guard и Module
Если нужна специфическая логика — пишем кастомный Guard или Module.
Пример Guard с лимитом дневных трат:
contract SpendingLimitGuard is BaseGuard {
uint256 public dailyLimit;
uint256 public currentDay;
uint256 public spentToday;
function checkTransaction(
address to,
uint256 value,
bytes memory data,
// ... остальные параметры
) external override {
if (block.timestamp / 1 days > currentDay) {
currentDay = block.timestamp / 1 days;
spentToday = 0;
}
require(spentToday + value <= dailyLimit, "Daily limit exceeded");
spentToday += value;
}
function checkAfterExecution(bytes32 txHash, bool success) external override {}
}
Guard подключается через Safe.setGuard(guardAddress) — сама транзакция требует threshold подписей.
Мультичейн Safe и Safe{Core} AA
Safe работает на 15+ сетях, адреса контрактов совпадают (деплой через CREATE2 с одинаковым salt). Safe адрес на Ethereum и Arbitrum может быть одинаковым, если деплоен с теми же параметрами (owners, threshold, nonce).
Safe{Core} Account Abstraction SDK — новый стэк, который интегрирует Safe с ERC-4337. Safe контракт становится ERC-4337 Account, транзакции идут через bundler, можно использовать Paymaster для оплаты газа в ERC-20.
Стек интеграции
| Задача | Инструмент |
|---|---|
| SDK для транзакций | @safe-global/protocol-kit |
| Pending транзакции | @safe-global/api-kit |
| Safe Apps (iframe dApp) | @safe-global/safe-apps-sdk |
| Модули и расширения | Zodiac framework |
| AA интеграция | @safe-global/safe-core-sdk |
Сроки
Базовая интеграция — UI для создания/подписи/исполнения транзакций через Safe Transaction Service, список pending транзакций, история: 3-4 недели.
Расширенная интеграция с кастомными модулями, Guard контрактами, Safe Apps, Zodiac: 6-8 недель + аудит кастомных контрактов.
Safe контракты прошли множество аудитов — сам Safe безопасен. Риски — в кастомных модулях и Guards, которые пишутся под проект.







