Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
edcfddf
docs: add Enterprise SDK overview and reference
bastienrp Jul 13, 2026
06c418d
i18n: auto-translate cn/ko for changed en content
github-actions[bot] Jul 13, 2026
e57805e
docs: add Gas Waiver and Guaranteed Blockspace to Enterprise SDK menu
bastienrp Jul 13, 2026
c198dbc
i18n: auto-translate cn/ko for changed en content
github-actions[bot] Jul 13, 2026
956c9e7
docs: add Enterprise SDK how-to guides and feature naming
bastienrp Jul 13, 2026
c81020a
i18n: auto-translate cn/ko for changed en content
github-actions[bot] Jul 13, 2026
61d9118
docs: add Guaranteed relayed transactions guide
bastienrp Jul 13, 2026
e17b54f
docs: rename Enterprise SDK menu item Gas Waiver to Relay Transactions
bastienrp Jul 13, 2026
705c032
i18n: auto-translate cn/ko for changed en content
github-actions[bot] Jul 13, 2026
5a589cf
build: raise docs:build heap ceiling to 7168 MB
bastienrp Jul 14, 2026
9002b0f
i18n: auto-translate cn/ko for changed en content
github-actions[bot] Jul 14, 2026
ae8da11
docs: document custody signers (AWS KMS) for the Enterprise SDK
bastienrp Jul 15, 2026
2602a0b
i18n: auto-translate cn/ko for changed en content
github-actions[bot] Jul 15, 2026
18a6bf1
docs: reflect top-level default signer for the Enterprise SDK
bastienrp Jul 16, 2026
11941a7
i18n: auto-translate cn/ko for changed en content
github-actions[bot] Jul 16, 2026
34bf6b8
docs: drop non-null assertions from Enterprise SDK code samples
bastienrp Jul 16, 2026
a551d74
i18n: auto-translate cn/ko for changed en content
github-actions[bot] Jul 16, 2026
e431fcf
docs: align KMS example env var with the SDK example (AWS_KMS_KEY_ID)
bastienrp Jul 17, 2026
080f255
i18n: auto-translate cn/ko for changed en content
github-actions[bot] Jul 17, 2026
6327f91
docs: link the @stablechain/enterprise npm package
bastienrp Jul 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions docs/pages/cn/explanation/enterprise-sdk.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
source_path: explanation/enterprise-sdk.mdx
source_sha: a632f3be5fbff966d9da230ec302b4ce4e6773f2
title: "Stable Enterprise SDK"
description: "使用类型化的 @stablechain/enterprise SDK 从后端中继免 gas 和保证区块空间的交易。"
diataxis: "explanation"
---

# Stable Enterprise SDK

`@stablechain/enterprise` 是 Stable 企业交易通道的服务器端 TypeScript 客户端。它会签署并中继两种特权交易:免 gas 交易(由您来支付用户的 gas)和保证区块空间交易(在保留的企业通道中处理)。您可以在一个客户端上启用其中一个或两个通道。

```ts
import { createStableEnterprise, stableTestnet } from "@stablechain/enterprise";
import { privateKeyToAccount } from "viem/accounts";

const enterprise = createStableEnterprise({
chain: stableTestnet,
gasWaiver: { account: privateKeyToAccount("0xYOUR_WAIVER_KEY") },
});

const { txHash } = await enterprise.gasWaiver.send(user, { to: token, data });
```

```text
txHash: 0x8f3a...2d41
```

此调用返回 `H_inner`,即用户交易的哈希,而不是承载它的包装器交易的哈希。

## SDK 的作用

SDK 暴露了三个功能,每个模块一个。每个功能都是可选的、独立配置的,并且都带有自己的签名账户,以便您可以使用单独的密钥。

- **免 gas 中继** (`gasWaiver`):构建、签署并中继免 gas 交易。一个白名单中的免 gas 账户会封装用户的零 gas 交易,这样用户就可以在不持有任何 USDT0 的情况下进行交易。请参阅[免 gas](/cn/explanation/gas-waiver)。
- **保证区块空间** (`guaranteedBlock`):通过企业 RPC 网关中继交易,使其落在保留的企业通道区块空间中。与免 gas 不同,签名者支付自己的 gas。请参阅[保证区块空间](/cn/explanation/guaranteed-blockspace)。
- **保证中继交易** (`guaranteedWaiver`):两者结合。一种通过保证区块空间路由的免 gas 交易,这样用户就不需要余额,并且交易仍然落在企业通道中。

每个功能都提供相同的四种方法:`send` 和 `sendBatch` 用于 SDK 签名的托管路径,以及 `relay` 和 `relayBatch` 用于用户在其他地方签名并只向您提供签名十六进制的非托管路径。

## 访问权限

企业 SDK 目前仅在 Stable Testnet 上可用。

这两个通道都是受限的。免 gas 需要治理注册的免 gas 密钥,而保证区块空间需要企业 RPC 网关 API 密钥。要进行集成,请[联系 Stable](https://discord.gg/stablexyz) 以获取访问权限。Stable 会为您提供所需的免 gas 密钥和网关端点。

## 仅限服务器端

:::warning
企业 SDK 是一个无状态的服务器端库,使用私钥进行签名。切勿在浏览器中运行它。请将免 gas 密钥和企业 RPC 网关 URL 保留在您的后端。
:::

免 gas 密钥是一个列入白名单的、经过治理注册的账户:任何持有它的人都可以根据您的策略支付 gas。企业 RPC 网关 URL 嵌入了您的 API 密钥。请将两者都视为秘密。为了使免 gas 密钥不被泄露,请使用 AWS KMS 等托管签名服务对其进行备份。请参阅[签名密钥和托管](/cn/reference/enterprise-sdk#signing-keys-and-custody)。

## 何时使用

当您运营后端并希望为用户支付 gas 或为自己的流量保证交易包含时,请使用企业 SDK。对于后端或浏览器中的日常转账、桥接、兑换和金库收益,请改用通用[Stable SDK](/cn/explanation/sdk-overview)。

## 从这里开始

- [**免 gas 中继**](/cn/how-to/relay-with-gas-waiver):为用户支付 gas,这样他们就可以在不持有 USDT0 的情况下进行交易。
- [**发送保证交易**](/cn/how-to/send-guaranteed-transactions):将交易落在保留的企业通道区块空间中。
- [**保证中继交易**](/cn/how-to/guaranteed-relayed-transactions):结合这两个通道:企业通道中的免 gas 交易。
- [**企业 SDK 参考**](/cn/reference/enterprise-sdk):每个模块、方法、配置选项和错误类。

## 下一步建议

- [**免 gas 协议**](/cn/reference/gas-waiver-api):交易格式、标记路由和治理控制。
- [**Stable SDK**](/cn/explanation/sdk-overview):用于转账、桥接、兑换和收益的通用客户端。
- [**连接 Stable**](/cn/reference/connect):测试网的链 ID、RPC 端点和浏览器。
141 changes: 141 additions & 0 deletions docs/pages/cn/how-to/guaranteed-relayed-transactions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
---
source_path: how-to/guaranteed-relayed-transactions.mdx
source_sha: 007be0e546cc1251771678ee74523b6a79a2d76d
title: "保证中继交易"
description: "通过 Enterprise SDK 经由保证的区块空间中继免 gas 交易,这样用户无需余额也能进入 Enterprise 通道。"
diataxis: "how-to"
---

# 保证中继交易

将 Stable 企业级网络与 `@stablechain/enterprise` 结合使用。保证中继交易是[免 gas 交易](/cn/how-to/relay-with-gas-waiver),其通过[保证的区块空间](/cn/how-to/send-guaranteed-transactions)进行路由:免除交易费的功能支付 gas 费,因此用户无需余额和费用字段,交易仍会进入预留的 Enterprise 通道。

`guaranteedWaiver` 模块同时处理这两个方面。用户签署内部的 `0x3F` CustomTx,白名单中的免除交易费账户将其包装在一个共享相同 Enterprise `nonceKey` 的外部 `0x3F` CustomTx 中,并通过 Enterprise RPC 网关广播。每个方法都返回 `H_inner`,即用户的交易哈希。

## 前提条件

- Node.js 20 或更高版本,并安装 `@stablechain/enterprise` 和 `viem`。请参阅 [Enterprise SDK 参考](/cn/reference/enterprise-sdk#install)。
- 一个在治理层注册的免除交易费密钥和一个 Enterprise RPC 网关 API 密钥。Enterprise SDK 目前仅支持测试网,并且需要申请访问权限:[联系 Stable](https://discord.gg/stablexyz) 以获取这两项。

:::warning
这是一个服务器端库。请将免除交易费密钥和 Enterprise RPC 网关 URL 保留在您的后端:网关 URL 嵌入了您的 API 密钥。
:::

## 1. 使用保证免除交易费模块创建客户端

将 `guaranteedWaiver` 和 `enterpriseRpcEndpoints` 传递给 `createStableEnterprise`。该模块接收白名单中的免除交易费密钥 (用于签署外部包装器) 和 Enterprise 通道。它还接受与 `gasWaiver` 相同的 `allowedTargets`、`maxGasLimit` 和 `maxDataLength` 策略限制。

```ts
import { createStableEnterprise, stableTestnet } from "@stablechain/enterprise";
import { privateKeyToAccount } from "viem/accounts";

const enterprise = createStableEnterprise({
chain: stableTestnet,
enterpriseRpcEndpoints: [process.env.ENTERPRISE_RPC_URL], // the gateway URL Stable provisions
guaranteedWaiver: {
account: privateKeyToAccount(process.env.WAIVER_PRIVATE_KEY as `0x${string}`),
laneId: 0n, // Enterprise lane
},
});

const gw = enterprise.guaranteedWaiver;
```

```text
StableEnterpriseClient { gasWaiver: undefined, guaranteedBlock: undefined, guaranteedWaiver }
```

:::tip
要将免除交易费密钥保留在托管后端中,请传递 `signer` 而不是 `account`。`@stablechain/enterprise/aws-kms` 中的 `awsKmsSigner` 支持 AWS KMS。请参阅[签名密钥和托管](/cn/reference/enterprise-sdk#signing-keys-and-custody)。
:::

## 2. 中继单个交易

使用用户账户和变化的字段调用 `send`。由于免除了 gas 费,用户不需要余额和费用字段。内部的 `0x3F` CustomTx、其 Enterprise `nonceKey` 和 2D nonce (从网关发现) 都会为您处理。

```ts
const user = privateKeyToAccount(process.env.USER_PRIVATE_KEY as `0x${string}`);

const { txHash } = await gw.send(user, { to: recipient });
console.log("H_inner:", txHash);
```

```text
H_inner: 0x8f3a...2d41
```

`gas` 默认为共享的内部 gas 默认值;仅在覆盖时传递。允许价值转移,因此您也可以传递 `value`。

## 3. 中继批次交易

调用 `sendBatch` 中继来自一个用户的多笔交易。内部 nonce 会从发现的基本 nonce 自动排序,并且您会按照输入顺序获得每个输入的单个结果。失败会导致其后续交易无法进行。

```ts
const results = await gw.sendBatch(user, [{ to: a }, { to: b }]);

for (const r of results) {
console.log(r.success ? `[${r.index}] ✔ ${r.txHash}` : `[${r.index}] ✖ ${r.error?.code}`);
}
```

```text
[0] ✔ 0x8f3a...2d41
[1] ✔ 0x2b7c...9e04
```

## 4. 中继预签名交易

对于非托管流程,用户在其自己的环境中签署内部 `0x3F` CustomTx,并只向您提供签名的十六进制数据。使用 `buildGuaranteedTx` 构建它,其中 Enterprise nonce 密钥使用 `nonceKeyForLane`,费用为零 (gas 已免除)。您的后端会使用免除交易费密钥对其进行封装,并使用 `relay` 进行中继。

```ts
import { buildGuaranteedTx, nonceKeyForLane, toSigner } from "@stablechain/enterprise";

// on the user's side — buildGuaranteedTx signs through a Signer; toSigner adapts a viem account
const signedInner = await buildGuaranteedTx(toSigner(user), stableTestnet.id, {
to: recipient,
gas: 100_000n,
gasFeeCap: 0n, // waived
gasTipCap: 0n,
nonce, // the user's current 2D-lane nonce
nonceKey: nonceKeyForLane(0n), // Enterprise lane 0
});

// on your backend
const { txHash } = await gw.relay(signedInner); // waiver wraps + broadcasts → H_inner
console.log("H_inner:", txHash);
```

```text
H_inner: 0x8f3a...2d41
```

对于多个预签名交易,请使用 `relayBatch`。

## 处理拒绝

`send` 和 `relay` 在拒绝时会抛出 `StableEnterpriseRelayError`。由于此流程通过网关路由,因此网关代码 (如 `GATEWAY_UNAUTHORIZED` 和 `QUOTA_EXCEEDED`) 以及免除交易费策略代码 (如 `TARGET_NOT_ALLOWED`) 都适用。

```ts
import { StableEnterpriseRelayError } from "@stablechain/enterprise";

try {
await gw.send(user, { to: recipient });
} catch (err) {
if (err instanceof StableEnterpriseRelayError && err.code === "GATEWAY_UNAUTHORIZED") {
// the Enterprise RPC gateway rejected the API key
}
throw err;
}
```

```text
StableEnterpriseRelayError: relay failed [GATEWAY_UNAUTHORIZED]: invalid api key
```

请参阅完整的 [`ErrorCode`](/cn/reference/enterprise-sdk#errorcode) 表,了解所有拒绝原因。

## 接下来去哪里

- [**使用免 gas 功能中继**](/cn/how-to/relay-with-gas-waiver):为用户支付 gas 费,无需保证通道。
- [**发送保证交易**](/cn/how-to/send-guaranteed-transactions):单独使用保证区块空间,由签署者支付 gas 费。
- [**Enterprise SDK 参考**](/cn/reference/enterprise-sdk#guaranteed-relay-transactions):所有方法、配置选项和错误类的完整说明。
157 changes: 157 additions & 0 deletions docs/pages/cn/how-to/relay-with-gas-waiver.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
---
source_path: how-to/relay-with-gas-waiver.mdx
source_sha: c1b34aab292d8e9623b59810cd6b668468e834ce
title: "使用 Gas 代付中继交易"
description: "使用 Enterprise SDK 赞助用户的 gas:中继零 gas 交易、批量中继、强制执行策略限制以及中继预签名交易。"
diataxis: "how-to"
---

# 使用 Gas 代付中继交易

使用 `@stablechain/enterprise` 赞助用户的 gas 费用。白名单代付账户会包装用户的零 gas 交易 (InnerTx) 并广播它,因此用户无需持有任何 USDT0 即可进行交易。`gasWaiver` 模块在一个调用中构建、签名和中继,因此您每个操作只需调用一个方法。

每个方法都返回 `H_inner`,即用户交易的哈希,而不是承载它的包装器。

## 先决条件

- Node.js 20 或更高版本,并安装了 `@stablechain/enterprise` 和 `viem`。请参阅 [Enterprise SDK 参考](/cn/reference/enterprise-sdk#install)。
- 治理注册的代付密钥。Enterprise SDK 目前仅限测试网,并且访问受限:[联系 Stable](https://discord.gg/stablexyz) 获取白名单代付密钥。

:::warning
这是一个使用私钥进行签名的服务器端库。切勿在浏览器中运行它。将代付密钥保存在您的后端。
:::

## 1. 使用 gas 代付模块创建客户端

将 `gasWaiver: { account }` 传递给 `createStableEnterprise`,其中 `account` 是您的白名单代付密钥。仅在您配置后,模块才会在客户端上出现。

```ts
import { createStableEnterprise, stableTestnet } from "@stablechain/enterprise";
import { privateKeyToAccount } from "viem/accounts";

const enterprise = createStableEnterprise({
chain: stableTestnet,
gasWaiver: { account: privateKeyToAccount(process.env.WAIVER_PRIVATE_KEY as `0x${string}`) },
});

const gw = enterprise.gasWaiver;
```

```text
StableEnterpriseClient { gasWaiver, guaranteedBlock: undefined, guaranteedWaiver: undefined }
```

`rpcEndpoints` 选项是可选的。如果未设置,客户端将使用链的内置 RPC。

:::tip
要将代付密钥保存在托管后端中,请传递 `signer` 而不是 `account`。`@stablechain/enterprise/aws-kms` 中的 `awsKmsSigner` 支持 AWS KMS。请参阅[签名密钥和托管](/cn/reference/enterprise-sdk#signing-keys-and-custody)。
:::

## 2. 中继单个交易

使用用户帐户和变化的字段调用 `send`。`gasPrice: 0`、旧版类型、`chainId` 和待处理 Nonce 都已为您处理,因此您只需传递 `to`,以及可选的 `data`、`value` 和 `gas`。

```ts
const user = privateKeyToAccount(process.env.USER_PRIVATE_KEY as `0x${string}`);

const { txHash } = await gw.send(user, { to: token, data, gas: 150_000n });
console.log("H_inner:", txHash);
```

```text
H_inner: 0x8f3a...2d41
```

用户不需要 USDT0:代付账户会赞助 gas。`gas` 默认为 `150_000n` (`DEFAULT_INNER_GAS`),足以覆盖代币转账或批准。对于更复杂的调用,请传递显式的 `gas`。

## 3. 批量中继

调用 `sendBatch` 从一个账户中继多笔交易。Nonce 会根据账户的待处理 Nonce 自动排序,并且您会按输入顺序获得每个输入的结果。

```ts
const results = await gw.sendBatch(user, [
{ to: token, data: dataA, gas: 150_000n },
{ to: token, data: dataB, gas: 150_000n },
]);

for (const r of results) {
console.log(r.success ? `[${r.index}] ✔ ${r.txHash}` : `[${r.index}] ✖ ${r.error?.code}`);
}
```

```text
[0] ✔ 0x8f3a...2d41
[1] ✔ 0x2b7c...9e04
```

批量处理报告每个项目的失败 `result.error` 而不是抛出异常,因此一个糟糕的交易不会影响其余交易。

## 4. 执行每个合作伙伴的策略限制

通过向配置添加策略限制来限制代付密钥可以赞助的内容。违反限制的 InnerTx 在广播前将被拒绝。

```ts
const enterprise = createStableEnterprise({
chain: stableTestnet,
gasWaiver: {
account: privateKeyToAccount(process.env.WAIVER_PRIVATE_KEY as `0x${string}`),
maxGasLimit: 500_000n,
maxDataLength: 4_096,
allowedTargets: [
{ address: token, selectors: ["0xa9059cbb"] }, // ERC-20 transfer only
],
},
});
```

针对 `allowedTargets` 之外的合约的交易将失败并显示 `TARGET_NOT_ALLOWED`;超过 `maxGasLimit` 的交易将失败并显示 `GAS_LIMIT_EXCEEDED`。使用 `"*"` 作为 `address` 允许任何合约,并省略 `selectors` 允许任何方法。

## 5. 中继预签名交易

对于非托管流程,用户在其自己的环境中签署 InnerTx 并仅将签名十六进制传递给您,因此您永远不会看到他们的密钥。使用 `buildWaiverInnerTx` 构建它,然后使用 `relay` 中继它。

```ts
import { buildWaiverInnerTx, toSigner } from "@stablechain/enterprise";

// 在用户端 — buildWaiverInnerTx 通过 Signer 签名;toSigner 适配 viem 账户
const signed = await buildWaiverInnerTx(toSigner(user), stableTestnet.id, { to: token, data, gas: 150_000n, nonce });

// 在您的后端
const { txHash } = await gw.relay(signed);
console.log("H_inner:", txHash);
```

```text
H_inner: 0x8f3a...2d41
```

对于多个预签名交易,请使用 `relayBatch`,它像 `sendBatch` 一样为每个输入返回一个结果。

## 处理拒绝

`send` 和 `relay` 在拒绝时会抛出 `StableEnterpriseRelayError`,并带有您可以分支的 `code`。

```ts
import { StableEnterpriseRelayError } from "@stablechain/enterprise";

try {
await gw.send(user, { to: token, data });
} catch (err) {
if (err instanceof StableEnterpriseRelayError && err.code === "TARGET_NOT_ALLOWED") {
// InnerTx 目标不在配置的白名单中
}
throw err;
}
```

```text
StableEnterpriseRelayError: relay failed [TARGET_NOT_ALLOWED]: target 0x... not allowed
```

请参阅完整的 [`ErrorCode`](/cn/reference/enterprise-sdk#errorcode) 表格以了解所有拒绝原因。

## 下一步

- [**发送保证交易**](/cn/how-to/send-guaranteed-transactions):在保留的 Enterprise 通道区块空间中进行交易,并将其与 gas 代付结合使用。
- [**Enterprise SDK 参考**](/cn/reference/enterprise-sdk#relay-with-gas-waiver):每个方法、配置选项和错误类的完整说明。
- [**Gas 代付**](/cn/explanation/gas-waiver):协议级别的零 gas 交易工作原理。
Loading
Loading