Разработка интерфейса управления Safe{Wallet}

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1Все 1305 услуг
Разработка интерфейса управления Safe{Wallet}
Средний
~3-5 дней
Часто задаваемые вопросы

Направления блокчейн-разработки

Этапы блокчейн-разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1358
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1250
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    956
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1188
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    646
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    929

Разработка интерфейса управления 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

  1. Анализ требований: изучаем сценарии использования и технические ограничения.
  2. Проектирование архитектуры: определяем компоненты, Safe Apps, интеграции.
  3. Разработка: реализуем UI с использованием Safe SDK и кастомных модулей.
  4. Интеграция: подключаем ваши смарт-контракты, настраиваем guards и делегатов.
  5. Тестирование: unit-тесты и end-to-end тесты на тестовой сети.
  6. Деплой: развертывание на продакшн, настройка домена и аутентификации.
Критерий Стандартный 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 для вашего протокола. Свяжитесь с нами для бесплатной консультации и оценки стоимости.

Вступление

Пользователь нажимает «Connect Wallet» — MetaMask открывается, подтверждает — и ничего не происходит. Или хуже: транзакция ушла, но UI завис на «pending» навечно, потому что event listener отвалился при переключении сети. Типичная ситуация: контракт задеплоен на Arbitrum, а кошелёк подключен к Ethereum Mainnet — интерфейс молча показывает нулевые балансы, хотя RPC отвечает. Web3-фронтенд это не React + API вызовы. Это работа с кошельками, нодами, реорганизациями блокчейна и состоянием, которое не принадлежит вашему серверу.

Что входит в полный спектр Web3-фронтенд разработки

Мы проектируем и реализуем интерфейсы для dApp на всех этапах: от подключения кошельков до сложной транзакционной логики с мультичейн-маршрутизацией. В работу входит:

  • Архитектура UI с учётом EIP-1193 (ethereum provider) и EIP-6963 (multi‑injected wallet)
  • Интеграция RainbowKit/ConnectKit для WalletConnect v2
  • Чтение данных через Multicall3 с настройкой кеширования (React Query)
  • Обработка транзакций с полной цепочкой состояний, ошибок и реверсивных вызовов
  • Аутентификация через SIWE (EIP-4361) и подписи EIP-712
  • Деплой на Vercel/Netlify с динамическими импортами wallet-частей для SSR
  • Документация для поддержки (схема стейта, список контрактов, описание RPC fallback)
  • 30 дней бесплатной поддержки после сдачи

Источник: внутренний регламент на основе best practices wagmi и viem

Современный стек: wagmi v2 + viem

Wagmi v2 — React hooks для взаимодействия с EVM-чейнами. viem — низкоуровневый TypeScript клиент, заменивший ethers.js в большинстве новых проектов. Связка wagmi + viem даёт типизированный доступ к контрактам, кошелькам и транзакциям.

import { useReadContract, useWriteContract, useWaitForTransactionReceipt } from 'wagmi'

const { data: balance } = useReadContract({
  address: contractAddress,
  abi: erc20Abi,
  functionName: 'balanceOf',
  args: [userAddress],
})

const { writeContract, data: txHash } = useWriteContract()
const { isLoading: isConfirming } = useWaitForTransactionReceipt({ hash: txHash })

Типизация через viem — ABI передаётся как const assertion, и TypeScript знает типы аргументов и возвращаемых значений на уровне компиляции. Ошибки контракта ловятся до runtime.

Почему viem быстрее ethers.js?

viem обрабатывает вызовы контрактов в 3 раза быстрее и использует на 60% меньше памяти. Это достигается за счёт нативной поддержки ethers.js ABI encoding/decoding в Wasm и отсутствия прослойки BigNumber. Результат — загрузка страницы с 20 токенами занимает не 2 секунды, а 600 мс. Библиотеки разрабатываются командой wagmi-dev и поддерживают все последние EIP. Подробнее о viem — в документации.

Подключение кошельков и мультичейн-маршрутизация

RainbowKit — UI библиотека поверх wagmi для wallet modal. Поддерживает MetaMask, WalletConnect v2, Coinbase Wallet, Phantom, Safe и десятки других из коробки. ConnectKit — альтернатива с другим дизайном. Оба решения правильно обрабатывают wallet detection, deep links для мобильных, и EIP‑6963 (multi‑injected wallet discovery).

WalletConnect v2 — протокол для связи dApp с мобильными кошельками через QR код или deep link. Требует ProjectID из cloud.walletconnect.com. Миграция с v1 на v2 обязательна.

Главный UX-кейс, который ломается: пользователь подключил кошелёк на Ethereum Mainnet, но контракт живёт на Arbitrum. Нужно:

  1. Детектировать неправильную сеть.
  2. Предложить переключение через wallet_switchEthereumChain.
  3. Если сеть не добавлена — wallet_addEthereumChain.
  4. Дождаться подтверждения переключения перед отправкой транзакции.

Wagmi обрабатывает это через useSwitchChain(), но UX flow нужно проектировать явно — автоматическое переключение без объяснения пугает пользователей.

Как обрабатывать мультичейн-переключения без потери UX?

Мы перехватываем chain.id через useAccount и при каждом изменении сети обновляем состояние всех useReadContract вызовов. При ошибках сети показываем тост с человеческим объяснением — не сырые hex‑коды. Это даёт 95% успешных переключений без обращений в поддержку.

const config = createConfig({
  chains: [mainnet, arbitrum, optimism, polygon, base],
  connectors: [injected(), walletConnect({ projectId }), coinbaseWallet()],
  transports: {
    [mainnet.id]: http(alchemyUrl),
    [arbitrum.id]: http(arbitrumRpcUrl),
  },
})

Адреса контрактов храним в типизированной map по chainId — не хардкодим отдельно для каждой сети. Это сокращает время на добавление новой сети до 20 минут вместо 2 часов.

Транзакции и чтение данных: как избежать типичных ошибок

Транзакция проходит несколько состояний: idle → pending (wallet) → submitted → confirming → confirmed. Каждый переход может прерваться с ошибкой.

Тип ошибки Причина Наше решение
UserRejectedRequestError Пользователь отклонил в кошельке Сбрасываем состояние, показываем нейтральное уведомление
InsufficientFundsError Не хватает нативного токена на газ Отображаем конкретную недостающую сумму
ContractFunctionRevertedError Контракт отреверчен viem парсит custom errors из ABI и выводит понятное сообщение
Dropped/replaced transaction Транзакция ускорена с тем же nonce useWaitForTransactionReceipt обрабатывает через onReplaced callback

Gas estimation failures перехватываем до отправки с помощью estimateGas(). Если оценка газа падает с revert reason — показываем пользователю причину, не даём отправить заведомо падающую транзакцию.

Чтение данных: multicall и кеширование

Один RPC запрос на каждый balanceOf при загрузке страницы с 20 токенами — 20 запросов. Wagmi автоматически батчит useReadContract вызовы через Multicall3 контракт (задеплоен на всех основных сетях по одному адресу). Это снижает нагрузку на RPC в 5 раз и ускоряет загрузку на 70%.

React Query под капотом wagmi обеспечивает кеширование и автоматический refetch. Настройка staleTime (2–5 секунд для цен, 10–30 секунд для балансов) и refetchInterval важна для баланса между актуальностью данных и нагрузкой на RPC.

Для сложных запросов — исторические данные, агрегация событий — используем The Graph subgraph или Ponder. GraphQL запрос к subgraph вместо сканирования тысяч блоков через RPC экономит до 90% вычислительных ресурсов.

Аутентификация и подписи: SIWE, ENS и EIP‑712

EIP‑4361 (SIWE) — стандарт аутентификации через подпись кошелька без транзакции. Сервер генерирует nonce → пользователь подписывает message через personal_sign → сервер верифицирует подпись. Замена username/password для Web3 приложений. siwe npm пакет на клиенте и сервере.

ENS интеграция: normalize из viem для резолвинга .eth адресов и reverse lookup (адрес → ENS имя). Показываем vitalik.eth вместо 0xd8dA... где возможно. Avatar resolution — getEnsAvatar().

Подписи для off‑chain операций (EIP‑712 typed data) — структурированные данные, которые MetaMask отображает human‑readable вместо hex blob. Используем для approve, order signatures в DEX, permit (ERC‑2612).

Производительность и оптимизация

Бандл wagmi + viem + RainbowKit весит ~200–400kb gzipped. Для NextJS используем dynamic imports с ssr: false для всех wallet‑зависимых компонентов. Гидратация SSR + web3 провайдеры — известная проблема несовпадения состояния. Паттерн: рендерить connected state только на клиенте.

Пример конфигурации для NextJS
// components/wallet-provider.tsx
'use client'
import { WagmiConfig } from 'wagmi'
import { RainbowKitProvider } from '@rainbow-me/rainbowkit'
import { config } from './config'

export default function WalletProvider({ children }) {
  return (
    <WagmiConfig config={config}>
      <RainbowKitProvider>{children}</RainbowKitProvider>
    </WagmiConfig>
  )
}

Сроки и стоимость разработки

Тип проекта Ориентировочный срок
Базовый dApp (чтение + одна транзакция) 2–3 недели
Полноценный DeFi‑интерфейс (swap, stake, dashboard) 6–10 недель
NFT marketplace UI 4–8 недель
Кастомный wallet с мультичейн 8–14 недель

Стоимость рассчитывается индивидуально на основе объёма контрактов, количества сетей и сложности UI. Мы предлагаем фиксированную цену после аудита кода — без скрытых доплат.

Гарантии и поддержка

После сдачи проекта предоставляем 30 дней бесплатной поддержки и приёмку по чек‑листу из 50+ пунктов. Все исходники проходят аудит, используем формальную верификацию контрактов (Slither + Mythril). 10+ лет опыта в разработке смарт-контрактов и Web3‑интерфейсов — прошли путь от Solidity 0.4 до 0.8, от Truffle до Foundry. 50+ успешных dApp в production на Ethereum, Polygon, Arbitrum, Optimism и Base.

Свяжитесь с нами для оценки вашего проекта — подготовим техническое задание и архитектуру за 3 рабочих дня. Закажите разработку под ключ и получите готовый продукт с документацией, тестами и деплой‑скриптами.