Перейти до вмісту

Як відкрити dApp у мобільних гаманцях Solana

React-dApp, побудований на @solana/wallet-adapter-react, без проблем під’єднує десктопні гаманці, але на телефоні той самий потік розсипається: гаманець має відкрити dApp у власному вбудованому браузері, а deeplinks, які мали б це зробити, просто мовчки не спрацьовують. Backpack виводить на сторінку «завантажте застосунок»; Solflare відкриває застосунок, але ніколи — сайт; здається, що не працює жоден варіант. Ми розібрали проблему на частини, і виявилося, що це чотири окремі проблеми з одним спільним симптомом.

Чотири проблеми

  • Посилання для Backpack було сформоване неправильно. Єдиний задокументований формат — https://backpack.app/ul/v1/browse/<url>?ref=<ref>: універсальне посилання із цільовим URL у шляху та обов’язковим ref. Здогадка з власною схемою на кшталт backpack://ul/v1/browse?url=... не збігається з жодним маршрутом, який реєструє застосунок, тож користувач опиняється на сторінці встановлення гаманця.
  • Solflare теж потребує свого універсального посилання: https://solflare.com/ul/v1/browse/<url>?ref=<ref>, а не голої схеми solflare://. Гола схема може запустити застосунок, не спрямувавши його — а це саме те, що «застосунок відкривається, але вкладку із сайтом доводиться відкривати вручну».
  • Обидва параметри мають бути закодовані. url — це повна абсолютна адреса dApp, а ref — origin, який робить запит; кожен проходить через encodeURIComponent. Незакодований ? або & у цілі псує розбір, і гаманець відкривається на своєму головному екрані замість вкладки браузера.
  • Спосіб запуску важить не менше за саме посилання. Універсальні посилання перемикають застосунки лише під час навігації, якій довіряє операційна система — і вони навмисно не роблять нічого, коли їх вставляють в адресний рядок, і саме так цілком коректне посилання «не працює» під час тестування.

Задокументовані формати

  • Phantom: https://phantom.app/ul/browse/<url>?ref=<ref> — саме тут без /v1.
  • Solflare: https://solflare.com/ul/v1/browse/<url>?ref=<ref>
  • Backpack: https://backpack.app/ul/v1/browse/<url>?ref=<ref>

Один шаблон покриває всі три:

const WALLET_BROWSE = {
  phantom: (url, ref) =>
    `https://phantom.app/ul/browse/${url}?ref=${ref}`,
  solflare: (url, ref) =>
    `https://solflare.com/ul/v1/browse/${url}?ref=${ref}`,
  backpack: (url, ref) =>
    `https://backpack.app/ul/v1/browse/${url}?ref=${ref}`,
};

function walletBrowseLink(
  walletName,
  targetUrl = window.location.href,
) {
  const build = WALLET_BROWSE[walletName.toLowerCase()];
  if (!build) return null;
  return build(
    encodeURIComponent(targetUrl),
    encodeURIComponent(window.location.origin),
  );
}

Як запустити посилання, щоб iOS та Android його прийняли

  • Рендерте справжній якір, обчислений заздалегідь. Звичайний <a href={walletBrowseLink('phantom')}> — найнадійніший спосіб запуску на обох платформах.
  • Якщо це має бути програмно, присвоюйте window.location.href синхронно всередині обробника натискання — без await, без fetch, без setTimeout перед цим. Після асинхронної роботи контекст жесту втрачено, і iOS відкочується до вебсайту гаманця. Ніколи не використовуйте window.open.
  • Ніколи не тестуйте вставлянням в адресний рядок. Універсальні посилання навмисно там не спрацьовують; тестуйте посиланням, на яке натискають, або QR-кодом, який сканує камера.
  • Зважайте на webview месенджерів. Відкриті у вбудованому браузері Telegram або Instagram, універсальні посилання часто просто поглинаються, і натомість завантажується звичайний вебсайт гаманця. Визначення за user-agent — у кращому разі евристика, тож дайте користувачам ще й видимий запасний вихід: «відкрийте в Safari чи Chrome, а тоді під’єднайтеся».

Ґрунтовніше виправлення на Android

Саморобні deeplinks — це історія про iOS. На Android Mobile Wallet Adapter від Solana Mobile дає dApp, що працює в мобільному браузері, під’єднатися прямо до встановленого застосунку гаманця, узагалі без гаку через вбудований браузер. Свіжі версії @solana/wallet-adapter-react реєструють мобільний адаптер автоматично, тож оновлення пакетів wallet-adapter може полагодити Android саме собою. Цільова архітектура: Mobile Wallet Adapter на Android, універсальні browse-посилання на iOS, де Apple не дозволяє нічого рівноцінного.

Перевірка на пристрої

  1. Справжній пристрій, встановлений гаманець, посилання відкрито із системного браузера — не з месенджера.
  2. Натисніть відрендерене посилання або відскануйте QR-код; ніколи не вставляйте в адресний рядок.
  3. Переконайтеся, що гаманець відкривається і dApp завантажується у вкладці його вбудованого браузера — саме друга половина і ламається.
  4. Повторіть без встановленого гаманця: універсальне посилання має деградувати до вебсайту гаманця. Якщо ця сторінка з’являється, коли застосунок встановлено, — посилання або спосіб запуску все ще неправильні.
  5. Потім перевірте шлях через месенджер і додайте підказку «відкрийте у браузері», якщо там не спрацьовує.

Джерела

Саме такі задачі ми розплутуємо для клієнтів. Зв'язатися з нами.

Усі нотатки