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

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка интерфейса управления Safe{Wallet}
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1221
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1163
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    855
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1056
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    828

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

Safe{Wallet} (бывший Gnosis Safe) — стандарт de facto для корпоративных и DAO трежури. Стандартный интерфейс на app.safe.global покрывает 80% сценариев, но как только появляются требования специфичные для протокола — кастомные Safe Apps, batch транзакции через Safe Transaction Builder, интеграция с governance модулями или кастомные guards — нужен собственный интерфейс.

Safe SDK: архитектура интеграции

Safe Protocol Kit

Основной инструмент для управления Safe через TypeScript:

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
});

Safe Transaction Service хранит pending транзакции off-chain и позволяет другим владельцам Safe найти их и подписать без прямой координации.

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 репозиторий (4byte.directory или локальный registry known ABIs проекта). Нераспознанные вызовы показываются как hex с предупреждением.

Форма создания транзакции

Для non-technical пользователей (например, финансовый директор DAO) важна форма с абстракцией над raw calldata:

// Форма для DeFi операций — без ввода 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';

// Внутри Safe App iframe
function SafeAppComponent() {
  const { sdk, safe } = useSafeAppsSDK();

  async function sendTransaction() {
    // Транзакция не требует wallet — отправляется через Safe SDK
    const { safeTxHash } = await sdk.txs.send({
      txs: [{
        to: CONTRACT_ADDRESS,
        value: '0',
        data: calldata
      }]
    });
    console.log('Proposed:', safeTxHash);
  }
}

Delegates и WalletConnect

Delegates — адреса, которым Safe делегирует право предлагать транзакции (но не подписывать). Полезно для автоматизированных систем, которые создают транзакции по расписанию (выплата grants, rebalancing).

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 и chain interaction, @tanstack/react-query для кэширования данных Safe Transaction Service.

Деплой: Vercel или статичный хостинг. Для внутреннего инструмента DAO — self-hosted на собственном домене с authentication (Privy или custom JWT).

Ориентиры по срокам

Кастомный интерфейс для конкретного Safe с batch транзакциями, списком pending и декодированием calldata для известных контрактов — 3-4 дня. С Safe Apps iframe, delegation управлением, governance интеграцией и полной историей операций — 1-2 недели.