原文:https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804
在 blink 客户端中添加新的输入类型,以改善用户体验,并为 Action 开发者解锁新用例。
当前的 Solana Actions 和 blinks 规范仅支持单一的、通用的非结构化文本框输入类型。虽然这种基本输入很有用,但拥有更明确和声明性的输入类型将允许 Action 开发者和 blink 客户端解锁新的用例,并改善在互联网上使用 blinks 的用户体验。
根据当前的规范,Action API 将使用初始 GET 请求的结构化响应(ActionGetResponse
)来声明它需要的用户输入字段,特别是通过links.actions
中包含parameters
字段的任何子项。
当前的规范是这样的:
/**
* Response body payload returned from the Action GET Request
*/
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;
}
/**
* Related action on a single endpoint
*/
export interface LinkedAction {
/** URL endpoint for an action */
href: string;
/** button text rendered to the user */
label: string;
/** parameters used to accept user input within an action */
parameters?: ActionParameter[];
}
任何 ActionParameter
声明都将被渲染成纯文本输入呈现给用户(带有可选的占位符文本),以便接受他们的输入,最终通过 POST 请求发送 Action API 端点。
此外,用户输入数据仅通过在特定 linked action 的href
字段中声明的查询参数和模板字面量(例如:{name}
)发送到 Action API。在接受更长的用户输入值或更复杂的输入类型时,这会带来限制和复杂性。
/**
* 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;
}
1. 为支持将更长的和更复杂的用户输入(通过 POST 请求)发送到 Action API,用户输入应可选地通过 POST 请求正文(body)
发送,而不仅仅是通过模板化的查询参数(例如已被发送的用户的account
地址)。对于每个LinkedAction
,所有用户输入都应以如下的方式被发送到 Action API:
href
值的查询参数中通过模板字面量指定的任何parameters
输入都应该通过其命名的查询参数发送各自的用户输入值(这是规范当前的运作方式);parameters
输入(也就是那些没有在href
中声明模板字面量的输入)应该在 POST 请求的正文
中发送(与用户的account
一起发送,但永远不能修改account
值);parameters
的模板字面量被找到,它就不应该通过正文
发送。这将减少通过网络发送的总数据,不发送重复数据从来也都是最佳的做法。最终,这会允许开发人员通过查询参数(不破坏现有的应用程序)或通过 POST 请求正文
接受用户输入。并可以像典型的 HTML 表单一样,有效地设置隐式默认使用 POST 正文来接收用户输入。
2. 更新ActionParameter
以支持声明不同类型的用户输入,并允许为更复杂的输入提供正则表达式匹配模式。
更新后的ActionParameter
应如下所示:
/**
* Parameter to accept user input within an action
*/
export interface ActionParameter {
/** input field type */
type?: ActionParameterType;
/** regular expression pattern to validate user input client side */
pattern?: string;
/** human readable description of the `pattern` */
patternDescription?: string;
/** 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;
}
该匹配模式(pattern)
等同于有效的正则表达式字符串。blink 客户端应在发出 POST 请求前使用该正则表达式匹配模式来验证用户输入。如果匹配模式
不是有效的正则表达式,客户端就会忽略它。
匹配模式描述(patternDescription)
是描述正则表达式匹配模式
的人类可读信息。如果提供了匹配模式
,则必须提供匹配模式描述
。
如果用户输入值根据匹配模式
被认为无效,用户在客户端就会收到一条错误信息,提示输入字段无效,并显示匹配模式描述
字符串。
在大多情况下,类型(type)
类似于标准的 HTML 输入元素。
新的类型
属性应有如下的类型声明:
/**
* Input type to present to the user
* @default `text`
*/
export type ActionParameterType =
| "text"
| "email"
| "url"
| "number"
| "date"
| "datetime-local"
| "checkbox"
| "radio"
| "textarea"
| "select";
每一个提出的类型
值通常应该生成一个用户输入字段,类似于相应的类型
的标准 HTML输入
元素(即 <输入类型 = "email" />) ,以提供更好的客户端验证和用户体验:
text
- 等同于 HTML “text” input元素email
- 等同于 HTML “email” input 元素url
- 等同于 HTML “url” input元素number
- 等同于 HTML “number” input元素date
- 等同于 HTML “date” input元素datetime-local
- 等同于 HTML “datetime-local” input元素checkbox
- 等同于一组标准的 HTML “checkbox” input元素。Action API 应返回如下所示的选项(options)
。用户应能于所提供的 checkbox 选项中进行多选。radio
- 等同于一组标准的 HTML “radio” input元素。Action API 应返回如下所示的选项
。用户只能于所提供的 radio 选项中选择一项。hidden
, button
, submit
, file
, 等等)。除了上述类似 HTML 输入类型的元素外,还支持以下用户输入元素:
textarea
- 等同于 HTML textarea element元素。用户可进行多行输入。select
- 等同于 HTML select element元素。用户会体验一个“下拉”样式的字段。Action API 应返回如下所示的选项
。当类型
设置为选择(select)
、复选框(checkbox)
或单选框(radio)
时,Action API 应包含一个选项
数组,每个选项至少提供一个标签(label)
和值(value)
。每个选项还可以有一个选中(selected)
值,以告知 blink 客户端用户在默认情况下应选择哪个选项(参见复选框和单选框的区别)。
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
}>;
}
如果没有设置类型
或设置了未知/不支持的值,blink 客户端应默认为文本(text)
,并呈现一个简单的文本输入(正如他们目前的做法)。
Action API 仍负责验证和清理用户输入参数中的所有数据,并在必要时强制执行任何“必需的”用户输入。
对于其它基于 HTML/web 的平台(如本地移动平台),应使用等效的本地用户输入组件,以获得与上述 HTML/web 输入类型相同的体验和客户端验证。
注意:与当前规范一样,如果LinkedAction
没有声明parameters
属性,那么 Action API 就不会请求用户输入,blink 客户端应继续渲染一个向href
端点执行 POST 请求的单个按钮。本提案不会改变这一点。
随着对更多输入类型的支持,开发人员将能够构建更复杂的 blinks,并接受更多的用户输入。户输入字段“过多”可能会降低用户体验,也会降低用户实际输入所有要求输入内容的可能性。
为了避免用户界面(UI)臃肿和降低用户体验,blink 客户端可能会对其显示的输入字段数量进行“软限制”。虽然本 Actions/blink 规范避免对 blinks 的用户界面层采取见仁见智的做法,但以下是一个合理的指导原则(目前 Dialect 的 blinks SDK 也在使用):
因此,Action API 开发人员应限制所请求的输入parameters
数量,因为 blink 客户端可能会限制向用户显示的输入字段数量。开发人员还应记住,如果用户看不到所有的输入字段(因为 blink 客户端软限制了这些字段,如上所述),那么用户将无法输入值。因此,如果所有这些字段都是 Action API 所要求的,用户将无法实际执行你的 Action 并达成交易。