Tóm tắt
Một giao thức tiêu 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.
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 tiêu 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 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.
Các 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 các 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 lớp 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 không tương tác vì các tham số trong URL được ví sử dụng để soạn thảo trực tiếp một giao dịch.
Người nhận
Một trường recipient duy nhất được yêu cầu làm pathname. Giá trị phải là khóa
công khai được mã hóa base58 của một tài khoản SOL gốc. Không được sử dụng
associated token account.
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ỉ token liên kết của người nhận phải
đượ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à một số nguyên không âm hoặc số thập phân tính 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à một giá trị hợp lệ. Nếu giá trị là số thập phân nhỏ hơn 1, nó phải có
0 đứng trước .. 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 được hỗ trợ cho SOL (9) hoặc SPL Token (tùy theo mint cụ thể), ví phải từ chối URL vì không đúng định dạng.
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 một mint account SPL Token.
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 một 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ả việc chuyển SOL gốc, và ví phải
bao gồm một 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. Những giá trị này có thể là hoặc không
phải là pubkey, nằm 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ự đã cho dưới
dạng khóa chỉ đọc, không ký vào 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.
Vì 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 để xác định vị trí giao dịch theo cách này.
Nhãn
Một trường label duy nhất được cho 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 gốc 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.
Tin nhắn
Một trường message duy nhất được cho 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 cho 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 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 của giao dịch, ngay trước lệnh chuyển SOL hoặc SPL Token, để
tránh sự nhầm lẫn với các lệnh khác trong giao dịch.
Ví dụ
URL mô tả yêu cầu chuyển khoả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 khoản 0.01 USDC
solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?amount=0.01&spl-token=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
URL mô tả yêu cầu chuyển khoản SOL (người dùng được yêu cầu nhập số tiền)
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 này 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 giao dịch.
Liên kết
Một trường link duy nhất là bắt buộc 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 giao thức có thể được thêm vào đặc tả này. Việc mã hóa URL giá trị này ngăn ngừa xung đột với các tham số giao thức.
Nếu URL không chứa các tham số truy vấn, nó không nên được mã hóa URL. Điều này tạo ra 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ị này. Việc này không có hiệu lực nếu giá trị chưa đượ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ì sai định dạng.
Yêu cầu GET
Ví nên thực hiện yêu cầu JSON HTTP GET đến URL. Yêu cầu này không nên xác định
ví hoặc người dùng.
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í phải hiển thị tên miền của URL trong 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 mã này, hoặc với phản hồi JSON HTTP OK 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 nó là không hợp
lệ.
Ví không nên lưu cache phản hồ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 JSON HTTP POST đến URL với body như sau:
{ "account": "<account>" }
Giá trị <account> phải là public key đượ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 trong khi yêu cầu đang được thực hiện. Nếu một
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 mã này, hoặc với phản hồi JSON HTTP OK 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à
giải tuần tự hóa nó.
Ứng dụng có thể phản hồi với một giao dịch đã được ký một phần hoặc hoàn toàn. Ví phải xác thực giao dịch như không đáng tin cậy.
Chữ Ký Trống
Nếu
signatures
của giao dịch trống:
- Ứng dụng nên đặt
feePayerthànhaccounttrong yêu cầu, hoặc giá trị bằng 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ị bằng 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.
Chữ Ký Không Trống
Nếu
signatures
của giao dịch không trố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à giải 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 vì không đúng định dạng.
Ví chỉ được ký giao dịch với account trong yêu cầu, và chỉ được làm như vậy
nếu một chữ ký cho account trong yêu cầu được yêu cầu.
Nếu có 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 vì độc hại.
Trường Thông Điệp Tùy Chọn
Ứng dụng cũng có thể bao gồm một trường message tùy chọn trong nội dung 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, giảm giá đượ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 nội dung yêu cầu và nội dung phản hồi, có thể được thêm vào bởi các đặc tả trong tương lai.
Các 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
Ví Dụ Yêu Cầu GET
GET /solana-pay?order=12345 HTTP/1.1Host: example.comConnection: closeAccept: application/jsonAccept-Encoding: br, gzip, deflate
Ví Dụ 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"}
Ví Dụ 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"}
Ví Dụ 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"}
Các Phần 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 đảm bảo tương thích với các ứng dụng và ví.
Vui lòng mở một Github issue để đề 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í.
Một ví dụ thực tế về đề xuất như vậy.
Xem Thêm
- Đặc Tả Solana Pay v1.1 - Phiên bản mới nhất với các cải tiến
- Hướng Dẫn Bắt Đầu Nhanh - Hướng dẫn triển khai
- Kho GitHub - Các triển khai tham chiếu
Is this page helpful?