bitcore-wallet-service
Version:
A service for Mutisig HD Bitcoin Wallets
165 lines (141 loc) • 4.92 kB
text/typescript
import {
Constants as ConstantsCWC,
} from 'crypto-wallet-core';
import * as _ from 'lodash';
import * as request from 'request';
import config from '../config';
import { Defaults } from '../lib/common/defaults';
import { ClientError } from '../lib/errors/clienterror';
import logger from '../lib/logger';
import { checkRequired } from '../lib/server';
import { Storage } from '../lib/storage';
export class OneInchService {
request: any = request;
storage: Storage;
constructor(storage) {
this.storage = storage;
}
private oneInchGetCredentials() {
if (!config.oneInch) throw new Error('1Inch missing credentials');
const credentials = {
API: config.oneInch.api,
API_KEY: config.oneInch.apiKey,
referrerAddress: config.oneInch.referrerAddress,
referrerFee: config.oneInch.referrerFee
};
return credentials;
}
oneInchGetReferrerFee(req): Promise<any> {
return new Promise((resolve, reject) => {
const credentials = this.oneInchGetCredentials();
const referrerFee: number = credentials.referrerFee;
resolve({ referrerFee });
});
}
oneInchGetSwap(req): Promise<any> {
return new Promise((resolve, reject) => {
const credentials = this.oneInchGetCredentials();
if (
!checkRequired(req.body, [
'fromTokenAddress',
'toTokenAddress',
'amount',
'fromAddress',
'slippage',
'destReceiver'
])
) {
return reject(new ClientError('oneInchGetSwap request missing arguments'));
}
const headers = {
'Content-Type': 'application/json'
};
let qs: string[] = [];
qs.push('fromTokenAddress=' + req.body.fromTokenAddress);
qs.push('toTokenAddress=' + req.body.toTokenAddress);
qs.push('amount=' + req.body.amount);
qs.push('fromAddress=' + req.body.fromAddress);
qs.push('slippage=' + req.body.slippage);
qs.push('destReceiver=' + req.body.destReceiver);
if (credentials.referrerFee) qs.push('fee=' + credentials.referrerFee);
if (credentials.referrerAddress) qs.push('referrerAddress=' + credentials.referrerAddress);
const chainNetwork: string = `${req.params?.['chain']?.toUpperCase()}_mainnet` || 'eth_mainnet';
const chainId: number = ConstantsCWC.EVM_CHAIN_NETWORK_TO_CHAIN_ID[chainNetwork];
const URL: string = `${credentials.API}/v5.2/${chainId}/swap/?${qs.join('&')}`;
this.request.get(
URL,
{
headers,
json: true
},
(err, data) => {
if (err) {
return reject(err.body ?? err);
} else {
return resolve(data.body);
}
}
);
});
}
oneInchGetTokens(req): Promise<any> {
return new Promise((resolve, reject) => {
const credentials = this.oneInchGetCredentials();
const chain = req.params?.['chain'] || 'eth';
const cacheKey = `oneInchTokens:${chain}`;
this.storage.checkAndUseGlobalCache(cacheKey, Defaults.ONE_INCH_CACHE_DURATION, (err, values, oldvalues) => {
if (err) logger.warn('Could not get stored tokens list', err);
if (values) return resolve(values);
const headers = {
'Content-Type': 'application/json',
Accept: 'application/json',
Authorization: 'Bearer ' + credentials.API_KEY,
};
const chainIdMap = {
eth: 1,
matic: 137,
pol: 137,
arb: 42161,
base: 8453,
op: 10,
};
const chainId = chainIdMap[chain];
const URL: string = `${credentials.API}/v5.2/${chainId}/tokens`;
this.request.get(
URL,
{
headers,
json: true
},
(err, data) => {
if (err) {
logger.warn('An error occured while retrieving the token list', err);
if (oldvalues) {
logger.warn('Using old cached values');
return resolve(oldvalues);
}
return reject(err.body ?? err);
} else if (data?.statusCode === 429 && oldvalues) {
// oneinch rate limit
return resolve(oldvalues);
} else {
if (!data?.body?.tokens) {
if (oldvalues) {
logger.warn('No token list available... using old cached values');
return resolve(oldvalues);
}
return reject(new Error('Could not get tokens list'));
}
this.storage.storeGlobalCache(cacheKey, data.body.tokens, err => {
if (err) {
logger.warn('Could not store tokens list');
}
return resolve(data.body.tokens);
});
}
}
);
});
});
}
}