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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cgentai/cgent-contracts

v1.0.0

Published

SDK for interacting with Cgent.AI Solidity contracts

Readme

P2P Escrow SDK 文档

本仓库提供一个用于点对点电商场景的资金托管合约 P2PEscrow.sol 以及与之配套的 TypeScript SDK,帮助买卖双方在交易过程中安全地锁定和释放资金。本文档覆盖以下内容:

  • 合约设计概览与角色职责
  • 订单生命周期及状态机
  • 合约公开方法与事件说明
  • 常量、费用与错误类型
  • SDK 安装、初始化及常用调用示例
  • 浏览器环境辅助方法

合约源码位置:contracts/P2PEscrow.sol

SDK 入口:src/index.ts(导出常量、类型与 P2PEscrowClient


1. 合约概览

P2PEscrow 合约主要面向买家(buyer)、卖家(seller)与仲裁者(arbitrator)三个角色:

  • 买家:发起订单并预付代币;在没有争议时可以确认收货或撤回资金。
  • 卖家:在确认收到款项后锁定订单;可在必要时退款或在锁定期后请求释放资金。
  • 仲裁者:当订单进入争议流程时,负责裁定资金归属。
  • 合约拥有者(owner):配置手续费接收地址、仲裁者和可用代币列表。

资金在订单创建时从买家转入合约,直至订单根据流程释放或退款。合约支持多个 ERC-20 代币,通过白名单管理支持的代币地址。

手续费设定为 1%FEE_BPS = 100,基础为 10_000)。手续费统一转入 feeRecipient 地址,其余金额发放给卖家。


2. 订单状态机

合约使用 OrderStatus 枚举区分订单生命周期:

| 数值 | 状态名 | 说明 | | --- | --- | --- | | 0 | None | 默认状态(订单不存在)。 | | 1 | BuyerPaid | 买家支付成功,订单已在合约中锁仓。 | | 2 | SellerLocked | 卖家确认并锁定订单,开始计算锁定期(30 天)。 | | 3 | SellerRefunded | 卖家将资金原路退回买家。 | | 4 | SellerReleased | 订单释放给卖家(扣除手续费)。 | | 5 | BuyerWithdrawn | 买家在卖家锁定前撤回资金。 | | 6 | ArbitrationPending | 仲裁者介入,等待裁决。 | | 7 | ArbitrationBuyer | 仲裁判定资金退回买家。 | | 8 | ArbitrationSeller | 仲裁判定资金释放给卖家(扣除手续费)。 |

锁定期(LOCK_DURATION = 30 days)从卖家调用 lockOrder 时开始计算。锁定期届满后,卖家可调用 sellerRelease 将资金解锁给自己。


3. 合约方法

3.1 配置与查看

  • feeRecipient() -> address:查看手续费接收地址。
  • arbitrator() -> address:查看当前仲裁者地址。
  • owner() -> address:查看合约拥有者。
  • supportedTokens(address token) -> bool:查询代币是否在支持列表。
  • getOrderId(address buyer, address seller, uint256 orderId) -> bytes32:计算订单唯一 key。
  • getOrder(address buyer, address seller, uint256 orderId) -> Order:获取订单结构体。
  • orders(bytes32 orderKey) -> Order:通过订单 key 读取原始存储。

3.2 订单生命周期

  • createOrder(address buyer, address seller, uint256 orderId, uint256 amount, address token)

    • 仅买家调用;检查代币是否支持、金额>0、卖家非零地址;将 amount 转入合约并创建订单。
  • lockOrder(address buyer, uint256 orderId)

    • 仅卖家调用;要求状态为 BuyerPaid;锁定期开始计时,状态改为 SellerLocked
  • buyerWithdraw(address seller, uint256 orderId)

    • 买家在卖家锁定前随时撤回资金,状态变为 BuyerWithdrawn
  • sellerRefund(address buyer, uint256 orderId)

    • 卖家在 BuyerPaidSellerLocked 状态下可主动退款给买家,状态为 SellerRefunded
  • buyerConfirmReceipt(address seller, uint256 orderId)

    • 买家在订单锁定后确认收货,触发 _releaseToSeller,将金额按费率拆分给卖家和手续费地址,状态变为 SellerReleased
  • sellerRelease(address buyer, uint256 orderId)

    • 卖家在锁定期已结束后自助释放资金给自己;状态要求 SellerLocked 且当前时间超过 lockedUntil

3.3 仲裁流程

  • setArbitrationPending(address buyer, address seller, uint256 orderId)

    • 仅仲裁者调用;在 BuyerPaidSellerLocked 状态下进入仲裁,记录上一个状态。
  • cancelArbitration(address buyer, address seller, uint256 orderId)

    • 仲裁者撤消仲裁,将状态还原至进入仲裁前的状态。
  • arbitrate(address buyer, address seller, uint256 orderId, bool releaseToSeller)

    • 仲裁者最终裁决。releaseToSeller = true 时拆分手续费后转给卖家;否则原额退回买家。状态分别变更为 ArbitrationSellerArbitrationBuyer

3.4 管理员操作

  • setFeeRecipient(address newRecipient):合约拥有者更新手续费地址。
  • setArbitrator(address newArbitrator):合约拥有者更新仲裁者。
  • addSupportedToken(address token) / removeSupportedToken(address token):增删支持代币。
  • transferOwnership(address newOwner) / renounceOwnership():标准 Ownable 权限管理。

3.5 内部逻辑

  • _releaseToSeller(Order storage order, bytes32 orderKey):私有函数,用于统一执行释放逻辑,计算手续费并发放资金。

4. 事件

合约定义的主要事件如下:

  • OrderCreated(orderKey, buyer, seller, orderId, token, amount)
  • OrderLocked(orderKey, lockedUntil)
  • BuyerWithdrawn(orderKey)
  • SellerRefunded(orderKey)
  • SellerReleased(orderKey, sellerAmount, feeAmount)
  • ArbitrationPendingSet(orderKey)
  • ArbitrationResolved(orderKey, releasedToSeller, amount, feeAmount)
  • ArbitrationCancelled(orderKey, restoredStatus)
  • FeeRecipientUpdated(newRecipient)
  • ArbitratorUpdated(newArbitrator)
  • SupportedTokenAdded(token) / SupportedTokenRemoved(token)

SDK 提供的 P2PEscrowClient 支持通过 on/once/off/removeAllListeners 订阅这些事件。


5. 常量与错误

  • LOCK_DURATION_SECONDS = 30 * 24 * 60 * 60:卖家锁定后需等待的秒数。
  • FEE_BPS = 100 (1%)BPS_DENOMINATOR = 10_000:手续费计算使用 amount * FEE_BPS / BPS_DENOMINATOR
  • 关键错误:
    • InvalidToken(address):代币或地址无效。
    • InvalidAmount():金额为零。
    • OrderAlreadyExists():同一订单重复创建。
    • Unauthorized():调用方角色不匹配。
    • InvalidStatus():当前订单状态不允许执行操作。
    • LockPeriodActive(uint256):卖家释放时锁定期尚未到期。
    • NothingToRelease():订单金额为零。

6. SDK 使用指南

SDK 基于 ethers@^6,在 Node.js、浏览器或任意支持 ESM/CJS 的环境中均可使用。

6.1 安装

npm install @cgentai/cgent-contracts ethers
# 或者使用 pnpm / yarn

6.2 初始化客户端

import { JsonRpcProvider } from "ethers";
import { P2PEscrowClient } from "@cgentai/cgent-contracts";

const provider = new JsonRpcProvider("https://rpc.sepolia.linea.build");
const signer = await provider.getSigner(); // 也可以用 wallet.connect(provider)

const escrow = new P2PEscrowClient({
  address: "0xEscrowAddress",
  runner: signer,
});

console.log(await escrow.getFeeRecipient());

P2PEscrowClient.connect(address, runner) 提供了便捷的静态初始化方法。

6.3 浏览器环境

import { createP2PEscrowClientFromBrowser } from "@cgentai/cgent-contracts";

const escrow = await createP2PEscrowClientFromBrowser({
  provider: window.ethereum,
  address: "0xEscrowAddress",
  accountIndex: 0, // 可选,默认 0
});

const account = await escrow.getRunnerAddress();

6.4 创建订单

const buyerAddress = await escrow.getRunnerAddress();

await escrow.createOrder({
  buyer: buyerAddress!,
  seller: "0xSellerAddress",
  orderId: 1n,
  amount: 1000n * 10n ** 6n, // 以最小单位传值
  token: "0xUSDC",
});

在调用前确保买家钱包已对合约执行 ERC20.approve 授权。

6.5 卖家操作

// 卖家确认锁定
await escrow.withRunner(sellerSigner).lockOrder({
  buyer: buyerAddress!,
  orderId: 1n,
});

// 卖家等待锁定期结束后释放
await escrow.withRunner(sellerSigner).sellerRelease({
  buyer: buyerAddress!,
  orderId: 1n,
});

// 或者在需要时退款
await escrow.withRunner(sellerSigner).sellerRefund({
  buyer: buyerAddress!,
  orderId: 1n,
});

6.6 买家确认或撤回

// 买家确认收货
await escrow.withRunner(buyerSigner).buyerConfirmReceipt({
  seller: "0xSellerAddress",
  orderId: 1n,
});

// 买家在卖家锁定前撤回
await escrow.withRunner(buyerSigner).buyerWithdraw({
  seller: "0xSellerAddress",
  orderId: 1n,
});

6.7 仲裁流程

// 仲裁者设置仲裁中
await escrow.withRunner(arbitratorSigner).setArbitrationPending({
  buyer: buyerAddress!,
  seller: "0xSellerAddress",
  orderId: 1n,
});

// 最终裁决:true 释放给卖家(扣除手续费),false 退给买家
await escrow.withRunner(arbitratorSigner).arbitrate({
  buyer: buyerAddress!,
  seller: "0xSellerAddress",
  orderId: 1n,
  releaseToSeller: true,
});

6.8 查询订单与辅助函数

const order = await escrow.getOrder({
  buyer: buyerAddress!,
  seller: "0xSellerAddress",
  orderId: 1n,
});

console.log(order.status); // OrderStatus 枚举值

const { feeAmount, sellerAmount } = P2PEscrowClient.calculateFee(order.amount);

SDK 返回的 ResolvedOrder 将合约中的 uint256 转换为 bigint,可直接参与 JS/TS 计算。


7. 事件监听

P2PEscrowClient 继承了 TypeChain 的事件类型,可在 TypeScript 中获得强类型支持:

import type { P2PEscrow } from "@cgentai/cgent-contracts/typechain-types";

escrow.on(escrow.contract.filters.OrderCreated(), (orderKey, buyer, seller, orderId) => {
  console.log("New order", { orderKey, buyer, seller, orderId: orderId.toString() });
});

// 取消监听
escrow.removeAllListeners(escrow.contract.filters.OrderCreated());

8. 部署与网络

deployments/ 目录中存放了示例部署信息(例如 P2PEscrow-84532.json 对应于 Linea Sepolia 测试网)。使用 SDK 时请根据实际网络配置合约地址与 RPC 节点。


9. 开发与测试

  • 本仓库基于 Hardhat,测试脚本位于 test/ 目录,可运行 pnpm testnpx hardhat test
  • 若需自建环境,可使用 pnpm deploy(具体脚本请参考 package.json)。
  • 修改合约或 SDK 后,请重新编译生成 TypeChain 类型:pnpm build

如需更多帮助或功能扩展,欢迎提交 Issue 或 PR。