Solana Actions zijn specificatie-conforme API's die transacties op de Solana-blockchain retourneren om te bekijken, te ondertekenen en te verzenden in verschillende contexten, waaronder QR-codes, knoppen + widgets en websites op het internet. Actions maken het voor ontwikkelaars eenvoudig om de mogelijkheden van het Solana-ecosysteem direct in jouw omgeving te integreren, zodat je blockchaintransacties kunt uitvoeren zonder naar een andere app of webpagina te hoeven navigeren.
Blockchain-links – oftewel blinks – maken van elke Solana Action een deelbare, metadata-rijke link. Blinks stellen Action-bewuste clients (browserextensie-wallets, bots) in staat om extra functionaliteit voor de gebruiker weer te geven. Op een website kan een blink direct een transactievoorvertoning in een wallet activeren zonder naar een gedecentraliseerde app te gaan; in Discord kan een bot de blink uitbreiden tot een interactieve reeks knoppen. Dit verplaatst de mogelijkheid om onchain te interageren naar elk weboppervlak dat een URL kan weergeven.
Aan de slag
Om snel aan de slag te gaan met het maken van aangepaste Solana Actions:
npm install @solana/actions
- installeer de Solana Actions SDK in jouw applicatie
- bouw een API-eindpunt voor het GET-verzoek dat de metadata over jouw Action retourneert
- maak een API-eindpunt dat het POST-verzoek accepteert en de ondertekenabare transactie voor de gebruiker retourneert
Bekijk deze videotutorial over hoe je een Solana Action bouwt met behulp van de
@solana/actionsSDK.Je kunt ook de broncode voor een Action vinden die een native SOL-overdracht uitvoert, en verschillende andere voorbeeldacties in deze repo.
Bij het implementeren van jouw aangepaste Solana Actions naar productie:
- zorg ervoor dat jouw applicatie een geldig actions.json-bestand heeft in de root van jouw domein
- zorg ervoor dat jouw applicatie reageert met de
vereiste Cross-Origin-headers op alle Action-eindpunten,
inclusief het
actions.json-bestand - test en debug jouw blinks/actions met de Blinks Inspector
Als je op zoek bent naar inspiratie voor het bouwen van Actions en blinks, bekijk dan de Awesome Blinks-repository voor een aantal creaties van de community en zelfs ideeën voor nieuwe.
Actions
De Solana Actions-specificatie maakt gebruik van een set standaard-API's om ondertekenabare transacties (en uiteindelijk ondertekenabare berichten) rechtstreeks van een applicatie naar een gebruiker te leveren. Ze worden gehost op openbaar toegankelijke URL's en zijn daarom via hun URL toegankelijk voor elke client.
Je kunt Actions zien als een API-eindpunt dat metadata retourneert en iets wat een gebruiker moet ondertekenen (een transactie of een authenticatiebericht) met hun blockchain-wallet.
De Actions API bestaat uit eenvoudige GET- en POST-verzoeken aan de URL-eindpunt van een Action en het verwerken van de antwoorden die voldoen aan de Actions-interface.
- het GET-verzoek retourneert metadata die de client leesbare informatie geeft over welke actions beschikbaar zijn op deze URL, en een optionele lijst van gerelateerde actions.
- het POST-verzoek retourneert een ondertekenabare transactie of bericht dat de client vervolgens aan de wallet van de gebruiker aanbiedt om te ondertekenen en uit te voeren op de blockchain of in een andere offchain-service.
Uitvoering en levenscyclus van Actions
In de praktijk lijkt het werken met Actions sterk op het werken met een typische REST API:
- een client doet het initiële
GET-verzoek aan een Action URL om metadata op te halen over de beschikbare Actions - het eindpunt retourneert een antwoord dat metadata bevat over het eindpunt (zoals de titel en het pictogram van de applicatie) en een overzicht van de beschikbare actions voor dit eindpunt
- de clientapplicatie (zoals een mobiele wallet, chatbot of website) toont een gebruikersinterface waarmee de gebruiker een van de actions kan uitvoeren
- nadat de gebruiker een action selecteert (door op een knop te klikken), doet de client een
POST-verzoek aan het eindpunt om de transactie te verkrijgen die de gebruiker moet ondertekenen - de wallet faciliteert het ondertekenen van de transactie door de gebruiker en stuurt de transactie uiteindelijk naar de blockchain ter bevestiging
Uitvoering en levenscyclus van Solana Actions
Bij het ontvangen van transacties van een Actions URL moeten clients de indiening van deze transacties op de blockchain afhandelen en hun toestandslevenscyclus beheren.
Actions ondersteunen ook een bepaalde mate van ongeldigverklaring vóór uitvoering. Het GET- en POST-verzoek kunnen metadata retourneren die aangeeft of de action uitgevoerd kan worden (zoals met het disabled-veld).
Als er bijvoorbeeld een Action-eindpunt is dat stemming op een DAO-governancevoorstel faciliteert waarvan het stemvenster is gesloten, kan het initiële GET-verzoek de foutmelding "Dit voorstel staat niet meer open voor stemming" retourneren en de knoppen "Stem Ja" en "Stem Nee" als "uitgeschakeld" weergeven.
Blinks
Blinks (blockchain-links) zijn clientapplicaties die Action API's analyseren en gebruikersinterfaces opbouwen voor het interageren met en uitvoeren van Actions.
Clientapplicaties die blinks ondersteunen, detecteren eenvoudig Action-compatibele URL's, verwerken deze en stellen gebruikers in staat ermee te interageren via gestandaardiseerde gebruikersinterfaces.
Elke clientapplicatie die een Actions API volledig analyseert om een complete interface daarvoor te bouwen, is een blink. Daarom zijn niet alle clients die Actions API's gebruiken, blinks.
Blink URL-specificatie
Een blink URL beschrijft een clientapplicatie waarmee een gebruiker de volledige levenscyclus van het uitvoeren van een Action kan voltooien, inclusief ondertekening met hun wallet.
https://example.domain/?action=<action_url>
Om van een clientapplicatie een blink te maken:
-
De blink URL moet een queryparameter
actionbevatten waarvan de waarde een URL-gecodeerde Action URL is. Deze waarde moet URL-gecodeerd zijn om conflicten met andere protocolparameters te voorkomen. -
De clientapplicatie moet de queryparameter
actionURL-decoderen en de opgegeven Action API-link analyseren (zie Action URL-schema). -
De client moet een rijke gebruikersinterface weergeven waarmee de gebruiker de volledige levenscyclus van het uitvoeren van een Action kan voltooien, inclusief ondertekening met hun wallet.
Niet alle blink-clientapplicaties (bijv. websites of dApps) ondersteunen alle Actions. Applicatieontwikkelaars kunnen kiezen welke Actions ze willen ondersteunen binnen hun blink-interfaces.
Het volgende voorbeeld toont een geldige blink URL met een action-waarde van
solana-action:https://actions.alice.com/donate die URL-gecodeerd is:
https://example.domain/?action=solana-action%3Ahttps%3A%2F%2Factions.alice.com%2Fdonate
Actions detecteren via Blinks
Blinks kunnen op ten minste 3 manieren aan Actions worden gekoppeld:
-
Een expliciete Action URL delen:
solana-action:https://actions.alice.com/donateIn dit geval kunnen alleen ondersteunde clients de blink weergeven. Er is geen fallback-linkvoorvertoning of site die buiten de niet-ondersteunende client bezocht kan worden.
-
Een link delen naar een website die via een
actions.json-bestand op de domeinroot van de website aan een Actions API is gekoppeld.Zo wijst
https://alice.com/actions.jsonbijvoorbeeldhttps://alice.com/donate, een website-URL waar gebruikers aan Alice kunnen doneren, toe aan de API URLhttps://actions.alice.com/donate, waar Actions voor doneren aan Alice worden gehost. -
Een Action URL insluiten in een "tussenliggende" site-URL die begrijpt hoe Actions verwerkt moeten worden.
https://example.domain/?action=<action_url>
Clients die blinks ondersteunen, moeten elk van de bovenstaande formaten kunnen verwerken en correct een interface weergeven om het uitvoeren van de action direct in de client te faciliteren.
Voor clients die geen blinks ondersteunen, moet er een onderliggende website zijn (waardoor de browser de universele fallback wordt).
Als een gebruiker ergens op een client tikt dat geen actieknop of tekstinvoerveld is, moeten ze naar de onderliggende site worden geleid.
Testen en verificatie van Blinks
Hoewel Solana Actions en blinks een rechtenvrij protocol/specificatie zijn, moeten clientapplicaties en wallets uiteindelijk faciliteren dat gebruikers de transactie ondertekenen.
Gebruik de Blinks Inspector-tool om jouw blinks en actions direct in jouw browser te inspecteren, debuggen en testen. Je kunt de GET- en POST-antwoordpayloads, antwoordheaders bekijken en alle invoer voor elk van jouw gekoppelde Actions testen.
Elke clientapplicatie of wallet kan andere vereisten hebben ten aanzien van welke Action-eindpunten automatisch worden uitgevouwen en direct aan hun gebruikers worden weergegeven op sociale mediaplatforms.
Sommige clients kunnen bijvoorbeeld werken met een "allowlist"-aanpak waarbij verificatie vereist is voordat hun client een Action voor gebruikers uitvouwt, zoals het Actions Registry van Dialect (hieronder beschreven).
Alle blinks worden nog steeds weergegeven en maken ondertekening mogelijk op de dial.to blinks-tussenliggende site van Dialect, met hun registerstatus weergegeven in de blink.
Het Actions Registry van Dialect
Als publiek goed voor het Solana-ecosysteem onderhoudt Dialect een openbaar register — samen met de hulp van Solana Foundation en andere communityleden — van blockchain-links die afkomstig zijn van vooraf geverifieerde bronnen. Vanaf de lancering zullen alleen Actions die zijn geregistreerd in het Dialect-register worden uitgevouwen in de Twitter-feed wanneer ze worden geplaatst.
Clientapplicaties en wallets kunnen vrijelijk kiezen om dit openbare register of een andere oplossing te gebruiken om de veiligheid van gebruikers te waarborgen. Als niet geverifieerd via het Dialect-register, wordt de blockchain-link niet verwerkt door de blink-client en wordt deze weergegeven als een gewone URL.
Ontwikkelaars kunnen zich hier aanmelden voor verificatie door Dialect: dial.to/register
Specificatie
De Solana Actions-specificatie bestaat uit belangrijke secties die deel uitmaken van een verzoek/antwoord-interactiestroom:
- Solana Action URL-schema dat een Action URL biedt
- OPTIONS-antwoord op een Action URL om te voldoen aan CORS- vereisten
- GET-verzoek aan een Action URL
- GET-antwoord van de server
- POST-verzoek aan een Action URL
- POST-antwoord van de server
Elk van deze verzoeken wordt gedaan door de Action-client (bijv. wallet-app, browserextensie, dApp, website, enz.) om specifieke metadata te verzamelen voor uitgebreide gebruikersinterfaces en om gebruikersinvoer voor de Actions API te faciliteren.
Elk van de antwoorden wordt samengesteld door een applicatie (bijv. website, server-backend, enz.) en teruggestuurd naar de Action-client. Uiteindelijk wordt hiermee een ondertekенbare transactie of bericht aangeboden waarmee een wallet de gebruiker vraagt om goed te keuren, te ondertekenen en naar de blockchain te verzenden.
De typen en interfaces die in dit readme-bestand zijn gedeclareerd, zijn vaak de vereenvoudigde versie van de typen om de leesbaarheid te verbeteren.
Voor betere type-veiligheid en een verbeterde ontwikkelaarservaring bevat het pakket
@solana/actions-specmeer complexe typedefinities. U kunt de broncode hier vinden.
URL-schema
Een Solana Action-URL beschrijft een interactief verzoek voor een ondertekенbare Solana-transactie of -bericht met behulp van het solana-action-protocol.
Het verzoek is interactief omdat de parameters in de URL door een client worden gebruikt om een reeks gestandaardiseerde HTTP-verzoeken te doen om een ondertekенbare transactie of bericht samen te stellen voor de gebruiker om te ondertekenen met zijn wallet.
solana-action:<link>
-
Een enkel
link-veld is vereist als padnaam. De waarde moet een voorwaardelijk URL-gecodeerde absolute HTTPS-URL zijn. -
Als de URL queryparameters bevat, moet deze URL-gecodeerd zijn. Het URL-coderen van de waarde voorkomt conflicten met eventuele Actions-protocolparameters, die mogelijk worden toegevoegd via de protocolspecificatie.
-
Als de URL geen queryparameters bevat, hoeft deze niet URL-gecodeerd te zijn. Dit levert een kortere URL en een minder dichte QR-code op.
In beide gevallen moeten clients de waarde URL-decoderen. Dit heeft geen effect als de waarde niet URL-gecodeerd is. Als de gedecodeerde waarde geen absolute HTTPS-URL is, moet de wallet deze afwijzen als ongeldig.
OPTIONS-antwoord
Om Cross-Origin Resource Sharing
(CORS) binnen Action-clients
(inclusief blinks) mogelijk te maken, moeten alle Action-eindpunten reageren op HTTP-verzoeken voor de OPTIONS-methode met geldige headers die clients in staat stellen CORS-controles te doorstaan voor alle volgende verzoeken vanaf hetzelfde brondomein.
Een Action-client kan
"preflight"-verzoeken
sturen naar het Action-URL-eindpunt om te controleren of het volgende GET-verzoek naar de Action-URL alle CORS-controles doorstaat. Deze CORS-preflight-controles worden uitgevoerd met de HTTP-methode OPTIONS en moeten reageren met alle vereiste HTTP-headers die Action-clients (zoals blinks) in staat stellen alle volgende verzoeken correct te doen vanaf hun brondomein.
De minimaal vereiste HTTP-headers zijn:
Access-Control-Allow-Originmet een waarde van*- dit zorgt ervoor dat alle Action-clients veilig CORS-controles kunnen doorstaan om alle vereiste verzoeken te kunnen doen
Access-Control-Allow-Methodsmet een waarde vanGET,POST,PUT,OPTIONS- zorgt ervoor dat alle vereiste HTTP-verzoekmethoden worden ondersteund voor Actions
Access-Control-Allow-Headersmet een minimumwaarde vanContent-Type, Authorization, Content-Encoding, Accept-Encoding
Voor de eenvoud kunnen ontwikkelaars overwegen hetzelfde antwoord en dezelfde headers terug te sturen op OPTIONS-verzoeken als hun GET-antwoord.
Cross-Origin-headers voor actions.json
Het bestandsantwoord actions.json moet ook geldige Cross-Origin-headers retourneren voor
GET- en OPTIONS-verzoeken, met name de headerwaarde Access-Control-Allow-Origin
van *.
Zie actions.json hieronder voor meer details.
GET-verzoek
De Action-client (bijv. wallet, browserextensie, enz.) moet een HTTP
GET JSON-verzoek sturen naar het URL-eindpunt van de Action.
- Het verzoek mag de wallet of de gebruiker niet identificeren.
- De client moet het verzoek doen met een
Accept-Encoding-header. - De client moet het domein van de URL weergeven terwijl het verzoek wordt gedaan.
GET-antwoord
Het URL-eindpunt van de Action (bijv. applicatie of server-backend) moet reageren met een HTTP OK JSON-antwoord (met een geldige payload in de body) of een passende HTTP-fout.
-
De client moet HTTP clientfouten, serverfouten en omleidingsantwoorden afhandelen.
-
Het eindpunt moet reageren met een
Content-Encoding-header voor HTTP-compressie. -
Het eindpunt moet reageren met een
Content-Type-header vanapplication/json. -
De client mag het antwoord niet cachen, tenzij dit is aangegeven door HTTP-caching antwoordheaders.
-
De client moet de
titleweergeven en deicon-afbeelding tonen aan de gebruiker.
Foutantwoorden (d.w.z. HTTP 4xx- en 5xx-statuscodes) moeten een JSON-antwoordbody retourneren volgens ActionError om een nuttige foutmelding aan gebruikers te tonen. Zie Action-fouten.
GET-antwoordbody
Een GET-antwoord met een HTTP OK JSON-antwoord moet een body-payload bevatten die de interfacespecificatie volgt:
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- Het type actie dat aan de gebruiker wordt gegeven. Standaard ingesteld opaction. De initiëleActionGetResponsemoet een type vanactionhebben.action- Standaardactie waarmee de gebruiker kan communiceren met elk van deLinkedActionscompleted- Wordt gebruikt om de "voltooide" status binnen actieketening te declareren.
-
icon- De waarde moet een absolute HTTP- of HTTPS-URL zijn van een icoонafbeelding. Het bestand moet een SVG-, PNG- of WebP-afbeelding zijn, anders moet de client/wallet het afwijzen als ongeldig. -
title- De waarde moet een UTF-8-tekenreeks zijn die de bron van het actieverzoek vertegenwoordigt. Dit kan bijvoorbeeld de naam zijn van een merk, winkel, applicatie of persoon die het verzoek doet. -
description- De waarde moet een UTF-8-tekenreeks zijn die informatie over de actie verstrekt. De beschrijving moet aan de gebruiker worden weergegeven. -
label- De waarde moet een UTF-8-tekenreeks zijn die wordt weergegeven op een knop waarop de gebruiker kan klikken. Alle labels mogen niet meer dan 5 woorden bevatten en moeten beginnen met een werkwoord om de actie die de gebruiker moet ondernemen te verduidelijken. Bijvoorbeeld: "Mint NFT", "Stem ja" of "Stake 1 SOL". -
disabled- De waarde moet een boolean zijn die de uitgeschakelde status van de weergegeven knop (die delabel-tekenreeks toont) vertegenwoordigt. Als er geen waarde is opgegeven, moetdisabledstandaardfalsezijn (d.w.z. standaard ingeschakeld). Als het actie-eindpunt bijvoorbeeld voor een bestuursstemming is die is gesloten, stel dandisabled=truein en hetlabelkan "Stemming gesloten" zijn. -
error- Een optionele foutindicatie voor niet-fatale fouten. Indien aanwezig, moet de client deze aan de gebruiker tonen. Indien ingesteld, mag dit de client niet verhinderen de actie te interpreteren of aan de gebruiker te tonen (zie Action-fouten). De fout kan bijvoorbeeld samen metdisabledworden gebruikt om een reden weer te geven zoals zakelijke beperkingen, autorisatie, de status of een fout van een externe resource. -
links.actions- Een optionele array van gerelateerde acties voor het eindpunt. Gebruikers moeten een UI te zien krijgen voor elk van de vermelde acties en worden verwacht er slechts één uit te voeren. Een eindpunt voor een bestuursstemactie kan bijvoorbeeld drie opties aan de gebruiker retourneren: "Stem ja", "Stem nee" en "Onthouding van stemming".-
Als er geen
links.actionsis opgegeven, moet de client één knop weergeven met de root-label-tekenreeks en het POST-verzoek doen naar hetzelfde actie-URL-eindpunt als het initiële GET-verzoek. -
Als er
links.actionszijn opgegeven, moet de client alleen knoppen en invoervelden weergeven op basis van de items in het veldlinks.actions. De client mag geen knop weergeven voor de inhoud van het root-label.
-
export interface LinkedAction {/** Type of action to be performed by user */type: LinkedActionType;/** 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>;}
De ActionParameter maakt het mogelijk te declareren welke invoer de Actions API van de gebruiker opvraagt:
/*** 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;}
Het pattern moet een tekenreeks zijn die equivalent is aan een geldig regulier expressie. Dit reguliere-expressiepatroon moet door blink-clients worden gebruikt om gebruikersinvoer te valideren voordat het POST-verzoek wordt gedaan. Als het pattern geen geldige reguliere expressie is, moet het door clients worden genegeerd.
De patternDescription is een voor mensen leesbare beschrijving van de verwachte invoerverzoeken van de gebruiker. Als pattern is opgegeven, is het verplicht om ook patternDescription op te geven.
De waarden min en max stellen de invoer in staat een onder- en/of bovengrens in te stellen voor de invoer die van de gebruiker wordt gevraagd (d.w.z. min/max-getal en/of min/max-tekenlength), en moeten worden gebruikt voor validatie aan de clientzijde. Voor invoertypes van date of datetime-local moeten deze waarden datumtekenreeksen zijn. Voor andere op tekenreeksen gebaseerde invoertypes moeten de waarden getallen zijn die de min/max-tekenlengte vertegenwoordigen.
Als de gebruikersinvoerwaarde niet geldig wordt geacht volgens het pattern, moet de gebruiker een foutmelding aan de clientzijde ontvangen die aangeeft dat het invoerveld ongeldig is, en moet de patternDescription-tekenreeks worden weergegeven.
Het veld type stelt de Actions API in staat meer specifieke gebruikersinvoervelden te declareren, wat betere validatie aan de clientzijde biedt en de gebruikerservaring verbetert. In veel gevallen zal dit type lijken op het standaard
HTML-invoerelement.
De ActionParameterType kan worden vereenvoudigd tot het volgende type:
/*** Input field type to present to the user* @default `text`*/export type ActionParameterType =| "text"| "email"| "url"| "number"| "date"| "datetime-local"| "checkbox"| "radio"| "textarea"| "select";
Elk van de type-waarden moet normaal gesproken resulteren in een gebruikersinvoerveld dat lijkt op een standaard HTML-input-element van het bijbehorende type (d.w.z.
<input type="email" />) om betere validatie aan de clientzijde en een betere gebruikerservaring te bieden:
text- equivalent van het HTML "text"-invoerelementemail- equivalent van het HTML "email"-invoerelementurl- equivalent van het HTML "url"-invoerelementnumber- equivalent van het HTML "number"-invoerelementdate- equivalent van het HTML "date"-invoerelementdatetime-local- equivalent van het HTML "datetime-local"-invoerelementcheckbox- equivalent van een groepering van standaard HTML "checkbox"-invoerelementen. De Actions API moetoptionsretourneren zoals hieronder beschreven. De gebruiker moet meerdere van de aangeboden selectievakopties kunnen selecteren.radio- equivalent van een groepering van standaard HTML "radio"-invoerelementen. De Actions API moetoptionsretourneren zoals hieronder beschreven. De gebruiker moet slechts één van de aangeboden radio-opties kunnen selecteren.- Andere HTML-invoertypeequivalenten die hierboven niet zijn opgegeven (
hidden,button,submit,file, enz.) worden momenteel niet ondersteund.
Naast de elementen die lijken op de bovenstaande HTML-invoertypen, worden ook de volgende gebruikersinvoerelementen ondersteund:
textarea- equivalent van het HTML textarea-element. Hiermee kan de gebruiker invoer op meerdere regels opgeven.select- equivalent van het HTML select-element, waarmee de gebruiker een "dropdown"-stijlveld kan gebruiken. De Action API moetoptionsretourneren zoals hieronder beschreven.
Wanneer type is ingesteld op select, checkbox of radio, moet de Action API
een array van options bevatten, waarbij elke optie minimaal een label en een value biedt.
Elke optie kan ook een selected-waarde hebben om de blink-client te informeren welke
optie standaard voor de gebruiker geselecteerd moet worden
(zie checkbox en radio voor de verschillen).
Deze ActionParameterSelectable kan worden vereenvoudigd tot de volgende typedefinitie:
/*** 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;}>;}
Als er geen type is ingesteld of een onbekende/niet-ondersteunde waarde is ingesteld, moeten
blink-clients standaard text gebruiken en een eenvoudig tekstinvoerveld weergeven.
De Action API blijft verantwoordelijk voor het valideren en opschonen van alle gegevens uit de gebruikersinvoerparameters, waarbij eventuele "verplichte" gebruikersinvoer naar behoefte wordt afgedwongen.
Voor andere platforms dan HTML/webgebaseerde platforms (zoals native mobiel) moet het equivalente native gebruikersinvoercomponent worden gebruikt om dezelfde ervaring en clientsidevalidatie te bereiken als de hierboven beschreven HTML/web-invoertypen.
Voorbeeld GET-respons
Het volgende voorbeeldantwoord biedt één enkele "root"-actie die naar verwachting aan de gebruiker wordt gepresenteerd als één knop met het label "Claim Access Token":
{"title": "HackerHouse Events","icon": "<url-to-image>","description": "Claim your Hackerhouse access token.","label": "Claim Access Token" // button text}
Het volgende voorbeeldantwoord biedt 3 gerelateerde actielinks waarmee de gebruiker op één van de 3 knoppen kan klikken om zijn stem uit te brengen voor een DAO-voorstel:
{"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"}]}}
Voorbeeld GET-respons met parameters
Het volgende voorbeeldantwoord laat zien hoe tekstinvoer van de gebruiker kan worden
ontvangen (via parameters) en opgenomen in het uiteindelijke POST-verzoekeindpunt
(via het veld href in een LinkedAction):
Het volgende voorbeeldantwoord biedt de gebruiker 3 gekoppelde acties om SOL te staken: een knop met het label "Stake 1 SOL", een andere knop met het label "Stake 5 SOL", en een tekstinvoerveld waarmee de gebruiker een specifieke "amount"-waarde kan invoeren die naar de Action API wordt verzonden:
{"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}]}]}}
Het volgende voorbeeldantwoord biedt één invoerveld waarmee de gebruiker een amount kan
invoeren die wordt meegestuurd met het POST-verzoek (als queryparameter of als subpad):
{"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-verzoek
De client moet een HTTP POST JSON-verzoek sturen naar de actie-URL met de volgende
bodyinhoud:
{"account": "<account>"}
account- De waarde moet de base58-gecodeerde publieke sleutel zijn van een account dat de transactie mag ondertekenen.
De client moet het verzoek uitvoeren met een Accept-Encoding header en de applicatie mag reageren met een Content-Encoding header voor HTTP-compressie.
De client moet het domein van de actie-URL weergeven terwijl het verzoek wordt uitgevoerd.
Als er een GET-verzoek is gedaan, moet de client ook de title weergeven en de icon-afbeelding
renderen uit die GET-respons.
POST-respons
Het POST-eindpunt van de actie moet reageren met een HTTP OK JSON-respons
(met een geldige payload in de body) of een passende HTTP-fout.
- De client moet HTTP clientfouten, serverfouten en omleidingsreacties verwerken.
- Het eindpunt moet reageren met een
Content-Typeheader vanapplication/json.
Foutreacties (d.w.z. HTTP 4xx- en 5xx-statuscodes) moeten een JSON-responsebody retourneren
die ActionError volgt om een nuttige foutmelding aan gebruikers te tonen.
Zie Action Errors.
POST-responsbody
Een POST-respons met een HTTP OK JSON-respons moet een bodyinhoud bevatten van:
/*** 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- De waarde moet een base64-gecodeerde geserialiseerde transactie zijn. De client moet de transactie base64-decoderen en deserialiseren. -
message- De waarde moet een UTF-8-tekenreeks zijn die de aard van de transactie in de respons beschrijft. De client moet deze waarde aan de gebruiker tonen. Dit kan bijvoorbeeld de naam zijn van een item dat wordt gekocht, een korting op een aankoop of een bedankbericht. -
links.next- Een optionele waarde om meerdere acties achter elkaar te "koppelen". Nadat de bijgevoegdetransactiononchain is bevestigd, kan de client de volgende actie ophalen en weergeven. Zie Action Chaining voor meer details. -
De client en de applicatie moeten aanvullende velden in de verzoekbody en responsebody toestaan, die mogelijk worden toegevoegd door toekomstige specificatie-updates.
De applicatie kan reageren met een gedeeltelijk of volledig ondertekende transactie. De client en wallet moeten de transactie als niet-vertrouwd valideren.
POST-respons - Transactie
Als de transactie
signatures
leeg zijn of de transactie NIET gedeeltelijk is ondertekend:
- De client moet de
feePayerin de transactie negeren en defeePayerinstellen op hetaccountin het verzoek. - De client moet de
recentBlockhashin de transactie negeren en derecentBlockhashinstellen op de meest recente blockhash. - De client moet de transactie serialiseren en deserialiseren voordat deze wordt ondertekend. Dit zorgt voor consistente volgorde van de accountsleutels, als tijdelijke oplossing voor dit probleem.
Als de transactie gedeeltelijk is ondertekend:
- De client mag de
feePayerofrecentBlockhashNIET wijzigen, omdat dit bestaande handtekeningen ongeldig zou maken. - De client moet bestaande handtekeningen verifiëren, en als een of meer ongeldig zijn, moet de client de transactie afwijzen als ongeldig gevormd.
De client mag de transactie alleen ondertekenen met het account in het verzoek, en mag
dat alleen doen als een handtekening voor het account in het verzoek wordt verwacht.
Als een andere handtekening dan die voor het account in het verzoek wordt verwacht, moet
de client de transactie afwijzen als kwaadaardig.
Actiefouten
Actions API's moeten fouten retourneren via ActionError om nuttige foutmeldingen aan de
gebruiker te presenteren. Afhankelijk van de context kan deze fout fataal of niet-fataal zijn.
export interface ActionError {/** simple error message to be displayed to the user */message: string;}
Wanneer een Actions API reageert met een HTTP-foutstatuscode (d.w.z. 4xx en 5xx), moet de
responsebody een JSON-payload zijn die ActionError volgt. De fout wordt als fataal beschouwd
en het bijgevoegde message moet aan de gebruiker worden getoond.
Voor API-reacties die het optionele error-attribuut ondersteunen (zoals
ActionGetResponse), wordt de fout als niet-fataal beschouwd en moet het
bijgevoegde message aan de gebruiker worden getoond.
Actiekoppeling
Solana Actions kunnen achter elkaar worden "gekoppeld". Nadat de transactie van een actie onchain is bevestigd, kan de volgende actie worden opgehaald en aan de gebruiker worden gepresenteerd.
Actiekoppeling stelt ontwikkelaars in staat om complexere en dynamischere ervaringen binnen blinks te bouwen, waaronder:
- het aanbieden van meerdere transacties (en uiteindelijk berichtondertekening) aan een gebruiker
- aangepaste actiemetadata op basis van het walletadres van de gebruiker
- de blink-metadata vernieuwen na een succesvolle transactie
- een API-callback ontvangen met de transactiehandtekening voor aanvullende validatie en logica op de Action API-server
- aangepaste "succes"-berichten door de weergegeven metadata bij te werken (bijv. een nieuwe afbeelding en beschrijving)
Om meerdere acties aan elkaar te koppelen, neem in elke ActionPostResponse een
links.next op van het type:
PostNextActionLink- POST-verzoeklink met een callback-url van dezelfde oorsprong om designatureen hetaccountvan de gebruiker in de body te ontvangen. Deze callback-url moet reageren met eenNextAction.InlineNextActionLink- Inline metadata voor de volgende actie die direct na bevestiging van de transactie aan de gebruiker wordt gepresenteerd. Er wordt geen callback uitgevoerd.
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
Nadat de transaction uit de ActionPostResponse door de gebruiker is ondertekend en
onchain is bevestigd, moet de blink-client:
- het callbackverzoek uitvoeren om de
NextActionop te halen en weer te geven, of - als een
NextActional beschikbaar is vialinks.next, moet de blink-client de weergegeven metadata bijwerken en geen callbackverzoek doen
Als de callback-url niet dezelfde oorsprong heeft als het eerste POST-verzoek, mag er geen callbackverzoek worden gedaan. Blink-clients moeten een foutmelding weergeven om de gebruiker te informeren.
/** 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">;
Op basis van het type moet de volgende actie via blink-clients op een van de volgende
manieren aan de gebruiker worden gepresenteerd:
-
action- (standaard) Een standaardactie waarmee de gebruiker de bijgevoegde actiemetadata kan bekijken, kan communiceren met de opgegevenLinkedActions, en verdere acties kan koppelen. -
completed- De eindstatus van een actieketen die de blink-UI kan bijwerken met de bijgevoegde actiemetadata, maar de gebruiker niet toestaat verdere acties uit te voeren.
Als links.next niet is opgegeven, moeten blink-clients aannemen dat de huidige actie de
laatste actie in de keten is en hun "voltooid"-UI-status weergeven nadat de transactie is bevestigd.
actions.json
Het doel van het actions.json-bestand stelt een applicatie in staat clients te
instrueren welke website-URL's Solana Actions ondersteunen en biedt een mapping die kan worden
gebruikt voor het uitvoeren van GET-verzoeken naar een Actions API-server.
Cross-Origin headers zijn vereist
Het antwoord van het actions.json-bestand moet ook geldige Cross-Origin headers retourneren voor
GET- en OPTIONS-verzoeken, met name de Access-Control-Allow-Origin-headerwaarde van *.
Zie OPTIONS-respons hierboven voor meer details.
Het actions.json-bestand moet worden opgeslagen en universeel toegankelijk zijn in de hoofdmap
van het domein.
Als uw webapplicatie bijvoorbeeld is geïmplementeerd op my-site.com, moet het
actions.json-bestand toegankelijk zijn via https://my-site.com/actions.json.
Dit bestand moet ook Cross-Origin toegankelijk zijn via elke browser door een
Access-Control-Allow-Origin-headerwaarde van * in te stellen.
Regels
Het veld rules stelt de applicatie in staat een set relatieve routepaden van een website
te koppelen aan een set andere paden.
Type: Array van ActionRuleObject.
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- Een patroon dat overeenkomt met elk inkomend padnaam. -
apiPath- Een bestemmingslocatie gedefinieerd als een absoluut padnaam of externe URL.
Regels - pathPattern
Een patroon dat overeenkomt met elk inkomend padnaam. Het kan een absoluut of relatief pad zijn en ondersteunt de volgende formaten:
-
Exacte Overeenkomst: Komt overeen met het exacte URL-pad.
- Voorbeeld:
/exact-path - Voorbeeld:
https://website.com/exact-path
- Voorbeeld:
-
Jokerteken Overeenkomst: Gebruikt jokertekens om een willekeurige reeks tekens in het URL-pad te matchen. Dit kan enkelvoudige segmenten (met
*) of meerdere segmenten (met**) matchen. (zie Padmatching hieronder).- Voorbeeld:
/trade/*komt overeen met/trade/123en/trade/abc, waarbij alleen het eerste segment na/trade/wordt vastgelegd. - Voorbeeld:
/category/*/item/**komt overeen met/category/123/item/456en/category/abc/item/def. - Voorbeeld:
/api/actions/trade/*/confirmkomt overeen met/api/actions/trade/123/confirm.
- Voorbeeld:
Regels - apiPath
Het doelpad voor het actieverzoek. Het kan worden gedefinieerd als een absoluut padnaam of een externe URL.
- Voorbeeld:
/api/exact-path - Voorbeeld:
https://api.example.com/v1/donate/* - Voorbeeld:
/api/category/*/item/* - Voorbeeld:
/api/swap/**
Regels - Queryparameters
Queryparameters van de oorspronkelijke URL worden altijd bewaard en toegevoegd aan de gekoppelde URL.
Regels - Padmatching
De volgende tabel beschrijft de syntaxis voor padmatchingpatronen:
| Operator | Komt overeen met |
|---|---|
* | Een enkel padsegment, zonder de omringende scheidingstekens /. |
** | Komt overeen met nul of meer tekens, inclusief scheidingstekens / tussen meerdere padsegmenten. Als andere operators zijn opgenomen, moet de **-operator de laatste operator zijn. |
? | Niet-ondersteund patroon. |
Regelvoorbeelden
Het volgende voorbeeld toont een exacte-overeenkomstregel om verzoeken naar /buy
vanaf de hoofdmap van uw site toe te wijzen aan het exacte pad /api/buy relatief aan de hoofdmap van uw site:
{"rules": [{"pathPattern": "/buy","apiPath": "/api/buy"}]}
Het volgende voorbeeld gebruikt jokerteken-padmatching om verzoeken naar elk pad
(exclusief submappen) onder /actions/ vanaf de hoofdmap van uw site toe te wijzen aan een
corresponderend pad onder /api/actions/ relatief aan de hoofdmap van uw site:
{"rules": [{"pathPattern": "/actions/*","apiPath": "/api/actions/*"}]}
Het volgende voorbeeld gebruikt jokerteken-padmatching om verzoeken naar elk pad
(exclusief submappen) onder /donate/ vanaf de hoofdmap van uw site toe te wijzen aan het corresponderende absolute pad https://api.dialect.com/api/v1/donate/ op een
externe site:
{"rules": [{"pathPattern": "/donate/*","apiPath": "https://api.dialect.com/api/v1/donate/*"}]}
Het volgende voorbeeld gebruikt jokerteken-padmatching voor een idempotente regel om
verzoeken naar elk pad (inclusief submappen) onder /api/actions/ vanaf de
hoofdmap van uw site naar zichzelf toe te wijzen:
Idempotente regels stellen blink-clients in staat gemakkelijker te bepalen of een gegeven pad Action API-verzoeken ondersteunt, zonder vooraf te hoeven worden voorzien van het
solana-action:URI of aanvullende responstest uit te voeren.
{"rules": [{"pathPattern": "/api/actions/**","apiPath": "/api/actions/**"}]}
Actie-identiteit
Actie-eindpunten kunnen een Actie-identiteit opnemen in de transacties die worden geretourneerd in hun POST-respons voor ondertekening door de gebruiker. Dit maakt het voor indexeerders en analyseplatformen eenvoudig en verifieerbaar mogelijk om onchain-activiteit toe te schrijven aan een specifieke Actieaanbieder (d.w.z. dienst) op een verifieerbare manier.
De Actie-identiteit is een keypair dat wordt gebruikt om een speciaal opgemaakt bericht te ondertekenen dat via een Memo-instructie in de transactie wordt opgenomen. Dit Identificatiebericht kan verifieerbaar worden toegeschreven aan een specifieke Actie-identiteit, en daarmee transacties aan een specifieke Actieaanbieder koppelen.
Het keypair hoeft de transactie zelf niet te ondertekenen. Dit stelt wallets en applicaties in staat de bezorging van transacties te verbeteren wanneer er geen andere handtekeningen op de aan de gebruiker geretourneerde transactie staan (zie POST-responstransactie).
Als de gebruikssituatie van een Actieaanbieder vereist dat hun backend-diensten de transactie vooraf ondertekenen vóór de gebruiker, dienen zij dit keypair te gebruiken als hun Actie-identiteit. Hierdoor hoeft er één account minder te worden opgenomen in de transactie, waardoor de totale transactiegrootte met 32 bytes wordt verkleind.
Actie-identificatiebericht
Het Actie-identificatiebericht is een met dubbele punten gescheiden UTF-8-tekenreeks die via een enkel SPL Memo-instructie in een transactie wordt opgenomen.
protocol:identity:reference:signature
protocol- De waarde van het gebruikte protocol (ingesteld opsolana-actionconform het URL-schema hierboven)identity- De waarde moet het base58-gecodeerde openbare-sleuteladres zijn van het Actie-identiteit keypairreference- De waarde moet een base58-gecodeerde 32-byte array zijn. Dit kunnen al dan niet publieke sleutels zijn, op of buiten de curve, en kunnen al dan niet overeenkomen met accounts op Solana.signature- base58-gecodeerde handtekening aangemaakt door het Actie-identiteit keypair dat alleen dereference-waarde ondertekent.
De reference-waarde mag slechts eenmaal en in één enkele transactie worden gebruikt. Voor
het doel van het koppelen van transacties aan een Actieaanbieder wordt alleen het eerste
gebruik van de reference-waarde als geldig beschouwd.
Transacties kunnen meerdere Memo-instructies bevatten. Bij het uitvoeren van
getSignaturesForAddress zal het memo-veld in de resultaten
het bericht van elke Memo-instructie retourneren als één tekenreeks, waarbij
elke instructie wordt gescheiden door een puntkomma.
Er mogen geen andere gegevens worden opgenomen in de Memo-instructie van het Identificatiebericht.
De identity en de reference dienen te worden opgenomen als alleen-lezen, niet-ondertekenende
sleutels
in de transactie op een instructie die NIET de Memo-instructie van het Identificatiebericht is.
De Memo-instructie van het Identificatiebericht moet nul accounts bevatten. Als er accounts worden opgegeven, vereist het Memo-programma dat deze accounts geldige ondertekenaars zijn. Voor de doeleinden van het identificeren van acties beperkt dit de flexibiliteit en kan dit de gebruikerservaring verslechteren. Daarom wordt dit beschouwd als een anti-patroon en must worden vermeden.
Verificatie van Actie-identiteit
Elke transactie die het identity-account bevat, kan verifieerbaar worden
gekoppeld aan de Actieaanbieder via een meerstapsproces:
- Haal alle transacties op voor een gegeven
identity. - Parseer en verifieer de memo-tekenreeks van elke transactie, en zorg dat de
signaturegeldig is voor de opgeslagenreference. - Verifieer dat de specifieke transactie de eerste onchain-aanwezigheid is van de
referenceonchain:- Als deze transactie de eerste aanwezigheid is, wordt de transactie als geverifieerd beschouwd en kan deze veilig worden toegeschreven aan de Actieaanbieder.
- Als deze transactie NIET de eerste aanwezigheid is, wordt deze als ongeldig beschouwd en daher niet toegeschreven aan de Actieaanbieder.
Omdat Solana validators transacties indexeren op basis van accountsleutels, kan de
getSignaturesForAddress RPC-methode
worden gebruikt om alle transacties met het identity-account te vinden.
De respons van deze RPC-methode bevat alle Memo-gegevens in het memo-veld. Als
meer dan één Memo-instructie is gebruikt in de transactie, wordt elk memo-bericht
opgenomen in dit memo-veld en moet het door de verificateur dienovereenkomstig worden geparseerd
om het Identiteitsverificatiebericht te verkrijgen.
Deze transacties dienen aanvankelijk als NIET-GEVERIFIEERD te worden beschouwd. Dit komt doordat
de identity niet verplicht is de transactie te ondertekenen, waardoor elke
transactie dit account als niet-ondertekenaar kan opnemen. Dit kan de attributie- en gebruikstellingen kunstmatig verhogen.
Het Identiteitsverificatiebericht moet worden gecontroleerd om te bevestigen dat de signature
is aangemaakt door de identity die de reference ondertekent. Als deze handtekeningverificatie
mislukt, is de transactie ongeldig en mag deze niet worden toegeschreven aan de
Actieaanbieder.
Als de handtekeningverificatie succesvol is, dient de verificateur te controleren of deze
transactie de eerste onchain-aanwezigheid van de reference is. Als dat niet het geval is,
wordt de transactie als ongeldig beschouwd.
Is this page helpful?