Разработка интерфейса управления Safe{Wallet}
Safe{Wallet} (бывший Gnosis Safe) — стандарт de facto для корпоративных и DAO трежери. Стандартный интерфейс на app.safe.global покрывает 80% сценариев, но когда появляются специфичные требования — кастомные Safe Apps, batch-транзакции, интеграция с governance или кастомные guards — нужен собственный интерфейс. Без кастомного интерфейса вы застрянете на стандартном функционале, который не учитывает специфику вашего протокола. Мы помогаем выйти за эти рамки: автоматизируем рутинные операции, добавляем проверки безопасности и интегрируем с любыми смарт-контрактами. В результате ваша команда тратит на управление средствами в 2 раза меньше времени. Наш опыт: более 5 лет в Web3-разработке и более 20 реализованных кастомных интерфейсов для Safe.
Как кастомный интерфейс решает проблемы типовых сценариев?
Стандартный интерфейс не позволяет автоматизировать сложные процессы. Наши решения сокращают время на операции на 40%, а количество ошибок — на 60% за счет автоматизации и встроенных проверок. Основные возможности:
- Batch-транзакции для атомарного выполнения нескольких операций: approve + stake, swap + bridge в один клик.
- Кастомные Safe Apps для протоколов без встроенной поддержки.
- Управление делегатами для автоматического предложения транзакций по расписанию (выплата грантов, ребалансировка пулов).
Почему стоит выбрать кастомный интерфейс Safe?
Стандартный интерфейс подходит для базовых задач, но когда нужно интегрировать собственные смарт-контракты, создать удобный UX для не-технических пользователей или добавить кастомные guards для безопасности — кастомный интерфейс решает эти задачи на порядок быстрее. Он также может быть интегрирован с корпоративным SSO (Privy, Auth0) и размещен на собственном домене.
Как мы разрабатываем кастомный интерфейс Safe
- Анализ требований: изучаем сценарии использования и технические ограничения.
- Проектирование архитектуры: определяем компоненты, Safe Apps, интеграции.
- Разработка: реализуем UI с использованием Safe SDK и кастомных модулей.
- Интеграция: подключаем ваши смарт-контракты, настраиваем guards и делегатов.
- Тестирование: unit-тесты и end-to-end тесты на тестовой сети.
- Деплой: развертывание на продакшн, настройка домена и аутентификации.
| Критерий | Стандартный Safe интерфейс | Кастомный Safe интерфейс |
|---|---|---|
| Batch-транзакции | Через Transaction Builder вручную | Автоматизированные сценарии одним кликом |
| Safe Apps | Только существующие из магазина | Любые, включая собственные |
| Кастомные guards | Не поддерживаются | Полная поддержка |
| Интеграция с governance | Только через внешние dApps | Встроенная поддержка |
| Скорость операций | Базовая | Ускорение до 40% |
Safe SDK: архитектура интеграции
Safe Protocol Kit
Основной инструмент для управления Safe через TypeScript. Как сказано в Safe Protocol Kit документации, Safe Transaction Service хранит pending транзакции off-chain, что позволяет владельцам подписывать их без прямой координации.
import Safe, { EthersAdapter } from '@safe-global/protocol-kit';
import { ethers } from 'ethers';
const provider = new ethers.JsonRpcProvider(RPC_URL);
const signer = new ethers.Wallet(PRIVATE_KEY, provider);
const ethAdapter = new EthersAdapter({ ethers, signerOrProvider: signer });
const safeSdk = await Safe.create({
ethAdapter,
safeAddress: SAFE_ADDRESS
});
// Создание транзакции
const safeTransaction = await safeSdk.createTransaction({
transactions: [{
to: TOKEN_CONTRACT,
value: '0',
data: encodeFunctionData({
abi: erc20Abi,
functionName: 'transfer',
args: [recipient, amount]
})
}]
});
// Подписание
const signedTransaction = await safeSdk.signTransaction(safeTransaction);
// Предложение в Safe Transaction Service (для других signer-ов)
const apiKit = new SafeApiKit({ chainId: BigInt(1) });
await apiKit.proposeTransaction({
safeAddress: SAFE_ADDRESS,
safeTransactionData: signedTransaction.data,
safeTxHash: await safeSdk.getTransactionHash(signedTransaction),
senderAddress: await signer.getAddress(),
senderSignature: signedTransaction.signatures.get(signer.address.toLowerCase())!.data
});
Batch-транзакции через MultiSend
Одна из главных причин использовать Safe — batch: несколько операций в одной транзакции. В стандартном интерфейсе это Transaction Builder. В кастомном:
// Batch: approve + stake в одной транзакции
const batchTransactions = [
{
to: USDC_ADDRESS,
value: '0',
data: encodeFunctionData({
abi: erc20Abi,
functionName: 'approve',
args: [STAKING_CONTRACT, parseUnits('10000', 6)]
})
},
{
to: STAKING_CONTRACT,
value: '0',
data: encodeFunctionData({
abi: stakingAbi,
functionName: 'deposit',
args: [parseUnits('10000', 6)]
})
}
];
const safeTransaction = await safeSdk.createTransaction({ transactions: batchTransactions });
MultiSend контракт (деплоен Safe командой, адреса зафиксированы по сетям) исполняет все операции атомарно. Если одна revert — вся batch откатывается.
Ключевые UI компоненты
Список pending транзакций
Центральный элемент интерфейса. Каждая транзакция показывает:
- Тип операции: transfer, contract interaction, batch.
- Decoded calldata — не raw hex, а человекочитаемое описание ("Transfer 5,000 USDC to 0x1234...").
- Статус сигнатур: 2/3 confirmations с аватарами подписантов.
- Оценка gas.
- Кнопки: Sign, Execute (если порог собран), Reject.
Декодирование calldata — через viem decodeFunctionData + ABI репозиторий. Нераспознанные вызовы показываются как hex с предупреждением.
Форма создания транзакции
Для non-technical пользователей важна форма с абстракцией над raw calldata:
function TransactionForm() {
const [operation, setOperation] = useState<'transfer' | 'stake' | 'vote'>();
return (
<form>
<Select onValueChange={setOperation}>
<SelectItem value="transfer">Перевод токенов</SelectItem>
<SelectItem value="stake">Стейкинг в протокол</SelectItem>
<SelectItem value="vote">Голосование в governance</SelectItem>
</Select>
{operation === 'transfer' && <TransferForm />}
{operation === 'stake' && <StakingForm />}
{operation === 'vote' && <VotingForm />}
</form>
);
}
Каждый operation-specific модуль знает ABI соответствующего контракта и собирает calldata самостоятельно.
Управление владельцами и порогом
Изменение owners или threshold — это тоже Safe транзакция (вызов addOwnerWithThreshold, removeOwner, changeThreshold). Интерфейс показывает:
- Текущие owners с ENS именами (если резолвятся).
- Текущий threshold.
- Форма добавления/удаления owner — создаёт Safe транзакцию, требующую M-of-N подпись.
- История изменений owners из on-chain событий.
Safe Apps iframe интеграция
Safe App — это веб-приложение, работающее внутри iframe Safe интерфейса. Для кастомного интерфейса можно встроить существующие Safe Apps (Uniswap, Aave, Compound) или создать собственные:
import { useSafeAppsSDK } from '@safe-global/safe-apps-react-sdk';
function SafeAppComponent() {
const { sdk, safe } = useSafeAppsSDK();
async function sendTransaction() {
const { safeTxHash } = await sdk.txs.send({
txs: [{
to: CONTRACT_ADDRESS,
value: '0',
data: calldata
}]
});
console.log('Proposed:', safeTxHash);
}
}
Delegates и WalletConnect
Delegates — адреса, которым Safe делегирует право предлагать транзакции (но не подписывать). Полезно для автоматизированных систем, создающих транзакции по расписанию.
Пример создания делегата через Safe SDK
// Код для добавления делегата (упрощенный)
const tx = await safeSdk.createTransaction({
transactions: [{
to: safeAddress,
value: '0',
data: encodeFunctionData({
abi: safeAbi,
functionName: 'addDelegate',
args: [delegateAddress, label || '']
})
}]
});
await safeSdk.executeTransaction(tx);
WalletConnect v2 в контексте Safe: Safe может действовать как WalletConnect peer — подключается к внешнему dApp и подписывает транзакции через Safe flow. Полезно для работы с протоколами, у которых нет Safe App.
Стек разработки
Next.js 14 + TypeScript, @safe-global/protocol-kit, @safe-global/api-kit, @safe-global/safe-apps-react-sdk, wagmi 2.x + viem для wallet connection, @tanstack/react-query для кэширования данных Safe Transaction Service. Деплой: Vercel или статичный хостинг. Для внутреннего инструмента DAO — self-hosted на собственном домене с authentication (Privy или custom JWT).
Что входит в работу
| Этап | Результат |
|---|---|
| Анализ требований | Документация с описанием сценариев и архитектурой |
| Разработка UI | Интерфейс с кастомными компонентами, интеграция с SDK |
| Тестирование | Unit-тесты, интеграционное тестирование на тестовой сети |
| Деплой | Развертывание на продакшн + инструкции по эксплуатации |
| Поддержка | 2 недели бесплатной поддержки после запуска |
Ориентиры по срокам
Кастомный интерфейс с batch-транзакциями, списком pending и декодированием calldata — 3-4 дня. С Safe Apps iframe, delegation, governance интеграцией — 1-2 недели. Закажите разработку кастомного интерфейса Safe для вашего протокола. Свяжитесь с нами для бесплатной консультации и оценки стоимости.







