npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@bhaltair/anchor-sdk

v0.1.36

Published

TypeScript SDK for interacting with Anchor ecosystem - badge minting, payment processing, and ERC1155 token management

Readme

Anchor SDK

npm version License: MIT TypeScript

Anchor SDK 是一个用于与 Anchor 生态系统交互的 TypeScript 开发工具包,支持徽章铸造、支付处理和 ERC1155 代币管理。

✨ 特性

  • 🌐 多网络支持 - 支持以太坊主网、Saigon、Ronin、Base Sepolia、Bera 等多个网络
  • 🔐 双模式支持 - 同时支持账户抽象(AA)和外部拥有账户(EOA)模式
  • 🎯 简单易用 - 提供直观的 API 接口进行徽章铸造和查询
  • 💰 多种支付方式 - 支持使用 ETH 或 ERC20 代币购买徽章
  • ✍️ 自定义签名 - 支持使用自定义签名购买徽章
  • 🆓 免费铸造 - 支持铸造免费徽章
  • 📝 完全类型化 - 提供完整的 TypeScript 类型支持,确保良好的开发体验
  • 批量操作 - 支持批量铸造和 multicall 操作
  • 🔄 React 支持 - 提供 React Hook 和组件

📦 安装

使用 npm

npm install @keccak256-evg/anchor-sdk

使用 yarn

yarn add @keccak256-evg/anchor-sdk

使用 pnpm

pnpm add @keccak256-evg/anchor-sdk

📋 依赖要求

Anchor SDK 需要以下依赖:

  • Node.js: >= 16.0.0
  • TypeScript: >= 4.5.0 (如果使用 TypeScript)
  • viem: ^2.23.9
  • ethers: ^6.15.0

可选依赖

  • React: ^19.0.0 (如果使用 React 组件)
  • @types/react: ^19.0.10 (如果使用 TypeScript 和 React)

🚀 快速开始

1. 初始化 SDK

import { createPublicClient, createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { mainnet } from "viem/chains";
import { AnchorSDK, NETWORKS, Environment } from "@keccak256-evg/anchor-sdk";

// 创建客户端
const rpcUrl = "https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY";
const privateKey = "0xYOUR_PRIVATE_KEY";

const publicClient = createPublicClient({
  chain: mainnet,
  transport: http(rpcUrl),
});

const account = privateKeyToAccount(
  `0x${
    privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey
  }` as `0x${string}`
);

const walletClient = createWalletClient({
  account,
  chain: mainnet,
  transport: http(rpcUrl),
});

// 创建 SDK 实例
const sdk = new AnchorSDK({
  publicClient,
  walletClient,
  network: NETWORKS.mainnet,
  // 可以指定环境,支持 DEV、BETA 和 PROD
  env: Environment.DEV,
  // 也可以直接指定 API URL,这将覆盖环境配置
  // apiBaseUrl: "https://api.example.com",
  authToken: "YOUR_JWT_TOKEN",
  clientId: "YOUR_CLIENT_ID",
});

2. 使用 ETH 购买徽章(EOA 模式)

// 直接发送交易
const txHash = await sdk.buyBadgeWithETH(
  "0xRECIPIENT_ADDRESS", // 接收徽章的地址
  "0xCONTRACT_ADDRESS", // 合约地址
  1, // Badge ID
  1, // 数量
  "0xRECEIPT_ADDRESS", // 接收支付的地址
  {
    value: "0.1", // 支付金额(ETH)
    gas: 300000n, // 可选:指定 gas 限制
    sendTransaction: true, // 明确指定直接发送交易
  }
);

console.log(`交易已发送: ${txHash}`);

3. 使用 ETH 购买徽章(AA 模式)

// 只返回交易数据,不发送交易
const txData = await sdk.buyBadgeWithETH(
  "0xRECIPIENT_ADDRESS", // 接收徽章的地址
  "0xCONTRACT_ADDRESS", // 合约地址
  1, // Badge ID
  1, // 数量
  "0xRECEIPT_ADDRESS", // 接收支付的地址
  {
    value: "0.1", // 支付金额(ETH)
    sendTransaction: false, // 指定不发送交易,只返回交易数据
  }
);

console.log(`交易数据: ${txData}`);
// 使用你的 AA 钱包发送此交易数据

4. 铸造免费徽章

import { createPublicClient, createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { saigon, baseSepolia } from "viem/chains";
import { AnchorSDK, NETWORKS, Environment } from "@keccak256-evg/anchor-sdk";

// 创建客户端
const privateKey = "0xYOUR_PRIVATE_KEY";

// 这里使用 saigon 测试网,也可以使用 baseSepolia 或其他支持的网络
const publicClient = createPublicClient({
  chain: saigon,
  transport: http(),
});

const account = privateKeyToAccount(
  `0x${
    privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey
  }` as `0x${string}`
);

const walletClient = createWalletClient({
  account,
  chain: saigon,
  transport: http(),
});

// 创建 SDK 实例
const sdk = new AnchorSDK({
  publicClient,
  walletClient,
  env: Environment.DEV,
  network: NETWORKS.saigon,
  authToken: "YOUR_JWT_TOKEN",
  clientId: "YOUR_CLIENT_ID",
});

try {
  // 使用封装的 mintFreeBadge 方法(推荐)
  // 这个方法会自动从后端获取签名请求并执行铸造
  const customerAddress = account.address;
  const contractAddress =
    "0x23Da7778F6152D7B91C20808bEF7163c5EC2C470" as `0x${string}`; // 替换为合约地址
  const claimableIds = ["CLAIMABLE_ID"]; // 替换为实际的可领取 ID

  const txHash = await sdk.mintFreeBadge(
    customerAddress,
    contractAddress,
    claimableIds,
    { sendTransaction: true } // 明确指定直接发送交易
  );

  console.log(`免费徽章铸造交易已提交:${txHash}`);

  // 检查铸造结果
  const receipt = await publicClient.waitForTransactionReceipt({
    hash: txHash,
  });
  console.log(`铸造成功: ${receipt.status === "success"}`);
} catch (error) {
  console.error("铸造免费徽章失败:", error);
}

5. 使用纯支付功能

import { createPublicClient, createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { saigon } from "viem/chains";
import { AnchorSDK, Environment } from "@keccak256-evg/anchor-sdk";

// 创建客户端
const privateKey = "0xYOUR_PRIVATE_KEY";

const publicClient = createPublicClient({
  chain: saigon,
  transport: http(),
});

const account = privateKeyToAccount(
  `0x${
    privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey
  }` as `0x${string}`
);

const walletClient = createWalletClient({
  account,
  chain: saigon,
  transport: http(),
});

// 创建 SDK 实例
const sdk = new AnchorSDK({
  publicClient,
  walletClient,
  env: Environment.DEV,
  network: NETWORKS.saigon,
});

try {
  // EOA 模式 - 直接发送交易
  const txHash = await sdk.pay(
    "order-123", // 订单 ID
    "0.01", // 支付金额(ETH)
    "0xRECEIPT_ADDRESS", // 接收地址
    { sendTransaction: true } // 明确指定直接发送交易
  );

  console.log(`交易已提交:${txHash}`);

  // AA 模式 - 只返回交易数据,不发送交易
  const txData = await sdk.pay(
    "order-456", // 订单 ID
    "0.05", // 支付金额(ETH)
    "0xRECEIPT_ADDRESS", // 接收地址
    { sendTransaction: false } // 指定不发送交易,只返回交易数据
  );

  console.log("交易数据:", txData);
  // 使用你的 AA 钱包发送此交易数据
} catch (error) {
  console.error("支付失败:", error);
}

6. 使用自定义签名购买徽章

import { createPublicClient, createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { mainnet, saigon } from "viem/chains";
import { AnchorSDK, NETWORKS, Environment } from "@keccak256-evg/anchor-sdk";
import MugenApiClient from "./MugenApiClient";

// 创建客户端
const rpcUrl = "https://saigon-testnet.roninchain.com/rpc";
const privateKey = "0xYOUR_PRIVATE_KEY";

const publicClient = createPublicClient({
  chain: saigon,
  transport: http(rpcUrl),
});

const account = privateKeyToAccount(
  `0x${
    privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey
  }` as `0x${string}`
);
const userAddress = account.address;

const walletClient = createWalletClient({
  account,
  chain: saigon,
  transport: http(rpcUrl),
});

// 创建 SDK 实例
const sdk = new AnchorSDK({
  publicClient,
  walletClient,
  network: NETWORKS.saigon,
  env: Environment.BETA,
});

// 从 Mugen API 获取签名数据
const mugenApiClient = new MugenApiClient(
  "https://api.mugen.com/",
  "YOUR_JWT_TOKEN"
);

try {
  // 创建订单
  const orderResult = await mugenApiClient.orderCreate(
    "PRODUCT_CODE",
    "PRODUCT_ID",
    userAddress
  );

  console.log("创建订单结果:", orderResult);

  if (orderResult.success && orderResult.obj) {
    // 使用 SDK 的自定义签名方法购买徽章
    const signedRequest = {
      request: {
        to: userAddress,
        tokenId: "TOKEN_ID",
        amount: 1,
        price: "0.01",
        currency: "0x0000000000000000000000000000000000000000", // ETH的地址是零地址
        deadline: Math.floor(Date.now() / 1000) + 3600, // 1小时后过期
        quantity: 1,
      },
      signature: orderResult.obj.signature,
    };

    const txHash = await sdk.buyBadgeWithETHWithSignedRequest(
      signedRequest,
      userAddress, // 接收地址
      { value: "0.01", sendTransaction: true }
    );

    console.log("交易已发送:", txHash);
  } else {
    console.error("创建订单失败:", orderResult);
  }
} catch (error) {
  console.error("购买徽章失败:", error);
}

🎯 DApp 函数调用场景

在 dApp 中,您可以在以下特定情况下调用这些函数来与 Anchor SDK 交互:

  • buyBadgeWithETH: 当用户想要使用 ETH 购买徽章时调用此函数,在 EOA 模式下直接发送交易,或在 AA 模式下获取交易数据而不发送。
  • buyBadgeWithETHWithSignedRequest: 用于使用预签名请求购买徽章,通常在集成外部 API 进行自定义签名时使用。
  • buyBadgeWithERC20: 当用户使用 ERC20 代币购买徽章时调用此函数,处理代币批准和转账。
  • buyBadgeWithERC20WithCustomSignature: 用于需要签名请求的 ERC20 购买,例如来自后端的验证订单场景。
  • pay: 用于一般支付,如使用 ETH 处理订单或为 AA 钱包获取交易数据。
  • mintFreeBadge: 为符合条件的用户铸造免费徽章时调用此函数,通常在从 API 获取可领取 ID 后使用。
  • 其他函数: 对于批量操作或高级交互,请参考 batchMintBadge 等方法在单个交易中进行多次铸造。

🌐 支持的网络

SDK 支持多种网络,包括:

| 网络 | 类型 | 链 ID | 说明 | | ------------------ | ------ | ----- | ------------------- | | mainnet | 主网 | 1 | 以太坊主网 | | saigon | 测试网 | 2021 | Saigon 测试网 | | ronin | 主网 | 2020 | Ronin 网络 | | baseSepolia | 测试网 | 84532 | Base Sepolia 测试网 | | berachain | 主网 | 80094 | Bera 主网 | | berachainBepolia | 测试网 | 80085 | Bera 测试网 | | abstractTestnet | 测试网 | 11124 | Abstract 测试网 | | base | 主网 | 8453 | Base 主网 | | abstract | 主网 | 11111 | Abstract 主网 |

🔐 API 认证

使用 Anchor API 功能时,需要提供以下认证参数:

  • authToken - JWT 令牌,格式为 "your-jwt-token"
  • clientId - 客户端标识

您可以在初始化 SDK 时提供这些参数,也可以在运行时更新:

// 初始化时设置
const sdk = new AnchorSDK({
  // 其他配置...
  apiBaseUrl: "https://api.example.com",
  authToken: "YOUR_JWT_TOKEN",
  clientId: "YOUR_CLIENT_ID",
});

// 运行时更新
sdk.anchorApi.setAuthToken("NEW_JWT_TOKEN");
sdk.anchorApi.setClientId("NEW_CLIENT_ID");

Token 过期处理

SDK 提供了 token 过期回调机制,当 API 调用遇到 token 过期错误时,会自动调用回调函数:

// 初始化时设置 token 过期回调
const sdk = new AnchorSDK({
  // 其他配置...
  apiBaseUrl: "https://api.example.com",
  authToken: "YOUR_JWT_TOKEN",
  clientId: "YOUR_CLIENT_ID",
  onTokenExpired: (error: Error) => {
    console.log("Token 已过期:", error.message);

    // 处理 token 过期逻辑
    // 例如:刷新 token、重新登录、通知用户等
    refreshToken().then((newToken) => {
      sdk.anchorApi?.setAuthToken(newToken);
      console.log("Token 已刷新");
    });
  },
});

// 运行时设置 token 过期回调
sdk.setTokenExpiredCallback((error: Error) => {
  console.log("Token 已过期:", error.message);
  // 处理 token 过期逻辑
});

回调函数会在以下情况下触发:

  • 响应体中的 code 字段为 params.jwt.check.invalid(即使 HTTP 状态码为 200)

错误码说明

当 API 返回 code: "params.jwt.check.invalid" 时,表示 JWT token 验证失败,可能的原因包括:

  • Token 已过期
  • Token 格式不正确
  • Token 签名无效
  • Token 被撤销

注意:即使 token 过期,API 也可能返回 HTTP 状态码 200,SDK 会检查响应体中的错误码来判断 token 是否有效。

SDK 会自动检测这种错误码并调用回调函数,让您可以执行相应的处理逻辑。

📚 API 文档

核心类

AnchorSDK

主要的 SDK 类,提供与 Anchor 生态系统交互的所有功能。

class AnchorSDK {
  constructor(config: AnchorSDKConfig);

  // 徽章购买方法
  buyBadgeWithETH(
    customerAddress: string,
    contractAddress: string,
    tokenId: string | number | bigint,
    quantity: string | number | bigint,
    receiptAddress: string,
    options?: PaymentOptions
  ): Promise<TransactionReceipt | { to: string; data: string; value: bigint }>;

  buyBadgeWithETHWithSignedRequest(
    signedRequest: SignedMintRequest,
    receiptAddress: string,
    options?: PaymentOptions
  ): Promise<TransactionReceipt | { to: string; data: string; value: bigint }>;

  buyBadgeWithERC20(
    customerAddress: string,
    contractAddress: string,
    tokenId: string | number | bigint,
    quantity: string | number | bigint,
    currency: string,
    receiptAddress: string,
    options?: PaymentOptions
  ): Promise<TransactionReceipt | { to: string; data: string; value: bigint }>;

  // 免费铸造方法
  mintFreeBadge(
    customerAddress: string,
    contractAddress: string,
    tokenIds: string[],
    options?: { sendTransaction?: boolean }
  ): Promise<
    | TransactionReceipt
    | { to: string; data: string; value: bigint }
    | { to: string; data: string; value: bigint }[]
  >;

  // 批量操作
  batchMintBadge(
    customerAddress: string,
    contractAddress: string,
    tokenIds: string[],
    options?: { sendTransaction?: boolean }
  ): Promise<
    TransactionReceipt | { to: string; data: string; value: bigint }[]
  >;

  batchMintBadgeWithMulticall(
    customerAddress: string,
    contractAddress: string,
    tokenIds: string[],
    options?: { sendTransaction?: boolean }
  ): Promise<TransactionReceipt | { to: string; data: string; value: bigint }>;

  // 支付方法
  pay(
    orderId: string,
    amount: string | number | bigint,
    receiptAddress: string,
    options?: PaymentOptions
  ): Promise<TransactionReceipt | { to: string; data: string; value: bigint }>;

  sendPaymentWithNativeToken(params: {
    callData: `0x${string}`;
    amount: string | number | bigint;
    receiptAddress: string;
    contractName?: string;
    options?: PaymentOptions;
  }): Promise<TransactionReceipt | { to: string; data: string; value: bigint }>;

  sendPaymentWithERC20(params: {
    callData: `0x${string}`;
    amount: string | number | bigint;
    receiptAddress: string;
    tokenAddress: string;
    contractName?: string;
    options?: PaymentOptions;
  }): Promise<TransactionReceipt | { to: string; data: string; value: bigint }>;

  // 工具方法
  setWalletClient(signerOrWalletClient: any): AnchorSDK;
  setTokenExpiredCallback(callback: (error: Error) => void): void;
  processTransactionHash(txHash: string): Promise<any>;
  getERC20ApprovalData(
    tokenAddress: Address,
    amount: bigint,
    spender?: Address
  ): { to: string; data: string; value: bigint };
}

类型定义

AnchorSDKConfig

SDK 配置接口:

interface AnchorSDKConfig {
  provider?: string | any; // Provider URL 或 Web3 Provider
  signer?: any; // 可选的签名者或钱包
  network: {
    // 网络信息
    id: number;
    name: string;
    [key: string]: any;
  };
  env: Environment; // 环境枚举
  apiBaseUrl?: string; // API 基础 URL
  authToken?: string; // 认证令牌
  projectId?: string; // 项目 ID
  anchorPayAddress?: string; // AnchorPay 合约地址
  anchorERC1155Address?: string; // AnchorERC1155 合约地址
  publicClient?: PublicClient; // 公共客户端
  walletClient?: WalletClient; // 钱包客户端
  account?: Account; // 账户信息
  onTokenExpired?: (error: Error) => void; // Token 过期回调
}

PaymentOptions

支付选项接口:

interface PaymentOptions {
  autoApprove?: boolean; // 是否自动批准 ERC20 代币
  gas?: bigint; // Gas 限制
  maxFeePerGas?: bigint; // 最大 Gas 费用
  maxPriorityFeePerGas?: bigint; // 最大优先费用
  value?: bigint; // 交易值
  nonce?: number; // 交易 nonce
  sendTransaction?: boolean; // 是否直接发送交易
}

SignedMintRequest

签名铸造请求接口:

interface SignedMintRequest {
  request: IMintRequest; // 铸造请求
  signature: string; // 签名
}

interface IMintRequest {
  to: Address; // 接收者地址
  tokenId: number | bigint; // 代币 ID
  quantity: number | bigint; // 数量
  price: bigint; // 价格
  currency: Address; // 货币地址
  validityStartTimestamp?: number | bigint; // 有效期开始时间戳
  validityEndTimestamp?: number | bigint; // 有效期结束时间戳
  uid: Hex; // 唯一 ID
  chainId: bigint; // 链 ID
  contractAddress?: string; // 合约地址
  projectHandle?: string; // 项目句柄
}

环境配置

Environment

环境枚举:

enum Environment {
  DEV = "dev", // 开发环境
  BETA = "beta", // 测试环境
  PROD = "prod", // 生产环境
}

React 支持

SDK 还提供了 React Hook 和组件支持:

import { useAnchorSDK, AnchorProvider } from "@keccak256-evg/anchor-sdk/react";

// 使用 Hook
const { sdk, loading, error } = useAnchorSDK();

// 使用 Provider
<AnchorProvider config={sdkConfig}>
  <YourApp />
</AnchorProvider>;

🛠️ 开发指南

本地开发

  1. 克隆仓库:
git clone https://github.com/keccak256-evg/anchor-sdk.git
cd anchor-sdk
  1. 安装依赖:
npm install
  1. 构建项目:
npm run build
  1. 运行测试:
npm test

项目结构

src/
├── index.ts                 # 主入口文件
├── AnchorSDK.ts            # 核心 SDK 类
├── AnchorPayClient.ts      # AnchorPay 客户端
├── AnchorERC1155Client.ts  # AnchorERC1155 客户端
├── AnchorApiClientV2.ts    # API 客户端
├── constants.ts            # 常量定义
├── types.ts               # 类型定义
├── abi/                   # 合约 ABI
├── generated/             # 生成的 API 代码
├── react/                 # React 组件和 Hook
└── utils/                 # 工具函数

🤝 贡献

我们欢迎社区贡献!请遵循以下步骤:

  1. Fork 这个仓库
  2. 创建您的特性分支 (git checkout -b feature/AmazingFeature)
  3. 提交您的更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 打开一个 Pull Request

贡献指南

  • 请确保您的代码遵循项目的 TypeScript 配置
  • 添加适当的测试覆盖
  • 更新相关文档
  • 遵循现有的代码风格

📄 许可证

本项目采用 MIT 许可证 - 查看 LICENSE 文件了解详情。

🔗 相关链接

📞 支持

如果您遇到任何问题或有疑问,请:

  1. 查看 文档
  2. 搜索 Issues
  3. 创建新的 Issue