# Phase 2 — Node.js API 테스트 스크립트

**날짜**: 2026-03-20
**대상**: blockchain-api (포트 3001), relayer-api (포트 3002)
**실행 방법**: 터미널에서 각 curl 명령을 순서대로 실행

> 모든 서비스가 기동된 상태에서 실행하세요:
> ```bash
> cd node-service
> pnpm dev:blockchain-api   # 터미널 1
> pnpm dev:relayer-api      # 터미널 2
> ```

---

## Phase 2-1. Health Check

```bash
# blockchain-api
curl -s http://localhost:3001/health | jq .
# 기대: { "status": "ok", ... }

# relayer-api
curl -s http://localhost:3002/health | jq .
# 기대: { "status": "ok", ... }
```

---

## Phase 2-2. Blockchain-API 조회 엔드포인트

### 2-2a. 잔액 조회 (Native)

```bash
# BSC ADMIN (id=1) — 0xF9cbB86D5fae82183AA8e0E4fFf05a4C917414FE
curl -s "http://localhost:3001/api/balance/native/0xF9cbB86D5fae82183AA8e0E4fFf05a4C917414FE?networkId=2" | jq .
# 기대: { "balance": "0.07xxx", "symbol": "BNB" }

# Polygon ADMIN (id=5)
curl -s "http://localhost:3001/api/balance/native/0x00113718ecF08339019e0E0F12Ced3a2dd9209E1?networkId=3" | jq .
# 기대: { "balance": "~49.9", "symbol": "POL" }

# TRON ADMIN (id=3)
curl -s "http://localhost:3001/api/balance/native/TXSXNMTsaYiiXvkXeiyBzu7rAxFSrDho1W?networkId=4" | jq .
# 기대: { "balance": "~636", "symbol": "TRX" }
```

### 2-2b. 잔액 조회 (Token — USDT)

```bash
# BSC USDT (아직 0)
curl -s "http://localhost:3001/api/balance/token/0xF9cbB86D5fae82183AA8e0E4fFf05a4C917414FE?networkId=2&tokenContract=0x55d398326f99059fF775485246999027B3197955" | jq .
# 기대: { "balance": "0" }

# TRON USDT (아직 0)
curl -s "http://localhost:3001/api/balance/token/TXSXNMTsaYiiXvkXeiyBzu7rAxFSrDho1W?networkId=4&tokenContract=TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" | jq .
# 기대: { "balance": "0" }
```

### 2-2c. 잔액 일괄 동기화

```bash
curl -s -X POST http://localhost:3001/api/balance/sync \
  -H "Content-Type: application/json" \
  -d '{"walletAddressIds": [1, 2, 3, 4, 5, 6, 8, 9, 10]}' | jq .
# 기대: 9개 지갑의 온체인 잔액 → DB wallet_balances 동기화 결과
```

### 2-2d. 가스 가격 조회

```bash
# BSC
curl -s "http://localhost:3001/api/gas/price?networkId=2" | jq .
# 기대: { "gasPrice": "1000000000", "unit": "gwei" } 또는 유사

# Polygon
curl -s "http://localhost:3001/api/gas/price?networkId=3" | jq .

# TRON (energy/bandwidth 기반 — 응답 형태 다를 수 있음)
curl -s "http://localhost:3001/api/gas/price?networkId=4" | jq .
```

### 2-2e. 최신 블록 번호

```bash
# BSC
curl -s "http://localhost:3001/api/block/latest?networkId=2" | jq .
# 기대: { "blockNumber": 12345678 }

# Polygon
curl -s "http://localhost:3001/api/block/latest?networkId=3" | jq .

# TRON
curl -s "http://localhost:3001/api/block/latest?networkId=4" | jq .
```

### 2-2f. Approve 상태 확인

```bash
# BSC GAS 지갑(id=2)의 USDT approve 상태 → Relayer 컨트랙트 대상
curl -s "http://localhost:3001/api/wallet/approve-status/0x85a1c69F246dB88c74a37b32966360b5c363DA0c?networkId=2&tokenContract=0x55d398326f99059fF775485246999027B3197955&spender=0x841c5833f70438F43671e5b66e87D9d6CED406Fc" | jq .
# 기대: { "allowance": "0" } — 아직 approve 실행 안 함
```

---

## Phase 2-3. System Admin 엔드포인트

### 2-3a. 컨트랙트 목록

```bash
curl -s http://localhost:3001/api/admin/contract/list | jq .
# 기대: 3개 (BSC, Polygon, TRON)
```

### 2-3b. 컨트랙트 상태

```bash
# BSC
curl -s http://localhost:3001/api/admin/contract/status/2 | jq .
# 기대: owner, paused=false, relayerCount=3

# Polygon
curl -s http://localhost:3001/api/admin/contract/status/3 | jq .

# TRON
curl -s http://localhost:3001/api/admin/contract/status/4 | jq .
```

### 2-3c. 네이티브 전송 (소액 테스트)

```bash
# BSC ADMIN(1) → GAS(2) 0.001 BNB (테스트)
curl -s -X POST http://localhost:3001/api/admin/wallet/transfer-native \
  -H "Content-Type: application/json" \
  -d '{"fromAddressId": 1, "toAddressId": 2, "amount": "0.001"}' | jq .
# 기대: { "txHash": "0x...", "from": "...", "to": "...", "amount": "0.001", "symbol": "BNB" }
```

### 2-3d. Validation 테스트

```bash
# 같은 지갑으로 전송 → 400
curl -s -X POST http://localhost:3001/api/admin/wallet/transfer-native \
  -H "Content-Type: application/json" \
  -d '{"fromAddressId": 1, "toAddressId": 1, "amount": "0.001"}' | jq .
# 기대: 400 "Cannot transfer to the same wallet"

# 다른 네트워크 → 400
curl -s -X POST http://localhost:3001/api/admin/wallet/transfer-native \
  -H "Content-Type: application/json" \
  -d '{"fromAddressId": 1, "toAddressId": 3, "amount": "0.001"}' | jq .
# 기대: 400 "Network mismatch"

# 필수 파라미터 누락 → 400
curl -s -X POST http://localhost:3001/api/admin/wallet/transfer-native \
  -H "Content-Type: application/json" \
  -d '{"fromAddressId": 1}' | jq .
# 기대: 400 "fromAddressId, toAddressId, and amount are required"
```

---

## Phase 2-4. Relayer-API 엔드포인트

### 2-4a. Relayer 목록

```bash
curl -s http://localhost:3002/api/relayer/list | jq .
# 기대: 3개 Relayer (BSC id=8, Polygon id=9, TRON id=10)
```

### 2-4b. Relayer 상태

```bash
# BSC Relayer
curl -s http://localhost:3002/api/relayer/status/8 | jq .
# 기대: { "addressId": 8, "address": "0x6e87...", "networkId": 2, "status": "ACTIVE" }

# TRON Relayer
curl -s http://localhost:3002/api/relayer/status/10 | jq .
```

### 2-4c. Nonce 조회

```bash
# BSC Relayer nonce
curl -s http://localhost:3002/api/relayer/nonce/8 | jq .
# 기대: { "currentNonce": N, "pendingCount": 0 }
```

### 2-4d. Collection Queue 상태

```bash
curl -s http://localhost:3002/api/collection/pending | jq .
# 기대: { "count": 0, "items": [] } — 아직 입금 없음
```

### 2-4e. Withdrawal Queue 상태

```bash
curl -s http://localhost:3002/api/withdrawal/pending | jq .
# 기대: { "count": 0, "items": [] } — 아직 출금 없음
```

---

## Phase 2-5. 결과 체크리스트

| # | 테스트 | 기대 | 결과 |
|---|--------|------|------|
| 2-1 | Health (blockchain-api) | `{ status: "ok" }` | |
| 2-1 | Health (relayer-api) | `{ status: "ok" }` | |
| 2-2a | Native balance (BSC) | ~0.078 BNB | |
| 2-2a | Native balance (Polygon) | ~49.9 POL | |
| 2-2a | Native balance (TRON) | ~636 TRX | |
| 2-2b | Token balance (BSC USDT) | 0 | |
| 2-2c | Balance sync (9 wallets) | 200 OK | |
| 2-2d | Gas price (BSC) | 200 OK | |
| 2-2d | Gas price (Polygon) | 200 OK | |
| 2-2e | Latest block (BSC) | 200 OK, blockNumber > 0 | |
| 2-2e | Latest block (TRON) | 200 OK | |
| 2-2f | Approve status | allowance = 0 | |
| 2-3a | Contract list | 3 contracts | |
| 2-3b | Contract status (BSC) | paused=false, relayers=3 | |
| 2-3c | Transfer native (0.001 BNB) | txHash 반환 | |
| 2-3d | Validation (same wallet) | 400 error | |
| 2-3d | Validation (network mismatch) | 400 error | |
| 2-4a | Relayer list | 3 relayers | |
| 2-4b | Relayer status | ACTIVE | |
| 2-4c | Nonce | 200 OK | |
| 2-4d | Collection pending | count=0 | |
| 2-4e | Withdrawal pending | count=0 | |

---

## 테스트 완료 후

결과를 Cowork에 공유해 주세요. 특히:
1. 실패한 엔드포인트가 있으면 에러 메시지 전체
2. 응답 형식이 기대와 다른 경우 실제 응답 JSON
3. relayer-api 엔드포인트 URL이 다를 수 있음 — 404가 나오면 `/api/relayer` 대신 `/api/relayers` 등 변형 시도
