@curvefi/api 2.70.5 → 2.71.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/README.md +0 -7
- package/lib/cached.d.ts +1 -1
- package/lib/cached.js +10 -7
- package/lib/constants/factory/stable.js +2 -2
- package/lib/constants/pools/avalanche.js +1 -1
- package/lib/constants/pools/ethereum.js +2 -2
- package/lib/constants/volumeNetworks.d.ts +0 -2
- package/lib/constants/volumeNetworks.js +1 -3
- package/lib/curve.js +6 -9
- package/lib/dao.js +37 -28
- package/lib/external-api.d.ts +3 -8
- package/lib/external-api.js +23 -122
- package/lib/factory/factory-api.js +7 -3
- package/lib/factory/factory-crypto.js +4 -2
- package/lib/factory/factory-tricrypto.js +4 -2
- package/lib/factory/factory-twocrypto.js +4 -2
- package/lib/factory/factory.js +14 -8
- package/lib/interfaces.d.ts +6 -23
- package/lib/lite-api.d.ts +4 -0
- package/lib/lite-api.js +130 -0
- package/lib/pools/PoolTemplate.d.ts +0 -2
- package/lib/pools/PoolTemplate.js +9 -13
- package/lib/pools/subClasses/corePool.d.ts +3 -1
- package/lib/pools/subClasses/corePool.js +1 -0
- package/lib/pools/subClasses/statsPool.js +1 -1
- package/lib/prices-api.d.ts +21 -0
- package/lib/prices-api.js +138 -0
- package/lib/router.js +3 -3
- package/lib/utils.d.ts +1 -2
- package/lib/utils.js +3 -10
- package/package.json +3 -1
package/lib/factory/factory.js
CHANGED
|
@@ -15,7 +15,7 @@ import factoryGaugeABI from "../constants/abis/gauge_factory.json" with { type:
|
|
|
15
15
|
import gaugeChildABI from "../constants/abis/gauge_child.json" with { type: "json" };
|
|
16
16
|
import StableNgBasePoolZapABI from "../constants/abis/stable-ng-base-pool-zap.json" with { type: "json" };
|
|
17
17
|
import { getPoolIdByAddress, setFactoryZapContracts } from "./common.js";
|
|
18
|
-
import { getPoolName
|
|
18
|
+
import { getPoolName } from "../utils.js";
|
|
19
19
|
import { formatUnits } from "../constants/utils.js";
|
|
20
20
|
export const BLACK_LIST = {
|
|
21
21
|
1: [
|
|
@@ -61,12 +61,11 @@ export function getBasePools(factoryAddress, rawSwapAddresses, tmpPools) {
|
|
|
61
61
|
function getRecentlyCreatedPoolId(swapAddress, factoryAddress) {
|
|
62
62
|
return __awaiter(this, void 0, void 0, function* () {
|
|
63
63
|
const factoryContract = this.contracts[factoryAddress].contract;
|
|
64
|
-
const prefix = factoryAddress === this.constants.ALIASES.factory ? 'factory-v2' : 'factory-stable-ng';
|
|
65
64
|
const poolCount = Number(this.formatUnits(yield factoryContract.pool_count(this.constantOptions), 0));
|
|
66
65
|
for (let i = 1; i <= poolCount; i++) {
|
|
67
66
|
const address = yield factoryContract.pool_list(poolCount - i);
|
|
68
67
|
if (address.toLowerCase() === swapAddress.toLowerCase())
|
|
69
|
-
return
|
|
68
|
+
return address.toLowerCase();
|
|
70
69
|
}
|
|
71
70
|
throw Error("Unknown pool");
|
|
72
71
|
});
|
|
@@ -77,15 +76,14 @@ function getFactoryIdsAndSwapAddresses() {
|
|
|
77
76
|
const factoryContract = this.contracts[factoryAddress].contract;
|
|
78
77
|
const factoryMulticallContract = this.contracts[factoryAddress].multicallContract;
|
|
79
78
|
const poolCount = Number(this.formatUnits(yield factoryContract.pool_count(this.constantOptions), 0));
|
|
79
|
+
console.log('POOL COUNT:', poolCount);
|
|
80
80
|
const calls = [];
|
|
81
81
|
for (let i = fromIdx; i < poolCount; i++) {
|
|
82
82
|
calls.push(factoryMulticallContract.pool_list(i));
|
|
83
83
|
}
|
|
84
84
|
if (calls.length === 0)
|
|
85
85
|
return [[], []];
|
|
86
|
-
|
|
87
|
-
factoryAddress === this.constants.ALIASES.crvusd_factory ? "factory-crvusd-" : "factory-stable-ng-";
|
|
88
|
-
let factories = (yield this.multicallProvider.all(calls)).map((addr, i) => ({ id: prefix + (fromIdx + i), address: addr.toLowerCase() }));
|
|
86
|
+
let factories = (yield this.multicallProvider.all(calls)).map((addr) => ({ id: addr.toLowerCase(), address: addr.toLowerCase() }));
|
|
89
87
|
const swapAddresses = Object.values(this.constants.POOLS_DATA).map((pool) => pool.swap_address.toLowerCase());
|
|
90
88
|
const blacklist = (_a = BLACK_LIST[this.chainId]) !== null && _a !== void 0 ? _a : [];
|
|
91
89
|
factories = factories.filter((f) => !swapAddresses.includes(f.address) && !blacklist.includes(f.address));
|
|
@@ -202,6 +200,10 @@ function getCoinsData(coinAddresses, existingCoinAddrNameDict, existingCoinAddrD
|
|
|
202
200
|
coinAddrNamesDict[addr] = existingCoinAddrNameDict[addr];
|
|
203
201
|
coinAddrDecimalsDict[addr] = existingCoinAddrDecimalsDict[addr];
|
|
204
202
|
}
|
|
203
|
+
else if (addr === "0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2") {
|
|
204
|
+
coinAddrNamesDict[addr] = "MKR";
|
|
205
|
+
coinAddrDecimalsDict[addr] = 18;
|
|
206
|
+
}
|
|
205
207
|
else {
|
|
206
208
|
newCoinAddresses.push(addr);
|
|
207
209
|
}
|
|
@@ -223,13 +225,15 @@ function getCoinsData(coinAddresses, existingCoinAddrNameDict, existingCoinAddrD
|
|
|
223
225
|
}
|
|
224
226
|
export function getFactoryPoolData() {
|
|
225
227
|
return __awaiter(this, arguments, void 0, function* (fromIdx = 0, swapAddress, factoryAddress = this.constants.ALIASES.factory) {
|
|
226
|
-
var _a, _b, _c;
|
|
228
|
+
var _a, _b, _c, _e;
|
|
227
229
|
const [rawPoolIds, rawSwapAddresses] = swapAddress ?
|
|
228
230
|
[[yield getRecentlyCreatedPoolId.call(this, swapAddress, factoryAddress)], [swapAddress.toLowerCase()]]
|
|
229
231
|
: yield getFactoryIdsAndSwapAddresses.call(this, fromIdx, factoryAddress);
|
|
230
232
|
if (rawPoolIds.length === 0)
|
|
231
233
|
return {};
|
|
232
234
|
const is_ng = factoryAddress === this.constants.ALIASES.stable_ng_factory;
|
|
235
|
+
const factory_type = factoryAddress === this.constants.ALIASES.crvusd_factory ? "factory-crvusd" :
|
|
236
|
+
is_ng ? "factory-stable-ng" : "factory";
|
|
233
237
|
const [rawImplementations, rawGauges, rawOldGauges, rawReferenceAssets, rawPoolSymbols, rawPoolNames, rawIsMeta, rawCoinAddresses] = yield getPoolsData.call(this, rawSwapAddresses, factoryAddress);
|
|
234
238
|
const poolIds = [];
|
|
235
239
|
const swapAddresses = [];
|
|
@@ -293,6 +297,7 @@ export function getFactoryPoolData() {
|
|
|
293
297
|
swap_abi: swapABIs[i],
|
|
294
298
|
gauge_abi: this.chainId === 1 ? factoryGaugeABI : gaugeChildABI,
|
|
295
299
|
is_ng,
|
|
300
|
+
factory_type,
|
|
296
301
|
};
|
|
297
302
|
}
|
|
298
303
|
else {
|
|
@@ -304,7 +309,7 @@ export function getFactoryPoolData() {
|
|
|
304
309
|
this.constants.BASE_POOLS[basePools.ids[i]] = this.constants.BASE_POOLS[basePools.ids[i]] ? this.constants.BASE_POOLS[basePools.ids[i]] + 1 : 1;
|
|
305
310
|
let deposit_address = (_c = this.constants.STABLE_FACTORY_CONSTANTS.stableNgBasePoolZap) !== null && _c !== void 0 ? _c : this.constants.ZERO_ADDRESS;
|
|
306
311
|
let deposit_abi = StableNgBasePoolZapABI;
|
|
307
|
-
if (
|
|
312
|
+
if ((_e = allPoolsData[basePools.ids[i]]) === null || _e === void 0 ? void 0 : _e.is_ng) {
|
|
308
313
|
this.setContract(deposit_address, StableNgBasePoolZapABI);
|
|
309
314
|
}
|
|
310
315
|
else {
|
|
@@ -334,6 +339,7 @@ export function getFactoryPoolData() {
|
|
|
334
339
|
gauge_abi: this.chainId === 1 ? factoryGaugeABI : gaugeChildABI,
|
|
335
340
|
deposit_abi,
|
|
336
341
|
is_ng,
|
|
342
|
+
factory_type,
|
|
337
343
|
};
|
|
338
344
|
}
|
|
339
345
|
}
|
package/lib/interfaces.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export interface IPoolData {
|
|
|
22
22
|
deposit_address?: string;
|
|
23
23
|
sCurveRewards_address?: string;
|
|
24
24
|
reward_contract?: string;
|
|
25
|
-
implementation_address?: string;
|
|
25
|
+
implementation_address?: string | null;
|
|
26
26
|
is_plain?: boolean;
|
|
27
27
|
is_lending?: boolean;
|
|
28
28
|
is_meta?: boolean;
|
|
@@ -31,6 +31,7 @@ export interface IPoolData {
|
|
|
31
31
|
is_factory?: boolean;
|
|
32
32
|
is_llamma?: boolean;
|
|
33
33
|
is_ng?: boolean;
|
|
34
|
+
factory_type?: IFactoryPoolType;
|
|
34
35
|
base_pool?: string;
|
|
35
36
|
meta_coin_idx?: number;
|
|
36
37
|
underlying_coins: string[];
|
|
@@ -130,7 +131,7 @@ export interface ICoinFromPoolDataApi {
|
|
|
130
131
|
address: string;
|
|
131
132
|
symbol: string;
|
|
132
133
|
decimals: string;
|
|
133
|
-
usdPrice: number | string;
|
|
134
|
+
usdPrice: number | string | null;
|
|
134
135
|
}
|
|
135
136
|
export interface IReward {
|
|
136
137
|
gaugeAddress: string;
|
|
@@ -151,14 +152,14 @@ export interface IPoolDataFromApi {
|
|
|
151
152
|
id: string;
|
|
152
153
|
name: string;
|
|
153
154
|
symbol: string;
|
|
154
|
-
assetTypeName: string;
|
|
155
|
+
assetTypeName: string | null;
|
|
155
156
|
address: string;
|
|
156
157
|
isMetaPool: boolean;
|
|
157
158
|
basePoolAddress?: string;
|
|
158
159
|
lpTokenAddress?: string;
|
|
159
160
|
gaugeAddress?: string;
|
|
160
|
-
implementation: string;
|
|
161
|
-
implementationAddress: string;
|
|
161
|
+
implementation: string | null;
|
|
162
|
+
implementationAddress: string | null;
|
|
162
163
|
coins: ICoinFromPoolDataApi[];
|
|
163
164
|
gaugeRewards: IRewardFromApi[];
|
|
164
165
|
gaugeExtraRewards?: IRewardFromApi[];
|
|
@@ -230,24 +231,6 @@ export interface IProfit {
|
|
|
230
231
|
symbol: string;
|
|
231
232
|
price: number;
|
|
232
233
|
}
|
|
233
|
-
export interface IGaugesDataFromApi {
|
|
234
|
-
blockchainId: string;
|
|
235
|
-
gauge: string;
|
|
236
|
-
rootGauge?: string;
|
|
237
|
-
swap: string;
|
|
238
|
-
swap_token: string;
|
|
239
|
-
shortName: string;
|
|
240
|
-
gauge_controller: {
|
|
241
|
-
gauge_relative_weight: string;
|
|
242
|
-
get_gauge_weight: string;
|
|
243
|
-
};
|
|
244
|
-
poolUrls?: {
|
|
245
|
-
swap: string[];
|
|
246
|
-
};
|
|
247
|
-
is_killed?: boolean;
|
|
248
|
-
hasNoCrv?: boolean;
|
|
249
|
-
gaugeStatus?: Record<string, boolean> | null;
|
|
250
|
-
}
|
|
251
234
|
export interface IVotingGauge {
|
|
252
235
|
poolUrl: string;
|
|
253
236
|
network: string;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ICurveLiteNetwork, IExtendedPoolDataFromApi, INetworkName, IPoolType } from "./interfaces";
|
|
2
|
+
export declare const getLiteNetworksFromApi2: () => Promise<ICurveLiteNetwork[]>;
|
|
3
|
+
export declare const getLitePoolsFromApi2: (network: INetworkName, poolType: IPoolType) => Promise<IExtendedPoolDataFromApi>;
|
|
4
|
+
export declare const getLiteDeploymentFromApi2: (chainId: number) => Promise<any>;
|
package/lib/lite-api.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import memoize from "memoizee";
|
|
11
|
+
const API2 = "https://api2.curve.finance";
|
|
12
|
+
function fetchJson(url) {
|
|
13
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
14
|
+
var _a;
|
|
15
|
+
const response = yield fetch(url);
|
|
16
|
+
return (_a = yield response.json()) !== null && _a !== void 0 ? _a : {};
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function fetchData(url) {
|
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
const { data } = yield fetchJson(url);
|
|
22
|
+
return data;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
const _getApi2Platforms = memoize(() => __awaiter(void 0, void 0, void 0, function* () { var _a; return (_a = yield fetchData(`${API2}/get_platforms`)) !== null && _a !== void 0 ? _a : { platforms: {}, platforms_metadata: {} }; }), {
|
|
26
|
+
promise: true,
|
|
27
|
+
maxAge: 5 * 60 * 1000,
|
|
28
|
+
});
|
|
29
|
+
export const getLiteNetworksFromApi2 = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
30
|
+
const { platforms, platforms_metadata } = yield _getApi2Platforms();
|
|
31
|
+
return Object.keys(platforms)
|
|
32
|
+
.map((id) => {
|
|
33
|
+
const meta = platforms_metadata[id];
|
|
34
|
+
return (meta === null || meta === void 0 ? void 0 : meta.name) && {
|
|
35
|
+
id,
|
|
36
|
+
name: meta.name,
|
|
37
|
+
rpcUrl: meta.rpc_url,
|
|
38
|
+
chainId: meta.chain_id,
|
|
39
|
+
explorerUrl: meta.explorer_base_url,
|
|
40
|
+
nativeCurrencySymbol: meta.native_currency_symbol,
|
|
41
|
+
isTestnet: !meta.is_mainnet,
|
|
42
|
+
};
|
|
43
|
+
})
|
|
44
|
+
.filter(Boolean);
|
|
45
|
+
});
|
|
46
|
+
const getChainIdByNetworkName = (network) => __awaiter(void 0, void 0, void 0, function* () {
|
|
47
|
+
var _a;
|
|
48
|
+
const { platforms_metadata } = yield _getApi2Platforms();
|
|
49
|
+
return (_a = platforms_metadata[network]) === null || _a === void 0 ? void 0 : _a.chain_id;
|
|
50
|
+
});
|
|
51
|
+
const API2_REGISTRY_TO_POOL_TYPE = {
|
|
52
|
+
factory_stable_ng: "factory-stable-ng",
|
|
53
|
+
factory_twocrypto: "factory-twocrypto",
|
|
54
|
+
factory_tricrypto: "factory-tricrypto",
|
|
55
|
+
// legacy registries — surfaced for api2-backed core chains (e.g. avalanche) whose
|
|
56
|
+
// data is not on prices.curve.finance. factory_v2 pools carry an implementation_address
|
|
57
|
+
// that is resolved against the chain's implementationABIDict, exactly like on prices/master.
|
|
58
|
+
// main & crypto are mapped only to feed the USD-price dict; those pools themselves are
|
|
59
|
+
// still built from static POOLS_DATA, not from the API.
|
|
60
|
+
factory_v2: "factory",
|
|
61
|
+
factory_crypto: "factory-crypto",
|
|
62
|
+
main: "main",
|
|
63
|
+
crypto: "crypto",
|
|
64
|
+
};
|
|
65
|
+
const _getApi2PoolsData = memoize((chainId) => __awaiter(void 0, void 0, void 0, function* () { var _a; return (_a = yield fetchData(`${API2}/get_pools/${chainId}`)) !== null && _a !== void 0 ? _a : { pool_data: [], tvl: 0 }; }), {
|
|
66
|
+
promise: true,
|
|
67
|
+
maxAge: 5 * 60 * 1000,
|
|
68
|
+
});
|
|
69
|
+
const adaptLitePool = (pool) => {
|
|
70
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
71
|
+
return ({
|
|
72
|
+
id: pool.address.toLowerCase(),
|
|
73
|
+
name: pool.name,
|
|
74
|
+
symbol: pool.symbol,
|
|
75
|
+
assetTypeName: null,
|
|
76
|
+
address: pool.address,
|
|
77
|
+
isMetaPool: pool.is_meta_pool,
|
|
78
|
+
basePoolAddress: (_a = pool.base_pool) !== null && _a !== void 0 ? _a : undefined,
|
|
79
|
+
lpTokenAddress: (_b = pool.lp_token_address) !== null && _b !== void 0 ? _b : undefined,
|
|
80
|
+
gaugeAddress: (_c = pool.gauge_address) !== null && _c !== void 0 ? _c : undefined,
|
|
81
|
+
implementation: null,
|
|
82
|
+
implementationAddress: pool.implementation_address,
|
|
83
|
+
coins: pool.coins.map((coin) => ({
|
|
84
|
+
address: coin.address,
|
|
85
|
+
symbol: coin.symbol,
|
|
86
|
+
decimals: coin.decimals,
|
|
87
|
+
usdPrice: coin.usd_price,
|
|
88
|
+
})),
|
|
89
|
+
gaugeRewards: [],
|
|
90
|
+
gaugeExtraRewards: ((_d = pool.gauge_extra_rewards) !== null && _d !== void 0 ? _d : []).map((reward) => {
|
|
91
|
+
var _a, _b;
|
|
92
|
+
return ({
|
|
93
|
+
gaugeAddress: reward.gauge_address,
|
|
94
|
+
tokenAddress: reward.token_address,
|
|
95
|
+
tokenPrice: (_a = reward.token_price) !== null && _a !== void 0 ? _a : 0,
|
|
96
|
+
name: reward.name,
|
|
97
|
+
symbol: reward.symbol,
|
|
98
|
+
decimals: reward.decimals,
|
|
99
|
+
apy: (_b = reward.apy) !== null && _b !== void 0 ? _b : 0,
|
|
100
|
+
});
|
|
101
|
+
}),
|
|
102
|
+
usdTotal: (_e = pool.tvl) !== null && _e !== void 0 ? _e : 0,
|
|
103
|
+
totalSupply: Number((_f = pool.total_supply) !== null && _f !== void 0 ? _f : 0),
|
|
104
|
+
amplificationCoefficient: pool.amplification_coefficient != null ? String(pool.amplification_coefficient) : "0",
|
|
105
|
+
gaugeCrvApy: (_g = pool.gauge_crv_apy) !== null && _g !== void 0 ? _g : [null, null],
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
export const getLitePoolsFromApi2 = (network, poolType) => __awaiter(void 0, void 0, void 0, function* () {
|
|
109
|
+
const chainId = yield getChainIdByNetworkName(network);
|
|
110
|
+
if (chainId == null)
|
|
111
|
+
return { poolData: [], tvl: 0, tvlAll: 0 };
|
|
112
|
+
const { pool_data, tvl } = yield _getApi2PoolsData(chainId);
|
|
113
|
+
const poolsOfType = (pool_data !== null && pool_data !== void 0 ? pool_data : []).filter((pool) => API2_REGISTRY_TO_POOL_TYPE[pool.registry_id] === poolType);
|
|
114
|
+
const poolData = poolsOfType.map((pool) => adaptLitePool(pool));
|
|
115
|
+
return {
|
|
116
|
+
poolData,
|
|
117
|
+
tvl: poolData.reduce((sum, p) => sum + p.usdTotal, 0),
|
|
118
|
+
tvlAll: tvl !== null && tvl !== void 0 ? tvl : 0,
|
|
119
|
+
};
|
|
120
|
+
});
|
|
121
|
+
export const getLiteDeploymentFromApi2 = (chainId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
122
|
+
var _a;
|
|
123
|
+
const response = yield fetch(`${API2}/get_deployment/${chainId}`);
|
|
124
|
+
const { data } = (_a = yield response.json()) !== null && _a !== void 0 ? _a : {};
|
|
125
|
+
if (response.status !== 200 || !data) {
|
|
126
|
+
console.error('Failed to fetch network data:', response.status, data);
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
return data;
|
|
130
|
+
});
|
|
@@ -7,7 +7,6 @@ import { StatsPool } from "./subClasses/statsPool.js";
|
|
|
7
7
|
import { WalletPool } from "./subClasses/walletPool.js";
|
|
8
8
|
export declare class PoolTemplate extends CorePool {
|
|
9
9
|
isGaugeKilled: () => Promise<boolean>;
|
|
10
|
-
gaugeStatus: () => Promise<any>;
|
|
11
10
|
estimateGas: {
|
|
12
11
|
depositApprove: (amounts: (number | string)[]) => Promise<number | number[]>;
|
|
13
12
|
deposit: (amounts: (number | string)[], slippage?: number) => Promise<number | number[]>;
|
|
@@ -216,6 +215,5 @@ export declare class PoolTemplate extends CorePool {
|
|
|
216
215
|
getStoredRates(useUnderlying?: boolean): Promise<string[]>;
|
|
217
216
|
_underlyingPrices: () => Promise<number[]>;
|
|
218
217
|
_wrappedPrices: () => Promise<number[]>;
|
|
219
|
-
private getGaugeStatus;
|
|
220
218
|
private getIsGaugeKilled;
|
|
221
219
|
}
|
|
@@ -8,7 +8,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import memoize from "memoizee";
|
|
11
|
-
import {
|
|
11
|
+
import { getGaugesOverview } from '../prices-api.js';
|
|
12
|
+
import { _getPoolFilters } from '../external-api.js';
|
|
12
13
|
import { _cutZeros, _ensureAllowance, _get_price_impact, _get_small_x, _getAddress, _getCoinAddresses, _getRewardsFromApi, _getUsdRate, _setContracts, BN, checkNumber, DIGas, ensureAllowance, ensureAllowanceEstimateGas, findAbiFunction, fromBN, hasAllowance, mulBy1_3, parseUnits, PERIODS, smartNumber, toBN, toStringFromBN, } from '../utils.js';
|
|
13
14
|
import { OLD_CHAINS } from "../curve.js";
|
|
14
15
|
import ERC20Abi from '../constants/abis/ERC20.json' with { type: 'json' };
|
|
@@ -549,7 +550,6 @@ export class PoolTemplate extends CorePool {
|
|
|
549
550
|
this.stats = new StatsPool(this);
|
|
550
551
|
this.wallet = new WalletPool(this);
|
|
551
552
|
this.isGaugeKilled = this.getIsGaugeKilled.bind(this);
|
|
552
|
-
this.gaugeStatus = this.getGaugeStatus.bind(this);
|
|
553
553
|
this.estimateGas = {
|
|
554
554
|
depositApprove: this.depositApproveEstimateGas.bind(this),
|
|
555
555
|
deposit: this.depositEstimateGas.bind(this),
|
|
@@ -757,7 +757,7 @@ export class PoolTemplate extends CorePool {
|
|
|
757
757
|
const multicallContract = this.curve.contracts[this.address].multicallContract;
|
|
758
758
|
if (this.isCrypto || this.id === 'wsteth') {
|
|
759
759
|
if (this.curve.isLiteChain) {
|
|
760
|
-
const prices = this.
|
|
760
|
+
const prices = this.factoryType === 'factory-twocrypto'
|
|
761
761
|
? [
|
|
762
762
|
1,
|
|
763
763
|
Number(yield this.curve.contracts[this.address].contract.price_oracle()) / (Math.pow(10, 18)),
|
|
@@ -1415,7 +1415,7 @@ export class PoolTemplate extends CorePool {
|
|
|
1415
1415
|
const multicallContract = this.curve.contracts[this.address].multicallContract;
|
|
1416
1416
|
if (this.isCrypto || this.id === 'wsteth') {
|
|
1417
1417
|
if (this.curve.isLiteChain) {
|
|
1418
|
-
const prices = this.
|
|
1418
|
+
const prices = this.factoryType === 'factory-twocrypto'
|
|
1419
1419
|
? [
|
|
1420
1420
|
1,
|
|
1421
1421
|
Number(yield this.curve.contracts[this.address].contract.price_oracle()) / (Math.pow(10, 18)),
|
|
@@ -1550,7 +1550,7 @@ export class PoolTemplate extends CorePool {
|
|
|
1550
1550
|
const multicallContract = this.curve.contracts[this.address].multicallContract;
|
|
1551
1551
|
if (this.isCrypto || this.id === 'wsteth') {
|
|
1552
1552
|
if (this.curve.isLiteChain) {
|
|
1553
|
-
const prices = this.
|
|
1553
|
+
const prices = this.factoryType === 'factory-twocrypto'
|
|
1554
1554
|
? [
|
|
1555
1555
|
1,
|
|
1556
1556
|
Number(yield this.curve.contracts[this.address].contract.price_oracle()) / (Math.pow(10, 18)),
|
|
@@ -2005,16 +2005,12 @@ export class PoolTemplate extends CorePool {
|
|
|
2005
2005
|
}
|
|
2006
2006
|
});
|
|
2007
2007
|
}
|
|
2008
|
-
getGaugeStatus() {
|
|
2009
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2010
|
-
const gaugeData = yield _getAllGaugesFormatted();
|
|
2011
|
-
return gaugeData[this.gauge.address] ? gaugeData[this.gauge.address].gaugeStatus : null;
|
|
2012
|
-
});
|
|
2013
|
-
}
|
|
2014
2008
|
getIsGaugeKilled() {
|
|
2015
2009
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2016
|
-
|
|
2017
|
-
|
|
2010
|
+
var _c;
|
|
2011
|
+
const gauges = yield getGaugesOverview();
|
|
2012
|
+
const gauge = gauges.find((g) => g.address.toLowerCase() === this.gauge.address.toLowerCase());
|
|
2013
|
+
return (_c = gauge === null || gauge === void 0 ? void 0 : gauge.is_killed) !== null && _c !== void 0 ? _c : false;
|
|
2018
2014
|
});
|
|
2019
2015
|
}
|
|
2020
2016
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Curve } from "../../curve.js";
|
|
2
2
|
import { IGaugePool } from "./gaugePool.js";
|
|
3
|
-
import { IPoolData } from "../../interfaces";
|
|
3
|
+
import { IFactoryPoolType, IPoolData } from "../../interfaces";
|
|
4
4
|
export interface ICorePool {
|
|
5
5
|
id: string;
|
|
6
6
|
name: string;
|
|
@@ -23,6 +23,7 @@ export interface ICorePool {
|
|
|
23
23
|
isMetaFactory: boolean;
|
|
24
24
|
isNg: boolean;
|
|
25
25
|
isLlamma: boolean;
|
|
26
|
+
factoryType: IFactoryPoolType | null;
|
|
26
27
|
basePool: string;
|
|
27
28
|
metaCoinIdx: number;
|
|
28
29
|
underlyingCoins: string[];
|
|
@@ -57,6 +58,7 @@ export declare class CorePool implements ICorePool {
|
|
|
57
58
|
isMetaFactory: boolean;
|
|
58
59
|
isNg: boolean;
|
|
59
60
|
isLlamma: boolean;
|
|
61
|
+
factoryType: IFactoryPoolType | null;
|
|
60
62
|
basePool: string;
|
|
61
63
|
metaCoinIdx: number;
|
|
62
64
|
underlyingCoins: string[];
|
|
@@ -27,6 +27,7 @@ export class CorePool {
|
|
|
27
27
|
this.isMetaFactory = (this.isMeta && this.isFactory) || this.zap === '0xa79828df1850e8a3a3064576f380d90aecdd3359';
|
|
28
28
|
this.isNg = poolData.is_ng || false;
|
|
29
29
|
this.isLlamma = poolData.is_llamma || false;
|
|
30
|
+
this.factoryType = poolData.factory_type || null;
|
|
30
31
|
this.basePool = poolData.base_pool || '';
|
|
31
32
|
this.metaCoinIdx = this.isMeta ? (_a = poolData.meta_coin_idx) !== null && _a !== void 0 ? _a : poolData.wrapped_coins.length - 1 : -1;
|
|
32
33
|
this.underlyingCoins = poolData.underlying_coins;
|
|
@@ -107,7 +107,7 @@ export class StatsPool {
|
|
|
107
107
|
return stablecoinTvlBN.plus(collateralTvlBN).toString();
|
|
108
108
|
}
|
|
109
109
|
if (useApi) {
|
|
110
|
-
const totalLiquidity = yield _getPoolTotalLiquidityFromApi(curve.constants.NETWORK_NAME, this.pool.
|
|
110
|
+
const totalLiquidity = yield _getPoolTotalLiquidityFromApi(curve.constants.NETWORK_NAME, this.pool.address, curve.isLiteChain);
|
|
111
111
|
if (totalLiquidity !== undefined)
|
|
112
112
|
return totalLiquidity;
|
|
113
113
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { IExtendedPoolDataFromApi, IPoolType, INetworkName, IVolumeAndAPYs } from "./interfaces";
|
|
2
|
+
export type TPricesPoolType = "main" | "crypto" | "factory" | "crvusd" | "factory_crypto" | "factory_tricrypto" | "stableswapng" | "twocryptong" | null;
|
|
3
|
+
export declare const LEGACY_POOL_TYPES: readonly IPoolType[];
|
|
4
|
+
export declare const PRICES_POOL_TYPE_TO_LEGACY: Record<NonNullable<TPricesPoolType>, IPoolType>;
|
|
5
|
+
export interface IPricesGauge {
|
|
6
|
+
address: string;
|
|
7
|
+
effective_address: string;
|
|
8
|
+
name: string;
|
|
9
|
+
lp_token: string;
|
|
10
|
+
pool: {
|
|
11
|
+
address: string;
|
|
12
|
+
name: string;
|
|
13
|
+
chain: string;
|
|
14
|
+
} | null;
|
|
15
|
+
is_killed: boolean;
|
|
16
|
+
gauge_weight: string;
|
|
17
|
+
gauge_relative_weight: number;
|
|
18
|
+
}
|
|
19
|
+
export declare const getGaugesOverview: () => Promise<IPricesGauge[]>;
|
|
20
|
+
export declare const getPoolsFromPricesApi: (network: INetworkName, poolType: IPoolType) => Promise<IExtendedPoolDataFromApi>;
|
|
21
|
+
export declare const getVolumesFromPricesApi: (network: INetworkName) => Promise<IVolumeAndAPYs>;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import memoize from "memoizee";
|
|
11
|
+
export const LEGACY_POOL_TYPES = [
|
|
12
|
+
"main",
|
|
13
|
+
"crypto",
|
|
14
|
+
"factory",
|
|
15
|
+
"factory-crvusd",
|
|
16
|
+
"factory-crypto",
|
|
17
|
+
"factory-twocrypto",
|
|
18
|
+
"factory-tricrypto",
|
|
19
|
+
"factory-stable-ng",
|
|
20
|
+
];
|
|
21
|
+
export const PRICES_POOL_TYPE_TO_LEGACY = {
|
|
22
|
+
main: "main",
|
|
23
|
+
crypto: "crypto",
|
|
24
|
+
factory: "factory",
|
|
25
|
+
crvusd: "factory-crvusd",
|
|
26
|
+
factory_crypto: "factory-crypto",
|
|
27
|
+
factory_tricrypto: "factory-tricrypto",
|
|
28
|
+
stableswapng: "factory-stable-ng",
|
|
29
|
+
twocryptong: "factory-twocrypto",
|
|
30
|
+
};
|
|
31
|
+
function fetchJson(url) {
|
|
32
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
33
|
+
var _a;
|
|
34
|
+
const response = yield fetch(url);
|
|
35
|
+
return (_a = yield response.json()) !== null && _a !== void 0 ? _a : {};
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
const _getPricesChainData = memoize((network) => __awaiter(void 0, void 0, void 0, function* () { return fetchJson(`https://prices.curve.finance/v1/chains/${network}`); }), {
|
|
39
|
+
promise: true,
|
|
40
|
+
maxAge: 5 * 60 * 1000,
|
|
41
|
+
});
|
|
42
|
+
const _getGaugesOverview = memoize(() => __awaiter(void 0, void 0, void 0, function* () { return fetchJson(`https://prices.curve.finance/v1/dao/gauges/overview`); }), {
|
|
43
|
+
promise: true,
|
|
44
|
+
maxAge: 5 * 60 * 1000,
|
|
45
|
+
});
|
|
46
|
+
const getGaugeAddressByPoolAddress = (network) => __awaiter(void 0, void 0, void 0, function* () {
|
|
47
|
+
var _a;
|
|
48
|
+
const { gauges } = yield _getGaugesOverview();
|
|
49
|
+
const map = new Map();
|
|
50
|
+
for (const gauge of gauges !== null && gauges !== void 0 ? gauges : []) {
|
|
51
|
+
if (((_a = gauge.pool) === null || _a === void 0 ? void 0 : _a.chain) === network)
|
|
52
|
+
map.set(gauge.pool.address.toLowerCase(), gauge.address.toLowerCase());
|
|
53
|
+
}
|
|
54
|
+
return map;
|
|
55
|
+
});
|
|
56
|
+
export const getGaugesOverview = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
57
|
+
const { gauges } = yield _getGaugesOverview();
|
|
58
|
+
return gauges !== null && gauges !== void 0 ? gauges : [];
|
|
59
|
+
});
|
|
60
|
+
const adaptPoolFromPricesApi = (pool, gaugeAddressByPoolAddress) => {
|
|
61
|
+
var _a, _b, _c, _d, _e;
|
|
62
|
+
const coins = [...pool.coins].sort((a, b) => a.pool_index - b.pool_index).slice(0, pool.n_coins);
|
|
63
|
+
return {
|
|
64
|
+
id: pool.address.toLowerCase(),
|
|
65
|
+
name: pool.name,
|
|
66
|
+
symbol: (_a = pool.lp_token_symbol) !== null && _a !== void 0 ? _a : pool.name,
|
|
67
|
+
assetTypeName: null,
|
|
68
|
+
address: pool.address,
|
|
69
|
+
isMetaPool: pool.is_metapool,
|
|
70
|
+
basePoolAddress: (_b = pool.base_pool) !== null && _b !== void 0 ? _b : undefined,
|
|
71
|
+
lpTokenAddress: (_c = pool.lp_token_address) !== null && _c !== void 0 ? _c : undefined,
|
|
72
|
+
gaugeAddress: gaugeAddressByPoolAddress.get(pool.address.toLowerCase()),
|
|
73
|
+
implementation: null,
|
|
74
|
+
implementationAddress: pool.implementation_address,
|
|
75
|
+
coins: coins.map((coin) => {
|
|
76
|
+
var _a, _b;
|
|
77
|
+
const balance = (_a = pool.balances) === null || _a === void 0 ? void 0 : _a[coin.pool_index];
|
|
78
|
+
const balanceUsd = (_b = pool.balances_usd) === null || _b === void 0 ? void 0 : _b[coin.pool_index];
|
|
79
|
+
return {
|
|
80
|
+
address: coin.address,
|
|
81
|
+
symbol: coin.symbol,
|
|
82
|
+
decimals: String(coin.decimals),
|
|
83
|
+
usdPrice: balance ? (balanceUsd !== null && balanceUsd !== void 0 ? balanceUsd : 0) / balance : null,
|
|
84
|
+
};
|
|
85
|
+
}),
|
|
86
|
+
gaugeRewards: [],
|
|
87
|
+
gaugeExtraRewards: undefined,
|
|
88
|
+
usdTotal: (_d = pool.tvl_usd) !== null && _d !== void 0 ? _d : 0,
|
|
89
|
+
totalSupply: ((_e = pool.lp_token_supply) !== null && _e !== void 0 ? _e : 0) * 1e18,
|
|
90
|
+
amplificationCoefficient: pool.amplification_coefficient != null ? String(pool.amplification_coefficient) : "0",
|
|
91
|
+
gaugeCrvApy: [null, null],
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
export const getPoolsFromPricesApi = (network, poolType) => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
|
+
var _a, _b;
|
|
96
|
+
const [chainData, gaugeAddressByPoolAddress] = yield Promise.all([
|
|
97
|
+
_getPricesChainData(network),
|
|
98
|
+
getGaugeAddressByPoolAddress(network),
|
|
99
|
+
]);
|
|
100
|
+
if (!(chainData === null || chainData === void 0 ? void 0 : chainData.data))
|
|
101
|
+
return { poolData: [], tvl: 0, tvlAll: 0 };
|
|
102
|
+
const poolsOfType = chainData.data
|
|
103
|
+
.filter((pool) => PRICES_POOL_TYPE_TO_LEGACY[pool.pool_type] === poolType)
|
|
104
|
+
.sort((a, b) => a.creation_block_number - b.creation_block_number);
|
|
105
|
+
const poolData = poolsOfType.map((pool) => adaptPoolFromPricesApi(pool, gaugeAddressByPoolAddress));
|
|
106
|
+
return {
|
|
107
|
+
poolData,
|
|
108
|
+
tvl: poolData.reduce((sum, p) => sum + p.usdTotal, 0),
|
|
109
|
+
tvlAll: (_b = (_a = chainData.total) === null || _a === void 0 ? void 0 : _a.total_tvl) !== null && _b !== void 0 ? _b : 0,
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
const CRYPTO_POOL_TYPES = ["crypto", "factory_crypto", "factory_tricrypto", "twocryptong"];
|
|
113
|
+
export const getVolumesFromPricesApi = (network) => __awaiter(void 0, void 0, void 0, function* () {
|
|
114
|
+
const chainData = yield _getPricesChainData(network);
|
|
115
|
+
if (!(chainData === null || chainData === void 0 ? void 0 : chainData.data))
|
|
116
|
+
return { poolsData: [], totalVolume: 0, cryptoVolume: 0, cryptoShare: 0 };
|
|
117
|
+
let totalVolume = 0;
|
|
118
|
+
let cryptoVolume = 0;
|
|
119
|
+
const poolsData = chainData.data.map((pool) => {
|
|
120
|
+
var _a, _b, _c;
|
|
121
|
+
const volumeUSD = (_a = pool.trading_volume_24h) !== null && _a !== void 0 ? _a : 0;
|
|
122
|
+
totalVolume += volumeUSD;
|
|
123
|
+
if (CRYPTO_POOL_TYPES.includes(pool.pool_type))
|
|
124
|
+
cryptoVolume += volumeUSD;
|
|
125
|
+
return {
|
|
126
|
+
address: pool.address,
|
|
127
|
+
volumeUSD,
|
|
128
|
+
day: ((_b = pool.base_daily_apr) !== null && _b !== void 0 ? _b : 0) * 100,
|
|
129
|
+
week: ((_c = pool.base_weekly_apr) !== null && _c !== void 0 ? _c : 0) * 100,
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
return {
|
|
133
|
+
poolsData,
|
|
134
|
+
totalVolume,
|
|
135
|
+
cryptoVolume,
|
|
136
|
+
cryptoShare: totalVolume ? (cryptoVolume / totalVolume) * 100 : 0,
|
|
137
|
+
};
|
|
138
|
+
});
|
package/lib/router.js
CHANGED
|
@@ -27,10 +27,10 @@ export function setRouterBlacklist(blacklist) {
|
|
|
27
27
|
delete this._getBestRoute;
|
|
28
28
|
}
|
|
29
29
|
function _getTVL(poolId_1, _a) {
|
|
30
|
-
return __awaiter(this, arguments, void 0, function* (poolId, {
|
|
30
|
+
return __awaiter(this, arguments, void 0, function* (poolId, { is_llamma, swap_address }) {
|
|
31
31
|
// LLAMMA liquidity must be calculated on-chain, even when the API has an entry.
|
|
32
32
|
if (!is_llamma) {
|
|
33
|
-
const totalLiquidity = yield _getPoolTotalLiquidityFromApi(this.constants.NETWORK_NAME,
|
|
33
|
+
const totalLiquidity = yield _getPoolTotalLiquidityFromApi(this.constants.NETWORK_NAME, swap_address, this.isLiteChain);
|
|
34
34
|
if (totalLiquidity !== undefined)
|
|
35
35
|
return Number(totalLiquidity);
|
|
36
36
|
}
|
|
@@ -237,7 +237,7 @@ function _getBestRouteImpl(inputCoinAddress, outputCoinAddress, amount) {
|
|
|
237
237
|
const [gasAmounts, outputCoinUsdRate, gasData, ethUsdRate] = yield Promise.all([
|
|
238
238
|
_estimateGasForDifferentRoutes.call(this, routes.map((r) => r.route), inputCoinAddress, outputCoinAddress, _amount),
|
|
239
239
|
_getUsdRate.call(this, outputCoinAddress),
|
|
240
|
-
fetch("https://
|
|
240
|
+
fetch("https://prices.curve.finance/v1/gas").then((res) => res.json()),
|
|
241
241
|
_getUsdRate.call(this, ETH_ADDRESS),
|
|
242
242
|
]);
|
|
243
243
|
const gasPrice = gasData.data.gas.standard;
|
package/lib/utils.d.ts
CHANGED
|
@@ -102,8 +102,7 @@ export declare const findAbiFunction: (abi: Abi, methodName: string) => AbiFunct
|
|
|
102
102
|
export declare const getCountArgsOfMethodByAbi: (abi: Abi, methodName: string) => number;
|
|
103
103
|
export declare const findAbiSignature: (abi: Abi, methodName: string, signature: string) => AbiFunction | undefined;
|
|
104
104
|
export declare const getPoolName: (name: string) => string;
|
|
105
|
-
export declare const
|
|
106
|
-
export declare const assetTypeNameHandler: (assetTypeName: string) => REFERENCE_ASSET;
|
|
105
|
+
export declare const assetTypeNameHandler: (assetTypeName: string | null) => REFERENCE_ASSET;
|
|
107
106
|
export declare function getBasePools(this: Curve): Promise<IBasePoolShortItem[]>;
|
|
108
107
|
export declare function log(fnName: string, ...args: unknown[]): void;
|
|
109
108
|
export declare function runWorker<In extends {
|
package/lib/utils.js
CHANGED
|
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { Contract, ethers } from 'ethers';
|
|
11
11
|
import { Contract as MulticallContract } from "@curvefi/ethcall";
|
|
12
12
|
import BigNumber from 'bignumber.js';
|
|
13
|
-
import { _getCurveLiteNetworks,
|
|
13
|
+
import { _getCurveLiteNetworks, _getLiteNetworksData, _getVolumes, } from "./external-api.js";
|
|
14
14
|
import { _getAllPoolsFromApi, _getUsdPricesFromApi } from "./cached.js";
|
|
15
15
|
import ERC20Abi from './constants/abis/ERC20.json' with { type: 'json' };
|
|
16
16
|
import { L2Networks } from './constants/L2Networks.js';
|
|
@@ -664,7 +664,7 @@ export function getNetworkConstants(chainId) {
|
|
|
664
664
|
const NAME = getNetworkNameByChainId(chainId, yield _getCurveLiteNetworks());
|
|
665
665
|
if (NAME === "Unknown Network")
|
|
666
666
|
throw Error(`Wrong chain id: ${chainId}`);
|
|
667
|
-
return Object.assign(Object.assign({}, yield _getLiteNetworksData(
|
|
667
|
+
return Object.assign(Object.assign({}, yield _getLiteNetworksData(chainId)), { NAME, IS_LITE_CHAIN: true });
|
|
668
668
|
}
|
|
669
669
|
});
|
|
670
670
|
}
|
|
@@ -683,12 +683,6 @@ export function getVolumeApiController(network) {
|
|
|
683
683
|
if (volumeNetworks.getVolumes.includes(this.chainId)) {
|
|
684
684
|
return yield _getVolumes(network);
|
|
685
685
|
}
|
|
686
|
-
if (volumeNetworks.getFactoryAPYs.includes(this.chainId)) {
|
|
687
|
-
return yield _getFactoryAPYs(network);
|
|
688
|
-
}
|
|
689
|
-
if (volumeNetworks.getSubgraphData.includes(this.chainId)) {
|
|
690
|
-
return yield _getSubgraphData(network);
|
|
691
|
-
}
|
|
692
686
|
throw Error(`Can't get volume for network: ${network}`);
|
|
693
687
|
});
|
|
694
688
|
}
|
|
@@ -785,9 +779,8 @@ export const getPoolName = (name) => {
|
|
|
785
779
|
return separatedName[0].trim();
|
|
786
780
|
}
|
|
787
781
|
};
|
|
788
|
-
export const isStableNgPool = (name) => name.includes('factory-stable-ng');
|
|
789
782
|
export const assetTypeNameHandler = (assetTypeName) => {
|
|
790
|
-
if (assetTypeName.toUpperCase() === 'UNKNOWN') {
|
|
783
|
+
if (!assetTypeName || assetTypeName.toUpperCase() === 'UNKNOWN') {
|
|
791
784
|
return 'OTHER';
|
|
792
785
|
}
|
|
793
786
|
else {
|