Files
a301_client/src/api/chain.js
tolelom 90b75413f1 refactor: api/ 주석 정리 및 소소한 개선
- client.js JSDoc 추가 (apiFetch, tryRefresh, apiUpload, localizeError)
- auth.js 단순 함수 JSDoc 제거, createLaunchTicket why 주석 유지
- chain.js BASE 중복 선언 이유 주석 추가, 단순 함수 JSDoc 제거
- announcements.js 후행 빈 줄 제거
- users.js getUsers 쿼리스트링 → URLSearchParams 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 18:47:26 +09:00

94 lines
2.6 KiB
JavaScript

import { apiFetch } from './client';
// exportWalletKey는 비밀번호 오류 시 서버가 401을 반환하므로
// apiFetch의 401 자동 refresh/로그아웃을 우회하기 위해 BASE를 직접 참조
const BASE = import.meta.env.VITE_API_BASE_URL || '';
// --- 지갑 ---
export async function getBalance() {
return apiFetch('/api/chain/balance');
}
export async function getWallet() {
return apiFetch('/api/chain/wallet');
}
/**
* 개인키 내보내기
* apiFetch를 우회해 직접 fetch 사용 — 비밀번호 오류(401)를 로그아웃 없이 처리하기 위함
* @param {string} password
* @returns {Promise<{privateKey: string}>}
* @throws {Error} 비밀번호 오류 시 status 401
*/
export async function exportWalletKey(password) {
const token = localStorage.getItem('token');
const headers = { 'Content-Type': 'application/json' };
if (token) headers['Authorization'] = `Bearer ${token}`;
const res = await fetch(BASE + '/api/chain/wallet/export', {
method: 'POST',
headers,
credentials: 'include',
body: JSON.stringify({ password }),
});
if (!res.ok) {
const err = new Error(res.status === 401 ? '비밀번호가 올바르지 않습니다' : '키 내보내기에 실패했습니다');
err.status = res.status;
try { const body = await res.json(); err.message = body.message || err.message; } catch { /* ignore parse failure */ }
throw err;
}
return res.json();
}
// --- 자산 ---
export async function getAssets() {
return apiFetch('/api/chain/assets');
}
export async function getAsset(id) {
return apiFetch(`/api/chain/asset/${id}`);
}
// --- 인벤토리 ---
export async function getInventory() {
return apiFetch('/api/chain/inventory');
}
// --- 마켓 ---
export async function getMarketListings() {
return apiFetch('/api/chain/market');
}
export async function getListing(id) {
return apiFetch(`/api/chain/market/${id}`);
}
/**
* Idempotency-Key 헤더를 붙인 POST 요청
* 중복 제출(네트워크 재시도 등)로 인한 이중 처리를 서버에서 방지
* @param {string} path
* @param {object} body
*/
function idempotentPost(path, body) {
return apiFetch(path, {
method: 'POST',
headers: { 'Idempotency-Key': crypto.randomUUID() },
body: JSON.stringify(body),
});
}
export async function listOnMarket(assetId, price) {
return idempotentPost('/api/chain/market/list', { assetId, price });
}
export async function buyFromMarket(listingId) {
return idempotentPost('/api/chain/market/buy', { listingId });
}
export async function cancelListing(listingId) {
return idempotentPost('/api/chain/market/cancel', { listingId });
}