Action'lar ve Blinkler

Solana Actions, Solana blok zincirindeki işlemlerin önizlenmesini, imzalanmasını ve QR kodları, düğmeler + widget'lar ve internet üzerindeki web siteleri de dahil olmak üzere çeşitli bağlamlarda gönderilmesini sağlayan spesifikasyon uyumlu API'lerdir. Action'lar, geliştiricilerin Solana ekosisteminde yapabileceğiniz şeyleri doğrudan ortamınıza entegre etmelerini kolaylaştırarak farklı bir uygulamaya veya web sayfasına gitmenize gerek kalmadan blok zinciri işlemlerini gerçekleştirmenize olanak tanır.

Blok zinciri bağlantıları - ya da blinkler - herhangi bir Solana Action'ı paylaşılabilir, meta veri açısından zengin bir bağlantıya dönüştürür. Blinkler, Action'a duyarlı kullanıcı uygulamalarının (tarayıcı uzantısı cüzdanları, botlar) kullanıcı için ek özellikler görüntülemesine olanak tanır. Bir web sitesinde, bir blink, merkezsizleştirilmiş bir uygulamaya gitmeden bir cüzdanda bir işlem önizlemesini hemen tetikleyebilir; Discord'da bir bot, blink'i etkileşimli bir düğme kümesine genişletebilir. Bu, zincirin üzerinde etkileşim kurma becerisini bir URL görüntüleyebilen herhangi bir ağ yüzeyine taşır.

Get Started #

To quickly get started with creating custom Solana Actions:

npm install @solana/actions
  • install the Solana Actions SDK in your application
  • build an API endpoint for the GET request that returns the metadata about your Action
  • create an API endpoint that accepts the POST request and returns the signable transaction for the user
Info

Checkout this video tutorial on how to build a Solana Action using the @solana/actions SDK.

You can also find the source code for an Action that performs a native SOL transfer here and several other example Actions in this repo.

When deploying your custom Solana Actions to production:

If you are looking for inspiration around building Actions and blinks, checkout the Awesome Blinks repository for some community creations and even ideas for new ones.

Actions #

Solana Actions spesifikasyonu, imzalanabilir işlemleri (ve nihayetinde imzalanabilir mesajları) bir uygulamadan doğrudan bir kullanıcıya sunmak için bir dizi standart API kullanır. Herkese açık URL'lerde barındırılırlar ve bu nedenle herhangi bir kullanıcının etkileşime girmesi için URL'leri ile erişilebilirler.

Info

Actions'ı, meta verileri ve kullanıcının blockchain cüzdanı ile imzalayabileceği bir şeyi (bir işlem ya da kimlik doğrulama mesajı) döndüren bir API olarak düşünebilirsiniz.

Actions API, bir Action'ın URL uç noktasına basit GET ve POST istekleri yapmak ve Actions arayüzüne uygun yanıtları işlemekten oluşur.

  1. GET isteği, kullanıcılara bu URL'de hangi eylemlerin mevcut olduğu hakkında okunabilir bilgiler sağlayan meta verileri ve ilgili Actions'ların isteğe bağlı bir listesini döndürür.
  2. 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 Yürütme ve Yaşam Döngüsü #

Pratikte, Action'lar ile etkileşim tipik bir REST API ile etkileşime çok benzer:

  • Bir kullanıcı, mevcut Action'lar hakkındaki meta verileri almak için bir Action URL'sine ilk GET isteğini yapar
  • Rest API uç noktası, uç nokta hakkındaki meta verileri (uygulamanın başlığı ve simgesi gibi) ve bu uç nokta için kullanılabilir eylemlerin bir listesini içeren bir yanıt döndürür
  • Kullanıcı uygulaması (mobil cüzdan, sohbet botu veya web sitesi gibi) kullanıcının eylemlerden birini gerçekleştirmesi için bir kullanıcı arayüzü görüntüler
  • Kullanıcı, bir eylem seçtikten sonra (bir düğmeye tıklayarak) uygulama, kullanıcının imzalayacağı işlemi almak için uç noktaya bir POST isteği yapar
  • Cüzdan, kullanıcının işlemi imzalamasını kolaylaştırır ve nihayetinde işlemi onay için blok zincirine gönderir

Solana Actions Execution and LifecycleSolana Actions Execution and Lifecycle

Bir Actions URL'sinden işlem alırken, kullanici uygulamalari bu işlemlerin blok zincirine gönderilmesini sağlamalı ve durum yaşam döngülerini yönetmelidir.

Actions ayrıca yürütmeden önce bir miktar iptal işlemini de destekler. GET ve POST isteği, action'ın gerçekleştirilip gerçekleştirilemeyeceğini belirten bazı meta veriler döndürebilir (disabled alanında olduğu gibi).

Örneğin, oylama penceresi kapanmış olan bir DAO teklifinin oylanmasını kolaylaştıran bir Action uç noktası varsa, ilk GET isteği "Bu teklif artık oylamaya açık değil" hata mesajını ve "Evet Oyu Ver" ve "Hayır Oyu Ver" düğmelerini "devre dışı" olarak döndürebilir.

Blinkler (blok zinciri bağlantıları), Action API'lerini gözlemleyen ve Action'larla etkileşim kurmak ve bunları yürütmek için kullanıcı arayüzleri oluşturan kullanıcı uygulamalarıdır.

Blinkleri destekleyen kullanıcı uygulamaları basitçe Action uyumlu URL'leri tespit eder, bunları ayrıştırır ve kullanıcıların standartlaştırılmış kullanıcı arayüzlerinde bunlarla etkileşime girmesine olanak tanır.

Info

Bir Action API'sine tam bir arayüz oluşturmak için tamamen gözlem yapan herhangi bir kullanıcı uygulaması bir blink'tir. Bu nedenle, Actions API'lerini kullanan tüm kullanıcı uygulamaları blink değildir.

Bir blink URL'si, kullanıcının cüzdanıyla imzalama da dahil olmak üzere bir Action'ı yürütmenin tüm yaşam döngüsünü tamamlamasını sağlayan bir kullanıcı uygulamasını tanımlar.

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

Herhangi bir kullanıcı uygulamasının blink olabilmesi için:

  • Blink URL'si, değeri URL kodlu bir Action URL'si olan bir Action sorgu parametresi içermelidir. Bu değer, diğer protokol parametreleriyle çakışmaması için URL kodlu olmalıdır.

  • Kullanıcı uygulaması, Action sorgu parametresinin URL kodunu çözmeli ve sağlanan Action API bağlantısını incelemelidir (bkz. Action URL şeması).

  • Kullanıcı uygulaması, kullanıcının cüzdanı ile imzalama da dahil olmak üzere bir Actions yürütmenin tüm yaşam döngüsünü tamamlamasını sağlayan zengin bir kullanıcı arayüzü oluşturmalıdır.

Info

Tüm blink kullanıcı uygulamaları (ör. web siteleri veya dApp'ler) tüm Action'ları desteklemeyecektir. Uygulama geliştiricileri, blink arayüzlerinde hangi Action'ları desteklemek istediklerini seçebilirler.

Aşağıdaki örnek, URL kodlu solana-action:https://actions.alice.com/donate action değerine sahip geçerli bir blink URL'sini göstermektedir:

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

Actions'ları Blink'ler ile Algılama #

Blinkler, Actions'lar ile en az 3 şekilde bağlanabilir:

  1. Açık bir Action URL'si paylaşma: solana-action:https://actions.alice.com/donate

    Bu durumda, yalnızca desteklenen uygulamalar blink oluşturabilir. Yedek bağlantı önizlemesi veya desteklenmeyen uygulama dışında ziyaret edilebilecek bir site olmayacaktır.

  2. Web sitesinin alan adı kök dizinindeki actions.json dosyası aracılığıyla bir Actions API'ye bağlı bir web sitesine bağlantı paylaşma.

    Örneğin, https://alice.com/actions.json, kullanıcıların Alice'e bağış yapabileceği bir web sitesi URL'si olan https://alice.com/donate'i, Alice'e bağış yapmak için Action'ların barındırıldığı API URL'si https://actions.alice.com/donate ile eşleştirir.

  3. Bir Action URL'sini, Action'ların nasıl ayrıştırılacağını anlayan bir " ara geçiş" site URL'sine gömmek.

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

Blinkleri destekleyen uygulamalar, yukarıdaki formatlardan herhangi birini alabilmeli ve Action'ın doğrudan kullanıcı uygulamasının yürütülmesini kolaylaştırmak için doğru bir arayüz oluşturabilmelidir.

Blinkleri desteklemeyen kullanıcı uygulamaları için altyapı sağlayan web sitesi olmalıdır (tarayıcıyı evrensel yedek haline getirir).

Bir kullanıcı, kullanıcı uygulaması üzerinde aksiyon düğmesi veya metin giriş alanı olmayan herhangi bir yere dokunursa, temel siteye yönlendirilmelidir.

Solana Actions ve blinks izne tabi olmayan bir protokol/spesifikasyon olsa da, istemci uygulamaları ve cüzdanların, kullanıcıların işlemi imzalamasını nihai olarak kolaylaştırması gerekmektedir.

Info

Use the Blinks Inspector tool to inspect, debug, and test your blinks and actions directly in your browser. You can view the GET and POST response payloads, response headers, and test all inputs to each of your linked Actions.

Each client application or wallets may have different requirements on which Action endpoints their clients will automatically unfurl and immediately display to their users on social media platforms.

Örneğin, bazı kullanıcı uygulamaları, Dialect'in Actions Registry'si (aşağıda ayrıntılı olarak açıklanmıştır) gibi kullanıcılar için bir Action'ı açmadan önce doğrulama gerektirebilecek bir "izin listesi" yaklaşımıyla çalışabilir.

Tüm blinkler, Dialect'in dial.to blinks Interstitial sitesinde imzalanmaya devam edecek ve kayıt durumları blinkte görüntülenecektir.

Diyalekt'in Actions Registery'si #

Solana ekosistemi için bir ortak fayda olarak [Dialect] (https://dialect.to), Solana Foundation ve diğer topluluk üyelerinin yardımıyla, bilinen kaynaklardan önceden doğrulanmış blok zinciri bağlantılarının kamuya açık bir kaydını tutar. Başlangıçtan itibaren, yalnızca Dialect registery kaydedilen Eylemler yayınlandığında Twitter akışında açılacaktır.

Kullanıcı uygulamaları ve cüzdanlar, kullanıcı güvenliğini ve emniyetini sağlamaya yardımcı olmak için bu genel kayıt defterini veya başka bir çözümü kullanmayı özgürce seçebilir. Dialect kayıt defteri aracılığıyla doğrulanmazsa, blok zinciri bağlantısına blink istemcisi tarafından dokunulmayacak ve tipik bir URL olarak işlenecektir.

Geliştiriciler Dialect tarafından doğrulanmak için buradan başvurabilirler: dial.to/register

Teknik Özellikler #

Solana Actions spesifikasyonu, bir istek/yanıt etkileşim akışının parçası olan temel bölümlerden oluşur:

  • Bir Action URL'si sağlayan Solana Action URL şeması
  • CORS gereksinimlerini geçmek için bir Eylem URL'sine OPTIONS yanıtı.
  • Bir Action URL'sine GET isteği
  • Sunucudan gelen GET yanıtı
  • Action URL'sine POST isteği
  • Sunucudan POST yanıtı

Bu taleplerin her biri, zengin kullanıcı arayüzleri için belirli meta verileri toplamak ve Actions API'ye kullanıcı girişini kolaylaştırmak amacıyla Action uygulaması (örn. cüzdan uygulaması, tarayıcı uzantısı, dApp, web sitesi vb.) tarafından yapılır.

Yanıtların her biri bir uygulama (ör. web sitesi, sunucu arka ucu, vb.) tarafından hazırlanır ve Action kullanıcı uygulamasına geri gönderilir. Nihayetinde, kullanıcıdan onaylamasını, imzalamasını ve blok zincirine göndermesini istemek için bir cüzdan için imzalanabilir bir işlem veya mesaj sağlar.

Info

The types and interfaces declared within this readme files are often the simplified version of the types to aid in readability.

For better type safety and improved developer experience, the @solana/actions-spec package contains more complex type definitions. You can find the source code for them here.

URL Şeması #

Bir Solana Action URL'si, solana-action protokolünü kullanarak imzalanabilir bir Solana işlemi veya mesajı için etkileşimli bir isteği tanımlar.

İstek etkileşimlidir çünkü URL'deki parametreler bir uygulama tarafından, kullanıcının cüzdanıyla imzalaması için imzalanabilir bir işlem veya mesaj oluşturmak üzere bir dizi standartlaştırılmış HTTP isteği yapmak için kullanılır.

solana-action:<link>
  • Yol adı olarak tek bir bağlantı alanı gereklidir. Yol adı, koşullu olarak URL kodlamalı mutlak HTTPS URL'si olmalıdır.

  • URL sorgu parametreleri içeriyorsa, URL kodlu olmalıdır. Değerin URL ile kodlanması, protokol belirtimi aracılığıyla eklenebilecek herhangi bir Actions protokol parametresiyle çakışmayı önler.

  • URL sorgu parametreleri içermiyorsa, URL kodlaması yapılmamalıdır. Bu, daha kısa bir URL ve daha az yoğun bir QR kodu üretir.

Her iki durumda da, kullanıcı uygulamaları URL kodunun değerini çözmelidir. Değer, URL kodlu değilse bunun bir etkisi yoktur. Kodu çözülen değer mutlak bir HTTPS URL'si değilse, cüzdan bunu hatalı biçimlendirilmiş olarak reddetmelidir.

OPTIONS Yanıtı #

Actions uygulamaları ("blink" dahil) içinde Çapraz Kaynak Paylaşımına (CORS) izin vermek için, tüm Action uç noktaları OPTIONS yöntemi için HTTP isteklerine, istemcilerin aynı kaynak etki alanından gelen sonraki tüm istekler için CORS kontrollerini geçmesine izin verecek geçerli başlıklarla yanıt vermelidir.

Bir Actions uygulaması, Action URL'sine yönelik sonraki GET isteğinin tüm CORS kontrollerini geçip geçmeyeceğini kontrol etmek için Action URL uç noktasına "[preflight](https://developer.mozilla.org/en US/docs/Web/HTTP/CORS#preflighted_requests)" istekleri gerçekleştirebilir. Bu CORS ön kontrolleri OPTIONS HTTP yöntemi kullanılarak yapılır ve Action uygulamasının (blinks gibi) kaynak etki alanlarından sonraki tüm istekleri düzgün bir şekilde yapmasına izin verecek tüm gerekli HTTP başlıklarıyla yanıt vermelidir.

En azından gerekli HTTP üstbilgileri şunları içerir:

  • * değerine sahip Access-Control-Allow-Origin
    • bu, tüm Action uygulamalarının gerekli tüm istekleri yapmak için CORS kontrollerini güvenli bir şekilde geçebilmesini sağlar
  • GET,POST,PUT,OPTIONSdeğerine sahipAccess-Control-Allow-Methods`
    • Actions için gerekli tüm HTTP istek yöntemlerinin desteklenmesini sağlar
  • Minimum değeri Access-Control-Allow-Headers olan Content-Type, Authorization, Content-Encoding, Accept-Encoding

Basitlik açısından, geliştiriciler OPTIONS isteklerine [GET yanıtı] (#get-response) ile aynı yanıtı ve üstbilgileri döndürmeyi düşünmelidir.

Cross-Origin headers for actions.json

The actions.json file response must also return valid Cross-Origin headers for GET and OPTIONS requests, specifically the Access-Control-Allow-Origin header value of *.

See actions.json below for more details.

GET İsteği #

Action istemcisi (ör. cüzdan, tarayıcı uzantısı vb.) Action URL uç noktasına bir HTTP GET JSON isteği yapmalıdır.

  • İstek, cüzdanı veya kullanıcıyı tanımlamamalıdır.
  • Kullanıcı uygulaması, isteği [Accept-Encoding] başlığı ile yapmalıdır.
  • Kullanıcı uygulaması, istek yapılırken URL'nin alan adını göstermelidir.

GET Yanıtı #

Action URL uç noktası (ör. uygulama veya sunucu arka ucu), HTTP OK JSON yanıtı (geçerli bir yük ile) veya uygun bir HTTP hatası ile yanıt vermelidir.

  • Kullanıcı uygulaması, HTTP kullanıcı uygulaması hataları, sunucu hataları ve yönlendirme yanıtları ile başa çıkmalıdır.

  • Uç nokta, HTTP sıkıştırması için [Content-Encoding] başlığı ile yanıt vermelidir.

  • Endpoint, application/json içerik türünde bir Content-Type başlığı ile yanıt vermelidir.

  • Kullanıcı uygulaması, HTTP önbelleğini kontrol eden yanıt başlıklarında belirtilen şekilde talimat verilmediği sürece yanıtı önbelleğe almamalıdır.

  • Kullanıcı uygulaması, "title"ı göstermeli ve kullanıcıya "icon" görüntüsünü sunmalıdır.

Error responses (i.e. HTTP 4xx and 5xx status codes) should return a JSON response body following ActionError to present a helpful error message to users. See Action Errors.

GET Yanıt Gövdesi #

HTTP OK JSON yanıtı içeren bir GET yanıtı bir gövde yükü içermelidir arayüz spesifikasyonunu şöyledir:

ActionGetResponse
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 - The type of action being given to the user. Defaults to action. The initial ActionGetResponse is required to have a type of action.

    • action - Standard action that will allow the user to interact with any of the LinkedActions
    • completed - Used to declare the "completed" state within action chaining.
  • icon - Değer, bir simge görüntüsünün mutlak HTTP veya HTTPS URL'si olmalıdır. Dosya bir SVG, PNG veya WebP görüntüsü olmalıdır veya kullanıcı uygulaması / cüzdan bunu hatalı biçimlendirilmiş olarak reddetmelidir.

  • title - Değer, action isteğinin kaynağını temsil eden bir UTF-8 dizesi olmalıdır. Örneğin, bu bir markanın, mağazanın, uygulamanın veya talebi yapan kişinin adı olabilir.

  • description - Değer, action hakkında bilgi sağlayan bir UTF-8 dizesi olmalıdır. Açıklama kullanıcıya gösterilmelidir.

  • label - Değer, kullanıcının tıklaması için bir düğme üzerinde oluşturulacak bir UTF-8 dizesi olmalıdır. Tüm etiketler 5 kelimelik ifadeleri geçmemeli ve kullanıcının yapmasını istediğiniz actioni'ı somutlaştırmak için bir fiil ile başlamalıdır. Örneğin, "Mint NFT", "Vote Yes" veya "Stake 1 SOL".

  • disabled - Değer, devre dışı durumunu temsil etmek için boolean olmalıdır. işlenmiş düğme (label dizesini görüntüler). Eğer herhangi bir değer belirtilmezse, disabled varsayılan olarak false (yani varsayılan olarak etkin) olmalıdır. Örneğin, action uç noktası yönetim oylamasının kapanması içinse, setdisabled=true ve label "Vote Closed" olabilir.

  • error - Önemli olmayan hatalar için isteğe bağlı bir hata göstergesi. Mevcutsa, kullanıcı uygulaması bunu kullanıcıya göstermelidir. 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 with disabled to display a reason like business constraints, authorization, the state, or an error of external resource.

  • links.actions - Uç nokta için ilgili action'ların isteğe bağlı bir dizisi. Kullanıcılara listelenen eylemlerin her biri için UI gösterilmeli ve yalnızca birini gerçekleştirmeleri beklenmelidir. Örneğin, bir yönetişim oylaması eylem uç noktası kullanıcı için üç seçenek döndürebilir: "Evet Oyu Ver", "Hayır Oyu Ver" ve "Oylamada Çekimser Kal".

    • Eğer links.actions belirtilmemişse, kullanıcı uygulaması label dizesini kullanarak tek bir düğme oluşturmalı ve POST isteğini ilk GET isteği ile aynı action URL uç noktasına yapmalıdır.

    • Herhangi bir links.actions' sağlanmışsa, kullanıcı uygulaması yalnızca links.actions' alanında listelenen öğelere göre butonları ve giriş alanlarını oluşturmalıdır. Kullanıcı uygulaması, kök label içeriği için bir buton oluşturmamalıdır.

LinkedAction
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>;
}

The ActionParameter allows declaring what input the Action API is requesting from the user:

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

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 description of the expected input requests from the user. If pattern is provided, the patternDescription is required to be provided.

The min and max values allows the input to set a lower and/or upper bounds of the input requested from the user (i.e. min/max number and or min/max character length), and should be used for client side validation. For input types of date or datetime-local, these values should be a string dates. For other string based input types, the values should be numbers representing their min/max character length.

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 type field allows the Action API to declare more specific user input fields, providing better client side validation and improving the user experience. In many cases, this type will resemble the standard HTML input element.

The ActionParameterType can be simplified to the following type:

ActionParameterType
/**
 * Input field 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 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 element
  • email - equivalent of HTML “email” input element
  • url - equivalent of HTML “url” input element
  • number - equivalent of HTML “number” input element
  • date - equivalent of HTML “date” input element
  • datetime-local - equivalent of HTML “datetime-local” input element
  • checkbox - equivalent to a grouping of standard HTML “checkbox” input 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 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 type equivalents 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. Allowing the user provide multi-line input.
  • select - equivalent of HTML select element, 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).

This ActionParameterSelectable can be simplified to the following type definition:

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

If no type is set or an unknown/unsupported value is set, blink-clients should default to text and render a simple text input.

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.

Örnek GET Yanıtı #

Aşağıdaki örnek yanıt, kullanıcıya "Erişim Token'ı Talep Et" etiketiyle tek bir düğme olarak sunulması beklenen tek bir "kök" eylemi sağlar.

{
  "title": "HackerHouse Etkinlikleri",
  "icon": "<url-to-image>",
  "description": "HackerHouse erişim token'larını talep edin.",
  "label": "Erişim Jetonunu Talep Et" // buton metni
}

Aşağıdaki örnek yanıt, kullanıcının bir DAO önerisi için oy vermek üzere 3 butondan birine tıklamasına olanak tanıyan 3 ilgili action bağlantısı sağlar:

{
  "title": "Realms DAO Platformu",
  "icon": "<url-to-image>",
  "description": "DAO yönetim önerisi #1234 için oy verinç",
  "label": "Oy Ver",
  "links": {
    "actions": [
      {
        "label": "Evet Oyu Ver", // buton metni
        "href": "/api/proposal/1234/vote?choice=yes"
      },
      {
        "label": "Hayır Oyu Ver", // buton metni
        "href": "/api/proposal/1234/vote?choice=no"
      },
      {
        "label": "Oy Kullanma", // buton metni
        "href": "/api/proposal/1234/vote?choice=abstain"
      }
    ]
  }
}

Parametrelerle birlikte örnek GET Yanıtı #

Aşağıdaki örnekler, kullanıcıdan metin girişi kabul etmenin (parametreler aracılığıyla) ve bu girişi nihai POST isteği uç noktasına (LinkedAction içindeki href alanı aracılığıyla) dahil etmenin nasıl yapıldığını göstermektedir:

Aşağıdaki örnek cevap, kullanıcıya SOL yatırma için 3 bağlantılı işlem sunar: "Stake 1 SOL" adlı bir buton, "Stake 5 SOL" adlı başka bir buton ve kullanıcının belirli bir "amount" değerini girmesine izin veren bir metin giriş alanı. Bu girilen "amount" değeri, Action API'sine gönderilecek:

```json
{
  "title": "Stake-o-matic",
  "icon": "<url-to-image>",
  "description": "Stake SOL to help secure the Solana network.",
  "label": "Stake SOL", // `links.actions` sağlandığı için görüntülenmez
  "links": {
    "actions": [
      {
        "label": "Stake 1 SOL", // buton metni
        "href": "/api/stake?amount=1"
        // `parameters` olmadığı için metin giriş alanı değil
      },
      {
        "label": "Stake 5 SOL", // buton metni
        "href": "/api/stake?amount=5"
        // `parameters` olmadığı için metin giriş alanı değil
      },
      {
        "label": "Amount to stake", // metin giriş yer tutucu metni
        "href": "/api/stake?amount={amount}",
        "parameters": [
          {
            "name": "amount", // alan adı
            "label": "SOL amount" // metin giriş yer tutucu
          }
        ]
      }
    ]
  }
}
```

Aşağıdaki örnek yanıt, kullanıcının girebileceği bir amount (miktar) giriş alanı sağlar ve bu miktar POST isteğiyle gönderilir (ya bir sorgu parametresi olarak ya da bir alt yol olarak kullanılabilir):

{
  "icon": "<url-to-image>",
  "label": "SOL Bağışı",
  "title": "İyi Nedenler Derneği'ne Bağış Yapın",
  "description": "Bu derneği SOL bağışı yaparak destekleyin.",
  "links": {
    "actions": [
      {
        "label": "Bağış Yap", // buton metni
        "href": "/api/donate/{amount}", // veya /api/donate?amount={amount}
        "parameters": [
          // {amount} giriş alanı
          {
            "name": "amount", // giriş alanı adı
            "label": "SOL miktarı" // metin girişi yer tutucusu
          }
        ]
      }
    ]
  }
}

POST İsteği #

Kullanıcı uygulaması, şu gövde yüküyle birlikte eylem URL'sine bir HTTP POST JSON isteği yapmalıdır:

{
  "account": "<account>"
}
  • account - Değer, işlemi imzalayabilecek bir hesabın base58 kodlu genel anahtarı olmalıdır.

Kullanıcı uygulaması, HTTP Sıkıştırması(Compression) için bir Accept-Encoding başlığı ile isteği yapmalıdır ve uygulama, HTTP sıkıştırması için bir Content-Encoding başlığı ile yanıt vermelidir.

İstek yapılırken kullanıcı uygulaması, Action URL'sinin alanını görüntülemelidir. Eğer bir GET isteği yapıldıysa, kullanıcı uygulaması ayrıca title'ı görüntülemeli ve bu GET yanıtından icon görüntüsünü oluşturmalıdır.

POST Yanıtı #

Action'ın POST uç noktası, geçerli bir yük içeren bir HTTP OK JSON yanıtı veya uygun bir HTTP hatasıyla yanıt vermelidir.

Error responses (i.e. HTTP 4xx and 5xx status codes) should return a JSON response body following ActionError to present a helpful error message to users. See Action Errors.

POST Yanıt Gövdesi #

Bir HTTP OK JSON yanıtı ile birlikte gönderilecek bir POST yanıtı için gövde yükü şöyle olmalıdır:

ActionPostResponse
/**
 * 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 - The value must be a base64-encoded serialized transaction. The client must base64-decode the transaction and deserialize it.

  • message - bu değer, yanıt içinde bulunan işlemin doğasını açıklayan UTF-8 biçiminde bir dize olmalıdır. Kullanıcı uygulaması, bu değeri kullanıcıya göstermelidir. Örneğin, bu satın alınan bir öğenin adı, bir satın alma işlemine uygulanan bir indirim veya bir teşekkür notu olabilir.

  • links.next - An optional value use to "chain" multiple Actions together in series. After the included transaction has been confirmed on-chain, the client can fetch and render the next action. See Action Chaining for more details.

  • Kullanıcı uygulaması ve uygulama, gelecekteki belirti güncellemeleri tarafından eklenebilecek istek gövdesi ve yanıt gövdesindeki ek alanları kabul etmelidir.

Info

Uygulama, kısmen veya tamamen imzalanmış bir işlemle yanıt verebilir. Kullanıcı uygulaması ve cüzdan, işlemi güvenilmeyen olarak doğrulamalıdır.

POST Yanıtı - İşlem #

If the transaction signatures are empty or the transaction has NOT been partially signed:

  • The client must ignore the feePayer in the transaction and set the feePayer to the account in the request.
  • The client must ignore the recentBlockhash in the transaction and set the recentBlockhash to the latest blockhash.
  • Kullanıcı uygulaması, işlemi imzalamadan önce seri hale getirip serileştirmelidir. Bu, bu sorun için bir geçici çözüm olarak hesap anahtarlarının tutarlı sıralanmasını sağlar.

İşlem kısmen imzalanmışsa:

  • The client must NOT alter the feePayer or recentBlockhash as this would invalidate any existing signatures.
  • Kullanıcı uygulaması, imzaları doğrulamalı ve geçersiz olan varsa işlemi hatalı biçimli olarak reddetmelidir.

Kullanıcı uygulaması, işlemi sadece istekteki account ile imzalamalı ve bunu sadece istekteki account için bir imza bekleniyorsa yapmalıdır.

Eğer istekteki account için olmayan bir imza bekleniyorsa, kullanıcı uygulaması işlemi kötü niyetli olarak reddetmelidir.

Action Errors #

Actions APIs should return errors using ActionError in order to present helpful error messages to the user. Depending on the context, this error could be fatal or non-fatal.

ActionError
export interface ActionError {
  /** simple error message to be displayed to the user */
  message: string;
}

When an Actions API responds with an HTTP error status code (i.e. 4xx and 5xx), the response body should be a JSON payload following ActionError. The error is considered fatal and the included message should be presented to the user.

For API responses that support the optional error attribute (like ActionGetResponse), the error is considered non-fatal and the included message should be presented to the user.

Action Chaining #

Solana Actions can be "chained" together in a successive series. After an Action's transaction is confirmed on-chain, the next action can be obtained and presented to the user.

Action chaining allows developers to build more complex and dynamic experiences within blinks, including:

  • providing multiple transactions (and eventually sign message) to a user
  • customized action metadata based on the user's wallet address
  • refreshing the blink metadata after a successful transaction
  • receive an API callback with the transaction signature for additional validation and logic on the Action API server
  • customized "success" messages by updating the displayed metadata (e.g. a new image and description)

To chain multiple actions together, in any ActionPostResponse include a links.next of either:

  • PostNextActionLink - POST request link with a same origin callback url to receive the signature and user's account in the body. This callback url should respond with a NextAction.
  • InlineNextActionLink - Inline metadata for the next action to be presented to the user immediately after the transaction has confirmed. No callback will be made.
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;
}

NextAction #

After the ActionPostResponse included transaction is signed by the user and confirmed on-chain, the blink client should either:

  • execute the callback request to fetch and display the NextAction, or
  • if a NextAction is already provided via links.next, the blink client should update the displayed metadata and make no callback request

If the callback url is not the same origin as the initial POST request, no callback request should be made. Blink clients should display an error notifying the user.

NextAction
/** 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">;

Based on the type, the next action should be presented to the user via blink clients in one of the following ways:

  • action - (default) A standard action that will allow the user to see the included Action metadata, interact with the provided LinkedActions, and continue to chain any following actions.

  • completed - The terminal state of an action chain that can update the blink UI with the included Action metadata, but will not allow the user to execute further actions.

If no links.next is not provided, blink clients should assume the current action is final action in the chain, presenting their "completed" UI state after the transaction is confirmed.

actions.json #

actions.json dosyasının amacı, bir uygulamanın kullanıcı uygulamalarına Solana Actions'ı destekleyen web sitesi URL'lerini hangilerinin desteklediği hakkında talimat vermek ve Actions API sunucusuna GET istekleri yapmak için kullanılabilecek bir eşleme sağlamaktır.

Cross-Origin headers are required

The actions.json file response must also return valid Cross-Origin headers for GET and OPTIONS requests, specifically the Access-Control-Allow-Origin header value of *.

See OPTIONS response above for more details.

actions.json dosyası, alan adının kökünde saklanmalı ve evrensel olarak erişilebilir olmalıdır.

Örneğin, web uygulamanız my-site.com adresine dağıtıldıysa, actions.json dosyasına https://my-site.com/actions.json adresinden erişilebilir olmalıdır. This file should also be Cross-Origin accessible via any browser by having a Access-Control-Allow-Origin header value of *.

Kurallar #

rules (kurallar) alanı, bir uygulamanın bir web sitesinin göreceli yol yollarını başka bir yol kümesine eşlemesine izin verir.

Tür ActionRuleObject in dizisi.

ActionRuleObject
interface ActionRuleObject {
  pathPattern: string; // kural eşlemesini yapmak için göreceli (tercih edilen) veya mutlak yol
  apiPath: string; // Action isteklerini destekleyen göreceli (tercih edilen) veya mutlak yol
}
  • pathPattern - Gelen her yol adıyla eşleşen bir desen.

  • apiPath - Mutlak bir yol adı veya harici bir URL olarak tanımlanan bir konum hedefi.

Kurallar - yolDeseni #

Gelen her yol adıyla eşleşen bir desen. Bu, mutlak veya göreceli bir yol olabilir ve aşağıdaki biçimleri destekler:

  • Tam Eşleme: Tam URL yolunu eşleştirir.

    • Örnek: /tam-yol
    • Örnek: https://website.com/tam-yol
  • Joker Eşleme: URL yolunda herhangi bir karakter dizisini eşleştirmek için joker karakterler kullanır. Bu, tek bir bölümü (* kullanarak) veya birden çok bölümü (** kullanarak) eşleştirebilir. (Bkz. Aşağıdaki Yol Eşleme).

    • Örnek: /trade/*, /trade/123 ve /trade/abc'yi eşleştirecek ve /trade/ sonrasındaki ilk bölümü yakalayacak.
    • Örnek: /category/*/item/**, /cateogry/123/item/456 ve /category/abc/item/def'yi eşleştirir.
    • Örnek:/api/actions/trade/*/confirm,/api/actions/trade/123/confirm i eşleştirir.

Kurallar - apiYolu #

Action isteği için hedef yol. Mutlak bir yol adı veya harici bir URL olarak tanımlanabilir.

  • Örnek: /api/tam-yol
  • Örnek:https://api.example.com/v1/donate/*
  • Örnek: /api/category/*/item/*
  • Example: /api/swap/**

Kurallar - Sorgu Parametreleri #

Orijinal URL'den gelen sorgu parametreleri her zaman korunur ve eşlenen URL'ye eklenir.

Kurallar - Yol Eşleme #

Aşağıdaki tablo, yol eşleme desenleri için sözdizimini açıklar:

OperatörEşleşme
*Tek bir yol segmenti, çevreleyen yol ayırıcı / karakterlerini içermeyen.
**Sıfır veya daha fazla karakteri eşleştirir; birden fazla yol bölümü arasında herhangi bir yol ayırıcı / karakterini içerir. Diğer operatörler dahil edilirse, ** operatörü son operatör olmalıdır.
?Desteklenmeyen desen.

Kurallar Örnekleri #

Aşağıdaki örnek, istekleri sitenizin kökünden(root) /buy yoluna tam eşleşen bir kuralı göstermektedir, bu istekleri sitenizin köküne göre /api/buy tam yoluna eşleştirir:

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

Aşağıdaki örnek, sitenizin kökünden /actions/' altındaki herhangi bir yola (alt dizinler hariç) gelen istekleri sitenizin köküne göre /api/actions/' altındaki karşılık gelen bir yolla eşleştirmek için joker yol eşleştirmesini kullanır:

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

Aşağıdaki örnek, joker karakter yol eşleştirme kullanarak, sitenizin kökünden /donate/ altındaki herhangi bir yol (alt dizinler dahil) isteğini, harici bir site olan https://api.dialect.com/api/v1/donate/ adresindeki karşılık gelen mutlak yola eşleştirir:

actions.json
{
  "rules": [
    {
      "pathPattern": "/donate/*",
      "apiPath": "https://api.dialect.com/api/v1/donate/*"
    }
  ]
}

Aşağıdaki örnek, /api/actions/ kökü altındaki herhangi bir yol (alt dizinler dahil) için istekleri kendine eşlemek için idempotent bir kural için joker karakter yol eşleme kullanır:

Info

Idempotent kurallar, blink kullanıcı uygulamalarının, belirli bir yolun Actions API isteklerini destekleyip desteklemediğini belirlemesini sağlar; bunu solana-action: URI'siyle ön eklemek veya ek yanıt testi yapmak zorunda kalmadan daha kolay yapar.

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

Action Kimliği #

Action uç noktaları, kullanıcı tarafından imzalanması için POST yanıtları içinde döndürülen işlemlerde bir Action Kimliği içerebilir. Bu, indeksleyicilerin ve analiz platformlarının on-chain aktiviteleri kolayca ve doğrulanabilir bir şekilde belirli bir Action Sağlayıcıya (yani hizmete) atfetmesini sağlar.

Action Kimliği, Memo talimatı kullanarak işleme dahil edilen özel biçimlendirilmiş bir mesajı imzalamak için kullanılan bir anahtar çiftidir. Bu Tanımlayıcı Mesaj, belirli bir Action Kimliği'ne doğrulanabilir bir şekilde atfedilebilir ve bu şekilde işlemleri belirli bir Action Sağlayıcısına atar.

Anahtar çifti, işlemin kendisini imzalamak için gerekli değildir. Bu, cüzdanların ve uygulamaların, kullanıcının döndürülen işlemde başka imzalar olmadığında işlem teslim edilebilirliğini artırmasına olanak tanır (bkz. POST yanıt işlemi).

Bir Action Sağlayıcısının kullanım durumu, kullanıcıdan önce işlemi önceden imzalamak için arka uç hizmetlerini gerektiriyorsa, bu anahtar çiftini Action Kimliği olarak kullanmalıdır. Bu, işleme bir hesabın daha az dahil edilmesine izin vererek, toplam işlem boyutunu 32 bayt azaltır.

Action Tanımlayıcı Mesajı #

Action Tanımlayıcı Mesajı, tek bir SPL Memo talimatı kullanılarak işlem içinde yer alan, iki nokta ile ayrılmış UTF-8 dizisidir.

protocol:identity:reference:signature
  • protocol - Kullanılan protokol değeri (yukarıdaki URL Şeması tarafından solana-action olarak ayarlanmış)
  • identity - Bu değer, Action Kimlik anahtar çiftinin base58 kodlanmış genel anahtar adresi olmalıdır.
  • reference - Değer, base58 ile kodlanmış 32 baytlık bir dizi olmalıdır. Bu, genel anahtarlar olabilir veya olmayabilir, eğri üzerinde veya dışında olabilir ve Solana'daki hesaplarla uyuşabilir veya uyuşmayabilir.
  • signature - Yalnızca reference değerini imzalayan Action Kimlik anahtar çiftinden oluşturulan base58 ile kodlanmış bir imzadır.

reference değeri sadece bir kez ve tek bir işlemde kullanılmalıdır. İşlemleri bir Action Sağlayıcı ile ilişkilendirme amacıyla, reference değerinin yalnızca ilk kullanımı geçerli kabul edilir.

İşlemlerde birden fazla Memo talimatı olabilir. getSignaturesForAddress işlemi gerçekleştirirken, sonuçların memo alanı, her memo talimatının mesajını noktalı virgülle ayrılmış tek bir dize olarak döndürecektir.

Tanımlayıcı Mesajı Notu talimatının Memo talimatında başka veri bulunmamalıdır.

The identity and the reference should be included as read-only, non-signer keys in the transaction on an instruction that is NOT the Identifier Message Memo instruction.

Tanımlayıcı Mesajı Notu talimatında hiçbir hesap belirtilmemelidir. Herhangi bir hesap sağlanırsa, Memo programının bu hesapların geçerli imzalayıcılar olmasını gerektirir. Actionsları tanımlama amaçları için, bu esnekliği sınırlar ve kullanıcı deneyimini olumsuz etkileyebilir. Bu nedenle, bu bir karşı kalıp olarak kabul edilir ve kaçınılmalıdır.

Action Kimlik Doğrulama #

identity hesabını içeren herhangi bir işlem, çok adımlı bir süreçte doğrulanabilir şekilde Action Sağlayıcı ile ilişkilendirilebilir:

  1. Belirli bir identity için tüm işlemleri al.
  2. Her işlemin memo dizesini ayrıştırın ve signature'ın saklanan reference için geçerli olduğundan emin olun.
  3. reference on-chain üzerindeki belirli işlemin ilk on-chain oluşumu doğrulayın:
    • Bu işlem ilk kez gerçekleşiyorsa, işlem doğrulanmış kabul edilir ve güvenle Action Sağlayıcısına atfedilebilir.
    • Eğer bu işlem İLK kez gerçekleşmiyorsa, geçersiz olarak kabul edilir ve dolayısıyla Action Sağlayıcı'ya atfedilmez.

Solana doğrulayıcıları işlem bilgilerini hesap anahtarlarına göre dizinlerler, bu nedenle getSignaturesForAddress RPC yöntemi, idedntity hesabını içeren tüm işlemleri bulmak için kullanılabilir.

Bu RPC yönteminin yanıtı, tüm Memo verilerini memo alanında içerir. Eğer işlemde birden fazla Memo talimatı kullanıldıysa, her memo mesajı bu memo alanına dahil edilecek ve doğrulayıcı tarafından Kimlik Doğrulama Mesajı'nı elde etmek için buna uygun şekilde ayrıştırılmalıdır.

Bu işlemler başlangıçta DOĞRULANMAMIŞ olarak kabul edilmelidir. Bu durum, işlemi imzalamak için identity'nin gerekli olmamasından kaynaklanır, bu da herhangi bir işlemin bu hesabı imza atmayan bir katılımcı olarak içermesine izin verir. Potansiyel olarak sahiplik ve kullanım sayılarını yapay olarak artırabilir.

Kimlik Doğrulama Mesajı, signature'ın identity tarafından reference imzalanarak oluşturulduğundan emin olmak için kontrol edilmelidir. Bu imza doğrulaması başarısız olursa, işlem geçersizdir ve Action Sağlayıcısına atfedilmemelidir.

Eğer imza doğrulaması başarılı olursa, doğrulayıcı bu işlemin reference'ın zincir üzerindeki ilk gerçekleşmesi olduğundan emin olmalıdır. Eğer değilse, işlem geçersiz sayılır.