# @arkiv-network/sdk 中文文档

规范地址：https://npmcn.com/package/%40arkiv-network/sdk/

版本：1\.0\.1
npm 元数据更新时间：2026-11-02T19:53:54.703Z
中文译文更新时间：2026-11-06T19:33:54.569Z
软件包许可：未声明

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40arkiv-network/sdk
原文对照：https://npmcn.com/package/%40arkiv-network/sdk/?lang=original
项目主页：https://arkiv.network/
源码仓库：https://github.com/Arkiv-Network/arkiv-sdk-js

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：1.7 MB，174 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=18\.0\.0
- 运行依赖：0 个
- peer 依赖：viem ^2\.0\.0，typescript \>=5\.0\.0
- 首次发布：2025-10-20T09:31:49.089Z
- 最新版本发布：2026-11-02T19:53:54.373Z
- 近 30 天下载量：7401（2026-10-07 至 2026-11-05，npm 官方下载统计）
- 已发布版本数：100（近 12 个月 76 个）

## 中文简介

用于 Arkiv 块链交互的 TypeScript 客户端库

## 安装

```sh
npm install @arkiv-network/sdk
```

也可以使用：`pnpm add @arkiv-network/sdk`、`yarn add @arkiv-network/sdk`、`bun add @arkiv-network/sdk`

## README

# 方块

一个用于 Arkiv 块链交互的 TypeScript 客户端库. Arkiv SDK大力发展 [维埃姆](https://github.com/wevm/viem) library - 它扩展了Viem的客户端,带有Arkiv的链式特有功能.

[`viem`](https://viem.sh/) 是一个 **同伴依赖**安装在SDK旁边.

## 安装

```bash
npm install @arkiv-network/sdk viem
# or
pnpm install @arkiv-network/sdk viem
# or
bun add @arkiv-network/sdk viem
# or
yarn add @arkiv-network/sdk viem
```

## 使用量

下面是帮助您创建使用 Arkiv 查询和写入数据的简单脚本的教程.

### 先决条件

-   **节点js 22.1.0或更新** (见 [节点js.org](https://nodejs.org/)),或 [`bun`](https://bun.sh/),一个JavaScript/TypeScript运行时间和包管理器,在本地支持TypeScript而无需转接.
-   **Arkiv 访问密钥 .** Arkiv的公开RPC在防止虐待方面受到很大限制,因此我们建议在 [网络/接入密钥](https://hub.arkiv.network/access-keys)。 。 。 .
-   **一些测试网资金.** 写一个实体是一种交易,其气体以 tGLM 测试网支付. 从水龙头取来一些你的账户地址 [网络/浮标](https://hub.arkiv.network/faucet)。 。 。 . [项目设置](https://npmcn.com/package/%40arkiv-network/sdk/#readme-project-setup) 显示在没有账户的情况下如何创建账户.

### 项目设置

创建新目录并浏览其中 :

```bash
mkdir arkiv-sample
cd arkiv-sample
```

创建空 `example.ts` 文件 :

```bash
touch example.ts
```

初始化一个新的 JavaScript/ TypeScript 项目 :

```bash
npm init
```

您可以按下所有默认选项 `Enter` 在每一个提示. 这一步之后 `package.json` 将创建类似内容的文件 :

```json
{
  "name": "arkiv-sample",
  "version": "1.0.0",
  "description": "",
  "license": "ISC",
  "author": "",
  "type": "commonjs",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  }
}
```

修改 `"main"` 条目为 `"example.ts"` 设置 `"type"` 改为 `"module"` 这么说你 `package.json` 看起来像这样:

```json
{
  "name": "arkiv-sample",
  "version": "1.0.0",
  "description": "",
  "license": "ISC",
  "author": "",
  "type": "module",
  "main": "example.ts",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  }
}
```

安装 `@arkiv-network/sdk` 联合国 `viem` 使用您首选的软件包管理器对等依赖 :

```bash
npm install @arkiv-network/sdk viem
```

此命令将更新您的 `package.json` 其中有一节如下:

```json
"dependencies": {
  "@arkiv-network/sdk": "^0.9.0",
  "viem": "^2.38.2"
}
```

它还将创建一个 `node_modules` 安装了所有依赖关系的目录.

如果你还没有测试网的账户, 创建一个Viem。 此打印出一个新的私人密钥及其地址 :

```bash
node --input-type=module -e "import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'; const key = generatePrivateKey(); console.log('Private key:', key); console.log('Address:', privateKeyToAccount(key).address)"
```

资助地址 [水龙头](https://hub.arkiv.network/faucet)。 。 。 .

最后,创建一个 `.env` 带有访问密钥和私人密钥的文件。 例子从那里读出来,所以你代码里都没有:

```bash
ARKIV_ACCESS_KEY=your-access-key
PRIVATE_KEY=0x-your-private-key
```

### 定义外观

Arkiv存储实体,而一个实体是一组被命名,被打入的属性. 你曾经描述过他们 schema,多用 SQL 来描述表格的列,并按列选择节点 索引它。 只有索引列才能被过滤;其余的可以存储和选择,不能 支付指数.

以下是博客文章使用这一计划的例子。 每个例子都表扬在自己的顶端 文件,以便它作为Node.js、Bun或 `tsc` 类似:

```typescript
import { addr, bytes, dec, defineSchema, str } from "@arkiv-network/sdk/schema"

// Called with no arguments, a type constructor describes a column.
const Posts = defineSchema("posts", {
  author:    addr().indexed(),
  category:  str().indexed(),
  score:     dec().indexed(),
  title:     str(),                          // stored, not indexed
  body:      bytes(),                        // a blob; bytes can never be indexed
  thumbnail: bytes().optional(),             // any number of bytes columns; this one may be absent
  mimeType:  str().default("text/markdown"), // written on create when left out
})
```

类型构造器是 `bool`, (中文(简体) ), `i32`, (中文(简体) ), `u64`, (中文(简体) ), `u256`, (中文(简体) ), `dec`, (中文(简体) ), `str`, (中文(简体) ), `addr`, (中文(简体) ), `key` 财务报告和审定财务报表 `bytes`。 。 。 . 每栏可采用下列方法加以改进: `.indexed()` (每类但 `bytes`, (中文(简体) ), `.optional()` 财务报告和审定财务报表 `.default(...)`。 。 。 .

相同的构造器,使用一个值,生成一个打入的值: `dec("4.1")` 是一个小数, SQL 方式 已经 `DECIMAL` 作为类型和 `DECIMAL '4.1'` 当作一字.

Schema是 SDK 边会:节点只看到属性,每个属性都有类型和索引 旗帜。 计划是您写作和阅读的键盘, 并在运行时检查.

这个名字, `"posts"`,是可选但建议。 一个命名的图案标记它创建的每个实体 已索引 `arkiv.schema` 属性持有其名称,通过它查询时只匹配实体 用那个标记——一种收藏将一个模型的文档与另一个模型的文档分开的方式. 为了这个 原因 `arkiv.schema` 无法用作列名.

### 创建实体

粘贴如下 `example.ts`。它设置了一个公共客户端,该客户端读取,以及一个钱包客户端,该客户端在交易中签名并发送交易,然后通过计划创建一个帖子:

```typescript
import { createPublicClient, createWalletClient, ExpirationTime } from "@arkiv-network/sdk"
import { rabdi } from "@arkiv-network/sdk/chains"
import { and, eq, gt } from "@arkiv-network/sdk/query"
import { addr, bytes, dec, defineSchema, str } from "@arkiv-network/sdk/schema"
import { hexToString, http, isHex, stringToBytes } from "viem"
import { privateKeyToAccount } from "viem/accounts"

// The schema from "Define a Schema" above
const Posts = defineSchema("posts", {
  author:    addr().indexed(),
  category:  str().indexed(),
  score:     dec().indexed(),
  title:     str(),
  body:      bytes(),
  thumbnail: bytes().optional(),
  mimeType:  str().default("text/markdown"),
})

// Rabdi is the Arkiv testnet
const chain = rabdi({ accessKey: process.env.ARKIV_ACCESS_KEY ?? "" })

const privateKey = process.env.PRIVATE_KEY
if (!privateKey || !isHex(privateKey)) {
  throw new Error("Set PRIVATE_KEY in .env to the private key of a funded testnet account")
}
const account = privateKeyToAccount(privateKey)

const publicClient = createPublicClient({ chain, transport: http() })
const walletClient = createWalletClient({ chain, transport: http(), account })

// Create an entity. Every required column must be given; a defaulted one (mimeType) left out is
// written with its default. Values carry their type: use the constructors from
// "@arkiv-network/sdk/schema", or a bare string, boolean, number, bigint or Uint8Array where it is
// unambiguous (string -> str, Uint8Array -> bytes, ...). createEntity resolves once the
// transaction is in a block.
const { entityKey, txHash } = await walletClient.createEntity(
  Posts,
  {
    author: addr(account.address),
    category: "docs",
    score: dec("4.5"),
    title: "Hello from Arkiv",
    body: stringToBytes("# Hello\n\nArkiv wishes you all the best!"),
  },
  { expiration: ExpirationTime.fromDays(1) }, // the entity expires in a day
)
console.log("Created entity:", entityKey)
console.log("Transaction hash:", txHash)

// Change one column, leaving the rest alone
await walletClient.patchEntity(Posts, entityKey, { set: { score: dec("4.7") } })
```

### 查询它

现在读回帖子。 在结尾添加以下内容: `example.ts`数字 :

```typescript
// Get the entity by key, read through the schema
const post = await publicClient.getEntity(entityKey, Posts)
console.log("Title:", post.title.value, "score:", post.score.value)

// Or find it with a query: select what to return, name the schema, then filter
const result = await publicClient
  .select({ $key: true, title: true, score: true, body: true })
  .from(Posts)
  .where(and(eq("category", "docs"), gt("score", dec("4.0"))))
  .ownedBy(account.address)
  .limit(10)
  .fetch()

for (const row of result.entities) {
  console.log(row.$key, row.title.value, row.score.value, hexToString(row.body.value))
}
```

#### 选择字段 `select()`

传递无( 或) `"*"`——通过计划、每个实体领域和每个 栏中——或通过一个对象只获取特定字段。 选择名称实体字段和 属性并列,每个结果都是平行。 实体字段从 `$`就像他们一样 `where`数字 : `$key`, (中文(简体) ), `$owner`, (中文(简体) ), `$creator`, (中文(简体) ), `$createdAt`, (中文(简体) ), `$updatedAt`, (中文(简体) ), `$expiresAt` 财务报告和审定财务报表 `$creationFlags`。任何其他名称都是属性。 属性名称不能从 `$`,所以请 二从不相撞——一个叫做 `owner` 刚刚 `owner`数字 :

```typescript
// Every entity field and every column
await publicClient.select().from(Posts).where(eq("category", "docs")).fetch();

// Only the fields you need
await publicClient.select({ $key: true, title: true }).from(Posts).where(eq("category", "docs")).fetch();
```

**仅选择所需.** 每个选定的字段都会从网络中获取, 所以请求 您不会使用的数据会让查询更慢。 缩小选择范围使响应量小而快.

从您的选择和计划中推断出结果类型: 每个列作为计划键入 声明它,读取您没有选择的字段是一个编译错误 .

```typescript
const row = (
  await publicClient.select({ $owner: true, score: true }).from(Posts).where(eq("category", "docs")).fetch()
).entities[0]!;
row.$owner;   // ✅ Hex
row.score;    // ✅ DecValue — row.score.value is "4.1"
row.title;    // ❌ compile error — not selected
```

`where` 将对照计划检查。 它需要Schema的索引列和系统 属性 `$key`, (中文(简体) ), `$owner`, (中文(简体) ), `$creator` 财务报告和审定财务报表 `$expiresAt`。在列上过滤时,计划不会 索引,或将一列与另一类型的数值相比较,是一个编译错误:

```typescript
.where(eq("title", "x"))   // ❌ title is not indexed
.where(eq("score", 5))     // ❌ score is a dec, 5 is an i32 — write dec(5)
.where(between("score", dec(1), 5))  // ❌ both bounds need one type
```

排序为 `orderBy`,通过一个键:a `asc(...)` 或一个 `desc(...)`调用 `orderBy` 再来一次 替换命令。 节点将属性排序为一种类型,所以密钥有一种类型: 通过一个计划它是 列,和系统属性 `$key`, (中文(简体) ), `$owner`, (中文(简体) ), `$creator` 财务报告和审定财务报表 `$expiresAt` 已经修正 这些。 没有计划,写吧。 打电话 `orderBy` 之后 `from(...)`,因此编译器可以检查 密钥对照方案; 仅在发送查询时检查前给定的密钥 :

```typescript
import { asc, desc } from "@arkiv-network/sdk/query"

.from(Posts).orderBy(desc("score"))      // score:dec DESC
.from(Posts).orderBy(asc("title"))       // title:str ASC, indexed or not
.from(Posts).orderBy(asc("$expiresAt"))  // $expiresAt:u64 ASC
.where(eq("category", "docs")).orderBy(desc("score", "dec"))  // without a schema
.from(Posts).orderBy(asc("body"))    // ❌ bytes cannot be sorted on
.from(Posts).orderBy(desc("$createdAt"))  // ❌ $createdAt cannot be sorted on
.from(Posts).orderBy(desc("score"), asc("$key"))  // ❌ one key only
```

任何一栏,但a `bytes` 一个可以排序,索引或不。 属性未设置或设置为 其它类型,没有值可按每个值排序,并在每个值下排序: `asc`最后一个 `desc`。命令贯穿所有匹配,而不是每个页面.

页为 `limit` 财务报告和审定财务报表 `offset`。页面最多可容纳100行 `offset` 跳过之前的匹配 这个 按一个不变的密钥排序, 如 `$key`,所以页面排行:

```typescript
const page3 = await publicClient
  .select({ $key: true, title: true })
  .from(Posts)
  .orderBy(asc("$key"))
  .limit(20)
  .offset(40)
  .fetch()
```

在两个请求之间创建或删除的实体在它之后会转移偏移,所以一行可以重复 或被错过。 要在其他人写的时候准确读取每个匹配, 页面按键: 保留 `asc("$key")` 排序和过滤器 `gt("$key", key(lastKey))`时 `lastKey` 是最后一个 `$key` 联 合 国 上页。 通过一个计划,通过 `{ onMismatch: "throw" }`: 跳过的实体的一页 没有行,所以没有键可以继续.

一个命名的策略不需要 `where` 完全没有.. `select().from(Posts)` 匹配每个文章。 未命名的策略类型 过滤它,所以 `where` 仅决定哪个实体匹配.

只检查您选择的内容 。 匹配但不符合方案的实体——选定 框,但缺少或持有其他类型,或,对于一个命名的图案,另一个图案 标记 – 放在页面外。 任何人都可以给一个实体写一个查询匹配, 所以一个不 从不辜负别人的阅读 页面可以比其限制少一行,并报告 有多少没有作为 `skipped`。通过 `{ onMismatch: "throw" }` 无法使用 `SchemaMismatchError` 相反:

```typescript
const page = await publicClient.select().from(Posts).where(eq("category", "docs")).fetch();
page.skipped; // matching entities on this page that did not fit Posts
```

一个查询读取相同,没有计划——比如,探索一个节点持有什么. 别管了 `.from(...)` 选择意味着它做了什么 `"*"`,下面),各行保留其 形状。 只有检查不见了,还有一个命名的 schema 标记过滤器: 每个属性都会回来 实体拥有的任何价值,或 `undefined`,以及 `where` 取出任何属性 :

```typescript
const row = (
  await publicClient.select({ $key: true, title: true }).where(eq("category", "docs")).fetch()
).entities[0]!;
row.title;    // ArkivValue | undefined — e.g. { type: "str", value: "Hello" }
```

在不命名的情况下读取每个属性, 请选择 `$attributes`一张他们所有的地图. `"*"` (或 无一无一地)在没有计划时与实体字段并取,因为没有栏 以列表形式列出.

`$attributeSchema` 用于找出实体持有哪些东西而不获取其价值: 属性的名称、类型以及是否索引。 价值可以很大——a `bytes` 属性 超过128KiB, RPC的端点可能会限制它发出的响应,所以100的一页 具有每个属性的实体可能比它返回时还要多。 首先获取计划, 然后选择 名称所需的属性。 它从来没有参与 `"*"`; 按名称选择它 :

```typescript
const page = await publicClient.select({ $key: true, $attributeSchema: true }).where(eq("category", "docs")).fetch();
page.entities[0]?.$attributeSchema; // { title: { type: "str", indexed: false }, body: { type: "bytes", indexed: false } }
```

两者都通过一个计划.

> **脚枪 :** 通过选择的内线。 存储在变量中的选择会拓宽其 `true` 数值 改为 `boolean`,因此只有运行时才知道哪些字段返回,结果的每个字段都是 选项。 如果你需要重用,请注明 `as const`数字 :
> 
> ```typescript
> const fields = { $owner: true, title: true } as const;
> await publicClient.select(fields).from(Posts).where(eq("category", "docs")).fetch();
> ```

### 运行示例

您有多个选项可以运行您的 TypeScript 样本 。 每个装入你的 `.env` 文件 :

-   **带有Node.js(使用实验类型Script支持):**
    
    ```bash
    node --env-file=.env --experimental-strip-types example.ts
    ```
    
-   **带有 Bun( 本地类型脚本支持, 负载) `.env` 单枪匹马:**
    
    ```bash
    bun example.ts
    ```
    
-   **经典节点.js(使用转录到JavaScript):**
    
    1.  如果您还没有安装类型脚本和节点.js类型定义 :
        
        ```bash
        npm install typescript @types/node
        ```
        
    2.  以默认设置初始化类型脚本配置 :
        
        ```bash
        npx tsc --init
        ```
        
        这将创建一个 `tsconfig.json` 文档。 设定 `"types": ["node"]` 在其中,这样 `process.env` 类型检查.
    3.  翻译你的 `.ts` 文件输入 `.js`数字 :
        
        ```bash
        npx tsc --outDir dist
        ```
        
        这创造了一个 `dist` 包含 `example.js` (被转接的代码),连同相应的类型声明和源地图文件.
    4.  运行转写脚本 :
        
        ```bash
        node --env-file=.env dist/example.js
        ```
        

样本代码也可以在 [`sample`](https://npmcn.com/package/%40arkiv-network/sdk/sample) 此仓库的目录 .

## 软件包分发

此软件包支持多个模块格式实现最大兼容性 :

-   **ES 模块** (单位:千美元)`dist/*.js`\- 对于现代 `import` 声明
-   **常见JS** (单位:千美元)`dist/*.cjs`\- 为节点.js `require()`
-   **类型声明** (单位:千美元)`dist/*.d.ts` 财务报告和审定财务报表 `dist/*.d.cts`) - 完整类型脚本支持

建筑用途 [s](https://github.com/rolldown/tsdown) 生成具有适当类型声明的无害环境管理格式和共同JS格式.

### 运行时间支持

**节点.js(ESM):**

```javascript
import { createPublicClient } from '@arkiv-network/sdk';  // Uses compiled ESM
```

**节点.js(CommonJS):**

```javascript
const { createPublicClient } = require('@arkiv-network/sdk');  // Uses compiled CJS
```

**Bun( TypeScript 本地语) :**

```javascript
import { createPublicClient } from '@arkiv-network/sdk'; // Uses *.ts directly
```

所有格式在使用TypeScript时都提供全类型安全性和IntelliSense支持.

## 发展

要安装依赖性 :

```bash
bun install
```

构建所有产出(ESM、CommonJS和类型声明):

```bash
bun run build
```

有关构建SDK的更多信息,请参见: [贝鲁特,md](https://npmcn.com/package/%40arkiv-network/sdk/BUILD.md)

要运行类型检查 :

```bash
bun run type-check
```

给 :

```bash
bun run lint
```

欲了解更多信息,请查阅: [捐款额](https://npmcn.com/package/%40arkiv-network/sdk/CONTRIBUTING.md)

## 微博日志

设定 `DEBUG` 环境变量(或在浏览器中 `DEBUG` 键入 `localStorage`查看动词日志:

```bash
DEBUG=arkiv:* bun run your-script
```

调整命名空间(例如, `arkiv:query:*` 或者说 `arkiv:actions:wallet:*`以特定日志源为目标,前缀1 `-` 将它排除在外。 未设置 `DEBUG` 关闭调试输出.

## 常见问题

### @arkiv-network/sdk 是什么？

用于 Arkiv 块链交互的 TypeScript 客户端库

### 如何安装 @arkiv-network/sdk？

在项目目录运行 npm install @arkiv-network/sdk，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：viem（^2\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @arkiv-network/sdk 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @arkiv-network/sdk 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @arkiv-network/sdk 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=18\.0\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @arkiv-network/sdk 可以商用吗？

@arkiv-network/sdk 使用 未声明 许可。package\.json 没有声明许可证。没有许可证的代码默认保留全部权利，商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括，不构成法律意见，请以许可原文为准。

### @arkiv-network/sdk 的下载量有多少？

根据 npm 官方下载统计，@arkiv-network/sdk 在 2026/10/07 – 2026/11/05 这 30 天内被下载 7,401 次，日均约 247 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @arkiv-network/sdk 还在维护吗？

最新版本 1\.0\.1 发布于 2026/11/03（5 天前）；至今共发布 100 个版本，其中过去 12 个月发布了 76 个；首次发布于 2025/10/20。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

