Документація SolanaСпецифікація

Специфікація Solana Pay v1

Підсумок

Стандартний протокол для кодування запитів транзакцій Solana в URL-адресах для здійснення платежів та інших варіантів використання.

Цей стандарт черпає натхнення з BIP 21 та EIP 681.

Мотивація

Стандартний URL-протокол для запиту нативних переказів SOL, переказів токенів SPL та транзакцій Solana забезпечує кращий користувацький досвід у різних додатках та гаманцях екосистеми Solana.

Ці URL-адреси можуть бути закодовані в QR-кодах або NFC-мітках, або надіслані між користувачами та додатками для запиту платежу та складання транзакцій.

Додатки повинні переконатися, що транзакція підтверджена і є дійсною, перш ніж надавати товари чи послуги, що продаються, або надавати доступ до об'єктів чи подій.

Мобільні гаманці повинні зареєструватися для обробки URL-схеми, щоб забезпечити безперебійний, але безпечний досвід при виявленні URL-адрес Solana Pay у середовищі.

Стандартизуючи простий підхід до вирішення цих проблем, ми забезпечуємо базову сумісність додатків і гаманців, щоб розробники могли зосередитися на абстракціях вищого рівня.

Специфікація: Запит на переказ

URL-адреса запиту на переказ Solana Pay описує неінтерактивний запит на переказ SOL або токена SPL.

solana:<recipient>
?amount=<amount>
&spl-token=<spl-token>
&reference=<reference>
&label=<label>
&message=<message>
&memo=<memo>

Запит є неінтерактивним, оскільки параметри в URL-адресі використовуються гаманцем для безпосереднього складання транзакції.

Одержувач

Одне поле recipient є обов'язковим як шлях. Значення має бути кодованим у base58 публічним ключем нативного облікового запису SOL. Асоційовані токенові облікові записи не повинні використовуватися.

Натомість, щоб запитати переказ токена SPL, необхідно використовувати поле spl-token для вказівки адреси mint токена SPL, з якої має бути отримана адреса асоційованого токенового облікового запису одержувача.

Сума

Одне поле amount дозволено як необов'язковий параметр запиту. Значення повинно бути невід'ємним цілим числом або десятковим числом «користувацьких» одиниць. Для SOL це SOL, а не lamport. Для токенів використовуйте uiAmountString, а не amount.

0 є дійсним значенням. Якщо значення є десятковим числом менше 1, воно повинно мати провідний 0 перед .. Наукова нотація заборонена.

Якщо значення не надано, гаманець повинен запитати у користувача суму. Якщо кількість десяткових знаків перевищує підтримувану для SOL (9) або SPL Token (специфічну для mint), гаманець повинен відхилити URL як некоректний.

SPL Token

Одне поле spl-token дозволено як необов'язковий параметр запиту. Значення повинно бути публічним ключем облікового запису mint SPL Token у кодуванні base58.

Якщо поле надано, необхідно використовувати конвенцію Associated Token Account, і гаманець повинен включити інструкцію TokenProgram.Transfer або TokenProgram.TransferChecked як останню інструкцію транзакції.

Якщо поле не надано, URL описує нативний переказ SOL, і гаманець повинен включити інструкцію SystemProgram.Transfer як останню інструкцію транзакції замість цього.

Гаманець повинен вивести адресу ATA з полів recipient та spl-token. Перекази на допоміжні token account не підтримуються.

Посилання

Декілька полів reference дозволено як необов'язкові параметри запиту. Значення повинні бути 32-байтовими масивами у кодуванні base58. Вони можуть бути або не бути публічними ключами, на кривій чи поза нею, і можуть відповідати або не відповідати обліковим записам на Solana.

Якщо значення надані, гаманець повинен включити їх у наданому порядку як ключі лише для читання, які не підписують, до інструкції SystemProgram.Transfer або TokenProgram.Transfer/TokenProgram.TransferChecked у транзакції платежу. Значення можуть бути унікальними або не унікальними для запиту платежу, і можуть відповідати або не відповідати обліковому запису в Solana.

Оскільки валідатори Solana індексують транзакції за цими ключами облікових записів, значення reference можна використовувати як ідентифікатори клієнта (ідентифікатори, які можна використовувати до того, як стане відома остаточна транзакція платежу). Метод RPC getSignaturesForAddress можна використовувати для пошуку транзакцій таким чином.

Мітка

Одне поле label дозволено як необов'язковий параметр запиту. Значення має бути URL-кодованим рядком UTF-8, що описує джерело запиту на переказ.

Наприклад, це може бути назва бренду, магазину, додатка або особи, яка робить запит. Гаманець повинен декодувати URL значення та відобразити декодоване значення користувачеві.

Повідомлення

Одне поле message дозволено як необов'язковий параметр запиту. Значення має бути URL-кодованим рядком UTF-8, що описує характер запиту на переказ.

Наприклад, це може бути назва товару, що купується, ідентифікатор замовлення або подяка. Гаманець повинен декодувати URL значення та відобразити декодоване значення користувачеві.

Мемо

Одне поле memo дозволено як необов'язковий параметр запиту. Значення має бути URL-кодованим рядком UTF-8, який повинен бути включений в інструкцію SPL Memo у транзакції платежу.

Гаманець повинен декодувати URL значення і має відобразити декодоване значення користувачеві. Мемо буде записано валідаторами і не повинно містити приватну або конфіденційну інформацію.

Якщо поле надано, гаманець повинен включити інструкцію MemoProgram як передостанню інструкцію транзакції, безпосередньо перед інструкцією передачі SOL або SPL Token, щоб уникнути неоднозначності з іншими інструкціями в транзакції.

Приклади

URL, що описує запит на переказ 1 SOL

solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?amount=1&label=Michael&message=Thanks%20for%20all%20the%20fish&memo=OrderId12345

URL, що описує запит на переказ 0,01 USDC

solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?amount=0.01&spl-token=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v

URL, що описує запит на переказ SOL (користувач вводить суму)

solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?label=Michael

Специфікація: Запит транзакції

URL запиту транзакції Solana Pay описує інтерактивний запит для будь-якої транзакції Solana.

solana:<link>

Запит є інтерактивним, оскільки параметри в URL використовуються гаманцем для здійснення HTTP-запиту для формування транзакції.

Посилання

Обов'язковим є одне поле link як шлях. Значення повинно бути умовно закодованою URL-адресою абсолютною HTTPS URL-адресою.

Якщо URL містить параметри запиту, він повинен бути закодованим URL-адресою. До цієї специфікації можуть бути додані параметри запиту протоколу. URL-кодування значення запобігає конфлікту з параметрами протоколу.

Якщо URL не містить параметрів запиту, він не повинен бути закодованим URL-адресою. Це створює коротшу URL-адресу та менш щільний QR-код.

У будь-якому випадку гаманець повинен декодувати URL-адресу значення. Це не має ефекту, якщо значення не закодоване URL-адресою. Якщо декодоване значення не є абсолютною HTTPS URL-адресою, гаманець повинен відхилити його як неправильно сформоване.

GET-запит

Гаманець повинен зробити HTTP GET JSON-запит до URL-адреси. Запит не повинен ідентифікувати гаманець або користувача.

Гаманець повинен зробити запит з заголовком Accept-Encoding, і застосунок повинен відповісти з заголовком Content-Encoding для HTTP-стиснення.

Гаманець повинен відображати домен URL під час виконання запиту.

Відповідь GET

Гаманець має обробляти HTTP клієнтські помилки, серверні помилки та відповіді перенаправлення. Додаток має відповідати цими кодами або HTTP OK JSON відповіддю з тілом:

{ "label": "<label>", "icon": "<icon>" }

Значення <label> має бути рядком UTF-8, який описує джерело запиту транзакції. Наприклад, це може бути назва бренду, магазину, додатка або особи, що робить запит.

Значення <icon> має бути абсолютним HTTP або HTTPS URL зображення іконки. Файл має бути зображенням SVG, PNG або WebP, інакше гаманець повинен відхилити його як некоректний.

Гаманець не повинен кешувати відповідь, окрім випадків, зазначених у HTTP кешуванні заголовками відповіді.

Гаманець повинен відображати мітку та рендерити зображення іконки для користувача.

Запит POST

Гаманець має виконати HTTP POST JSON запит до URL з тілом:

{ "account": "<account>" }

Значення <account> має бути публічним ключем облікового запису в кодуванні base58, який може підписати транзакцію.

Гаманець повинен виконувати запит із заголовком Accept-Encoding, а додаток має відповідати заголовком Content-Encoding для HTTP стиснення.

Гаманець повинен відображати домен URL під час виконання запиту. Якщо був виконаний запит GET, гаманець також повинен відображати мітку та рендерити зображення іконки з відповіді.

Відповідь POST

Гаманець має обробляти HTTP клієнтські помилки, серверні помилки та відповіді перенаправлення. Додаток має відповідати цими кодами або HTTP OK JSON відповіддю з тілом:

{ "transaction": "<transaction>" }

Значення <transaction> має бути закодованою в base64 серіалізованою транзакцією. Гаманець повинен декодувати транзакцію з base64 та десеріалізувати її.

Додаток може відповісти частково або повністю підписаною транзакцією. Гаманець повинен валідувати транзакцію як недовірену.

Порожні підписи

Якщо signatures транзакції порожні:

  • Додаток повинен встановити feePayer на account із запиту, або нульове значення (new PublicKey(0) або new PublicKey("11111111111111111111111111111111")).
  • Додаток повинен встановити recentBlockhash на останній хеш блоку, або нульове значення (new PublicKey(0).toBase58() або "11111111111111111111111111111111").
  • Гаманець повинен ігнорувати feePayer у транзакції та встановити feePayer на account із запиту.
  • Гаманець повинен ігнорувати recentBlockhash у транзакції та встановити recentBlockhash на останній хеш блоку.

Непорожні підписи

Якщо signatures транзакції непорожні:

  • Додаток повинен встановити feePayer на публічний ключ першого підпису.
  • Додаток повинен встановити recentBlockhash на останній хеш блоку.
  • Додаток повинен серіалізувати та десеріалізувати транзакцію перед її підписанням. Це забезпечує послідовне впорядкування ключів облікових записів як обхідне рішення для цієї проблеми.
  • Гаманець не повинен встановлювати feePayer та recentBlockhash.
  • Гаманець повинен перевірити підписи, і якщо будь-який з них недійсний, гаманець повинен відхилити транзакцію як некоректну.

Гаманець повинен підписувати транзакцію лише з account із запиту, і повинен робити це лише якщо очікується підпис для account із запиту.

Якщо очікується будь-який підпис, крім підпису для account із запиту, гаманець повинен відхилити транзакцію як шкідливу.

Необов'язкове поле повідомлення

Додаток також може включати необов'язкове поле message у тілі відповіді:

{ "message": "<message>", "transaction": "<transaction>" }

Значення <message> має бути рядком UTF-8, який описує характер відповіді на транзакцію.

Наприклад, це може бути назва товару, що купується, знижка, застосована до покупки, або подяка. Гаманець повинен відображати це значення користувачеві.

Гаманець і додаток повинні дозволяти додаткові поля в тілі запиту та тілі відповіді, які можуть бути додані майбутньою специфікацією.

Приклади

URL-адреса, що описує запит транзакції

solana:https://example.com/solana-pay

URL-адреса, що описує запит транзакції з параметрами запиту

solana:https%3A%2F%2Fexample.com%2Fsolana-pay%3Forder%3D12345

Приклад GET-запиту

GET /solana-pay?order=12345 HTTP/1.1
Host: example.com
Connection: close
Accept: application/json
Accept-Encoding: br, gzip, deflate

Приклад GET-відповіді

HTTP/1.1 200 OK
Connection: close
Content-Type: application/json
Content-Length: 62
Content-Encoding: gzip
{"label":"Michael Vines","icon":"https://example.com/icon.svg"}

Приклад POST-запиту

POST /solana-pay?order=12345 HTTP/1.1
Host: example.com
Connection: close
Accept: application/json
Accept-Encoding: br, gzip, deflate
Content-Type: application/json
Content-Length: 57
{"account":"mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN"}

Приклад POST-відповіді

HTTP/1.1 200 OK
Connection: close
Content-Type: application/json
Content-Length: 298
Content-Encoding: gzip
{"message":"Thanks for all the fish","transaction":"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAECC4JMKqNplIXybGb/GhK1ofdVWeuEjXnQor7gi0Y2hMcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQECAAAMAgAAAAAAAAAAAAAA"}

Розширення

Додаткові формати та поля можуть бути включені до цієї специфікації для забезпечення нових сценаріїв використання, зберігаючи при цьому сумісність з додатками та гаманцями.

Будь ласка, відкрийте issue на Github, щоб запропонувати зміни до специфікації та отримати відгуки від розробників додатків і гаманців.

Фактичний приклад такої пропозиції.

Дивіться також

Is this page helpful?

Керується

© 2026 Фонд Solana.
Всі права захищені.
Залишайтеся на зв'язку