@debate300/bithumb-pro
Version:
A real-time cryptocurrency price tracker for Bithumb (Pro).
117 lines (116 loc) • 4.73 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Upbit = void 0;
const ws_1 = __importDefault(require("ws"));
const chalk_1 = __importDefault(require("chalk"));
const axios_1 = __importDefault(require("axios"));
const uuid_1 = require("uuid");
const common_1 = require("../common");
class Upbit extends common_1.Exchange {
constructor(redrawCallback) {
super(redrawCallback);
this.name = "Upbit";
this.ws = null;
this.isActive = false;
this.wsUri = "wss://api.upbit.com/websocket/v1";
this.marketInfo = new Map();
this.iconMap = new Map();
}
async fetchMarketInfo() {
try {
const response = await axios_1.default.get("https://api.upbit.com/v1/market/all");
if (response.status === 200) {
const markets = response.data;
markets.forEach((market) => {
if (market.market.startsWith("KRW-")) {
this.marketInfo.set(market.market, market);
}
});
}
}
catch (error) {
console.error(chalk_1.default.red("Upbit 마켓 정보 로딩 오류:"), error);
}
}
async connect(appConfig) {
await this.fetchMarketInfo();
const upbitSymbols = appConfig.coins.map((coin) => {
const symbol = `${coin.unit_currency}-${coin.symbol}`;
this.iconMap.set(symbol, coin.icon);
return symbol;
});
if (this.ws)
this.disconnect();
this.ws = new ws_1.default(this.wsUri);
this.ws.on("open", () => {
console.log(chalk_1.default.green("Upbit WebSocket에 연결되었습니다."));
const subscribeMsg = JSON.stringify([
{ ticket: (0, uuid_1.v4)() },
{ type: "ticker", codes: upbitSymbols },
]);
this.ws?.send(subscribeMsg);
});
this.ws.on("message", (data) => {
try {
const message = JSON.parse(data.toString("utf8"));
if (message.type === "ticker") {
const coinConfig = appConfig.coins.find((c) => `${c.unit_currency}-${c.symbol}` === message.code);
const standardizedData = this.standardize(message, coinConfig);
this.realTimeData.set(standardizedData.symbol, standardizedData);
this.redrawCallback();
}
}
catch (error) {
console.error(chalk_1.default.red("Upbit 메시지 처리 오류:"), error);
}
});
this.ws.on("error", (error) => {
console.error(chalk_1.default.red("Upbit WebSocket 오류 발생:"), error);
});
this.ws.on("close", () => {
console.log(chalk_1.default.yellow("Upbit WebSocket 연결이 종료되었습니다. 5초 후 재연결 시도..."));
setTimeout(() => this.connect(appConfig), 5000);
});
}
disconnect() {
this.isActive = false;
if (this.ws) {
this.ws.close();
this.ws = null;
this.realTimeData.clear();
}
}
standardize(data, coinConfig) {
const symbol = data.code.replace("KRW-", "") + "_KRW";
const koreanName = this.marketInfo.get(data.code)?.korean_name || symbol;
let priceColor = chalk_1.default.white;
if (data.change === "RISE")
priceColor = chalk_1.default.redBright;
else if (data.change === "FALL")
priceColor = chalk_1.default.cyanBright;
let profitLossRate;
if (coinConfig && coinConfig.averagePurchasePrice > 0) {
const avgPrice = coinConfig.averagePurchasePrice;
profitLossRate = ((data.trade_price - avgPrice) / avgPrice) * 100;
}
return {
symbol: symbol,
koreanName: koreanName,
icon: this.iconMap.get(data.code) || " ",
currentPrice: data.trade_price,
priceChangeRate: data.signed_change_rate * 100,
priceChangeAmount: data.signed_change_price,
highPrice: data.high_price,
lowPrice: data.low_price,
prevClosePrice: data.prev_closing_price,
averagePurchasePrice: coinConfig?.averagePurchasePrice,
profitLossRate: profitLossRate,
priceColor: priceColor,
volumePower: undefined, // Upbit ticker does not provide volume power
};
}
}
exports.Upbit = Upbit;