Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,34 @@
Welcome to the tip.cc API Client npm package!

# Installation

Simply create an npm project if you don't have an already, and install the package.

```
npm init
npm i tipcc.js
```

# Getting Started

> Tip: Want to get started without an introduction? Check out our [documentation](https://tipccjs.org/).

You can create a simple TipccClient like this:

```js
import { TipccClient } from 'tipcc.js';

const client = TipccClient(myToken);

client.on('ready', () => {
console.log('TipccClient is ready!')
console.log('TipccClient is ready!');
});
```

`myToken` is your tip.cc API key.

## A note on API values

The tip.cc API uses the smallest denomination of currencies, giving values in atomic units.
For an explanation of how this works, use [Ethereum's wei](https://www.investopedia.com/terms/w/wei.asp) as an example.

Expand All @@ -33,6 +39,7 @@ tipcc.js uses the bignumber.js package to handle these numbers, and our API will
For a in-depth explanation of BigNumbers and available features, check their own [documentation](https://mikemcl.github.io/bignumber.js/).

## Wallets

To get your balance on tip.cc, use the [WalletManager](https://tipccjs.org/classes/WalletManager):

```js
Expand All @@ -42,13 +49,16 @@ client.on('ready', async () => {
return console.log('No BNB wallet found. Have you received any BNB?');
}

console.log(`We've got ${wallet.balance.value} ${wallet.code} on our BNB wallet`);
console.log(
`We've got ${wallet.balance.value} ${wallet.code} on our BNB wallet`,
);

console.log(`This is approximately ${wallet.balance.usdValue} USD`);
});
```

## Transactions

To receive transactions as events, use [TransactionManager](https://tipccjs.org/classes/TransactionManager)'s events:

```js
Expand All @@ -62,14 +72,19 @@ client.transactions.on('tip', (transaction) => {
```

You can also get a single or many transactions by id:

```js
client.on('ready', async () => {
const oneTransaction = await client.transactions.fetch('one-id');
const manyTransactions = await client.transactions.fetchMany(['this-id', 'another-id']);
const manyTransactions = await client.transactions.fetchMany([
'this-id',
'another-id',
]);
});
```

Getting transactions based on a filter is also possible:

```js
client.on('ready', async () => {
const transactionsByFilter = await client.transactions.fetchAll({
Expand All @@ -83,6 +98,7 @@ Using no filter will get all transactions for the bot/user.
This is not recommended, unless you know what you're doing.

## Exchange rates

Use the [ExchangeRateCache](https://tipccjs.org/classes/ExchangeRateCache) to get exchange rates:

```js
Expand All @@ -97,6 +113,7 @@ client.on('ready', async () => {
```

This is also accessible on other structures, such as wallets:

```js
client.on('ready', async () => {
const wallet = await client.wallets.fetch('BTC');
Expand All @@ -109,11 +126,13 @@ client.on('ready', async () => {
```

## Currencies

The client provides caches for cryptocurrencies ([CryptocurrencyCache](https://tipccjs.org/classes/CryptocurrencyCache)) and fiats ([FiatCache](https://tipccjs.org/classes/FiatCache)).

This may be useful when you need some basic information about a currency.

Getting a cryptocurrency:

```js
client.on('ready', async () => {
const btc = client.cryptos.get('BTC');
Expand All @@ -127,6 +146,7 @@ client.on('ready', async () => {
```

Getting a fiat:

```js
client.on('ready', async () => {
const usd = client.fiats.get('USD');
Expand All @@ -140,14 +160,17 @@ client.on('ready', async () => {
```

## Exploring

Feel free to check out our [documentation](https://tipccjs.org/) to learn about our API and how you can use it.

Notice that the examples above are bits of code separated from each other.
You can often use provided properties to get your task done with fewer lines of code by combining the structures explained.

# License

This project is licensed under the [MIT License](https://github.com/tipccjs/tipcc.js/blob/main/LICENSE).

# Disclaimer

The authors of this package are not the authors of [tip.cc](https://tip.cc).
We are not responsible for any loss of funds caused by incorrect usage, bugs, exploits, or other causes when using this package.
17 changes: 15 additions & 2 deletions src/structures/managers/TransactionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import { Transaction } from '../Transaction';
import { Cache } from '../Cache';
import { EventEmitter } from 'stream';
import { CacheSet } from '../../utils/CacheSet';

interface ValueTransaction {
recipient_s: string | string[];
Expand Down Expand Up @@ -51,6 +52,10 @@ export class TransactionManager extends EventEmitter {

private _pollingRetries = 0;

private _processedTransactions: CacheSet<string> = new CacheSet(
24 * 60 * 60 * 1000,
);

public constructor(payload: {
client: TipccClient;
cacheTtl?: number;
Expand Down Expand Up @@ -165,12 +170,20 @@ export class TransactionManager extends EventEmitter {
await this.client.cryptos.refresh();
refreshedCurrencies = true;
}
if (this.client.cryptos.get(transaction.amount.currencyCode))
if (this.client.cryptos.get(transaction.amount.currencyCode)) {
if (this._processedTransactions.has(transaction.id)) {
console.warn(
`Event emittion cancelled: Transaction ${transaction.id} has already been emitted`,
);
continue;
}
this._processedTransactions.add(transaction.id);
this.emit(transaction.type, transaction);
else
} else {
console.warn(
`Event emittion cancelled: Unknown currency code ${transaction.amount.currencyCode} for transaction ${transaction.id}`,
);
}
}

this._lastPoll = now;
Expand Down
30 changes: 30 additions & 0 deletions src/utils/CacheSet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export class CacheSet<T> extends Set {
private _cacheTtl: number;

private _timeouts: Map<T, NodeJS.Timeout> = new Map();

constructor(cacheTtl: number) {
super();
this._cacheTtl = cacheTtl;
}

public add(value: T): this {
super.add(value);
if (this._timeouts.has(value)) clearTimeout(this._timeouts.get(value)!);
this._timeouts.set(
value,
setTimeout(() => this.delete(value), this._cacheTtl),
);
return this;
}

public delete(value: T): boolean {
if (this._timeouts.has(value)) clearTimeout(this._timeouts.get(value)!);
return super.delete(value);
}

public clear(): void {
for (const timeout of this._timeouts.values()) clearTimeout(timeout);
super.clear();
}
}