| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- import crypto from "crypto";
- import axios from "axios";
- import dotenv from 'dotenv';
- import path from "path";
- import { fileURLToPath } from "url";
- import { getData } from "../libs/cache.js";
- import Logs from "../libs/logs.js";
- dotenv.config();
- const __filename = fileURLToPath(import.meta.url);
- const __dirname = path.dirname(__filename);
- const IS_DEV = process.env.NODE_ENV == 'development';
- const PARTNER_DATA_FILE = path.join(__dirname, '../data/partner.json');
- /**
- * Partner API environment variables
- */
- const PARTNER_API_BASE = 'https://dev.api.ppai.win/api/p/gate';
- const { PARTNER_APP_ID, PARTNER_APP_KEY } = process.env;
- const PARTNER_DATA = {};
- /**
- * QBoss API environment variables
- */
- const QBOSS_API_BASE = IS_DEV ? 'https://cb.long.bid/api' : 'http://172.27.74.243/api';
- /**
- * axios instance
- */
- const axiosInstance = axios.create({
- proxy: false,
- });
- /**
- *
- */
- /**
- * 加载本地数据
- */
- const loadLocalData = async () => {
- const data = await getData(PARTNER_DATA_FILE);
- Object.assign(PARTNER_DATA, data);
- }
- loadLocalData().catch(error => {
- Logs.out('not load partner data', error.message);
- });
- /**
- * 生成SHA256
- */
- const generateSHA256 = (message) => {
- return crypto.createHash('sha256').update(message).digest('hex');
- }
- /**
- * 生成随机 nonce
- */
- const generateNonce = () => {
- return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
- }
- /**
- * 生成签名
- */
- const generateSignature = (appKey, action, timestamp, nonce) => {
- return generateSHA256(`${appKey}${action}${timestamp}${nonce}`);
- }
- /**
- * 获取时间戳 秒级
- */
- const getTimestamp = () => {
- return Math.floor(Date.now() / 1000);
- }
- /**
- * 时间窗口校验
- */
- const isTimestampValid = (timestamp, window=300) => {
- const now = getTimestamp();
- return Math.abs(now - timestamp) <= window;
- }
- /**
- * 请求Partner数据接口
- */
- export const requestData = async (action, data={}) => {
- const timestamp = getTimestamp();
- const nonce = generateNonce();
- const sign = generateSignature(PARTNER_APP_KEY, action, timestamp, nonce);
- const appid = PARTNER_APP_ID;
- const requestData = { action, appid, nonce, sign, timestamp };
- if (Object.keys(data).length > 0) {
- requestData.params = data;
- }
- return axiosInstance.post(PARTNER_API_BASE, requestData).then(res => res.data);
- }
- /**
- * 更新策略
- * @param {*} solutions
- * @returns
- */
- export const updateSolutions = async (solutions) => {
- if (process.env.NODE_ENV == 'development') {
- return Promise.resolve({ message: 'development mode' });
- }
- return requestData('opps.soccer', solutions);
- }
- /**
- * 获取关联比赛
- * @returns
- */
- export const getSoccerGames = async () => {
- return requestData('game.soccer');
- }
- /**
- * 获取QBoss赔率数据
- * @returns
- */
- export const getObossOdds = async () => {
- return axiosInstance.get(`${QBOSS_API_BASE}/pstery/get_games_relation`, {
- params: { lo: true, lp: true, hb: true, hh: true },
- }).then(res => res.data);
- }
- /**
- * 接收Partner数据
- */
- export const receivePartnerData = async (data) => {
- const { action, appid, nonce, sign, timestamp, params } = data;
- if (!isTimestampValid(timestamp)) {
- return Promise.reject(new Error('timestamp invalid'));
- }
- const partnerData = PARTNER_DATA[appid];
- if (!partnerData) {
- return Promise.reject(new Error('appid invalid'));
- }
- const newSign = generateSignature(partnerData.appkey, action, timestamp, nonce);
- if (newSign !== sign) {
- return Promise.reject(new Error('sign invalid'));
- }
- return Promise.resolve({ action, params });
- }
- export default { updateSolutions, getSoccerGames, getObossOdds, receivePartnerData };
|