Actions and Blinks
Solana Actions 是符合规范的 API,返回 Solana 区块链上的交易,供预 览、签名和在各种上下文中发送,包括二维码、按钮 + 小部件和互联网上的网站。Actions 使开发人员能够轻松地将 Solana 生态系统中的操作集成到他们的环境中,允许你执行区块 链交易而无需导航到不同的应用程序或网页。
区块链链接——或称 blinks——将任何 Solana Action 转化为可共享的、富含元 数据的链接。 Blinks 允许支持 Action 的客户端(浏览器扩展钱包、机器人)为用户显示 额外的功能。 在网站上,blink 可能会立即在钱包中触发交易预览,而无需访问去中心化 应用程序;在 Discord 中,机器人可能会将 blink 扩展为一组交互式按钮。 这将链上交 互的能力推向任何能够显示 URL 的网页表面。
开始使用 #
快速开始创建自定义 Solana Actions:
npm install @solana/actions
- 在您的应用程序中安装 Solana Actions SDK
- 为 GET request 构建一个 API 端点,返回关于 Action 的元数据
- 创建一个 API 端点,接受POST request 和返回用户的可签名交易
Info
查看YouTube 视频教程: 学习使用 @solana/actions
SDK
您也可以找到 [Action > 的源代码](https://github.com/solana-developers/solana-actions/blob/main/examples es/next-js/src/app/api/actions/transfer-sol/route.ts) 在这里进行原生 SOL 转移 和其他几个示例操作可以在 这个库 查看。
当部署您自定义的 Solana Action 投入到生产中时:
- 确保您的应用程序在您的域名的根目录上有有效的 actions.json 文件
- 确保您的应用程序响应所有 Action 端点使用 required Cross-Origin headers,包括
actions.json
文件 - test and debug your blinks/actions using the Blinks Inspector
如果你正在寻求围绕建 Action 和 blinks 的灵感,查看 Awesome Blinks 代码库 , 有一些社区作品甚 至新的创意.
Actions #
Solana Actions 规范使用一组标准 API 将可签名的交易(最终是可签名的消息)从应用程 序直接传递给用户。 它们托管在公开可访问的 URL 上,因此任何客户端都可以通过其 URL 进行交互。
Info
你可以将 Actions 视为一个 API 端点,它将返回元数据和供用户使用其区块链钱包签名 的内容(交易或身份验证消息)。
Actions API 包括对 Action 的 URL 端点进行简单的GET
和POST
请求,并处理符合 Actions 接口的响应。
- GET 请求返回元数据,为客户端提供有关此 URL 上可用操作的可读信 息,以及相关操作的可选列表。
- the POST request returns a signable transaction or message that the client then prompts the user's wallet to sign and execute on the blockchain or in another offchain service.
Action 执行和生命周期 #
在实践中,与 Actions 交互与典型的 REST API 交互非常相似:
- 客户端向 Action URL 发出初始
GET
请求以获取有关可用 Actions 的元数据 - 端点返回包含端点元数据(如应用程序的标题和图标)和此端点可用操作列表的响应
- 客户端应用程序(如移动钱包、聊天机器人或网站)显示用户执行其中一个操作的 UI
- 用户选择一个操作(通过点击按钮)后,客户端向端点发出
POST
请求以获取用户签名的 交易 - 钱包促使用户签署交易并最终将交易发送到区块链进行确认
Solana Actions Execution and Lifecycle
从 Actions URL 接收交易时,客户端应处理这些交易的提交到区块链并管理其状态生命周 期。
Actions 还支持在执行前进行某种程度的无效化。 GET
和POST
请求可能会返回一些元数 据,说明操作是否可以执行(如disabled
字段)。
例如,如果有一个 Action 端点用于对 DAO 治理提案进行投票,而投票窗口已关闭,初始 GET 请求可能会返回错误消息“此提案不再接受投票”,并将“投赞成票”和 “投反对票”按钮设置为“禁用”。
Blinks #
Blinks(区块链链接)是客户端应用程序,它们检查 Action API 并构建与 Actions 交互 和执行的用户界面。
支持 blinks 的客户端应用程序只需检测与 Action 兼容的 URL,解析它们,并允许用户在 标准化的用户界面中与它们交互。
Info
任何完全检查 Actions API 以构建完整界面的客户端应用程序都是一个 blink。 因 此,并非所有使用 Actions API 的客户端都是 blinks。
Blink URL 规范 #
一个 blink URL 描述了一个客户端应用程序,使用户能够完成 执行 Action 的完整生命周期,包括使用他们的钱 包签名。
https://example.domain/?action=<action_url>
要使任何客户端应用程序成为 blink:
- blink URL 必须包含一个查询参数
action
,其值是 URL 编码的 Action URL。 此值必须是 URL 编码 的,以避免与任何其他协议参数冲突。 - 客户端应用程序必须 URL 解码
action
查 询参数并检查提供的 Action API 链接(参见 Action URL 方案)。 - 客户端必须呈现一个丰富的用户界面,使用户能够完 成执行 Action 的完整生命周期,包括使用他们 的钱包签名。
Info
并非所有 blink 客户端应用程序(例如网站或 dApps)都将支持所有 Actions。 应用程 序开发人员可以选择他们希望在 blink 界面中支持的 Actions。
以下示例演示了一个有效的 blink URL,其action
值 为solana-action:https://actions.alice.com/donate
,并进行了 URL 编码:
https://example.domain/?action=solana-action%3Ahttps%3A%2F%2Factions.alice.com%2Fdonate
Detecting Actions via Blinks #
Blinks 可以通过至少 3 种方式链接到 Actions:
-
共享一个显式的 Action URL:
solana-action:https://actions.alice.com/donate
在这种情况下,只有支持的客户端可以渲染 blink。 在这种情况下,只有支持的客户端 可以渲染 blink。不会有回退链接预览,或显示不支持的客户端之外访问的网站。
-
共享一个链接到 Actions API 的网站链接,通过网站域根目录 的actions.json文件。
例如,
https://alice.com/actions.json
将https://alice.com/donate
,一个用户 可以向 Alice 捐款的网站 URL,映射到 API URLhttps://actions.alice.com/donate
,在该 URL 上托管了向 Alice 捐款的 Actions。 -
在一个“中间”网站 URL 中嵌入一个 Action URL,该网站 URL 知道如何解析 Actions。
https://example.domain/?action=<action_url>
支持 blinks 的客户端应能够采用上述任何格式并正确渲染界面,以便直接在客户端中执行 操作。
对于不支持 blinks 的客户端,应有一个底层网站(使浏览器成为通用回退)。
如果用户在客户端的任何地方点击,而不是操作按钮或文本输入字段,他们应该被带到底层 网站。
Blink 测试和验证#
虽然 Solana Actions 和 blinks 是一种无需许可的协议 / 规范,但最终仍需要客户端应用程序和钱包来方便用户签署交易。
信息
使用Blinks Inspector工具直接在浏览器中检查、调试和测试您的眨眼和操作。您可以查看 GET 和 POST 响应负载、响应标头,并测试每个链接操作的所有输入。
每个客户端应用程序或钱包可能对其客户端将自动展开并立即在社交媒体平台上向其用户显示的操作端点有不同的要求。
例如,一些客户端可能采用“允许列表”方式进行操作,这可能要求在其客户端为用户展开操作之前进行验证,例如 Dialect 的操作注册表(详见下文)。
所有闪烁仍将呈现并允许在 Dialect 的 dial.to闪烁间质网站上签名,其注册状态显示在闪烁中。
Dial的actions注册表#
作为 Solana 生态系统的公共资源,Dialect 在 Solana 基金会和其他社区成员的帮助下维护了一个公共注册表,其中包含来自已知来源的预先验证过的区块链链接。自发布以来,只有在 Dialect 注册表中注册的操作才会在发布时在 Twitter 源中展开。
客户端应用程序和钱包可以自由选择使用此公共注册表或其他解决方案,以帮助确保用户安全。如果未通过 Dialect 注册表进行验证,区块链链接将不会被 Blink 客户端触及,并将呈现为典型的 URL。
开发者可以在此处申请 Dialect 验证: dial.to/register
规范 #
Solana Actions 规范包括请求/响应交互流程中的关键部分:
- Solana Action URL 方案 提供一个 Action URL
- 选项响应 针对通过 CORS 要求的操作 URL
- 对 Action URL 的 GET 请求
- 服务器返回的 GET 响应
- 对 Action URL 的 POST 请求
- 服务器返回的 POST 响应
这些请求都是由 Action 客户端(例如钱包应用程序、浏览器扩展、dApp、网站等)发出 的,以收集丰富用户界面的特定元数据并促进用户输入到 Actions API。
每个响应都是由应用程序(例如网站、服务器后端等)制作并返回给 Action 客户端。最 终,提供一个可签名的交易或消息,供钱包提示用户批准、签名并发送到区块链。
信息
本自述文件中声明的类型和接口通常是类型的简化版本,以提高可读性。
为了提高类型安全性并改善开发人员体验,该 @solana/actions-spec
包包含更复杂的类型定义。您可以在此处找到 它们的源代码。
URL 方案 #
一个 Solana Action URL 描述了一个使用solana-action
协议的可交互请求,用于签名的 Solana 交易或消息。
请求是交互式的,因为 URL 中的参数被客户端用来进行一系列标准化的 HTTP 请求,以为 用户组成一个可签名的交易或消息,供其使用钱包签名。
solana-action:<link>
- 单个
link
字段是必需的,作为路径名。 单个link
字段是必需的,作为路径名。该值 必须是条件性 URL 编码的 绝对 HTTPS URL。 - 如果 URL 包含查询参数,则必须进行 URL 编码。 URL 编码的值可防止与任何 Actions 协议参数冲突,这些参数可能会通过协议规范添加。
- 如果 URL 不包含查询参数,则不应进行 URL 编码。这会生成一个更短的 URL 和一个更 少密集的二维码。
在任何情况下,客户端都必须 URL 解码该 值。 如果该值未进行 URL 编码,则不会产生任何影响。 如果解码后的值不是绝对的 HTTPS URL,钱包必须将其拒绝为格式错误。
OPTIONS 响应#
为了允许 Actions 客户端(包括 blink)内的跨源资源共享 ( CORS ),所有 Action 端点都应使用有效标头响应该OPTIONS
方法的 HTTP 请求,以便客户端能够对来自其同一源域的所有后续请求传递 CORS 检查。
Actions 客户端可以对 Action URL 端点执行“预检”请求,以检查对 Action URL 的后续 GET 请求是否会通过所有 CORS 检查。这些 CORS 预检检查使用OPTIONS
HTTP 方法进行,并应使用所有必需的 HTTP 标头进行响应,以使 Action 客户端(如 blinks)能够从其原始域正确发出所有后续请求。
至少,所需的 HTTP 标头包括:
-
Access-Control-Allow-Origin
其值为*
- 这确保所有 Action 客户端都可以安全地通过 CORS 检查,以便发出所有必需的请求
-
Access-Control-Allow-Methods
其值为GET,POST,PUT,OPTIONS
- 确保 Actions 支持所有必需的 HTTP 请求方法
-
Access-Control-Allow-Headers
最小值为Content-Type, Authorization, Content-Encoding, Accept-Encoding
OPTIONS
为了简单起见,开发人员应该考虑向请求返回与其GET响应相同的响应和标头。
action.json 的跨域标头
文件响应还必须返回和请求actions.json
的有效跨域标头 ,特别 是的标头值。GET``OPTIONS``Access-Control-Allow-Origin``*
有关更多详细信息,请参阅下面的actions.json。
GET 请求 #
Action 客户端(例如钱包、浏览器扩展等)应向 Action 的 URL 端点发出 HTTP GET
JSON 请求。
- 请求不应识别钱包或用户。
- 客户端应发起 带Accept-Encoding请求头的 请求
- 客户端应在请求时显示 URL 的域名。
GET 响应 #
Action 的 URL 端点(例如应用程序或服务器后端)应以 HTTP OK
JSON 响应(正文中包 含有效负载)或适当的 HTTP 错误进行响应。
- 客户端必须处理 HTTP 客户端错误、服务器错误 和 重定向响应。
- 端点应使 用Content-Encoding请求头进 行 HTTP 压缩响应。
- 端点应以
application/json
类型 的Content-Type请求头进 行响应。 - 除非HTTP 缓存响应标头另有指示,否则客户端不应缓存响应 。
- 客户端应该向用户显示
title
并呈现icon
图像。
错误响应(即 HTTP 4xx 和 5xx 状态代码)应返回 JSON 响应主体,以便ActionError
向用户显示有用的错误消息。请参阅操作错误。
GET 响应正文 #
带有 HTTP OK
JSON 响应的GET
响应应包括一个遵循接口规范的正文负载:
actions获取响应
export type ActionType = "action" | "completed"; export type ActionGetResponse = Action<"action">; export interface Action<T extends ActionType> { /** type of Action to present to the user */ type: T; /** 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;}
-
type
- 向用户提供的操作类型。默认为action
。初始值ActionGetResponse
必须为 类型action
。action
- 标准操作,允许用户与任何LinkedActions
completed
- 用于声明actions链中的“完成”状态。
-
icon
- 该值必须是图标图像的绝对 HTTP 或 HTTPS URL。 文件必须是 SVG、PNG 或 WebP 图像,否则客户端/钱包必须将其拒绝为格式错误。 -
title
- 该值必须是表示操作请求来源的 UTF-8 字符串。 例如,这可能是发出请求的 品牌、商店、应用程序或个人的名称。 -
description
- 该值必须是提供操作信息的 UTF-8 字符串。 描述应显示给用户。 -
label
- 该值必须是将在按钮上呈现给用户点击的 UTF-8 字符串。 所有标签不应超过 5 个单词短语,并应以动词开头,以明确你希望用户采取的操作。 例如,“铸造 NFT”、“ 投赞成票”或“质押 1 SOL”。 -
disabled
- 该值必须是布尔值,表示呈现按钮的禁用状态(显示label
字符串)。如 果未提供值,disabled
应默认为false
(即默认启用)。 例如,如果操作端点是一个 已关闭的治理投票,设置disabled=true
,标签可以是“投票已关闭”。 -
error
- 一个可选的非致命错误指示。 如果存在,客户端应将其显示给用户。 If set, it should not prevent the client from interpreting the action or displaying it to the user (see Action Errors). For example, the error can be used together withdisabled
to display a reason like business constraints, authorization, the state, or an error of external resource. -
links.actions
- 端点的相关操作的可选数组。 用户应显示每个列出的操作的 UI,并 期望只执行一个。 例如,一个治理投票操作端点可能会返回三个选项供用户选择:“投赞 成票”、“投反对票”和“弃权”。- 如果没有
links.actions
提供,客户端应该使用根字符串呈现单个按钮label
,并向与初始 GET 请求相同的操作 URL 端点发出 POST 请求。 - 如果
links.actions
提供了任何内容,客户端应仅根据字段中列出的项目呈现按钮和输入字段links.actions
。客户端不应为根的内容呈现按钮label
。
- 如果没有
链接actions
export interface LinkedAction { /** URL endpoint for an action */ href: string; /** button text rendered to the user */ label: string; /** * Parameters to accept user input within an action * @see {ActionParameter} * @see {ActionParameterSelectable} */ parameters?: Array<TypedActionParameter>;}
允许ActionParameter
声明 Action API 向用户请求什么输入:
actions参数
/** * Parameter to accept user input within an action * note: for ease of reading, this is a simplified type of the actual */export interface ActionParameter { /** input field type */ type?: ActionParameterType; /** 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; /** regular expression pattern to validate user input client side */ pattern?: string; /** human-readable description of the `type` and/or `pattern`, represents a caption and error, if value doesn't match */ patternDescription?: string; /** the minimum value allowed based on the `type` */ min?: string | number; /** the maximum value allowed based on the `type` */ max?: string | number;}
应pattern
为有效正则表达式的字符串等价物。blink 客户端应使用此正则表达式模式在发出 POST 请求之前验证用户输入。如果pattern
不是有效的正则表达式,客户端应忽略它。
是patternDescription
预期用户输入请求的可读描述。如果pattern
提供,则patternDescription
需要提供。
min
和值max
允许输入设置从用户请求的输入的下限和/或上限(即最小/最大数字和或最小/最大字符长度),并应用于客户端验证。对于 或type
的输入,这些值应该是字符串日期。对于其他基于字符串的输入,值应该是代表其最小/最大字符长度的数字。date``datetime-local``type
如果用户输入的值不符合要求pattern
,则用户应该收到一条客户端错误消息,指示输入字段无效并显示字符串patternDescription
。
字段type
允许 Action API 声明更具体的用户输入字段,从而提供更好的客户端验证并改善用户体验。在许多情况下,此类型将类似于标准 HTML 输入元素。
可以ActionParameterType
简化为以下类型:
actions参数类型
/** * Input field type to present to the user * @default `text` */export type ActionParameterType = | "text" | "email" | "url" | "number" | "date" | "datetime-local" | "checkbox" | "radio" | "textarea" | "select";
每个值type
通常都会产生一个类似于input
相应标准 HTML 元素的用户输入字段type
(即 <input type="email" />
),以提供更好的客户端验证和用户体验:
text
- 相当于 HTML “文本”输入 元素email
- 相当于 HTML “电子邮件”输入 元素url
- 相当于 HTML “url”输入 元素number
- 相当于 HTML “number” 输入 元素date
- 相当于 HTML “日期”输入 元素datetime-local
- 相当于 HTML “datetime-local”输入 元素checkbox
- 相当于一组标准 HTML “复选框”输入 元素。Action API 应返回options
如下所述。用户应该能够选择多个提供的复选框选项。radio
- 相当于一组标准 HTML “单选”输入 元素。Action API 应返回options
如下所述。用户应该只能选择提供的单选选项之一。- 目前不支持上面未指定 的其他 HTML 输入类型等效项(
hidden
、、、等) 。button``submit``file
除了上面类似于 HTML 输入类型的元素之外,还支持以下用户输入元素:
textarea
- 相当于 HTML textarea 元素。允许用户提供多行输入。select
- 相当于 HTML select 元素,让用户体验“下拉”样式的字段。Action API 应返回options
如下所述。
当type
设置为select
、checkbox
或radio
时,Action API 应包含一个 数组,每个数组至少options
提供一个label
和。每个选项还可以有一个值,以通知 blink-client 应默认为用户选择哪个选项(请参阅和了解区别)。value``selected``checkbox``radio
这ActionParameterSelectable
可以简化为以下类型定义:
可选择actions参数
/** * note: for ease of reading, this is a simplified type of the actual */interface ActionParameterSelectable extends ActionParameter { options: Array<{ /** displayed UI label of this selectable option */ label: string; /** value of this selectable option */ value: string; /** whether or not this option should be selected by default */ selected?: boolean; }>;}
如果未type
设置或设置了未知/不支持的值,则 blink-clients 应默认text
并呈现简单的文本输入。
Action API 仍然负责验证和清理来自用户输入参数的所有数据,并根据需要强制执行任何“必需的”用户输入。
对于非基于 HTML/web 的平台(如原生移动平台),应使用等效的原生用户输入组件来实现与上述 HTML/web 输入类型等效的体验和客户端验证。
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
请 求端点中包含该输入(通过LinkedAction
中的href
字段):
以下示例响应为用户提供了 3 个链接操作来质押 SOL:一个标签为“质押 1 SOL”的按钮, 另一个标签为“质押 5 SOL”的按钮,以及一个允许用户输入特定“金额”值的文本输入字段, 该值将发送到 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 请求 #
客户端必须向操作 URL 发出 HTTP POST
JSON 请求,正文负载为:
{ "account": "<account>"}
account
- 该值必须是一个 base58 编码的账户公钥,该账户可以签署交易。
客户端应使用Accept-Encoding 标头发出请求 ,应用程序可以使用 Content-Encoding 标头进行响应 以进行 HTTP 压缩。
客户端应在请求时显示操作 URL 的域名。 如果发出了GET
请求,客户端还应显 示title
并呈现icon
图像。
POST 响应 #
Action 的POST
端点应以 HTTP OK
JSON 响应(正文中包含有效负载)或适当的 HTTP 错误进行响应。
- 客户端必须处理 HTTP 客户端错误、服务器错误和重定向响应。
- 端点应以
application/json
类型的 Content-Type响应头进 行响应。
错误响应(即 HTTP 4xx 和 5xx 状态代码)应返回 JSON 响应主体,以便ActionError
向用户显示有用的错误消息。请参阅操作错误。
POST 响应正文 #
带有 HTTP OK
JSON 响应的POST
响应应包括一个正文负载:
actions后响应
/** * Response body payload returned from the Action POST Request */export interface ActionPostResponse<T extends ActionType = ActionType> { /** base64 encoded serialized transaction */ transaction: string; /** describes the nature of the transaction */ message?: string; links?: { /** * The next action in a successive chain of actions to be obtained after * the previous was successful. */ next: NextActionLink; };}
transaction
- 该值必须是一个 base64 编码 的序列化交易。 The client must base64-decode the transaction and deserialize it.message
- 该值必须是描述响应中包含的交易性质的 UTF-8 字符串。 The client should display this value to the user. 例如,这可能是购买商品的名称、购买时应 用的折扣或感谢信。links.next
- 可选值,用于将多个操作串联在一起。在transaction
链上确认包含的操作后,客户端可以获取并呈现下一个操作。 有关更多详细信息,请参阅操作链。- 客户端和应用程序应允许请求正文和响应正文中的其他字段,这些字段可能会通过未来的 规范更新添加。
信息
应用程序可以响应部分或完全签名的交易。 The client and wallet must validate the transaction as untrusted.
POST 响应 - 交易#
如果交易 signatures 为空或者交易尚未部分签名:
- 客户端必须忽略 feePayer 交易中的,并将请求中的设置
feePayer
为。account
- 客户端必须忽略 recentBlockhash 交易中的并将设置
recentBlockhash
为 最新的区块哈希。 - 客户端必须在签名之前序列化和反序列化交易。这确保了账户密钥的顺序一致,作 为此问题的解决方法。
如果交易已部分签署:
- 客户不得更改 feePayer 或 recentBlockhash ,因为这会使任何现有签名无效。
- 客户端必须验证现有的签名,如果签名无效,则客户端必须拒绝该交易,因为其格式不正确。
客户端只能在请求中使用 签署交易,并且只有在预期请求中account
的 签名时才必须这样做。account
account
如果期望请求中的签名以外的任何签名,则客户端必须拒绝该交易,因为交易是恶意的。
操作错误#
Actions API 应使用 返回错误,ActionError
以便向用户显示有用的错误消息。根据上下文,此错误可能是致命的,也可能是非致命的。
actions错误
export interface ActionError { /** simple error message to be displayed to the user */ message: string;}
当 Actions API 响应 HTTP 错误状态代码(即 4xx 和 5xx)时,响应主体应为以下 JSON 负载ActionError
。该错误被视为致命错误,message
应向用户显示包含的内容。
对于支持可选error
属性(如 ActionGetResponse)的 API 响应,该错误被视为非致命错误,并且message
应向用户显示所包含的内容。
Actions链
Solana Actions 可以以连续的序列“链接”在一起。在 Action 的交易在链上确认后,可以获得下一个 Action 并呈现给用户。
actions链允许开发人员在眨眼间构建更复杂、更动态的体验,包括:
- 向用户提供多个交易(并最终签署消息)
- 根据用户钱包地址定制操作元数据
- 交易成功后刷新闪烁元数据
- 接收带有交易签名的 API 回调,以便在 Action API 服务器上进行额外的验证和逻辑
- 通过更新显示的元数据(例如新图像和描述)定制“成功”消息
要将多个操作链接在一起,请在其中ActionPostResponse
包含 links.next
以下任一操作:
PostNextActionLink
- POST 请求链接,使用同源回调 URL 接收主体中的signature
和用户account
。此回调 URL 应以 响应NextAction
。InlineNextActionLink
- 交易确认后立即向用户呈现下一步操作的内联元数据。不会进行回调。
export type NextActionLink = PostNextActionLink | InlineNextActionLink; /** @see {NextActionPostRequest} */export interface PostNextActionLink { /** Indicates the type of the link. */ type: "post"; /** Relative or same origin URL to which the POST request should be made. */ href: string;} /** * Represents an inline next action embedded within the current context. */export interface InlineNextActionLink { /** Indicates the type of the link. */ type: "inline"; /** The next action to be performed */ action: NextAction;}
下一步操作#
在ActionPostResponse
包含的内容transaction
由用户签名并在链上确认后,Blink 客户端应该执行以下操作之一:
- 执行回调请求以获取并显示
NextAction
,或 - 如果
NextAction
已经通过提供links.next
,则 Blink 客户端应更新显示的元数据,并且不进行回调请求
如果回调 URL 与初始 POST 请求的来源不同,则不应发出回调请求。Blink 客户端应显示错误通知用户。
下一步行动
/** The next action to be performed */export type NextAction = Action<"action"> | CompletedAction; /** The completed action, used to declare the "completed" state within action chaining. */export type CompletedAction = Omit<Action<"completed">, "links">;
根据type
,下一步操作应通过以下方式之一通过 Blink 客户端呈现给用户:
action
- (默认)标准操作将允许用户查看所包含的操作元数据、与提供的进行交互LinkedActions
并继续链接任何后续操作。completed
- actions链的终端状态,可以使用包含的actions元数据更新闪烁 UI,但不允许用户执行进一步的actions。
如果links.next
没有提供,Blink 客户端应该假定当前操作是链中的最终操作,并在交易确认后显示其“完成”的 UI 状态。
actions.json #
actions.json文件的目的是允许应用程序指示客户端哪些网站 URL 支 持 Solana Actions,并提供一个映射,可用于对 Actions API 服务器执行 GET 请求 。
需要跨域标头
文件响应还必须返回和请求actions.json
的有效跨域标头 ,特别 是的标头值。GET``OPTIONS``Access-Control-Allow-Origin``*
请参阅上面的OPTIONS 响应以了解更多详细信息。
actions.json
文件应存储在域的根目录下,并且可以被普遍访问。
例如,如果你的 web 应用程序部署在my-site.com
,那么actions.json
文件应可以通 过https://my-site.com/actions.json
访问。This file should also be Cross-Origin accessible via any browser by having a Access-Control-Allow-Origin
header value of *
.
规则 #
rules
字段允许应用程序将一组网站的相对路径映射到另一组路径。
类型:ActionRuleObject
的数组
。
actions规则对象
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 路径。
- 示例:
/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 #
actions请求的目标路径。它可以定义为绝对路径名或外部 URL。 它可以定义为绝对路径名或 外部 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
{ "rules": [ { "pathPattern": "/donate/*", "apiPath": "https://api.dialect.com/api/v1/donate/*" } ]}
以下示例使用通配符路径匹配的幂等规则将来自站点根目录的/api/actions/
下的任何路 径(包括子目录)请求映射到自身:
信息
幂等规则允许闪烁客户端更容易确定给定路径是否支持 Action API 请求,而无需 以solana-action:
URI 为前缀或执行额外的响应测试。
actions.json
{ "rules": [ { "pathPattern": "/api/actions/**", "apiPath": "/api/actions/**" } ]}
actions标识#
在返回给用户签署的 POST 响应中的事务中,操作端点可能包含一个 Action Identity。 这样允许索引器和分析平台以可验证的方式轻松地将链上活动归因于 特定的 Action Provider(即服务)。
Action Identity 是一个密钥对,用于签署包含在交易中的特殊格式 消息,使用 Memo 指令。 这种 Identifier Message 可以被验证地归属于特定的 Action Identity,从而将交易归属于特定的 Action Provider。
密钥对本身不需要签署交易。 这允许钱包和应用程序在没有其他签名的情况下提高返回给 用户的交易的可交付性(参见 POST response transaction)。
如果 Action Provider 的用例要求其后端服务在用户之前预签交易,他们应使用此密钥对 作为其 Action Identity。 这将减少交易中包含的一个账户,从而将总交易大小减少 32 字节。
actions标识符消息#
Action Identifier Message 是一个使用单个 SPL Memo 指令包含在交易中的以冒号分隔的 UTF-8 字符串。
protocol:identity:reference:signature
protocol
- 使用的协议的值(根据上面的 URL Scheme 设置 为solana-action
)identity
- 值必须是 Action Identity 密钥对的 base58 编码的公钥地址reference
- 值必须是 base58 编码的 32 字节数组。这可能是也可能不是公钥,可能 在曲线上也可能不在曲线上,可能与 Solana 上的账户对应也可能不对应。signature
- 由 Action Identity 密钥对仅签署reference
值创建的 base58 编码签 名。
reference
值必须仅使用一次并且在单个交易中使用。 为了将交易与 Action Provider 关联,只有第一次使用reference
值被认为是有效的。
交易可能有多个 Memo 指令。 当执 行getSignaturesForAddress 时,结果memo
字段将返回每个 memo 指令的消息作为单个字符串,每个字符串用分号分 隔。
Identifier Message 的 Memo 指令不应包含其他数据。
identity
和reference
应作为只读的、非签名的 keys 包含在交易中,但不应在 Identifier Message Memo 指令中。
Identifier Message Memo 指令必须不提供任何账户。 如果提供了任何账户,Memo 程序要 求这些账户是有效的签名者。 为了识别操作,这限制了灵活性并可能降低用户体验。 因此 被认为是一种反模式,必须避免。
Action Identity 验证 #
任何包含identity
账户的交易都可以通过多步骤过程验证地与 Action Provider 关联:
-
获取给定
identity
的所有交易。 -
解析并验证每个交易的 memo 字符串,确保
signature
对存储的reference
是有效 的。 -
验证特定交易是链上首次出现的
reference
:- 如果此交易是首次出现,则交易被认为是验证的,可以安全地归属于 Action Provider。
- 如果此交易不是首次出现,则被认为是无效的,因此不归属于 Action Provider。
由于 Solana 验证器按账户密钥索引交 易,getSignaturesForAddressRPC 方法可用于定位所有包含identity
账户的交易。
此 RPC 方法的响应包括memo
字段中的所有 Memo 数据。 如果交易中使用了多个 Memo 指 令,每个 memo 消息将包含在此memo
字段中,验证者必须相应地解析以获取 Identity Verification Message。
这些交易应初步视为 UNVERIFIED。 这是因为identity
不需要签署交易,这允许任何 交易将此账户作为非签名者包含在内。 可能会人为地增加归属和使用计数。
应检查 Identity Verification Message 以确保signature
是由identity
签 署reference
创建的。 如果此签名验证失败,则交易无效,不应归属于 Action Provider。
如果签名验证成功,验证者应确保此交易是链上首次出现的reference
。 如果不是,则交 易被认为无效,https://t.me/gtokentool。