-
Notifications
You must be signed in to change notification settings - Fork 0
/
fetcher.ts
75 lines (71 loc) · 2.74 KB
/
fetcher.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { Contract } from '@ethersproject/contracts'
import { getNetwork } from '@ethersproject/networks'
import { getDefaultProvider } from '@ethersproject/providers'
import { TokenAmount } from './entities/fractions/tokenAmount'
import { Pair } from './entities/pair'
import IPancakePair from '@pancakeswap-libs/pancake-swap-core/build/IPancakePair.json'
import invariant from 'tiny-invariant'
import ERC20 from './abis/ERC20.json'
import { ChainId } from './constants'
import { Token } from './entities/token'
let TOKEN_DECIMALS_CACHE: { [chainId: number]: { [address: string]: number } } = {
[ChainId.MAINNET]: {
'0xE0B7927c4aF23765Cb51314A0E0521A9645F0E2A': 9 // DGD
}
}
/**
* Contains methods for constructing instances of pairs and tokens from on-chain data.
*/
export abstract class Fetcher {
/**
* Cannot be constructed.
*/
private constructor() {}
/**
* Fetch information for a given token on the given chain, using the given ethers provider.
* @param chainId chain of the token
* @param address address of the token on the chain
* @param provider provider used to fetch the token
* @param symbol optional symbol of the token
* @param name optional name of the token
*/
public static async fetchTokenData(
chainId: ChainId,
address: string,
provider = getDefaultProvider(getNetwork(chainId)),
symbol?: string,
name?: string
): Promise<Token> {
const parsedDecimals =
typeof TOKEN_DECIMALS_CACHE?.[chainId]?.[address] === 'number'
? TOKEN_DECIMALS_CACHE[chainId][address]
: await new Contract(address, ERC20, provider).decimals().then((decimals: number): number => {
TOKEN_DECIMALS_CACHE = {
...TOKEN_DECIMALS_CACHE,
[chainId]: {
...TOKEN_DECIMALS_CACHE?.[chainId],
[address]: decimals
}
}
return decimals
})
return new Token(chainId, address, parsedDecimals, symbol, name)
}
/**
* Fetches information about a pair and constructs a pair from the given two tokens.
* @param tokenA first token
* @param tokenB second token
* @param provider the provider to use to fetch the data
*/
public static async fetchPairData(
tokenA: Token,
tokenB: Token,
provider = getDefaultProvider(getNetwork(tokenA.chainId))
): Promise<Pair> {
invariant(tokenA.chainId === tokenB.chainId, 'CHAIN_ID')
const address = Pair.getAddress(tokenA, tokenB)
const [reserves0, reserves1] = await new Contract(address, IPancakePair.abi, provider).getReserves()
const balances = tokenA.sortsBefore(tokenB) ? [reserves0, reserves1] : [reserves1, reserves0]
return new Pair(new TokenAmount(tokenA, balances[0]), new TokenAmount(tokenB, balances[1]))
}
}