НОВОЕ: Helius приобретает Light Protocol
разработка смарт-контрактов Solana с помощью gill
Блог/Разработка

Как создавать приложения Solana с помощью Gill

Создаёт @useDecal, ранее — @SolanaFndnNick Frostbutter в XNick Frostbutter в LinkedIn
Чтение: 9 мин

Gill — новейшая библиотека инструментов для разработки на Solana на базе JavaScript/TypeScript. Изначально её разработал Ник Фростбаттер, сооснователь Decal, во время работы в команде по связям с разработчиками Solana Foundation. Цель gill — значительно упростить разработку приложений на JavaScript.

Gill включает как умеренно абстрагированные инструменты для повышения продуктивности разработчиков, так и низкоуровневые примитивы. Разработчики могут гибко выбирать подходящий вариант.

Легковесные абстракции устраняют многие сложности и шаблонный код, необходимые для типичных операций с Solana. Низкоуровневые примитивы служат «аварийными выходами», когда разработчикам нужен более точный контроль над логикой приложения.

В этой статье мы рассмотрим основы «библиотеки gill», её состав, начало работы с gill и отличия от @solana/kit (ранее — «web3.js v2»).

Что такое Gill?

Gill — современная библиотека TypeScript для разработки приложений Solana в любой среде на базе JavaScript: в браузере, на сервере или мобильном устройстве.

Библиотека gill предназначена для разработчиков Solana с любым уровнем опыта — от начинающих до экспертов. Высокоуровневые абстракции и низкоуровневые примитивы поставляются в одном пакете. Поэтому разработчики могут легко использовать расширенные возможности, когда это необходимо или когда абстракции их не поддерживают. 

А главное? 

Gill полностью поддерживает tree shaking, поэтому сборщик автоматически удаляет все примитивы и абстракции, которые не используются в кодовой базе.

Главная цель Gill — улучшить опыт разработчиков: упростить типичные задачи разработки на Solana и устранить шаблонный код, сохранив возможность работать на более низком уровне. Разработчики не должны ограничиваться только высокоуровневыми абстракциями или низкоуровневыми примитивами. Они должны легко выбирать подходящий вариант в зависимости от задачи.

Установка Gill

Gill можно установить в любой проект на базе JavaScript или TypeScript, включая NodeJS/Bun, браузерные и React Native-приложения, а также практически любую другую среду JavaScript.

Код
npm install gill

Библиотека gill хорошо поддерживает TypeScript и должна работать без дополнительной настройки в большинстве приложений. Однако конфигурацию конкретного проекта может потребоваться скорректировать для лучшей работы с gill. Подробнее см. в документации о поддержке TypeScript в gill.

Gill и @solana/kit: сравнение

Библиотека gill построена непосредственно поверх @solana/kit — новых низкоуровневых примитивов JavaScript, которые Anza разработала как более производительную замену старому @solana/web3.js.

Kit поставляет только эти низкоуровневые примитивы. Поэтому разработчикам приходится создавать всё вручную, а приложения разрастаются из-за многословного шаблонного кода.

И тут появляется gill.

Gill поставляет и те же низкоуровневые примитивы, что и Kit, и умеренно абстрагированные инструменты для упрощения типичных задач — через единый совместимый интерфейс. Благодаря комплексным упрощениям gill разработчики могут уделять больше времени бизнес-логике приложения и меньше — многословному шаблонному коду.

Примеры кода Gill и Kit

Следующие фрагменты кода показывают, как упростить код, сохранив ту же функциональность и потенциально расширив её. Практически каждому приложению нужно выполнять две задачи: устанавливать соединение с блокчейном и создавать транзакции.

Соединение с блокчейном через @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,
});

Ту же логику можно реализовать проще с помощью функции createSolanaClient из gill:

Код
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();

Простая транзакция с инструкцией memo и базовой оптимизацией на основе инструкций бюджета вычислений в @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,
});

Более подробное сравнение этих библиотек см. в документации 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 включает следующие клиенты SPL, доступные непосредственно по пути импорта gill/programs:

  • @solana-program/system
  • @solana-program/memo
  • @solana-program/compute-budget
  • @solana-program/address-lookup-table
  • @solana-program/token-2022 (см. примечание о клиентах токен-программ ниже)

Чтобы использовать единый пакет gill для этих клиентов программ SPL:

  1. Замените указанные выше импорты пакетов @solana-program/* на gill/programs
  2. Удалите указанные выше пакеты @solana-program/*.

После обновления импортов приложение сразу готово к работе с библиотекой «gill core». Теперь можно без труда заменить многословный шаблонный код Kit, например для подключения к блокчейну и создания транзакций, любой из доступных абстракций gill.

Какие компоненты входят в Gill?

Библиотеку gill можно разделить на несколько ключевых компонентов:

  • Основная функциональность (также известная как «gill core»)
  • Вспомогательные инструменты для серверных сред выполнения, например NodeJS и Bun
  • Клиенты программ
  • Конструкторы транзакций
  • Режим отладки

Вспомогательные функции Node.js

Пакет gill включает несколько утилит для серверных сред выполнения JavaScript. Они входят в пакет gill, но используют отдельный путь импорта для более эффективного tree shaking. Эти утилиты позволяют легко загружать ключевые пары из файлов или переменных 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, бессерверных функциях и даже в консоли браузера.

Чтобы включить режим отладки, задайте для любого из следующих параметров значение true или 1:

  • process.env.GILL_DEBUG
  • global.__GILL_DEBUG__
  • window.__GILL_DEBUG__ (например, в консоли браузера)
  • либо вручную задайте любой уровень журнала отладки (см. документацию)

Подробнее см. в документации gill о режиме отладки.

Дополнительные инструменты для разработки с Gill

@gillsdk/react

В библиотеку gill непосредственно входит ещё один пакет — @gillsdk/react. Это набор хуков React, предназначенных для значительного улучшения разработки фронтенд-приложений на React. Он также построен поверх популярной библиотеки реактивности TanStack Query, поэтому его проще использовать в существующих приложениях.

Пакет @gillsdk/react пока находится на ранней стадии и активно разрабатывается. Сейчас он предоставляет несколько полезных хуков React для приложений Solana:

  • useAccount — получение информации об аккаунте по адресу
  • useBalance — получение баланса аккаунта в лампортах
  • useLatestBlockhash — получение последнего хеша блока
  • useSignatureStatuses — получение статусов подписей
  • useProgramAccounts — получение аккаунтов программы (GPA)
  • useTokenMint — получение декодированного аккаунта Mint токена
  • useTokenAccount — получение токен-аккаунта для заданных Mint и владельца (или ATA)

Codama

Codama — инструмент, который позволяет разработчикам взять IDL программы Solana и создать клиентские библиотеки, например на JavaScript или Rust, для использования другими приложениями. Codama сводит все сложности создания инструкций Solana к IDL, файлу конфигурации и импорту функции.

Gill и Codama легко интегрируются с помощью функции createCodamaConfig из gill. Сопровождающий gill также активно работает над дальнейшим улучшением интеграции gill<>Codama, включая прямую поддержку в Codama CLI!

По умолчанию созданные Codama клиенты программ TypeScript используют @solana/kit, но это легко изменить в файле конфигурации Codama для программы Solana. Функция createCodamaConfig значительно упрощает переход на gill в конфигурации Codama.

Ниже приведён пример файла codama.js, который создаст TypeScript-клиент программы Solana с использованием gill:

Код
import { createCodamaConfig } from "gill";

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

Полное руководство по созданию клиентов программ Solana с помощью Codama доступно в документации gill.

Будущее Gill

У библиотеки gill большое будущее и множество задач впереди. Недавно запустился официальный сайт с документацией gill, а число ежемесячных загрузок библиотеки приближается к 20 000.

Подробнее о текущих планах развития gill см. на странице GitHub Projects. Сейчас в краткий список входят:

  • Прямая поддержка спецификации Solana Pay
  • Нативная интеграция спецификации API Digital Assets Standard (DAS)
  • Улучшенная поддержка токенов на базе Token Extension
  • Улучшенная поддержка Address Lookup Tables
  • Более полная документация

Входящий в библиотеку gill пакет @gillsdk/react пока находится на ранней стадии и содержит девять разных хуков React. Его продолжают развивать, чтобы разработчики могли легко добавлять реактивность в приложения на React, включая поддержку всех распространённых методов Solana RPC и более тесную интеграцию с wallet-ui.

Интересный факт: gill планируют напрямую интегрировать в фреймворк Anchor, чтобы разработчикам было проще использовать оптимизации gill и улучшения процесса разработки в своих приложениях. Кто знает, возможно, gill станет вариантом по умолчанию в Anchor v2. :shhh:

Как внести вклад в Gill

Gill — библиотека с открытым исходным кодом по лицензии MIT, и вклад участников приветствуется! Если вы хотите помочь в её разработке, изучите открытые задачи и попробуйте решить одну из них.

Если вы хотите предложить новую функцию или улучшение библиотеки, сначала создайте задачу, чтобы обсудить её с сопровождающими до начала работы над кодом для PR.

Дополнительные ресурсы

Дополнительную информацию и ресурсы о gill можно найти по следующим ссылкам:

Подпишитесь на Helius

Следите за новостями разработки на Solana и получайте уведомления о наших публикациях