Solana - JS/TS 客户端

  • 想样
  • 更新于 19小时前
  • 阅读 57

Anchor提供了一个Typescript客户端库,简化了使用JavaScript或TypeScript从客户端与Solana程序交互的过程。客户端程序Program要使用客户端库,首先使用Anchor生成的IDL文件创建一个实例。创建的实例Program需要

<!--StartFragment-->

Anchor 提供了一个 Typescript 客户端库,简化了使用 JavaScript 或 TypeScript 从客户端与 Solana 程序交互的过程。 <!--EndFragment-->

<!--StartFragment-->

客户端程序

Program 要使用客户端库,首先使用Anchor 生成的IDL 文件创建一个实例 。\ 创建 的实例Program需要程序的 IDL 和 AnchorProvider。AnchorProvider是结合了两件事的抽象:

  • Connection- 与Solana 集群的连接 (即 localhost、devnet、mainnet)
  • Wallet- (可选)用于支付和签署交易的默认钱包

<!--EndFragment--> <!--StartFragment-->

前端/节点

[当使用钱包适配器]与前端集成时 ,您需要设置AnchorProvider和Program。 <!--EndFragment-->

import { Program, AnchorProvider, setProvider } from "@coral-xyz/anchor";
import { useAnchorWallet, useConnection } from "@solana/wallet-adapter-react";
import type { HelloAnchor } from "./idlType";
import idl from "./idl.json";

const { connection } = useConnection();
const wallet = useAnchorWallet();

const provider = new AnchorProvider(connection, wallet, {});
setProvider(provider);

export const program = new Program(idl as HelloAnchor, {
  connection,
});

<!--StartFragment-->

在上面的代码片段中:

  • idl.json是 Anchor 生成的 IDL 文件,可以 /target/idl/&lt;program-name>.json在 Anchor 项目中找到。
  • idlType.ts是 IDL 类型(用于 TS), /target/types/&lt;program-name>.ts在 Anchor 项目中找到。

Program或者,您可以仅使用 IDL 和Solana 集群创建 的实例Connection。这意味着没有默认的 Wallet,但允许您使用Program来获取帐户或构建指令,而无需连接钱包

<!--EndFragment-->

import { clusterApiUrl, Connection, PublicKey } from "@solana/web3.js";
import { Program } from "@coral-xyz/anchor";
import type { HelloAnchor } from "./idlType";
import idl from "./idl.json";

const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

export const program = new Program(idl as HelloAnchor, {
  connection,
});

<!--StartFragment-->

测试文件

Anchor 会自动在新项目的默认测试文件中设置一个Program实例。但是,此设置与在 Anchor 工作区外部初始化的方式不同Program ,例如在 React 或 Node.js 应用程序中。 <!--EndFragment-->

import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { HelloAnchor } from "../target/types/hello_anchor";

describe("hello_anchor", () => {
  // Configure the client to use the local cluster.
  anchor.setProvider(anchor.AnchorProvider.env());

  const program = anchor.workspace.HelloAnchor as Program&lt;HelloAnchor>;

  it("Is initialized!", async () => {
    // Add your test here.
    const tx = await program.methods.initialize().rpc();
    console.log("Your transaction signature", tx);
  });
});

<!--StartFragment-->

调用指令

一旦Program使用程序 IDL 设置,您就可以使用 Anchor MethodsBuilder 来:

  • 建立个别指令
  • 建立交易
  • 建立并发送交易

基本格式如下:

<!--EndFragment-->

await program.methods // 这是用于从程序的 IDL 创建指令调用的构建器 API
  .instructionName(instructionData) // 接下来.methods,从程序 IDL 中指定指令的名称,并将任何所需的参数作为逗号分隔的值传递。
  .accounts({}) // 按照IDL中指定的方式传入指令所需的账户地址
  .signers([]) //  可选地传入指令所需的作为附加签名者的密钥对数组。这通常在创建新帐户时使用,其中帐户地址是新生成的密钥对的公钥。请注意,.signers只有在使用.rpc()时才应使用。当使用 .transaction()或 时.instruction(),应在发送之前将签名者添加到交易中。
  .rpc();

<!--StartFragment-->

Anchor 提供了多种构建程序指令的方法:

.rpc

该 rpc() 方法 发送 带有指定指令的签名交易TransactionSignature并返回。\ 当使用 时.rpc,Wallet来自 的Provider将自动包含在签名者中。 <!--EndFragment-->

// Generate keypair for the new account
const newAccountKp = new Keypair();

const data = new BN(42);
const transactionSignature = await program.methods
  .initialize(data)
  .accounts({
    newAccount: newAccountKp.publicKey,
    signer: wallet.publicKey,
    systemProgram: SystemProgram.programId,
  })
  .signers([newAccountKp])
  .rpc();

<!--StartFragment-->

.transaction()

该 transaction() 方法 使用指定的指令构建Transaction 而不发送交易。 <!--EndFragment-->

// Generate keypair for the new account
const newAccountKp = new Keypair();

const data = new BN(42);
const transaction = await program.methods
  .initialize(data)
  .accounts({
    newAccount: newAccountKp.publicKey,
    signer: wallet.publicKey,
    systemProgram: SystemProgram.programId,
  })
  .transaction();

const transactionSignature = await connection.sendTransaction(transaction, [
  wallet.payer,
  newAccountKp,
]);

<!--StartFragment-->

.instruction()

该 instruction() 方法 使用指定的指令构建TransactionInstruction 。如果您想手动将指令添加到交易并将其与其他指令相结合,这很有用。 <!--EndFragment-->

// Generate keypair for the new account
const newAccountKp = new Keypair();

const data = new BN(42);
const instruction = await program.methods
  .initialize(data)
  .accounts({
    newAccount: newAccountKp.publicKey,
    signer: wallet.publicKey,
    systemProgram: SystemProgram.programId,
  })
  .instruction();

const transaction = new Transaction().add(instruction);

const transactionSignature = await connection.sendTransaction(transaction, [
  wallet.payer,
  newAccountKp,
]);

<!--StartFragment-->

获取账户

客户端Program简化了获取和反序列化由 Anchor 程序创建的帐户的过程。\ 使用program.account后跟 IDL 中定义的帐户类型的名称。Anchor 提供了多种方法来获取帐户。

.all()

用于 all() 获取特定帐户类型的所有现有帐户。

<!--EndFragment-->

const accounts = await program.account.newAccount.all();

<!--StartFragment-->

memcmp

使用memcmp(内存比较)来筛选与特定偏移量处的特定值匹配的帐户数据。使用memcmp需要您了解要获取的帐户类型的数据字段的字节布局。 计算偏移量时,请记住 Anchor 程序创建的账户中的前 8 个字节是为账户鉴别器保留的。 <!--EndFragment-->

const accounts = await program.account.newAccount.all([
  {
    memcmp: {
      offset: 8,
      bytes: "",
    },
  },
]);

<!--StartFragment-->

fetch()

用于 fetch() 获取单个账户的账户数据 <!--EndFragment-->

const account = await program.account.newAccount.fetch(ACCOUNT_ADDRESS);

<!--StartFragment-->

fetchMultiple()

fetchMultiple() 通过传入账户地址数组来获取多个账户的账户数据

<!--EndFragment-->

const accounts = await program.account.newAccount.fetchMultiple([
  ACCOUNT_ADDRESS_ONE,
  ACCOUNT_ADDRESS_TWO,
]);

作者:GTokenTool 来源:https://www.gtokentool.com

  • 原创
  • 学分: 2
  • 分类: Solana
  • 标签:
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
想样
想样
江湖只有他的大名,没有他的介绍。