API 인터페이스는 암호화폐 시스템과 외부 애플리케이션 간의 통신을 가능하게 하는 핵심 계층입니다. 이 장에서는 지갑 API, 거래소 API, 노드 API의 설계 원칙과 구현 방법, 그리고 보안과 성능을 보장하는 인증 및 속도 제한 메커니즘을 다룹니다.
암호화폐 API 설계 시 다음의 핵심 원칙을 준수해야 합니다:
WIA-FIN-003은 RESTful API 설계를 기본으로 하며, 다음 원칙을 따릅니다:
/wallets/{id}, /transactions/{hash})암호화폐 API는 금융 자산을 다루므로 보안이 최우선입니다:
모든 WIA 인증 암호화폐 시스템은 다음 API 표준을 준수해야 합니다:
X-RateLimit-*)지갑 API는 사용자가 암호화폐 자산을 관리할 수 있도록 하는 핵심 인터페이스입니다.
POST /api/v1/wallets
Content-Type: application/json
Authorization: Bearer <api_key>
{
"currency": "BTC",
"type": "hot",
"label": "Main Wallet"
}
Response (201 Created):
{
"wallet_id": "wlt_9k2j3h4g5f6d7s8a",
"address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"currency": "BTC",
"type": "hot",
"created_at": "2025-12-25T10:30:00Z"
}
GET /api/v1/wallets/{wallet_id}/balance
Authorization: Bearer <api_key>
Response (200 OK):
{
"wallet_id": "wlt_9k2j3h4g5f6d7s8a",
"balance": {
"available": "1.25000000",
"pending": "0.10000000",
"total": "1.35000000"
},
"currency": "BTC",
"last_updated": "2025-12-25T10:35:22Z"
}
POST /api/v1/wallets/{wallet_id}/transactions
Content-Type: application/json
Authorization: Bearer <api_key>
X-Signature: <hmac_signature>
{
"to_address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
"amount": "0.05000000",
"fee_level": "medium",
"memo": "Payment for services"
}
Response (201 Created):
{
"transaction_id": "txn_4j5k6l7m8n9o0p1q",
"hash": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6",
"status": "pending",
"amount": "0.05000000",
"fee": "0.00002500",
"created_at": "2025-12-25T10:40:15Z"
}
| 메서드 | 엔드포인트 | 설명 | 인증 |
|---|---|---|---|
| POST | /api/v1/wallets | 새 지갑 생성 | API Key |
| GET | /api/v1/wallets | 지갑 목록 조회 | API Key |
| GET | /api/v1/wallets/{id} | 지갑 상세 정보 | API Key |
| GET | /api/v1/wallets/{id}/balance | 잔액 조회 | API Key |
| POST | /api/v1/wallets/{id}/transactions | 트랜잭션 생성 | API Key + HMAC |
| GET | /api/v1/wallets/{id}/transactions | 트랜잭션 내역 | API Key |
| GET | /api/v1/wallets/{id}/addresses | 주소 목록 | API Key |
| POST | /api/v1/wallets/{id}/addresses | 새 주소 생성 | API Key + HMAC |
거래소 API는 거래, 주문 관리, 시장 데이터 조회를 위한 인터페이스를 제공합니다.
GET /api/v1/markets/BTC-USD/ticker
Response (200 OK):
{
"symbol": "BTC-USD",
"last_price": "94850.50",
"bid": "94848.00",
"ask": "94852.00",
"volume_24h": "12548.75",
"change_24h": "+2.45",
"high_24h": "95200.00",
"low_24h": "92800.00",
"timestamp": "2025-12-25T10:45:30Z"
}
POST /api/v1/orders
Content-Type: application/json
Authorization: Bearer <api_key>
X-Signature: <hmac_signature>
X-Timestamp: 1735126800
X-Nonce: 8492038475
{
"symbol": "BTC-USD",
"side": "buy",
"type": "limit",
"price": "94800.00",
"quantity": "0.1",
"time_in_force": "GTC"
}
Response (201 Created):
{
"order_id": "ord_2a3b4c5d6e7f8g9h",
"symbol": "BTC-USD",
"side": "buy",
"type": "limit",
"price": "94800.00",
"quantity": "0.1",
"filled": "0.0",
"status": "open",
"created_at": "2025-12-25T10:50:00Z"
}
GET /api/v1/orders/{order_id}
Authorization: Bearer <api_key>
Response (200 OK):
{
"order_id": "ord_2a3b4c5d6e7f8g9h",
"status": "partially_filled",
"filled": "0.05",
"remaining": "0.05",
"average_price": "94795.50"
}
DELETE /api/v1/orders/{order_id}
Authorization: Bearer <api_key>
X-Signature: <hmac_signature>
Response (200 OK):
{
"order_id": "ord_2a3b4c5d6e7f8g9h",
"status": "cancelled",
"cancelled_at": "2025-12-25T11:00:00Z"
}
| 카테고리 | 주요 엔드포인트 | 인증 필요 | 속도 제한 |
|---|---|---|---|
| 시장 데이터 | /markets/*/ticker, /markets/*/orderbook | 아니오 | 100 req/min |
| 거래 | /orders, /trades | 예 | 20 req/min |
| 계정 | /account/balance, /account/history | 예 | 30 req/min |
| 입출금 | /deposits, /withdrawals | 예 | 10 req/min |
노드 API는 블록체인 네트워크와 직접 통신하여 블록, 트랜잭션, 네트워크 상태를 조회합니다.
GET /api/v1/blocks/latest
Authorization: Bearer <api_key>
Response (200 OK):
{
"height": 825000,
"hash": "00000000000000000002a7c4c1e48d76c5a37902165a270156b7a8d72728a054",
"timestamp": "2025-12-25T11:10:00Z",
"transactions": 2456,
"size": 1398745,
"difficulty": 72032647305818.98,
"nonce": 3842947562
}
GET /api/v1/blocks/{height}
GET /api/v1/blocks/{hash}
GET /api/v1/transactions/{hash}
Authorization: Bearer <api_key>
Response (200 OK):
{
"hash": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6",
"block_height": 824998,
"confirmations": 2,
"timestamp": "2025-12-25T11:05:30Z",
"inputs": [
{
"address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"amount": "0.06000000"
}
],
"outputs": [
{
"address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
"amount": "0.05000000"
},
{
"address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"amount": "0.00995000"
}
],
"fee": "0.00005000",
"size": 225
}
GET /api/v1/network/status
Authorization: Bearer <api_key>
Response (200 OK):
{
"network": "mainnet",
"connected_peers": 8,
"block_height": 825000,
"sync_status": "synced",
"mempool_size": 15420,
"mempool_bytes": 45892634,
"estimated_smart_fee": {
"low": "10 sat/vB",
"medium": "25 sat/vB",
"high": "50 sat/vB"
}
}
| 기능 | Bitcoin Core | Ethereum Geth | WIA 표준 |
|---|---|---|---|
| 블록 조회 | getblock | eth_getBlockByNumber | GET /blocks/{id} |
| 트랜잭션 조회 | getrawtransaction | eth_getTransactionByHash | GET /transactions/{hash} |
| 잔액 조회 | getbalance | eth_getBalance | GET /addresses/{addr}/balance |
| 트랜잭션 전송 | sendrawtransaction | eth_sendRawTransaction | POST /transactions |
| 멤풀 조회 | getmempoolinfo | txpool_status | GET /mempool |
암호화폐 API는 다층 인증 시스템을 통해 보안을 보장합니다.
기본 인증 방식으로 모든 요청에 API 키를 포함합니다:
Authorization: Bearer wia_api_key_9k2j3h4g5f6d7s8a1b2c3d4e5f6g7h8i
# 또는 헤더로
X-API-Key: wia_api_key_9k2j3h4g5f6d7s8a1b2c3d4e5f6g7h8i
wia_api_key_민감한 작업(트랜잭션 생성, 출금 등)에는 HMAC-SHA256 서명이 필요합니다:
// 서명 생성 과정
const timestamp = Date.now();
const nonce = generateNonce();
const method = 'POST';
const path = '/api/v1/wallets/wlt_xxx/transactions';
const body = JSON.stringify(requestBody);
const message = `${timestamp}${nonce}${method}${path}${body}`;
const signature = crypto
.createHmac('sha256', apiSecret)
.update(message)
.digest('hex');
// 요청 헤더
headers: {
'Authorization': 'Bearer ' + apiKey,
'X-Signature': signature,
'X-Timestamp': timestamp,
'X-Nonce': nonce
}
function verifySignature(req, apiSecret) {
const { signature, timestamp, nonce } = req.headers;
// 타임스탬프 검증 (5분 이내)
const now = Date.now();
if (Math.abs(now - timestamp) > 300000) {
throw new Error('Request expired');
}
// Nonce 중복 검증
if (isNonceUsed(nonce)) {
throw new Error('Nonce already used');
}
// 서명 재생성 및 비교
const message = `${timestamp}${nonce}${req.method}${req.path}${req.body}`;
const expected = crypto
.createHmac('sha256', apiSecret)
.update(message)
.digest('hex');
if (signature !== expected) {
throw new Error('Invalid signature');
}
// Nonce 저장 (재사용 방지)
storeNonce(nonce, timestamp);
return true;
}
제3자 애플리케이션을 위한 OAuth 2.0 지원:
// 1. 인증 URL로 리다이렉트
https://api.wia-crypto.io/oauth/authorize
?client_id=app_client_123
&redirect_uri=https://yourapp.com/callback
&response_type=code
&scope=wallet:read,transaction:write
// 2. 콜백으로 code 수신
https://yourapp.com/callback?code=auth_code_xyz
// 3. 액세스 토큰 교환
POST /oauth/token
{
"grant_type": "authorization_code",
"code": "auth_code_xyz",
"client_id": "app_client_123",
"client_secret": "app_secret_456",
"redirect_uri": "https://yourapp.com/callback"
}
Response:
{
"access_token": "wia_access_a1b2c3d4e5f6",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "wia_refresh_g7h8i9j0k1l2",
"scope": "wallet:read transaction:write"
}
API 남용 방지 및 공정한 리소스 분배를 위한 속도 제한이 필수입니다.
| API 티어 | 분당 요청 | 일일 요청 | 동시 연결 | 비용 |
|---|---|---|---|---|
| 무료 | 60 | 10,000 | 2 | $0 |
| 스타터 | 300 | 100,000 | 10 | $49/월 |
| 프로 | 1,200 | 500,000 | 50 | $199/월 |
| 엔터프라이즈 | 무제한 | 무제한 | 무제한 | 맞춤형 |
모든 API 응답에는 속도 제한 정보가 포함됩니다:
HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1735127400
X-RateLimit-Retry-After: 30
// 제한 초과 시
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1735127400
Retry-After: 30
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "API rate limit exceeded. Retry after 30 seconds.",
"retry_after": 30
}
}
WIA-FIN-003은 다음 알고리즘을 권장합니다:
class TokenBucket {
constructor(capacity, refillRate) {
this.capacity = capacity;
this.tokens = capacity;
this.refillRate = refillRate; // tokens per second
this.lastRefill = Date.now();
}
tryConsume(tokens = 1) {
this.refill();
if (this.tokens >= tokens) {
this.tokens -= tokens;
return true;
}
return false;
}
refill() {
const now = Date.now();
const elapsed = (now - this.lastRefill) / 1000;
const tokensToAdd = elapsed * this.refillRate;
this.tokens = Math.min(this.capacity, this.tokens + tokensToAdd);
this.lastRefill = now;
}
}
class SlidingWindowRateLimiter {
constructor(limit, windowMs) {
this.limit = limit;
this.windowMs = windowMs;
this.requests = new Map(); // userId -> [timestamps]
}
tryRequest(userId) {
const now = Date.now();
const windowStart = now - this.windowMs;
// 오래된 요청 제거
const userRequests = this.requests.get(userId) || [];
const validRequests = userRequests.filter(t => t > windowStart);
if (validRequests.length < this.limit) {
validRequests.push(now);
this.requests.set(userId, validRequests);
return {
allowed: true,
remaining: this.limit - validRequests.length
};
}
const oldestRequest = validRequests[0];
const resetTime = oldestRequest + this.windowMs;
return {
allowed: false,
remaining: 0,
resetAt: resetTime
};
}
}
const rateLimits = {
// 공개 API (낮은 제한)
'GET /api/v1/markets/*/ticker': { limit: 100, window: 60000 },
'GET /api/v1/markets/*/orderbook': { limit: 50, window: 60000 },
// 계정 조회 (중간 제한)
'GET /api/v1/wallets/*': { limit: 60, window: 60000 },
'GET /api/v1/account/balance': { limit: 30, window: 60000 },
// 거래 작업 (높은 제한)
'POST /api/v1/orders': { limit: 20, window: 60000 },
'POST /api/v1/withdrawals': { limit: 5, window: 60000 },
'POST /api/v1/wallets/*/transactions': { limit: 10, window: 60000 }
};
일관된 에러 응답 형식은 API 사용성을 크게 향상시킵니다.
{
"error": {
"code": "INSUFFICIENT_BALANCE",
"message": "지갑 잔액이 부족합니다.",
"details": {
"wallet_id": "wlt_9k2j3h4g5f6d7s8a",
"required": "0.1 BTC",
"available": "0.05 BTC"
},
"timestamp": "2025-12-25T11:30:00Z",
"request_id": "req_8x9y0z1a2b3c4d5e"
}
}
| HTTP 상태 | 에러 코드 | 설명 | 재시도 가능 |
|---|---|---|---|
| 400 | INVALID_REQUEST | 잘못된 요청 형식 | 아니오 |
| 401 | UNAUTHORIZED | 인증 실패 | 아니오 |
| 403 | FORBIDDEN | 권한 없음 | 아니오 |
| 404 | NOT_FOUND | 리소스를 찾을 수 없음 | 아니오 |
| 429 | RATE_LIMIT_EXCEEDED | 속도 제한 초과 | 예 |
| 500 | INTERNAL_ERROR | 서버 내부 오류 | 예 |
| 503 | SERVICE_UNAVAILABLE | 서비스 일시 중단 | 예 |
실시간 데이터 스트리밍을 위한 WebSocket 지원:
// 연결 설정
const ws = new WebSocket('wss://api.wia-crypto.io/v1/stream');
ws.onopen = () => {
// 인증
ws.send(JSON.stringify({
type: 'auth',
api_key: 'wia_api_key_xxx'
}));
// 구독
ws.send(JSON.stringify({
type: 'subscribe',
channels: ['ticker.BTC-USD', 'trades.BTC-USD']
}));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Received:', data);
};
// 메시지 예시
{
"type": "ticker",
"symbol": "BTC-USD",
"price": "94850.50",
"volume": "12548.75",
"timestamp": "2025-12-25T11:45:30Z"
}
| 채널 | 설명 | 업데이트 빈도 | 인증 필요 |
|---|---|---|---|
| ticker.{symbol} | 실시간 시세 | 1초 | 아니오 |
| trades.{symbol} | 최근 거래 | 실시간 | 아니오 |
| orderbook.{symbol} | 호가창 | 실시간 | 아니오 |
| account.balance | 계정 잔액 | 변경 시 | 예 |
| account.orders | 주문 상태 | 변경 시 | 예 |
| wallet.{id}.transactions | 지갑 트랜잭션 | 변경 시 | 예 |
WIA-FIN-003은 OpenAPI 3.0 스펙을 사용한 자동 문서화를 권장합니다.
openapi: 3.0.0
info:
title: WIA Crypto Exchange API
version: 1.0.0
description: WIA-FIN-003 준수 암호화폐 거래소 API
servers:
- url: https://api.wia-crypto.io/v1
description: Production server
security:
- ApiKeyAuth: []
- HmacAuth: []
paths:
/wallets:
post:
summary: 새 지갑 생성
tags: [Wallets]
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [currency, type]
properties:
currency:
type: string
enum: [BTC, ETH, USDT]
type:
type: string
enum: [hot, cold]
responses:
'201':
description: 지갑 생성 성공
content:
application/json:
schema:
$ref: '#/components/schemas/Wallet'
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
HmacAuth:
type: apiKey
in: header
name: X-Signature
schemas:
Wallet:
type: object
properties:
wallet_id:
type: string
address:
type: string
currency:
type: string
created_at:
type: string
format: date-time
API 성능 향상을 위한 핵심 전략:
// Redis 캐싱 예시
async function getMarketTicker(symbol) {
const cacheKey = `ticker:${symbol}`;
// 캐시 확인
let data = await redis.get(cacheKey);
if (data) {
return JSON.parse(data);
}
// DB 조회
data = await database.getTickerData(symbol);
// 캐시 저장 (1초 TTL)
await redis.setex(cacheKey, 1, JSON.stringify(data));
return data;
}
GET /api/v1/transactions?page=2&limit=50
Response:
{
"data": [...],
"pagination": {
"page": 2,
"limit": 50,
"total": 1547,
"total_pages": 31
},
"links": {
"first": "/api/v1/transactions?page=1&limit=50",
"prev": "/api/v1/transactions?page=1&limit=50",
"next": "/api/v1/transactions?page=3&limit=50",
"last": "/api/v1/transactions?page=31&limit=50"
}
}
한국 금융결제원(KFTC) 오픈뱅킹 공동망·금융위원회(FSC) 「전자금융감독규정」·금융보안원(FSEC) 「오픈뱅킹 보안 가이드라인」·KISA ISMS-P 인증이 API 인터페이스 보안을 규율한다. KS X ISO 20022·OAuth 2.0·OpenID Connect·FIDO2/WebAuthn (한국 정부 「전자서명법」 채택 표준) 이 의무 적용된다. 업비트·빗썸·코인원·코빗·고팍스 VASP 의 OpenAPI 사양, 케이뱅크·NH농협·신한은행 실명계좌 API, 금융결제원 오픈뱅킹 표준 API (잔액조회·이체·거래내역) 와의 상호운용을 KS X ISO 20022 한국 프로파일이 정의한다. KATS·TTA·NIA·ETRI·KISA·KCMVP 협력으로 W3C VC 2.0·DIDComm v2 한국 프로파일도 발행 중이다.
한국의 산업·기술 표준화는 다음 협력 체계를 통해 운영된다. 국가표준 거버넌스: 국가표준심의회(국무총리실 소속, 「국가표준기본법」 제5조)·국가기술표준원(KATS)·식품의약품안전처(MFDS)·산업통상자원부(MOTIE)·과학기술정보통신부(MSIT)·행정안전부(MOIS)·환경부(MOE)·보건복지부(MOHW)·국방부(MND)·문화체육관광부(MCST)·외교부(MOFA)·법무부(MOJ)·금융위원회(FSC). 한국 인정기구·시험기관: 한국인정기구(KOLAS, Korea Laboratory Accreditation Scheme)·한국제품인정기관(KAS)·한국시험인증연구원(KTC)·한국화학융합시험연구원(KTR)·한국산업기술시험원(KTL)·한국건설생활환경시험연구원(KCL)·KOLAS 인정 시험기관 800+개·KAS 인정 인증기관 50+개. 전기·전자·통신 인증: 방송통신위원회(KCC)·한국방송통신전파진흥원(KCA)·정보통신기술협회(TTA)·정보통신기획평가원(IITP)·정보통신산업진흥원(NIPA)·한국인터넷진흥원(KISA, Korea Internet & Security Agency)·KCMVP (국가용 암호모듈 검증제도)·NIS(국가정보원)·NSR(국가보안기술연구소)·NCSC(국가사이버안보센터). 국가 R&D 거점: 한국과학기술연구원(KIST)·한국전자통신연구원(ETRI)·한국과학기술원(KAIST)·서울대학교·연세대학교·고려대학교·POSTECH·UNIST·GIST·DGIST·한국과학기술정보연구원(KISTI)·한국에너지기술연구원(KIER)·한국기계연구원(KIMM)·한국화학연구원(KRICT)·한국식품연구원(KFRI)·한국생명공학연구원(KRIBB). 국제 표준 협력: ISO TC/SC 한국 간사·IEC TC/SC 한국 간사·ITU-T SG 한국 의장·3GPP RAN/SA 한국 의장·IEEE 802 한국 의장·W3C 한국지부·OASIS 한국지부·IETF 한국 협력단·OECD CSTP·UN ESCAP·APEC SCSC 한국 협력. 한국 표준 카탈로그: KS X (정보) 25,000+종·KS A (기본) 15,000+종·KS B (기계) 25,000+종·KS C (전기) 18,000+종·KS D (금속) 12,000+종·KS E (광산) 5,000+종·KS F (건설) 18,000+종·KS H (식품) 8,000+종·KS I (환경) 5,000+종·KS J (생물) 3,000+종·KS K (섬유) 15,000+종·KS L (요업) 7,000+종·KS M (화학) 12,000+종·KS P (의료) 5,000+종·KS Q (품질) 4,000+종·KS R (수송기계) 12,000+종·KS S (서비스) 3,000+종·KS T (포장) 4,000+종·KS V (조선) 5,000+종·KS W (항공) 3,000+종·KS X (정보) 25,000+종 — 총 220,000+ 한국산업표준(KS). 「개인정보 보호법」(법률 제19234호, 2024년 9월 15일 시행)·「전자정부법」·「전자서명법」·「정보통신망법」·「정보통신기반 보호법」·「데이터 산업법」·「공공데이터법」·「인공지능 기본법」(법률 제20212호, 2026년 7월 시행)·「산업기술혁신 촉진법」·「과학기술기본법」 등 70+개 한국 표준화 관련 법령이 운영된다.