UNPKG

yhtx

Version:

HTX API

148 lines (133 loc) 4.94 kB
const crypto = require("crypto"); const axios = require("axios"); const https = require("https"); //4 agent function getSign(queryString, secret, method, path) { let signString = [ method, path.includes("linear-swap-api") ? "api.hbdm.com" : "api.huobi.pro", path, queryString || undefined, ] .filter(Boolean) .join("\n"); return crypto.createHmac("sha256", secret).update(signString).digest("base64"); } async function call(path, { apiKey, secret, data, method, recvWindow } = {}) { apiKey ||= ""; secret ||= ""; method ||= "GET"; recvWindow ??= 30000; const origin = path.includes("linear-swap-api") ? "https://api.hbdm.com" //UM //for debig:https:api.btcgateway.pro, aws:https://api.hbdm.vn : "https://api.huobi.pro"; //spot //https:api-aws.huobi.pro data ||= {}; let timestamp = Date.now(); let url; let sign; timestamp = new Date(timestamp).toISOString().slice(0, 19); let preBody = { AccessKeyId: apiKey, SignatureMethod: "HmacSHA256", //Ed25519 SignatureVersion: 2, Timestamp: timestamp, }; body = { ...preBody, ...data, }; let pars = []; for (let k in method == "GET" ? body : preBody) pars.push(k + "=" + encodeURIComponent(body[k])); let queryString = pars.sort().join("&"); if (method === "POST") { url = origin + path + "?" + queryString; sign = getSign(queryString, secret, method, path); url += `&Signature=${sign}`; } /*GET*/ else { url = origin + path + "?" + queryString; sign = getSign(queryString, secret, method, path); url += `&Signature=${sign}`; } let headers = { "Content-Type": "application/json" }; let config = { method, url, headers, ...(method == "POST" && { data }), //must be "data" //if GET, don't send }; const agent = new https.Agent({ rejectUnauthorized: false }); async function queryApi({ useAgent } = {}) { if (useAgent) config.httpsAgent = agent; let r = await axios(config) .then((r) => { let dt = r.data; let rs = r.data.data; if (dt?.code == 403 && dt?.msg == "Verification failure [校验失败]") { console.log("api bug: null"); //{code:403,msg:'Verification failure [校验失败]',data:null,ts:1758849372250} } else if (dt?.status == "error") { if (dt?.["err-code"] == "api-signature-not-valid") { console.log("api bug2: null"); //{status: 'error','err-code': 'api-signature-not-valid','err-msg': 'Signature not valid: Verification failure [校验失败]',data:null} } else if (dt?.err_code == 403) { console.log("api bug3: undefined"); //{status:"error",err_code:403,err_msg:"Verification failure [校验失败]",ts:1758854139970}; } else if (dt?.["err-msg"] == "Format Error: account-id.") { console.log("api bug(accId): null"); //{status: 'error','err-code': 'validation-format-error','err-msg': 'Format Error: account-id.',data:null} } else { console.log(dt); rs = dt; //rs={status:'error',} } } else if (dt?.message == "Verification failure [校验失败]") { if (dt?.code == 1003) { console.log("api bug4: undefined"); //{ message: 'Verification failure [校验失败]', code: 1003, success: false } } else if (dt?.code == 513) { console.log("api bug4.1: undefined"); //{code: 513,data: null,message:"Verification failure [校验失败]",success:false,"print-log":true} } } else if (dt?.message == "Verification failure") { if (dt?.code == 12008) { console.log("api bug5: null"); //{ code: 12008, message: "Verification failure", data: null }; } else console.log(`api bug5.1: uncaught`); } else if (!rs /*null*/) { console.log(dt); // console.log(`rs:${rs}`, dt); rs = dt; } //else rs=DATA return rs; //rs=DATA | {status:'error','err=code','err-msg',data:null} | null(if api fail) | undefined(if apiFail) }) .catch(async (e) => { if ( !useAgent && e?.code == "UNABLE_TO_GET_ISSUER_CERT_LOCALLY" && path.includes("linear-swap-api") ) { console.log("catch", e.code); return await queryApi({ useAgent: true }); } else console.log("catch", e.response?.data); }); return r; } let r = await queryApi(); return r; } class api { constructor(apiKey = "", secret = "") { this.apiKey = apiKey; this.secret = secret; } async get(path, pr = {}) { let data = { apiKey: this.apiKey, secret: this.secret, data: pr, }; return call(path, data); } async post(path, pr = {}) { let data = { apiKey: this.apiKey, secret: this.secret, method: "POST", data: pr, }; return call(path, data); } } module.exports = api; module.exports.call = call;