UNPKG

bitcore-wallet-service

Version:
358 lines (319 loc) 10.1 kB
import * as crypto from 'crypto'; import * as _ from 'lodash'; import * as request from 'request'; import config from '../config'; import { ClientError } from '../lib/errors/clienterror'; import { Errors } from '../lib/errors/errordefinitions'; import logger from '../lib/logger'; import { checkRequired } from '../lib/server'; export class ChangellyService { request: any = request; private changellyGetKeysV2(req) { if (!config.changelly) { logger.warn('Changelly missing credentials'); throw new Error('ClientError: Service not configured.'); } else if (!config.changelly.v2) { logger.warn('Changelly v2 missing credentials'); throw new Error('ClientError: Service v2 not configured.'); } const keys = { API: config.changelly.v2.api, SECRET: config.changelly.v2.secret }; return keys; } changellySignRequestsV2(message, secret: string) { if (!message || !secret) throw new Error('Missing parameters to sign Changelly v2 request'); const privateKey = crypto.createPrivateKey({ key: Buffer.from(secret, 'hex'), format: 'der', type: 'pkcs8', }); const publicKey = crypto.createPublicKey(privateKey).export({ type: 'pkcs1', format: 'der' }); const signature = crypto.sign('sha256', Buffer.from(JSON.stringify(message)), privateKey); return { signature, publicKey }; } changellyGetCurrencies(req): Promise<any> { return new Promise((resolve, reject) => { let keys, headers; if (req.body.useV2) { keys = this.changellyGetKeysV2(req); } else { return reject(Errors.UPGRADE_NEEDED.withMessage('Credentials expired, please update the app to continue using Changelly services.')); } if (!checkRequired(req.body, ['id'])) { return reject(new ClientError('changellyGetCurrencies request missing arguments')); } const message = { jsonrpc: '2.0', id: req.body.id, method: req.body.full ? 'getCurrenciesFull' : 'getCurrencies', params: {} }; const URL: string = keys.API; const { signature, publicKey } = this.changellySignRequestsV2(message, keys.SECRET); headers = { 'Content-Type': 'application/json', 'X-Api-Key': crypto.createHash('sha256').update(publicKey).digest('base64'), 'X-Api-Signature': signature.toString('base64'), }; this.request.post( URL, { headers, body: message, json: true }, (err, data) => { if (err) { return reject(err.body ?? err); } else { return resolve(data.body); } } ); }); } changellyGetPairsParams(req): Promise<any> { return new Promise((resolve, reject) => { let keys, headers; if (req.body.useV2) { keys = this.changellyGetKeysV2(req); } else { return reject(Errors.UPGRADE_NEEDED.withMessage('Credentials expired, please update the app to continue using Changelly services.')); } if (!checkRequired(req.body, ['id', 'coinFrom', 'coinTo'])) { return reject(new ClientError('changellyGetPairsParams request missing arguments')); } const message = { id: req.body.id, jsonrpc: '2.0', method: 'getPairsParams', params: [ { from: req.body.coinFrom, to: req.body.coinTo } ] }; const URL: string = keys.API; const { signature, publicKey } = this.changellySignRequestsV2(message, keys.SECRET); headers = { 'Content-Type': 'application/json', 'X-Api-Key': crypto.createHash('sha256').update(publicKey).digest('base64'), 'X-Api-Signature': signature.toString('base64'), }; this.request.post( URL, { headers, body: message, json: true }, (err, data) => { if (err) { return reject(err.body ?? err); } else { return resolve(data.body); } } ); }); } changellyGetFixRateForAmount(req): Promise<any> { return new Promise((resolve, reject) => { let keys, headers; if (req.body.useV2) { keys = this.changellyGetKeysV2(req); } else { return reject(Errors.UPGRADE_NEEDED.withMessage('Credentials expired, please update the app to continue using Changelly services.')); } if (!checkRequired(req.body, ['id', 'coinFrom', 'coinTo', 'amountFrom'])) { return reject(new ClientError('changellyGetFixRateForAmount request missing arguments')); } const message = { id: req.body.id, jsonrpc: '2.0', method: 'getFixRateForAmount', params: [ { from: req.body.coinFrom, to: req.body.coinTo, amountFrom: req.body.amountFrom } ] }; const URL: string = keys.API; const { signature, publicKey } = this.changellySignRequestsV2(message, keys.SECRET); headers = { 'Content-Type': 'application/json', 'X-Api-Key': crypto.createHash('sha256').update(publicKey).digest('base64'), 'X-Api-Signature': signature.toString('base64'), }; this.request.post( URL, { headers, body: message, json: true }, (err, data) => { if (err) { return reject(err.body ?? err); } else { return resolve(data.body); } } ); }); } changellyCreateFixTransaction(req): Promise<any> { return new Promise((resolve, reject) => { let keys, headers; if (req.body.useV2) { keys = this.changellyGetKeysV2(req); } else { return reject(Errors.UPGRADE_NEEDED.withMessage('Credentials expired, please update the app to continue using Changelly services.')); } if ( !checkRequired(req.body, [ 'id', 'coinFrom', 'coinTo', 'amountFrom', 'addressTo', 'fixedRateId', 'refundAddress' ]) ) { return reject(new ClientError('changellyCreateFixTransaction request missing arguments')); } const message = { id: req.body.id, jsonrpc: '2.0', method: 'createFixTransaction', params: { from: req.body.coinFrom, to: req.body.coinTo, address: req.body.addressTo, amountFrom: req.body.amountFrom, rateId: req.body.fixedRateId, refundAddress: req.body.refundAddress } }; const URL: string = keys.API; const { signature, publicKey } = this.changellySignRequestsV2(message, keys.SECRET); headers = { 'Content-Type': 'application/json', 'X-Api-Key': crypto.createHash('sha256').update(publicKey).digest('base64'), 'X-Api-Signature': signature.toString('base64'), }; this.request.post( URL, { headers, body: message, json: true }, (err, data) => { if (err) { return reject(err.body ?? err); } else { return resolve(data.body); } } ); }); } changellyGetTransactions(req): Promise<any> { return new Promise((resolve, reject) => { let keys, headers; if (req.body.useV2) { keys = this.changellyGetKeysV2(req); } else { return reject(Errors.UPGRADE_NEEDED.withMessage('Credentials expired, please update the app to continue using Changelly services.')); } if (!checkRequired(req.body, ['id', 'exchangeTxId'])) { return reject(new ClientError('changellyGetTransactions request missing arguments')); } const message = { id: req.body.id, jsonrpc: '2.0', method: 'getTransactions', params: { id: req.body.exchangeTxId, limit: req.body.limit ?? 1, } }; const URL: string = keys.API; const { signature, publicKey } = this.changellySignRequestsV2(message, keys.SECRET); headers = { 'Content-Type': 'application/json', 'X-Api-Key': crypto.createHash('sha256').update(publicKey).digest('base64'), 'X-Api-Signature': signature.toString('base64'), }; this.request.post( URL, { headers, body: message, json: true }, (err, data) => { if (err) { return reject(err.body ?? err); } else { return resolve(data.body); } } ); }); } changellyGetStatus(req): Promise<any> { return new Promise((resolve, reject) => { let keys, headers; if (req.body.useV2) { keys = this.changellyGetKeysV2(req); } else { return reject(Errors.UPGRADE_NEEDED.withMessage('Credentials expired, please update the app to continue using Changelly services.')); } if (!checkRequired(req.body, ['id', 'exchangeTxId'])) { return reject(new ClientError('changellyGetStatus request missing arguments')); } const message = { jsonrpc: '2.0', id: req.body.id, method: 'getStatus', params: { id: req.body.exchangeTxId } }; const URL: string = keys.API; const { signature, publicKey } = this.changellySignRequestsV2(message, keys.SECRET); headers = { 'Content-Type': 'application/json', 'X-Api-Key': crypto.createHash('sha256').update(publicKey).digest('base64'), 'X-Api-Signature': signature.toString('base64'), }; this.request.post( URL, { headers, body: message, json: true }, (err, data) => { if (err) { return reject(err.body ?? err); } else { return resolve(data.body); } } ); }); } }