Действия и Blinks

Solana Действия - это API, соответствующие спецификации, которые позволяют просматривать, подписывать и отправлять транзакции на блокчейне Solana в различных контекстах, включая QR-коды, кнопки + виджеты и веб-сайты в Интернете. Действия упрощают для разработчиков интеграцию вещей, которые вы можете делать в экосистеме Solana, прямо в вашу среду, позволяя вам выполнять транзакции блокчейна без необходимости переходить в другое приложение или на другую веб-страницу.

Блокчейн-ссылки - или blinks - превращают любое действие Solana в ссылку, которой можно поделиться и которая содержит метаданные. Cсылки позволяют клиентам с поддержкой Action (кошельки расширения браузера, боты) отображать дополнительные возможности для пользователя. На веб-сайте мигание может немедленно вызвать предварительный просмотр транзакции в кошельке без перехода к децентрализованному приложению; в Discord бот может расширить мигание до интерактивного набора кнопок. Таким образом, возможность взаимодействия внутри цепочки распространяется на любую веб-поверхность, способную отображать URL.

Начало работы #

Чтобы быстро начать с создания пользовательских действий Solana:

 
  • установите Solana Actions SDK в вашем приложении
  • постройте конечную точку API для GET request, которая возвращает метаданные о вашем действии
  • создайте конечную точку API, которая принимает запрос POST и возвращает подписанную транзакцию для пользователя
Info

Посмотрите этот видеоурок на как создать действие Солана с помощью команды @solana/actions SDK.

Вы также можете найти исходный код Action, выполняющего нативную передачу SOL, здесь и несколько других примеров Actions в этом репозитории.

При развертывании ваших пользовательских действий Solana в производстве:

  • убедитесь, что ваше приложение имеет корректный файл actions.json в корне вашего домена
  • убедитесь, что ваше приложение отвечает с необходимыми заголовками Cross-Origin на всех конечных точках Action, включая файл actions.json.

Если вы ищете вдохновение для создания Actions и мигалок, загляните в репозиторий Awesome Blinks, где вы найдете несколько творений сообщества и даже идеи для новых.

Действия #

Спецификация Solana Действия использует набор стандартных API для доставки подписываемых транзакций (и, в конечном счете, подписываемых сообщений) из приложения непосредственно пользователю. Они размещаются на общедоступных URL-адресах и поэтому доступны по их URL-адресу любому клиенту для взаимодействия.

Info

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

API Действия состоит из простых GET- и POST-запросов к конечной точке URL Действия и обработки ответов, соответствующих интерфейсу Действия.

  1. GET-запрос возвращает метаданные, которые предоставляют клиенту человекочитаемую информацию о том, какие действия доступны по данному URL, и необязательный список связанных действий.
  2. POST-запрос возвращает подписанную транзакцию или сообщение, которое клиент предлагает кошельку пользователя подписать и выполнить на блокчейне или в другом внецепочечном сервисе.

Выполнение и Жизненный цикл Действий #

На практике взаимодействие с Действиями очень похоже на взаимодействие с типичным REST API:

  • клиент делает начальный GET-запрос к URL-адресу Действия, чтобы получить метаданные о доступных Действиях
  • конечная точка возвращает ответ, содержащий метаданные о конечной точке (например, название и иконку приложения) и список доступных действий для этой конечной точки
  • клиентское приложение (например, мобильный кошелек, чат-бот или веб-сайт) отображает пользовательский интерфейс для выполнения одного из действий
  • после того как пользователь выбирает действие (нажимает кнопку), клиент делает POST-запрос к конечной точке, чтобы получить транзакцию для подписания пользователем
  • кошелек помогает пользователю подписать транзакцию и в конечном итоге отправляет ее в блокчейн для подтверждения

Выполнение и жизненный цикл действий Solana

При получении транзакций от URL-адреса Действия клиенты должны обрабатывать отправку этих транзакций в блокчейн и управлять жизненным циклом их состояния.

Действия также поддерживают некоторый уровень проверки достоверности перед выполнением. GET- и POST-запросы могут возвращать некоторые метаданные, указывающие, может ли действие быть выполнено (как в случае с полем disabled). GET- и POST-запросы могут возвращать некоторые метаданные, указывающие, может ли действие быть выполнено (как в случае с полем disabled).

Например, если есть конечная точка действия, которая облегчает голосование по предложению управления DAO, окно голосования по которому закрылось, первоначальный GET-запрос может вернуть сообщение об ошибке "Это предложение больше не подлежит голосованию", а кнопки "Голосовать да" и "Голосовать нет" - как "отключенные".

Blinks (блокчейн-ссылки) - это клиентские приложения, которые исследуют Действия API и создают пользовательские интерфейсы для взаимодействия и выполнения Действий.

Клиентские приложения, поддерживающие мигание, просто обнаруживают совместимые с Действиями URL, анализируют их и позволяют пользователям взаимодействовать с ними в стандартных пользовательских интерфейсах.

Info

Любое клиентское приложение, которое полностью исследует Действия API, чтобы создать для него полноценный интерфейс, является мигающим. Поэтому не все клиенты, использующие API Actions, являются мигалками.

URL-адрес blink описывает клиентское приложение, которое позволяет пользователю завершить полный жизненный цикл выполнения действия, включая подписание с помощью своего кошелька.

https://example.domain/?action=<action_url>

Чтобы любое клиентское приложение стало blink:

  • URL-адрес должен содержать параметр запроса action, значение которого является URL-кодированным URL действия. Это значение должно быть закодировано в URL, чтобы не конфликтовать с другими параметрами протокола.

  • Клиентское приложение должно URL-декодировать параметр запроса action и просмотреть предоставленную ссылку Действия API (см. схему Action URL).

  • Клиент должен предоставлять богатый пользовательский интерфейс, позволяющий пользователю пройти весь жизненный цикл выполнения действия, включая подписание кошелька.

Info

Не все клиентские приложения blink (например, веб-сайты или dApps) будут поддерживать все действия.Разработчики приложений могут выбирать, какие действия они хотят поддерживать в своих интерфейсах мигания.

Следующий пример демонстрирует действительный URL-адрес мигания со значением действияsolana-action:https://actions.alice.com/donate, который закодирован в URL:

https://example.domain/?action=solana-action%3Ahttps%3A%2F%2Factions.alice.com%2Fdonate

Blinks могут быть связаны с действиями как минимум тремя способами:

  1. Совместное использование явного URL-адреса действия: solana-action:https://actions.alice.com/donate

    В этом случае только поддерживаемые клиенты могут отображать blink. Не будет ни предварительного просмотра резервной ссылки, ни сайта, который можно посетить за пределами неподдерживаемого клиента.

  2. Обмен ссылкой на веб-сайт, связанный с API Actions через файл actions.json в корневом домене сайта.

    Например, https://alice.com/actions.json сопоставляет https://alice.com/donate\`, URL веб-сайта, на котором пользователи могут пожертвовать Алисе, с API URL https://actions.alice.com/donate, на котором размещены Действия для пожертвования Алисе.

  3. Встраивание URL-адреса действия в URL-адрес "интерстициального" сайта, который понимает, как разбирать Действия.

    https://example.domain/?action=<action_url>

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

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

Если пользователь нажимает на любом месте клиента, которое не является кнопкой действия или полем ввода текста, он должен перейти на базовый сайт.

Хотя действия и blinks Solana представляют собой протокол/спецификацию без разрешений, клиентские приложения и кошельки все равно должны в конечном итоге помочь пользователям подписать транзакцию.

У каждого из этих клиентских приложений или кошельков могут быть свои требования к тому, какие конечные точки действия их клиенты будут автоматически разворачивать и немедленно показывать своим пользователям на платформах социальных сетей.

Например, некоторые клиенты могут работать по принципу "разрешенного списка", который может требовать проверки перед тем, как их клиент развернет действие для пользователей, как, например, реестр действий Dialect (подробнее см. ниже).

Все blinks по-прежнему будут отображаться и позволять подписаться на Dialect's dial.to blinks Interstitial сайт, с их реестра статус отображается в blink.

Реестр действий Dialect #

В качестве общественного блага для экосистемы Solana, Dialect ведет публичный реестр - с помощью Solana Foundation и других членов сообщества - блокчейн-связей, которые были предварительно проверены из известных источников. С момента запуска в Твиттере будут появляться только те действия, которые были зарегистрированы в реестре Dialect.

Клиентские приложения и кошельки могут свободно выбирать, использовать этот публичный реестр или другое решение для обеспечения безопасности пользователей. Если ссылка на блокчейн не верифицирована в реестре Dialect, клиент blink не будет к ней прикасаться и отобразит ее как обычный URL.

Разработчики могут подать заявку на верификацию в Dialect здесь: dial.to/register

Спецификация #

Спецификация Solana Действия состоит из ключевых разделов, которые являются частью потока взаимодействия запрос/ответ:

  • Схема Solana Действия URL, предоставляющая URL-адрес действия
  • Ответ OPTIONS на URL-адрес действия для соблюдения требований CORS
  • GET-запрос к URL-адресу действия
  • GET-ответ от сервера
  • POST-запрос к URL-адресу действия
  • POST-ответ от сервера

Каждый из этих запросов выполняется клиентом действия (например, приложением для кошелька, расширением для браузера, dApp, веб-сайтом и т. д.), чтобы собрать определенные метаданные для богатых пользовательских интерфейсов и облегчить ввод данных пользователем в API действий.

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

Схема URL #

URL-адрес действия Solana описывает интерактивный запрос на подписанную транзакцию или сообщение Solana с использованием протокола solana-action.

Запрос является интерактивным, поскольку параметры в URL используются клиентом для выполнения серии стандартизированных HTTP-запросов для создания подписываемой транзакции или сообщения, которое пользователь должен подписать с помощью своего кошелька.

solana-action:<link>
  • В качестве пути требуется одно поле link. Значение должно быть условно URL-encoded абсолютный HTTPS URL.

  • Если URL содержит параметры запроса, он должен быть кодирован в URL-кодировке. Значение кодировки предотвращает конфликты с параметрами протокола Действий, которые могут быть добавлены через спецификацию протокола.

  • Если URL содержит параметры запроса, он должен быть кодирован в URL-кодировке. Это создает более короткий URL и менее плотный QR-код.

Значение должно быть условно URL-encodedthe) абсолютный HTTPS URL. Это не влияет, если значение не имеет URL-кодировки. Если декодированное значение не является абсолютным HTTPS URL, кошелек должен отклонить его как malformed.

Ответ OPTIONS #

Чтобы разрешить кросс-оригинальный обмен ресурсами (CORS) в клиентах Actions (включая мигалки), все конечные точки Action должны отвечать на HTTP-запросы метода OPTIONS с корректными заголовками, которые позволят клиентам пройти CORS-проверку для всех последующих запросов из домена того же происхождения.

Клиент Actions может выполнять "префлайт" запросы к конечной точке Action URL, чтобы проверить, пройдет ли последующий GET-запрос к Action URL все CORS-проверки. Эти предварительные проверки CORS выполняются с помощью HTTP-метода OPTIONS и должны содержать все необходимые HTTP-заголовки, которые позволят Action-клиентам (например, blinks) правильно выполнять все последующие запросы из их исходного домена.

Как минимум, требуемые заголовки HTTP включают:

  • Access-Control-Allow-Origin со значением *
    • это гарантирует, что все клиенты действий смогут безопасно проходить проверку CORS для того, чтобы все необходимые запросы
  • Access-Control-Allow-Methods со значением GET,POST,PUT,OPTIONS
    • гарантирует, что все необходимые методы HTTP запроса поддерживаются для действий
  • Access-Control-Allow-Headers с минимальным значением Content-Type, авторизация, Содержимое-кодирование, Accept-Encoding

Для простоты разработчикам стоит подумать о том, чтобы возвращать на запросы OPTIONS тот же ответ и заголовки, что и на GET.

Cross-Origin headers for actions.json

Ответ файла actions.json должен также возвращать допустимые заголовки Cross-Origin для запросов GET и OPTIONS, в частности заголовок Access-Control-Allow-Origin в заголовке *.

Более подробную информацию см. в файле actions.json ниже.

Запрос GET #

Клиент Действия (например, кошелек, расширение браузера и т. д.) должен сделать HTTP GET JSON запрос к конечной точке URL Действия.

  • Запрос не должен идентифицировать кошелек или пользователя.
  • Клиент должен отправить запрос с заголовком Accept-Encoding.
  • Клиент должен отобразить домен URL по мере выполнения запроса.

GET Ответ #

Конечная точка URL Действия (например, приложение или бэкэнд сервера) должна ответить JSON-ответом HTTP OK (с корректной полезной нагрузкой в теле) или соответствующей HTTP-ошибкой.

  • Клиент должен обрабатывать ошибки HTTP-клиента, ошибки сервера и ответы перенаправления.

  • Конечная точка должна отвечать с заголовком Content-Encoding для сжатия HTTP.

  • Конечная точка должна отвечать с заголовком Content-Type application/json.

  • Кошелек не должен кэшировать ответ, за исключением случаев, когда это предписано заголовками кэширующего ответа HTTP.

  • Клиент должен отобразить title и выдать пользователю изображение icon.

Тело GET Ответа #

GET-ответ с ответом HTTP OK JSON должен содержать тело полезной нагрузки, соответствующее спецификации интерфейса:

ActionGetResponse
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, иначе клиент/кошелек отвергнет его как неверно сформированный. Файл должен быть изображением SVG, PNG или WebP, иначе клиент/кошелек отвергнет его как неверно сформированный.

  • title - Значение должно быть строкой UTF-8, представляющей источник запроса действия. Например, это может быть название бренда, магазина, приложения или человека, сделавшего запрос.

  • description - Значение должно быть строкой UTF-8, содержащей информацию о действии. Описание должно быть показано пользователю.

  • label - Значение должно представлять собой строку UTF-8, которая будет отображаться на кнопке для нажатия пользователем. Все метки не должны превышать 5 слов и должны начинаться с глагола, чтобы определить действие, которое вы хотите, чтобы пользователь совершил. Например, "Mint NFT", "Vote Yes" или "Stake 1 SOL".

  • disabled - значение должно быть булевым, чтобы представлять отключенное состояние отображаемой кнопки (которая отображает строку метки). Если значение не указано, то disabled по умолчанию должно быть равно false (т. е. включено по умолчанию). Например, если конечная точка действия предназначена для голосования по управлению, которое было закрыто, установите disabled=true, и метка может быть "Голосование закрыто".

  • error - необязательный признак ошибки для нефатальных ошибок. Если он присутствует, клиент должен отобразить его пользователю. Если установлено, оно не должно мешать клиенту интерпретировать действие или отображать его пользователю. Например, ошибка может быть использована вместе с disabled для отображения причины, например, бизнес-ограничений, авторизации, состояния или ошибки внешнего ресурса.

ActionError
export interface ActionError {
  /** non-fatal error message to be displayed to the user */
  message: string;
}
  • links.actions - Необязательный массив связанных действий для конечной точки. Пользователям должен быть показан пользовательский интерфейс для каждого из перечисленных действий, и ожидается, что они выполнят только одно из них. Например, конечная точка действия голосования по вопросам управления может возвращать пользователю три варианта: "Голосовать да", "Голосовать нет" и "Воздержаться от голосования".

    • Если поле links.actionsне указано, клиент должен отобразить единственную кнопку, используя строку корневого label, и выполнить POST-запрос к той же конечной точке URL действия, что и первоначальный GET-запрос.

    • Если указаны какие-либо links.actions, клиент должен отображать кнопки и поля ввода только на основе элементов, перечисленных в поле links.actions. Клиент не должен отображать кнопку для содержимого корневого label.

LinkedAction
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 Ответа #

Следующий пример предоставляет одно действие "root", которое ожидается для предоставления пользователю одной кнопки с меткой "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
          }
        ]
      }
    ]
  }
}

Запрос GET #

Клиент должен сделать HTTP-запрос POST JSON URL действия с телом приложения:

 
  • account - значение должно быть публичным ключом в base58-кодированном аккаунте, который может подписать транзакцию.

Клиент должен сделать запрос с заголовком Accept-Encoding header, а приложение должно ответить заголовком Content-Encoding для сжатия HTTP.

Во время выполнения запроса клиент должен отобразить домен URL действия. Если был сделан GET-запрос, клиент также должен отобразить заголовок и вывести изображение иконки из GET-ответа.

POST Ответ #

Конечная точка URL Действия (например, приложение или бэкэнд сервера) должна ответить JSON-ответом HTTP OK (с корректной полезной нагрузкой в теле) или соответствующей HTTP-ошибкой.

  • Клиент должен обрабатывать ошибки HTTP-клиента, ошибки сервера и ответы перенаправления.
  • Конечная точка должна отвечать с заголовком Content-Type application/json.

Тело POST ответа #

Ответ POST с ответом HTTP OK JSON должен содержать в себя тело полезной нагрузки из:

ActionPostResponse
export interface ActionPostResponse {
  /** base64 encoded serialized transaction */
  transaction: string;
  /** describes the nature of the transaction */
  message?: string;
}
  • transaction - значение должно быть сериализованной транзакции. Кошелек должен base64-декодировать транзакцию и десериализовать ее.

  • message - значение должно быть строкой UTF-8, описывающей характер транзакции в ответе. Кошелек должен отображать это значение для пользователя. Например, это может быть название приобретаемого товара, скидка, примененная к покупке, или благодарность.

  • Клиент и приложение должны разрешить дополнительные поля в теле запроса и в теле ответа, которые могут быть добавлены в будущих обновлениях спецификации.

Info

Приложение может ответить частично или полностью подписанной транзакцией. Кошелек должен подтвердить транзакцию как недоверенную.

POST Ответ - Транзакция #

Если транзакция signatures пуста:

  • Кошелек должен игнорироватьfeePayer в транзакции и установить feePayer на счет в запросе.
  • Кошелек должен игнорировать recentBlockhash в транзакции и установить recentBlockhash на последний блокчейн..
  • Клиент должен сериализовать и десериализовать транзакцию перед ее подписанием. Это обеспечивает последовательное упорядочивание ключей аккаунтов в качестве обходного пути для решения этой проблемы.

Если транзакция была подписана частично:

  • Кошелек не должен устанавливать значения feePayer и recentBlockhash.
  • Кошелек должен проверять подписи, и если какая-либо из них недействительна, кошелек должен отклонить транзакцию как ошибочную.

Кошелек должен подписывать транзакцию только с account в запросе, и должны сделать это только в том случае, если ожидается подпись для account в запросе.

Если в запросе ожидается любая подпись, кроме подписи для account. ожидается, клиент должен отклонить транзакцию как malicious.

#

Назначение файла actions.json file позволяет приложению информировать клиентов о том, какие URL-адреса веб-сайтов поддерживают Solana Actions, и предоставлять сопоставление, которое можно использовать для выполнения GET requestsк серверу API Actions.

Cross-Origin headers are required

Ответ файла actions.json должен также возвращать допустимые заголовки Cross-Origin для запросов GET и OPTIONS, в частности заголовок Access-Control-Allow-Origin в заголовке *.

Смотрите OPTIONS response выше, чтобы узнать подробности.

Файл actions.json должен храниться и быть общедоступным в корневой домене.

Например, если ваше веб-приложение развернуто на my-site.com, то файл actions.json должен быть доступен по адресу https://my-site.com/actions.json. Этот файл также должен быть доступен через любой браузер с заголовком Access-Control-Allow-Origin для *.

Правила #

Поле правил позволяет приложению сопоставить набор относительных маршрутных путей веб-сайта с набором других путей.

Тип: Array ActionRuleObject.

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 #

Шаблон, который соответствует каждому входящему имени пути. Он может быть абсолютным или относительным путем и поддерживает следующие форматы:

  • Точное соответствие: соответствует точному пути URL.

    • Пример: /api/exact-path
    • Пример: https://website.com/exact-path
  • Подстановочный знак: Использует подстановочные знаки для соответствия любой последовательности символов в пути URL. Это может соответствовать одному (с помощью *) или нескольким сегментам (с помощью **). (см. Сопоставление пути ниже).

    • Пример: /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/**

Правила - Параметры запросов #

Параметры запроса из исходного URL всегда сохраняются и добавляются к сопоставленному URL.

Правила - Соответствие пути #

В следующей таблице описывается синтаксис для шаблонов пути соответствия:

ОператорСовпадения
Сегмент одного пути, не включающий разделитель контуров / символов.
Соответствует нулю или более символов, включая любой разделитель пути / символы между несколькими сегментами пути. Если другие операторы включены, то «**» оператор должен быть последним оператором.
Шаблон не поддерживается.

Примеры Правил #

Следующий пример демонстрирует правило точного соответствия запросам на карту запросов в /buy из корня вашего сайта в точный путь /api/buy относительно корня вашего сайта :

actions.json
{
  "rules": [
    {
      "pathPattern": "/buy",
      "apiPath": "/api/buy"
    }
  ]
}

В следующем примере используется подстановочное сопоставление путей для сопоставления запросов к любому пути (включая подкаталоги) в каталоге /actions/ из корня вашего сайта с соответствующим путем в каталоге /api/actions/ относительно корня вашего сайта:

actions.json
{
  "rules": [
    {
      "pathPattern": "/actions/*",
      "apiPath": "/api/actions/*"
    }
  ]
}

В следующем примере используется подстановочное сопоставление путей для сопоставления запросов к любому пути (включая подкаталоги) под /donate/ из корня вашего сайта к соответствующий абсолютный путь https://api.dialect.com/api/v1/donate/ на внешнем сайте:

actions.json
 

В следующем примере используется подстановочное сопоставление путей для идемпотентного правила, чтобы сопоставить запросы к любому пути (включая подкаталоги) под /api/actions/ из вашего корня сайта к самому себе:

Info

Правила Idempotent позволяют морским клиентам более легко определить, поддерживает ли данный путь запросы Action API без необходимости префикса с помощью solana-action: URI или выполнения дополнительного тестирования ответов.

actions.json
{
  "rules": [
    {
      "pathPattern": "/api/actions/**",
      "apiPath": "/api/actions/**"
    }
  ]
}

Идентификатор Действия #

Конечные точки действия могут включать идентификатор действия в транзакции, возвращаемые в POST-ответе для подписи пользователем. Это позволяет индексаторам и аналитическим платформам легко и достоверно относить активность на цепи к конкретному поставщику действий (т. е. сервису).

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

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

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

Сообщение идентификатора действия #

Сообщение идентификатора действия - это отдельная строка UTF-8 с двоеточием, включаемая в транзакцию с помощью одной инструкции SPL Memo.

protocol:identity:reference:signature
  • protocol - значение используемого протокола (установите значение solana-action на в схеме URL выше)
  • identity - значение должно быть адресом открытого ключа с кодировкой base58-кодировки
  • reference - значение должно быть 32-байтовым массивом base58. Это могут быть открытые ключи, на кривой или вне кривой, и могут соответствовать или не соответствовать учетными записями на Solana.
  • signature - подпись, созданная из клавиши Action Identity с кодировкой, подписывающей только значение reference.

Значение reference должно использоваться только один раз и в одной транзакции. Для цель привязки транзакций к Поставщику Действий, только первое использование значения reference считается действительным.

Транзакции могут иметь несколько инструкций по примечаниям. При выполнении [getSignaturesForAddress](https://solana. om/docs/rpc/http/getsignaturesforaddress), результаты поля memo будут возвращать каждое сообщение инструкций как одну строку с каждой отделенной точкой с запятой.

Никакие другие данные не должны быть включены в инструкцию Memo Identifier Message.

identity и reference должны быть включены в качестве только для чтения, неподписавшего [keys](https://solana-labs.github.io/solana-web3. s/classes/TransactionInstruction.html#keys) в транзакции инструкции, не являющейся инструкцией Memo .

В инструкции Identifier Message Memo должна быть указана нулевая учетная запись. Если какие-либо учетные записи предоставлены, программа Memo требует наличия учетных записей для действительных подписчиков . Для определения действий это ограничивает гибкость, а может ухудшить качество работы пользователя. Поэтому он считается антипаттерном, и его следует избегать.

Действие Проверка личности #

Любая транзакция, включающая в себя учётную запись identity, может быть проверяемым связанным с оператором в многоэтапном процессе:

  1. Получить все транзакции для данного identity.
  2. Разберите и проверьте строку мемо каждой транзакции, чтобы убедиться, что подпись действительна для сохраненной ссылки.
  3. Верифицировать конкретную транзакцию - первое вхождение reference в цепочку:
    • Если эта транзакция встречается впервые, транзакция считается проверенной и может быть надежно приписана Поставщику Действий.
    • Если эта транзакция не является первой, она считается недействительной и, следовательно, не может быть приписана Поставщику Действий.

Поскольку Solana индексирует транзакции по ключам аккаунта, getSignaturesForAddress Метод RPC может быть использован для определения всех транзакций, включая identity аккаунт.

Ответ этого метода RPC включает все данные Memo в поле memo. Если несколько инструкций для Memo были использованы в транзакции, каждое сообщение будет включено в это поле memo и должно быть обработано соответствующим образом верификатором для получения Verification Message.

Эти транзакции сначала должны быть признаны НЕВЕРИФИЦИРОВАННЫЙ. Это вызвано тем, что не требуется подписывать транзакцию, которая позволяет транзакции включить эту учетную запись в качестве неподписавшего. Потенциально искусственное Завышение показателей атрибуции и использования.

Сообщение проверка личности следует проверить, чтобы убедиться в том, что signature был создан с помощью identity подписи reference. Если проверка подписи не удается, транзакция считается недействительной и должна быть передана к Поставщику Действий.

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