新消息:Helius 收购 Light Protocol
一只风筝飘在“Kite 简介”文字上方,Kite 是现代 Solana TypeScript 框架。
博客/开发

Kite 简介:现代 Solana TypeScript 框架

开发者教育X 上的 Mike MacCanaLinkedIn 上的 Mike MacCana
阅读需 4 分钟
目录

    今天,我们很高兴地宣布推出 Kite——面向浏览器和 Node.js 的现代 TypeScript 框架。Kite 基于 Solana web3.js 版本 2 的强大能力构建,同时大幅简化了常见任务。

    为什么选择 Kite?

    Kite 充分利用 Solana web3.js 版本 2 的速度与优雅,同时让你通过单个函数完成日常 Solana 任务。

    Kite 使用 web3.js 版本 2 处理底层繁重工作,因此你可以使用 web3.js 版本 2 的全部功能。如果不再需要 Kite,你可以轻松将其移除,直接使用原生 web3.js 版本 2。

    Kite 是 @solana-developers/helpers 针对 web3.js v2 的升级版,由原作者打造。@solana-developers/helpers 是 web3.js 版本 1 最受欢迎的高级库。

    Kite 包含大多数原始辅助函数的更新版本,其中汇集了 Helius、Solana Foundation、Anza、Turbin3、Unboxed Software 和 StarAtlas 的贡献。

    Kite 尚未包含的 @solana-developers/helpers 函数将很快加入。

    Kite 可同时在浏览器和 Node.js 中运行,并且依赖项极少。

    我能用 Kite 做什么?

    Kite 提供了可完成以下任务的函数:

    钱包

    SOL

    代币

    交易

    浏览器

    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,即可获得新 mint 的地址。

    Kite 与 Poseidon 对比

    Kite 是一个完全在客户端运行的库,适用于浏览器和 Node.js。如果你有兴趣使用 TypeScript 构建链上应用(例如智能合约),不妨了解 Poseidon。 

    参与贡献

    虽然 Kite 才刚刚推出,但我们致力于将它发展成一个稳健的框架,让每个人都能更轻松地进行 Solana 开发。

    通过简化常见任务并减少样板代码,我们可以帮助更多开发者在 Solana 上构建出色的产品。

    你可以通过以下方式提供帮助:

    立即试用 Kite

    准备好让 Solana 开发变得更简单了吗?

    开始使用 Kite:

    Installing Kite
    npm i @helius-dev/kite

    查看我们的 GitHub 仓库,获取完整文档和示例。

    让我们一起加速 Solana 开发!🪁

    订阅 Helius

    及时了解 Solana 开发的最新动态,并在我们发布新内容时收到更新