使用 Gas 代付中继
使用 @stablechain/enterprise 赞助您用户的 gas。一个列入白名单的代付账户会封装用户的零 gas 交易(InnerTx)并广播它,这样用户无需持有任何 USDT0 即可进行交易。gasWaiver 模块在一个调用中完成构建、签名和中继,因此您可以为每个操作调用一个方法。
每个方法都返回 H_inner,即用户交易的哈希,而不是承载它的封装器。
先决条件
- Node.js 20 或更高版本,并安装了
@stablechain/enterprise和viem。请参阅 Enterprise SDK 参考。 - 经过治理注册的代付密钥。Enterprise SDK 在 Stable 主网和 Stable 测试网上运行,访问受限:请联系 Stable 以获取白名单代付密钥。
1. 使用 Gas 代付模块创建客户端
将 gasWaiver: { account } 传递给 createStableEnterprise,其中 account 是您列入白名单的代付密钥。只有在您配置它时,该模块才会在客户端上出现。
import { createStableEnterprise, stable } from "@stablechain/enterprise";
import { privateKeyToAccount } from "viem/accounts";
const enterprise = createStableEnterprise({
chain: stable,
gasWaiver: { account: privateKeyToAccount(process.env.WAIVER_PRIVATE_KEY as `0x${string}`) },
});
const gw = enterprise.gasWaiver;StableEnterpriseClient { gasWaiver, guaranteedBlock: undefined, guaranteedWaiver: undefined }rpcEndpoints 选项是可选的。如果未设置,客户端将使用链的内置 RPC。
2. 中继单个交易
使用用户的账户和变化的字段调用 send。gasPrice: 0、旧版类型、chainId 和待处理 nonce 会为您处理,因此您只需传递 to,以及可选的 data、value 和 gas。
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);H_inner: 0x8f3a...2d41用户不需要 USDT0:代付账户会赞助 gas。gas 默认为 150_000n (DEFAULT_INNER_GAS),足以覆盖代币转账或批准。对于更重的调用,请传递显式的 gas。
3. 中继批量交易
调用 sendBatch 以中继来自一个账户的多个交易。Nonce 会根据账户的待处理 nonce 自动排序,并且您会按输入顺序获得每个输入的一个结果。
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}`);
}[0] ✔ 0x8f3a...2d41
[1] ✔ 0x2b7c...9e04批量报告失败时,每个项目的错误都在 result.error 中,而不是抛出异常,因此一个糟糕的交易不会导致其余交易失败。
4. 执行每个合作伙伴的策略限制
通过向配置添加策略限制来限制代付密钥可以赞助的内容。违反限制的 InnerTx 会在广播之前被拒绝。
const enterprise = createStableEnterprise({
chain: stable,
gasWaiver: {
account: privateKeyToAccount(process.env.WAIVER_PRIVATE_KEY as `0x${string}`),
maxGasLimit: 500_000n,
maxDataLength: 4_096,
allowedTargets: [
{ address: token, selectors: ["0xa9059cbb"] }, // 仅限 ERC-20 传输
],
},
});目标在 allowedTargets 之外的交易会失败并显示 TARGET_NOT_ALLOWED;超过 maxGasLimit 的交易会失败并显示 GAS_LIMIT_EXCEEDED。使用 "*" 作为 address 以允许任何合约,并省略 selectors 以允许任何方法。
5. 中继预签名交易
对于非托管流程,用户在其自己的环境中签署 InnerTx 并仅将签名十六进制交给您,这样您就永远看不到他们的密钥。使用 buildWaiverInnerTx 构建它,然后使用 relay 中继它。
import { buildWaiverInnerTx, toSigner } from "@stablechain/enterprise";
// 在用户端 - buildWaiverInnerTx 通过 Signer 签名;toSigner 适配 viem 账户
const signed = await buildWaiverInnerTx(toSigner(user), stable.id, { to: token, data, gas: 150_000n, nonce });
// 在您的后端
const { txHash } = await gw.relay(signed);
console.log("H_inner:", txHash);H_inner: 0x8f3a...2d41对于多个预签名交易,请使用 relayBatch,它会像 sendBatch 一样为每个输入返回一个结果。
处理拒绝
send 和 relay 在拒绝时会抛出 StableEnterpriseRelayError,其中包含一个您可以根据其进行分支的 code。
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;
}StableEnterpriseRelayError: relay failed [TARGET_NOT_ALLOWED]: target 0x... not allowed请参阅完整的 ErrorCode 表格,了解所有拒绝原因。
接下来去哪里
- 发送担保交易:将交易放入保留的 Enterprise-lane 区块空间,并将其与 gas 代付结合使用。
- Enterprise SDK 参考:所有方法、配置选项和错误类的完整说明。
- Gas 代付:零 gas 交易在协议层面的工作原理。
- 启用无 gas 交易:使用 Stable 托管的代付服务器,而不是注册您自己的代付。

