AgentSkillsCN

near-kit

NEAR Protocol 区块链交互的 TypeScript 库。当您编写与 NEAR Protocol 交互的代码时,可调用此技能——包括查看合约数据、调用合约方法、发送 NEAR 代币、构建交易、创建类型安全的合约封装、集成钱包(Wallet Selector、HOT Connect)、React Hooks 与 Provider(@near-kit/react)、管理密钥、使用沙箱进行测试、处理元交易(NEP-366),以及进行消息签名(NEP-413)。

SKILL.md
--- frontmatter
name: near-kit
description: TypeScript library for NEAR Protocol blockchain interaction. Use this skill when writing code that interacts with NEAR Protocol, including viewing contract data, calling contract methods, sending NEAR tokens, building transactions, creating type-safe contract wrappers, integrating wallets (Wallet Selector, HOT Connect), React hooks and providers (@near-kit/react), managing keys, testing with sandbox, meta-transactions (NEP-366), and message signing (NEP-413).

near-kit

A TypeScript library for NEAR Protocol with an intuitive, fetch-like API.

Quick Start

typescript
import { Near } from "near-kit"

// Read-only (no key needed)
const near = new Near({ network: "testnet" })
const data = await near.view("contract.near", "get_data", { key: "value" })

// With signing capability
const near = new Near({
  network: "testnet",
  privateKey: "ed25519:...",
  defaultSignerId: "alice.testnet",
})
await near.call("contract.near", "method", { arg: "value" })
await near.send("bob.testnet", "1 NEAR")

Core Operations

View Methods (Read-Only, Free)

typescript
const result = await near.view("contract.near", "get_data", { key: "value" })
const balance = await near.getBalance("alice.near")
const exists = await near.accountExists("alice.near")

Call Methods (Requires Signing)

typescript
await near.call(
  "contract.near",
  "method",
  { arg: "value" },
  { gas: "30 Tgas", attachedDeposit: "1 NEAR" }
)

Send NEAR Tokens

typescript
await near.send("bob.near", "5 NEAR")

Type-Safe Contracts

typescript
import type { Contract } from "near-kit"

type MyContract = Contract<{
  view: {
    get_balance: (args: { account_id: string }) => Promise<string>
  }
  call: {
    transfer: (args: { to: string; amount: string }) => Promise<void>
  }
}>

const contract = near.contract<MyContract>("token.near")
await contract.view.get_balance({ account_id: "alice.near" })
await contract.call.transfer({ to: "bob.near", amount: "10" }, { attachedDeposit: "1 yocto" })

Transaction Builder

Chain multiple actions in a single atomic transaction:

typescript
await near
  .transaction("alice.near")
  .transfer("bob.near", "1 NEAR")
  .functionCall("contract.near", "method", { arg: "value" }, { gas: "30 Tgas" })
  .send()

For all transaction actions and meta-transactions, see references/transactions.md

Configuration

Backend/Scripts

typescript
// Direct private key
const near = new Near({
  network: "testnet",
  privateKey: "ed25519:...",
  defaultSignerId: "alice.testnet",
})

// File-based keystore
import { FileKeyStore } from "near-kit/keys/file"
const near = new Near({
  network: "testnet",
  keyStore: new FileKeyStore("~/.near-credentials"),
})

// High-throughput with rotating keys
import { RotatingKeyStore } from "near-kit"
const near = new Near({
  network: "mainnet",
  keyStore: new RotatingKeyStore({
    "bot.near": ["ed25519:key1...", "ed25519:key2...", "ed25519:key3..."],
  }),
})

For all key stores and utilities, see references/keys-and-testing.md

Browser Wallets

typescript
import { NearConnector } from "@hot-labs/near-connect"
import { Near, fromHotConnect } from "near-kit"

const connector = new NearConnector({ network: "mainnet" })

connector.on("wallet:signIn", async (event) => {
  const near = new Near({
    network: "mainnet",
    wallet: fromHotConnect(connector),
  })
  
  await near.call("contract.near", "method", { arg: "value" })
})

connector.connect()

For HOT Connect and Wallet Selector integration, see references/wallets.md

React Bindings (@near-kit/react)

tsx
import { NearProvider, useNear, useView, useCall } from "@near-kit/react"

function App() {
  return (
    <NearProvider config={{ network: "testnet" }}>
      <Counter />
    </NearProvider>
  )
}

function Counter() {
  const { data: count, isLoading } = useView<{}, number>({
    contractId: "counter.testnet",
    method: "get_count",
  })

  const { mutate: increment, isPending } = useCall({
    contractId: "counter.testnet",
    method: "increment",
  })

  if (isLoading) return <div>Loading...</div>
  return <button onClick={() => increment({})} disabled={isPending}>Count: {count}</button>
}

For all React hooks, React Query/SWR integration, and SSR patterns, see references/react.md

Testing with Sandbox

typescript
import { Sandbox } from "near-kit/sandbox"

const sandbox = await Sandbox.start()
const near = new Near({ network: sandbox })

const testAccount = `test-${Date.now()}.${sandbox.rootAccount.id}`
await near
  .transaction(sandbox.rootAccount.id)
  .createAccount(testAccount)
  .transfer(testAccount, "10 NEAR")
  .send()

await sandbox.stop()

For sandbox patterns and Vitest integration, see references/keys-and-testing.md

Error Handling

typescript
import {
  InsufficientBalanceError,
  FunctionCallError,
  NetworkError,
  TimeoutError,
} from "near-kit"

try {
  await near.call("contract.near", "method", {})
} catch (error) {
  if (error instanceof InsufficientBalanceError) {
    console.log(`Need ${error.required}, have ${error.available}`)
  } else if (error instanceof FunctionCallError) {
    console.log(`Panic: ${error.panic}`, `Logs: ${error.logs}`)
  }
}

Unit Formatting

All amounts accept human-readable formats:

typescript
"10 NEAR"     // 10 NEAR
"10"          // 10 NEAR
10            // 10 NEAR
"30 Tgas"     // 30 trillion gas units

Key Utilities

typescript
import {
  generateKey,
  parseKey,
  generateSeedPhrase,
  parseSeedPhrase,
  isValidAccountId,
  Amount,
  Gas,
} from "near-kit"

const { publicKey, privateKey } = generateKey()
const { seedPhrase, publicKey, privateKey } = generateSeedPhrase()
const restored = parseSeedPhrase("word1 word2 ... word12")

isValidAccountId("alice.near") // true
Amount.parse("5 NEAR")  // bigint in yoctoNEAR
Gas.parse("30 Tgas")    // bigint in gas units

References

For detailed documentation on specific topics: