新着:HeliusがLight Protocolを買収
GillでSolanaスマートコントラクトを開発
ブログ/開発

GillでSolanaアプリを構築する方法

@useDecalを開発、以前は@SolanaFndnに所属XのNick FrostbutterLinkedInのNick Frostbutter
読了時間:9分

Gillは、JavaScript/TypeScriptベースの最新Solana開発ツールライブラリです。元々は、Decalの共同創業者であるNick Frostbutter氏がSolana FoundationのDeveloper Relationsチーム在籍中に開発したもので、JavaScriptベースのアプリケーションにおける開発者体験を大幅に改善することを目指しています。

Gillには、開発者の生産性を高める適度に方針を定めた抽象化と、低レベルのプリミティブの両方が含まれており、開発者は独自のアプローチを柔軟に選択できます。

軽量な抽象化により、Solanaとの一般的なやり取りに必要な複雑さやボイラープレートの多くを削減できます。一方、低レベルのプリミティブは、アプリケーションのロジックをより細かく制御する必要がある場合や、そうした制御を望む場合の「エスケープハッチ」として機能します。

この記事では、「gillライブラリ」の基本、ライブラリに含まれる機能、gillの始め方、@solana/kit(旧称「web3.js v2」)との違いを解説します。

Gillとは?

Gillは、ブラウザ、サーバー、モバイルなど、あらゆるJavaScriptベースの環境でSolanaアプリケーションを開発するためのモダンなTypeScriptライブラリです。

gillライブラリは、初心者から上級者まで、あらゆる経験レベルのSolana開発者を対象としています。高レベルの抽象化と低レベルのプリミティブを同じパッケージで提供することで、必要な場合や抽象化でサポートされていない場合に、より高度な機能を簡単に利用できます。 

最大の特長は何でしょうか? 

Gillは完全にツリーシェイキングに対応しているため、コードベースで使用されていないプリミティブや抽象化は、バンドラーによって自動的に削除されます。

Gillの主な目標は、一般的なSolana開発タスクを簡素化し、ボイラープレートを排除することで、必要に応じて低レベルの操作を行う能力を損なうことなく、開発者体験を向上させることです。開発者が高レベルの抽象化か低レベルのプリミティブのどちらか一方に制限されるべきではありません。状況に応じて、どちらでも簡単に選択できるべきです。

Gillのインストール

Gillは、NodeJS/Bun、ブラウザ、React Nativeをはじめ、ほぼすべてのJavaScript環境を含む、あらゆるJavaScriptまたはTypeScriptベースのプロジェクトにインストールできます。

コード
npm install gill

gillライブラリはTypeScriptを強力にサポートしており、ほとんどのアプリケーションですぐに動作します。ただし、プロジェクト固有の設定によっては、gillとの連携を改善するために調整が必要になる場合があります。詳しくは、gillのTypeScriptサポートに関するドキュメントをご覧ください。

Gillと@solana/kitの比較

gillライブラリは、旧@solana/web3.jsを置き換える高性能なライブラリとしてAnzaが開発した、新しい低レベルJavaScriptプリミティブの@solana/kit上に直接構築されています。

Kitはこれらの低レベルプリミティブのみを提供するため、開発者はすべてを手動で組み立てなければならず、冗長なボイラープレートによってアプリケーションが肥大化します。

そこで登場するのがgillです。

Gillは、Kitと同じ低レベルプリミティブと、一般的なタスクを簡素化する適度に方針を定めた抽象化の両方を、単一の互換性のあるインターフェースから提供します。gillによって全体を簡素化することで、開発者は冗長なボイラープレートに費やす時間を減らし、アプリケーションのビジネスロジックにより多くの時間を充てられます。

GillとKitのコード例

以下のコードスニペットは、同じ機能を維持しながら、場合によっては機能を追加しつつ、コードを簡素化する方法を示しています。ほぼすべてのアプリケーションで、ブロックチェーンへの接続確立とトランザクションの作成という2つのタスクが必要になります。

@solana/kitでブロックチェーンへの接続を作成する方法は次のとおりです。

コード
import {
  devnet,
  createSolanaRpc,
  createSolanaRpcSubscriptions,
  sendAndConfirmTransactionFactory,
} from "@solana/kit";

const rpc = createSolanaRpc(devnet("https://api.devnet.solana.com"));

const rpcSubscriptions = createSolanaRpcSubscriptions(
  devnet("wss://api.devnet.solana.com"),
);

const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({
  rpc,
  rpcSubscriptions,
});

同じロジックは、gillのcreateSolanaClient関数を使うと、より簡潔に実装できます。

コード
import { createSolanaClient } from "gill";

const { rpc, rpcSubscriptions, sendAndConfirmTransaction } = createSolanaClient({
  urlOrMoniker: "devnet",
});

上記の例でいずれかのライブラリを使用して作成したrpcオブジェクトを使い、簡単なRPCリクエストを実行できるようになりました。

コード
// get the latest blockhash from your RPC provider
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();

@solana/kitで、基本的な最適化(コンピュートバジェット命令を使用)を適用したメモ命令を含むシンプルなトランザクションを作成する方法は次のとおりです。

コード
import {
  pipe,
  createTransactionMessage,
  setTransactionMessageFeePayerSigner,
  appendTransactionMessageInstructions,
  setTransactionMessageLifetimeUsingBlockhash,
} from "@solana/kit";
import { getAddMemoInstruction } from "@solana-program/memo";
import {
  getSetComputeUnitLimitInstruction,
  getSetComputeUnitPriceInstruction,
} from "@solana-program/compute-budget";

const transaction = pipe(
  createTransactionMessage({ version: "legacy" }),
  (tx) => setTransactionMessageFeePayerSigner(signer, tx),
  (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
  (tx) =>
    appendTransactionMessageInstructions(
      [
        getAddMemoInstruction({
          memo: "gm world!",
        }),
        getSetComputeUnitLimitInstruction({ units: 5000 }),
        getSetComputeUnitPriceInstruction({ microLamports: 1000 }),
      ],
      tx,
    ),
);

gillを使用すると、同じロジックを次のように大幅に簡素化できます。

コード
import { createTransaction } from "gill";
import { getAddMemoInstruction } from "gill/programs";

const transaction = createTransaction({
  version: "legacy",
  feePayer: signer,
  instructions: [
    getAddMemoInstruction({
      memo: "gm world!",
    }),
  ],
  latestBlockhash,
  computeUnitLimit: 5000,
  computeUnitPrice: 1000,
});

この2つのライブラリのより包括的な比較については、gillドキュメントのgillと@solana/kitの比較をご覧ください。

KitからGillへの移行プロセス

@solana/kitライブラリを使用しているアプリケーションでは、gillパッケージへの移行は非常に簡単です。

  1. gillをインストールします
  2. すべての@solana/kitインポートをgillに置き換えます
  3. @solana/kitをアンインストールします

gillには、最も一般的なSolana Program Library(SPL)クライアントも直接含まれているため、それらのパッケージインポートもgillに置き換えられます。Gillには、gill/programsインポートパスから直接アクセスできる次のSPLクライアントが含まれています。

  • @solana-program/system
  • @solana-program/memo
  • @solana-program/compute-budget
  • @solana-program/address-lookup-table
  • @solana-program/token-2022(トークンプログラムクライアントについては以下の注記を参照)

これらのSPLプログラムクライアントで単一のgillパッケージを利用するには、次の手順を実行します。

  1. 上記の@solana-program/*パッケージのインポートをgill/programsに置き換えます
  2. 上記の@solana-program/*パッケージをアンインストールします。

インポートを更新すると、アプリケーションですぐに「gill core」ライブラリを使い始められます。利用可能なgillの抽象化を使って、ブロックチェーン接続やトランザクション作成など、冗長なKitのボイラープレートを簡単にリファクタリングできるようになります。

Gillに含まれるコンポーネント

gillライブラリは、いくつかの主要コンポーネントに分けられます。

  • コア機能(別名「gill core」)
  • サーバーランタイム固有のヘルパー(NodeJSやBunなど)
  • プログラムクライアント
  • トランザクションビルダー
  • デバッグモード

Node.jsヘルパー関数

gillパッケージには、JavaScriptサーバーランタイム固有のユーティリティがいくつか含まれています。gillパッケージに含まれていますが、ツリーシェイキングを改善するため、インポートパスは分けられています。これらのユーティリティを使うと、キーペアをファイルやENV変数から簡単に読み込んだり、保存したりできます。

コード
import { ... } from "gill/node"

ローカルファイルシステムからキーペアファイル(Solana CLIのキーペアなど)を簡単に読み込むには、次のようにします。

コード
import { loadKeypairSignerFromFile } from "gill/node";

// default file path: ~/.config/solana/id.json
const signer = await loadKeypairSignerFromFile();
console.log("address:", signer.address);

base58でエンコードされたキーペアをENV変数から読み込むこともできます。

コード
import { loadKeypairSignerFromEnvironmentBase58 } from "gill/node";

// loads signer from base58 keypair stored at `process.env[variableName]`
const signer = await loadKeypairSignerFromEnvironmentBase58(variableName);
console.log("address:", signer.address);

トランザクションビルダー

複数のプログラムと同時にやり取りすることが多い一般的なトランザクションの作成を簡素化するため、gillには、これらのタスク向けに署名可能なトランザクションを簡単に組み立てるためのさまざまな「トランザクションビルダー」が含まれています。

各トランザクションビルダーは単一のタスクに特化しているため、さまざまなボイラープレートを簡単に抽象化しながら、最適化されたトランザクションの作成にも役立ちます。

gillが提供するトランザクションビルダーには、次のものがあります。

  • buildCreateTokenTransaction - メタデータ付きトークンを作成
  • buildMintTokensTransaction - 宛先ウォレットにトークンをミント
  • buildTransferTokensTransaction - 宛先ウォレットにトークンを転送

各トランザクションビルダーには、これらのgill抽象化をより柔軟に利用できるよう、「命令ビルダー」が付属しています。

デバッグモード

gillでは「デバッグモード」を有効にすると、トランザクションのトラブルシューティングに役立つ追加情報を自動的にログへ記録できます。

アプリケーションから出力される追加ログを最小限に抑えるため、デバッグモードはデフォルトで無効になっています。柔軟なコントローラーにより、コード自体、NodeJSバックエンド、サーバーレス関数、さらにはWebブラウザのコンソールなど、コードが実行される一般的な場所からデバッグモードを有効にできます。

デバッグモードを有効にするには、次のいずれかをtrueまたは1に設定します。

  • process.env.GILL_DEBUG
  • global.__GILL_DEBUG__
  • window.__GILL_DEBUG__(Webブラウザのコンソールなど)
  • または、任意のデバッグログレベルを手動で設定します(ドキュメントを参照)

詳しくは、gillのデバッグモードに関するドキュメントをご覧ください。

Gillでの開発を補完する開発者ツール

@gillsdk/react

gillライブラリには、Reactベースのフロントエンドアプリケーションの開発者体験を大幅に向上させるために設計されたReactフックのコレクション、@gillsdk/reactという別のパッケージが直接含まれています。また、広く利用されているリアクティビティライブラリのTanStack Query上に構築されているため、既存のアプリケーションでも簡単に利用できます。

@gillsdk/reactパッケージはまだ初期段階にあり、活発に開発されています。現在、Solanaアプリケーション向けに、便利なReactフックをいくつか提供しています。

  • useAccount - アドレスのアカウント情報を取得
  • useBalance - アカウント残高(lamports単位)を取得
  • useLatestBlockhash - 最新のブロックハッシュを取得
  • useSignatureStatuses - 署名ステータスを取得
  • useProgramAccounts - プログラムアカウント(GPA)を取得
  • useTokenMint - デコード済みトークンのMintアカウントを取得
  • useTokenAccount - 指定したMintと所有者(またはATA)のトークンアカウントを取得

Codama

Codamaは、開発者がSolanaプログラムのIDLから、他のアプリケーションで使用するクライアントライブラリ(JavaScriptやRustなど)を生成できるツールです。Codamaは、Solana命令の作成に伴うすべての複雑さをIDL、設定ファイル、関数のインポートに集約します。

GillとCodamaは、gillのcreateCodamaConfig関数を使って簡単に統合できます。gillのメンテナーは、Codama CLIでの直接サポートを含め、gill<>Codama統合をさらに改善するための作業も積極的に進めています。

Codamaが生成するTypeScriptプログラムクライアントは、デフォルトでは@solana/kitを使用しますが、SolanaプログラムのCodama設定ファイルで簡単に変更できます。createCodamaConfig関数を使えば、Codama設定でgillを使用するアップグレードも容易です。

以下は、gillを使用するSolanaプログラムのTypeScriptクライアントを生成するcodama.jsファイルの例です。

コード
import { createCodamaConfig } from "gill";

export default createCodamaConfig({
  idl: "program/idl.json",
  clientJs: "clients/js/src/generated",
});

Codamaを使用したSolanaプログラムクライアントの生成については、gillのドキュメントで完全なガイドをご覧いただけます。

Gillの今後

gillライブラリの未来は明るく、取り組むべきことが数多くあります。公式のgillドキュメントサイトが公開されたばかりで、ライブラリの月間ダウンロード数は20,000件に迫っています。

現在のgillロードマップについて詳しくは、GitHub Projectsページをご覧ください。現時点での主な項目は次のとおりです。

  • Solana Pay仕様の直接サポート
  • Digital Assets Standard(DAS)API仕様のネイティブ統合
  • Token Extensionベースのトークンのサポート改善
  • Address Lookup Tablesのサポート改善
  • より包括的なドキュメント

gillライブラリに含まれる@gillsdk/reactパッケージは、まだ初期段階です(9種類のReactフックを提供)。一般的なすべてのSolana RPCメソッドのサポートや、wallet-uiとのより緊密な統合など、Reactベースのアプリケーションにリアクティビティを簡単に追加できるよう、引き続き開発が進められています。

豆知識:gillをAnchorフレームワークに直接統合し、開発者がアプリケーション内でgillの最適化や開発者体験の改善をより簡単に活用できるようにする計画があります。もしかすると、gillがAnchor v2のデフォルトになるかもしれません。:shhh:

Gillへのコントリビューション方法

gillライブラリはオープンソース(MITライセンス)であり、コントリビューターを歓迎しています。ライブラリへのコントリビューションに関心がある場合は、未解決のissueを確認し、自分で取り組めるものを探してみてください。

ライブラリの新機能や改善を提案したい場合は、PRのコード作業を始める前に、まずissueを作成してメンテナーとの議論を開始してください。

その他のリソース

gillに関する詳しい情報やリソースは、以下のリンクから確認できます。

Heliusを購読

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