sRFC 31: Compatibility of Blinks and Actions

sRFC 31: Compatibility of Blinks and Actions

Context & Problem

Actions Spec Version Compatibility

Different Blink clients, such as wallets, update at different rates. This means they might not support the latest features, which can lead to situations where Blink is rendered incorrectly, with elements not being visible or displayed correctly, or being completely non-functional.

Blockchain Compatibility

Currently, the action doesn’t specify which chain to target, other than the recent blockhash being invalid on another Solana network. Also, the community has started building actions for non-Solana chains following the spec. As actions are built for various chains, there is a risk of consuming and unfurling incompatible actions, which can break client functionality.

Proposed Solution

Proposing to include compatibility metadata across Action API responses, specifically

  • The version of the spec being used.
  • The chains it supports.

This approach allows Blink clients to decide whether to unfurl the action based on the data provided by the server. The benefits of the approach are

  • Minimizes breaking changes, including CORS configuration for existing action providers.
  • Ensures low friction for end action developers by reducing the code required to maintain consistent and expected behaviour across different versions of clients.

To ensure smooth operation, Blink clients should follow the best-practices below:

  • If the action version is higher than the action spec version used in the client, clients should render a fallback UI indicating that version is incompatible and suggesting to update if possible. This practice encourages wallets to adopt newer spec versions and users to upgrade their clients.
  • If the client doesn’t support the blockchain, the action should not be unfurled.

Implementation Proposal

Technically the proposal is to introduce compatibility metadata in the Actions API response headers. Headers are suitable for passing such metadata for several reasons:

  • Consistency: Uniform application across all types of requests, including GET requests where bodies are not applicable.
  • Clarity: Keeps versioning metadata separate from request data, maintaining a clean separation of concerns.
  • Efficiency: Headers facilitate making HEAD requests to check compatibility before fetching the entire action, improving performance.

In order to ensure consistent encoding and identification of blockchain networks, the proposal is to utilize chain-agnostic standards that are gaining traction in the industry, specifically CAIPs.

So, two response headers are proposed to be returned by action developers:

  • X-Action-Version to show what spec version the action API server is using. For example, X-Action-Version: 2.1.3.
  • X-Blockchain-Ids to list blockchains the action supports, using CAIP-2 compatible strings. For example, X-Blockchain-Ids: solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp for Solana mainnet or X-Blockchain-Ids: solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1 for Solana devnet. See Solana Namespace - Addresses | Chain Agnostic Namespaces for more details.

For backward compatibility, Blink clients should treat:

  • The absence of the X-Action-Version header as the last pre-compatibility release.
  • The absence of the X-Blockchain-Ids header as a Solana mainnet action.

Note: Wallets cannot get custom response headers from browser requests by default. The Action Provider needs to add Access-Control-Expose-Headers: X-Blockchain-Ids, X-Action-Version to the response to make metadata available to scripts running in the browser.

Out of Scope & Future Work

Introducing compatibility metadata in Blink client requests:

  • Request Header: X-Accept-Action-Version to show the max spec version the Blink client supports.
  • Request Header: X-Accept-Blockchain-Ids to list blockchains the client supports, using CAIP-2 compatible strings.

This will allow for accurate handling when necessary by relying on client request headers and having extra logic to handle different client versions. While it is possible that action developers might not accurately handle the version provided by the client initially, it could be useful to have this data.

Proposing to include this change in separate sRFC to maintain backward compatibility, as current APIs would break unless existing servers update CORS settings to allow 2 extra CORS headers Access-Control-Allow-Headers: X-Accept-Action-Version, X-Accept-Blockchain-Ids.

2 Likes

Having clear guidelines and best practices around Actions and blinks is super important. Especially as blink clients, like wallets, ship update on different timelines (just like you called out).

With a versioning system like you describe (both the blink client and action server stating which they support), we can ensure the best possible user experience. I am very much for this update! Especially by using standardized headers sent by BOTH blink clients and action API servers.

  • If the action version is higher than the action spec version used in the client, clients should render a fallback UI indicating that version is incompatible and suggesting to update if possible. This practice encourages wallets to adopt newer spec versions and users to upgrade their clients.

I think for some future features in the spec, their maybe be a reasonable fallback option to give to users instead of simply rendering a fallback UI stating its incompatible. In some cases, sure this will not be possible. But for many types of updates, I suspect having some reasonable fallback functionality should be expected on the client side.

How would a multi-blockchain action declare the chains it supports? Should the X-Blockchain-Ids be a comma separated list? Or something else?

To help with adoption of these headers, I can add helper functions, constants, and types into the @solana/actions sdk and the @solana/actions-spec package

2 Likes

Thanks for feedback!

I agree that ideally, both the client and server should state what versions and chains they support and this is how I see this generally.

However, I have mixed feelings about the implementation sequencing. Adding compatibility metadata in request headers from the Blink Client will break existing action providers due to incompatible CORS configurations. On the other hand, adding compatibility metadata to Action API response headers is safe and backward compatible.

Therefore, I would propose starting with adding compatibility metadata to Action API response headers, but postponing the implementation of Blink client headers.

What are your thoughts on this concern?

Agreed here

Realistically, I think it will be a single blockchain id in most cases for the nearest future. However, it’s comma separated list for extensibility, several examples of what could be possible in the future

  • Define actions that support both devnet and mainnet:
    X-Blockchain-Ids: solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp, solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1
  • Support multiple blockchains in single action (e.g. donation blink that supports both Solana and some other chain)
    X-Blockchain-Ids: solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp, eip155:1

That said, if we want full multi-chain experience, I think we will need extra sRFC that will specify several extra aspects of operating in such environment.

This would be awesome! Def will simplify adoption

4 Likes

Introducing compatibility metadata in the Action API responses sounds like a smart move to handle version mismatches and blockchain support issues more effectively. It’ll help Blink clients avoid breaking changes and improve overall compatibility with diverse blockchain actions.

2 Likes

I think your plans makes the most sense. Straightforward to accomplish.

Also makes sense, future sRFC it is.

3 Likes