@1delta/margin-fetcher 0.0.28 → 0.0.30
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/lending/user-data/aave-v2-type/userCallParse.d.ts.map +1 -1
- package/dist/lending/user-data/aave-v2-type/userCallParse.js +2 -3
- package/dist/lending/user-data/compound-v3/userCallParse.d.ts.map +1 -1
- package/dist/lending/user-data/compound-v3/userCallParse.js +1 -2
- package/dist/lending/user-data/fetchUserData.d.ts.map +1 -1
- package/dist/lending/user-data/morpho/userCallParse.d.ts.map +1 -1
- package/dist/lending/user-data/morpho/userCallParse.js +43 -34
- package/dist/prices/defillama/index.d.ts.map +1 -1
- package/dist/prices/defillama/index.js +28 -7
- package/dist/prices/main-prices/addresses/morpho.d.ts.map +1 -1
- package/dist/prices/main-prices/addresses/morpho.js +353 -325
- package/dist/prices/main-prices/fetchOracleData.js +4 -2
- package/dist/yields/index.d.ts.map +1 -1
- package/dist/yields/index.js +57 -8
- package/package.json +2 -2
- package/src/lending/user-data/aave-v2-type/userCallParse.ts +2 -3
- package/src/lending/user-data/compound-v3/userCallParse.ts +1 -2
- package/src/lending/user-data/fetchUserData.ts +1 -0
- package/src/lending/user-data/morpho/userCallParse.ts +65 -51
- package/src/prices/defillama/index.ts +29 -8
- package/src/prices/main-prices/addresses/morpho.ts +353 -325
- package/src/prices/main-prices/fetchOracleData.ts +5 -2
- package/src/yields/index.ts +67 -7
- package/test/mainPriceMB.test.ts +1 -2
- package/test/mainPrices.test.ts +1 -1
- package/test/morphoPrice.test.ts +1 -1
- package/test/userDataAll.test.ts +1 -4
- package/test/userDataMorpho.test.ts +1 -1
- package/test/userDataMorphoEthereum.test.ts +77 -0
- package/test/userDataMorphoKatana.test.ts +75 -0
|
@@ -439,11 +439,14 @@ const parseMorphoResults = (
|
|
|
439
439
|
|
|
440
440
|
const oracleId =
|
|
441
441
|
ASSET_META[chainId][loanAsset]?.assetGroup ?? chainId + '-' + loanAsset
|
|
442
|
-
|
|
442
|
+
// get price from map or just computed ones
|
|
443
|
+
const debtPrice = donePrices[oracleId] ?? prices[oracleId]
|
|
443
444
|
const oracleIdCollateral =
|
|
444
445
|
ASSET_META[chainId][collateralAsset]?.assetGroup ??
|
|
445
446
|
chainId + '-' + collateralAsset
|
|
446
|
-
|
|
447
|
+
// get price from map or just computed ones
|
|
448
|
+
const collateralPrice =
|
|
449
|
+
donePrices[oracleIdCollateral] ?? prices[oracleIdCollateral]
|
|
447
450
|
const priceDebtToCollateral = formatMorphoPrice(
|
|
448
451
|
d.toString(),
|
|
449
452
|
loanAssetDecimals,
|
package/src/yields/index.ts
CHANGED
|
@@ -10,8 +10,8 @@ const osETH = 'StakeWise Staked ETH::OSETH'
|
|
|
10
10
|
// const ethPlus = 'ETHPlus::ETH+'
|
|
11
11
|
const ethX = 'Stader ETHx::ETHx'
|
|
12
12
|
const pufEth = 'PUFETH'
|
|
13
|
-
const stUSD = 'Angle Staked USDA::
|
|
14
|
-
const stEur = 'Angle Staked EURA::
|
|
13
|
+
const stUSD = 'Angle Staked USDA::stUSD'
|
|
14
|
+
const stEur = 'Angle Staked EURA::stEUR'
|
|
15
15
|
const sUsds = 'sUSDS::SUSDS'
|
|
16
16
|
const srUsd = 'Reservoir srUSD::SRUSD'
|
|
17
17
|
const yusd = 'YieldFi yUSD::yUSD'
|
|
@@ -28,7 +28,9 @@ const rsweth = 'Restaked Swell ETH::RSWETH'
|
|
|
28
28
|
const ynethx = 'ynETH MAX::YNETHX'
|
|
29
29
|
const usdZeroPlus = 'Staked USD0::USD0++'
|
|
30
30
|
const ethZero = 'ETH0::ETH0'
|
|
31
|
-
const usdThree =
|
|
31
|
+
const usdThree = 'Web 3 Dollar::USD3'
|
|
32
|
+
const jitoSol = 'Jito Staked SOL::JitoSOL'
|
|
33
|
+
const thBill = 'Theo Short Duration US Treasury Fund::THBILL'
|
|
32
34
|
const FeedData = {
|
|
33
35
|
WSTETH: 'https://eth-api.lido.fi/v1/protocol/steth/apr/sma',
|
|
34
36
|
STMATIC: 'https://polygon.lido.fi/api/stats',
|
|
@@ -61,6 +63,8 @@ const FeedData = {
|
|
|
61
63
|
YNETHX: 'https://gateway.yieldnest.finance/api/v1/graphql',
|
|
62
64
|
USDZEROPLUS: 'https://app.usual.money/api/rewards/rates/USD0++',
|
|
63
65
|
ETHZERO: 'https://app.usual.money/api/rewards/rates/ETH0',
|
|
66
|
+
JITOSOL: 'https://www.jito.network/api/getJitoPoolStats/',
|
|
67
|
+
THBILL: 'https://thbill-api.theo.xyz/snapshots',
|
|
64
68
|
}
|
|
65
69
|
|
|
66
70
|
const LenderAPIs = {
|
|
@@ -68,6 +72,15 @@ const LenderAPIs = {
|
|
|
68
72
|
'https://omnidex.bmaa3ajd1gjri.eu-west-2.cs.amazonlightsail.com/lending_yields',
|
|
69
73
|
}
|
|
70
74
|
|
|
75
|
+
function averageDataLastN<T extends { data: number }>(
|
|
76
|
+
arr: readonly T[],
|
|
77
|
+
n = 7,
|
|
78
|
+
): number {
|
|
79
|
+
const last = arr.slice(-n)
|
|
80
|
+
if (last.length === 0) return 0
|
|
81
|
+
return last.reduce((sum, x) => sum + x.data, 0) / last.length
|
|
82
|
+
}
|
|
83
|
+
|
|
71
84
|
enum MeridainNetwork {
|
|
72
85
|
TAIKO = 'taiko',
|
|
73
86
|
}
|
|
@@ -176,6 +189,31 @@ export const fetchGeneralYields = async () => {
|
|
|
176
189
|
return apyToAprPercent(res.apy)
|
|
177
190
|
})
|
|
178
191
|
|
|
192
|
+
const thbillPromise = safeFetch('THBILL', async () => {
|
|
193
|
+
const res = await fetch(FeedData.THBILL).then((r) => r.json())
|
|
194
|
+
// the entries are nested as
|
|
195
|
+
// "cash": {
|
|
196
|
+
// "USDC": 0.0
|
|
197
|
+
// },
|
|
198
|
+
// "money_market": {
|
|
199
|
+
// "ULTRA": 30364810.9557616
|
|
200
|
+
// },
|
|
201
|
+
// "pending": {
|
|
202
|
+
// "tULTRA": 16220629.251993446
|
|
203
|
+
// }
|
|
204
|
+
// },
|
|
205
|
+
|
|
206
|
+
// we read the keys and assign the approx rate of 4.5% to ULTRA
|
|
207
|
+
const entrs = Object.values(res.history[0]?.composition ?? {}).flatMap(
|
|
208
|
+
(a: any) => Object.entries(a),
|
|
209
|
+
)
|
|
210
|
+
const total = entrs.reduce((acc, b) => acc + Number(b[1]), 0)
|
|
211
|
+
const val = entrs
|
|
212
|
+
.filter((a) => a[0] === 'ULTRA')
|
|
213
|
+
.reduce((acc, b) => acc + Number(b[1]), 0)
|
|
214
|
+
return (val / total) * 4.5
|
|
215
|
+
})
|
|
216
|
+
|
|
179
217
|
const ethxPromise = safeFetch('ETHX', async () => {
|
|
180
218
|
const res = await fetch(FeedData.ETHX).then((r) => r.json())
|
|
181
219
|
return apyToAprPercent(res.value)
|
|
@@ -233,6 +271,15 @@ export const fetchGeneralYields = async () => {
|
|
|
233
271
|
return Number(res?.rewards[0]?.apr ?? 0) * 100
|
|
234
272
|
})
|
|
235
273
|
|
|
274
|
+
const jitoSolPromise = safeFetch('JITOSOL', async () => {
|
|
275
|
+
const res = await fetch(FeedData.JITOSOL, {
|
|
276
|
+
method: 'GET',
|
|
277
|
+
headers: { Accept: 'application/json' },
|
|
278
|
+
}).then((r) => r.json())
|
|
279
|
+
const val = averageDataLastN(res?.getStakePoolStats?.apy, 7)
|
|
280
|
+
return apyToApr(val) * 100
|
|
281
|
+
})
|
|
282
|
+
|
|
236
283
|
const ethZeroPromise = safeFetch('ETHZERO', async () => {
|
|
237
284
|
const res = await fetch(FeedData.ETHZERO, {
|
|
238
285
|
method: 'GET',
|
|
@@ -246,7 +293,7 @@ export const fetchGeneralYields = async () => {
|
|
|
246
293
|
method: 'GET',
|
|
247
294
|
headers: { Accept: 'application/json' },
|
|
248
295
|
}).then((r) => r.json())
|
|
249
|
-
return
|
|
296
|
+
return apyToApr(Number(res?.[0]?.sky_savings_rate_apy ?? 0)) * 100
|
|
250
297
|
})
|
|
251
298
|
|
|
252
299
|
const srusdPromise = safeFetch('SRUSD', async () => {
|
|
@@ -268,7 +315,11 @@ export const fetchGeneralYields = async () => {
|
|
|
268
315
|
const rlpPromise = safeFetch('RLP', async () => {
|
|
269
316
|
const res = await fetch(FeedData.RLP, {
|
|
270
317
|
method: 'GET',
|
|
271
|
-
headers: {
|
|
318
|
+
headers: {
|
|
319
|
+
Accept: 'application/json',
|
|
320
|
+
|
|
321
|
+
'User-Agent': '1delta/yields',
|
|
322
|
+
},
|
|
272
323
|
}).then((r) => r.json())
|
|
273
324
|
return Number(res?.value ?? 0) * 100
|
|
274
325
|
})
|
|
@@ -276,7 +327,10 @@ export const fetchGeneralYields = async () => {
|
|
|
276
327
|
const wstusrPromise = safeFetch('WSTUSR', async () => {
|
|
277
328
|
const res = await fetch(FeedData.WSTUSR, {
|
|
278
329
|
method: 'GET',
|
|
279
|
-
headers: {
|
|
330
|
+
headers: {
|
|
331
|
+
Accept: 'application/json',
|
|
332
|
+
'User-Agent': '1delta/yields',
|
|
333
|
+
},
|
|
280
334
|
}).then((r) => r.json())
|
|
281
335
|
return Number(res?.value ?? 0) * 100
|
|
282
336
|
})
|
|
@@ -292,7 +346,7 @@ export const fetchGeneralYields = async () => {
|
|
|
292
346
|
const rswethPromise = safeFetch('RSWETH', async () => {
|
|
293
347
|
const res = await fetch(FeedData.RSWETH, {
|
|
294
348
|
method: 'GET',
|
|
295
|
-
headers: { Accept: 'application/json' },
|
|
349
|
+
headers: { Accept: 'application/json', 'User-Agent': '1delta/yields' },
|
|
296
350
|
}).then((r) => r.text())
|
|
297
351
|
return Number(res) ?? 0
|
|
298
352
|
})
|
|
@@ -413,6 +467,8 @@ export const fetchGeneralYields = async () => {
|
|
|
413
467
|
ynethxData,
|
|
414
468
|
ethZeroData,
|
|
415
469
|
usdZeroPlusData,
|
|
470
|
+
jitoSolData,
|
|
471
|
+
thBillData,
|
|
416
472
|
] = await Promise.all([
|
|
417
473
|
wstethPromise,
|
|
418
474
|
ezethPromise,
|
|
@@ -444,6 +500,8 @@ export const fetchGeneralYields = async () => {
|
|
|
444
500
|
ynethxPromise,
|
|
445
501
|
ethZeroPromise,
|
|
446
502
|
usdZeroPlusPromise,
|
|
503
|
+
jitoSolPromise,
|
|
504
|
+
thbillPromise,
|
|
447
505
|
])
|
|
448
506
|
|
|
449
507
|
const data: YieldDataWithTimestamp = {
|
|
@@ -477,6 +535,8 @@ export const fetchGeneralYields = async () => {
|
|
|
477
535
|
[ynethx]: ynethxData,
|
|
478
536
|
[tETH]: wstethData,
|
|
479
537
|
[pufEth]: pufEthData,
|
|
538
|
+
[jitoSol]: jitoSolData,
|
|
539
|
+
[thBill]: thBillData,
|
|
480
540
|
...rtokensData,
|
|
481
541
|
...hypeData,
|
|
482
542
|
...angleData,
|
package/test/mainPriceMB.test.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { describe, it } from 'vitest'
|
|
2
2
|
import { Chain } from '@1delta/asset-registry'
|
|
3
3
|
import { fetchMainPrices } from '../src'
|
|
4
|
-
import { getEvmClient } from '@1delta/providers'
|
|
5
4
|
|
|
6
5
|
const chainIds =
|
|
7
6
|
// [ Chain.BASE]
|
|
@@ -23,7 +22,7 @@ describe(
|
|
|
23
22
|
'find prices',
|
|
24
23
|
() => {
|
|
25
24
|
it('should return prices for valid tokens', async () => {
|
|
26
|
-
const prices = await fetchMainPrices(chainIds
|
|
25
|
+
const prices = await fetchMainPrices(chainIds)
|
|
27
26
|
|
|
28
27
|
prettyPrint(prices)
|
|
29
28
|
})
|
package/test/mainPrices.test.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { describe, it } from 'vitest'
|
|
2
2
|
import { fetchMainPrices } from '../src'
|
|
3
3
|
import { Chain } from '@1delta/asset-registry'
|
|
4
|
-
import { getEvmClient } from '@1delta/providers'
|
|
5
4
|
import { prettyPrint } from './utils'
|
|
6
5
|
|
|
7
6
|
describe(
|
|
@@ -20,6 +19,7 @@ describe(
|
|
|
20
19
|
Chain.ETHEREUM_MAINNET,
|
|
21
20
|
],
|
|
22
21
|
)
|
|
22
|
+
console.log(mainPrices["SOL"])
|
|
23
23
|
prettyPrint(mainPrices)
|
|
24
24
|
})
|
|
25
25
|
},
|
package/test/morphoPrice.test.ts
CHANGED
package/test/userDataAll.test.ts
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { describe, it, expect
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
2
|
import {
|
|
3
3
|
getLenderUserDataResult,
|
|
4
4
|
convertLenderUserDataResult,
|
|
5
5
|
} from '../src/lending/user-data/fetchUserData'
|
|
6
|
-
import { fetchGeneralYields, fetchMainPrices } from '../src'
|
|
7
6
|
import { getEvmClient } from '@1delta/providers'
|
|
8
7
|
import { Chain, Lender } from '@1delta/asset-registry'
|
|
9
|
-
import { LenderUserQuery } from '../src/lending/user-data/types'
|
|
10
|
-
import { fetchMorphoPublicData } from '../src/lending/morpho/publicCallBuild'
|
|
11
8
|
import { prettyPrint } from './utils'
|
|
12
9
|
import { TestData } from './data'
|
|
13
10
|
// random user with ETH
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import {
|
|
3
|
+
getLenderUserDataResult,
|
|
4
|
+
convertLenderUserDataResult,
|
|
5
|
+
} from '../src/lending/user-data/fetchUserData'
|
|
6
|
+
import { getEvmClient } from '@1delta/providers'
|
|
7
|
+
import { Chain, Lender } from '@1delta/asset-registry'
|
|
8
|
+
import { LenderUserQuery } from '../src/lending/user-data/types'
|
|
9
|
+
import { prettyPrint } from './utils'
|
|
10
|
+
|
|
11
|
+
// random user with ETH
|
|
12
|
+
const TEST_ADDRESS = '0xbadA9c382165b31419F4CC0eDf0Fa84f80A3C8E5'
|
|
13
|
+
let prices
|
|
14
|
+
|
|
15
|
+
async function getUserData(chainId: Chain, publicData: any) {
|
|
16
|
+
// Define user queries
|
|
17
|
+
const queries: LenderUserQuery[] = Object.keys(publicData.data).map((m) => ({
|
|
18
|
+
lender: m,
|
|
19
|
+
account: TEST_ADDRESS.toLowerCase(),
|
|
20
|
+
// params: lenders,
|
|
21
|
+
}))
|
|
22
|
+
|
|
23
|
+
// console.log("queries", queries)
|
|
24
|
+
|
|
25
|
+
// Fetch raw user data
|
|
26
|
+
const rawUserData = await getLenderUserDataResult(
|
|
27
|
+
chainId,
|
|
28
|
+
queries,
|
|
29
|
+
getEvmClient,
|
|
30
|
+
)
|
|
31
|
+
// Convert raw data to structured format
|
|
32
|
+
const userData = convertLenderUserDataResult(
|
|
33
|
+
chainId,
|
|
34
|
+
queries,
|
|
35
|
+
rawUserData,
|
|
36
|
+
prices as any,
|
|
37
|
+
prices as any,
|
|
38
|
+
{ [chainId]: publicData },
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
return { userData, rawUserData, publicData, queries }
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
describe(
|
|
45
|
+
'user data fetching',
|
|
46
|
+
() => {
|
|
47
|
+
it(
|
|
48
|
+
'should fetch user data for Morpho on KATANA',
|
|
49
|
+
async () => {
|
|
50
|
+
try {
|
|
51
|
+
const chainId = Chain.ETHEREUM_MAINNET
|
|
52
|
+
const all = await fetch(
|
|
53
|
+
`https://margin-data.1delta.io/lending-multi?chains=${chainId}`,
|
|
54
|
+
).then((a) => a.json())
|
|
55
|
+
prices = all.prices
|
|
56
|
+
|
|
57
|
+
const publicData = all.data[chainId]
|
|
58
|
+
const { userData } = await getUserData(chainId, publicData)
|
|
59
|
+
|
|
60
|
+
prettyPrint(
|
|
61
|
+
userData[
|
|
62
|
+
'MORPHO_BLUE_C4E18EB6D0E9B0FA90A15BC0A98190CBF3D5BA763AF410346F5174B014CEFD8D'
|
|
63
|
+
],
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
// Basic validation
|
|
67
|
+
expect(userData).toBeDefined()
|
|
68
|
+
expect(typeof userData).toBe('object')
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.log('Error fetching Morpho KATANA data:', error)
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
{ timeout: 30000 },
|
|
74
|
+
)
|
|
75
|
+
},
|
|
76
|
+
{ timeout: 90000 },
|
|
77
|
+
)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import {
|
|
3
|
+
getLenderUserDataResult,
|
|
4
|
+
convertLenderUserDataResult,
|
|
5
|
+
} from '../src/lending/user-data/fetchUserData'
|
|
6
|
+
import { getEvmClient } from '@1delta/providers'
|
|
7
|
+
import { Chain, Lender } from '@1delta/asset-registry'
|
|
8
|
+
import { LenderUserQuery } from '../src/lending/user-data/types'
|
|
9
|
+
import { prettyPrint } from './utils'
|
|
10
|
+
|
|
11
|
+
// random user with ETH
|
|
12
|
+
const TEST_ADDRESS = '0xaffe73AA5EBd0CD95D89ab9fa2512Fc9e2d3289b'
|
|
13
|
+
let prices, yields
|
|
14
|
+
|
|
15
|
+
async function getUserData(chainId: Chain, publicData: any) {
|
|
16
|
+
// Define user queries
|
|
17
|
+
const queries: LenderUserQuery[] = Object.keys(publicData.data).map((m) => ({
|
|
18
|
+
lender: m,
|
|
19
|
+
account: TEST_ADDRESS.toLowerCase(),
|
|
20
|
+
// params: lenders,
|
|
21
|
+
}))
|
|
22
|
+
|
|
23
|
+
// Fetch raw user data
|
|
24
|
+
const rawUserData = await getLenderUserDataResult(
|
|
25
|
+
chainId,
|
|
26
|
+
queries,
|
|
27
|
+
getEvmClient,
|
|
28
|
+
)
|
|
29
|
+
// Convert raw data to structured format
|
|
30
|
+
const userData = convertLenderUserDataResult(
|
|
31
|
+
chainId,
|
|
32
|
+
queries,
|
|
33
|
+
rawUserData,
|
|
34
|
+
prices as any,
|
|
35
|
+
prices as any,
|
|
36
|
+
{ [chainId]: publicData },
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
return { userData, rawUserData, publicData, queries }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
describe(
|
|
43
|
+
'user data fetching',
|
|
44
|
+
() => {
|
|
45
|
+
it(
|
|
46
|
+
'should fetch user data for Morpho on KATANA',
|
|
47
|
+
async () => {
|
|
48
|
+
try {
|
|
49
|
+
const chainId = Chain.KATANA
|
|
50
|
+
const all = await fetch(
|
|
51
|
+
`https://margin-data.1delta.io/lending-multi?chains=${chainId}`,
|
|
52
|
+
).then((a) => a.json())
|
|
53
|
+
prices = all.prices
|
|
54
|
+
yields = all.yields
|
|
55
|
+
const publicData = all.data[chainId]
|
|
56
|
+
const { userData } = await getUserData(chainId, publicData)
|
|
57
|
+
|
|
58
|
+
prettyPrint(
|
|
59
|
+
userData[
|
|
60
|
+
'MORPHO_BLUE_16DED80178992B02F7C467C373CFC9F4EEE7F0356DF672F6A768EC92B2FFDEFF'
|
|
61
|
+
],
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
// Basic validation
|
|
65
|
+
expect(userData).toBeDefined()
|
|
66
|
+
expect(typeof userData).toBe('object')
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.log('Error fetching Morpho KATANA data:', error)
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
{ timeout: 30000 },
|
|
72
|
+
)
|
|
73
|
+
},
|
|
74
|
+
{ timeout: 90000 },
|
|
75
|
+
)
|