From 7ebce1816812d0912fff42b1453f48f9af2e8ded Mon Sep 17 00:00:00 2001 From: ZeroWave022 <36341766+ZeroWave022@users.noreply.github.com> Date: Sat, 22 Apr 2023 21:22:49 +0200 Subject: [PATCH 1/5] refactor: Merge currencies to one module --- src/index.ts | 3 +- src/structures/CryptoCurrency.ts | 46 ----------------- src/structures/Currency.ts | 86 ++++++++++++++++++++++++++++++++ src/structures/FiatCurrency.ts | 40 --------------- 4 files changed, 87 insertions(+), 88 deletions(-) delete mode 100644 src/structures/CryptoCurrency.ts create mode 100644 src/structures/Currency.ts delete mode 100644 src/structures/FiatCurrency.ts diff --git a/src/index.ts b/src/index.ts index f6762cc..e0ef1a1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,8 +2,7 @@ import { EventEmitter } from 'node:events'; import RequestHandler from './structures/RequestHandler'; import Transaction from './structures/Transaction'; import CurrencyCache from './structures/CurrencyCache'; -import CryptoCurrency from './structures/CryptoCurrency'; -import FiatCurrency from './structures/FiatCurrency'; +import { CryptoCurrency, FiatCurrency } from './structures/Currency'; import ExchangeRate from './structures/ExchangeRate'; import Wallet from './structures/Wallet'; import { diff --git a/src/structures/CryptoCurrency.ts b/src/structures/CryptoCurrency.ts deleted file mode 100644 index 750bb77..0000000 --- a/src/structures/CryptoCurrency.ts +++ /dev/null @@ -1,46 +0,0 @@ -import BigNumber from 'bignumber.js'; -import type { APICryptoCurrency } from '@tipccjs/tipcc-api-types'; -import CryptoCurrencyFormat from './CurrencyFormat'; - -/** - * A class for storing an API cryptocurrency. - */ -export default class CryptoCurrency { - public code: string; - - public name: string; - - public icon: string; - - public explorer: string; - - public format: CryptoCurrencyFormat; - - /** - * Create a CryptoCurrency. - * @param payload The currency from the API - */ - constructor(payload: APICryptoCurrency) { - this.code = payload.code; - this.name = payload.name; - this.icon = payload.icon; - this.explorer = payload.explorer; - this.format = new CryptoCurrencyFormat(payload.format); - } - - /** - * Convert a raw value to a BigNumber in human readable format. - * @param value The raw value - */ - public convertFromRaw(value: BigNumber): BigNumber { - return BigNumber(value).shiftedBy(this.format.scale * -1); - } - - /** - * Convert a BigNumber value in human readable format to a raw API BigNumber. - * @param value The amount - */ - public convertToRaw(value: BigNumber): BigNumber { - return value.shiftedBy(this.format.scale); - } -} diff --git a/src/structures/Currency.ts b/src/structures/Currency.ts new file mode 100644 index 0000000..01a2403 --- /dev/null +++ b/src/structures/Currency.ts @@ -0,0 +1,86 @@ +import BigNumber from 'bignumber.js'; +import type { + APICryptoCurrency, + APIFiatCurrency, +} from '@tipccjs/tipcc-api-types'; +import CurrencyFormat from './CurrencyFormat'; + +/** + * A class for storing an API cryptocurrency. + */ +export class CryptoCurrency { + public code: string; + + public name: string; + + public icon: string; + + public explorer: string; + + public format: CurrencyFormat; + + /** + * Create a CryptoCurrency. + * @param payload The currency from the API + */ + constructor(payload: APICryptoCurrency) { + this.code = payload.code; + this.name = payload.name; + this.icon = payload.icon; + this.explorer = payload.explorer; + this.format = new CurrencyFormat(payload.format); + } + + /** + * Convert a raw value to a BigNumber in human readable format. + * @param value The raw value + */ + public convertFromRaw(value: BigNumber): BigNumber { + return BigNumber(value).shiftedBy(this.format.scale * -1); + } + + /** + * Convert a BigNumber value in human readable format to a raw API BigNumber. + * @param value The amount + */ + public convertToRaw(value: BigNumber): BigNumber { + return value.shiftedBy(this.format.scale); + } +} + +/** + * A class for storing an API fiat currency. + */ +export class FiatCurrency { + public code: string; + + public name: string; + + public format: CurrencyFormat; + + /** + * Create a FiatCurrency. + * @param payload The currency from the API + */ + constructor(payload: APIFiatCurrency) { + this.code = payload.code; + this.name = payload.name; + this.format = new CurrencyFormat(payload.format); + } + + /** + * Convert a raw value to a BigNumber in human readable format. + * @param value The raw value + */ + public convertFromRaw(value: BigNumber): BigNumber { + return BigNumber(value).shiftedBy(this.format.scale * -1); + } + + /** + * Convert a BigNumber value in human readable format to a raw API BigNumber. + * @param value The amount + */ + public convertToRaw(value: BigNumber): BigNumber { + return value.shiftedBy(this.format.scale); + } +} diff --git a/src/structures/FiatCurrency.ts b/src/structures/FiatCurrency.ts deleted file mode 100644 index 56cafcf..0000000 --- a/src/structures/FiatCurrency.ts +++ /dev/null @@ -1,40 +0,0 @@ -import BigNumber from 'bignumber.js'; -import type { APIFiatCurrency } from '@tipccjs/tipcc-api-types'; -import CurrencyFormat from './CurrencyFormat'; - -/** - * A class for storing an API fiat currency. - */ -export default class FiatCurrency { - public code: string; - - public name: string; - - public format: CurrencyFormat; - - /** - * Create a FiatCurrency. - * @param payload The currency from the API - */ - constructor(payload: APIFiatCurrency) { - this.code = payload.code; - this.name = payload.name; - this.format = new CurrencyFormat(payload.format); - } - - /** - * Convert a raw value to a BigNumber in human readable format. - * @param value The raw value - */ - public convertFromRaw(value: BigNumber): BigNumber { - return BigNumber(value).shiftedBy(this.format.scale * -1); - } - - /** - * Convert a BigNumber value in human readable format to a raw API BigNumber. - * @param value The amount - */ - public convertToRaw(value: BigNumber): BigNumber { - return value.shiftedBy(this.format.scale); - } -} From 91faddade3017611fbf79a16e206639167fccc61 Mon Sep 17 00:00:00 2001 From: ZeroWave022 <36341766+ZeroWave022@users.noreply.github.com> Date: Sat, 22 Apr 2023 21:24:41 +0200 Subject: [PATCH 2/5] refactor: Merge currency formatting to one module --- src/structures/Currency.ts | 2 +- src/structures/CurrencyFormat.ts | 25 ------------------- ...cyFormatUnits.ts => CurrencyFormatting.ts} | 24 +++++++++++++++++- 3 files changed, 24 insertions(+), 27 deletions(-) delete mode 100644 src/structures/CurrencyFormat.ts rename src/structures/{CurrencyFormatUnits.ts => CurrencyFormatting.ts} (66%) diff --git a/src/structures/Currency.ts b/src/structures/Currency.ts index 01a2403..2c17e56 100644 --- a/src/structures/Currency.ts +++ b/src/structures/Currency.ts @@ -3,7 +3,7 @@ import type { APICryptoCurrency, APIFiatCurrency, } from '@tipccjs/tipcc-api-types'; -import CurrencyFormat from './CurrencyFormat'; +import { CurrencyFormat } from './CurrencyFormatting'; /** * A class for storing an API cryptocurrency. diff --git a/src/structures/CurrencyFormat.ts b/src/structures/CurrencyFormat.ts deleted file mode 100644 index 24b2d98..0000000 --- a/src/structures/CurrencyFormat.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { - APICryptoCurrency, - APIFiatCurrency, -} from '@tipccjs/tipcc-api-types'; -import CryptoCurrencyUnit from './CurrencyFormatUnits'; - -/** - * A class for storing an API cryptocurrency format. - */ -export default class CurrencyFormat { - public scale: number; - - public units: CryptoCurrencyUnit[]; - - /** - * Create a CryptoCurrencyFormat. - * @param payload The format from the API - */ - constructor( - payload: APIFiatCurrency['format'] | APICryptoCurrency['format'], - ) { - this.scale = payload.scale; - this.units = payload.units.map((unit) => new CryptoCurrencyUnit(unit)); - } -} diff --git a/src/structures/CurrencyFormatUnits.ts b/src/structures/CurrencyFormatting.ts similarity index 66% rename from src/structures/CurrencyFormatUnits.ts rename to src/structures/CurrencyFormatting.ts index c23830a..7771017 100644 --- a/src/structures/CurrencyFormatUnits.ts +++ b/src/structures/CurrencyFormatting.ts @@ -1,4 +1,6 @@ import type { + APICryptoCurrency, + APIFiatCurrency, APICryptoCurrencyUnit, APIFiatCurrencyUnit, } from '@tipccjs/tipcc-api-types'; @@ -6,7 +8,7 @@ import type { /** * A class for storing an API cryptocurrency unit. */ -export default class CurrencyUnit { +export class CurrencyUnit { public singular: string; public plural: string | null; @@ -41,3 +43,23 @@ export default class CurrencyUnit { this.min = payload.min ?? null; } } + +/** + * A class for storing an API cryptocurrency format. + */ +export class CurrencyFormat { + public scale: number; + + public units: CurrencyUnit[]; + + /** + * Create a CryptoCurrencyFormat. + * @param payload The format from the API + */ + constructor( + payload: APIFiatCurrency['format'] | APICryptoCurrency['format'], + ) { + this.scale = payload.scale; + this.units = payload.units.map((unit) => new CurrencyUnit(unit)); + } +} From 83930fa79bf4078eb89f2c988e414baf0da3fa37 Mon Sep 17 00:00:00 2001 From: ZeroWave022 <36341766+ZeroWave022@users.noreply.github.com> Date: Sat, 22 Apr 2023 21:26:06 +0200 Subject: [PATCH 3/5] refactor: Reorder imports --- src/structures/Currency.ts | 2 +- src/structures/ExchangeRate.ts | 2 +- src/structures/Transaction.ts | 2 +- src/structures/Wallet.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/structures/Currency.ts b/src/structures/Currency.ts index 2c17e56..cff4124 100644 --- a/src/structures/Currency.ts +++ b/src/structures/Currency.ts @@ -1,9 +1,9 @@ import BigNumber from 'bignumber.js'; +import { CurrencyFormat } from './CurrencyFormatting'; import type { APICryptoCurrency, APIFiatCurrency, } from '@tipccjs/tipcc-api-types'; -import { CurrencyFormat } from './CurrencyFormatting'; /** * A class for storing an API cryptocurrency. diff --git a/src/structures/ExchangeRate.ts b/src/structures/ExchangeRate.ts index 6c8f504..655cd91 100644 --- a/src/structures/ExchangeRate.ts +++ b/src/structures/ExchangeRate.ts @@ -1,5 +1,5 @@ -import type { APIExchangeRate } from '@tipccjs/tipcc-api-types'; import Amount from './Amount'; +import type { APIExchangeRate } from '@tipccjs/tipcc-api-types'; /** * A class for storing an API exchange rate for a cryptocurrency. diff --git a/src/structures/Transaction.ts b/src/structures/Transaction.ts index 52817e9..82ee4e3 100644 --- a/src/structures/Transaction.ts +++ b/src/structures/Transaction.ts @@ -1,6 +1,6 @@ -import type { APITransaction } from '@tipccjs/tipcc-api-types'; import Amount from './Amount'; import User from './User'; +import type { APITransaction } from '@tipccjs/tipcc-api-types'; /** * A class for storing an API transaction. diff --git a/src/structures/Wallet.ts b/src/structures/Wallet.ts index 6c0ecfb..e115c9f 100644 --- a/src/structures/Wallet.ts +++ b/src/structures/Wallet.ts @@ -1,5 +1,5 @@ -import type { APIWallet } from '@tipccjs/tipcc-api-types'; import Amount from './Amount'; +import type { APIWallet } from '@tipccjs/tipcc-api-types'; /** * A class for storing an API wallet. From 378b7d0e9aac80412c5cbff5b0972bb497e631a1 Mon Sep 17 00:00:00 2001 From: ZeroWave022 <36341766+ZeroWave022@users.noreply.github.com> Date: Sat, 22 Apr 2023 21:37:29 +0200 Subject: [PATCH 4/5] refactor: Move TipccClient to own module --- src/index.ts | 284 ++-------------------------------- src/structures/TipccClient.ts | 274 ++++++++++++++++++++++++++++++++ 2 files changed, 284 insertions(+), 274 deletions(-) create mode 100644 src/structures/TipccClient.ts diff --git a/src/index.ts b/src/index.ts index e0ef1a1..400348d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,274 +1,10 @@ -import { EventEmitter } from 'node:events'; -import RequestHandler from './structures/RequestHandler'; -import Transaction from './structures/Transaction'; -import CurrencyCache from './structures/CurrencyCache'; -import { CryptoCurrency, FiatCurrency } from './structures/Currency'; -import ExchangeRate from './structures/ExchangeRate'; -import Wallet from './structures/Wallet'; -import { - RESTGetAPICurrenciesCryptoCurrenciesResult, - RESTGetAPICurrenciesFiatsResult, - RESTGetAPIAccountTransactionResult, - RESTGetAPIAccountTransactionsResult, - RESTGetAPIAccountWalletResult, - RESTGetAPIAccountWalletsResult, - RESTGetAPICurrenciesRatesResult, - RESTPostAPITipBody, - RESTPostAPITipResult, - Routes, -} from '@tipccjs/tipcc-api-types'; - -interface Events { - tip: Transaction; - ready: void; -} - -/** - * A tip.cc client to interact with the API. - */ -class TipccClient extends EventEmitter { - public token: string; - - public REST: RequestHandler; - - public cryptos = new CurrencyCache(this._refreshCryptos); - - public fiats = new CurrencyCache(this._refreshFiats); - - public isReady = false; - - public pollingInterval = 10000; - - public maxRetries = 5; - - private polling = new Set(); - - private pollingTimeout: NodeJS.Timeout | null = null; - - private pollingRetries = 0; - - private lastPoll = new Date(); - - /** - * Create a tip.cc client. - * @param token The tip.cc API token to use - * @param options Optional options - */ - constructor( - token: string, - options: { - baseUrl?: string; - pollingInterval?: number; - maxRetries?: number; - } = {}, - ) { - super(); - - if (!/(^[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*$)/.test(token)) - throw new Error('Invalid token provided'); - - this.token = token; - this.REST = new RequestHandler(token, { - apiBaseUrl: options.baseUrl, - }); - - if (options.pollingInterval) this.pollingInterval = options.pollingInterval; - if (options.maxRetries) this.maxRetries = options.maxRetries; - - Promise.all([this.cryptos.refresh(), this.fiats.refresh()]).then(() => { - this.emit('ready'); - this.isReady = true; - }); - } - - /** - * Poll the tip.cc API for new data. - */ - private async _poll(): Promise { - const now = new Date(); - let transactions; - - // Retry until a successful reponse is received or max retries are reached - do { - try { - transactions = ( - (await this.REST.request('GET', '/account/transactions', { - types: [...this.polling], - since: this.lastPoll.toISOString(), - until: now.toISOString(), - })) as RESTGetAPIAccountTransactionsResult - ).transactions; - - break; - } catch { - this.pollingRetries += 1; - - if (this.pollingRetries >= this.maxRetries) - throw new Error( - `Failed ${this.pollingRetries} consecutive API polls. Is the API responding?`, - ); - } - } while (!transactions); - - // Reset pollingRetries, as it should only increment if multiple consecutive requests don't succeed - if (this.pollingRetries > 0) this.pollingRetries = 0; - - for (const transaction of transactions) { - if (!this.cryptos.get(transaction.amount.currency)) - await this.cryptos.refresh(); - this.emit(transaction.type, new Transaction(transaction)); - } - - this.lastPoll = now; - if (this.polling.size > 0) - this.pollingTimeout = setTimeout( - () => this._poll(), - this.pollingInterval, - ); - } - - private _stopPolling(): void { - if (this.pollingTimeout) { - clearTimeout(this.pollingTimeout); - this.pollingTimeout = null; - } - } - - private async _refreshCryptos(): Promise { - const { cryptocurrencies } = (await this.REST.request( - 'GET', - Routes.currenciesCryptocurrencies(), - )) as RESTGetAPICurrenciesCryptoCurrenciesResult; - - const processed = cryptocurrencies.map((c) => new CryptoCurrency(c)); - - return processed; - } - - private async _refreshFiats(): Promise { - const { fiats } = (await this.REST.request( - 'GET', - Routes.currenciesFiats(), - )) as RESTGetAPICurrenciesFiatsResult; - - const processed = fiats.map((c) => new FiatCurrency(c)); - - return processed; - } - - public on(s: K, f: (arg: Events[K]) => void): this { - super.on(s, f); - this.polling.add(s); - if (this.polling.size === 1 && !this.pollingTimeout) this._poll(); - return this; - } - - public off(s: K, f: (arg: Events[K]) => void): this { - super.off(s, f); - this.polling.delete(s); - if (this.polling.size === 0 && this.pollingTimeout) this._stopPolling(); - return this; - } - - /** - * Get a list of transactions based on options. - * @param options Which options to use when requesting transactions - */ - public async getTransactions( - options: { - types?: string[]; - since?: Date; - until?: Date; - limit?: number; - offset?: number; - } = {}, - ): Promise { - const { transactions } = (await this.REST.request( - 'GET', - Routes.accountWalletTransactions(), - options, - )) as RESTGetAPIAccountTransactionsResult; - return transactions.map((t) => new Transaction(t)); - } - - /** - * Get a list of exchange rates. - */ - public async getExchangeRates(): Promise { - const { rates } = (await this.REST.request( - 'GET', - Routes.currenciesRates(), - )) as RESTGetAPICurrenciesRatesResult; - return rates.map((r) => new ExchangeRate(r)); - } - - /** - * Get a single transaction. - * @param id The transaction id - */ - public async getTransaction(id: string): Promise { - const { transaction } = (await this.REST.request( - 'GET', - Routes.accountWalletTransaction(id), - )) as RESTGetAPIAccountTransactionResult; - if (!transaction) return null; - return new Transaction(transaction); - } - - /** - * Post a new tip. - * @param payload The post tip payload - */ - public async postTip( - payload: RESTPostAPITipBody, - ): Promise { - return (await this.REST.request( - 'POST', - '/tips', - payload, - )) as RESTPostAPITipResult; - } - - /** - * Get a single wallet. - * @param currency The wallet currency - * @param fallback Whether to create an empty wallet if there's no API response - */ - public async getWallet( - currency: string, - fallback = true, - ): Promise { - const result = (await this.REST.request( - 'GET', - Routes.accountWallet(currency), - )) as RESTGetAPIAccountWalletResult | null; - if (!result && !fallback) return null; - return new Wallet( - result ?? { - code: currency, - name: currency, - usd_value: { - value: '0', - currency: 'USD', - }, - balance: { - value: '0', - currency, - }, - }, - ); - } - - /** - * Get all wallets. - */ - public async getWallets(): Promise { - const { wallets } = (await this.REST.request( - 'GET', - Routes.accountWallets(), - )) as RESTGetAPIAccountWalletsResult; - return wallets.map((w) => new Wallet(w)); - } -} - -export default TipccClient; +export * from './structures/Amount'; +export * from './structures/Currency'; +export * from './structures/CurrencyCache'; +export * from './structures/CurrencyFormatting'; +export * from './structures/ExchangeRate'; +export * from './structures/TipccClient'; +export * from './structures/Transaction'; +export * from './structures/User'; +export * from './structures/Wallet'; +export * from './utils/Bucket'; diff --git a/src/structures/TipccClient.ts b/src/structures/TipccClient.ts new file mode 100644 index 0000000..f165cb8 --- /dev/null +++ b/src/structures/TipccClient.ts @@ -0,0 +1,274 @@ +import { EventEmitter } from 'node:events'; +import RequestHandler from './RequestHandler'; +import Transaction from './Transaction'; +import CurrencyCache from './CurrencyCache'; +import { CryptoCurrency, FiatCurrency } from './Currency'; +import ExchangeRate from './ExchangeRate'; +import Wallet from './Wallet'; +import { + RESTGetAPICurrenciesCryptoCurrenciesResult, + RESTGetAPICurrenciesFiatsResult, + RESTGetAPIAccountTransactionResult, + RESTGetAPIAccountTransactionsResult, + RESTGetAPIAccountWalletResult, + RESTGetAPIAccountWalletsResult, + RESTGetAPICurrenciesRatesResult, + RESTPostAPITipBody, + RESTPostAPITipResult, + Routes, +} from '@tipccjs/tipcc-api-types'; + +interface Events { + tip: Transaction; + ready: void; +} + +/** + * A tip.cc client to interact with the API. + */ +class TipccClient extends EventEmitter { + public token: string; + + public REST: RequestHandler; + + public cryptos = new CurrencyCache(this._refreshCryptos); + + public fiats = new CurrencyCache(this._refreshFiats); + + public isReady = false; + + public pollingInterval = 10000; + + public maxRetries = 5; + + private polling = new Set(); + + private pollingTimeout: NodeJS.Timeout | null = null; + + private pollingRetries = 0; + + private lastPoll = new Date(); + + /** + * Create a tip.cc client. + * @param token The tip.cc API token to use + * @param options Optional options + */ + constructor( + token: string, + options: { + baseUrl?: string; + pollingInterval?: number; + maxRetries?: number; + } = {}, + ) { + super(); + + if (!/(^[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*$)/.test(token)) + throw new Error('Invalid token provided'); + + this.token = token; + this.REST = new RequestHandler(token, { + apiBaseUrl: options.baseUrl, + }); + + if (options.pollingInterval) this.pollingInterval = options.pollingInterval; + if (options.maxRetries) this.maxRetries = options.maxRetries; + + Promise.all([this.cryptos.refresh(), this.fiats.refresh()]).then(() => { + this.emit('ready'); + this.isReady = true; + }); + } + + /** + * Poll the tip.cc API for new data. + */ + private async _poll(): Promise { + const now = new Date(); + let transactions; + + // Retry until a successful reponse is received or max retries are reached + do { + try { + transactions = ( + (await this.REST.request('GET', '/account/transactions', { + types: [...this.polling], + since: this.lastPoll.toISOString(), + until: now.toISOString(), + })) as RESTGetAPIAccountTransactionsResult + ).transactions; + + break; + } catch { + this.pollingRetries += 1; + + if (this.pollingRetries >= this.maxRetries) + throw new Error( + `Failed ${this.pollingRetries} consecutive API polls. Is the API responding?`, + ); + } + } while (!transactions); + + // Reset pollingRetries, as it should only increment if multiple consecutive requests don't succeed + if (this.pollingRetries > 0) this.pollingRetries = 0; + + for (const transaction of transactions) { + if (!this.cryptos.get(transaction.amount.currency)) + await this.cryptos.refresh(); + this.emit(transaction.type, new Transaction(transaction)); + } + + this.lastPoll = now; + if (this.polling.size > 0) + this.pollingTimeout = setTimeout( + () => this._poll(), + this.pollingInterval, + ); + } + + private _stopPolling(): void { + if (this.pollingTimeout) { + clearTimeout(this.pollingTimeout); + this.pollingTimeout = null; + } + } + + private async _refreshCryptos(): Promise { + const { cryptocurrencies } = (await this.REST.request( + 'GET', + Routes.currenciesCryptocurrencies(), + )) as RESTGetAPICurrenciesCryptoCurrenciesResult; + + const processed = cryptocurrencies.map((c) => new CryptoCurrency(c)); + + return processed; + } + + private async _refreshFiats(): Promise { + const { fiats } = (await this.REST.request( + 'GET', + Routes.currenciesFiats(), + )) as RESTGetAPICurrenciesFiatsResult; + + const processed = fiats.map((c) => new FiatCurrency(c)); + + return processed; + } + + public on(s: K, f: (arg: Events[K]) => void): this { + super.on(s, f); + this.polling.add(s); + if (this.polling.size === 1 && !this.pollingTimeout) this._poll(); + return this; + } + + public off(s: K, f: (arg: Events[K]) => void): this { + super.off(s, f); + this.polling.delete(s); + if (this.polling.size === 0 && this.pollingTimeout) this._stopPolling(); + return this; + } + + /** + * Get a list of transactions based on options. + * @param options Which options to use when requesting transactions + */ + public async getTransactions( + options: { + types?: string[]; + since?: Date; + until?: Date; + limit?: number; + offset?: number; + } = {}, + ): Promise { + const { transactions } = (await this.REST.request( + 'GET', + Routes.accountWalletTransactions(), + options, + )) as RESTGetAPIAccountTransactionsResult; + return transactions.map((t) => new Transaction(t)); + } + + /** + * Get a list of exchange rates. + */ + public async getExchangeRates(): Promise { + const { rates } = (await this.REST.request( + 'GET', + Routes.currenciesRates(), + )) as RESTGetAPICurrenciesRatesResult; + return rates.map((r) => new ExchangeRate(r)); + } + + /** + * Get a single transaction. + * @param id The transaction id + */ + public async getTransaction(id: string): Promise { + const { transaction } = (await this.REST.request( + 'GET', + Routes.accountWalletTransaction(id), + )) as RESTGetAPIAccountTransactionResult; + if (!transaction) return null; + return new Transaction(transaction); + } + + /** + * Post a new tip. + * @param payload The post tip payload + */ + public async postTip( + payload: RESTPostAPITipBody, + ): Promise { + return (await this.REST.request( + 'POST', + '/tips', + payload, + )) as RESTPostAPITipResult; + } + + /** + * Get a single wallet. + * @param currency The wallet currency + * @param fallback Whether to create an empty wallet if there's no API response + */ + public async getWallet( + currency: string, + fallback = true, + ): Promise { + const result = (await this.REST.request( + 'GET', + Routes.accountWallet(currency), + )) as RESTGetAPIAccountWalletResult | null; + if (!result && !fallback) return null; + return new Wallet( + result ?? { + code: currency, + name: currency, + usd_value: { + value: '0', + currency: 'USD', + }, + balance: { + value: '0', + currency, + }, + }, + ); + } + + /** + * Get all wallets. + */ + public async getWallets(): Promise { + const { wallets } = (await this.REST.request( + 'GET', + Routes.accountWallets(), + )) as RESTGetAPIAccountWalletsResult; + return wallets.map((w) => new Wallet(w)); + } +} + +export default TipccClient; From cb940970ba4d20c90e1bf797410e32b1f7e31771 Mon Sep 17 00:00:00 2001 From: ZeroWave022 <36341766+ZeroWave022@users.noreply.github.com> Date: Sat, 22 Apr 2023 21:47:44 +0200 Subject: [PATCH 5/5] refactor: Make exports non-default --- src/structures/Amount.ts | 2 +- src/structures/CurrencyCache.ts | 2 +- src/structures/ExchangeRate.ts | 4 ++-- src/structures/RequestHandler.ts | 4 ++-- src/structures/TipccClient.ts | 14 ++++++-------- src/structures/Transaction.ts | 6 +++--- src/structures/User.ts | 2 +- src/structures/Wallet.ts | 4 ++-- src/utils/Bucket.ts | 2 +- 9 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/structures/Amount.ts b/src/structures/Amount.ts index be382b5..8911cf2 100644 --- a/src/structures/Amount.ts +++ b/src/structures/Amount.ts @@ -4,7 +4,7 @@ import type { APICoin, APIMonetary } from '@tipccjs/tipcc-api-types'; /** * A class for storing an API amount. This can be used for either fiats or cryptocurrencies. */ -export default class Amount { +export class Amount { public valueRaw: BigNumber; public currency: string; diff --git a/src/structures/CurrencyCache.ts b/src/structures/CurrencyCache.ts index dae1cc3..97e74fa 100644 --- a/src/structures/CurrencyCache.ts +++ b/src/structures/CurrencyCache.ts @@ -1,4 +1,4 @@ -export default class CurrencyCache extends Array { +export class CurrencyCache extends Array { private refreshFunction: () => T[] | Promise; constructor(refreshFunction: () => T[] | Promise) { diff --git a/src/structures/ExchangeRate.ts b/src/structures/ExchangeRate.ts index 655cd91..269b49a 100644 --- a/src/structures/ExchangeRate.ts +++ b/src/structures/ExchangeRate.ts @@ -1,10 +1,10 @@ -import Amount from './Amount'; +import { Amount } from './Amount'; import type { APIExchangeRate } from '@tipccjs/tipcc-api-types'; /** * A class for storing an API exchange rate for a cryptocurrency. */ -export default class ExchangeRate { +export class ExchangeRate { public code: string; public name: string; diff --git a/src/structures/RequestHandler.ts b/src/structures/RequestHandler.ts index 98ce5e1..890787e 100644 --- a/src/structures/RequestHandler.ts +++ b/src/structures/RequestHandler.ts @@ -1,10 +1,10 @@ import axios, { AxiosRequestConfig, RawAxiosResponseHeaders } from 'axios'; -import Bucket from '../utils/Bucket'; +import { Bucket } from '../utils/Bucket'; /** * A handler used for HTTP requests. */ -export default class RequestHandler { +export class RequestHandler { private _apiBaseUrl: string; private _apiKey: string; diff --git a/src/structures/TipccClient.ts b/src/structures/TipccClient.ts index f165cb8..ea19a81 100644 --- a/src/structures/TipccClient.ts +++ b/src/structures/TipccClient.ts @@ -1,10 +1,10 @@ import { EventEmitter } from 'node:events'; -import RequestHandler from './RequestHandler'; -import Transaction from './Transaction'; -import CurrencyCache from './CurrencyCache'; +import { RequestHandler } from './RequestHandler'; +import { Transaction } from './Transaction'; +import { CurrencyCache } from './CurrencyCache'; import { CryptoCurrency, FiatCurrency } from './Currency'; -import ExchangeRate from './ExchangeRate'; -import Wallet from './Wallet'; +import { ExchangeRate } from './ExchangeRate'; +import { Wallet } from './Wallet'; import { RESTGetAPICurrenciesCryptoCurrenciesResult, RESTGetAPICurrenciesFiatsResult, @@ -26,7 +26,7 @@ interface Events { /** * A tip.cc client to interact with the API. */ -class TipccClient extends EventEmitter { +export class TipccClient extends EventEmitter { public token: string; public REST: RequestHandler; @@ -270,5 +270,3 @@ class TipccClient extends EventEmitter { return wallets.map((w) => new Wallet(w)); } } - -export default TipccClient; diff --git a/src/structures/Transaction.ts b/src/structures/Transaction.ts index 82ee4e3..253e769 100644 --- a/src/structures/Transaction.ts +++ b/src/structures/Transaction.ts @@ -1,11 +1,11 @@ -import Amount from './Amount'; -import User from './User'; +import { Amount } from './Amount'; +import { User } from './User'; import type { APITransaction } from '@tipccjs/tipcc-api-types'; /** * A class for storing an API transaction. */ -export default class Transaction { +export class Transaction { public id: string; public type: 'tip' | 'withdrawal' | 'deposit' = 'tip'; diff --git a/src/structures/User.ts b/src/structures/User.ts index 9a774ec..8b13894 100644 --- a/src/structures/User.ts +++ b/src/structures/User.ts @@ -3,7 +3,7 @@ import type { APIConnection } from '@tipccjs/tipcc-api-types'; /** * A class for storing an API user. */ -export default class User { +export class User { public identifier: string; public username: string | null; diff --git a/src/structures/Wallet.ts b/src/structures/Wallet.ts index e115c9f..8910839 100644 --- a/src/structures/Wallet.ts +++ b/src/structures/Wallet.ts @@ -1,10 +1,10 @@ -import Amount from './Amount'; +import { Amount } from './Amount'; import type { APIWallet } from '@tipccjs/tipcc-api-types'; /** * A class for storing an API wallet. */ -export default class Wallet { +export class Wallet { public code: string; public name: string; diff --git a/src/utils/Bucket.ts b/src/utils/Bucket.ts index 7e6f1b1..6066d76 100644 --- a/src/utils/Bucket.ts +++ b/src/utils/Bucket.ts @@ -1,6 +1,6 @@ import type { AxiosRequestConfig } from 'axios'; -export default class Bucket extends Array { +export class Bucket extends Array { public processing: ReturnType | boolean = false; public limit: number;