가스 면제 릴레이
@stablechain/enterprise로 사용자 가스를 지원하세요. 화이트리스트에 등록된 면제 계정은 사용자의 제로 가스 트랜잭션(InnerTx)을 래핑하고 브로드캐스트하여 사용자가 USDT0를 보유하지 않고도 트랜잭션을 수행할 수 있도록 합니다. gasWaiver 모듈은 빌드, 서명 및 릴레이를 한 번의 호출로 처리하므로 작업당 하나의 메서드를 호출합니다.
모든 메서드는 트랜잭션을 전달한 래퍼가 아닌, 사용자 트랜잭션의 해시인 H_inner를 반환합니다.
전제 조건
- Node.js 20 이상,
@stablechain/enterprise및viem설치. Enterprise SDK 참조를 참조하세요. - 거버넌스에 등록된 면제 키. Enterprise SDK는 Stable Mainnet 및 Stable Testnet에서 실행되며 액세스는 제한됩니다. 화이트리스트에 등록된 면제 키를 얻으려면 Stable에 문의하세요.
1. 가스 면제 모듈로 클라이언트 생성
createStableEnterprise에 gasWaiver: { account }를 전달합니다. 여기서 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는 토큰 전송 또는 승인을 처리하는 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 transfer only
],
},
});allowedTargets 외부의 컨트랙트로의 트랜잭션은 TARGET_NOT_ALLOWED 오류로 실패하고, maxGasLimit을 초과하는 트랜잭션은 GAS_LIMIT_EXCEEDED 오류로 실패합니다. address에 "*"를 사용하여 모든 컨트랙트를 허용하고, selectors를 생략하여 모든 메서드를 허용할 수 있습니다.
5. 미리 서명된 트랜잭션 릴레이
비관리 흐름의 경우, 사용자는 자신의 환경에서 InnerTx에 서명하고 서명된 hex만 제공하므로 사용자의 키를 볼 필요가 없습니다. buildWaiverInnerTx로 빌드한 다음 relay로 릴레이합니다.
import { buildWaiverInnerTx, toSigner } from "@stablechain/enterprise";
// on the user's side — buildWaiverInnerTx signs through a Signer; toSigner adapts a viem account
const signed = await buildWaiverInnerTx(toSigner(user), stable.id, { to: token, data, gas: 150_000n, nonce });
// on your backend
const { txHash } = await gw.relay(signed);
console.log("H_inner:", txHash);H_inner: 0x8f3a...2d41여러 개의 미리 서명된 트랜잭션의 경우, sendBatch와 같이 입력당 하나의 결과를 반환하는 relayBatch를 사용하세요.
거부 처리
send 및 relay는 거부 시 StableEnterpriseRelayError를 throw하며, 분기할 수 있는 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") {
// the InnerTx target is outside the configured allowlist
}
throw err;
}StableEnterpriseRelayError: relay failed [TARGET_NOT_ALLOWED]: target 0x... not allowed모든 거부 사유에 대한 전체 ErrorCode 표를 참조하세요.
다음 단계
- 보장된 트랜잭션 전송: 예약된 엔터프라이즈 레인 블록스페이스에 트랜잭션을 전송하고 가스 면제와 결합합니다.
- Enterprise SDK 참조: 모든 메서드, 구성 옵션 및 오류 클래스에 대한 자세한 설명입니다.
- 가스 면제: 프로토콜 수준에서 제로 가스 트랜잭션이 작동하는 방식.

