НОВОЕ: Helius приобретает Light Protocol
Воздушный змей парит над текстом «Представляем Kite» — современный фреймворк Solana для TypeScript.
Блог/Разработка

Представляем Kite — современный TypeScript-фреймворк для Solana

Обучение разработчиковMike MacCana в XMike MacCana в LinkedIn
Чтение: 4 мин
Содержание

    Сегодня мы рады представить Kite — современный TypeScript-фреймворк для браузера и Node.js. Kite использует возможности Solana web3.js версии 2 и при этом значительно упрощает распространённые задачи.

    Почему Kite?

    Kite использует скорость и элегантность Solana web3.js версии 2, но позволяет выполнять повседневные задачи Solana с помощью одной функции.

    Поскольку Kite выполняет основную работу с помощью web3.js версии 2, вам доступны все возможности web3.js версии 2. Если Kite вам больше не нужен, его можно легко удалить и использовать обычный web3.js версии 2.

    Kite — это обновлённая для web3.js v2 версия @solana-developers/helpers, самой популярной высокоуровневой библиотеки для web3.js версии 1, созданная тем же автором.

    Пакет Kite содержит обновлённые версии большинства исходных вспомогательных функций, включая наработки Helius, Solana Foundation, Anza, Turbin3, Unboxed Software и StarAtlas.

    Функции @solana-developers/helpers, которых пока нет в Kite, будут добавлены в ближайшее время.

    Kite работает как в браузере, так и в node.js и имеет минимум зависимостей.

    Что можно делать с помощью Kite?

    Kite включает функции для следующих задач:

    Кошельки

    SOL

    Токены

    Транзакции

    Explorer

    Сравнение Kite и Solana web3.js 2:

    Вот краткий пример создания токена

    С помощью Kite

    Помните, что Kite — это лишь фреймворк поверх web3.js v2, поэтому он использует те же типы и базовые возможности web3.js v2.

    Making a token (including metadata) using Kite
    import { connect } from "@helius-dev/kite";
    const connection = connect();
    const mintAddress = await connection.makeTokenMint(
      mintAuthority,
      6,
      "My Token",
      "MTKN",
      "https://example.com/metadata.json",
      {
        description: "A sample token",
        website: "https://example.com",
      },
    );
    console.log(connection.getExplorerLink(mintAddress));

    С помощью Solana web3.js v2

    ...без Kite!

    Making a token using web3.js version 2
    import {
      airdropFactory,
      appendTransactionMessageInstructions,
      createSolanaRpc,
      createSolanaRpcSubscriptions,
      createTransactionMessage,
      generateKeyPairSigner,
      getSignatureFromTransaction,
      lamports,
      pipe,
      sendAndConfirmTransactionFactory,
      setTransactionMessageFeePayerSigner,
      setTransactionMessageLifetimeUsingBlockhash,
      signTransactionMessageWithSigners,
      some,
    } from "@solana/web3.js";
    import { getCreateAccountInstruction } from "@solana-program/system";
    import {
      getInitializeMintInstruction,
      getMintSize,
      TOKEN_2022_PROGRAM_ADDRESS,
      extension,
      getInitializeMetadataPointerInstruction,
      getInitializeTokenMetadataInstruction,
      tokenMetadataField,
      getUpdateTokenMetadataFieldInstruction,
    } from "@solana-program/token-2022";
    
    const rpc = createSolanaRpc("http://127.0.0.1:8899");
    const rpcSubscriptions = createSolanaRpcSubscriptions("ws://127.0.0.1:8900");
    
    const feePayer = await generateKeyPairSigner();
    console.log(feePayer.address);
    const mint = await generateKeyPairSigner();
    
    await airdropFactory({ rpc, rpcSubscriptions })({
      recipientAddress: feePayer.address,
      lamports: lamports(1_000_000_000n),
      commitment: "confirmed",
    });
    
    const balance = await rpc.getBalance(feePayer.address).send();
    console.log("balance:", balance.value);
    
    const metadataPointerExtension = extension("MetadataPointer", {
      authority: some(feePayer.address),
      metadataAddress: some(mint.address),
    });
    
    const tokenMetadataExtension = extension("TokenMetadata", {
      updateAuthority: some(feePayer.address),
      mint: mint.address,
      name: "OPOS",
      symbol: "OPOS",
      uri: "https://raw.githubusercontent.com/solana-developers/opos-asset/main/assets/DeveloperPortal/metadata.json",
      additionalMetadata: new Map<string, string>([["description", "Only Possible On Solana"]]),
    });
    
    const spaceWithoutMetadata = BigInt(getMintSize([metadataPointerExtension]));
    
    const spaceWithMetadata = BigInt(getMintSize([metadataPointerExtension, tokenMetadataExtension]));
    
    const rent = await rpc.getMinimumBalanceForRentExemption(spaceWithMetadata).send();
    
    const createAccountInstruction = getCreateAccountInstruction({
      payer: feePayer,
      newAccount: mint,
      lamports: rent,
      space: spaceWithoutMetadata,
      programAddress: TOKEN_2022_PROGRAM_ADDRESS,
    });
    
    const initializeMetadataPointerInstruction = getInitializeMetadataPointerInstruction({
      mint: mint.address,
      authority: feePayer.address,
      metadataAddress: mint.address,
    });
    
    const initializeMintInstruction = getInitializeMintInstruction({
      mint: mint.address,
      decimals: 2,
      mintAuthority: feePayer.address,
    });
    
    const initializeTokenMetadataInstruction = getInitializeTokenMetadataInstruction({
      metadata: mint.address,
      updateAuthority: feePayer.address,
      mint: mint.address,
      mintAuthority: feePayer,
      name: tokenMetadataExtension.name,
      symbol: tokenMetadataExtension.symbol,
      uri: tokenMetadataExtension.uri,
    });
    
    const updateTokenMetadataInstruction = getUpdateTokenMetadataFieldInstruction({
      metadata: mint.address,
      updateAuthority: feePayer,
      field: tokenMetadataField("Key", ["description"]),
      value: "Only Possible On Solana",
    });
    
    const instructions = [
      createAccountInstruction,
      initializeMetadataPointerInstruction,
      initializeMintInstruction,
      initializeTokenMetadataInstruction,
      updateTokenMetadataInstruction,
    ];
    
    const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
    
    const transactionMessage = pipe(
      createTransactionMessage({ version: 0 }),
      (message) => setTransactionMessageFeePayerSigner(feePayer, message),
      (message) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, message),
      (message) => appendTransactionMessageInstructions(instructions, message),
    );
    
    const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);
    
    const transactionSignature = getSignatureFromTransaction(signedTransaction);
    
    await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTransaction, {
      commitment: "confirmed",
      skipPreflight: true,
    });
    
    console.log("Transaction Signature:", `https://explorer.solana.com/tx/${transactionSignature}?cluster=custom`);
    

    Как видите, без Kite пришлось бы создать сообщение транзакции с пятью инструкциями и соответствующими параметрами, подписать его и отправить в RPC. В Kite достаточно запустить makeTokenMint, чтобы получить адрес нового минта.

    Сравнение Kite и Poseidon

    Kite — это полностью клиентская библиотека для браузеров и node.js. Обратите внимание на Poseidon, если вас интересует создание ончейн-приложений (например, смарт-контрактов) с помощью TypeScript. 

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

    Kite появился недавно, но мы намерены развивать его в надёжный фреймворк, который сделает разработку на Solana доступнее для всех.

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

    Вот как вы можете помочь:

    Попробуйте Kite уже сегодня

    Готовы упростить разработку на Solana?

    Начните работу с Kite:

    Installing Kite
    npm i @helius-dev/kite

    Полную документацию и примеры вы найдёте в нашем репозитории GitHub.

    Давайте вместе ускорим разработку на Solana! 🪁

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

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