@aurigami/sdk 1.23.1 → 1.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SDK.d.ts +48 -65
- package/dist/SDK.js +165 -0
- package/dist/abis/index.d.ts +18 -18
- package/dist/abis/index.js +39 -0
- package/dist/consts/constants.d.ts +139 -139
- package/dist/consts/constants.js +185 -0
- package/dist/consts/decimals.d.ts +1 -1
- package/dist/consts/decimals.js +35 -0
- package/dist/consts/deployments.d.ts +3 -3
- package/dist/consts/deployments.js +9 -0
- package/dist/consts/dummy.d.ts +13 -13
- package/dist/consts/dummy.js +43 -0
- package/dist/consts/index.d.ts +5 -5
- package/dist/consts/index.js +9 -0
- package/dist/consts/symbols.d.ts +1 -1
- package/dist/consts/symbols.js +10 -0
- package/dist/entities/BlockchainEntity.d.ts +13 -13
- package/dist/entities/BlockchainEntity.js +36 -0
- package/dist/entities/auriEnv.d.ts +34 -40
- package/dist/entities/auriEnv.js +166 -0
- package/dist/entities/index.d.ts +4 -4
- package/dist/entities/index.js +8 -0
- package/dist/entities/token.d.ts +7 -7
- package/dist/entities/token.js +27 -0
- package/dist/entities/tokenAmount.d.ts +13 -13
- package/dist/entities/tokenAmount.js +52 -0
- package/dist/helpers/aurigami-api.d.ts +13 -13
- package/dist/helpers/aurigami-api.js +26 -0
- package/dist/helpers/aurora-api-helpers.d.ts +1 -1
- package/dist/helpers/aurora-api-helpers.js +15 -0
- package/dist/helpers/graphql-helpers.d.ts +1 -1
- package/dist/helpers/graphql-helpers.js +13 -0
- package/dist/helpers/helpers.d.ts +23 -40
- package/dist/helpers/helpers.js +148 -0
- package/dist/helpers/historicalPriceFetcher.d.ts +15 -15
- package/dist/helpers/historicalPriceFetcher.js +142 -0
- package/dist/helpers/index.d.ts +7 -7
- package/dist/helpers/index.js +11 -0
- package/dist/helpers/kyber-aggregator-api.d.ts +5 -5
- package/dist/helpers/kyber-aggregator-api.js +27 -0
- package/dist/helpers/multicall.d.ts +40 -0
- package/dist/helpers/multicall.js +203 -0
- package/dist/helpers/notification-api.d.ts +2 -2
- package/dist/helpers/notification-api.js +21 -0
- package/dist/helpers/one-inch-aggregator-api.d.ts +21 -21
- package/dist/helpers/one-inch-aggregator-api.js +19 -0
- package/dist/helpers/priceFetcher.d.ts +36 -36
- package/dist/helpers/priceFetcher.js +292 -0
- package/dist/helpers/subgraphQuery.d.ts +1 -1
- package/dist/helpers/subgraphQuery.js +22 -0
- package/dist/helpers/transfer-event-query.d.ts +17 -26
- package/dist/helpers/transfer-event-query.js +41 -0
- package/dist/index.d.ts +7 -7
- package/dist/index.js +17 -8
- package/dist/interactors/Airdrop.d.ts +17 -26
- package/dist/interactors/Airdrop.js +48 -0
- package/dist/interactors/MoneyMarket.d.ts +63 -63
- package/dist/interactors/MoneyMarket.js +392 -0
- package/dist/interactors/Multicall.d.ts +15 -18
- package/dist/interactors/Multicall.js +36 -0
- package/dist/interactors/Papermill.d.ts +27 -57
- package/dist/interactors/Papermill.js +125 -0
- package/dist/interactors/PlyGame.d.ts +30 -42
- package/dist/interactors/PlyGame.js +146 -0
- package/dist/interactors/PlyTokenLock.d.ts +16 -16
- package/dist/interactors/PlyTokenLock.js +44 -0
- package/dist/interactors/Pulp.d.ts +17 -17
- package/dist/interactors/Pulp.js +43 -0
- package/dist/interactors/Referral.d.ts +35 -78
- package/dist/interactors/Referral.js +158 -0
- package/dist/interactors/Staking.d.ts +20 -26
- package/dist/interactors/Staking.js +106 -0
- package/dist/interactors/index.d.ts +9 -9
- package/dist/interactors/index.js +13 -0
- package/dist/interactors/misc.d.ts +31 -39
- package/dist/interactors/misc.js +318 -0
- package/dist/types/index.d.ts +175 -197
- package/dist/types/index.js +18 -0
- package/package.json +4 -16
- package/dist/sdk.cjs.development.js +0 -6325
- package/dist/sdk.cjs.development.js.map +0 -1
- package/dist/sdk.cjs.production.min.js +0 -2
- package/dist/sdk.cjs.production.min.js.map +0 -1
- package/dist/sdk.esm.js +0 -6193
- package/dist/sdk.esm.js.map +0 -1
- package/src/SDK.ts +0 -223
- package/src/abis/index.ts +0 -38
- package/src/consts/constants.ts +0 -210
- package/src/consts/decimals.ts +0 -31
- package/src/consts/deployments.ts +0 -4
- package/src/consts/dummy.ts +0 -51
- package/src/consts/index.ts +0 -5
- package/src/consts/symbols.ts +0 -9
- package/src/entities/BlockchainEntity.ts +0 -29
- package/src/entities/auriEnv.ts +0 -178
- package/src/entities/index.ts +0 -4
- package/src/entities/token.ts +0 -21
- package/src/entities/tokenAmount.ts +0 -48
- package/src/helpers/aurigami-api.ts +0 -42
- package/src/helpers/aurora-api-helpers.ts +0 -17
- package/src/helpers/graphql-helpers.ts +0 -8
- package/src/helpers/helpers.ts +0 -212
- package/src/helpers/historicalPriceFetcher.ts +0 -203
- package/src/helpers/index.ts +0 -7
- package/src/helpers/kyber-aggregator-api.ts +0 -37
- package/src/helpers/notification-api.ts +0 -22
- package/src/helpers/one-inch-aggregator-api.ts +0 -45
- package/src/helpers/priceFetcher.ts +0 -389
- package/src/helpers/subgraphQuery.ts +0 -17
- package/src/helpers/transfer-event-query.ts +0 -68
- package/src/index.ts +0 -14
- package/src/interactors/Airdrop.ts +0 -72
- package/src/interactors/MoneyMarket.ts +0 -482
- package/src/interactors/Multicall.ts +0 -50
- package/src/interactors/Papermill.ts +0 -185
- package/src/interactors/PlyGame.ts +0 -172
- package/src/interactors/PlyTokenLock.ts +0 -47
- package/src/interactors/Pulp.ts +0 -39
- package/src/interactors/Referral.ts +0 -214
- package/src/interactors/Staking.ts +0 -152
- package/src/interactors/index.ts +0 -9
- package/src/interactors/misc.ts +0 -431
- package/src/types/index.ts +0 -222
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
import { IUniswapV2Pair, PriceOracle } from '@aurigami/contracts/typechain';
|
|
2
|
-
import BigNumber from 'bignumber.js';
|
|
3
|
-
import { BigNumber as BN, Contract, providers } from 'ethers';
|
|
4
|
-
import { AuriOracleABI, IUniswapV2PairABI } from '../abis';
|
|
5
|
-
import { HARDCODE_PRICE_TOKENS, networkAddresses } from '../consts/constants';
|
|
6
|
-
import { Address } from '../types';
|
|
7
|
-
import { decimalFactor, devLog, getDecimal, isSameAddress } from './helpers';
|
|
8
|
-
|
|
9
|
-
export async function fetchHistoricalLPPositions(
|
|
10
|
-
LPAddress: Address,
|
|
11
|
-
provider: providers.Provider,
|
|
12
|
-
block: number
|
|
13
|
-
): Promise<{
|
|
14
|
-
token0: Address;
|
|
15
|
-
token1: Address;
|
|
16
|
-
reserve0: BN;
|
|
17
|
-
reserve1: BN;
|
|
18
|
-
totalSupply: BN;
|
|
19
|
-
}> {
|
|
20
|
-
const LPContract = new Contract(LPAddress, IUniswapV2PairABI.abi, provider) as IUniswapV2Pair;
|
|
21
|
-
var promises: any[] = [];
|
|
22
|
-
promises.push(LPContract.token0());
|
|
23
|
-
promises.push(LPContract.token1());
|
|
24
|
-
promises.push(LPContract.getReserves({ blockTag: block }));
|
|
25
|
-
promises.push(LPContract.totalSupply({ blockTag: block }));
|
|
26
|
-
const values: any[] = await Promise.all(promises);
|
|
27
|
-
|
|
28
|
-
return {
|
|
29
|
-
token0: values[0] as string,
|
|
30
|
-
token1: values[1] as string,
|
|
31
|
-
reserve0: (values[2] as { reserve0: BN; reserve1: BN }).reserve0,
|
|
32
|
-
reserve1: (values[2] as { reserve0: BN; reserve1: BN }).reserve1,
|
|
33
|
-
totalSupply: values[3] as BN,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export async function fetchHistoricalLPPrice(
|
|
38
|
-
address: Address,
|
|
39
|
-
provider: providers.Provider,
|
|
40
|
-
block: number
|
|
41
|
-
): Promise<BigNumber> {
|
|
42
|
-
var LPInfo = await fetchHistoricalLPPositions(address, provider, block);
|
|
43
|
-
const LPDecimal = getDecimal(address);
|
|
44
|
-
|
|
45
|
-
async function fetchLPPriceBy(
|
|
46
|
-
tokenReverse: {
|
|
47
|
-
address: string;
|
|
48
|
-
reserve: BN;
|
|
49
|
-
},
|
|
50
|
-
block: number
|
|
51
|
-
): Promise<BigNumber> {
|
|
52
|
-
if (tokenReverse.reserve.isZero()) return new BigNumber(0);
|
|
53
|
-
|
|
54
|
-
const tokenPrice: BigNumber = await fetchHistoricalPrice(tokenReverse.address, provider, block);
|
|
55
|
-
const tokenDecimal = getDecimal(tokenReverse.address);
|
|
56
|
-
|
|
57
|
-
// reserveUSD will be divided by 10^tokenDecimal later for more precision
|
|
58
|
-
const reserveUSD: BigNumber = tokenPrice
|
|
59
|
-
.multipliedBy(tokenReverse.reserve.toString())
|
|
60
|
-
.multipliedBy(2);
|
|
61
|
-
return reserveUSD
|
|
62
|
-
.multipliedBy(decimalFactor(LPDecimal))
|
|
63
|
-
.dividedBy(new BigNumber(LPInfo.totalSupply.toString()))
|
|
64
|
-
.dividedBy(decimalFactor(tokenDecimal));
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
try {
|
|
68
|
-
// MUST await here
|
|
69
|
-
const lpPrice = await fetchLPPriceBy(
|
|
70
|
-
{
|
|
71
|
-
address: LPInfo.token0,
|
|
72
|
-
reserve: LPInfo.reserve0,
|
|
73
|
-
},
|
|
74
|
-
block
|
|
75
|
-
);
|
|
76
|
-
if (lpPrice.isZero()) {
|
|
77
|
-
throw Error(`Price is zero`);
|
|
78
|
-
}
|
|
79
|
-
return lpPrice;
|
|
80
|
-
} catch (e) {
|
|
81
|
-
devLog(`fetchLPPriceBy ${LPInfo.token0} failed`, e);
|
|
82
|
-
try {
|
|
83
|
-
// MUST await here
|
|
84
|
-
return await fetchLPPriceBy(
|
|
85
|
-
{
|
|
86
|
-
address: LPInfo.token1,
|
|
87
|
-
reserve: LPInfo.reserve1,
|
|
88
|
-
},
|
|
89
|
-
block
|
|
90
|
-
);
|
|
91
|
-
} catch (e) {
|
|
92
|
-
devLog(`fetchLPPriceBy ${LPInfo.token1} failed`, e);
|
|
93
|
-
throw Error(`Unable to fetch price for both tokens of LP ${address}`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function processPriceFromOracle(rawPrice: BN, underlyingDecimal: number) {
|
|
99
|
-
return new BigNumber(rawPrice.toString()).div(decimalFactor(36 - underlyingDecimal));
|
|
100
|
-
}
|
|
101
|
-
export async function fetchHistoricalPriceFromOracle(
|
|
102
|
-
auTokenAddress: Address,
|
|
103
|
-
underlyingDecimal: number,
|
|
104
|
-
provider: providers.Provider,
|
|
105
|
-
block: number
|
|
106
|
-
): Promise<BigNumber> {
|
|
107
|
-
// from this block, we switch to use pyth
|
|
108
|
-
// TODO: add to consts
|
|
109
|
-
const oracleAddress =
|
|
110
|
-
block < 102438637
|
|
111
|
-
? networkAddresses.misc.DEPRECATED_OLD_ORACLE
|
|
112
|
-
: networkAddresses.misc.PYTH_ORACLE;
|
|
113
|
-
|
|
114
|
-
const oracleContract: PriceOracle = new Contract(
|
|
115
|
-
oracleAddress,
|
|
116
|
-
AuriOracleABI.abi,
|
|
117
|
-
provider
|
|
118
|
-
) as PriceOracle;
|
|
119
|
-
const rawPrice = await oracleContract
|
|
120
|
-
.getUnderlyingPrice(auTokenAddress, { blockTag: block })
|
|
121
|
-
.catch((e: any) => {
|
|
122
|
-
console.log(`Unable to fetch price from oracle for ${auTokenAddress}`);
|
|
123
|
-
return BN.from(0);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
return processPriceFromOracle(rawPrice, underlyingDecimal);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export async function fetchHistoricalPrice(
|
|
130
|
-
address: Address,
|
|
131
|
-
provider: providers.Provider,
|
|
132
|
-
block: number
|
|
133
|
-
): Promise<BigNumber> {
|
|
134
|
-
if (address.toLowerCase() in HARDCODE_PRICE_TOKENS) {
|
|
135
|
-
return new BigNumber(HARDCODE_PRICE_TOKENS[address.toLowerCase()]);
|
|
136
|
-
} else if (
|
|
137
|
-
isSameAddress(address, networkAddresses.tokens.PLY_WNEAR) ||
|
|
138
|
-
isSameAddress(address, networkAddresses.tokens.WNEAR_TRI) ||
|
|
139
|
-
isSameAddress(address, networkAddresses.tokens.AURORA_WNEAR)
|
|
140
|
-
) {
|
|
141
|
-
return fetchHistoricalLPPrice(address, provider, block);
|
|
142
|
-
} else if (isSameAddress(address, networkAddresses.tokens.PLY)) {
|
|
143
|
-
return fetchHistoricalPriceByLP(networkAddresses.tokens.PLY_WNEAR, provider, block);
|
|
144
|
-
} else if (isSameAddress(address, networkAddresses.tokens.TRI)) {
|
|
145
|
-
return fetchHistoricalPriceByLP(networkAddresses.tokens.WNEAR_TRI, provider, block, 1);
|
|
146
|
-
} else if (isSameAddress(address, networkAddresses.tokens.AURORA)) {
|
|
147
|
-
return fetchHistoricalPriceByLP(networkAddresses.tokens.AURORA_WNEAR, provider, block);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const matchingAuToken = networkAddresses.auTokens.find((auToken) => {
|
|
151
|
-
return isSameAddress(auToken.underlying, address);
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
if (matchingAuToken !== undefined) {
|
|
155
|
-
return fetchHistoricalPriceFromOracle(
|
|
156
|
-
matchingAuToken.address,
|
|
157
|
-
getDecimal(address),
|
|
158
|
-
provider,
|
|
159
|
-
block
|
|
160
|
-
);
|
|
161
|
-
} else {
|
|
162
|
-
throw Error(`Unable to fetch price for ${address}`);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
export async function fetchHistoricalPULPPrice(provider: providers.Provider): Promise<BigNumber> {
|
|
167
|
-
//TODO: Calculate PULP price
|
|
168
|
-
return new BigNumber(0);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
export async function fetchHistoricalPriceByLP(
|
|
172
|
-
LP: Address,
|
|
173
|
-
provider: providers.Provider,
|
|
174
|
-
block: number,
|
|
175
|
-
tokenNumber: 0 | 1 = 0
|
|
176
|
-
): Promise<BigNumber> {
|
|
177
|
-
let LPInfo = await fetchHistoricalLPPositions(LP, provider, block);
|
|
178
|
-
|
|
179
|
-
if (tokenNumber === 1) {
|
|
180
|
-
LPInfo = {
|
|
181
|
-
token0: LPInfo.token1,
|
|
182
|
-
token1: LPInfo.token0,
|
|
183
|
-
reserve0: LPInfo.reserve1,
|
|
184
|
-
reserve1: LPInfo.reserve0,
|
|
185
|
-
totalSupply: LPInfo.totalSupply,
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
if (LPInfo.reserve1.isZero()) {
|
|
190
|
-
return new BigNumber(0);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
const token0Decimal = getDecimal(LPInfo.token0);
|
|
194
|
-
const token1Decimal = getDecimal(LPInfo.token1);
|
|
195
|
-
|
|
196
|
-
// (token0Price * reserve0) / 10^decimal0 = (token1Price * reserve1) / 10^decimal1
|
|
197
|
-
// token0Price = (token1Price * reserve1) * 10^decimal0 / 10^decimal1 / reserve0
|
|
198
|
-
return (await fetchHistoricalPrice(LPInfo.token1, provider, block))
|
|
199
|
-
.multipliedBy(LPInfo.reserve1.toString())
|
|
200
|
-
.multipliedBy(decimalFactor(token0Decimal))
|
|
201
|
-
.dividedBy(decimalFactor(token1Decimal))
|
|
202
|
-
.dividedBy(LPInfo.reserve0.toString());
|
|
203
|
-
}
|
package/src/helpers/index.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
|
|
3
|
-
const KYBER_AGGREGATOR_AURORA_API_END_POINT =
|
|
4
|
-
'https://aggregator-api.kyberswap.com/aurora/route/encode';
|
|
5
|
-
|
|
6
|
-
const KYBER_AGGREGATOR_ETH_API_END_POINT =
|
|
7
|
-
'https://aggregator-api.kyberswap.com/ethereum/route/encode';
|
|
8
|
-
|
|
9
|
-
export async function getSwapInfo(
|
|
10
|
-
tokenIn: string,
|
|
11
|
-
tokenOut: string,
|
|
12
|
-
amountIn: string,
|
|
13
|
-
onAurora = true
|
|
14
|
-
): Promise<KyberApiResponse> {
|
|
15
|
-
const params = {
|
|
16
|
-
tokenIn,
|
|
17
|
-
tokenOut,
|
|
18
|
-
amountIn,
|
|
19
|
-
to: '0x0000000000000000000000000000000000000000',
|
|
20
|
-
useMeta: '1',
|
|
21
|
-
saveGas: '1',
|
|
22
|
-
gasInclude: '1',
|
|
23
|
-
};
|
|
24
|
-
const endpoint = onAurora
|
|
25
|
-
? KYBER_AGGREGATOR_AURORA_API_END_POINT
|
|
26
|
-
: KYBER_AGGREGATOR_ETH_API_END_POINT;
|
|
27
|
-
const resp = await axios.get(endpoint + '?' + new URLSearchParams(params), {
|
|
28
|
-
headers: { 'Content-Type': 'application/json' },
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
return resp.data;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export type KyberApiResponse = {
|
|
35
|
-
inputAmount: string;
|
|
36
|
-
outputAmount: string;
|
|
37
|
-
};
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
|
|
3
|
-
const NOTIFICATION_API_END_POINT = 'https://api.aurigami.finance/notification/';
|
|
4
|
-
|
|
5
|
-
export async function getApi(url: string, params: Record<string, any> = {}): Promise<any> {
|
|
6
|
-
const resp = await axios.get(
|
|
7
|
-
NOTIFICATION_API_END_POINT + url + '?' + new URLSearchParams(params),
|
|
8
|
-
{
|
|
9
|
-
headers: { 'Content-Type': 'application/json' },
|
|
10
|
-
}
|
|
11
|
-
);
|
|
12
|
-
|
|
13
|
-
return resp.data;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export async function postApi(url: string, body: Record<string, any>): Promise<any> {
|
|
17
|
-
const resp = await axios.post(NOTIFICATION_API_END_POINT + url, body, {
|
|
18
|
-
headers: { 'Content-Type': 'application/json' },
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
return resp.data;
|
|
22
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
// https://api.1inch.io/v5.0/1313161554/quote?fromTokenAddress=0x8bec47865ade3b172a928df8f990bc7f2a3b9f79&toTokenAddress=0x4988a896b1227218e4a686fde5eabdcabd91571f&amount=1000000000000000000
|
|
2
|
-
|
|
3
|
-
import axios from 'axios';
|
|
4
|
-
|
|
5
|
-
const ONEINCH_AGGREGATOR_API_END_POINT = 'https://api.1inch.io/v5.0/1313161554/quote';
|
|
6
|
-
|
|
7
|
-
export async function getQuoteOneInch(
|
|
8
|
-
fromTokenAddress: string,
|
|
9
|
-
toTokenAddress: string,
|
|
10
|
-
amount: string
|
|
11
|
-
): Promise<OneInchApiResponse> {
|
|
12
|
-
const params = {
|
|
13
|
-
fromTokenAddress,
|
|
14
|
-
toTokenAddress,
|
|
15
|
-
amount,
|
|
16
|
-
};
|
|
17
|
-
const resp = await axios.get(
|
|
18
|
-
ONEINCH_AGGREGATOR_API_END_POINT + '?' + new URLSearchParams(params),
|
|
19
|
-
{
|
|
20
|
-
headers: { 'Content-Type': 'application/json' },
|
|
21
|
-
}
|
|
22
|
-
);
|
|
23
|
-
return resp.data;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export type OneInchApiResponse = {
|
|
27
|
-
fromToken: {
|
|
28
|
-
symbol: string;
|
|
29
|
-
name: string;
|
|
30
|
-
decimals: number;
|
|
31
|
-
address: string;
|
|
32
|
-
logoURI: string;
|
|
33
|
-
tags: string[];
|
|
34
|
-
};
|
|
35
|
-
toToken: {
|
|
36
|
-
symbol: string;
|
|
37
|
-
name: string;
|
|
38
|
-
decimals: number;
|
|
39
|
-
address: string;
|
|
40
|
-
logoURI: string;
|
|
41
|
-
tags: string[];
|
|
42
|
-
};
|
|
43
|
-
toTokenAmount: string;
|
|
44
|
-
fromTokenAmount: string;
|
|
45
|
-
};
|
|
@@ -1,389 +0,0 @@
|
|
|
1
|
-
import AuriLensABI from '@aurigami/contracts/artifacts/contracts/AuriLens.sol/AuriLens.json';
|
|
2
|
-
import { AuriPythOracle, ERC20, IUniswapV2Pair } from '@aurigami/contracts/typechain';
|
|
3
|
-
import axios from 'axios';
|
|
4
|
-
import BigNumber from 'bignumber.js';
|
|
5
|
-
import { BigNumber as BN, Contract, ethers, providers } from 'ethers';
|
|
6
|
-
import { AuriOracleABI, EIP20InterfaceABI, IUniswapV2PairABI } from '../abis';
|
|
7
|
-
import {
|
|
8
|
-
DECIMAL_PRECISION,
|
|
9
|
-
HARDCODE_PRICE_TOKENS,
|
|
10
|
-
PRICE_WHITELISTED,
|
|
11
|
-
STADER_ETH,
|
|
12
|
-
USDT_ETH,
|
|
13
|
-
networkAddresses,
|
|
14
|
-
} from '../consts/constants';
|
|
15
|
-
import { TokenAmount } from '../entities/tokenAmount';
|
|
16
|
-
import { Address, TokenValuation } from '../types';
|
|
17
|
-
import { assert, decimalFactor, devLog, getDecimal, isSameAddress } from './helpers';
|
|
18
|
-
import { getSwapInfo } from './kyber-aggregator-api';
|
|
19
|
-
import { getQuoteOneInch } from './one-inch-aggregator-api';
|
|
20
|
-
|
|
21
|
-
export async function prepareParamsAggregator(address: string, provider: providers.Provider) {
|
|
22
|
-
const tokenInErc20 = new Contract(address, EIP20InterfaceABI.abi, provider) as ERC20;
|
|
23
|
-
const tokenInDecimal = await tokenInErc20.decimals();
|
|
24
|
-
const tokenInQuantity = BN.from(10).pow(tokenInDecimal).toString();
|
|
25
|
-
const usdtAddress =
|
|
26
|
-
networkAddresses.auTokens.find((autoken) => autoken.name == 'auUSDT')?.underlying ?? '';
|
|
27
|
-
const usdtDecimal = getDecimal(usdtAddress);
|
|
28
|
-
return {
|
|
29
|
-
tokenInQuantity,
|
|
30
|
-
usdtAddress,
|
|
31
|
-
usdtDecimal,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export async function fetchPriceFromOneInch(address: string, provider: providers.Provider) {
|
|
36
|
-
const { tokenInQuantity, usdtAddress, usdtDecimal } = await prepareParamsAggregator(
|
|
37
|
-
address,
|
|
38
|
-
provider
|
|
39
|
-
);
|
|
40
|
-
const info = await getQuoteOneInch(address, usdtAddress, tokenInQuantity);
|
|
41
|
-
const outputAmount = info.toTokenAmount;
|
|
42
|
-
return new BigNumber(outputAmount).dividedBy(10 ** usdtDecimal);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export async function fetchPriceFromKyberSwap(
|
|
46
|
-
address: string,
|
|
47
|
-
provider: providers.Provider,
|
|
48
|
-
onAurora = true
|
|
49
|
-
): Promise<BigNumber> {
|
|
50
|
-
if (address == networkAddresses.tokens.STADER) {
|
|
51
|
-
const ETH_PROVIDER = new ethers.providers.JsonRpcProvider('https://rpc.ankr.com/eth');
|
|
52
|
-
|
|
53
|
-
return fetchPriceFromKyberSwap(STADER_ETH, ETH_PROVIDER, false);
|
|
54
|
-
}
|
|
55
|
-
let { tokenInQuantity, usdtAddress, usdtDecimal } = await prepareParamsAggregator(
|
|
56
|
-
address,
|
|
57
|
-
provider
|
|
58
|
-
);
|
|
59
|
-
if (!onAurora) {
|
|
60
|
-
usdtAddress = USDT_ETH;
|
|
61
|
-
}
|
|
62
|
-
const info = await getSwapInfo(address, usdtAddress, tokenInQuantity, onAurora);
|
|
63
|
-
const outputAmount = info.outputAmount;
|
|
64
|
-
return new BigNumber(outputAmount).dividedBy(10 ** usdtDecimal);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export async function fetchPriceFromDefiLlamaAPI(id: string): Promise<BigNumber> {
|
|
68
|
-
const price = await axios
|
|
69
|
-
.get(`https://coins.llama.fi/prices/current/${id}`)
|
|
70
|
-
.then((res: any) => {
|
|
71
|
-
return res.data.coins[id].price;
|
|
72
|
-
})
|
|
73
|
-
.catch((err: any) => {
|
|
74
|
-
console.log(`unable to fetch price from DefiLlama API: ${err}`);
|
|
75
|
-
console.error(err);
|
|
76
|
-
return 0;
|
|
77
|
-
});
|
|
78
|
-
return new BigNumber(price);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export async function fetchPriceFromCoingeckoAPI(id: string): Promise<BigNumber> {
|
|
82
|
-
const price = await axios
|
|
83
|
-
.get(`https://api.coingecko.com/api/v3/simple/price?ids=${id}&vs_currencies=usd`)
|
|
84
|
-
.then((res: any) => {
|
|
85
|
-
return res.data[id];
|
|
86
|
-
})
|
|
87
|
-
.catch((err: any) => {
|
|
88
|
-
console.log(`Unable to fetch price from Coingecko API for ${id}`);
|
|
89
|
-
console.error(err);
|
|
90
|
-
return { usd: 0 };
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
return new BigNumber(price.usd);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export async function fetchPriceFromDefiLlamaAndCoingecko(id: Address): Promise<BigNumber> {
|
|
97
|
-
if (
|
|
98
|
-
id.toLowerCase() == networkAddresses.tokens.AURORA ||
|
|
99
|
-
id.toLowerCase() == networkAddresses.tokens.TRI ||
|
|
100
|
-
id.toLowerCase() == networkAddresses.tokens.META
|
|
101
|
-
) {
|
|
102
|
-
return fetchPriceFromDefiLlamaAPI(`aurora:${id.toLowerCase()}`).catch((e) =>
|
|
103
|
-
fetchPriceFromCoingecko(id)
|
|
104
|
-
);
|
|
105
|
-
} else if (id.toLowerCase() == networkAddresses.tokens.STADER) {
|
|
106
|
-
return fetchPriceFromCoingecko(id);
|
|
107
|
-
}
|
|
108
|
-
throw Error(`Unknown token ${id} in fetchPriceFromDefiLlama`);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export async function fetchPriceFromCoingecko(id: Address): Promise<BigNumber> {
|
|
112
|
-
switch (id.toLowerCase()) {
|
|
113
|
-
case networkAddresses.tokens.AURORA:
|
|
114
|
-
return fetchPriceFromCoingeckoAPI('aurora-near');
|
|
115
|
-
|
|
116
|
-
case networkAddresses.tokens.TRI:
|
|
117
|
-
return fetchPriceFromCoingeckoAPI('trisolaris');
|
|
118
|
-
|
|
119
|
-
case networkAddresses.tokens.META:
|
|
120
|
-
return fetchPriceFromCoingeckoAPI('meta-pool');
|
|
121
|
-
|
|
122
|
-
case networkAddresses.tokens.STADER:
|
|
123
|
-
return fetchPriceFromCoingeckoAPI('stader');
|
|
124
|
-
|
|
125
|
-
default:
|
|
126
|
-
throw Error(`Unknown token ${id} in fetchPriceFromCoingecko`);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export async function fetchLPPositions(
|
|
131
|
-
LPAddress: Address,
|
|
132
|
-
provider: providers.Provider
|
|
133
|
-
): Promise<{
|
|
134
|
-
token0: Address;
|
|
135
|
-
token1: Address;
|
|
136
|
-
reserve0: BN;
|
|
137
|
-
reserve1: BN;
|
|
138
|
-
totalSupply: BN;
|
|
139
|
-
}> {
|
|
140
|
-
const LPContract = new Contract(LPAddress, IUniswapV2PairABI.abi, provider) as IUniswapV2Pair;
|
|
141
|
-
const [token0, token1, reserves, totalSupply] = await Promise.all([
|
|
142
|
-
LPContract.token0(),
|
|
143
|
-
LPContract.token1(),
|
|
144
|
-
LPContract.getReserves(),
|
|
145
|
-
LPContract.totalSupply(),
|
|
146
|
-
]);
|
|
147
|
-
|
|
148
|
-
return {
|
|
149
|
-
token0: token0,
|
|
150
|
-
token1: token1,
|
|
151
|
-
reserve0: reserves.reserve0,
|
|
152
|
-
reserve1: reserves.reserve1,
|
|
153
|
-
totalSupply: totalSupply,
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
export async function fetchLPPrice(
|
|
158
|
-
address: Address,
|
|
159
|
-
provider: providers.Provider
|
|
160
|
-
): Promise<BigNumber> {
|
|
161
|
-
var LPInfo = await fetchLPPositions(address, provider);
|
|
162
|
-
const LPDecimal = getDecimal(address);
|
|
163
|
-
|
|
164
|
-
async function fetchLPPriceBy(tokenReverse: {
|
|
165
|
-
address: string;
|
|
166
|
-
reserve: BN;
|
|
167
|
-
}): Promise<BigNumber> {
|
|
168
|
-
if (tokenReverse.reserve.isZero()) return new BigNumber(0);
|
|
169
|
-
|
|
170
|
-
// Should NOT call `fetchPrice`, it will cause an infinite loop
|
|
171
|
-
// because the token can be PLY. To calculate PLY price, we need to
|
|
172
|
-
// call `fetchPrice` again...
|
|
173
|
-
const tokenPrice: BigNumber = await _fetchPrice(tokenReverse.address, provider);
|
|
174
|
-
const tokenDecimal = getDecimal(tokenReverse.address);
|
|
175
|
-
|
|
176
|
-
// reserveUSD will be divided by 10^tokenDecimal later for more precision
|
|
177
|
-
const reserveUSD: BigNumber = tokenPrice
|
|
178
|
-
.multipliedBy(tokenReverse.reserve.toString())
|
|
179
|
-
.multipliedBy(2);
|
|
180
|
-
return reserveUSD
|
|
181
|
-
.multipliedBy(decimalFactor(LPDecimal))
|
|
182
|
-
.dividedBy(new BigNumber(LPInfo.totalSupply.toString()))
|
|
183
|
-
.dividedBy(decimalFactor(tokenDecimal));
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
try {
|
|
187
|
-
// MUST await here
|
|
188
|
-
const lpPrice = await fetchLPPriceBy({
|
|
189
|
-
address: LPInfo.token0,
|
|
190
|
-
reserve: LPInfo.reserve0,
|
|
191
|
-
});
|
|
192
|
-
if (lpPrice.isZero()) {
|
|
193
|
-
throw Error(`Price is zero`);
|
|
194
|
-
}
|
|
195
|
-
return lpPrice;
|
|
196
|
-
} catch (e) {
|
|
197
|
-
devLog(`fetchLPPriceBy ${LPInfo.token0} failed`, e);
|
|
198
|
-
try {
|
|
199
|
-
// MUST await here
|
|
200
|
-
return await fetchLPPriceBy({
|
|
201
|
-
address: LPInfo.token1,
|
|
202
|
-
reserve: LPInfo.reserve1,
|
|
203
|
-
});
|
|
204
|
-
} catch (e) {
|
|
205
|
-
devLog(`fetchLPPriceBy ${LPInfo.token1} failed`, e);
|
|
206
|
-
throw Error(`Unable to fetch price for both tokens of LP ${address}`);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
export async function fetchStNEARPrice(): Promise<BigNumber> {
|
|
212
|
-
const ratioPromise = axios
|
|
213
|
-
.get('https://validators.narwallets.com/metrics_json')
|
|
214
|
-
.then((res) => res.data);
|
|
215
|
-
const nearPricePromise = fetchPriceFromCoingeckoAPI('near');
|
|
216
|
-
const [ratioRes, nearPrice]: [any, BigNumber] = await Promise.all([
|
|
217
|
-
ratioPromise,
|
|
218
|
-
nearPricePromise,
|
|
219
|
-
]);
|
|
220
|
-
const ratio = new BigNumber(ratioRes.st_near_price);
|
|
221
|
-
return ratio.multipliedBy(nearPrice);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
function processPriceFromOracle(rawPrice: BN, underlyingDecimal: number) {
|
|
225
|
-
return new BigNumber(rawPrice.toString()).div(decimalFactor(36 - underlyingDecimal));
|
|
226
|
-
}
|
|
227
|
-
export async function fetchPriceFromOracle(
|
|
228
|
-
auTokenAddress: Address,
|
|
229
|
-
underlyingDecimal: number,
|
|
230
|
-
provider: providers.Provider
|
|
231
|
-
): Promise<BigNumber> {
|
|
232
|
-
const oracleContract: AuriPythOracle = new Contract(
|
|
233
|
-
networkAddresses.misc.PYTH_ORACLE,
|
|
234
|
-
AuriOracleABI.abi,
|
|
235
|
-
provider
|
|
236
|
-
) as AuriPythOracle;
|
|
237
|
-
const rawPrice = await oracleContract.getUnderlyingPrice(auTokenAddress).catch((e: any) => {
|
|
238
|
-
console.log(`Unable to fetch price from oracle for ${auTokenAddress}`);
|
|
239
|
-
return BN.from(0);
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
// In case of error, probally it is because the underlying token is not supported
|
|
243
|
-
// by the backup oracle. In that case, we will fetch from third-party.
|
|
244
|
-
if (rawPrice.isZero()) {
|
|
245
|
-
const matchingAuToken = networkAddresses.auTokens.find((auToken) => {
|
|
246
|
-
return isSameAddress(auToken.address, auTokenAddress);
|
|
247
|
-
});
|
|
248
|
-
if (matchingAuToken?.name == 'auSTNEAR') {
|
|
249
|
-
return fetchStNEARPrice();
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
return processPriceFromOracle(rawPrice, underlyingDecimal);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
export async function fetchUnderlyingTokensPrices(provider: providers.Provider): Promise<
|
|
257
|
-
{
|
|
258
|
-
auToken: string;
|
|
259
|
-
underlyingPrice: BigNumber;
|
|
260
|
-
}[]
|
|
261
|
-
> {
|
|
262
|
-
const auriLens: Contract = new Contract(
|
|
263
|
-
networkAddresses.misc.AURILENS,
|
|
264
|
-
AuriLensABI.abi,
|
|
265
|
-
provider
|
|
266
|
-
);
|
|
267
|
-
const auTokenAddresses = networkAddresses.auTokens.map((auToken) => auToken.address);
|
|
268
|
-
const underlyingDecimals = networkAddresses.auTokens.map((auToken) =>
|
|
269
|
-
getDecimal(auToken.underlying)
|
|
270
|
-
);
|
|
271
|
-
const rawPrices = await auriLens.auTokenUnderlyingPriceAll(auTokenAddresses);
|
|
272
|
-
return rawPrices.map((res: any, ind: number) => {
|
|
273
|
-
return {
|
|
274
|
-
auToken: res.auToken,
|
|
275
|
-
underlyingPrice: processPriceFromOracle(res.underlyingPrice, underlyingDecimals[ind]),
|
|
276
|
-
};
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
function shouldFetchFromKyberSwap(address: string) {
|
|
281
|
-
address = address.toLowerCase();
|
|
282
|
-
return (
|
|
283
|
-
address == networkAddresses.tokens.TRI ||
|
|
284
|
-
address == networkAddresses.tokens.META ||
|
|
285
|
-
address == networkAddresses.tokens.STADER
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Fetch price from Oracle or Coingecko
|
|
291
|
-
*/
|
|
292
|
-
async function _fetchPrice(address: Address, provider: providers.Provider): Promise<BigNumber> {
|
|
293
|
-
assert(
|
|
294
|
-
PRICE_WHITELISTED.has(address.toLocaleLowerCase()),
|
|
295
|
-
`Address ${address} is not whitelisted for price fetching`
|
|
296
|
-
);
|
|
297
|
-
if (address.toLowerCase() == networkAddresses.tokens.META) {
|
|
298
|
-
return fetchPriceFromDefiLlamaAndCoingecko(address);
|
|
299
|
-
}
|
|
300
|
-
if (shouldFetchFromKyberSwap(address)) {
|
|
301
|
-
return fetchPriceFromKyberSwap(address, provider).catch((e) => {
|
|
302
|
-
return fetchPriceFromDefiLlamaAndCoingecko(address);
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
const matchingAuToken = networkAddresses.auTokens.find((auToken) => {
|
|
306
|
-
return isSameAddress(auToken.underlying, address);
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
if (matchingAuToken !== undefined) {
|
|
310
|
-
return fetchPriceFromOracle(matchingAuToken.address, getDecimal(address), provider);
|
|
311
|
-
} else {
|
|
312
|
-
throw Error(`Unable to fetch price for ${address}`);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
export async function fetchPrice(
|
|
317
|
-
address: Address,
|
|
318
|
-
provider: providers.Provider
|
|
319
|
-
): Promise<BigNumber> {
|
|
320
|
-
if (address.toLowerCase() in HARDCODE_PRICE_TOKENS) {
|
|
321
|
-
return new BigNumber(HARDCODE_PRICE_TOKENS[address.toLowerCase()]);
|
|
322
|
-
} else if (isSameAddress(address, networkAddresses.tokens.PLYWNEAR)) {
|
|
323
|
-
return fetchLPPrice(address, provider);
|
|
324
|
-
} else if (isSameAddress(address, networkAddresses.tokens.PLY)) {
|
|
325
|
-
return fetchPLYPrice(provider);
|
|
326
|
-
} else if (isSameAddress(address, networkAddresses.tokens.PULP)) {
|
|
327
|
-
return fetchPULPPrice(provider);
|
|
328
|
-
}
|
|
329
|
-
return _fetchPrice(address, provider);
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
export async function fetchPLYPrice(provider: providers.Provider): Promise<BigNumber> {
|
|
333
|
-
//TODO: Fetch PLY price from CEX?
|
|
334
|
-
return fetchToken0PriceByLP(networkAddresses.tokens.PLYWNEAR, provider);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
export async function fetchPULPPrice(provider: providers.Provider): Promise<BigNumber> {
|
|
338
|
-
//TODO: Calculate PULP price
|
|
339
|
-
return new BigNumber(0);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
export async function fetchToken0PriceByLP(
|
|
343
|
-
LP: Address,
|
|
344
|
-
provider: providers.Provider
|
|
345
|
-
): Promise<BigNumber> {
|
|
346
|
-
const LPInfo = await fetchLPPositions(LP, provider);
|
|
347
|
-
|
|
348
|
-
if (LPInfo.reserve1.isZero()) {
|
|
349
|
-
return new BigNumber(0);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
const token0Decimal = getDecimal(LPInfo.token0);
|
|
353
|
-
const token1Decimal = getDecimal(LPInfo.token1);
|
|
354
|
-
|
|
355
|
-
// (token0Price * reserve0) / 10^decimal0 = (token1Price * reserve1) / 10^decimal1
|
|
356
|
-
// token0Price = (token1Price * reserve1) * 10^decimal0 / 10^decimal1 / reserve0
|
|
357
|
-
return (await fetchPrice(LPInfo.token1, provider))
|
|
358
|
-
.multipliedBy(LPInfo.reserve1.toString())
|
|
359
|
-
.multipliedBy(decimalFactor(token0Decimal))
|
|
360
|
-
.dividedBy(decimalFactor(token1Decimal))
|
|
361
|
-
.dividedBy(LPInfo.reserve0.toString());
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
export async function fetchValuation(
|
|
365
|
-
tokenAmount: TokenAmount,
|
|
366
|
-
provider: providers.Provider
|
|
367
|
-
): Promise<BigNumber> {
|
|
368
|
-
if (tokenAmount.rawAmount() == '0') return new BigNumber(0);
|
|
369
|
-
var price = await fetchPrice(tokenAmount.token.address, provider);
|
|
370
|
-
return calcValuation(tokenAmount, price);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
export function calcValuation(tokenAmount: TokenAmount, price: BigNumber) {
|
|
374
|
-
return new BigNumber(tokenAmount.formattedAmount()).multipliedBy(price);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
export async function valuateToken(
|
|
378
|
-
tokenAmount: TokenAmount,
|
|
379
|
-
provider: providers.Provider
|
|
380
|
-
): Promise<TokenValuation> {
|
|
381
|
-
let tokenValuation = await fetchValuation(tokenAmount, provider);
|
|
382
|
-
return {
|
|
383
|
-
tokenAmount: tokenAmount,
|
|
384
|
-
currencyAmount: {
|
|
385
|
-
currency: 'USD',
|
|
386
|
-
amount: tokenValuation.toFixed(DECIMAL_PRECISION),
|
|
387
|
-
},
|
|
388
|
-
};
|
|
389
|
-
}
|