Реалізація маркетплейсу внутрішньоігрових предметів у мобільній GameFi-грі
Розробка NFT-маркетплейсу всередині мобільної гри — одне з найскладніших завдань, з яким ми стикаємося в GameFi-проєктах. За нашими даними, до 70% користувачів кидають маркетплейси через високі газові комісії та складний онбординг. Тут стикаються два світи: звичний мобільний UX (швидко, інтуїтивно, без seed-фраз) і блокчейн-реальність (gas fees, час підтвердження транзакцій, ownership через гаманець). Якщо не вирішити цю суперечність — маркетплейс просто не використовуватимуть. Ми гарантуємо рішення завдяки досвіду в інтеграції Account Abstraction та off-chain лістингів. Якщо ви зіткнулися з падінням користувачів або високими газовими витратами — зв'яжіться з нами, ми допоможемо.
Чому off-chain лістинги критичні для мобільної GameFi?
Повністю on-chain маркетплейс (як OpenSea v1) — кожен лістинг це транзакція. На мобільних пристроях це недоцільно: користувач не платитиме $0.50–5 газу за кожне виставлення предмета на продаж. Off-chain лістинги працюють у 10 разів швидше та економлять до 90% на газі.
Правильна архітектура для GameFi-мобайлу — off-chain лістинги з on-chain розрахунками:
- Продавець підписує лістинг оффчейн (
signTypedData/ EIP-712) — транзакції немає, газу немає - Лістинг зберігається в базі даних додатку
- Покупець натискає «Купити» — тільки в цей момент відбувається on-chain транзакція
- Смарт-контракт верифікує підпис продавця, переводить NFT покупцю та оплату продавцю атомарно
struct Listing { address seller; address nftContract; uint256 tokenId; address paymentToken; uint256 price; uint256 expiry; uint256 nonce; } bytes32 public constant LISTING_TYPEHASH = keccak256( "Listing(address seller,address nftContract,uint256 tokenId,address paymentToken,uint256 price,uint256 expiry,uint256 nonce)" ); function buyItem(Listing calldata listing, bytes calldata signature) external { require(block.timestamp < listing.expiry, "Listing expired"); require(!usedNonces[listing.seller][listing.nonce], "Nonce used"); bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(LISTING_TYPEHASH, listing))); require(ECDSA.recover(digest, signature) == listing.seller, "Invalid signature"); usedNonces[listing.seller][listing.nonce] = true; IERC20(listing.paymentToken).transferFrom(msg.sender, listing.seller, listing.price); IERC721(listing.nftContract).safeTransferFrom(listing.seller, msg.sender, listing.tokenId); } Цей підхід використовують Seaport (OpenSea v2) та Blur — перевірена схема.
Як забезпечити безшовний UX покупки NFT на мобільному?
Головна проблема — як користувач підписує транзакцію покупки без seed-фрази в додатку. Розглянемо три варіанти:
| Метод | UX | Безпека | Складність реалізації |
|---|---|---|---|
| Account Abstraction (Privy/Dynamic) | Біометрія, без газу | Висока (smart account) | Середня |
| WalletConnect (MetaMask/Phantom) | Deep Link, вихід з додатку | Висока (зовнішній гаманець) | Низька |
| Кастодіальний гаманець (Fireblocks MPC) | Вбудований, максимально простий | Середня (ключі на сервері) | Середня |
Для GameFi з мільйонною аудиторією ми рекомендуємо Account Abstraction. Користувач входить через Google/Apple — отримує smart account автоматично. Paymaster спонсорує газ, економія до 90% на комісіях. Наша команда сертифікованих інженерів має досвід впровадження Privy та Dynamic в ігрових проєктах.
Що входить в роботу
- Смарт-контракт маркетплейсу з аудитом
- Бекенд: індексування метаданих, лістинги, повнотекстовий пошук
- Мобільний клієнт: грид предметів, картка, потік покупки
- Інтеграція гаманця (WalletConnect або Account Abstraction)
- Фільтри, сортування, історія угод
- Документація по API та смарт-контракту
- Тестова документація та підтримка при запуску
Як працює off-chain лістинг з точки зору користувача?
Користувач заходить у маркетплейс, обирає предмет і натискає «Купити». Система перевіряє підпис лістингу, який продавець створив заздалегідь off-chain. Транзакція в блокчейні відбувається тільки в цей момент — користувач підписує її через свій smart account (біометрія). Весь процес займає менше 10 секунд, а газ спонсорується Paymaster.
Процес покупки: покроково
Кожен NFT-предмет — це tokenId + метадані з tokenURI на IPFS або centralised CDN. Ми індексуємо метадані в базу даних і віддаємо через REST API — мобільний клієнт ніколи не звертається до IPFS напряму. Зображення предметів доставляються через CDN (CloudFront / Cloudflare), з кешуванням на клієнті через Kingfisher (iOS) або Coil (Android). Lazy loading у списку — LazyColumn з AsyncImage в Compose, LazyVGrid в SwiftUI.
struct MarketplaceGridView: View { @StateObject var viewModel: MarketplaceViewModel let columns = [GridItem(.adaptive(minimum: 160), spacing: 12)] var body: some View { ScrollView { LazyVGrid(columns: columns, spacing: 12) { ForEach(viewModel.items) { item in NFTItemCard(item: item) .onAppear { if item == viewModel.items.last { viewModel.loadNextPage() } } } } .padding() } } } Типові помилки при розробці
- Завантаження метаданих напряму з IPFS (повільно, нестабільно) — правильне рішення: бекенд-індексування.
- Використання on-chain лістингів (дорогий газ) — рішення: off-chain підписи EIP-712.
- Відсутність перевірки nonce та терміну дії лістингу (replay attack) — у коді вище це враховано.
Фільтрація та пошук
Фільтри: рідкість (Rare/Epic/Legendary), тип предмета (зброя/броня/улюбленець), ціновий діапазон, актив оплати. Сортування: за ціною, за датою лістингу, за рідкістю. Повнотекстовий пошук за ім'ям предмета — через PostgreSQL tsvector або Elasticsearch на бекенді. Атрибути NFT-предметів індексуються в реляційну таблицю при мінті — не парсяться з IPFS JSON при кожному запиті.
Роялті та модерація
При кожному P2P-продажу на вторинному ринку — автоматичне відрахування роялті (2–5%) в гаманець студії. ERC-2981 (NFT Royalty Standard) задає royaltyInfo(tokenId, salePrice) — смарт-контракт маркетплейсу викликає це перед розрахунком і утримує комісію.
Система скарг на підозрілі лістинги (чит-предмети, дублікати). Адміністративний endpoint POST /listings/{id}/delist — видаляє лістинг з бази. On-chain нічого не змінюється (транзакції не було), предмет просто перестає відображатися. Блокування вкрадених токенів (якщо акаунт зламано) — blacklist на рівні смарт-контракту: blockedTokens[tokenId] = true з перевіркою в buyItem.
Терміни та вартість
| Етап | Термін |
|---|---|
| Смарт-контракт маркетплейсу + аудит | 2 тижні |
| Бекенд: індексування, лістинги, пошук | 2 тижні |
| Мобільний клієнт: грид, картка, покупка | 2–3 тижні |
| Гаманець (WalletConnect або Account Abstraction) | 1 тиждень |
| Фільтри, сортування, історія угод | 1 тиждень |
Разом: 8–10 тижнів. Вартість розраховується індивідуально після аналізу вимог. Отримайте консультацію щодо вашого проєкту прямо зараз — зв'яжіться з нами для безкоштовної оцінки.







