# sRFC 29 - Input types of blinks and actions

**URL:** <https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804>\
**Category:** sRFC\
**Created:** [July 15, 2024, 7:12pm UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804 "2024-07-15T19:12:28Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![nickfrosty](https://yyz2.discourse-cdn.com/flex030/user_avatar/forum.solana.com/nickfrosty/32/106_2.png) [@nickfrosty](https://forum.solana.com/u/nickfrosty)\
**Post date:** [July 15, 2024, 7:12pm UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804/1 "2024-07-15T19:12:29Z")

</div>

# sRFC 29 - Input types of blinks and actions

## TLDR

Add new input types within blink clients to improve the user experience and unlock new use cases for Action builders.

## Rationale

The current Solana Actions and blinks specification only supports a single, generic input type of a non-structured text box. While this basic input is useful, having more explicit and declarative input types would allow Action builders and blink clients to unlock new use cases and improve the user experience of using blinks across the internet.

## Current Spec

Per the current specification, an Action api will declare what user input fields it desires using the structured response (`ActionGetResponse`) from the initial GET request, specifically via any child item of `links.actions` containing the `parameters` field.

The current specification is this:

```tsx
/**
 * 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[];
}

```

Any `ActionParameter` declared will result in a plain text input be rendered to the user (with the optional placeholder text) in order to accept their input, which ultimately gets sent the Action api endpoint via the POST request.

Additionally, the user input data is only sent to the Action api via query parameters and template literals (e.g. `{name}`) declared within the specific linked action’s `href` field. This presents limitations and complexities when accepting longer user input values or more complex input types.

```tsx
/**
 * 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;
}

```

## Proposal

1. To support sending longer and more complex user input to the Action API (via the POST request), user input should be optionally sent via the POST request `body`, not just templatized query parameters (like the user’s `account` address is already being sent).  
All user input should be sent to the Action API as follows for each `LinkedAction`:

2. Update the `ActionParameter` to support declaring different types of user input. In many cases, this `type` will resemble the standard [HTML input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input).

```tsx
/**
 * Input type to present to the user 
 * @default `text`
 */
export type ActionParameterType =
  | "text"
  | "email"
  | "url"
  | "number"
  | "date"
  | "datetime-local"
  | "checkbox"
  | "radio"
  | "textarea"
  | "select";

```

Each of the proposed `type` values should normally result in a user input field that resembles a standard HTML `input` element of the corresponding `type` (i.e. `<input type="email" />`) to provide better client side validation and user experience:

- `text` - equivalent of HTML [“text” input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/text) element
- `email` - equivalent of HTML [“email” input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/email) element
- `url` - equivalent of HTML [“url” input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/url) element
- `number` - equivalent of HTML [“number” input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number) element
- `date` - equivalent of HTML [“date” input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date) element
- `datetime-local` - equivalent of HTML [“datetime-local” input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/datetime-local) element
- `checkbox` - equivalent to a grouping of standard HTML [“checkbox” input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox) elements. The Action api should return `options` as detailed below. The user should be able to select multiple of the provided checkbox options.
- `radio` - equivalent to a grouping of standard HTML [“radio” input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio) elements. The Action api should return `options` as detailed below. The user should be able to select only one of the provided radio options.
- Other HTML input types not specified above (`hidden`, `button`, `submit`, `file`, etc) are not supported at this time.

In addition to the elements resembling HTML input types above, the following user input elements are also supported:

- `textarea` - equivalent of HTML [textarea element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea). Allowing the user provide multi-line input.
- `select` - equivalent of HTML [select element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select), allowing the user to experience a “dropdown” style field. The Action api should return `options` as detailed below.

When `type` is set as `select`, `checkbox`, or `radio` then the Action api should include an array of `options` that each provide a `label` and `value` at a minimum. Each option may also have a `selected` value to inform the blink-client which of the options should be selected by default for the user (see `checkbox` and `radio` for differences).

```tsx
 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
  }>;
}

```

If no `type` is set or an unknown/unsupported value is set, blink clients should default to `text` and render a simple text input (just as they do now).

The Action API is still responsible to validate and sanitize all data from the user input parameters, enforcing any “required” user input as necessary.

For platforms other that HTML/web based ones (like native mobile), the equivalent native user input component should be used to achieve the equivalent experience and client side validation as the HTML/web input types described above.

Note: As with the current spec, if a `LinkedAction` does not declare the `parameters` attribute, then no user input is requested by the Action api and blink clients should continue to render a single button that performs the POST request to the `href` endpoint. This proposal does not change that.

## Closing Notes

With the support of more input types, developers will be able to build more complex blinks and accept more user input. Having “too many” user input fields could result in a reduced user experience and also make users less likely to actually enter all the requested inputs.

To avoid UI bloat and degrading user experiences, blink-clients are likely to impose “soft limits” on the number of input fields they display. While this Actions/blink specification avoids taking an opinionated approach on the UI layer of blinks, the following is a reasonable guideline (and used by Dialect’s blinks SDK today):

- 10 buttons + 3 inputs (if separate Actions)
- 10 inputs (if it’s a form, and other actions are not rendered if there is a form in the response)

As such, Action API developers should limit the number of input `parameters` they request as blink-clients may limit how many input fields get shown to users. Developers should also keep in mind that if a user does not see all input fields (because the blink-client soft limits them as described above), then the user will have no way to enter a value. Therefore if all these fields are required by the Actions API, the user will NOT be able to actually execute your Action and get a transaction.

---

<div class="post-metadata">

**Author:** ![0xaryan](https://yyz2.discourse-cdn.com/flex030/user_avatar/forum.solana.com/0xaryan/32/1078_2.png) [@0xaryan](https://forum.solana.com/u/0xaryan)\
**Post date:** [July 16, 2024, 8:50am UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804/2 "2024-07-16T08:50:13Z")

</div>

For the user input, instead of having different types for `text` , `email` , `url`, `number` , a general tag `regexp` can be used, which would provide more flexibility.

The `ActionParamaterType` can then be modified to

```auto
/**
 * Input type to present to the user 
 * @default `regexp`
 */

export type ActionParameterType =
  | "regexp"
  | "date"
  | "datetime-local"
  | "checkbox"
  | "radio"
  | "textarea"
  | "select";

```

The following regex pattern can be used for the `text`, `email`, `url` , `number`

1. `text` - `.*`
2. `email` - `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}`
3. `url` - `^(https?|ftp):\/\/[^\s/$.?#].[^\s]*`
4. `number` - `^-?\d+(\.\d+)?`

any other `regex` can be used for more specific input types.

If `ActionParamterType` is set to `regexp` then the input field will be like

```auto
<input type="text" id="emailInput" name="emailInput" pattern="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$" required>

```

With the support of `regexp`, the input field provides a more flexible approach.

---

<div class="post-metadata">

**Author:** ![nickfrosty](https://yyz2.discourse-cdn.com/flex030/user_avatar/forum.solana.com/nickfrosty/32/106_2.png) [@nickfrosty](https://forum.solana.com/u/nickfrosty)\
**Post date:** [July 16, 2024, 12:50pm UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804/3 "2024-07-16T12:50:31Z")

</div>

Having a regex option makes a lot of sense, but could be really annoying for people out of the box that just want the benefit of simple input types like `email` or `url`.

We could support both though! Adding an additional `type=regexp` and accepting an additional `regexp` value in the `ActionParameter` type. This way people get the best of both worlds

Edit:  
@0xaryan we could also simplify even more by adding the `regexp` attribute to the `ActionParameter` so it could be applied to any user input type, no matter the type.

The benefit of using the natively support input types (like email, url, etc) is that browsers and native clients will give the better UX and help enforce that input type in a native way (like if `email` is set and you try to enter a non email, the browser will not let you submit the form). Vice if you only use a regex, then the blink client would be the only layer of client side validation there, allowing users to still submit

---

<div class="post-metadata">

**Author:** ![nickfrosty](https://yyz2.discourse-cdn.com/flex030/user_avatar/forum.solana.com/nickfrosty/32/106_2.png) [@nickfrosty](https://forum.solana.com/u/nickfrosty)\
**Post date:** [July 17, 2024, 4:35pm UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804/4 "2024-07-17T16:35:20Z")

</div>

This is my official update to the proposal above, specifically point (2)  
PS: For some reason I could not actually update the original post

* * *

1. Update the `ActionParameter` to support declaring different types of user input and allow providing regular expression patterns for more complicated input.

The updated `ActionParameter` should be updated as follows:

```tsx
/**
 * 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;
}

```

The `pattern` should be a string equivalent of a valid regular expression. This regular expression pattern should by used by blink-clients to validate user input before before making the POST request. If the `pattern` is not a valid regular expression, it should be ignored by clients.

The `patternDescription` is a human readable message that describes the regular expression `pattern`. If `pattern` is provided, the `patternDescription` is required to be provided.

If the user input value is not considered valid per the `pattern`, the user should receive a client side error message indicating the input field is not valid and displayed the `patternDescription` string.

(the remaining contents of section (2) remains the same)

---

<div class="post-metadata">

**Author:** ![0xaryan](https://yyz2.discourse-cdn.com/flex030/user_avatar/forum.solana.com/0xaryan/32/1078_2.png) [@0xaryan](https://forum.solana.com/u/0xaryan)\
**Post date:** [July 18, 2024, 7:12am UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804/5 "2024-07-18T07:12:57Z")

</div>

Having the input types coupled with regexp makes more sense, and I strongly agree on making a better UX for the user.

The `pattern` and `patternDescription` will create a good UX and also offer more design space to the developer.

---

<div class="post-metadata">

**Author:** ![nickfrosty](https://yyz2.discourse-cdn.com/flex030/user_avatar/forum.solana.com/nickfrosty/32/106_2.png) [@nickfrosty](https://forum.solana.com/u/nickfrosty)\
**Post date:** [July 19, 2024, 6:05pm UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804/6 "2024-07-19T18:05:29Z")

</div>

PR has been opened on the Actions spec repo:

> <https://github.com/solana-developers/solana-actions/pull/13>
>
> \## TLDR
> 
> Add new input types within blink clients to improve the user experien…ce and unlock new use cases for Action builders.
> 
> \## Rationale
> 
> The current Solana Actions and blinks specification only supports a single, generic input type of a non-structured text box. While this basic input is useful, having more explicit and declarative input types would allow Action builders and blink clients to unlock new use cases and improve the user experience of using blinks across the internet.
> 
> \## SRFC
> 
> See SRFC #29 - https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804
> 
> 
> The \`next\` tag has been published with this PR at version \`2.1.0-beta\`
> 
> \`\`\`
> npm install @solana/actions-spec@2.1.0-beta
> \`\`\`

---

<div class="post-metadata">

**Author:** ![fsher](https://avatars.discourse-cdn.com/v4/letter/f/b2d939/32.png) [@fsher](https://forum.solana.com/u/fsher)\
**Post date:** [July 23, 2024, 2:30pm UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804/7 "2024-07-23T14:30:42Z")

</div>

Given current support of passing arguments is limited to url encoded query parameters (through string templates) and there is still a possibility to pass them as such, I think it’s worth specifying how are they passed for multiple option types (`checkbox`). I propose for types that are considered multi-option (`checkbox`, or maybe `select` with `multiple` in the future) to be inserted as a single comma-separated string.

Example:  
`href: "/?test={test}"` , where `test` is a parameter type `checkbox` with options (just values for simplicity): `1, 2, 3, 4` . If user selects `1, 4` , then the request will be made with `?test=1,4` (url encoded)

POST body would return actions with multiple values as arrays of strings.

---

<div class="post-metadata">

**Author:** ![fsher](https://avatars.discourse-cdn.com/v4/letter/f/b2d939/32.png) [@fsher](https://forum.solana.com/u/fsher)\
**Post date:** [July 23, 2024, 3:33pm UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804/8 "2024-07-23T15:33:23Z")

</div>

Also several other suggestions:

**POST request parameters**  
Since the Actions spec may change in the future with proposals to add additional fields to POST request body, I think it’s worth moving parameter values to a separate object inside POST request body. This would avoid potential conflicts with incoming parameter action names.

POST request body type can look something like this:

```auto
{
  account: string;
  /** 
    Map of parameter values from user's interaction
    key - parameter name
    value - input value (by default `string`, if multi-option, `Array<string>`
  */
  data?: Record<string, string | Array<string>>;
}

```

**Min/Max options**  
Most of the parameter types can support `min` and `max` natively in some way or another. Adding them would strongly help developers achieve better UX with forms or single actions.

Expected behavior:  
`text, url, email, textarea`

- `min` and `max` represent the minimum and maximum string length required. (should follow `minlength` and `maxlength` HTML attributes)

`date, datetime-local`

- `min` and `max` represent the borders for date selection (should follow `min` and `max` HTML attributes)

`number`

- `min` and `max` represent the minimum and maximum for the numerical value (see `date, datetime-local` links)

`checkbox`

- `min` and `max` represent the amount of checked boxes that user can select

`select, radio`

- not applicable

If `select` will support multiple options, then it would follow the same rules as `checkbox`.

**Pattern & Pattern Description**  
`pattern` can be provided to all parameter types (except `select, radio, checkbox, date, datetime-local`).  
If `pattern` present, `type` is not empty and not equal to `text`, then `type` would become a more stylistic property (for blink clients to render the input styled for the `type`) and use `pattern` to validate the entered value.

`patternDescription` is definitely important for cases when `pattern` is specified, but also can be valuable for other parameter types for better explanation to the user. Which is why I’d like to suggest renaming to just `description` or more specific `settingsDescription` or `validationDescription`.

Would love some feedback around these points.

---

<div class="post-metadata">

**Author:** ![nickfrosty](https://yyz2.discourse-cdn.com/flex030/user_avatar/forum.solana.com/nickfrosty/32/106_2.png) [@nickfrosty](https://forum.solana.com/u/nickfrosty)\
**Post date:** [July 23, 2024, 4:43pm UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804/9 "2024-07-23T16:43:06Z")

</div>

This is a good callout @fsher, thanks for bringing it up. In my head I was assuming that a multi select option like `checkbox` would function the same as a traditional HTML form, but this could become inconsistent easily. Especially when considering non-web based platforms.

So I agree with making it more explicit in the spec, and your proposal looks good to me.

My one thought on it is that if the comma separated value is sent in a url query param: should we specify anything about the value being uri encoded, but not the commas?  
Depending on the value that the Action API declares in the option, it could have spaces or special characters which would be required to uri encode/decode. And I think having the comma uri encoded might potentially having issues when parsing it server side?

In my head, ideally people would not use a query param for checkboxes and instead have it sent in the body, but you never know what a dev might do lol

---

<div class="post-metadata">

**Author:** ![nickfrosty](https://yyz2.discourse-cdn.com/flex030/user_avatar/forum.solana.com/nickfrosty/32/106_2.png) [@nickfrosty](https://forum.solana.com/u/nickfrosty)\
**Post date:** [July 23, 2024, 4:54pm UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804/10 "2024-07-23T16:54:56Z")

</div>

> **POST request parameters**  
> Love this. it helps keep things more clean. You have my vote!  
> Do you think it is worth it in the spec types to allow developers to specify the keys for the `data` fields? This could improve DX if they decide to use it.

Something like this:

```auto
/**
 * Response body payload sent via the Action POST Request
 */
export interface ActionPostRequest<T = string> {
  /** base58-encoded public key of an account that may sign the transaction */
  account: string;
  /** 
    Map of parameter values from user's interaction
    key - parameter name
    value - input value (by default `string`, if multi-option, `Array<string>`
  */
  data?: Record<keyof T, string | Array<string>>;
}

```

> **Min/Max options**

Adding min/max options make sense as it can provide a better UX on the client side and is an easy add too. Using them with checkboxes is an interesting idea too, I don’t think I have ever seen that in the wild anywhere, but it could be useful for people.

> **Pattern & Pattern Description**

Your clarification on `pattern` not actually applying to `select, radio, checkbox, date, datetime-local` is fair. I had the assumption of exactly this when writing it up, but we can make it more explicit in the spec details. Especially to help craft better types in the `@solana/actions-spec` package.

For the description, are you suggesting that this could simply be displayed to the user for any parameter field that’s declared regardless of if a regex `pattern` is being used?

- If so, I’m game. I think it helps developers provide a better UX
- If not, can you clarify?

---

<div class="post-metadata">

**Author:** ![fsher](https://avatars.discourse-cdn.com/v4/letter/f/b2d939/32.png) [@fsher](https://forum.solana.com/u/fsher)\
**Post date:** [July 23, 2024, 6:28pm UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804/11 "2024-07-23T18:28:18Z")

</div>

> My one thought on it is that if the comma separated value is sent in a url query param: should we specify anything about the value being uri encoded, but not the commas?

I believe since it’s in query params, the whole string should be encoded, including the commas. Servers should parse that into a regular string, or potentially just decode with `decodeURIComponent` (or similar in other languages). But I definitely agree, this is something that can be hard to debug. At the same time, since the spec now prefers sending values inside POST body, it could be ok (just a limitation that can be documented).

What do you think?

---

<div class="post-metadata">

**Author:** ![fsher](https://avatars.discourse-cdn.com/v4/letter/f/b2d939/32.png) [@fsher](https://forum.solana.com/u/fsher)\
**Post date:** [July 23, 2024, 6:42pm UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804/12 "2024-07-23T18:42:38Z")

</div>

> Do you think it is worth it in the spec types to allow developers to specify the keys for the `data` fields? This could improve DX if they decide to use it.

Yes, love it! Better typing, better DX!

> Adding min/max options make sense as it can provide a better UX on the client side and is an easy add too. Using them with checkboxes is an interesting idea too, I don’t think I have ever seen that in the wild anywhere, but it could be useful for people.

Yep, it’s just an option that can be implemented. E.g. devs can be doing questioners or group together checkboxes to make them all required (like have 2 checkboxes and `min` to be 2). Again, just wild guesses, I’m sure people will think of something!

> For the description, are you suggesting that this could simply be displayed to the user for any parameter field that’s declared regardless of if a regex `pattern` is being used?

The first one, yes. Sorry, should’ve made myself clearer :D. A description for the field to explain what’s expected in the input and potentially an explanation why the validation fails.

again, wild (and not the best) example:  
`type: "url", max: 20, description: "Please provide a shortened link (e.g. bit.ly)"`

`description` can initially show as a label, but if user somehow entered more that 20 symbols (assuming it’s possible), that description could become an error indicator inside the client.

---

<div class="post-metadata">

**Author:** ![nickfrosty](https://yyz2.discourse-cdn.com/flex030/user_avatar/forum.solana.com/nickfrosty/32/106_2.png) [@nickfrosty](https://forum.solana.com/u/nickfrosty)\
**Post date:** [July 23, 2024, 7:22pm UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804/13 "2024-07-23T19:22:17Z")

</div>

Understood! I like it all 🙂

> the whole string should be encoded, including the commas.

I think this might cause issue with complicated values, but I think it is fine just being a limitation because the POST body.  
I’m okay with the simple blanket statement to the effect of “uri encode the comma separated list, but we recommend using the query param for it”

---

<div class="post-metadata">

**Author:** ![fsher](https://avatars.discourse-cdn.com/v4/letter/f/b2d939/32.png) [@fsher](https://forum.solana.com/u/fsher)\
**Post date:** [July 24, 2024, 8:52am UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804/14 "2024-07-24T08:52:09Z")

</div>

Just to be clear, POST body should receive an array of strings. If parameter used in query params, then it should become a comma-separated uri-encoded string.

---

<div class="post-metadata">

**Author:** ![Gabynto](https://yyz2.discourse-cdn.com/flex030/user_avatar/forum.solana.com/gabynto/32/494_2.png) [@Gabynto](https://forum.solana.com/u/Gabynto)\
**Post date:** [July 24, 2024, 9:15am UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804/15 "2024-07-24T09:15:42Z")

</div>

Sure! It sounds like adding more input types to blinks will really enhance what developers can do with them. Keeping the user experience in mind by limiting the number of input fields makes a lot of sense too.

---

<div class="post-metadata">

**Author:** ![nickfrosty](https://yyz2.discourse-cdn.com/flex030/user_avatar/forum.solana.com/nickfrosty/32/106_2.png) [@nickfrosty](https://forum.solana.com/u/nickfrosty)\
**Post date:** [July 24, 2024, 1:06pm UTC](https://forum.solana.com/t/srfc-29-input-types-of-blinks-and-actions/1804/16 "2024-07-24T13:06:08Z")

</div>

Yup, we are on the same page
