UNPKG

bivcore-insight

Version:

A blockchain explorer for Bitcore

156 lines (137 loc) 4.58 kB
import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { DefaultProvider } from '../../providers/default/default'; import * as _ from 'lodash'; export interface ChainNetwork { chain: string; network: string; } export interface NetworkSettings { availableNetworks: ChainNetwork[]; selectedNetwork: ChainNetwork; } const CurrentEnv = process.env.ENV || 'dev'; const EnvApiHosts: { [env: string]: { [chain: string]: string } } = { prod: { default: 'https://api.bivcore.io/api', ETH: 'https://api-eth.bivcore.io/api' }, dev: { default: '/api' } }; const CurrentApiHosts = EnvApiHosts[CurrentEnv]; @Injectable() export class ApiProvider { public defaultNetwork = { chain: this.defaults.getDefault('%CHAIN%'), network: this.defaults.getDefault('%NETWORK%') }; public networkSettings = { availableNetworks: [this.defaultNetwork], selectedNetwork: this.defaultNetwork, chainNetworkLookup: {} }; // TODO: check me public ratesAPI = { btc: 'https://bitpay.com/api/rates', bch: 'https://bitpay.com/api/rates/bch', eth: 'https://bitpay.com/api/rates/eth' }; public bwsUrl = { urlPrefix: 'https://bws.bitpay.com/bws/api/v1/fiatrates/' }; constructor( public httpClient: HttpClient, private defaults: DefaultProvider ) { this.getAvailableNetworks().subscribe(data => { const newNetworks = data .map(x => x.supported) .reduce((agg, arr) => [...agg].concat(arr), []); const chainNetworkLookup = {}; for (const hostConfig of data) { for (const chainNetwork of hostConfig.supported) { const key = `${chainNetwork.chain}:${chainNetwork.network}`; chainNetworkLookup[key] = hostConfig.host; } } for (const { chain, network } of newNetworks) { const found = this.networkSettings.availableNetworks.find( available => available.chain === chain && available.network === network ); if (!found) { this.networkSettings.availableNetworks.push({ chain, network }); } } this.networkSettings = { availableNetworks: this.networkSettings.availableNetworks, selectedNetwork: this.networkSettings.selectedNetwork, chainNetworkLookup }; }); } public getAvailableNetworks(): Observable< Array<{ host: string; supported: ChainNetwork[] }> > { const hosts = CurrentApiHosts; return Observable.fromPromise( Promise.all( Object.keys(hosts).map(async chain => { const host = hosts[chain]; const supported = await this.httpClient .get<ChainNetwork[]>(host + '/status/enabled-chains') .toPromise(); return { host, supported }; }) ) ); } getHostForChain(chain: string) { return CurrentApiHosts[chain] || CurrentApiHosts.default; } public getUrlPrefix(chain, network): string { const defaultChain = chain || this.defaultNetwork.chain; const defaultNetwork = network || this.defaultNetwork.network; const key = `${defaultChain}:${defaultNetwork}`; const lookupHost = this.networkSettings.chainNetworkLookup[key]; const prefix = lookupHost || this.getHostForChain(chain); return prefix; } public getUrl(params?: { chain?: string; network?: string }): string { let { chain, network } = params; chain = chain || this.networkSettings.selectedNetwork.chain; network = network || this.networkSettings.selectedNetwork.network; const prefix: string = this.getUrlPrefix(chain, network); const apiPrefix = `${prefix}/${chain}/${network}`; return apiPrefix; } public getConfig(): ChainNetwork { const config = { chain: this.networkSettings.selectedNetwork.chain, network: this.networkSettings.selectedNetwork.network }; return config; } public changeNetwork(network: ChainNetwork): void { const availableNetworks = this.networkSettings.availableNetworks; // Can't do the following because availableNetworks is loaded /* *const isValid = _.some(availableNetworks, network); *if (!isValid) { * this.logger.error( * 'Invalid URL: missing or invalid COIN or NETWORK param' * ); * return; *} */ this.networkSettings = { availableNetworks, selectedNetwork: network, chainNetworkLookup: this.networkSettings.chainNetworkLookup || {} }; } }