185 lines
4.7 KiB
TypeScript
185 lines
4.7 KiB
TypeScript
import axios from 'axios'
|
||
import { hmacsha256, sha1 } from 'utils/security.util'
|
||
import crypto from 'crypto'
|
||
|
||
export function createSimpleSign() {
|
||
let timestamp = Date.now()
|
||
let appid = process.env.ALCHEMY_APPID
|
||
let secret = process.env.ALCHEMY_APP_SECRET
|
||
// let sign = sha1(appid + secret + timestamp)
|
||
let sign = hmacsha256(appid + timestamp, secret)
|
||
return {
|
||
appid,
|
||
timestamp,
|
||
sign,
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check if the pay result sign is valid
|
||
* @param data - the data to be checked
|
||
* @returns true if the sign is valid, false otherwise
|
||
*/
|
||
export function checkPayResultSign(data: any) {
|
||
const { appId, orderNo, crypto, network, address, signature } = data
|
||
const sign = hmacsha256(appId + orderNo + crypto + network + address, process.env.ALCHEMY_APP_SECRET)
|
||
return sign === signature
|
||
}
|
||
|
||
export function checkSimpleSign(data: any) {
|
||
// alchemy 很不严谨, 有时候是 appid, 有时候是 appId
|
||
const { appid, appId, timestamp, sign } = data
|
||
let appIdToCheck = appId || appid
|
||
const expectedSign = sha1(appIdToCheck + process.env.ALCHEMY_APP_SECRET + timestamp)
|
||
return sign === expectedSign
|
||
}
|
||
|
||
/**
|
||
* Create page sign
|
||
* @param plainText - plain text to be encrypted
|
||
* @returns encrypted text
|
||
*/
|
||
export function createPageSign(plainText: string) {
|
||
let secret = process.env.ALCHEMY_APP_SECRET
|
||
try {
|
||
const plainTextData = Buffer.from(plainText, 'utf8')
|
||
const secretKey = Buffer.from(secret, 'utf8')
|
||
const iv = secret.substring(0, 16)
|
||
|
||
const cipher = crypto.createCipheriv('aes-128-cbc', secretKey, iv)
|
||
|
||
let encrypted = cipher.update(plainTextData)
|
||
encrypted = Buffer.concat([encrypted, cipher.final()])
|
||
|
||
return encrypted.toString('base64')
|
||
} catch (e) {
|
||
console.log(`AES encrypting exception, msg is ${e.toString()}`)
|
||
}
|
||
return null
|
||
}
|
||
|
||
/**
|
||
* Refresh token
|
||
* https://alchemycn.readme.io/docs/获取token
|
||
* @param email - user email
|
||
* @returns token
|
||
*/
|
||
export async function refreshToken(email: string) {
|
||
const data = JSON.stringify({ email })
|
||
const { appid, timestamp, sign } = createSimpleSign()
|
||
const host = process.env.ALCHEMY_API_BASE
|
||
const config = {
|
||
method: 'post',
|
||
url: `${host}/merchant/getToken`,
|
||
headers: {
|
||
appId: appid,
|
||
timestamp: timestamp,
|
||
sign: sign,
|
||
'Content-Type': 'application/json',
|
||
},
|
||
data: data,
|
||
}
|
||
let response = await axios(config)
|
||
return response.data
|
||
}
|
||
/**
|
||
* 创建订单
|
||
* https://alchemycn.readme.io/docs/创建订单
|
||
*/
|
||
export async function createOrder(token: string, data: any) {
|
||
const { appid, timestamp, sign } = createSimpleSign()
|
||
const host = process.env.ALCHEMY_API_BASE
|
||
const config = {
|
||
method: 'post',
|
||
url: `${host}/merchant/trade/create`,
|
||
headers: {
|
||
'access-token': token,
|
||
appId: appid,
|
||
timestamp: timestamp,
|
||
sign: sign,
|
||
'Content-Type': 'application/json',
|
||
},
|
||
data: data,
|
||
}
|
||
let response = await axios(config)
|
||
return response.data
|
||
}
|
||
|
||
/**
|
||
* 更新订单状态
|
||
* 当您给用户转移token后,您需要通过此接口通知Alchemy打币的信息
|
||
* https://alchemycn.readme.io/docs/更新订单状态
|
||
* TODO:: test
|
||
*/
|
||
export async function updateOrderStatus(data: any) {
|
||
const { appid, timestamp, sign } = createSimpleSign()
|
||
const url = process.env.ALCHEMY_API_BASE + '/webhooks/treasure'
|
||
const config = {
|
||
method: 'post',
|
||
url,
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
appId: appid,
|
||
sign: sign,
|
||
timestamp,
|
||
},
|
||
data,
|
||
}
|
||
let response = await axios(config)
|
||
return response.data
|
||
}
|
||
/**
|
||
* 查询数字货币币价
|
||
* https://alchemycn.readme.io/docs/查询数字货币币价
|
||
*/
|
||
export async function queryPrice(data: any) {
|
||
const { appid, timestamp, sign } = createSimpleSign()
|
||
let dataOrign = {
|
||
crypto: 'ETH',
|
||
network: 'ETH',
|
||
fiat: 'USD',
|
||
amount: '100',
|
||
payWayCode: '10001',
|
||
side: 'BUY',
|
||
}
|
||
dataOrign = { ...dataOrign, ...data }
|
||
const config = {
|
||
method: 'post',
|
||
url: process.env.ALCHEMY_API_BASE + '/merchant/order/quote',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
appId: appid,
|
||
sign,
|
||
timestamp,
|
||
},
|
||
data: dataOrign,
|
||
}
|
||
let response = await axios(config)
|
||
return response.data
|
||
}
|
||
|
||
/**
|
||
* 查询法币及支付方式
|
||
* https://alchemycn.readme.io/docs/查询法币及支付方式
|
||
* @returns
|
||
*/
|
||
export async function queryFiat() {
|
||
const { appid, timestamp, sign } = createSimpleSign()
|
||
let dataOrign = {
|
||
type: 'BUY',
|
||
}
|
||
const config = {
|
||
method: 'GET',
|
||
url: process.env.ALCHEMY_API_BASE + '/merchant/fiat/list',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
appId: appid,
|
||
sign,
|
||
timestamp,
|
||
},
|
||
data: dataOrign,
|
||
}
|
||
let response = await axios(config)
|
||
return response.data
|
||
}
|