新着:HeliusがLight Protocolを買収
Solana Payガイド
ブログ/開発

Solana Pay:知っておくべきこと

開発者体験エンジニアXのOwen VenterLinkedInのOwen Venter
読了時間:8分

Solanaブロックチェーン上に構築されたSolana Payは、URL内のトランザクションを簡素化するための共通言語です。即時トランザクションと1セント未満の手数料により、決済をよりスムーズにし、ユーザー体験を向上させる新しい方法を提供します。

これらのURLは、QRコードやNFCタグに変換したり、決済やトランザクションの設定が必要なときにユーザーやアプリ間で共有したりできる、特別なWebアドレスだと考えてください。これにより、Solanaトランザクションの利用プロセス全体が、よりシームレスかつ安全になります。

Solana Payの仕組み

Solana Payは、ユーザーがスマートコントラクトを操作し、トークンを転送するための新しい方法を提供します。ウォレットを接続する代わりに、リンク経由でトランザクションを確認して署名できます。これにより、操作のためにウォレットを接続する必要がなくなります。単純な決済にもアプリとのやり取りにも使用でき、トランザクションリクエストと転送リクエストの両方に対応できます。

Solana Payの主な機能はTransfer Requestです。これは、SOLまたはSPLトークンを転送するための非対話型リクエストです。すべてのSolanaウォレットがこの形式に対応しているわけではありませんが、主要なウォレットの多く(Phantom、Solflare、Glow)は対応しています。Solana Payの転送リクエストURLは次のようになります。

コード
solana:<recipient>?amount=<amount>&spl-token=<spl-token>&reference=<reference>&label=<label>&message=<message>&memo=<memo>

URL内のパラメータは、ウォレットがトランザクションを直接構成するために使用します。このガイドではTransfer Requestに焦点を当てますが、ほぼすべてのSolanaトランザクションを有効なSolana Pay URLに変換できる点も重要です。

パラメータ

各パラメータを詳しく見ていきましょう。

受取人:

SOLの送信先となる相手の公開鍵です。SPLトークンの転送では、spl-tokenフィールドにトークンの種類を指定します。ウォレットはこの情報を使用して、実際の転送先アカウントを特定します。

金額

送信するSOLまたはトークンの数量です。1未満の場合は、小数点の前に0を付ける必要があります。金額が指定されていない場合、ウォレットが入力を求めます。SOLを転送する場合、この金額はlamportsではなくSOL単位です。

SPLトークン

特定の種類のSPLトークンアカウントのミントアドレスを表す任意フィールドです。指定しない場合、トランザクションは通常のSOL転送になります。

参照情報

トランザクションにエンコードされる一意の識別子です。特定のトランザクションを見つけ、トランザクション結果を検証するために使用します。

ラベル

転送リクエストの送信元を示す短い説明です。店舗名やアプリ名などを指定できます。ウォレットはこれをユーザーに表示し、トランザクションに関する情報を提供します。

メッセージ

転送が行われる理由の詳細を格納する、エンコードされたURLです。購入する商品、注文ID、簡単なメモなどを含められます。ウォレットがユーザーにより詳しい情報を提供するためにも使用されます。

メモ

決済トランザクションに含まれるメモです。オンチェーンに保存されるため、個人情報や機密情報を含めないでください。

これらの詳細情報により、トランザクションを完全に制御でき、ウォレットと受取人のやり取りがシンプルになります。セキュリティのため、アプリはトランザクションがオンチェーンで確定した後にのみ処理する必要があります。

Solana Pay:URLの例

0.5 SOLを送信する場合:

コード
solana:CckxW6C1CjsxYcXSiDbk7NYfPLhfqAm3kSB5LEZunnSE?amount=0.5&label=Amazon&message=Thanks%20for%20shopping%20at%20Amazon&memo=ID321

5 USDCを送信する場合:

コード
solana:CckxW6C1CjsxYcXSiDbk7NYfPLhfqAm3kSB5LEZunnSE?amount=5&spl-token=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v

Solana Pay:Next.jsでの実装

何を構築するのでしょうか?このチュートリアルを完了すると、ユーザーが入力したデータ(ウォレットアドレスとSOLの金額)からSolana Pay QRコードを生成するWebアプリが完成します。また、ブロックチェーン上のトランザクションステータスを確認し、決済状況を表示します。

前提条件

  • マシンにNode.jsがインストールされている必要があります
  • ReactとTypeScriptを十分に理解している必要があります。
  • 資金を送受信するにはSolanaウォレットが必要です。
  • オンチェーン処理にはHelius APIキーも必要です。ウォレットがあれば、開発者ポータルからHelius APIキーを無料で取得できます。

手順

以下の手順に従って、Next.jsでSolana Payを使用します。

Next.jsアプリを作成する

まずNodeがインストールされていることを確認し、Next.jsアプリを作成します。ターミナルに次のコマンドを入力してください。

コード
npx create-next-app@latest sol-pay-app

‍続いていくつかの質問が表示されるので、次のオプションを選択してください。

作成が完了したら、次のコマンドでディレクトリに移動できます。

コード
cd sol-pay-app

ディレクトリ内で、次のコマンドを実行してアプリを起動できます。

コード
npm run dev

http://localhost:3000/ にアクセスすると、アプリを確認できます。

パッケージをインストールする

このアプリには、Solana web3.jsとSolana Payの2つのパッケージが必要です。また、トランザクションリンクのQRコード版を生成するために、「react-qr-code」というパッケージも使用します。

次のコマンドを実行して、これらのパッケージをインストールできます。

コード
npm install @solana/pay @solana/web3.js bignumber.js react-qr-code --save

フロントエンドを作成する

Solana Pay QRコードを表示し、SOLの受取先アドレスとSOLの金額を編集できるフロントエンドを作成します。安全上の理由から、すべてのロジック、特に金額と受取人の設定はバックエンドで処理することをお勧めします。

ただし、ここではシンプルにするため、アプリのロジックもフロントエンドで処理します。

  1. pagesディレクトリに移動し、index.tsxファイルを開きます。このファイルがホームページを表します。既存のコードを次のコードに置き換えてください。
コード
export default function Home() {
  return (
    <div className="flex flex-col items-center justify-center min-h-screen bg-gray-100">
      <h1 className="mb-6 text-3xl font-bold text-orange-700">
        Helius Solana Pay Demo
      </h1>
    </div>
  );
}
  1. ページ上部にimport文を追加します。
コード
// imports
import {Cluster,clusterApiUrl,Connection,PublicKey,Keypair} from "@solana/web3.js";
import { encodeURL, createQR,findReference, FindReferenceError, validateTransfer } from "@solana/pay";
import BigNumber from "bignumber.js";
import { useState } from "react";
import QRCode from "react-qr-code";
  1. Helius RPC URLを格納する変数を作成します。このアプリをデプロイする場合は、ENVファイルまたはプロキシを使用してAPIキーを隠してください。
コード
// get a free Helius RPC at helius.dev
 const RPC="https://rpc.helius.xyz/?api-key="!
  1. Helius RPC URLを使用してSolana Connectionオブジェクトを作成します。
コード
console.log('Connecting to the Solana network\n');
const connection = new Connection(RPC, 'confirmed');
  1. 次に、使用する変数を宣言して初期化します。これには、Solana Pay URLに必要なすべての変数が含まれます。これらの変数はHome()関数内で作成できます。
コード
// URL Variables
  const [address, setAddress] = useState("");
  const [recipient, setRecipient] = useState(
    new PublicKey("CckxW6C1CjsxYcXSiDbk7NYfPLhfqAm3kSB5LEZunnSE"));
  const [amount, setAmount] = useState(new BigNumber(1));
  const [message, setMessage] = useState("Helius Demo Order");
  const reference = new Keypair().publicKey;
  const label = "Helius Super Store";
  const memo = "Helius#4098";

  // for the QR code
  const [qrCodeValue, setQrCodeValue] = useState('');
  const [paymentStatus, setPaymentStatus] = useState('');
  1. 次に、決済を作成する関数を記述します。この関数は入力フィールドから変数を取得し、encodedURLメソッドでエンコードされたSolana Pay URLを作成します。その後、URLオブジェクトを文字列に変換して保存し、後でQRコードの表示に使用します。変数の下に次のコードを追加してください。
コード
async function createPayment() {
    console.log("Creating a payment URL \n");
    setRecipient(new PublicKey(address));
    const url = encodeURL({
      recipient,
      amount,
      reference,
      label,
      message,
      memo,
    });

    setQrCodeValue(url.toString()); // convert URL object to string
    checkPayment();
  }
  1. 決済が作成されると、ユーザーにQRコードが表示されます。ユーザーはコードをスキャンしてトランザクションを実行できます。そのトランザクションが実行され、成功したかどうかを検証するには、オンチェーンの決済トランザクションを確認する関数を作成する必要があります。上記のcreatePayment関数では、トランザクションを作成した直後にこの関数を呼び出しています。
コード
async function checkPayment() {
    // update payment status
    setPaymentStatus('pending');

		// search for transaction

		// validate transaction
}

この関数は、確定済みトランザクションの検索とトランザクションの検証という2つの処理で構成されます。

ユーザーは別のデバイスからトランザクションを操作するため、トランザクションがいつ実行されたかを正確に把握することはできません。代わりに、一致する参照情報を持つトランザクションが実行されたか、そのステータスがどうなっているかを繰り返し確認します。これにはSolana PayのfindReferenceメソッドを使用します。

コード
// search for transaction
console.log('Searching for the payment\n');
    let signatureInfo;
  
    const {signature} = await new Promise((resolve, reject) => {
      
        const interval = setInterval(async () => {
            console.count('Checking for transaction...'+reference);
            try {
                signatureInfo = await findReference(connection, reference, { finality: 'confirmed' });
                console.log('\n Signature: ', signatureInfo.signature,signatureInfo);
                clearInterval(interval);
                resolve(signatureInfo);
            } catch (error: any) {
                if (!(error instanceof FindReferenceError)) {
                    console.error(error);
                    clearInterval(interval);
                    reject(error);
                }
            }
        }, 250);
    });
	// Update payment status
  setPaymentStatus('confirmed');

トランザクションが見つかったら、トランザクション内で正しい処理が行われたことを確認する必要があります。

これには、正しい受取人がトークンを受け取ったことと、正しい数量のトークンが送信されたことの確認が含まれます。これを行うために、Solana PayのvalidateTransferメソッドを使用します。

コード
//validate transaction
    console.log('Validating the payment\n');
    try {
      await validateTransfer(connection, signature, { recipient: recipient, amount });

      // Update payment status
      setPaymentStatus('validated');
      console.log('Payment validated');
      return true;
      
  } catch (error) {
      console.error('Payment failed', error);
      return false;
  }
  1. 最後に、UIを設定するTSXを追加します。要素のスタイル設定にはTailwindを使用します。UIには、見出し、受取人のアドレスとSOLの金額を入力する2つのフィールド、ボタン、Solana Pay QRコードを含めます。決済が検証されると、Solana Pay QRコードは「決済が検証されました」というテキストに置き換わります。ボタンはcreatePaymentメソッドを呼び出します。
コード
//validate transaction
return (
    <div className="flex flex-col items-center justify-center min-h-screen bg-gray-100">
      <h1 className="mb-6 text-3xl font-bold text-orange-700">
        Helius Solana Pay Demo
      </h1>
      <div className="w-full max-w-md p-6 mx-auto bg-white rounded-xl shadow-md">
        <div className="mb-4">
          <label className="block mb-2 text-sm font-medium text-gray-700">
            Address:
          </label>
          <input
            type="text"
            onChange={(e) => setAddress(e.target.value)}
            className="w-full px-3 py-2 text-sm leading-tight text-gray-700 border rounded shadow appearance-none focus:outline-none focus:shadow-outline"
          />
        </div>
        <div className="mb-4">
          <label className="block mb-2 text-sm font-medium text-gray-700">
            Amount:
          </label>
          <input
            type="number"
            onChange={(e) => setAmount(new BigNumber(e.target.value))}
            className="w-full px-3 py-2 text-sm leading-tight text-gray-700 border rounded shadow appearance-none focus:outline-none focus:shadow-outline"
          />
        </div>
        <div className="flex justify-center items-center">
        <button
          className="px-4 py-2 font-bold text-white bg-blue-500 rounded hover:bg-blue-700"
          onClick={createPayment}
        >
          Create QR Code
        </button>
        </div>
        
        <div>
        {paymentStatus === 'validated' ? <p className="mt-4 text-green-500 text-center">Payment Validated</p> : <div className="flex justify-center mt-4">
          {qrCodeValue && }
        </div>}
      </div>
      </div>
      
    </div>
  );

‍すべての手順を完了すると、次のような外観と動作のアプリが完成します。

Solana Pay:シームレスな体験の構築

決済を行う場合でもトランザクションを設定する場合でも、Solana Payのエンコードシステムはユーザーとアプリの双方にシームレスな体験を提供します。このガイドがSolana Payを理解して実装するための包括的な手引きとなり、Solanaブロックチェーンとのやり取りをよりスムーズかつ効率的にする一助になれば幸いです。サポートが必要な場合は、Helius Discordに参加するか、Twitterでお気軽にお問い合わせください。

‍

‍

‍

Heliusを購読

Solana開発の最新情報や新しい記事の公開通知を受け取れます

拡大画像