
Solana Developer Hub #1: Solana Pay 入門
この記事は2023/12/1に開催したSolana Developer Hub #1で行われた「Solana Pay 入門」をテキスト化したものになります。
Solana Pay 入門

はい、それではSolana Payについて話をしていきたいと思います。

Solana大好きおじさんやってます。最近はSolanaのことばかりツイートしたり、記事を書いたりしてます

皆さん、Solana Payご存知でしょうか。今年にShopifyでサポートされたSolanaで支払いができますという機能が出ました。

エンジニア的にはソリューション自体には関心はなくて、ここで関心があるのはSolana PayというSolanaチェーンを使用して、トークンによる支払いを行うための決済プロトコルです。
このプロトコルとしてのSolana Payというのは、例えばURLやQRコード、NFCタグを使って直接ウォレットを開いて支払いができるというものになります。

Solana Payの仕様をこちらに書かれているので、興味がある方は読まれるのをおすすめします。
この仕様のモチベーションのとこに書いてある話ですが、BIP-21とERC-681を元にSolana Payの仕様は作られています。そのため、元になっているビットコイン、イーサリアム系のソリューションはあると思いますので興味がある方は探してみてください。
また、そこまで凝った仕様でもないので他のチェーンでも実装可能なプロトコルだと思います。
このSolana Payというのは二つのリクエストを作る仕様にわかれます。一つがTransaction Request。もう一つがTransfer Requestという、この2種類のリクエストのどちらかを作ることで実装することができます。
Transaction Request


Transaction Requestは solana:<link> という文字列を扱う仕様になります。例えば、 solana:https://example.com とか、そういったリンクを扱う仕様ですね。

全体像はこの図の形になります。
図の右側のGenerate solana:<link> の部分は何を使って生成しても構いません。形式も何でも良く、ただの文字列から、URL、QRコード、NFCタグでも構いません。おそらく今後出てくる文字列を扱える規格なら何にでも対応できると思います。
ここの肝が solana: という部分で、よくモバイルアプリで使われるディープリンクの仕様に基づいています。そのため solana: で始まる文字列を読み込んだらウォレットを開いて、ウォレットがその後の文字列を処理してくれる動きになります。
ウォレット側の実装としては、solana:<link> の <link> のURLに対してGETリクエストするとトランザクションページに表示するラベルとアイコンが取得可能になります。
<link> のURLに対してPOSTリクエストをすると、シリアライズされたトランザクションが取得できます。それをウォレットでデシリアライズしてSolanaネットワークに送信すると、Solanaのトークンで支払いができます。
この流れを見てわかる通り、Solana Payの仕様は、かなりウォレットに頑張ってもらってる仕様になります。

少し先に説明してしまいましたが、ポイントはウォレットの仕様の部分です。
もし、Solana Payを使ったソリューション作りたい方は、このGET/POSTの2つのリンクのエンドポイントを作るだけでできます。
この、Solana Payの仕様の面白いところが、POSTリクエストで返すトランザクションは特に何も決まっていないところです。例えば、feeの支払いを事業者側がやる、顧客はSOLで送信するけど、事業者はUSDCで受け取るなどもできます。もっと複雑なこともできるとは思っていて、NFTのMintのトランザクションを返すとかもできると思います。

このTransaction Requestの仕様は自由度が高いです。ただし、デメリットとしてサーバーが必要になります。
Transaction Requestは、在庫管理とかあるオフチェーンとの連動があるユースケースが向いています。
フローの中でサーバーで処理するタイミングがあるため、そこで在庫の仮予約をして在庫を制御する、トランザクションの書き込みを監視して完了したら実際に在庫を減らす処理を行うとか、こういった連動させるタイミングを仕込みやすいです。
Transfer Request

次にTransfer Requestです。こちらは少し複雑な文字列を扱いますがサーバーを介さずにウォレットだけで完結します。

Transfer Requestでは solana:<recipient> という文字列を扱います。こちらでは <recipient> のあとにいくつかパラメータを指定して複雑な指定を行えます。

全体のフローとしてはTransaction Requestと同様に、 solana:<recipient> という文字列を作り、ウォレットでトランザクションを生成します。そのトランザクションを承認して、Solanaネットワークに送信することで支払いが可能になります。

作成する文字列の完全な書式はこちらになります。
recipientに送信先のウォレットのアドレスが入ります。
amountに何件送るのか、spl-tokenにトークンの種類としてトークンのプログラムアドレス、referenceにトランザクションを識別して後で検索するための一意なキー、labelはウォレット上に表示するラベルになります。
こう見てわかる通り、Transaction Requestと比べてTransfer Requestは指定できるものが決まってしまっています。そのため、こちらはトークンの転送に特化した仕様になっています。

そのため、クライアントとオンチェーンに閉じるようなユースケースで、転送のみを行いたいときはTransfer Requestが向いてます。
例えば在庫管理が不要だったり、展示会や即売会などでの販売ではこちらの方が合ってると思ってます。
ただ、Transaction Requestと比べると複雑なことはできないため、ユースケースに合うのかどうかは注意するポイントになります。
まとめ


SolanaPayの仕様というのは、三つの仕様から成り立ってます。
solana:で始まる文字列を作る仕様
solana:で始まる文字列を扱う仕様
トランザクションを返すサーバーの仕様
この観点で仕様を読んでいただくとわかりやすいかと思います。

いくつか、他にも参考になる情報を紹介しておきますのでご参考にしてください。
