# TronZap external_id 멱등성 수정 가이드

> **날짜**: 2026-03-21
> **대상 파일**: `node-service/packages/wallet-activator/src/services/ApprovalProcessor.ts`
> **문제**: id=6 USDC `Account resource insufficient error`

---

## 1. 문제 원인

### external_id 멱등성 (id=6 FAILED 원인)

TronZap API는 **동일 external_id**로 요청하면 **이전 완료된 트랜잭션을 그대로 반환**합니다.

```
현재 코드:  external_id: `approval-${approval.id}`
```

| 시도 | external_id | TronZap 동작 | 결과 |
|------|-------------|-------------|------|
| 1차 (이전 세션) | `approval-6` | 신규 에너지 렌탈 → 1시간 위임 | 에너지 렌탈 성공 |
| 2차 (이번 재시작) | `approval-6` | **동일 ID → 이전 완료 결과 반환** | 에너지 없음 (만료됨) |

코드는 `waitForCompletion`에서 `status: "success"`를 받고 정상 진행하지만,
실제 에너지 위임은 이미 만료된 상태 → approve 시 `Account resource insufficient error`.

### id=5 gas_tx_hash NULL — 정상 동작

id=5 (USDT)는 이번 실행에서 이전 세션의 **잔여 에너지**로 approve 성공.
에너지 렌탈을 스킵했으므로 저장할 TronZap ID가 없어 gas_tx_hash=NULL은 정상.

---

## 2. 수정사항 (1건)

### ApprovalProcessor.ts ~337행: external_id에 타임스탬프 추가

```typescript
// ❌ 기존 — 멱등성으로 이전 만료된 결과 반환
external_id: `approval-${approval.id}`,

// ✅ 수정 — 매 요청마다 고유한 ID
external_id: `approval-${approval.id}-${Date.now()}`,
```

이렇게 하면 매 실행마다 새로운 external_id가 생성되어 TronZap이 **신규 에너지 렌탈**을 실행합니다.

---

## 3. 적용 후 DB 리셋

VS Code에서 수정 적용 → common 빌드 전에 DB 리셋:

```sql
-- id=6 USDC만 리셋 (id=5 USDT는 이미 APPROVED)
UPDATE wallet_approvals
SET status = 'PENDING', retry_count = 0, error_message = NULL, gas_tx_hash = NULL
WHERE id = 6;

-- id=6의 이전 ENERGY_RENTAL 실패 기록 삭제 (모두 만료된 렌탈)
DELETE FROM gas_cost_records
WHERE reference_type = 'WALLET_APPROVAL' AND reference_id = 6;
```

## 4. 빌드 & 재시작

```bash
cd /Users/dudgh/git/cryptoments/node-service
npm run build --workspace=packages/common
# wallet-activator 재시작
```

## 5. 검증 SQL

```sql
-- 전체 wallet_approvals 최종 확인 (8건 전체 APPROVED 기대)
SELECT id, network_id, currency_id, status, gas_tx_hash, approve_tx_hash
FROM wallet_approvals ORDER BY id;

-- id=6 새 gas_cost_records 확인
SELECT id, reference_id, tx_type, fee_native, fee_usd, tx_hash
FROM gas_cost_records
WHERE reference_type = 'WALLET_APPROVAL' AND reference_id = 6;
```
