В этом уроке мы будем использовать протокол Rarible для создания простого, но очень практичного приложения. В этом приложении пользователи смогут подключить свой кошелек Metamask, просмотреть все принадлежащие им NFT (в блокчейне Ethereum) и выставить их на продажу!

Зачем углубляться в надежность и тратить месяцы на разработку и тестирование собственного контракта, если можно просто БЕСПЛАТНО использовать законченное и полностью надежное решение? Только с JS! 😄

Без лишних слов, давайте погрузимся в это!

Приложение имеет 3 экрана:

  1. Экран кнопки «Подключить кошелек»

Поскольку функциональность нашего приложения ограничена (показаны только NFT, принадлежащие пользователю), нет необходимости что-либо показывать на этом первом экране, если пользователь еще не подключил свой кошелек. Эта функция привязана к событиям, поэтому при каждом подключении или отключении кошелька содержимое на экране будет обновляться.

2. Экран «Просмотрите свои NFT»

Главный экран нашего приложения. Мы используем хороший метод загрузки, при котором изображения отображаются только после того, как они полностью загружены (бонус: я также покажу вам, как это сделать).

3. Экран «Выставьте свой NFT на продажу»

Здесь мы можем создать ордер на продажу, который может быть принят другими. Покупатель сможет подписать транзакцию, обменяв токены ETH на собственность NFT.

Если вам удобнее работать с кодом, вот ссылка на репозиторий github для этого проекта:

https://github.com/kolberszymon/nft-marketplace-tutorial

Клонируйте его, и вы будете готовы к работе.

0. Архитектура приложения

Давайте сначала немного поговорим о том, почему мы используем то, что используем. В качестве фреймворка я выбрал NextJS. Он имеет четкую структуру проекта и обеспечивает маршрутизацию из коробки. Каждая папка в папке pages с индексным файлом в ней преобразуется в URL-адрес. Это позволяет нам использовать генератор статических сайтов, который является очень крутой функцией, и, поскольку NextJS является родственником React, мы также можем использовать контекст. Мы будем использовать его, чтобы обернуть наше приложение в EthereumContext, который отслеживает, подключен ли кошелек или нет. Что касается Type Script, я в основном использовал его в образовательных целях, чтобы вы могли четко видеть каждый тип.

1. Экран кнопки «Подключить метамаску»

Самое полезное и важное, что вы можете узнать из этого экрана, — это как правильно создавать контекст. Давайте проанализируем это.

Как видите, мы импортировали две функции реагирования, createContext и useContext, чтобы иметь возможность создавать контекст. После этого мы определяем ContextProps, которые будем использовать на наших экранах. (Не пугайтесь этой штуки «Partial», это просто способ создать пустой объект контекста в TypeScript 😉). Мы экспортируем EthereumContext, а также используем EthContext. EthereumContext потребуется, чтобы обернуть в него компонент приложения, а useEthContext будет использоваться для извлечения текущих сохраненных значений.

Давайте взглянем на файл _app.tsx, который является основным файлом для приложений NextJS.

Как видите, здесь есть 2 эффекта useEffect: один с пустым массивом зависимостей и один, отслеживающий изменения web3. Первый отвечает за проверку того, поддерживает ли наш браузер web3 (другими словами, он проверяет, установлен ли Metamask и есть ли в окне глобальная переменная Ethereum). Если это не так, мы создаем прослушиватель событий, который будет запускаться при инициализации Ethereum.

Второй позволяет нам всегда обновлять текущую выбранную учетную запись при изменении web3.

Приведенные выше процедуры представляют собой довольно стандартный способ запуска криптопроекта. Мы деструктурируем свойство Ethereum из оконных объектов, а затем проверяем, определено ли оно и является ли оно Metamask. После этого мы устанавливаем прослушиватель событий для объекта Ethereum, чтобы устанавливать учетные записи каждый раз, когда мы переключаем учетную запись или отключаем ее. И последнее, но не менее важное, мы устанавливаем объект web3.

Как видите, setCurrentlyConnectedAccount используется исключительно для целей обновления. Он получает ваши учетные записи Metamask и, если находит, устанавливает первую учетную запись в массиве как текущую используемую. Первый элемент в списке, возвращаемый функцией getAccounts, всегда является текущим выбранным.

Теперь самое интересное: файл _app.tsx.

Вся тяжелая работа по настройке вещей окупилась. Теперь мы просто элегантно оборачиваем приложение в EthereumContext.Provider, передаем ранее определенные значения, которые будут автоматически обновляться в случае каких-либо изменений (поскольку мы установили для них прослушиватели событий), и вуаля! Нам больше не нужно беспокоиться о кошельках, все остальное строго связано с NFT! 🤩

2. Экран «Просмотрите свои NFT»

Теперь мы узнаем, как мы можем составить список принадлежащих NFT. Если вы работаете с Rarible, вы можете найти документацию по API здесь. Мы будем использовать конечную точку getNftItemsByOwner.

Сначала мы определяем тип NftItem. Есть гораздо больше свойств, чем эти, как вы можете видеть на экране ответа API, но эти четыре удовлетворят наши потребности.

Обратите внимание на то, как мы используем EthContext здесь. ✨

Это вся логика, необходимая для отображения принадлежащих NFT. Благодаря Rarible API вы можете сделать это буквально всего за несколько строк. Во-первых, нам нужно получить данные из Rarible API, а затем сопоставить возвращаемый список, чтобы настроить его на тип NftItem. Кнопка HandleConnectWallet используется для подключения вашей учетной записи Metamask. Да, вот как вы это делаете, всего с ОДНОЙ строкой кода!!! Люди часто боятся Web3, но на самом деле программировать в нем довольно просто…

Давайте завершим рендеринг HTML! Здесь у нас есть три состояния: не подключено, подключено, но NFT еще не выбрано и готово. Мы показываем только то, что нужно. В последнем случае мы сопоставляем все NFT и визуализируем тайлы для каждого из них.

Вот бонус, о котором я упоминал ранее! Если вы хотите создать изображение, которое будет мерцать до тех пор, пока оно полностью не загрузится, сделайте это следующим образом:

Создайте состояние isLoaded, которое определяет тип отображения img. Если он еще не загружен, ему присваивается значение none, в противном случае это блочный тип. У изображений есть свойство onLoad, которое позволяет нам что-то делать, когда изображение полностью загружено. В этом случае мы просто устанавливаем для isLoaded значение true, что соответствует нашей предыдущей логике.

CSS для этой анимации выглядит так. Вы можете найти все исходники на github. Не стесняйтесь «вдохновляться» этим. И, да, под «вдохновиться» я имею в виду Ctrl + C, Ctrl + V. 😛

2. Экран «Выставьте свои NFT на продажу»

Хорошо, вот самая интересная часть этого урока: как мы можем выставить NFT на продажу с помощью Rarible? Давайте посмотрим:

Мы передаем tokenId в URL-адресе, поэтому сначала нам нужно получить его с помощью следующего маршрутизатора. Если tokenId существует, то есть если кто-то не передал неправильный URL, мы получим tokenData и tokenSellOrder. К сожалению, это две разные конечные точки, поэтому мы не можем получить цену токена и информацию в одном запросе. Теперь давайте перейдем к чему-то очень важному, что, возможно, сэкономит вам время.

В Rarible существуют разные конечные точки в зависимости от того, какую цепочку вы используете в настоящее время. Поскольку мы в основном используем цепочку тестирования для целей разработки, это редко будет api.rarible.com. Все, что вам нужно нужно указать текущую сеть, выбрав ее из перечисления NETWORKS. Вы также должны импортировать переменную currentChainInfo и использовать ее.

Держитесь, мы почти закончили!!!

Обработчик кнопки довольно прост, так как у нас хорошая структура кода. Здесь мы в основном передаем все необходимые аргументы и делегируем их функции createSellOrder.

Существует несколько типов ордеров на продажу, но в данном случае мы выбираем «MAKE_ERC721_TAKE_ETH», что буквально означает: я хочу получить токены ETH в обмен на мой ERC-721 NFT.

Чтобы создать ордер на продажу, мы должны указать тип объекта, который будет соответствовать схеме запроса (это основано на EIP712). Это базовая механика копировать и вставить, поэтому в этой части вы не можете слишком много вводить новшеств.

После того, как объект создан, мы теперь хотим подписать его.

Я знаю, что на первый взгляд это выглядит странно, но на самом деле это не так! Давайте пройдемся по нему.

Во-первых, мы просто «привязываем» наши данные. В двух словах, мы отправляем байты в контракт, поэтому объект должен быть в виде строки. Затем мы используем провайдера, которым в нашем случае является Metamask, чтобы пользователь мог подписать транзакцию. Переменная Sig — это все, что нам нужно от этой функции.

Мы создали шаблон для наших данных в виде объекта, преобразовали его в формат JSON, подписали его с помощью Metamask и… в общем, все. Осталось сделать еще одну вещь: добавить подпись. Мы добавляем его по порядку, вот так:

и мы готовы опубликовать это!

Мы включили raribleJson в качестве тела запроса, установили заголовки в application/json, и все готово. Вот и все! Отныне он уже сохранен на Rarible, поэтому, если мы хотим взаимодействовать с ним, мы делаем это через API-запросы. 😊

Краткое содержание

Это было не так уж сложно, не так ли? В этом руководстве мы создали место, где можно увидеть ваши NFT, а также выставить их на продажу. Для этого мы использовали Rarible, который позволяет нам на 100 % взаимодействовать со смарт-контрактами через их API.

Здесь вы можете найти проект github для этого:

GitHub — kolberszymon/nft-marketplace-tutorial

Это стартовый шаблон Next.js 11.x, TailwindCSS 2.x и TypeScript 4.x. Дополнительные сведения см. в моем блоге. Nextjs…github.com

Здесь вы можете найти живые примеры:

Учебное пособие по торговой площадке NFT

Изменить описаниеoptimistic-swartz-2725f5.netlify.app

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

Небольшой раздор DAO: https://discord.com/invite/zqsZsEWBbN

Рассмотрите возможность подписки на нашу еженедельную рассылку: https://www.getrevue.co/profile/raribleprotocol

Моя личная контактная информация:

Дискорд: Шимон из Польши#6093

Github: колбершимон

Linkedin: koblerszymon

Удачного кодирования, амигос!