@aurigami/sdk 1.19.0 → 1.19.2

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.
@@ -178,3 +178,23 @@ export declare type UserNotification = {
178
178
  liquidation: boolean;
179
179
  }[];
180
180
  };
181
+ export declare type UserLiquidationHistorySubgraph = {
182
+ liquidationEvents: LiquidationEventSubgraph[];
183
+ };
184
+ export declare type LiquidationEventSubgraph = {
185
+ auTokenSymbol: string;
186
+ amount: number;
187
+ blockTime: number;
188
+ from: string;
189
+ id: string;
190
+ underlyingRepayAmount: number;
191
+ underlyingRepayAmountUSD: number;
192
+ underlyingSymbol: string;
193
+ };
194
+ export declare type LiquidationDetail = {
195
+ liquidationTime: Timestamp;
196
+ tokenAmount: TokenAmount;
197
+ value: CurrencyAmount;
198
+ transactionId: string;
199
+ };
200
+ export declare type Timestamp = number;
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.19.0",
2
+ "version": "1.19.2",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
package/src/SDK.ts CHANGED
@@ -1,11 +1,18 @@
1
1
  import { TransactionResponse } from '@ethersproject/abstract-provider';
2
2
  import BigNumber from 'bignumber.js';
3
- import { ALL_STAKING_POOLS, SD_INCENTIVE_IN_SD } from './consts';
3
+ import {
4
+ ALL_STAKING_POOLS,
5
+ AURIGAMI_SUBGRAPH_URL,
6
+ SD_INCENTIVE_IN_SD,
7
+ networkAddresses,
8
+ } from './consts';
4
9
  import { AuriEnv, BlockchainEntity, BlockchainEntityRead, Token, TokenAmount } from './entities';
5
10
  import { MiscRead, StakingRead, StakingReadWrite } from './interactors';
6
11
  import * as types from './types';
7
12
  import * as NotificationApi from './helpers/notification-api';
8
13
  import { BigNumber as BN } from 'ethers';
14
+ import { getDecimal, queryGraphQL } from './helpers';
15
+ import { getLiquidationEventsQuery } from './helpers/subgraphQuery';
9
16
 
10
17
  export class SdkRead extends BlockchainEntityRead {
11
18
  protected env: AuriEnv;
@@ -94,14 +101,16 @@ export class SdkRead extends BlockchainEntityRead {
94
101
  return this._misc.sneakAccounts(accounts, tokenAddresses, dust);
95
102
  }
96
103
 
104
+ public async getLTVAndLiquidationThreshold(userAddr: types.Address) {
105
+ return this._misc.getLTVAndLiquidationThreshold(userAddr);
106
+ }
107
+
97
108
  public async getNetApyWithoutIncentive(userAddress: types.Address): Promise<BigNumber> {
98
- const miscRead = new MiscRead(this._networkConnection);
99
- return miscRead.getNetApyWithoutIncentive(userAddress);
109
+ return this._misc.getNetApyWithoutIncentive(userAddress);
100
110
  }
101
111
 
102
112
  public async getNetApyWithIncentive(userAddress: types.Address): Promise<BigNumber> {
103
- const miscRead = new MiscRead(this._networkConnection);
104
- return miscRead.getNetApyWithIncentive(userAddress);
113
+ return this._misc.getNetApyWithIncentive(userAddress);
105
114
  }
106
115
 
107
116
  public async setUserNotificationSettings(
@@ -147,6 +156,36 @@ export class SdkRead extends BlockchainEntityRead {
147
156
  const response = await NotificationApi.postApi('alert-setting/get-user-setting', body);
148
157
  return response;
149
158
  }
159
+
160
+ public async getLiquidationHistory(address: string): Promise<types.LiquidationDetail[]> {
161
+ const liquidationHistorySubgraph = (await queryGraphQL(
162
+ getLiquidationEventsQuery(address, 100),
163
+ AURIGAMI_SUBGRAPH_URL
164
+ )) as types.UserLiquidationHistorySubgraph;
165
+ const liquidationEvents = liquidationHistorySubgraph.liquidationEvents.map((event) => {
166
+ const value: types.CurrencyAmount = {
167
+ amount: event.underlyingRepayAmountUSD.toString(),
168
+ currency: 'USD',
169
+ };
170
+ const underlyingAddress = networkAddresses.auTokens.find(
171
+ (auToken) => auToken.name.slice(2).toLowerCase() === event.underlyingSymbol.toLowerCase()
172
+ )!.underlying;
173
+ const decimal = getDecimal(underlyingAddress);
174
+ const token = new Token(underlyingAddress, decimal);
175
+ const tokenAmount = new TokenAmount(token, event.underlyingRepayAmount.toString(), false);
176
+ return {
177
+ liquidationTime: event.blockTime,
178
+ tokenAmount,
179
+ value,
180
+ transactionId: event.id.split('-')[0],
181
+ };
182
+ }) as types.LiquidationDetail[];
183
+ return liquidationEvents;
184
+ }
185
+
186
+ public calculateBorrowPower(tokenAmount: TokenAmount): Promise<types.CurrencyAmount> {
187
+ return this._misc.calcBorrowPower(tokenAmount);
188
+ }
150
189
  }
151
190
 
152
191
  export class SdkReadWrite extends SdkRead {
@@ -190,3 +190,8 @@ export const SD_INCENTIVE_IN_SD = 83.35;
190
190
  export const STADER_ETH = '0x30D20208d987713f46DFD34EF128Bb16C404D10f'.toLowerCase();
191
191
 
192
192
  export const USDT_ETH = '0xdAC17F958D2ee523a2206206994597C13D831ec7'.toLowerCase();
193
+
194
+ export const AURIGAMI_SUBGRAPH_URL =
195
+ 'https://api.thegraph.com/subgraphs/name/takao-aurigami/aurigami-feb-27';
196
+
197
+ export const GRAPHQL_URL = 'https://explorer.mainnet.aurora.dev/graphiql';
@@ -1,9 +1,7 @@
1
1
  import axios from 'axios';
2
2
 
3
- const GRAPHQL_URL = 'https://explorer.mainnet.aurora.dev/graphiql';
4
-
5
- export async function queryGraphQL(query: string): Promise<any> {
6
- let resp = await axios.post(GRAPHQL_URL, {
3
+ export async function queryGraphQL(query: string, graphqlUrl: string): Promise<any> {
4
+ let resp = await axios.post(graphqlUrl, {
7
5
  query: query,
8
6
  });
9
7
  return resp.data.data!;
@@ -3,7 +3,7 @@ import { Provider } from '@ethersproject/abstract-provider';
3
3
  import BigNumber from 'bignumber.js';
4
4
  import { BigNumber as BN, utils } from 'ethers';
5
5
  import { Result } from 'ethers/lib/utils';
6
- import { CACHE_TIMEOUT, networkAddresses } from '../consts/constants';
6
+ import { CACHE_TIMEOUT, GRAPHQL_URL, networkAddresses } from '../consts/constants';
7
7
  import { decimalRecords } from '../consts/decimals';
8
8
  import { symbolRecords } from '../consts/symbols';
9
9
  import { Address } from '../types';
@@ -129,7 +129,7 @@ export async function getBlocksTimestamp(
129
129
 
130
130
  for (let i = 0; i < lines.length; i += CHUNK_SIZE) {
131
131
  let query = `{ ${lines.slice(i, i + CHUNK_SIZE).join('\n')} }`;
132
- promises.push(queryGraphQL(query));
132
+ promises.push(queryGraphQL(query, GRAPHQL_URL));
133
133
  }
134
134
 
135
135
  // merge all the json objects
@@ -0,0 +1,17 @@
1
+ export function getLiquidationEventsQuery(address: string, limit: number) {
2
+ return `{
3
+ liquidationEvents(
4
+ first: ${limit},
5
+ where: {from: "${address.toLowerCase()}"}
6
+ ) {
7
+ amount
8
+ auTokenSymbol
9
+ blockTime
10
+ from
11
+ id
12
+ underlyingRepayAmountUSD
13
+ underlyingSymbol
14
+ underlyingRepayAmount
15
+ }
16
+ }`;
17
+ }
@@ -326,6 +326,20 @@ export class MoneyMarketRead extends BlockchainEntityRead {
326
326
  );
327
327
  }
328
328
 
329
+ public async getDepositBorrowValue(userAddress: Address) {
330
+ const [price, depositBalance, borrowBalance] = await Promise.all([
331
+ this.getUnderlyingPrice(),
332
+ this.getUserDepositBalance(userAddress),
333
+ this.getUserBorrowBalance(userAddress),
334
+ ]);
335
+ const suppliedValue = price.multipliedBy(depositBalance.formattedAmount());
336
+ const borrowedValue = price.multipliedBy(borrowBalance.formattedAmount());
337
+ return {
338
+ suppliedValue,
339
+ borrowedValue,
340
+ };
341
+ }
342
+
329
343
  public async getApyWithoutIncentive(userAddress: Address): Promise<Apy> {
330
344
  const [price, depositApy, borrowApy, depositBalance, borrowBalance] = await Promise.all([
331
345
  this.getUnderlyingPrice(),
@@ -145,6 +145,29 @@ export class MiscRead extends BlockchainEntityRead {
145
145
  };
146
146
  }
147
147
 
148
+ public async calcBorrowPower(tokenAmount: TokenAmount) {
149
+ const autoken = consts.networkAddresses.auTokens.find((auToken) =>
150
+ isSameAddress(auToken.underlying, tokenAmount.token.address)
151
+ )!;
152
+ const moneyMarket: MoneyMarketRead = new MoneyMarketRead(
153
+ this._networkConnection,
154
+ autoken.address,
155
+ autoken.underlying
156
+ );
157
+ const collateralRatio = await moneyMarket.getCollateralRatio();
158
+ const underlyingPrice = await fetchPrice(
159
+ tokenAmount.token.address,
160
+ this._networkConnection.provider
161
+ );
162
+ const borrowPower = calcValuation(tokenAmount!, new BigNumber(underlyingPrice))
163
+ .multipliedBy(collateralRatio)
164
+ .multipliedBy(consts.BORROW_LIMIT_BUFFER);
165
+ return {
166
+ currency: 'USD',
167
+ amount: borrowPower.toFixed(consts.DECIMAL_PRECISION),
168
+ };
169
+ }
170
+
148
171
  public calcHypotheticalStats({
149
172
  userMarketDetail,
150
173
  currentBorrowLimit,
@@ -309,6 +332,47 @@ export class MiscRead extends BlockchainEntityRead {
309
332
  return res;
310
333
  }
311
334
 
335
+ public async getLTVAndLiquidationThreshold(userAddr: types.Address) {
336
+ let totalSuppliedValue = new BigNumber(0);
337
+ let totalBorrowedValue = new BigNumber(0);
338
+ let collateralValue = new BigNumber(0);
339
+ const assetsIn = await this.env.comptroller.getAssetsIn(userAddr);
340
+ const marketValues = await Promise.all(
341
+ consts.networkAddresses.auTokens.map(async (auToken) => {
342
+ const moneyMarket: MoneyMarketRead = new MoneyMarketRead(
343
+ this._networkConnection,
344
+ auToken.address,
345
+ auToken.underlying
346
+ );
347
+ return Promise.all([
348
+ moneyMarket.getCollateralRatio(),
349
+ moneyMarket.getDepositBorrowValue(userAddr),
350
+ ]);
351
+ })
352
+ );
353
+ consts.networkAddresses.auTokens.forEach(async (auToken, i) => {});
354
+ for (var i = 0; i < marketValues.length; i++) {
355
+ const auToken = consts.networkAddresses.auTokens[i];
356
+ const [collateralRatio, depositBorrowValue] = marketValues[i];
357
+ if (
358
+ assetsIn!.find((auAddress: types.Address) => isSameAddress(auToken.address, auAddress)) !==
359
+ undefined
360
+ ) {
361
+ totalSuppliedValue = totalSuppliedValue.plus(depositBorrowValue.suppliedValue);
362
+ collateralValue = collateralValue.plus(
363
+ depositBorrowValue.suppliedValue.times(collateralRatio)
364
+ );
365
+ }
366
+ totalBorrowedValue = totalBorrowedValue.plus(depositBorrowValue.borrowedValue);
367
+ }
368
+ const ltv = totalBorrowedValue.div(totalSuppliedValue);
369
+ const liquidationThreshold = collateralValue.div(totalSuppliedValue);
370
+ return {
371
+ ltv,
372
+ liquidationThreshold,
373
+ };
374
+ }
375
+
312
376
  public async getNetApyWithoutIncentive(userAddress: types.Address): Promise<BigNumber> {
313
377
  let sum = new BigNumber(0);
314
378
  let totalSuppliedValue = new BigNumber(0);
@@ -200,3 +200,27 @@ export type UserNotification = {
200
200
  liquidation: boolean;
201
201
  }[];
202
202
  };
203
+
204
+ export type UserLiquidationHistorySubgraph = {
205
+ liquidationEvents: LiquidationEventSubgraph[];
206
+ };
207
+
208
+ export type LiquidationEventSubgraph = {
209
+ auTokenSymbol: string;
210
+ amount: number;
211
+ blockTime: number;
212
+ from: string;
213
+ id: string;
214
+ underlyingRepayAmount: number;
215
+ underlyingRepayAmountUSD: number;
216
+ underlyingSymbol: string;
217
+ };
218
+
219
+ export type LiquidationDetail = {
220
+ liquidationTime: Timestamp;
221
+ tokenAmount: TokenAmount;
222
+ value: CurrencyAmount;
223
+ transactionId: string;
224
+ };
225
+
226
+ export type Timestamp = number;