| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- import dotenv from 'dotenv';
- import https from 'https';
- import axios from "axios";
- import { HttpsProxyAgent } from "https-proxy-agent";
- import Logs from "./logs.js";
- import { getAccountInfo } from "./getAccount.js";
- dotenv.config();
- const axiosDefaultOptions = {
- baseURL: "",
- url: "",
- method: "GET",
- headers: {},
- params: {},
- data: {},
- timeout: 10000,
- };
- const BaseURL = {
- pinnacle: "https://api.pinnacle888.com",
- ps3838: "https://api.ps3838.com",
- pstery: "http://127.0.0.1:9055",
- }
- const betPostPaths = new Set([
- '/v4/bets/place',
- '/v4/bets/parlay',
- '/v4/bets/teaser',
- '/v4/bets/special',
- ]);
- const cloneJsonData = (data) => {
- if (data === undefined || data === null) {
- return data;
- }
- return JSON.parse(JSON.stringify(data));
- }
- const toAccountCurrencyStake = (amount, accountInfo) => {
- const value = Number(amount);
- if (!Number.isFinite(value)) {
- return amount;
- }
- const currency = accountInfo?.currency?.toUpperCase() || 'USD';
- if (currency === 'USD') {
- return Math.round(value);
- }
- const rate = Number(accountInfo?.currencyInfo?.rate);
- if (!Number.isFinite(rate) || rate <= 0) {
- const error = new Error(`currency rate is not ready: ${currency}`);
- error.cause = 503;
- error.data = { currency };
- throw error;
- }
- return Math.round(value * rate);
- }
- const convertBetStakeToUsd = (data, accountInfo) => {
- if (!data || typeof data !== 'object') {
- return data;
- }
- const converted = cloneJsonData(data);
- const requests = Array.isArray(converted.bets) ? converted.bets : [converted];
- requests.forEach(request => {
- if (!request || typeof request !== 'object') {
- return;
- }
- if (request.stake !== undefined) {
- request.stake = toAccountCurrencyStake(request.stake, accountInfo);
- }
- if (request.riskAmount !== undefined) {
- request.riskAmount = toAccountCurrencyStake(request.riskAmount, accountInfo);
- }
- });
- return converted;
- }
- export const pinnacleRequest = async (options, channel) => {
- const accountInfo = getAccountInfo() ?? {};
- const { username, password, localAddress, platform } = accountInfo;
- const { data, params, url, ...optionsRest } = options;
- if (!url || !channel && (!username || !password)) {
- throw new Error("url、username、password、channel is required");
- }
- const requestData = !channel && optionsRest.method === 'POST' && betPostPaths.has(url)
- ? convertBetStakeToUsd(data, accountInfo)
- : data;
- Logs.outDev('pinnacle request', { url, channel, username, password, localAddress, platform });
- const authHeader = channel ? `Basic ${channel}` : `Basic ${Buffer.from(`${username}:${password}`).toString("base64")}`;
- const axiosConfig = { ...axiosDefaultOptions, ...optionsRest, data: requestData, params, url, baseURL: BaseURL[platform] ?? BaseURL.pinnacle };
- Object.assign(axiosConfig.headers, {
- "Authorization": authHeader,
- "Accept": "application/json",
- });
- const proxy = process.env.NODE_HTTP_PROXY;
- if (proxy) {
- axiosConfig.proxy = false;
- axiosConfig.httpsAgent = new HttpsProxyAgent(proxy);
- // Logs.outDev('pinnacle request using proxy', axiosConfig.httpsAgent);
- }
- else if (localAddress) {
- axiosConfig.httpsAgent = new https.Agent({ localAddress });
- }
- return axios(axiosConfig)
- .then(res => {
- // Logs.out('pinnacle request', url, axiosConfig, res.data);
- return res.data;
- })
- .catch(err => {
- let user_name = '';
- if (channel) {
- user_name = Buffer.from(channel, "base64").toString().split(':')[0];
- }
- else {
- user_name = username;
- }
- const source = { url, params, username: user_name };
- if (err?.response?.data) {
- const data = err.response.data;
- Object.assign(source, { data });
- }
- err.source = source;
- return Promise.reject(err);
- });
- }
- /**
- * Pinnacle API Get请求
- * @param {*} url
- * @param {*} params
- * @returns
- */
- export const pinnacleGet = async (url, params, channel) => {
- return pinnacleRequest({
- url,
- params
- }, channel)
- }
- /**
- * Pinnacle API Post请求
- * @param {*} url
- * @param {*} data
- * @returns
- */
- export const pinnaclePost = async (url, data, channel) => {
- return pinnacleRequest({
- url,
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- data
- }, channel);
- }
- export const getPsteryRelations = async (mk=-1) => {
- const axiosConfig = {
- baseURL: BaseURL.pstery,
- url: '/api/pstery/get_games_relation',
- method: 'GET',
- params: {
- mk,
- },
- proxy: false,
- };
- return axios(axiosConfig).then(res => res.data);
- }
- export const updateBaseEvents = async (data) => {
- const axiosConfig = {
- baseURL: BaseURL.pstery,
- url: '/api/pstery/update_base_events',
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- data: JSON.stringify(data),
- proxy: false,
- };
- axios(axiosConfig).then(res => res.data)
- .then(() => {
- Logs.outDev('update base events success', data);
- })
- .catch(err => {
- Logs.err('failed to update base events:', err.response?.data ?? err.message);
- });
- }
- export const notifyException = async (message) => {
- const axiosConfig = {
- baseURL: BaseURL.pstery,
- url: '/api/pstery/notify_exception',
- method: 'POST',
- data: { message },
- proxy: false,
- };
- axios(axiosConfig).then(res => res.data)
- .then(() => {
- Logs.out('notify exception success');
- })
- .catch(err => {
- Logs.err('failed to notify exception:', err.message);
- });
- }
|