# @pbjpro/relay 中文文档

规范地址：https://npmcn.com/package/%40pbjpro/relay/

版本：1\.3\.0
npm 元数据更新时间：2026-11-02T03:53:31.168Z
中文译文更新时间：2026-11-02T04:03:21.001Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40pbjpro/relay
原文对照：https://npmcn.com/package/%40pbjpro/relay/?lang=original
项目主页：https://0xpbj.pro/
源码仓库：https://github.com/pbjprotocol/relay

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

- 包体积（解压后）：431 kB，19 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=20
- 运行依赖：0 个
- 首次发布：2026-10-28T04:55:42.848Z
- 最新版本发布：2026-11-02T03:53:31.022Z
- 已发布版本数：3（近 12 个月 3 个）

## 中文简介

Relay的USDC里程碑托管协议的TypeScript SDK

## 安装

```sh
npm install @pbjpro/relay
```

也可以使用：`pnpm add @pbjpro/relay`、`yarn add @pbjpro/relay`、`bun add @pbjpro/relay`

## README

# Relay TypeScript SDK

[![npm version](https://img.shields.io/npm/v/@pbjpro/relay?color=a8ff54&label=npm)](https://www.npmjs.com/package/@pbjpro/relay) [![license](https://img.shields.io/badge/license-MIT-black)](https://npmcn.com/package/%40pbjpro/relay/LICENSE) [![Node.js](https://img.shields.io/badge/Node.js-20%2B-black)](https://nodejs.org/) [![Solana](https://img.shields.io/badge/network-Solana-9945FF)](https://solana.com/)

![Relay — your work deserves a funded commitment](https://cyan-worried-mite-516.mypinata.cloud/ipfs/bafkreieqsywmgjdhkg77ligv6ovthbsryqduyszs66ijnrnygdna33xwgm)

Relay是PBJ Protocol的生产TypeScript SDK，用于Solana上的USDC里程碑托管。它帮助应用程序、代理机构、客户和独立团队定义可交付成果，在工作开始之前确保项目预算，保存交付证据，批准发布，并通过明确的规则解决争议。

-   **端到端打字** 严格的TypeScript模型、错误和服务api
-   **没有签字** - Relay准备事务；你的钱包会告诉他们
-   **开发和主网** -明确的网络选择与主网保障
-   **证据准备好了** - GitHub, Figma，谷歌驱动器，url和校验和
-   **安全的运输** -超时、中止信号、幂等、重试控制和编校

> \[!警告) Relay执行资助、证据、批准和发布规则。它不能独立地决定主观的创造性或软件工作是否满足期望。定义可衡量的里程碑标准，并在资助之前选择争议解决者。

## 安装

```bash
npm i @pbjpro/relay
```

当前版本: **v1.3.0**

## 要求

-   Node.js 20或更新版本，或使用 `fetch` 和 `AbortController`
-   用于经过身份验证的服务器操作的中继API密钥
-   一个兼容的Solana钱包，用于签署资金和发布交易
-   所有令牌数量的十进制字符串——绝不是JavaScript浮点数

这个包包括ESM、CommonJS、声明文件和源映射。

## 快速入门

```ts
import { RelayClient } from "@pbjpro/relay";

const relay = new RelayClient({
  apiKey: process.env.RELAY_API_KEY!,
  baseUrl: process.env.RELAY_API_URL,
  network: "devnet",
});
```

将API密钥保存在受信任的服务器上。不要在浏览器包中包含特权中继或集成凭据。

### 环境

```bash
RELAY_API_KEY=relay_test_replace_me
RELAY_API_URL=https://api.0xpbj.pro
RELAY_NETWORK=devnet
RELAY_CONFIRM_MAINNET=false
```

看到 [`.env.example`](https://npmcn.com/package/%40pbjpro/relay/.env.example) 获取完整的配置模板。

## 创建一个托管项目

```ts
const project = await relay.escrows.create({
  name: "Brand redesign",
  clientWallet: "CLIENT_SOLANA_ADDRESS",
  freelancerWallet: "FREELANCER_SOLANA_ADDRESS",
  resolverWallet: "RESOLVER_SOLANA_ADDRESS",
  currency: "USDC",
  milestones: [
    {
      title: "Creative direction",
      amount: "1500.00",
      description: "Approved research and creative direction",
      dueAt: "2027-01-31T00:00:00.000Z",
    },
    {
      title: "Final delivery",
      amount: "3500.00",
      description: "Approved final files and documented handoff",
      dueAt: "2027-02-28T00:00:00.000Z",
    },
  ],
  disputePolicy: {
    resolverType: "human",
    inactivityTimeoutHours: 168,
    evidenceWindowHours: 72,
  },
  idempotencyKey: "brand-redesign-001",
});
```

## 与USDC的资金托管

Relay准备事务。客户端钱包在本地审核并签名。

```ts
const funding = await relay.escrows.prepareFunding({
  projectId: project.id,
  amount: "5000.00",
});

const signature = await wallet.sendTransaction(funding.transaction);

await relay.escrows.confirmFunding({
  projectId: project.id,
  signature,
});
```

Relay不需要钱包种子短语或私钥。

### 管理资金工作流程

高级工作流准备事务，将签名委托给您的钱包，并确认提交的签名。私钥永远不会进入SDK。

```ts
const confirmation = await relay.escrows.fund({
  projectId: project.id,
  amount: "5000.00",
  signTransaction: (transaction) => wallet.sendTransaction(transaction),
  onProgress: ({ stage, signature }) => {
    console.log(stage, signature ?? "");
  },
});
```

## 提交里程碑证据

尽可能固定特定的、不可变的版本。活动分支、设计文件或驱动链接在提交后可能会更改。

```ts
const submission = await relay.milestones.submit({
  milestoneId: "milestone_id",
  summary: "Final files and handoff documentation",
  evidence: [
    {
      type: "github",
      repository: "pbjprotocol/client-project",
      commitSha: "FULL_COMMIT_SHA",
    },
    {
      type: "figma",
      fileKey: "FIGMA_FILE_KEY",
      versionId: "FIGMA_VERSION_ID",
    },
    {
      type: "google_drive",
      fileId: "GOOGLE_DRIVE_FILE_ID",
      checksum: "SHA256_CHECKSUM",
    },
  ],
  idempotencyKey: "delivery-001",
});
```

### 核实交货证据

```ts
const report = await relay.evidence.verify("evidence_id");

if (!report.valid) {
  console.error("Evidence verification failed", report.checks);
}
```

## 批准和放行

```ts
const prepared = await relay.milestones.prepareRelease({
  milestoneId: submission.milestoneId,
});

const signature = await wallet.sendTransaction(prepared.transaction);

await relay.milestones.confirmRelease({
  milestoneId: submission.milestoneId,
  signature,
});
```

签名的区块链事务确认永远不会自动重试。

等效的管理发布工作流可作为 `relay.milestones.release()`：

```ts
await relay.milestones.release({
  milestoneId: submission.milestoneId,
  signTransaction: (transaction) => wallet.sendTransaction(transaction),
});
```

## 解决争议

```ts
const dispute = await relay.disputes.create({
  milestoneId: "milestone_id",
  reason: "delivery_does_not_match_scope",
  statement: "The submitted package omits the agreed mobile layouts.",
  evidenceIds: ["evidence_1", "evidence_2"],
  idempotencyKey: "dispute-001",
});

await relay.disputes.resolve({
  disputeId: dispute.id,
  outcome: "split",
  statement: "Desktop scope delivered; mobile scope remains incomplete.",
  clientAmount: "1800.00",
  freelancerAmount: "1200.00",
});
```

## 人则

在处理webhook之前，始终验证准确的、未修改的请求体。验证包括HMAC认证和时间戳重放保护。

```ts
const event = await relay.webhooks.verify({
  payload: rawRequestBody,
  signature: request.headers["x-relay-signature"],
  secret: process.env.RELAY_WEBHOOK_SECRET!,
});

switch (event.type) {
  case "milestone.submitted":
    console.log(event.data.submission.id);
    break;
  case "dispute.opened":
    console.log(event.data.id);
    break;
}
```

使用 `relay.webhooks.idempotent(store, handler)` 使用数据库或缓存来防止重复传递处理。只有在处理程序成功后才会记录事件。

## 开发和主网

Devnet是开发过程中的默认和推荐环境。

```ts
const relay = new RelayClient({
  apiKey: process.env.RELAY_API_KEY!,
  network: "devnet",
});
```

主网需要明确的确认，永远不会无声地退回到devnet。

```ts
const relay = new RelayClient({
  apiKey: process.env.RELAY_API_KEY!,
  network: "mainnet",
  confirmMainnet: true,
});
```

## 集成

| 集成 | 交付的证据 |
| --- | --- |
| GitHub | 存储库、不可变提交sha、交付活动 |
| Figma | 文件版本，冻结预览，审查意见 |
| 谷歌驱动 | 文件、文件夹、版本元数据、校验和 |

集成令牌应该使用工作流支持的最窄权限。

## 分页

```ts
const page = await relay.milestones.list({
  projectId: project.id,
  status: ["submitted", "in_dispute"],
  page: 1,
  limit: 20,
});

for await (const milestone of relay.milestones.iterate({
  projectId: project.id,
})) {
  console.log(milestone.id, milestone.status);
}
```

## 事务监控

```ts
for await (const update of relay.solana.watchTransaction(signature, {
  timeoutMs: 60_000,
  signal: abortController.signal,
})) {
  console.log(update.status);
}
```

迭代器发出状态变化，并在确认时停止。失败的事务和超时会产生输入错误。

## 输入错误

```ts
import { RelayAuthenticationError, RelayTransactionError } from "@pbjpro/relay";

try {
  await createFundedProject();
} catch (error) {
  if (error instanceof RelayAuthenticationError) {
    console.error("Check RELAY_API_KEY");
  } else if (error instanceof RelayTransactionError) {
    console.error("Transaction failed", error.signature);
  } else {
    throw error;
  }
}
```

所有中继错误暴露 `code`， `message`, `retryable`，加上可选 `statusCode`， `requestId`， `cause`，并有结构 `details`.

## 公共服务

| 服务 | 方法 |
| --- | --- |
| `relay.escrows` | `create`， `get`， `list`， `prepareFunding`， `confirmFunding`， `cancel`， `getBalance`， `getActivity` |
| `relay.milestones` | `create`， `get`， `list`， `iterate`， `submit`， `prepareRelease`， `confirmRelease`， `requestChanges` |
| `relay.evidence` | `create`， `get`， `list`， `refresh`， `getFrozenPreview`， `verifyChecksum` |
| `relay.disputes` | `create`， `get`， `list`， `addEvidence`， `addStatement`， `resolve`， `getTimeline` |
| `relay.integrations` | GitHub， Figma和谷歌驱动证据服务 |
| `relay.solana` | 网络、RPC、USDC铸币厂、交易状态、确认和钱包验证 |
| `relay.webhooks` | HMAC验证，重放保护，重复检测和幂等处理程序 |

## 测试工具

可选的测试入口点提供了不需要网络访问的确定性装置和模拟中继传输。

```ts
import { createRelayMock, projectFixture } from "@pbjpro/relay/testing";

const project = projectFixture();
const mock = createRelayMock([
  { path: `/v1/escrows/${project.id}`, body: project },
]);

const result = await mock.client.escrows.get(project.id);
```

它也输出 `milestoneFixture`， `evidenceFixture`， `webhookFixture`, `signWebhookEvent`.

## 安全检查表

-   将API和集成凭据保持在服务器端。
-   永远不要在Relay配置中存储钱包私钥。
-   在签名之前验证网络、钱包地址、USDC铸币厂、里程碑总数和解析器。
-   对不可变证据使用完整提交sha、冻结设计版本和校验和。
-   对创建和提交工作流使用唯一的等幂键。
-   从应用程序日志中编辑授权标头和敏感主体。
-   签署前审查主网交易。

## 示例

中提供可运行的集成 [`examples`](https://npmcn.com/package/%40pbjpro/relay/examples)：

-   Node.js项目创建、资助、提交、发布和争议流
-   js路由处理程序集成，将API密钥保存在服务器端
-   快速服务器集成与类型化错误处理

## 开发

```bash
npm ci
npm run typecheck
npm run lint
npm test
npm run build
```

其他脚本包括 `test:coverage`， `format`, `format:check`.

## 文档和支持

-   [SDK文档](https://0xpbj.pro/docs)
-   [GitHub库](https://github.com/pbjprotocol/relay)
-   [问题跟踪器](https://github.com/pbjprotocol/relay/issues)
-   [PBJ协议](https://0xpbj.pro/)

## 出版

1.  更新软件包版本和 [`CHANGELOG.md`](https://npmcn.com/package/%40pbjpro/relay/CHANGELOG.md).
2.  运行 `npm ci` 和 `npm run prepublishOnly`.
3.  检查包装 `npm pack --dry-run`.
4.  发布与 `npm publish --access public` 从授权的NPM帐户。

## 许可证

MIT©PBJ协议。看到 [许可证](https://npmcn.com/package/%40pbjpro/relay/LICENSE).

## 常见问题

### @pbjpro/relay 是什么？

Relay的USDC里程碑托管协议的TypeScript SDK

### 如何安装 @pbjpro/relay？

在项目目录运行 npm install @pbjpro/relay，或使用 pnpm add / yarn add / bun add。

### @pbjpro/relay 支持 TypeScript 吗？

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

### @pbjpro/relay 支持 ESM 还是 CommonJS？

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

### @pbjpro/relay 需要什么版本的 Node\.js？

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

### @pbjpro/relay 可以商用吗？

@pbjpro/relay 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @pbjpro/relay 还在维护吗？

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

