diff --git a/src/index.ts b/src/index.ts index a4330cc..b718da0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,2 +1,4 @@ +export * from './lib'; export { default as CryptoCurrencies } from './types/CryptoCurrencies'; export { default as FiatCurrencies } from './types/FiatCurrencies'; +export { default as getCurrencySymbol } from './utils/getCurrencySymbol'; diff --git a/src/lib/Ticker/Ticker.ts b/src/lib/Ticker/Ticker.ts new file mode 100644 index 0000000..2f8d54b --- /dev/null +++ b/src/lib/Ticker/Ticker.ts @@ -0,0 +1,107 @@ +import CryptoCurrencies from '../../types/CryptoCurrencies'; +import FiatCurrencies from '../../types/FiatCurrencies'; +import getCurrencySymbol from '../../utils/getCurrencySymbol'; + +type TickerConfig = { + base: CryptoCurrencies | FiatCurrencies; + quote: CryptoCurrencies | FiatCurrencies; + frequency?: number; + request: () => Promise; + onUpdate?: (price: number) => void; + onError?: (e: any) => void; +} + +type TickerHistory = Array<{ + price: number; + date: Date; +}>; + +class Ticker { + private readonly _baseName: string; + private readonly _baseSymbol: string; + + private readonly _quoteName: string; + private readonly _quoteSymbol: string; + + private readonly _frequency: number; + private readonly _request: () => Promise; + private readonly _onUpdate?: (price: number) => void; + private readonly _onError?: (e: any) => void; + + private _price: number = 0; + private _history: TickerHistory = []; + + private _interval: NodeJS.Timeout | undefined = undefined; + private _fetching: boolean = false; + + constructor(config: TickerConfig) { + const baseSymbol = getCurrencySymbol(config.base); + if (!baseSymbol) throw new Error('Invalid base currency.'); + + const quoteSymbol = getCurrencySymbol(config.quote); + if (!quoteSymbol) throw new Error('Invalid quote currency.'); + + this._baseName = config.base.toString(); + this._baseSymbol = baseSymbol; + + this._quoteName = config.quote.toString(); + this._quoteSymbol = quoteSymbol; + + this._frequency = config.frequency || 1000; + this._request = config.request; + this._onUpdate = config.onUpdate; + this._onError = config.onError; + } + + public get baseName(): string { return this._baseName; } + public get baseSymbol(): string { return this._baseSymbol; } + + public get quoteName(): string { return this._quoteName; } + public get quoteSymbol(): string { return this._quoteSymbol; } + + public get price(): number { return this._price; } + public get history(): TickerHistory { return this._history; } + + public get active(): boolean { return this._interval !== undefined; } + + public update(): void { + if (!this._fetching) { + this._fetching = true; + this._request() + .then(price => { + this._price = price; + this._history.push({ price, date: new Date() }); + if (this._onUpdate) this._onUpdate(price); + }) + .catch(e => { + if (this._onError) this._onError(e); + }) + .finally(() => { + this._fetching = false; + }); + } + } + + public start(): void { + if (this._interval === undefined) { + this._interval = setInterval(() => { + this.update(); + }, this._frequency); + } + } + + public stop(): void { + if (this._interval !== undefined) { + clearTimeout(this._interval); + this._interval = undefined; + } + } + + public reset(): void { + this.stop(); + this._price = 0; + this._history = []; + } +} + +export default Ticker; diff --git a/src/lib/Ticker/index.ts b/src/lib/Ticker/index.ts new file mode 100644 index 0000000..81f57fa --- /dev/null +++ b/src/lib/Ticker/index.ts @@ -0,0 +1 @@ +export { default } from './Ticker'; diff --git a/src/lib/index.ts b/src/lib/index.ts new file mode 100644 index 0000000..7e1481f --- /dev/null +++ b/src/lib/index.ts @@ -0,0 +1 @@ +export { default as Ticker } from './Ticker'; diff --git a/src/types/CryptoCurrencies.ts b/src/types/CryptoCurrencies.ts index 4175b53..7e3a177 100644 --- a/src/types/CryptoCurrencies.ts +++ b/src/types/CryptoCurrencies.ts @@ -1,22 +1,43 @@ enum CryptoCurrencies { - ADA, - ALGO, - ATOM, - BNB, - BTC, - DASH, - DOT, - DAI, - DNT, - ETH, - GLM, - LINK, - LTC, - REN, - STORJ, - XLM, - XTZ, - XRP + AAVE = 'Aave', + ADA = 'Cardano', + ALGO = 'Algorland', + ATOM = 'Cosmos', + AVAX = 'Avalanche', + BAT = 'Basic Attention Token', + BCH = 'Bitcoin Cash', + BNB = 'Binance Coin', + BTC = 'Bitcoin', + BUSD = 'Binance USD', + COMP = 'Compound', + DASH = 'Dash', + DAI = 'Dai', + DOT = 'Polkadot', + DNT = 'District0x', + EOS = 'EOS', + ETC = 'Ethereum Classic', + ETH = 'Ethereum', + FIL = 'Filecoin', + GLM = 'Golem', + GRT = 'The Graph', + LINK = 'Chainlink', + LTC = 'Litecoin', + MKR = 'Maker', + NEO = 'Neo', + ONT = 'Ontology', + REN = 'Ren', + REP = 'Augur', + STORJ = 'Storj', + USDC = 'USD Coin', + USDT = 'Tether', + VET = 'VeChain', + XLM = 'Stellar', + XMR = 'Monero', + XTZ = 'Tezos', + XRP = 'Ripple', + YFI = 'yearn.finance', + ZEC = 'Zcash', + ZRX = '0x' } export default CryptoCurrencies; diff --git a/src/types/FiatCurrencies.ts b/src/types/FiatCurrencies.ts index 4535923..c4c914f 100644 --- a/src/types/FiatCurrencies.ts +++ b/src/types/FiatCurrencies.ts @@ -1,6 +1,13 @@ enum FiatCurrencies { + AUD = 'Australian Dollar', + CAD = 'Canadian Dollar', + CHF = 'Swiss Franc', + CNY = 'Chinese Yuan', EUR = 'Euro', - USD = 'US Dollar' + GBP = 'Pound Sterling', + JPY = 'Japanese Yen', + MXN = 'Mexican Peso', + USD = 'United States Dollar' } -export default FiatCurrencies; \ No newline at end of file +export default FiatCurrencies; diff --git a/src/utils/getCurrencySymbol.ts b/src/utils/getCurrencySymbol.ts new file mode 100644 index 0000000..59adfea --- /dev/null +++ b/src/utils/getCurrencySymbol.ts @@ -0,0 +1,14 @@ +import CryptoCurrencies from '../types/CryptoCurrencies'; +import FiatCurrencies from '../types/FiatCurrencies'; + +function getCurrencySymbol(currency: CryptoCurrencies | FiatCurrencies): string | undefined { + return Object.keys(CryptoCurrencies).find(key => { + const crypto = CryptoCurrencies[key as keyof typeof CryptoCurrencies]; + if (currency === crypto) return key; + }) || Object.keys(FiatCurrencies).find(key => { + const fiat = FiatCurrencies[key as keyof typeof FiatCurrencies]; + if (currency === fiat) return key; + }); +} + +export default getCurrencySymbol; diff --git a/tsconfig.json b/tsconfig.json index 9b5512c..55741b7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "target": "ESNEXT", - "module": "ESNEXT", + "module": "commonjs", "declaration": true, "declarationMap": true, "sourceMap": true, @@ -10,10 +10,6 @@ "removeComments": false, "strict": true, "moduleResolution": "node", - "baseUrl": "./", - "paths": { - "~types/*": ["./src/types/*"] - }, "esModuleInterop": true, "resolveJsonModule": true, "experimentalDecorators": true, @@ -27,4 +23,4 @@ "exclude": [ "node_modules" ] -} \ No newline at end of file +}