2026-02-11 16:31:28 +09:00
|
|
|
import type { KisRuntimeCredentials } from "@/features/settings/store/use-kis-runtime-store";
|
2026-02-10 11:16:39 +09:00
|
|
|
import type {
|
|
|
|
|
DashboardKisRevokeResponse,
|
|
|
|
|
DashboardKisValidateResponse,
|
|
|
|
|
DashboardKisWsApprovalResponse,
|
2026-02-11 16:31:28 +09:00
|
|
|
} from "@/features/trade/types/trade.types";
|
2026-02-10 11:16:39 +09:00
|
|
|
|
2026-02-11 15:27:03 +09:00
|
|
|
interface KisApiBaseResponse {
|
|
|
|
|
ok: boolean;
|
|
|
|
|
message: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function postKisAuthApi<T extends KisApiBaseResponse>(
|
|
|
|
|
endpoint: string,
|
2026-02-10 11:16:39 +09:00
|
|
|
credentials: KisRuntimeCredentials,
|
2026-02-11 15:27:03 +09:00
|
|
|
fallbackErrorMessage: string,
|
|
|
|
|
): Promise<T> {
|
|
|
|
|
const response = await fetch(endpoint, {
|
2026-02-10 11:16:39 +09:00
|
|
|
method: "POST",
|
|
|
|
|
headers: {
|
|
|
|
|
"content-type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify(credentials),
|
|
|
|
|
cache: "no-store",
|
|
|
|
|
});
|
|
|
|
|
|
2026-02-11 15:27:03 +09:00
|
|
|
const payload = (await response.json()) as T;
|
2026-02-10 11:16:39 +09:00
|
|
|
|
|
|
|
|
if (!response.ok || !payload.ok) {
|
2026-02-11 15:27:03 +09:00
|
|
|
throw new Error(payload.message || fallbackErrorMessage);
|
2026-02-10 11:16:39 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return payload;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2026-02-11 15:27:03 +09:00
|
|
|
* @description KIS API 키를 검증합니다.
|
|
|
|
|
* @see app/api/kis/validate/route.ts
|
|
|
|
|
*/
|
|
|
|
|
export async function validateKisCredentials(
|
|
|
|
|
credentials: KisRuntimeCredentials,
|
|
|
|
|
): Promise<DashboardKisValidateResponse> {
|
|
|
|
|
return postKisAuthApi<DashboardKisValidateResponse>(
|
|
|
|
|
"/api/kis/validate",
|
|
|
|
|
credentials,
|
|
|
|
|
"API 키 검증에 실패했습니다.",
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @description KIS 액세스 토큰을 폐기합니다.
|
|
|
|
|
* @see app/api/kis/revoke/route.ts
|
2026-02-10 11:16:39 +09:00
|
|
|
*/
|
|
|
|
|
export async function revokeKisCredentials(
|
|
|
|
|
credentials: KisRuntimeCredentials,
|
|
|
|
|
): Promise<DashboardKisRevokeResponse> {
|
2026-02-11 15:27:03 +09:00
|
|
|
return postKisAuthApi<DashboardKisRevokeResponse>(
|
|
|
|
|
"/api/kis/revoke",
|
|
|
|
|
credentials,
|
|
|
|
|
"API 토큰 폐기에 실패했습니다.",
|
|
|
|
|
);
|
2026-02-10 11:16:39 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2026-02-11 15:27:03 +09:00
|
|
|
* @description 웹소켓 승인키와 WS URL을 조회합니다.
|
|
|
|
|
* @see app/api/kis/ws/approval/route.ts
|
2026-02-10 11:16:39 +09:00
|
|
|
*/
|
|
|
|
|
export async function fetchKisWebSocketApproval(
|
|
|
|
|
credentials: KisRuntimeCredentials,
|
|
|
|
|
): Promise<DashboardKisWsApprovalResponse> {
|
2026-02-11 15:27:03 +09:00
|
|
|
const payload = await postKisAuthApi<DashboardKisWsApprovalResponse>(
|
|
|
|
|
"/api/kis/ws/approval",
|
|
|
|
|
credentials,
|
|
|
|
|
"웹소켓 승인키 발급에 실패했습니다.",
|
|
|
|
|
);
|
2026-02-10 11:16:39 +09:00
|
|
|
|
2026-02-11 15:27:03 +09:00
|
|
|
if (!payload.approvalKey || !payload.wsUrl) {
|
|
|
|
|
throw new Error(payload.message || "웹소켓 연결 정보가 누락되었습니다.");
|
2026-02-10 11:16:39 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return payload;
|
|
|
|
|
}
|