본문으로 건너뛰기

트랜잭션 수수료 대납

ABC Paymaster를 사용하면 기존 EOA 지갑 주소 그대로 트랜잭션 수수료를 대납받을 수 있습니다.
EIP-7702 기반으로 동작하며, EOA가 처음 대납 트랜잭션을 전송할 때 위임(delegation) 설정이 자동으로 처리됩니다.
이후에는 트랜잭션 파라미터만 전달하면 수수료 없이 트랜잭션을 전송할 수 있습니다.

지원 네트워크

현재 가스비 대납 서비스 지원 네트워크는 Ethereum, Kaia, Base 입니다.
테스트넷은 Ethereum Sepolia, Kaia Kairos, Base Sepolia 를 지원합니다.

Avalanche C-Chain 사용 시

Avalanche C-Chain은 이 방식을 지원하지 않습니다. SmartAccount 가이드를 참고하세요.

API 가이드

전체 흐름은 3단계입니다.

단계메서드엔드포인트
1. SponsorPOST/core/evm/v2/eoa/paymaster/sponsor
2. SendPOST/core/evm/v2/eoa/paymaster/send
3. ReceiptGET/core/evm/v2/eoa/paymaster/receipt

1. Sponsor

가스대납 요청을 보내고, 서명할 데이터를 받습니다.

Request

POST /core/evm/v2/eoa/paymaster/sponsor
{
"network": "ethereum-sepolia",
"from": "0xAbC...",
"to": "0xDeF...",
"value": "0x0",
"data": "0x..."
}
필드설명
network대상 네트워크 식별자
from송신자 EOA 주소
to수신자 주소 (컨트랙트 또는 EOA)
value전송할 ETH 양 (wei, hex)
data컨트랙트 호출 데이터. 단순 전송 시 "0x"

Response

{
"sponsored_transaction": {
"sender": "0xAbC...",
"nonce": "0x1",
"callData": "0x...",
"callGasLimit": "0x...",
"verificationGasLimit": "0x...",
"preVerificationGas": "0x...",
"maxFeePerGas": "0x...",
"maxPriorityFeePerGas": "0x...",
"paymasterAndData": "0x...",
"signature": "0x"
},
"sign_hash": "0xabcdef...",
"authorization": {
"chainId": "0x...",
"address": "0x...",
"nonce": "0x..."
},
"authorization_hash": "0x..."
}
필드설명
sponsored_transaction2단계 Send에 그대로 전달할 데이터
sign_hashEOA가 서명해야 할 UserOperation 해시
authorization최초 트랜잭션에만 포함. 아래 참고
authorization_hash최초 트랜잭션에만 포함. 아래 참고

2. Send

서명한 데이터를 전송합니다.

Request

POST /core/evm/v2/eoa/paymaster/send
{
"network": "ethereum-sepolia",
"sponsored_transaction": { "..." },
"signature": "0x...",
"authorization": {
"chainId": "0x...",
"address": "0x...",
"nonce": "0x...",
"v": 0,
"r": "0x...",
"s": "0x..."
}
}
필드설명
sponsored_transaction1. Sponsor 응답의 sponsored_transaction 그대로 전달
signaturesign_hash에 대한 서명값. 아래 참고
authorization최초 트랜잭션에만 포함. 아래 참고
경고

sponsored_transaction의 필드를 임의로 수정하면 서명 검증에 실패합니다. 응답을 그대로 전달하세요.

Response

{
"tx_id": "0x..."
}

3. Receipt

tx_id로 트랜잭션 처리 결과를 조회합니다.

Request

GET /core/evm/v2/eoa/paymaster/receipt?tx_id={tx_id}&network={network}

트랜잭션이 처리 중이면 null이 반환될 수 있습니다. 완료까지 폴링하세요.

서명 방법

sign_hashauthorization_hash 모두 WaaS의 MPC Sign API를 사용하여 서명합니다.

POST /v3/wallet/sign
{
"curve": "secp256k1",
"encrypted_share": "지갑 생성/복구 시 반환된 암호화된 MPC 쉐어",
"key_id": "서명에 사용할 키의 고유 식별자",
"message": "서명할 해시 (hex string)",
"secret_store": "쉐어 복호화에 사용되는 키"
}

sign_hash 서명

sign_hashpersonal_sign 방식의 서명이 필요합니다. Ethereum personal_sign 프리픽스를 적용한 해시를 계산한 뒤 /v3/wallet/sign에 전달합니다.

import { keccak256, toBytes, concat, toHex } from 'viem';

// personal_sign 프리픽스 적용
const prefix = toBytes(`\x19Ethereum Signed Message:\n32`);
const messageHash = keccak256(concat([prefix, toBytes(sponsorResponse.sign_hash)]));

const signRes = await fetch('/v3/wallet/sign', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${accessToken}` },
body: JSON.stringify({
curve: 'secp256k1',
encrypted_share: encryptedShare,
key_id: keyId,
message: messageHash,
secret_store: secretStore,
}),
});
const { signature } = await signRes.json();

const sendSignature = `0x${signature}`;

authorization_hash 서명 (최초 트랜잭션에만 해당)

authorizationauthorization_hash는 EOA가 처음으로 수수료 대납 트랜잭션을 전송할 때만 Sponsor 응답에 포함됩니다. 이후 트랜잭션에서는 포함되지 않습니다.

messageauthorization_hash 값을 전달하고, 응답의 signature(65바이트)를 r, s, v로 분해하여 authorization 객체에 채웁니다.

const authSignRes = await fetch('/v3/wallet/sign', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${accessToken}` },
body: JSON.stringify({
curve: 'secp256k1',
encrypted_share: encryptedShare,
key_id: keyId,
message: sponsorResponse.authorization_hash,
secret_store: secretStore,
}),
});
const { signature: authSig } = await authSignRes.json();

// 65바이트 서명(130 hex chars)을 r, s, v로 분해
const r = `0x${authSig.slice(0, 64)}`;
const s = `0x${authSig.slice(64, 128)}`;
const v = parseInt(authSig.slice(128, 130), 16) - 27; // 0 또는 1

const authorization = {
...sponsorResponse.authorization,
v,
r,
s,
};