Tóm tắt
Một giao thức chuẩn để mã hóa các yêu cầu giao dịch Solana trong URL nhằm hỗ trợ thanh toán và các trường hợp sử dụng khác.
Sự đồng thuận sơ bộ về đặc tả này đã đạt được, và các triển khai đã tồn tại trong Phantom, FTX và Slope.
Tiêu chuẩn này lấy cảm hứng từ BIP 21 và EIP 681.
Động lực
Một giao thức URL chuẩn để yêu cầu chuyển SOL gốc, chuyển SPL Token và các giao dịch Solana cho phép trải nghiệm người dùng tốt hơn trên các ứng dụng và ví trong hệ sinh thái Solana.
Các URL này có thể được mã hóa trong mã QR hoặc thẻ NFC, hoặc được gửi giữa người dùng và ứng dụng để yêu cầu thanh toán và soạn thảo giao dịch.
Các ứng dụng nên đảm bảo rằng một giao dịch đã được xác nhận và hợp lệ trước khi họ phát hành hàng hóa hoặc dịch vụ đang bán, hoặc cấp quyền truy cập vào các đối tượng hoặc sự kiện.
Ví di động nên đăng ký xử lý lược đồ URL để cung cấp trải nghiệm liền mạch nhưng an toàn khi gặp các URL Solana Pay trong môi trường.
Bằng cách tiêu chuẩn hóa một phương pháp đơn giản để giải quyết những vấn đề này, chúng tôi đảm bảo khả năng tương thích cơ bản của các ứng dụng và ví để các nhà phát triển có thể tập trung vào các trừu tượng cấp cao hơn.
Đặc tả: Yêu cầu Chuyển khoản
URL yêu cầu chuyển khoản Solana Pay mô tả một yêu cầu không tương tác để chuyển SOL hoặc SPL Token.
solana:<recipient>?amount=<amount>&spl-token=<spl-token>&reference=<reference>&label=<label>&message=<message>&memo=<memo>
Yêu cầu này là không tương tác vì các tham số trong URL được ví sử dụng để trực tiếp soạn thảo một giao dịch.
Người nhận
Một trường recipient duy nhất là bắt buộc làm đường dẫn. Giá trị phải là
pubkey được mã hóa base58 của một tài khoản SOL gốc. associated token account
không được sử dụng.
Thay vào đó, để yêu cầu chuyển SPL Token, trường spl-token phải được sử dụng
để chỉ định một SPL Token mint, từ đó địa chỉ associated token account của người
nhận sẽ được suy ra.
Số lượng
Một trường amount duy nhất được phép làm tham số truy vấn tùy chọn. Giá trị
phải là số nguyên không âm hoặc số thập phân theo đơn vị "người dùng". Đối với
SOL, đó là SOL chứ không phải lamport. Đối với token, hãy sử dụng
uiAmountString chứ không phải amount.
0 là giá trị hợp lệ. Nếu giá trị là số thập phân nhỏ hơn 1, nó phải có số
0 đứng trước dấu .. Ký hiệu khoa học bị cấm.
Nếu không cung cấp giá trị, ví phải nhắc người dùng nhập số lượng. Nếu số chữ số thập phân vượt quá mức hỗ trợ cho SOL (9) hoặc SPL Token (tùy theo mint cụ thể), ví phải từ chối URL do định dạng không hợp lệ.
SPL Token
Một trường spl-token duy nhất được phép làm tham số truy vấn tùy chọn. Giá trị
phải là pubkey được mã hóa base58 của tài khoản SPL Token mint.
Nếu trường này được cung cấp, quy ước
Associated Token Account phải
được sử dụng, và ví phải bao gồm lệnh TokenProgram.Transfer hoặc
TokenProgram.TransferChecked làm lệnh cuối cùng của giao dịch.
Nếu trường này không được cung cấp, URL mô tả một giao dịch chuyển SOL gốc, và
ví phải bao gồm lệnh SystemProgram.Transfer làm lệnh cuối cùng của giao dịch.
Ví phải suy ra địa chỉ ATA từ các trường recipient và spl-token. Việc chuyển
đến các token account phụ không được hỗ trợ.
Tham chiếu
Nhiều trường reference được phép làm tham số truy vấn tùy chọn. Các giá trị
phải là mảng 32 byte được mã hóa base58. Chúng có thể là hoặc không phải là
pubkey, trên hoặc ngoài đường cong, và có thể tương ứng hoặc không tương ứng với
các tài khoản trên Solana.
Nếu các giá trị được cung cấp, ví phải bao gồm chúng theo thứ tự được cung cấp
dưới dạng khóa chỉ đọc, không phải người ký cho lệnh SystemProgram.Transfer
hoặc TokenProgram.Transfer/TokenProgram.TransferChecked trong giao dịch
thanh toán. Các giá trị có thể là duy nhất hoặc không duy nhất đối với yêu cầu
thanh toán, và có thể tương ứng hoặc không tương ứng với một tài khoản trên
Solana.
Do các validator Solana lập chỉ mục giao dịch theo các khóa tài khoản này, các
giá trị reference có thể được sử dụng làm ID khách hàng (ID có thể sử dụng
trước khi biết giao dịch thanh toán cuối cùng). Phương thức RPC
getSignaturesForAddress
có thể được sử dụng để định vị giao dịch theo cách này.
Nhãn
Một trường label duy nhất được phép làm tham số truy vấn tùy chọn. Giá trị
phải là một chuỗi UTF-8 được
mã hóa URL
mô tả nguồn của yêu cầu chuyển khoản.
Ví dụ, đây có thể là tên của một thương hiệu, cửa hàng, ứng dụng hoặc người đưa ra yêu cầu. Ví nên giải mã URL giá trị và hiển thị giá trị đã giải mã cho người dùng.
Thông báo
Một trường message duy nhất được phép làm tham số truy vấn tùy chọn. Giá trị
phải là một chuỗi UTF-8 được
mã hóa URL
mô tả bản chất của yêu cầu chuyển khoản.
Ví dụ, đây có thể là tên của một mặt hàng đang được mua, ID đơn hàng hoặc một lời cảm ơn. Ví nên giải mã URL giá trị và hiển thị giá trị đã giải mã cho người dùng.
Ghi chú
Một trường memo duy nhất được phép làm tham số truy vấn tùy chọn. Giá trị phải
là một chuỗi UTF-8 được
mã hóa URL
mà phải được bao gồm trong một lệnh SPL Memo
trong giao dịch thanh toán.
Ví phải giải mã URL giá trị và nên hiển thị giá trị đã giải mã cho người dùng. Ghi chú sẽ được ghi lại bởi các validator và không nên bao gồm thông tin riêng tư hoặc nhạy cảm.
Nếu trường này được cung cấp, ví phải bao gồm một lệnh MemoProgram làm lệnh
thứ hai từ cuối trong giao dịch, ngay trước lệnh chuyển SOL hoặc SPL Token, để
tránh sự mơ hồ với các lệnh khác trong giao dịch.
Ví dụ
URL mô tả yêu cầu chuyển 1 SOL
solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?amount=1&label=Michael&message=Thanks%20for%20all%20the%20fish&memo=OrderId12345
URL mô tả yêu cầu chuyển 0.01 USDC
solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?amount=0.01&spl-token=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
URL mô tả yêu cầu chuyển SOL (người dùng được yêu cầu nhập số lượng)
solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?label=Michael
Đặc tả: Yêu cầu Giao dịch
URL yêu cầu giao dịch Solana Pay mô tả một yêu cầu tương tác cho bất kỳ giao dịch Solana nào.
solana:<link>
Yêu cầu mang tính tương tác vì các tham số trong URL được ví sử dụng để thực hiện yêu cầu HTTP nhằm soạn thảo một giao dịch.
Liên kết
Một trường link duy nhất được yêu cầu làm đường dẫn. Giá trị phải là một URL
HTTPS tuyệt đối được
mã hóa URL
có điều kiện.
Nếu URL chứa các tham số truy vấn, nó phải được mã hóa URL. Các tham số truy vấn của giao thức có thể được thêm vào đặc tả này. Mã hóa URL giá trị này ngăn chặn xung đột với các tham số giao thức.
Nếu URL không chứa tham số truy vấn, nó không nên được mã hóa URL. Điều này tạo ra một URL ngắn hơn và mã QR ít dày đặc hơn.
Trong cả hai trường hợp, ví phải giải mã URL giá trị. Điều này không có hiệu lực nếu giá trị không được mã hóa URL. Nếu giá trị đã giải mã không phải là URL HTTPS tuyệt đối, ví phải từ chối nó vì không hợp lệ.
Yêu cầu GET
Ví nên thực hiện yêu cầu JSON GET qua HTTP đến URL. Yêu cầu không nên xác định
danh tính của ví hoặc người dùng.
Ví nên thực hiện yêu cầu với header Accept-Encoding, và ứng dụng nên phản hồi với header Content-Encoding để nén HTTP.
Ví nên hiển thị tên miền của URL khi yêu cầu đang được thực hiện.
Phản hồi GET
Ví phải xử lý các phản hồi HTTP
lỗi phía client,
lỗi phía server,
và
chuyển hướng.
Ứng dụng phải phản hồi với các trạng thái này, hoặc với phản hồi HTTP OK JSON
có body như sau:
{ "label": "<label>", "icon": "<icon>" }
Giá trị <label> phải là chuỗi UTF-8 mô tả nguồn gốc của yêu cầu giao dịch. Ví
dụ, đây có thể là tên thương hiệu, cửa hàng, ứng dụng hoặc người thực hiện yêu
cầu.
Giá trị <icon> phải là URL HTTP hoặc HTTPS tuyệt đối của hình ảnh biểu tượng.
Tệp phải là ảnh SVG, PNG hoặc WebP, nếu không ví phải từ chối vì không hợp
lệ.
Ví không nên lưu cache phản hồi ngoại trừ khi được chỉ định bởi HTTP caching trong response headers.
Ví nên hiển thị nhãn và render hình ảnh biểu tượng cho người dùng.
Yêu cầu POST
Ví phải thực hiện yêu cầu HTTP POST JSON đến URL với body như sau:
{ "account": "<account>" }
Giá trị <account> phải là khóa công khai được mã hóa base58 của tài khoản có
thể ký giao dịch.
Ví nên thực hiện yêu cầu với Accept-Encoding header, và ứng dụng nên phản hồi với Content-Encoding header để nén HTTP.
Ví nên hiển thị tên miền của URL khi yêu cầu đang được thực hiện. Nếu yêu cầu
GET đã được thực hiện, ví cũng nên hiển thị nhãn và render hình ảnh biểu tượng
từ phản hồi.
Phản hồi POST
Ví phải xử lý các phản hồi HTTP
lỗi phía client,
lỗi phía server,
và
chuyển hướng.
Ứng dụng phải phản hồi với các trạng thái này, hoặc với phản hồi HTTP OK JSON
có body như sau:
{ "transaction": "<transaction>" }
Giá trị <transaction> phải là một
giao dịch đã được tuần tự hóa
được mã hóa base64. Ví phải giải mã base64 giao dịch và
khử tuần tự hóa nó.
Ứng dụng có thể phản hồi bằng một giao dịch đã được ký một phần hoặc đầy đủ. Ví phải xác thực giao dịch như không đáng tin cậy.
Chữ Ký Rỗng
Nếu
signatures
của giao dịch rỗng:
- Ứng dụng nên đặt
feePayerthànhaccounttrong yêu cầu, hoặc giá trị không (new PublicKey(0)hoặcnew PublicKey("11111111111111111111111111111111")). - Ứng dụng nên đặt
recentBlockhashthành blockhash mới nhất, hoặc giá trị không (new PublicKey(0).toBase58()hoặc"11111111111111111111111111111111"). - Ví phải bỏ qua
feePayertrong giao dịch và đặtfeePayerthànhaccounttrong yêu cầu. - Ví phải bỏ qua
recentBlockhashtrong giao dịch và đặtrecentBlockhashthành blockhash mới nhất.
Nếu
signatures
của giao dịch không rỗng:
- Ứng dụng phải đặt
feePayerthành khóa công khai của chữ ký đầu tiên. - Ứng dụng phải đặt
recentBlockhashthành blockhash mới nhất. - Ứng dụng phải tuần tự hóa và khử tuần tự hóa giao dịch trước khi ký nó. Điều này đảm bảo thứ tự nhất quán của các khóa tài khoản, như một giải pháp tạm thời cho vấn đề này.
- Ví không được đặt
feePayervàrecentBlockhash. - Ví phải xác minh các chữ ký, và nếu có chữ ký nào không hợp lệ, ví phải từ chối giao dịch là không đúng định dạng.
Ví chỉ được ký giao dịch bằng account trong yêu cầu, và chỉ được thực hiện nếu
chữ ký cho account trong yêu cầu được yêu cầu.
Nếu bất kỳ chữ ký nào ngoài chữ ký cho account trong yêu cầu được yêu cầu, ví
phải từ chối giao dịch là độc hại.
Ứng dụng cũng có thể bao gồm trường message tùy chọn trong phần thân phản hồi:
{ "message": "<message>", "transaction": "<transaction>" }
Giá trị <message> phải là một chuỗi UTF-8 mô tả bản chất của phản hồi giao
dịch.
Ví dụ, đây có thể là tên của một mặt hàng đang được mua, một khoản chiết khấu được áp dụng cho giao dịch mua, hoặc một lời cảm ơn. Ví nên hiển thị giá trị này cho người dùng.
Ví và ứng dụng nên cho phép các trường bổ sung trong phần thân yêu cầu và phần thân phản hồi, có thể được thêm vào bởi các đặc tả trong tương lai.
Ví dụ
URL mô tả một yêu cầu giao dịch.
solana:https://example.com/solana-pay
URL mô tả một yêu cầu giao dịch với các tham số truy vấn.
solana:https%3A%2F%2Fexample.com%2Fsolana-pay%3Forder%3D12345
Yêu cầu GET
GET /solana-pay?order=12345 HTTP/1.1Host: example.comConnection: closeAccept: application/jsonAccept-Encoding: br, gzip, deflate
Phản hồi GET
HTTP/1.1 200 OKConnection: closeContent-Type: application/jsonContent-Length: 62Content-Encoding: gzip{"label":"Michael Vines","icon":"https://example.com/icon.svg"}
Yêu cầu POST
POST /solana-pay?order=12345 HTTP/1.1Host: example.comConnection: closeAccept: application/jsonAccept-Encoding: br, gzip, deflateContent-Type: application/jsonContent-Length: 57{"account":"mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN"}
Phản hồi POST
HTTP/1.1 200 OKConnection: closeContent-Type: application/jsonContent-Length: 298Content-Encoding: gzip{"message":"Thanks for all the fish","transaction":"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAECC4JMKqNplIXybGb/GhK1ofdVWeuEjXnQor7gi0Y2hMcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQECAAAMAgAAAAAAAAAAAAAA"}
Tiện ích mở rộng
Các định dạng và trường bổ sung có thể được tích hợp vào đặc tả này để kích hoạt các trường hợp sử dụng mới trong khi vẫn đảm bảo khả năng tương thích với các ứng dụng và ví.
Vui lòng mở một vấn đề trên Github để đề xuất các thay đổi cho đặc tả nhằm thu thập phản hồi từ các nhà phát triển ứng dụng và ví.
Is this page helpful?