Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

가스 없는 트랜잭션 활성화

Gas Waiver는 Stable에서 가스 없는 트랜잭션을 가능하게 합니다. Gas Waiver를 사용하면 애플리케이션이 사용자를 대신하여 가스 요금을 지불하므로 사용자는 가스 비용으로 USDT0를 보유하지 않고도 컨트랙트와 상호 작용할 수 있습니다.

이 가이드에서는 Waiver Server API를 통해 통합하는 방법을 다룹니다.

필수 조건

  • Stable 팀이 발급한 Waiver Server용 API 키
  • 대상 컨트랙트 주소는 Waiver의 AllowedTarget 정책에 등록되어야 합니다.

Waiver Server

기본 URL:
  • 메인넷: TBD
  • 테스트넷: https://waiver.testnet.stable.xyz

인증: Bearer <your-api-key>

개요

통합 흐름은 세 단계로 구성됩니다.

  1. InnerTx 빌드: 사용자는 gasPrice = 0으로 트랜잭션에 서명합니다.
  2. Waiver Server에 제출: 서명된 트랜잭션을 Waiver Server API에 제출합니다.
  3. 응답 처리: Waiver Server가 트랜잭션을 래핑하고 브로드캐스트합니다. 스트리밍된 결과를 처리하고 트랜잭션 해시를 사용자에게 표시합니다.

1단계: 사용자의 InnerTx 생성

사용자는 gasPrice = 0으로 표준 트랜잭션에 서명합니다. to 주소와 메서드 선택기는 Waiver의 AllowedTarget 정책에 의해 허용되어야 합니다.

// config.ts
export const CONFIG = {
  RPC_URL: "https://rpc.testnet.stable.xyz",
  CHAIN_ID: 2201, // 메인넷의 경우 988
  WAIVER_SERVER: "https://waiver.testnet.stable.xyz",
  USDT0_ADDRESS: "0x78Cf24370174180738C5B8E352B6D14c83a6c9A9",
};
import { ethers } from "ethers";
import { CONFIG } from "./config";
 
const provider = new ethers.JsonRpcProvider(CONFIG.RPC_URL);
const usdt0 = new ethers.Contract(CONFIG.USDT0_ADDRESS, [
  "function transfer(address to, uint256 amount) returns (bool)"
], provider);
 
const callData = usdt0.interface.encodeFunctionData("transfer", [
  recipientAddress,
  ethers.parseUnits("0.01", 18)
]);
 
const gasEstimate = await provider.estimateGas({
  from: userWallet.address,
  to: CONFIG.USDT0_ADDRESS,
  data: callData,
});
 
const nonce = await provider.getTransactionCount(userWallet.address);
 
const innerTx = {
  to: CONFIG.USDT0_ADDRESS,
  data: callData,
  value: 0,
  gasPrice: 0,
  gasLimit: gasEstimate,
  nonce: nonce,
  chainId: CONFIG.CHAIN_ID,
};
 
const signedInnerTx = await userWallet.signTransaction(innerTx);

2단계: Waiver Server에 제출

import { CONFIG } from "./config";
 
const API_KEY = process.env.WAIVER_API_KEY;
 
const response = await fetch(`${CONFIG.WAIVER_SERVER}/v1/submit`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${API_KEY}`,
  },
  body: JSON.stringify({
    transactions: [signedInnerTx],
  }),
});

배치 제출

단일 요청으로 여러 개의 서명된 트랜잭션을 제출할 수 있습니다.

body: JSON.stringify({
  transactions: [signedTx1, signedTx2, signedTx3],
})

각 결과 줄에는 배열 내 트랜잭션의 위치에 해당하는 index 필드가 포함됩니다.

3단계: 응답 처리

응답은 NDJSON(줄바꿈으로 구분된 JSON)으로 스트리밍됩니다. 각 줄은 제출된 하나의 트랜잭션에 해당합니다.

const reader = response.body.getReader();
const decoder = new TextDecoder();
 
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
 
  const lines = decoder.decode(value).trim().split("\n");
  for (const line of lines) {
    const result = JSON.parse(line);
    if (result.success) {
      console.log(`tx ${result.index} confirmed: ${result.txHash}`);
    } else {
      console.error(`tx ${result.index} failed: ${result.error.message}`);
    }
  }
}
성공 응답:
{"index": 0, "id": "abc123", "success": true, "txHash": "0x..."}
실패 응답:
{"index": 1, "id": "def456", "success": false, "error": {"code": "VALIDATION_FAILED", "message": "invalid signature"}}

오류 코드

코드설명
PARSE_ERROR트랜잭션 구문 분석 실패
INVALID_REQUEST잘못된 요청 본문
BATCH_SIZE_EXCEEDED배치 크기가 허용된 최대치를 초과함
VALIDATION_FAILED트랜잭션 유효성 검사 실패 (예: 유효하지 않은 서명, 허용되지 않는 대상)
BROADCAST_FAILED체인으로 브로드캐스트 실패
RATE_LIMITED속도 제한 초과
QUEUE_FULL서버 큐가 용량에 도달함
TIMEOUT요청 시간 초과

API 레퍼런스

GET /v1/health

상태 확인 엔드포인트. 인증: 없음.

POST /v1/submit

서명된 내부 트랜잭션 배치를 제출합니다. 인증: 필수 (Bearer).

요청 본문:
{
  "transactions": ["0x<signedInnerTx1>", "0x<signedInnerTx2>"]
}

응답은 NDJSON으로 스트리밍됩니다. 각 줄은 제출된 트랜잭션 인덱스에 해당합니다.

GET /v1/submit

스트리밍 제출을 위한 WebSocket 인터페이스. 인증: 필수 (Bearer).

요점

  • Gas Waiver는 서버 측 통합입니다. 백엔드가 서명된 사용자 트랜잭션을 Waiver Server에 제출합니다. 사용자는 Waiver Server와 직접 상호 작용하지 않습니다.
  • 사용자는 항상 InnerTx에 서명하여 서명 무결성을 보존합니다. Waiver는 사용자의 트랜잭션을 수정할 수 없습니다.
  • 대상 컨트랙트는 Waiver의 AllowedTarget 목록에 있어야 합니다.

다음에 권장되는 내용

  • 제로 가스 트랜잭션: 데모 중심 흐름과 영수증에서 제로 가스를 확인하는 방법을 참조하십시오.
  • 셀프 호스팅 Gas Waiver: 호스팅된 API 없이 자체 Waiver를 실행합니다.
  • Gas Waiver 프로토콜: 전체 래퍼 트랜잭션 사양 및 거버넌스 모델.
  • Stable SDK: 유형이 지정된 클라이언트를 사용하여 Waiver Server에 제출할 사용자 트랜잭션에 서명합니다.