Actions та Blinks
Solana Actions - це API, що відповідають специфікації, які повертають транзакції в блокчейні Solana для попереднього перегляду, підпису та відправлення в різних контекстах, включаючи QR-коди, кнопки + віджети, а також вебсайти в інтернеті. Actions роблять простою інтеграцію можливостей екосистеми Solana у ваше середовище розробники, дозволяючи виконувати блокчейн-транзакції без необхідності переходу до іншого додатка або вебсторінки.
Blockchain links – або blinks – перетворюють будь-який Solana Action на посилання, яким можна поділитися і яке містить багато метаданих. Blinks дозволяють клієнтам, що підтримують Action (браузерні гаманці, боти), відображати додаткові можливості для користувача. На вебсайті blink може одразу ж викликати попередній перегляд транзакції в гаманці без переходу до децентралізованого додатка; у Discord бот, blink може бути розгорнутий у наборі інтерактивних кнопок. Це дозволяє взаємодіяти з блокчейном на будь-якій вебплатформі, здатній відображати URL.
Початок роботи #
Щоб швидко розпочати створення Solana Actions:
npm install @solana/actions
- встановіть Solana Actions SDK у вашому додатку
- побудуйте API ендпоінт для GET запиту, який повертає метадані про ваш Action
- створіть API ендпоінт, який приймає POST запит і повертає транзакцію, яку користувач може підписати
Перегляньте цей відеоурок про
те, як створити Solana Action
за допомогою SDK @solana/actions
.
Ви також можете знайти вихідний код для Action, який виконує нативний переказ SOL, тут, а також кілька інших прикладів Action у цьому репозиторії.
Під час розгортання ваших Solana Action у продакшн:
- переконайтеся, що у вашому додатку є дійсний файл actions.json у корені вашого домену
- переконайтеся, що ваш додаток відповідає з
необхідними заголовками Cross-Origin на всіх Action
ендпоінтах, включаючи файл
actions.json
Якщо ви шукаєте натхнення для створення Action та blink, перегляньте репозиторій Awesome Blinks, де можна знатий творіння спільноти та навіть ідеї для нових blink.
Actions #
Специфікація Solana Actions використовує набір стандартних API для надання транзакцій, які можна підписати (а згодом і повідомлень, що також можна підписати), безпосередньо від додатка до користувача. Вони розміщуються за загальнодоступними URL-адресами й відповідно доступні для будь-якого клієнта за своїм URL.
Ви можете розглядати Actions як API ендпоінт, який повертає метадані та щось для підпису користувачем (транзакцію або повідомлення для аутентифікації) за допомогою їх блокчейн-гаманця.
API Actions полягає у здійсненні простих GET та POST запитів до Action URL ендпоінту й обробці відповідей, що відповідають інтерфейсу Actions.
- GET запит повертає метадані, які надають клієнту читабельну інформацію про те, які дії доступні за цією URL-адресою, а також необов'язковий список пов'язаних дій.
- POST запит повертає транзакцію або повідомлення для підпису, після чого клієнт пропонує користувачеві підписати його за допомогою гаманця та виконати їх у блокчейні або в іншій off-chain службі.
Виконання та життєвий цикл Action #
На практиці взаємодія з Actions дуже схожа на взаємодію зі звичайним REST API:
- клієнт робить початковий
GET
запит до URL-адреси Action, щоб отримати метадані про доступні дії - ендпоінт повертає відповідь, яка містить метадані про нього (такі як заголовок та іконка додатка) та перелік доступних дій для цього ендпоінта
- клієнтський додаток (наприклад, мобільний гаманець, чат-бот або вебсайт) відображає інтерфейс для користувача для виконання однієї з дій
- після того як користувач обрав дію (натиснувши кнопку), клієнт виконує
POST
запит до ендпоінту, щоб отримати транзакцію для підпису користувачем - гаманець допомагає користувачеві підписати транзакцію і відправляє її до блокчейну для підтвердження
Виконання Solana Actions та життєвий цикл
Отримуючи транзакції з Actions URL, клієнти повинні обробляти відправку цих транзакцій до блокчейну і керувати їх життєвим циклом.
Actions також підтримують певний рівень валідації перед виконанням. Запити GET
і POST
можуть повертати деякі метадані, які вказують, чи можна виконати дію
(наприклад, з полем disabled
).
Наприклад, якщо існує Action ендпоінт, що дозволяє голосувати за пропозицію управління DAO, але період голосування закритий, початковий GET запит може повернути повідомлення про помилку "This proposal is no longer up for a vote", а кнопки "Vote Yes" та "Vote No" будуть відключені.
Blinks #
Blinks (blockchain links) - це клієнтські додатки, які аналізують Action API та створюють користувацькі інтерфейси для взаємодії та виконання Actions.
Клієнтські додатки, які підтримують blink, просто виявляють сумісні Action URL, розбирають їх і дозволяють користувачам взаємодіяти з ними у стандартизованих користувацьких інтерфейсах.
Будь-який клієнтський додаток, який повністю аналізує Actions API для побудови повного інтерфейсу для нього, є blink. Тому не всі клієнти, який використовує Actions API, є blink.
Blink URL Специфікація #
URL blink описує клієнтський додаток, яка дозволяє користувачеві завершити повний цикл виконання Action, включаючи підпис з їх гаманцем.
https://example.domain/?action=<action_url>
Для того щоб будь-яка клієнтська програма могла використовувати blink:
-
Blink URL повинна містити параметр запиту
action
, значення якого буде URL закодованим для Action URL. Це значення повинно бути закодовано, щоб уникнути конфліктів з іншими параметрами протоколу. -
Клієнтський додаток повинний декодувати URL параметр запиту
action
і інтроспектувати надане посилання Action API (див. Action URL scheme). -
Клієнт повинен відображати користувацький інтерфейс, який дозволяє завершити весь життєвий цикл виконання Action, включаючи підпис з їх гаманця.
Не всі клієнтські blink програми (наприклад, вебсайти або dApps) підтримують усі Actions. Розробники додатків можуть вибирати, які Actions вони хочуть підтримувати у своїх blink інтерфейсах.
Наведений приклад демонструє дійсну blink URL-адресу зі значенням параметра
action
, який URL закодовано solana-action:https://actions.alice.com/donate
:
https://example.domain/?action=solana-action%3Ahttps%3A%2F%2Factions.alice.com%2Fdonate
Виявлення Actions за допомогою Blinks #
Blink можуть бути пов'язані з Actions принаймні трьома способами:
-
Поширення за допомогою явного Action URL:
solana-action:https://actions.alice.com/donate
У цьому випадку лише підтримувані клієнти можуть відтворювати blink. Не буде доступно жодного альтернативного попереднього перегляду посилання або сайту, який можна було б відвідати за межами непідтримуваного клієнта.
-
Поширення посилання на вебсайт, який пов'язаний з Actions API за допомогою
actions.json
файлуу кореневій директорії домену вебсайту.Наприклад,
https://alice.com/actions.json
відображає посиланняhttps://alice.com/donate на веб-сайті, де користувачі можуть здійснити пожертвування на користь Alice, на API URL
https://actions.alice.com/donate\`, де знаходяться Actions для здійснення пожертвування Alice. -
Вбудовування Action URL в "проміжний" URL веб-сайту, який розуміє, як парсити Actions.
https://example.domain/?action=<action_url>
Клієнти, які підтримують блінки, повинні мати можливість приймати будь-який з вищезазначених форматів і правильно відображати інтерфейс для безпосереднього виконання дії в клієнті.
Для клієнтів, які не підтримують blink, повинен бути доступний базовий вебсайт (що робить браузер універсальним резервом).
Якщо користувач натискає на будь-яке місце в клієнтській програмі, крім кнопки дії або поля введення тексту, його повинно перенаправити на базовий сайт.
Тестування та Верифікація Blink #
Хоча Solana Actions та blinks є протоколом/специфікацією без права доступу, клієнтські додатки та гаманці все одно повинні забезпечувати користувачам можливість підписувати транзакції.
Кожен з цих клієнтських додатків або гаманців може мати різні вимоги щодо того, які Action ендпоінт їхні клієнти будуть автоматично розгортати та відображати своїм користувачам на платформах соціальних мереж.
Наприклад, деякі клієнти можуть працювати за принципом "дозволеного списку", що може вимагати перевірки перед тим, як їхній клієнт розгорне Action для користувачів, таких як Dialect's Actions Registry (детально описаний нижче).
Усі blinks все ще будуть відображатися та дозволяти підписання на сайті проміжної сторінки Dialect's dial.to, з вказанням їх статусу в реєстрі blink.
Dialect's Actions Registry #
З користю для екосистеми Solana, Dialect разом із допомогою Solana Foundation та інших членів спільноти підтримує публічний реєстр блокчейн-посилань, які були попередньо перевірені відомими джерелами. На момент запуску, лише Actions зареєстровані в реєстрі Dialect, будуть розгортатися в стрічці Twitter після публікації.
Клієнтські додатки та гаманці можуть вільно вибирати чи використовувати цей публічний реєстр або інше рішення, щоб забезпечити безпеку та захист користувачів. Якщо посилання на блокчейн не підтверджено через реєстр Dialect, blink клієнт його ігнорує і відображає як звичайний URL.
Розробники можуть подати заявку на верифікацію через Dialect за цим посиланням: dial.to/register
Специфікація #
Специфікація Solana Actions складається з ключових розділів, які є частиною процесу взаємодії запит/відповідь:
- Solana Action URL scheme яка надає Action URL
- OPTIONS відповідь на Action URL для виконання вимог CORS
- GET запит до Action URL
- GET відповідь від сервера
- POST запит до Action URL
- POST відповідь від сервера
Кожен із цих запитів робиться Action клієнтом (наприклад, додатком гаманця, браузерним розширенням, dApp, вебсайтом тощо), щоб зібрати специфічні метадані для багатих користувацьких інтерфейсів і для полегшення введення користувача в Actions API.
Кожна з відповідей формується додатком (наприклад, вебсайтом, серверною частиною, тощо) і повертається клієнту Action. Зрештою, надаючи транзакцію або повідомлення для підпису, щоб гаманець запропонував користувачу підтвердити, підписати та відправити у блокчейн.
URL Scheme #
Solana Action URL описує інтерактивний запит для транзакції або повідомлення
Solana, яке можна підписати, використовуючи протокол solana-action
.
Запит є інтерактивним через те, що параметри в URL використовуються клієнтом для створення серії стандартизованих HTTP-запитів для складання транзакції або повідомлення, яке користувач може підписати за допомогою свого гаманця.
solana-action:<link>
-
Єдине поле
link
є обов’язковим як шлях. Значення повинно бути умовно URL закодованим абсолютним HTTPS URL. -
Якщо URL містить параметри запиту, вони повинні бути URL закодовані. Кодування значень дозволяє уникнути конфліктів з параметрами протоколу Actions, які можуть бути додані за допомогою специфікації протоколу.
-
Якщо URL не містить параметрів запиту, його не потрібно кодувати. Це забезпечує коротший URL і менш щільний QR-код.
У будь-якому випадку клієнти повинні URL декодувати значення. Це не вплине на значення, якщо воно не закодоване. Якщо декодоване значення не є абсолютним HTTPS URL адресою, гаманець повинен відхилити його як неправильний формат.
OPTIONS відповідь #
Для забезпечення міжсайтового обміну ресурсами
(CORS) у клієнтах
Actions (включаючи blink), всі Actions ендпоінти повинні відповідати на
HTTP-запити для методу OPTIONS
з коректними заголовками, що дозволяють
клієнтам успішно проходити перевірку CORS для всіх наступних запитів з їхнього
власного початкового домену.
Action клієнт може виконувати
"попередні"
запити до енпоінта Action URL, щоб перевірити, чи пройде наступний GET запит на
Action URL всі перевірки CORS. Ці попередні перевірки CORS виконуються за
допомогою HTTP-методу OPTIONS
і повинні відповідати з усіма необхідними
HTTP-заголовками, що дозволяють Action клієнтам (таким як blink) належним чином
виконувати всі наступні запити з їх вихідного домену.
Мінімальний набір обов'язкових HTTP заголовків включає:
Access-Control-Allow-Origin
зі значенням*
- це забезпечує можливість всім Action клієнтам безпечно проходити перевірку CORS для здійснення всіх необхідних запитів
Access-Control-Allow-Methods
зі значенням "GET,POST,PUT,OPTIONS"- це забезпечує підтримку всіх необхідних HTTP методів для Action
Access-Control-Allow-Headers
з мінімальним значеннямContent-Type, Authorization, Content-Encoding, Accept-Encodding
Для спрощення, розробники повинні очікувати повернення такої самої відповіді та
заголовків на запити методу OPTIONS
, як на їхні відповіді запиту методу
GET
.
Відповідь файлу actions.json
також повинна містити дійсні заголовки
Cross-Origin для запитів GET
і OPTIONS
, зокрема значення заголовка
Access-Control-Allow-Origin
повинно бути *
.
Дивіться нижче для деталей щодо actions.json.
GET запит #
Action клієнт (наприклад, гаманець, браузерне розширення тощо) повинен
здійснювати HTTP GET
JSON запит до Action's URL ендпоінт.
- Запит не повинен ідентифікувати гаманець або користувача.
- Клієнт повинен робити запит з заголовком
Accept-Encoding
. - Клієнт повинен відображати домен URL під час виконання запиту.
Відповідь на GET запит #
Action's URL ендпоінт (наприклад, додаток або серверна частина) повинна
відповісти HTTP-статусом OK
із JSON-відповіддю (з коректним вмістом тіла) або
відповідною HTTP-помилкою.
-
Клієнт повинен обробляти HTTP помилки клієнта, помилки сервера, та перенаправляти відповіді.
-
Ендпоінт повинний відповісти з заголовком
Content-Encoding
для HTTP компресії. -
Ендпоінт повинний відповісти з заголовком
Content-Type
зapplication/json
. -
Клієнт повинен ігнорувати кешування відповіді, за винятком випадків, коли це зазначено в заголовках відповіді HTTP кешування.
-
Клієнт повинен відображати заголовок (
title
) та іконку (icon
) для користувача.
Тіло відповіді GET запиту #
Відповідь на GET
запит з HTTP OK
JSON повинна містити тіло з вмістом, що
відповідає специфікації інтерфейсу:
export interface ActionGetResponse {
/** image url that represents the source of the action request */
icon: string;
/** describes the source of the action request */
title: string;
/** brief summary of the action to be performed */
description: string;
/** button text rendered to the user */
label: string;
/** UI state for the button being rendered to the user */
disabled?: boolean;
links?: {
/** list of related Actions a user could perform */
actions: LinkedAction[];
};
/** non-fatal error message to be displayed to the user */
error?: ActionError;
}
-
icon
- Значення повинно бути абсолютною HTTP або HTTPS URL-адресою зображення іконки. Файл повинен бути зображенням у форматі SVG, PNG або WebP, інакше клієнт/гаманець повинен відхилити його як неправильний формат. -
title
- Значення повинно бути рядком у форматі UTF-8, що представляє джерело запиту дії. Наприклад, це може бути назва бренду, магазину, додатка або особи, яка робить запит. -
description
- Значення повинно бути рядком у форматі UTF-8, що надає інформацію про дію. Опис повинен бути відображений користувачу. -
label
- Значення повинно бути рядком у форматі UTF-8, який буде відображено на кнопці для натискання користувачем. Усі мітки не повинні перевищувати 5 слів і мають починатися з дієслова, щоб чітко позначити дію, яку ви хочете, щоб користувач виконав. Наприклад, "Mint NFT", "Vote Yes" або "Stake 1 SOL". -
disabled
- Значення повинно бути булевим для відображення стану відключення кнопки (яка показує рядок з підписом label). Якщо значення не вказано, параметрdisabled
повинен за замовчуванням бутиfalse
(тобто ввімкнено за замовчуванням). Наприклад, якщо кінцевий ендпоінт призначений для голосування в управлінні, яке вже завершилося, встановітьdisabled=true
, а значенняlabel
може бути "Vote Closed". -
error
- Опційне вказівне поле для відображення не критичних помилок. Якщо воно присутнє, клієнт повинен відображати його користувачу. Якщо воно встановлене, воно не повинно заважати клієнту інтерпретувати дію або відображати її користувачу. Наприклад, помилку можна використовувати разом із параметромdisabled
для відображення причин, таких як бізнес-обмеження, авторизація, стан чи помилка зовнішнього ресурсу.
export interface ActionError {
/** non-fatal error message to be displayed to the user */
message: string;
}
-
links.actions
- Опціональний масив пов'язаних дій для ендпоінта. Користувачам повинно відображатися інтерфейсне вікно для кожної з перелічених дій і очікувати, що вони виконають лише одну. Наприклад, ендпоінт дії голосування в управлінні може повертати три варіанти для користувача: "Vote Yes", "Vote No" і "Abstain from Vote".-
Якщо не надано
links.actions
, клієнт повинен відобразити одну кнопку з кореневим рядком міткиlabel
і виконати POST запит до того ж URL-ендпоінту дії, що й початковий GET запит. -
Якщо надано будь-які
links.actions
, клієнт повинен відображати лише кнопки і поля введення на основі елементів, перераховані у поліlinks.actions
. Клієнт не повинен відображати кнопку для перегляду вмісту кореневого поляlabel
.
-
export interface LinkedAction {
/** URL endpoint for an action */
href: string;
/** button text rendered to the user */
label: string;
/** Parameter to accept user input within an action */
parameters?: [ActionParameter];
}
/** Parameter to accept user input within an action */
export interface ActionParameter {
/** parameter name in url */
name: string;
/** placeholder text for the user input field */
label?: string;
/** declare if this field is required (defaults to `false`) */
required?: boolean;
}
Приклад GET відповіді #
Приклад відповіді, яка надає одну "кореневу" дію, що має бути представлена користувачу у вигляді однієї кнопки з написом "Claim Access Token":
{
"title": "HackerHouse Events",
"icon": "<url-to-image>",
"description": "Claim your Hackerhouse access token.",
"label": "Claim Access Token" // button text
}
Приклад відповіді, яка надає 3 пов'язаних посилання на дії, що дозволяють користувачу натиснути одну з 3 кнопок для голосування за пропозицію DAO:
{
"title": "Realms DAO Platform",
"icon": "<url-to-image>",
"description": "Vote on DAO governance proposals #1234.",
"label": "Vote",
"links": {
"actions": [
{
"label": "Vote Yes", // button text
"href": "/api/proposal/1234/vote?choice=yes"
},
{
"label": "Vote No", // button text
"href": "/api/proposal/1234/vote?choice=no"
},
{
"label": "Abstain from Vote", // button text
"href": "/api/proposal/1234/vote?choice=abstain"
}
]
}
}
Приклад GET відповіді з параметрами #
Наступний приклад відповіді демонструє, як приймати текстове введення від користувача (через 'parameters') і включати це введення в ендпоінт 'POST' запиту (через поле 'href' у 'LinkedAction'):
Приклад відповіді, яка надає користувачеві 3 пов'язаних дії для стейкінгу SOL: кнопку з написом "Stake 1 SOL", іншу кнопку з написом "Stake 5 SOL" і текстове поле введення, яке дозволяє користувачеві ввести конкретне значення "amount", яке буде надіслано до Action API:
{
"title": "Stake-o-matic",
"icon": "<url-to-image>",
"description": "Stake SOL to help secure the Solana network.",
"label": "Stake SOL", // not displayed since `links.actions` are provided
"links": {
"actions": [
{
"label": "Stake 1 SOL", // button text
"href": "/api/stake?amount=1"
// no `parameters` therefore not a text input field
},
{
"label": "Stake 5 SOL", // button text
"href": "/api/stake?amount=5"
// no `parameters` therefore not a text input field
},
{
"label": "Stake", // button text
"href": "/api/stake?amount={amount}",
"parameters": [
{
"name": "amount", // field name
"label": "SOL amount" // text input placeholder
}
]
}
]
}
}
Приклад відповіді, яка надає єдине поле введення для користувача, щоб ввести
значення amount
, яке буде відправлено з POST-запитом (або як параметр запиту,
або як підшлях):
{
"icon": "<url-to-image>",
"label": "Donate SOL",
"title": "Donate to GoodCause Charity",
"description": "Help support this charity by donating SOL.",
"links": {
"actions": [
{
"label": "Donate", // button text
"href": "/api/donate/{amount}", // or /api/donate?amount={amount}
"parameters": [
// {amount} input field
{
"name": "amount", // input field name
"label": "SOL amount" // text input placeholder
}
]
}
]
}
}
POST запит #
Клієнт повинен виконати HTTP POST
JSON-запит до URL дії з тілом запиту:
{
"account": "<account>"
}
account
- Значення повинно бути закодованим у форматі Base58 публічним ключем облікового запису, який може підписати транзакцію.
Клієнт повинен робити запит з заголовком Accept-Encoding, а додаток може відповісти з заголовком Content-Encoding для HTTP стиснення.
Клієнт повинен відображати домен URL адреси дії під час виконання запиту. Якщо
був зроблений GET
запит, клієнт також повинен відображати title
і
відтворювати зображення icon
з отриманої GET відповіді.
POST відповідь #
Ендпоінт Action's POST повинен відповісти з HTTP OK
JSON-відповіддю (з дійсним
вмістом у тілі) або відповідною HTTP-помилкою.
- Клієнт повинен обробляти HTTP-помилки, такі як помилки клієнта, помилки сервера, та перенаправляти відповіді.
- Ендпоінт повинен відповісти з заголовком
Content-Type
зapplication/json
.
Тіло POST відповіді #
Відповідь на POST
запит з HTTP OK
JSON повинна містити тіло з вмістом:
export interface ActionPostResponse {
/** base64 encoded serialized transaction */
transaction: string;
/** describes the nature of the transaction */
message?: string;
}
-
transaction
- Значення повинно бути закодованою у форматі base64 серіалізованої транзакції. Клієнт повинен декодувати транзакцію з base64 і провести її [десеріалізацію] (https://solana-labs.github.io/solana-web3.js/classes/Transaction.html#from). -
message
- Значення повинно бути рядком UTF-8, який описує характер транзакції, включеної в відповідь. Клієнт повинен відображати це значення користувачеві. Наприклад, це може бути назва товару, що придбана, знижка на покупку або подяка. -
Клієнт та додаток повинні дозволяти додаткові поля у тілі запиту та тілі відповіді, які можуть бути додані у майбутніх оновленнях специфікації.
Додаток може відповісти частково або повністю підписаною транзакцією. Клієнт і гаманець повинні позначити транзакцію як ненадійну.
POST Відповідь - Транзакція #
Якщо підписи транзакції порожні або транзакція не була частково підписана:
- Клієнт повинен ігнорувати
feePayer
у транзакції і встановитиfeePayer
на обліковий запис у запиті. - Клієнт повинен ігнорувати
recentBlockhash
у транзакції і встановитиrecentBlockhash
на останній блокхеш. - Клієнт повинен серіалізувати та десеріалізувати транзакцію перед її підписанням. Це забезпечує послідовний порядок ключів облікових записів, як обхідне рішення для цієї проблеми.
Якщо транзакцію було частково підписано:
- Клієнт не повинен змінювати
feePayer
абоrecentBlockhash
, оскільки це може призвести до недійсності наявних підписів. - Клієнт повинен перевірити наявні підписи і якщо який-небудь з них недійсний, клієнт повинен відхилити транзакцію як неправильно сформовану.
Клієнт повинен підписувати транзакцію лише з обліковим записом у запиті і робити це тільки в тому випадку, якщо очікується підпис для облікового запису у запиті.
Якщо очікується будь-який підпис, крім підпису для облікового запису у запиті, клієнт повинен відхилити транзакцію як зловмисну.
actions.json #
Мета файлу actions.json
file полягає в тому, щоб додаток міг
вказати клієнтам, які веб-сайти підтримують Solana Action і надавати
відображення, яке можна використовувати для виконання
GET запитів до сервера Actions API.
Відповідь файлу actions.json
також повинна містити дійсні заголовки
Cross-Origin для запитів GET
і OPTIONS
, зокрема значення заголовка
Access-Control-Allow-Origin
повинно бути *
.
Дивіться вище для деталей щодо відповіді OPTIONS.
Файл 'actions.json' повинен бути збережений і доступний у кореневій директорії домену.
Наприклад, якщо ваш веб-додаток розгорнуто на my-site.com
, то файл
actions.json
повинен бути доступний за адресою
https://my-site.com/actions.json
. Цей файл також повинен бути доступним через
Cross-Origin у будь-якому браузері за допомогою заголовка
Access-Control-Allow-Origin
зі значенням *
.
Rules #
Поле rules
дозволяє додатку зіставляти набір відносних маршрутів вебсайту з
іншими шляхами.
Type: Array
of ActionRuleObject
.
interface ActionRuleObject {
/** relative (preferred) or absolute path to perform the rule mapping from */
pathPattern: string;
/** relative (preferred) or absolute path that supports Action requests */
apiPath: string;
}
-
pathPattern
- Шаблон, який відповідає кожному вхідному шляху. -
apiPath
- Місцезнаходження, визначене як абсолютний шлях або зовнішній URL.
Правила - pathPattern #
Шаблон, який відповідає кожному вхідному шляху. Це може бути абсолютним або відносним шляхом і підтримує наступні формати:
-
Exact Match: відповідає точному шляху URL.
- Приклад:
/exact-path
- Приклад:
https://website.com/exact-path
- Приклад:
-
Wildcard Match: використовує підстановки для відповідності будь-якій послідовності символів у шляху URL. Це може відповідати одному (за допомогою *) або декільком сегментам (за допомогою **). (див. розділ Path Matching нижче).
- Приклад:
/trade/*
відповідатиме/trade/123
та/trade/abc
, захоплюючи лише перший сегмент після/trade/
. - Приклад:
/category/*/item/**
відповідатиме/category/123/item/456
та/category/abc/item/def
. - Приклад:
/api/actions/trade/*/confirm
відповідатиме/api/actions/trade/123/confirm
.
- Приклад:
Правила - apiPath #
Цільовий шлях для запиту на дію. Це може бути визначено як абсолютний шлях або зовнішній URL.
- Приклад:
/api/exact-path
- Приклад:
https://api.example.com/v1/donate/*
- Приклад:
/api/category/*/item/*
- Приклад:
/api/swap/**
Правила - Query Parameters #
Параметри запиту з оригінального URL завжди зберігаються і додаються до відображеного URL.
Правила - Path Matching #
Наступна таблиця наводить синтаксис для шаблонів відповідності шляхів:
Оператор | Matches |
---|---|
* | Один сегмент шляху, не включаючи оточуючих символів роздільника шляху / символів. |
** | Відповідає нулю або більше символам, включаючи будь-які символи роздільника шляху / між кількома сегментами шляху. Якщо використовуються інші оператори, оператор ** повинен бути останнім оператором. |
? | Непідтримуваний шаблон. |
Rules Приклади #
Наступний приклад демонструє правило точного збігу для зіставлення запитів до '/buy' з кореня вашого сайту з точним шляхом '/api/buy' відносно кореня вашого сайту:
{
"rules": [
{
"pathPattern": "/buy",
"apiPath": "/api/buy"
}
]
}
Наступний приклад використовує шаблонне зіставлення шляхів для відображення
запитів до будь-якого шляху (крім підкаталогів) під /actions/
в корені вашого
сайту на відповідний шлях під /api/actions/
відносно кореня вашого сайту:
{
"rules": [
{
"pathPattern": "/actions/*",
"apiPath": "/api/actions/*"
}
]
}
Наступний приклад використовує шаблонне зіставлення шляхів для відображення
запитів до будь-якого шляху (крім підкаталогів) під /donate/
в корені вашого
сайту на відповідний абсолютний шлях https://api.dialect.com/api/v1/donate/
на
зовнішньому сайті:
{
"rules": [
{
"pathPattern": "/donate/*",
"apiPath": "https://api.dialect.com/api/v1/donate/*"
}
]
}
Наступний приклад використовує збіг шляхів з підстановкою для ідемпотентного
правила зіставлення запитів до будь-якого шляху (включаючи підкаталоги) під
/api/actions/
з кореня вашого сайту на цей же шлях:
Ідемпотентні правила дозволяють blink клієнтам легше визначити, чи підтримує
заданий шлях запити Action API, без необхідності додавання префікса
solana-action:
URI або виконання додаткового тестування відповідей.
{
"rules": [
{
"pathPattern": "/api/actions/**",
"apiPath": "/api/actions/**"
}
]
}
Action Identity #
Action ендпоінти можуть включати Action Identity в транзакціях, які повертаються у їхній POST відповіді для підпису користувачем. Це дозволяє індексаторам та аналітичним платформам легко та надійно приписувати активність у блокчейні до конкретного Action Provider (тобто сервісу) у перевірюваний спосіб.
Action Identity — це пара ключів, яка використовується для підпису спеціально сформованого повідомлення, що включається у транзакцію за допомогою інструкції Memo. Це Identifier Message можна достовірно приписати певному Action Identity, а отже, і транзакціям, певного Action Provider.
Пара ключів не обов'язково повинна підписувати саму транзакцію. Це дозволяє гаманцям та додаткам покращити доставку транзакцій, коли на транзакції, повернутій користувачеві, немає інших підписів (див. Транзакція POST відповіді).
Якщо для випадку використання Action Provider потрібно, щоб його бекенд-сервіси попередньо підписали транзакцію перед користувачем, вони повинні використовувати цю пару ключів як свій Action Identity. Це дозволить зменшити кількість облікових записів, які включаються в транзакцію, що знижує загальний розмір транзакції на 32 байти.
Action Identity повідомлення #
Повідомлення Action Identity є рядком UTF-8, розділеним двокрапками, яке включається у транзакцію за допомогою єдиної інструкції SPL Memo.
protocol:identity:reference:signature
protocol
- Значення протоколу, що використовується (встановлене якsolana-action
) відповідно до URL Scheme вищеidentity
- Значення повинно бути публічною адресою ключа Action Identity, закодованою у форматі base58reference
- Значення повинно бути масивом із 32 байтів, закодованим у форматі base58. Це можуть бути або не бути публічні ключі, у межах або поза кривою, і можуть або не можуть відповідати обліковим записам у Solana.signature
- Підпис, закодований у форматі base58, створений від підпису пари ключів Action Identity тільки значеннямreference
.
Значення reference
повинно бути використане лише один раз і лише в одній
транзакції. Для приписування транзакцій Action Provider лише перше використання
значення reference
вважається дійсним.
Транзакції можуть мати кілька інструкцій Memo. Під час виконання
getSignaturesForAddress
,
поле результатів memo
поверне кожну інструкцію Memo як окремий рядок,
розділений крапкою з комою.
Інструкція Memo повинна містити лише Identifier Message і не повинна містити інших даних.
Параметри identity
і reference
повинні бути включені як
ключі
типу read-only, non-signer в транзакцію для інструкції, яка НЕ є інструкцією
Memo для повідомлення ідентифікатора.
Інструкція Memo Identifier Message не повинна мати жодних наданих облікових записів. Якщо будь-які облікові записи надані, програма Memo вимагає, щоб ці облікові записи були дійсними підписниками. Для цілей ідентифікації дій це обмежує гнучкість і може погіршити досвід користувача. Тому це вважається антипаттерном і повинно бути уникнене.
Перевірка Action Identity #
Будь-яка транзакція, яка включає обліковий запис identity
, може бути надійно
пов'язана з Action Provider у багатокроковому процесі:
- Отримайте всі транзакції для даного
identity
. - Проаналізуйте та перевірте рядок memo кожної транзакції, переконуючись, що
підпис
signature
є дійсним для збереженого значенняreference
. - Перевірте, що конкретна транзакція є першим випадком
reference
на ланцюжку:- Якщо ця транзакція є першим випадком
reference
, транзакція вважається перевіреною і може бути безпечно приписана Action Provider. - Якщо ця транзакція НЕ є першим випадком
reference
, вона вважається недійсною і, отже, не приписується Action Provider.
- Якщо ця транзакція є першим випадком
Оскільки валідатори Solana індексують транзакції за ключами облікових записів,
метод RPC
getSignaturesForAddress
може бути використаний для пошуку всіх транзакцій, які включають обліковий запис
identity
.
Відповідь цього методу RPC містить усі дані Memo у полі memo
. Якщо у
транзакції використовувалися кілька інструкцій Memo, кожне повідомлення memo
буде включено в це поле memo
, і його слід відповідно проаналізувати
перевіряючому для отримання Identity Verification Message.
Ці транзакції повинні спочатку вважатися НЕПЕРЕВІРЕНІ. Це пов’язано з тим,
що для підписання транзакції не потрібен identity
, що дозволяє будь-якій
транзакції включати цей обліковий запис, як такий, що не підписує. Це потенційно
може штучно збільшувати кількість приписувань та використань.
Identity Verification Message слід перевірити, щоб забезпечити, що підпис був
створений identity
, який підписав reference
. Якщо перевірка цього підпису не
вдалася, транзакцію вважають недійсною і вона не повинна приписуватися Action
Provider.
Якщо перевірка підпису успішна, перевіряючий повинен переконатися, що ця
транзакція є першим випадком reference
на ланцюжку. Якщо це не так, транзакцію
вважають недійсною.