Zusammenfassung
Ein Standardprotokoll zur Kodierung von Solana-Transaktionsanfragen in URLs, um Zahlungen und andere Anwendungsfälle zu ermöglichen.
Dieser Standard ist inspiriert von BIP 21 und EIP 681.
Motivation
Ein Standard-URL-Protokoll für die Anforderung nativer SOL-Überweisungen, SPL-Token- Überweisungen und Solana-Transaktionen ermöglicht eine bessere Benutzererfahrung über Apps und Wallets im Solana-Ökosystem hinweg.
Diese URLs können in QR-Codes oder NFC-Tags kodiert oder zwischen Nutzern und Anwendungen gesendet werden, um Zahlungen anzufordern und Transaktionen zu erstellen.
Anwendungen sollten sicherstellen, dass eine Transaktion bestätigt wurde und gültig ist, bevor sie Waren oder Dienstleistungen freigeben oder Zugang zu Objekten oder Veranstaltungen gewähren.
Mobile Wallets sollten sich registrieren, um das URL-Schema zu verarbeiten und so eine nahtlose und dennoch sichere Erfahrung zu bieten, wenn Solana Pay URLs in der Umgebung angetroffen werden.
Durch die Standardisierung eines einfachen Ansatzes zur Lösung dieser Probleme stellen wir grundlegende Kompatibilität von Anwendungen und Wallets sicher, sodass sich Entwickler auf höhere Abstraktionsebenen konzentrieren können.
Spezifikation: Überweisungsanfrage
Eine Solana Pay Überweisungsanfrage-URL beschreibt eine nicht-interaktive Anfrage für eine SOL- oder SPL-Token-Überweisung.
solana:<recipient>?amount=<amount>&spl-token=<spl-token>&reference=<reference>&label=<label>&message=<message>&memo=<memo>
Die Anfrage ist nicht-interaktiv, da die Parameter in der URL von einer Wallet verwendet werden, um direkt eine Transaktion zu erstellen.
Empfänger
Ein einzelnes recipient-Feld ist als Pfadname erforderlich. Der Wert muss der
base58-kodierte öffentliche Schlüssel eines nativen SOL-Konten sein. Associated
Token Accounts dürfen nicht verwendet werden.
Um stattdessen eine SPL-Token-Überweisung anzufordern, muss das spl-token-Feld
verwendet werden, um eine SPL-Token-Mint anzugeben, von der die associated token
account-Adresse des Empfängers abgeleitet werden muss.
Betrag
Ein einzelnes amount-Feld ist als optionaler Abfrageparameter zulässig. Der
Wert muss eine nicht-negative ganze Zahl oder Dezimalzahl in
„Benutzer“-Einheiten sein. Bei SOL sind das SOL und nicht Lamports. Verwenden
Sie bei Token
uiAmountString und nicht amount.
0 ist ein gültiger Wert. Wenn der Wert eine Dezimalzahl kleiner als 1 ist,
muss vor dem . eine führende 0 stehen. Wissenschaftliche Notation ist nicht
zulässig.
Wenn kein Wert angegeben wird, muss die Wallet den Benutzer zur Eingabe des Betrags auffordern. Wenn die Anzahl der Dezimalstellen die für SOL (9) oder das SPL-Token (Mint-spezifisch) unterstützte Anzahl überschreitet, muss die Wallet die URL als fehlerhaft ablehnen.
SPL-Token
Ein einzelnes spl-token-Feld ist als optionaler Abfrageparameter zulässig. Der
Wert muss der base58-kodierte öffentliche Schlüssel eines SPL-Token-Mint-Kontos
sein.
Wenn das Feld angegeben wird, muss die
Associated Token Account-Konvention
verwendet werden, und die Wallet muss eine TokenProgram.Transfer- oder
TokenProgram.TransferChecked- Anweisungen als letzte Anweisung der Transaktion
einfügen.
Wenn das Feld nicht angegeben wird, beschreibt die URL eine native
SOL-Übertragung, und die Wallet muss stattdessen eine SystemProgram.Transfer-
Anweisungen als letzte Anweisung der Transaktion einfügen.
Die Wallet muss die ATA-Adresse aus den Feldern recipient und spl-token
ableiten. Überweisungen an zusätzliche Token-Konten werden nicht unterstützt.
Referenz
Mehrere reference-Felder sind als optionale Abfrageparameter zulässig. Die
Werte müssen base58-kodierte 32-Byte-Arrays sein. Diese können öffentliche
Schlüssel sein oder auch nicht, auf oder außerhalb der Kurve, und können Konten
auf Solana entsprechen oder auch nicht.
Wenn die Werte bereitgestellt werden, muss die Wallet sie in der angegebenen
Reihenfolge als schreibgeschützte, nicht signierende Schlüssel in die
SystemProgram.Transfer- oder
TokenProgram.Transfer/TokenProgram.TransferChecked-Anweisung in der
Zahlungstransaktion einfügen. Die Werte können, müssen aber nicht eindeutig für
die Zahlungsanforderung sein und können, müssen aber nicht einem Konto auf
Solana entsprechen.
Da Solana-Validatoren Transaktionen anhand dieser Kontoschlüssel indizieren,
können reference-Werte als Client-IDs verwendet werden (IDs, die verwendet
werden können, bevor die endgültige Zahlungstransaktion bekannt ist). Die
RPC-Methode
getSignaturesForAddress
kann verwendet werden, um Transaktionen auf diese Weise zu lokalisieren.
Beschriftung
Ein einzelnes label-Feld ist als optionaler Abfrageparameter zulässig. Der
Wert muss eine
URL-kodierte
UTF-8-Zeichenkette sein, die die Quelle der Übertragungsanforderung beschreibt.
Dies könnte beispielsweise der Name einer Marke, eines Geschäfts, einer Anwendung oder einer Person sein, die die Anforderung stellt. Die Wallet sollte den Wert URL-dekodieren und den dekodierten Wert dem Benutzer anzeigen.
Nachricht
Ein einzelnes message-Feld ist als optionaler Abfrageparameter zulässig. Der
Wert muss eine
URL-kodierte
UTF-8-Zeichenkette sein, die die Art der Übertragungsanforderung beschreibt.
Dies könnte beispielsweise der Name eines zu kaufenden Artikels, eine Bestellnummer oder eine Danksagung sein. Die Wallet sollte den Wert URL-dekodieren und den dekodierten Wert dem Benutzer anzeigen.
Memo
Ein einzelnes memo-Feld ist als optionaler Abfrageparameter zulässig. Der Wert
muss eine
URL-kodierte
UTF-8-Zeichenkette sein, die in einer
SPL Memo-Anweisung in der Zahlungstransaktion
enthalten sein muss.
Die Wallet muss den Wert URL-dekodieren und sollte den dekodierten Wert dem Benutzer anzeigen. Das Memo wird von Validatoren aufgezeichnet und sollte keine privaten oder sensiblen Informationen enthalten.
Falls das Feld angegeben wird, muss die Wallet eine MemoProgram-Anweisung als
vorletzte Anweisung der Transaktion einfügen, unmittelbar vor der SOL- oder
SPL-Token-Transferanweisung, um Mehrdeutigkeiten mit anderen Anweisungen in der
Transaktion zu vermeiden.
Beispiele
URL, die eine Transferanfrage für 1 SOL beschreibt
solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?amount=1&label=Michael&message=Thanks%20for%20all%20the%20fish&memo=OrderId12345
URL, die eine Transferanfrage für 0,01 USDC beschreibt
solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?amount=0.01&spl-token=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
URL, die eine Transferanfrage für SOL beschreibt (Benutzer wird nach Betrag gefragt)
solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?label=Michael
Spezifikation: Transaktionsanfrage
Eine Solana Pay-Transaktionsanfrage-URL beschreibt eine interaktive Anfrage für jede beliebige Solana-Transaktion.
solana:<link>
Die Anfrage ist interaktiv, da die Parameter in der URL von einer Wallet verwendet werden, um eine HTTP-Anfrage zur Zusammenstellung einer Transaktion zu stellen.
Link
Ein einzelnes link-Feld ist als Pfadname erforderlich. Der Wert muss eine
bedingt
URL-kodierte
absolute HTTPS-URL sein.
Falls die URL Query-Parameter enthält, muss sie URL-kodiert sein. Protokoll-Query-Parameter können dieser Spezifikation hinzugefügt werden. Die URL-Kodierung des Werts verhindert Konflikte mit Protokollparametern.
Falls die URL keine Query-Parameter enthält, sollte sie nicht URL-kodiert sein. Dies erzeugt eine kürzere URL und einen weniger dichten QR-Code.
In jedem Fall muss die Wallet den Wert URL-dekodieren. Dies hat keine Auswirkung, wenn der Wert nicht URL-kodiert ist. Falls der dekodierte Wert keine absolute HTTPS-URL ist, muss die Wallet ihn als fehlerhaft ablehnen.
GET-Anfrage
Die Wallet sollte eine HTTP-GET-JSON-Anfrage an die URL stellen. Die Anfrage
sollte weder die Wallet noch den Benutzer identifizieren.
Die Wallet sollte die Anfrage mit einem Accept-Encoding-Header stellen, und die Anwendung sollte mit einem Content-Encoding-Header für HTTP-Komprimierung antworten.
Das Wallet sollte die Domain der URL anzeigen, während die Anfrage durchgeführt wird.
GET-Antwort
Das Wallet muss HTTP-
Client-Fehler,
Server-Fehler
und
Weiterleitungsantworten
verarbeiten. Die Anwendung muss mit diesen oder mit einer HTTP OK JSON-Antwort
mit folgendem Body antworten:
{ "label": "<label>", "icon": "<icon>" }
Der <label>-Wert muss eine UTF-8-Zeichenkette sein, die die Quelle der
Transaktionsanfrage beschreibt. Dies könnte beispielsweise der Name einer Marke,
eines Geschäfts, einer Anwendung oder einer Person sein, die die Anfrage stellt.
Der <icon>-Wert muss eine absolute HTTP- oder HTTPS-URL eines Icon-Bildes
sein. Die Datei muss ein SVG-, PNG- oder WebP-Bild sein, andernfalls muss das
Wallet sie als fehlerhaft ablehnen.
Das Wallet sollte die Antwort nicht zwischenspeichern, außer dies wird durch HTTP-Caching- Antwort-Header angewiesen.
Das Wallet sollte das Label anzeigen und das Icon-Bild für den Benutzer darstellen.
POST-Anfrage
Das Wallet muss eine HTTP POST JSON-Anfrage an die URL mit folgendem Body
senden:
{ "account": "<account>" }
Der <account>-Wert muss der base58-kodierte öffentliche Schlüssel eines Kontos
sein, das die Transaktion signieren darf.
Das Wallet sollte die Anfrage mit einem Accept-Encoding-Header senden, und die Anwendung sollte mit einem Content-Encoding-Header für HTTP-Komprimierung antworten.
Das Wallet sollte die Domain der URL anzeigen, während die Anfrage durchgeführt
wird. Wenn eine GET-Anfrage durchgeführt wurde, sollte das Wallet außerdem das
Label anzeigen und das Icon-Bild aus der Antwort darstellen.
POST-Antwort
Das Wallet muss HTTP-
Client-Fehler,
Server-Fehler
und
Weiterleitungsantworten
verarbeiten. Die Anwendung muss mit diesen oder mit einer HTTP OK JSON-Antwort
mit folgendem Body antworten:
{ "transaction": "<transaction>" }
Der <transaction>-Wert muss eine base64-kodierte
serialisierte Transaktion
sein. Die Wallet muss die Transaktion base64-dekodieren und
deserialisieren.
Die Anwendung kann mit einer teilweise oder vollständig signierten Transaktion antworten. Die Wallet muss die Transaktion als nicht vertrauenswürdig validieren.
Leere Signaturen
Wenn die Transaktions-
signatures
leer sind:
- Die Anwendung sollte den
feePayerauf denaccountin der Anfrage oder auf den Nullwert (new PublicKey(0)odernew PublicKey("11111111111111111111111111111111")) setzen. - Die Anwendung sollte den
recentBlockhashauf den neuesten Blockhash oder auf den Nullwert (new PublicKey(0).toBase58()oder"11111111111111111111111111111111") setzen. - Die Wallet muss den
feePayerin der Transaktion ignorieren und denfeePayerauf denaccountin der Anfrage setzen. - Die Wallet muss den
recentBlockhashin der Transaktion ignorieren und denrecentBlockhashauf den neuesten Blockhash setzen.
Nicht-leere Signaturen
Wenn die Transaktions-
signatures
nicht leer sind:
- Die Anwendung muss den
feePayerauf den öffentlichen Schlüssel der ersten Signatur setzen. - Die Anwendung muss den
recentBlockhashauf den neuesten Blockhash setzen. - Die Anwendung muss die Transaktion vor dem Signieren serialisieren und deserialisieren. Dies gewährleistet eine konsistente Reihenfolge der Kontoschlüssel als Workaround für dieses Problem.
- Die Wallet darf den
feePayerund denrecentBlockhashnicht setzen. - Die Wallet muss die Signaturen überprüfen, und falls welche ungültig sind, muss die Wallet die Transaktion als fehlerhaft ablehnen.
Die Wallet darf die Transaktion nur mit dem account in der Anfrage signieren,
und muss dies nur tun, wenn eine Signatur für den account in der Anfrage
erwartet wird.
Falls irgendeine Signatur außer einer Signatur für den account in der Anfrage
erwartet wird, muss die Wallet die Transaktion als bösartig ablehnen.
Optionales Nachrichtenfeld
Die Anwendung kann auch ein optionales message-Feld im Antwortkörper
enthalten:
{ "message": "<message>", "transaction": "<transaction>" }
Der <message>-Wert muss eine UTF-8-Zeichenkette sein, die die Art der
Transaktionsantwort beschreibt.
Dies könnte beispielsweise der Name eines gekauften Artikels, ein auf den Kauf angewendeter Rabatt oder eine Danksagung sein. Das Wallet sollte den Wert dem Benutzer anzeigen.
Das Wallet und die Anwendung sollten zusätzliche Felder im Anfragekörper und Antwortkörper zulassen, die durch zukünftige Spezifikationen hinzugefügt werden können.
Beispiele
URL zur Beschreibung einer Transaktionsanfrage
solana:https://example.com/solana-pay
URL zur Beschreibung einer Transaktionsanfrage mit Abfrageparametern
solana:https%3A%2F%2Fexample.com%2Fsolana-pay%3Forder%3D12345
GET-Anfrage-Beispiel
GET /solana-pay?order=12345 HTTP/1.1Host: example.comConnection: closeAccept: application/jsonAccept-Encoding: br, gzip, deflate
GET-Antwort-Beispiel
HTTP/1.1 200 OKConnection: closeContent-Type: application/jsonContent-Length: 62Content-Encoding: gzip{"label":"Michael Vines","icon":"https://example.com/icon.svg"}
POST-Anfrage-Beispiel
POST /solana-pay?order=12345 HTTP/1.1Host: example.comConnection: closeAccept: application/jsonAccept-Encoding: br, gzip, deflateContent-Type: application/jsonContent-Length: 57{"account":"mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN"}
POST-Antwort-Beispiel
HTTP/1.1 200 OKConnection: closeContent-Type: application/jsonContent-Length: 298Content-Encoding: gzip{"message":"Thanks for all the fish","transaction":"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAECC4JMKqNplIXybGb/GhK1ofdVWeuEjXnQor7gi0Y2hMcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQECAAAMAgAAAAAAAAAAAAAA"}
Erweiterungen
Zusätzliche Formate und Felder können in diese Spezifikation aufgenommen werden, um neue Anwendungsfälle zu ermöglichen und gleichzeitig die Kompatibilität mit Apps und Wallets sicherzustellen.
Bitte öffnen Sie ein Github-Issue, um Änderungen an der Spezifikation vorzuschlagen und Feedback von Anwendungs- und Wallet-Entwicklern einzuholen.
Ein tatsächliches Beispiel für einen solchen Vorschlag.
Siehe auch
- Solana Pay Spezifikation v1.1 - Neueste Version mit Verbesserungen
- Schnellstart-Anleitung - Implementierungs- anleitungen
- GitHub-Repository - Referenzimplementierungen
Is this page helpful?