Работа с WalletConnect из мобильных Dapps (часть 1)



Кошельки являются неотъемлемой частью блокчейна. Они функционируют как способ хранения наших web3-активов, как форма идентификации, для аутентификации и т.д. При создании Dapp знание того, как работать с кошельками, имеет решающее значение, поскольку это большая часть пользовательского опыта. Одна из областей, которая не так часто освещалась, это работа с кошельками при создании мобильных Dapps, и поскольку наша главная цель в Weedle — продвижение разработки Dapp для мобильных устройств, это кажется отличной темой для статьи.

Цель этого руководства — рассказать обо всем, что вам нужно знать, чтобы эффективно добавить возможность использования кошельков в ваши мобильные Dapps. Учебник будет разбит на части, каждая из которых будет посвящена более продвинутым темам, чем предыдущая.

Сначала некоторые зависимости

Я предполагаю, что у вас уже готово приложение, если нет, перейдите к этой статье, чтобы узнать, как настроить react native приложение, совместимое с web3.

Документацию по walletconnect для react native можно найти здесь. Согласно документации, нам нужны три зависимости, вы можете скопировать код ниже, чтобы установить их.

yarn add @walletconnect/react-native-dapp react-native-svg @react-native-async-storage/async-storage

Однако есть небольшая проблема: типы, указанные в библиотеке асинхронного хранения (@react-native-async-storage/async-storage), несовместимы с walletconnect. Фактически, при использовании его напрямую с установкой typescript вы увидите ошибку о том, что тип несовместим с walletconnect.
Есть несколько решений:

Вариант 1

Один из вариантов (долгий и трудный путь) — получить типы, которые ожидает walletconnect, и написать адаптер, сопоставляющий эти типы. Если вы хотите пойти по этому пути, вы можете найти файл с типами walletconnect в отдельном репозитории utils на github здесь. Вы можете создать файл и поместить в него типы, а затем использовать его в качестве типа для вашего адаптера.

Вариант 2 (мой предпочтительный вариант)

Быстрый и грязный. Исследуя функции keyvaluestorage из walletconnect, вы увидите, что они используют не только очень маленький набор функций из библиотеки async storage. Чтобы получить правильные типы, мы можем использовать типы, упомянутые в варианте 1, и просто привести их к реквизиту asyncStorage из провайдера walletconnect.

Я предпочитаю этот метод, поскольку walletconnect не использует значительное количество функций из библиотеки, поэтому отображение всех функций только потому, что используется несколько, не имеет смысла. Это может рассматриваться как временная мера, по крайней мере, пока эта проблема не будет исправлена командой WalletConnect.

Интеграция WalletConnect с нашим приложением

Согласно документации, у нас есть два способа использования WalletConnect. Мы можем использовать его как провайдер или как компонент высшего порядка; давайте остановимся на методе провайдера. Провайдер принимает несколько реквизитов, но только два из них являются обязательными, для остальных реквизитов предусмотрены значения по умолчанию, что достаточно для нашего случая использования.

Допустим, наше приложение в настоящее время выглядит следующим образом

<View style={styles.mainContainer}>
  <MainApp />
</View>
Вход в полноэкранный режим Выход из полноэкранного режима

Чтобы включить wallectconnect, нам нужно просто обернуть приложение в его провайдер следующим образом

<WalletConnectProvider
  redirectUrl={`wmw://app`} // Explained below
  storageOptions={{
    asyncStorage: AsyncStorage as unknown as IAsyncStorage,
  }}>
  <View style={styles.mainContainer}>
    <MainApp />
  </View>
</WalletConnectProvider>
Войти в полноэкранный режим Выйти из полноэкранного режима

Значение в storageOptions было описано ранее, что касается redirectUrl, то это url глубокой ссылки, на которую walletconnect перенаправляет после проверки. Подробнее об этом здесь. Я бы предпочел использовать метод обработки url перенаправления, чтобы перенаправить на представление, где я могу проверить, был ли пользователь аутентифицирован или нет, предпочтительно вернуться на текущую страницу, где пользователь пытался войти в систему, используя свой кошелек.

Теперь, когда мы обернули наше приложение провайдером walletconnect, давайте рассмотрим, как мы можем аутентифицироваться с помощью walletconnect. Чтобы объяснить это, допустим, внутри MainApp у нас есть два компонента, Auth и Dashboard. Мы хотим показывать приборную панель только после аутентификации пользователя.

// Auth.tsx
import React, {useState} from 'react'
import WalletConnectProvider, { useWalletConnect } from '@walletconnect/react-native-dapp';
...

const Auth = () => {
  const [isConnected, setIsConnected] = useState<boolean>(false);
  const connector = useWalletConnect(); // Wallet connect hook
  ...

  // Note: for example purposes only, do better and split your components into files properly
  return (
    <View>
    {
      !isConnected ? 
        <View> 
          <Button title='Login' onPress={authenticateUser} />
        </View> :
        <Dashboard />
    }
    </View>
  )
}

Вход в полноэкранный режим Выйти из полноэкранного режима

В приведенном выше коде мы делаем несколько вещей.

  • useWalletConnect — Этот хук предоставляет нам объект коннектора, который содержит все функции, необходимые для использования walletconnect.

  • isConnected — переменная состояния, которую мы можем использовать для определения того, прошел ли пользователь аутентификацию или нет.

  • Мы также используем простую кнопку для обработки вызова функции аутентификации authenticateUser, которую мы определим далее.

// Auth.tsx

// Our login function looks like this

const authenticateUser = async () => {
  if (connector.connected) {
    setIsConnected(true)
  }else{
    const session = await connector.connect();
    // The session object will contain details about the chain you are connected to and also an accounts array
    setIsConnected(true)
  }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Здесь мы сначала проверяем, аутентифицировались ли мы уже с кошельком, если нет, то вызываем .connect, чтобы пройти процесс аутентификации с нашим кошельком. Процесс выглядит так: walletconnect проверяет наличие всех кошельков на нашем устройстве и отображает их в нижнем компоненте листа, после чего мы можем выбрать конкретный кошелек, который хотим использовать (например, Metamask, Trust wallet и т.д.). Затем создается намерение, которое направляет нас к выбранному кошельку для одобрения, после одобрения мы возвращаемся по redirectUrl, который мы предоставили walletconnect.

Вызов authenticate возвращает тип ISessionStatus, который содержит информацию о сети, к которой мы подключены, например chainId, а также массив accounts, содержащий адрес нашего кошелька из подключенного кошелька.

Объект коннектора может быть получен из хука useWalletConnect в любое время и в любом компоненте нашего приложения. Объект содержит все, что нам нужно, например, наши счета и информацию о сети, поэтому нам не нужно хранить то, что мы получаем при вызове .connect.

Обработка ошибок

Потрясающе, мы почти закончили, но нам нужно обработать некоторые ошибки, например, если пользователь отклонит запрос auth. Это можно сделать, обернув наш вызов .connect в простой блок try catch, как показано ниже

// Auth.tsx

// Our login function looks like this

const authenticateUser = async () => {
  try{
    if (connector.connected) {
      setIsConnected(true)
    }else{
      const session = await connector.connect();
      // The session object will contain details about the chain you are connected to and also an accounts array
      setIsConnected(true)
    }
  }catch(e){
    // handle error here
  }
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Функциональность выхода из системы

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

// Dasboard.tsx

const Dashboard = async () => {
  ...

  const logUserOut = async () => {
    await connector.killSession();
  }

  return (
    <View>
      <Button title='Logout' onPress={logUserOut} />
      ...
    </View>
}
Вход в полноэкранный режим Выход из полноэкранного режима

Заключение

Потрясающая вещь, мы смогли создать dapp, который может аутентифицироваться с помощью walletconnect. Вы должны изучить другие возможности из документации walletconnect, например, уменьшить количество кошельков, доступных для аутентификации.
Хотя это довольно хорошая отправная точка, есть еще несколько вещей, которые нам нужно сделать, чтобы получить стабильный и рабочий dapp.

Если вам понравилась эта статья или она была вам чем-то полезна. Следите за нами здесь и в twitter, чтобы получать уведомления о выходе последующих статей. Ваше здоровье


В Weedle Labs мы работаем над созданием мобильной инфраструктуры web3. Цель — упростить разработку web3 Dapps для мобильных устройств и помочь вам охватить гораздо более широкую аудиторию, чем та, которую может предложить веб. Мы работаем с открытым исходным кодом и активно ищем соавторов для активной разработки. Напишите нам на twitter @weedle_app или tech@joinweedle.com.
Если вы также хотите узнать, когда мы запустимся и получить больше подробностей, вы можете проверить https://joinweedle.com.

Оцените статью
devanswers.ru
Добавить комментарий