# Spring Boot ↔ Node.js API 엔드포인트 크로스 체크 보고서

> **작성일**: 2026-03-22
> **검토 범위**: `BlockchainApiClient` (blockchain-api:3001) + `RelayerApiClient` (relayer-api:3002)
> **Framework**: Axim REST Framework v1.3.1

---

## 1. BlockchainApiClient ↔ blockchain-api 라우트 비교

### ✅ 일치 (20개)

| # | Spring Boot 메서드 | 경로 | HTTP | Node.js 라우트 파일 |
|---|---|---|---|---|
| 1 | `deriveWallet()` | `/api/wallet/derive` | POST | wallet.ts |
| 2 | `getApproveStatus()` | `/api/wallet/approve-status/{address}` | GET | wallet.ts |
| 3 | `getTokenBalance()` | `/api/balance/token/{address}` | GET | balance.ts |
| 4 | `getNativeBalance()` | `/api/balance/native/{address}` | GET | balance.ts |
| 5 | `syncBalances()` | `/api/balance/sync` | POST | balance.ts |
| 6 | `getTxStatus()` | `/api/tx/status/{txHash}` | GET | tx.ts |
| 7 | `getTxReceipt()` | `/api/tx/receipt/{txHash}` | GET | tx.ts |
| 8 | `getGasPrice()` | `/api/gas/price` | GET | gas.ts |
| 9 | `estimateGas()` | `/api/gas/estimate` | POST | gas.ts |
| 10 | `getLatestBlock()` | `/api/block/latest` | GET | block.ts |
| 11 | `createAdminWallet()` | `/api/admin/wallet/create-admin` | POST | system-admin.ts |
| 12 | `createInfraWallet()` | `/api/admin/wallet/create-infra` | POST | system-admin.ts |
| 13 | `registerContract()` | `/api/admin/contract/register` | POST | system-admin.ts |
| 14 | `addRelayerToContract()` | `/api/admin/contract/add-relayer` | POST | system-admin.ts |
| 15 | `removeRelayerFromContract()` | `/api/admin/contract/remove-relayer` | POST | system-admin.ts |
| 16 | `pauseContract()` | `/api/admin/contract/pause` | POST | system-admin.ts |
| 17 | `unpauseContract()` | `/api/admin/contract/unpause` | POST | system-admin.ts |
| 18 | `getContractStatus()` | `/api/admin/contract/status/{networkId}` | GET | system-admin.ts |
| 19 | `getContractList()` | `/api/admin/contract/list` | GET | system-admin.ts |
| 20 | `getOnChainNonce()` | `/api/nonce/{address}` | GET | nonce.ts |

### ❌ 불일치 → 수정 완료 (2건)

| # | 문제 | 원인 | 조치 |
|---|------|------|------|
| 1 | `queryBalance()` — `POST /api/wallet/balance` | Node.js에 해당 엔드포인트 없음. `getTokenBalance()`/`getNativeBalance()`로 대체됨 | **삭제 완료** — Dead code 제거 |
| 2 | `getRelayerStatus()` — `GET /api/relayer/status` (path variable 없음) | Node.js는 `/api/relayer/status/:walletId`만 존재. 전체 목록은 `/api/relayer/list` | **삭제 완료** — `getRelayerList()` + `getRelayerDetailStatus()` 가 커버 |

### Node.js에만 존재 (Spring Boot 클라이언트 미선언, 3건)

| # | Node.js 경로 | HTTP | 설명 | Spring Boot 필요성 |
|---|---|---|---|---|
| 1 | `/api/admin/wallet/transfer-native` | POST | 네이티브 코인 수동 전송 | ⚠️ admin-api에서 호출 가능성 — 향후 추가 검토 |
| 2 | `/api/admin/wallet/distribute-native` | POST | 네이티브 코인 일괄 배분 | ⚠️ 동일 |
| 3 | `/api/admin/wallet/transfer-token` | POST | 토큰 수동 전송 | ⚠️ 동일 |

> **판단**: 위 3개 엔드포인트는 admin-api에서 수동 자금 이동 시 필요할 수 있으나, 현재 비즈니스 흐름에서는 미사용. Phase 2 운영 도구 구현 시 `BlockchainApiClient`에 메서드 추가 예정.

---

## 2. RelayerApiClient ↔ relayer-api 라우트 비교

### ✅ 일치 (4개)

| # | Spring Boot 메서드 | 경로 | HTTP | Node.js 라우트 |
|---|---|---|---|---|
| 1 | `registerRelayer()` | `/api/relayer/register` | POST | relayer.ts |
| 2 | `unregisterRelayer()` | `/api/relayer/unregister` | POST | relayer.ts |
| 3 | `getRelayerList()` | `/api/relayer/list` | GET | relayer.ts |
| 4 | `getRelayerDetailStatus()` | `/api/relayer/status/{walletId}` | GET | relayer.ts |

### ❌ 불일치 → 수정 완료 (1건)

| # | 문제 | 조치 |
|---|------|------|
| 1 | `getRelayerStatus()` — 경로 불일치 + 미사용 | **삭제 완료** |

### Node.js에만 존재 (Spring Boot 미선언, 1건)

| # | Node.js 경로 | HTTP | 설명 | Spring Boot 필요성 |
|---|---|---|---|---|
| 1 | `/api/relayer/nonce/:walletId` | GET | Relayer nonce tracker 조회 | ❌ 불필요 — core `NonceTrackerService`가 `BlockchainApiClient.getOnChainNonce()`로 직접 조회 |

---

## 3. DTO 정합성 요약

### BlockchainApiClient DTO (사용 중)

| DTO | 용도 | 사용 모듈 |
|-----|------|----------|
| `WalletDeriveRequest/Response` | HD 지갑 파생 | core (WalletService) |
| `TokenBalanceResponse` | 토큰 잔액 조회 | core (WalletService.syncOnchainBalance) |
| `NativeBalanceResponse` | 네이티브 잔액 조회 | core (WalletService.syncOnchainBalance, monitorGasWallets) |
| `TxReceiptResponse` | TX 영수증 조회 | scheduler (StaleTxMonitorJob) |
| `OnChainNonceResponse` | 온체인 논스 조회 | core (NonceTrackerService) |
| `InfraWalletCreateApiRequest/Response` | 인프라 지갑 생성 | admin-api (InfraWalletService) |
| `ContractRegisterRequest/Response` | 컨트랙트 등록 | admin-api (ContractManagementService) |
| `ContractRelayerRequest/Response` | Relayer 컨트랙트 등록/해제 | admin-api (ContractManagementService) |
| `ContractPauseRequest/Response` | 컨트랙트 정지/해제 | admin-api (ContractManagementService) |

### Dead DTO (미사용 — 정리 대상)

| DTO | 원인 |
|-----|------|
| `BalanceQueryRequest` | `queryBalance()` 삭제로 미사용 |
| `BalanceQueryResponse` | 동일 |

---

## 4. Error Handler Bean 상태

| Bean 이름 | 대상 서비스 | 상태 |
|-----------|-----------|------|
| `blockchain-api-error-handler` | blockchain-api:3001 | ✅ `BlockchainApiErrorHandler` 등록됨 |
| `relayer-api-error-handler` | relayer-api:3002 | ✅ `RelayerApiErrorHandler` 등록됨 |

Node.js 에러 응답 `{ code, error, detail }` → Axim `ApiError` 자동 변환.

---

## 5. 권장 후속 조치

| 우선순위 | 항목 | 상태 |
|---------|------|------|
| P0 | Dead code 제거 (`queryBalance`, `getRelayerStatus`) | ✅ 완료 |
| P1 | Dead DTO 삭제 (`BalanceQueryRequest/Response`) | ⚠️ 다음 정리 시 |
| P2 | admin-api 수동 전송 API 추가 (`transfer-native/token/distribute`) | 향후 운영 도구 구현 시 |

---

**검토 결과**: Spring Boot ↔ Node.js API 연동 **정합성 확인 완료**. 20+4=24개 엔드포인트 일치, 2건 dead code 제거, 3건 향후 추가 대상 식별.
