> ## Documentation Index
> Fetch the complete documentation index at: https://docs.superearn.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 트랜잭션 연동 가이드

> 실행 프로필, 견적, 예치, 출금 요청 및 청구.

[빠른 시작](/ko/developers/integrate-earn-usdt) · [Data API](/ko/developers/data-api) · [회계·금융식](/ko/developers/financial-data)

## 실행 프로필

통합 릴리스에 `kaia-earnusdt-2026-07`을 고정하십시오.

| 컨트랙트                  | 주소                                           |
| --------------------- | -------------------------------------------- |
| SuperEarnRouter       | `0x7437892a3e2e658038758dd7ca638334c0c2006c` |
| SuperVault / EarnUSDT | `0x2e4e573d86c70688cd97d76bc5ddc1bb265bf5d6` |
| CooldownVault / seCDV | `0x4e4654ce4ca7ff0ba66a0a4a588a4bd55a6f9a33` |
| USDT                  | `0xd077a400968890eacc75cdc901f0356c943e4fdb` |

| 항목                      | 기대값                                  |
| ----------------------- | ------------------------------------ |
| 체인                      | Kaia `8217`                          |
| Router                  | 고정된 주소의 배포 바이트코드                     |
| `SuperVault.token()`    | CooldownVault 주소                     |
| `CooldownVault.asset()` | USDT 주소                              |
| Decimals                | USDT / seCDV / EarnUSDT: 6; KAIA: 18 |
| 상품 상태                   | 쓰기는 활성 배포; 조회의 경우 비활성 보유분도 보존        |

* 프로필 불일치 시 쓰기를 비활성화하십시오. 주소와 ABI는 검토된 릴리스를 거쳐 업데이트합니다.
* 데이터 결합 시 Data API의 chain-qualified ID를 사용하십시오.

### 최소 ABI

<Accordion title="Viem 조회 및 트랜잭션 인터페이스">
  ```ts theme={null}
  import { parseAbi } from "viem";

  export const routerAbi = parseAbi([
    "function previewDeposit(address yVault, uint256 amount) view returns (uint256 expectedShares)",
    "function previewRedeem(address yVault, uint256 yShares) view returns (uint256 assets)",
    "function previewWithdraw(address yVault, uint256 assets) view returns (uint256 ySharesNeeded)",
    "function previewClaim(address yVault, uint256 requestId) view returns (bool isClaimable, uint256 maxAssetsOut)",
    "function maxRedeemableShares(address yVault) view returns (uint256 maxShares)",
    "function deposit(address yVault, uint256 amount, uint256 minSharesOut) returns (uint256 yShares)",
    "function depositWithPermit(address yVault, uint256 amount, address receiver, uint256 minSharesOut, uint256 deadline, uint8 v, bytes32 r, bytes32 s) returns (uint256 yShares)",
    "function depositWithReferral(address yVault, uint256 amount, uint256 minSharesOut, bytes32 referralCode) returns (uint256 yShares)",
    "function depositWithPermitAndReferral(address yVault, uint256 amount, address receiver, uint256 minSharesOut, bytes32 referralCode, uint256 deadline, uint8 v, bytes32 r, bytes32 s) returns (uint256 yShares)",
    "function redeem(address yVault, uint256 yShares, uint256 minAssetsOut) returns (uint256 requestId)"
  ]);

  export const erc20Abi = parseAbi([
    "function balanceOf(address account) view returns (uint256)",
    "function allowance(address owner, address spender) view returns (uint256)",
    "function approve(address spender, uint256 amount) returns (bool)",
    "function nonces(address owner) view returns (uint256)",
    "function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)"
  ]);

  export const vaultReadAbi = parseAbi([
    "function token() view returns (address)",
    "function pricePerShare() view returns (uint256)",
    "function maxAvailableShares() view returns (uint256)",
    "function decimals() view returns (uint8)"
  ]);

  export const cooldownVaultAbi = parseAbi([
    "function asset() view returns (address)",
    "function cooldownPeriod() view returns (uint256)",
    "function maxLossThresholdBps() view returns (uint256)",
    "function claim(uint256 requestId, uint256 maxLossBps) returns (uint256 claimable)"
  ]);
  ```
</Accordion>

## 견적과 최소 수령액

원시 토큰 단위의 견적 출력값 `q`와 베이시스 포인트(bps) 단위의 슬리피지 허용 오차 `s`에 대해:

```text theme={null}
minOut = floor(q * (10,000 - s) / 10,000)
```

| 값        | 제약 조건                              |
| -------- | ---------------------------------- |
| `q`      | 양의 정수; 예치 시 지분 수량, 출금 시 USDT atoms |
| `s`      | 정수 basis points, `0 <= s < 10,000` |
| `minOut` | 양의 정수; 결과가 0으로 내림되는 견적은 거부         |

* 명시적인 제품/사용자 정책으로 슬리피지를 설정하고 서명 직전에 견적을 새로고침하십시오.
* 정수 연산을 사용하십시오. 100 bps는 1%입니다.
* 제출 전에 체인, 지갑 잔고, 승인량, 가스용 KAIA를 검증하십시오.

## 예치

| 단계 | 처리                                                    |
| -- | ----------------------------------------------------- |
| 1  | USDT를 6자리 소수점 atoms로 변환                               |
| 2  | `previewDeposit(vault, amount)`를 읽고 `minSharesOut` 계산 |
| 3  | 아래 permit 또는 approve 흐름 선택                            |
| 4  | 제출 후 영수증 확인, 잔고/활동 내역 갱신                              |

| 인증 방식            | 트랜잭션                                                                                  |
| ---------------- | ------------------------------------------------------------------------------------- |
| EIP-2612 permit  | `depositWithPermit(vault, amount, receiver, minSharesOut, deadline, v, r, s)`         |
| ERC-20 allowance | `allowance(owner, Router)` 확인; 필요 시 `approve`; `deposit(vault, amount, minSharesOut)` |
| 추천인 코드 지정        | 대응하는 `depositWithReferral` 또는 `depositWithPermitAndReferral`                          |

| USDT permit 필드 | 설정값                                                                              |
| -------------- | -------------------------------------------------------------------------------- |
| Domain         | `name: "Tether USD"`, `version: "1"`, `chainId: 8217`, `verifyingContract: USDT` |
| Message        | Owner, Router spender, 정확한 수량, 현재 nonce, 짧은 마감시한                                 |
| Referral       | 지정된 `bytes32` 코드; 예치 전용                                                          |

**주의**

* 서명 거부 시 시도를 중단하십시오. approve+deposit은 별도 사용자 액션으로 제공하십시오.
* 사용자 대면 예치와 출금은 반드시 Router를 사용해야 합니다.
* 대사를 위해 영수증 금액과 트랜잭션 해시를 보존하십시오.

## 출금 요청 (Redemption)

| 단계 | 처리                                                                 |
| -- | ------------------------------------------------------------------ |
| 1  | 지분 입력: `previewRedeem`; 자산 입력: `previewWithdraw` 후 `previewRedeem` |
| 2  | `maxRedeemableShares(vault)` 확인 및 연동의 명시적 한도 버퍼 적용                 |
| 3  | EarnUSDT 보유량과 Router 승인량 확인                                        |
| 4  | `minAssetsOut` 계산; `redeem(vault, shares, minAssetsOut)` 제출        |
| 5  | 영수증 이벤트에서 request ID와 체결 수량 확인                                     |
| 6  | 청구 완료될 때까지 `/accounts/{account}/redemptions` 및 `/activity` 갱신      |

| 한도 / 체결               | 의미                                   |
| --------------------- | ------------------------------------ |
| `maxRedeemableShares` | 볼트 전체의 동시 출금 채무 여유 한도                |
| `type(uint256).max`   | 채무 한도 비활성화 상태                        |
| 0                     | 현재 출금 여유 한도 없음                       |
| 부분 체결                 | 영수증에 체결 수량 기록; 미체결 EarnUSDT는 지갑으로 반환 |

**주의**

* 견적과 한도는 블록 포함 전에 변경될 수 있습니다. 트랜잭션 실패 내역을 사용자가 검토할 수 있도록 보존하십시오.
* 대기열의 `shares`는 seCDV 단위를 사용하며, 체결된 EarnUSDT는 Router 영수증에서 확인합니다.
* Request ID는 해당 대기열 컨트랙트 및 체인 범위 내에서 유일합니다.

## 청구 생애주기 (Claim)

| 상태값                                  | 의미                                  | 처리                               |
| ------------------------------------ | ----------------------------------- | -------------------------------- |
| `status: pending`                    | 미지급 출금 요청                           | 지급 완료까지 갱신                       |
| `claimability: ready / fully_funded` | 관측 블록 시점에 선행 FIFO 예약 및 해당 요청 자금 확보됨 | 즉시 수령 가능 상태 표시                   |
| `waiting / not_fully_funded`         | 해당 블록 시점에 자금 미확보 상태                 | 갱신 지속                            |
| `unknown`                            | 관측 불가 또는 미지원 상태                     | 수령 가능 여부 알 수 없음 표시               |
| `status: claimed`                    | 최종 정산 완료                            | `claim` 확인; `claimability`는 null |
| `cooldownEndsAt`                     | 정상 상환 윈도우 경계                        | 자금 상태와 함께 만료 시각 표시               |

* 키퍼는 쿨다운 만료 전이라도 자금이 완전히 확보되면 정상 청구를 자동 처리합니다.
* 선행 FIFO 요청이 유동성을 먼저 예약하므로 쿨다운 만료 후에도 자금 부족이 지속될 수 있습니다.

### 선택적 직접 청구 (Direct Claim)

| 요건       | 구현                                                            |
| -------- | ------------------------------------------------------------- |
| 직접 청구 UX | `CooldownVault.claim(requestId, maxLossBps)` 호출               |
| 사전 검증    | `eth_call`로 호출자 및 손실 허용 오차를 적용해 시뮬레이션                         |
| 제3자 호출   | `maxLossBps`가 `maxLossThresholdBps` 이하일 때 가능; 초과 시 수신자 본인만 가능 |
| 최종 확인    | 시뮬레이션된 지급액과 명시적 손실 허용 오차를 사용자에게 표시                            |

**주의**

* 직접 청구 클라이언트는 트랜잭션 제출 직전에 반드시 시뮬레이션을 실행해야 합니다. 시계 상태와 `previewClaim`만으로는 충분하지 않습니다.
* 준비 완료 상태(`ready`)라도 블록 포함 전에 유동성 상태가 달라질 수 있습니다.
