@merkl/api 0.21.16 → 0.21.18
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/database/api/.generated/drizzle/schema.d.ts +3 -3
- package/dist/database/api/.generated/drizzle/schema.js +1 -1
- package/dist/database/api/.generated/drizzle/schema.ts +1 -1
- package/dist/database/api/.generated/edge.js +5 -4
- package/dist/database/api/.generated/index-browser.js +2 -1
- package/dist/database/api/.generated/index.d.ts +2 -1
- package/dist/database/api/.generated/index.js +5 -4
- package/dist/database/api/.generated/package.json +1 -1
- package/dist/database/api/.generated/schema.prisma +1 -0
- package/dist/database/api/.generated/wasm.js +2 -1
- package/dist/src/eden/index.d.ts +6 -6
- package/dist/src/index.d.ts +2 -2
- package/dist/src/modules/v4/chain/chain.repository.d.ts +13 -3
- package/dist/src/modules/v4/chain/chain.repository.js +9 -3
- package/dist/src/modules/v4/chain/chain.service.d.ts +13 -1
- package/dist/src/modules/v4/chain/chain.service.js +6 -4
- package/dist/src/modules/v4/merklRoot/merklRoot.service.js +1 -1
- package/dist/src/modules/v4/price/price.controller.d.ts +2 -2
- package/dist/src/modules/v4/price/price.model.d.ts +2 -0
- package/dist/src/modules/v4/price/price.service.js +3 -2
- package/dist/src/modules/v4/reward/reward.service.js +1 -1
- package/dist/src/modules/v4/router.d.ts +2 -2
- package/dist/src/utils/prices/priceFetcherFactory.js +3 -0
- package/dist/src/utils/prices/services/OnChainCallService.d.ts +8 -0
- package/dist/src/utils/prices/services/OnChainCallService.js +38 -0
- package/dist/tsconfig.package.tsbuildinfo +1 -1
- package/package.json +1 -1
@@ -622,7 +622,8 @@ exports.PriceSourceMethod = exports.$Enums.PriceSourceMethod = {
|
|
622
622
|
ERC4626: 'ERC4626',
|
623
623
|
DEXSCREENER: 'DEXSCREENER',
|
624
624
|
INDEXCOOP: 'INDEXCOOP',
|
625
|
-
DEFILLAMA: 'DEFILLAMA'
|
625
|
+
DEFILLAMA: 'DEFILLAMA',
|
626
|
+
ONCHAIN_CALL: 'ONCHAIN_CALL'
|
626
627
|
};
|
627
628
|
|
628
629
|
exports.LoggedEntityType = exports.$Enums.LoggedEntityType = {
|
package/dist/src/eden/index.d.ts
CHANGED
@@ -3204,7 +3204,7 @@ declare const eden: {
|
|
3204
3204
|
}>>;
|
3205
3205
|
post: (body: {
|
3206
3206
|
symbol: string;
|
3207
|
-
method: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA";
|
3207
|
+
method: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | "ONCHAIN_CALL";
|
3208
3208
|
args: {};
|
3209
3209
|
}, options: {
|
3210
3210
|
headers: {
|
@@ -3233,7 +3233,7 @@ declare const eden: {
|
|
3233
3233
|
}>>;
|
3234
3234
|
patch: (body: {
|
3235
3235
|
symbol?: string | undefined;
|
3236
|
-
method?: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | undefined;
|
3236
|
+
method?: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | "ONCHAIN_CALL" | undefined;
|
3237
3237
|
args?: {} | undefined;
|
3238
3238
|
}, options: {
|
3239
3239
|
headers: {
|
@@ -9443,7 +9443,7 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
|
|
9443
9443
|
post: {
|
9444
9444
|
body: {
|
9445
9445
|
symbol: string;
|
9446
|
-
method: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA";
|
9446
|
+
method: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | "ONCHAIN_CALL";
|
9447
9447
|
args: {};
|
9448
9448
|
};
|
9449
9449
|
params: {};
|
@@ -9464,7 +9464,7 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
|
|
9464
9464
|
patch: {
|
9465
9465
|
body: {
|
9466
9466
|
symbol?: string | undefined;
|
9467
|
-
method?: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | undefined;
|
9467
|
+
method?: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | "ONCHAIN_CALL" | undefined;
|
9468
9468
|
args?: {} | undefined;
|
9469
9469
|
};
|
9470
9470
|
params: {
|
@@ -15670,7 +15670,7 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
|
|
15670
15670
|
}>>;
|
15671
15671
|
post: (body: {
|
15672
15672
|
symbol: string;
|
15673
|
-
method: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA";
|
15673
|
+
method: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | "ONCHAIN_CALL";
|
15674
15674
|
args: {};
|
15675
15675
|
}, options: {
|
15676
15676
|
headers: {
|
@@ -15699,7 +15699,7 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
|
|
15699
15699
|
}>>;
|
15700
15700
|
patch: (body: {
|
15701
15701
|
symbol?: string | undefined;
|
15702
|
-
method?: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | undefined;
|
15702
|
+
method?: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | "ONCHAIN_CALL" | undefined;
|
15703
15703
|
args?: {} | undefined;
|
15704
15704
|
}, options: {
|
15705
15705
|
headers: {
|
package/dist/src/index.d.ts
CHANGED
@@ -3854,7 +3854,7 @@ declare const app: Elysia<"", false, {
|
|
3854
3854
|
post: {
|
3855
3855
|
body: {
|
3856
3856
|
symbol: string;
|
3857
|
-
method: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA";
|
3857
|
+
method: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | "ONCHAIN_CALL";
|
3858
3858
|
args: {};
|
3859
3859
|
};
|
3860
3860
|
params: {};
|
@@ -3875,7 +3875,7 @@ declare const app: Elysia<"", false, {
|
|
3875
3875
|
patch: {
|
3876
3876
|
body: {
|
3877
3877
|
symbol?: string | undefined;
|
3878
|
-
method?: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | undefined;
|
3878
|
+
method?: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | "ONCHAIN_CALL" | undefined;
|
3879
3879
|
args?: {} | undefined;
|
3880
3880
|
};
|
3881
3881
|
params: {
|
@@ -51,12 +51,22 @@ export declare class ChainRepository {
|
|
51
51
|
id: number;
|
52
52
|
icon: string;
|
53
53
|
})[]>;
|
54
|
+
static findAll(): Promise<({
|
55
|
+
Explorer: {
|
56
|
+
url: string;
|
57
|
+
type: import("@db/api").$Enums.ExplorerType;
|
58
|
+
id: string;
|
59
|
+
chainId: number;
|
60
|
+
}[];
|
61
|
+
} & {
|
62
|
+
name: string;
|
63
|
+
id: number;
|
64
|
+
icon: string;
|
65
|
+
})[]>;
|
54
66
|
static countMany(query: ChainSearchDto): Promise<number>;
|
55
67
|
/** Returns all chainIds in the database
|
56
68
|
*/
|
57
|
-
static
|
58
|
-
id: number;
|
59
|
-
}[]>;
|
69
|
+
static findManyIds(): Promise<number[]>;
|
60
70
|
/**
|
61
71
|
* Creates a new chain
|
62
72
|
* @param template for chain creation
|
@@ -28,6 +28,12 @@ export class ChainRepository {
|
|
28
28
|
...args,
|
29
29
|
});
|
30
30
|
}
|
31
|
+
static async findAll() {
|
32
|
+
return await apiDbClient.chain.findMany({
|
33
|
+
include: { Explorer: { take: 5 } },
|
34
|
+
orderBy: { id: "asc" },
|
35
|
+
});
|
36
|
+
}
|
31
37
|
static async countMany(query) {
|
32
38
|
const args = ChainRepository.transformQueryToPrismaFilters(query);
|
33
39
|
return apiDbClient.chain.count({
|
@@ -36,10 +42,10 @@ export class ChainRepository {
|
|
36
42
|
}
|
37
43
|
/** Returns all chainIds in the database
|
38
44
|
*/
|
39
|
-
static async
|
40
|
-
return apiDbClient.chain.findMany({
|
45
|
+
static async findManyIds() {
|
46
|
+
return (await apiDbClient.chain.findMany({
|
41
47
|
select: { id: true },
|
42
|
-
});
|
48
|
+
})).map(({ id }) => id);
|
43
49
|
}
|
44
50
|
/**
|
45
51
|
* Creates a new chain
|
@@ -12,6 +12,18 @@ export declare abstract class ChainService {
|
|
12
12
|
id: number;
|
13
13
|
icon: string;
|
14
14
|
}) | null>;
|
15
|
+
static findAll(): Promise<({
|
16
|
+
Explorer: {
|
17
|
+
url: string;
|
18
|
+
type: import("@db/api").$Enums.ExplorerType;
|
19
|
+
id: string;
|
20
|
+
chainId: number;
|
21
|
+
}[];
|
22
|
+
} & {
|
23
|
+
name: string;
|
24
|
+
id: number;
|
25
|
+
icon: string;
|
26
|
+
})[]>;
|
15
27
|
static findMany(query: ChainSearchDto): Promise<({
|
16
28
|
Explorer: {
|
17
29
|
url: string;
|
@@ -41,7 +53,7 @@ export declare abstract class ChainService {
|
|
41
53
|
* @warning some chains may not be fully integrated yet
|
42
54
|
* @returns an array of chainId
|
43
55
|
*/
|
44
|
-
static
|
56
|
+
static findManyIds(): Promise<number[]>;
|
45
57
|
/** List all chainIds which have a distribituor (i.e. which is fully integrated)
|
46
58
|
* @returns an array of chainId
|
47
59
|
*/
|
@@ -6,6 +6,9 @@ export class ChainService {
|
|
6
6
|
static async get(chainId) {
|
7
7
|
return ChainRepository.read(chainId);
|
8
8
|
}
|
9
|
+
static async findAll() {
|
10
|
+
return await CacheService.wrap(TTLPresets.MIN_10, ChainRepository.findAll);
|
11
|
+
}
|
9
12
|
static async findMany(query) {
|
10
13
|
// Bypass cache in test mode
|
11
14
|
if (query.test)
|
@@ -22,15 +25,14 @@ export class ChainService {
|
|
22
25
|
* @warning some chains may not be fully integrated yet
|
23
26
|
* @returns an array of chainId
|
24
27
|
*/
|
25
|
-
static async
|
26
|
-
|
27
|
-
return ids.map(({ id }) => id);
|
28
|
+
static async findManyIds() {
|
29
|
+
return ChainRepository.findManyIds();
|
28
30
|
}
|
29
31
|
/** List all chainIds which have a distribituor (i.e. which is fully integrated)
|
30
32
|
* @returns an array of chainId
|
31
33
|
*/
|
32
34
|
static async getSupportedIds() {
|
33
|
-
const ids = await ChainService.
|
35
|
+
const ids = await ChainService.findManyIds();
|
34
36
|
const supportedIds = [];
|
35
37
|
for (const chainId of ids) {
|
36
38
|
try {
|
@@ -29,7 +29,7 @@ export class MerklRootService {
|
|
29
29
|
*/
|
30
30
|
static async fetchAll(chainIds) {
|
31
31
|
return await CacheService.wrap(TTLPresets.MIN_1, async () => {
|
32
|
-
let ids = chainIds ?? (await ChainService.
|
32
|
+
let ids = chainIds ?? (await ChainService.findManyIds());
|
33
33
|
/** Fetch current Merkle Roots */
|
34
34
|
const merkleRootsPromises = await Promise.allSettled(ids.map(chainId => MerklRootService.fetchFromCache(chainId)));
|
35
35
|
/** Filter out unsuccessful chainIds */
|
@@ -105,7 +105,7 @@ export declare const PriceController: Elysia<"/prices", false, {
|
|
105
105
|
post: {
|
106
106
|
body: {
|
107
107
|
symbol: string;
|
108
|
-
method: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA";
|
108
|
+
method: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | "ONCHAIN_CALL";
|
109
109
|
args: {};
|
110
110
|
};
|
111
111
|
params: {};
|
@@ -126,7 +126,7 @@ export declare const PriceController: Elysia<"/prices", false, {
|
|
126
126
|
patch: {
|
127
127
|
body: {
|
128
128
|
symbol?: string | undefined;
|
129
|
-
method?: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | undefined;
|
129
|
+
method?: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | "ONCHAIN_CALL" | undefined;
|
130
130
|
args?: {} | undefined;
|
131
131
|
};
|
132
132
|
params: {
|
@@ -8,6 +8,7 @@ export declare const CreatePriceSourceDto: import("@sinclair/typebox").TObject<{
|
|
8
8
|
DEXSCREENER: "DEXSCREENER";
|
9
9
|
INDEXCOOP: "INDEXCOOP";
|
10
10
|
DEFILLAMA: "DEFILLAMA";
|
11
|
+
ONCHAIN_CALL: "ONCHAIN_CALL";
|
11
12
|
}>;
|
12
13
|
args: import("@sinclair/typebox").TObject<{}>;
|
13
14
|
}>;
|
@@ -21,6 +22,7 @@ export declare const UpdatePriceSourceDto: import("@sinclair/typebox").TObject<{
|
|
21
22
|
DEXSCREENER: "DEXSCREENER";
|
22
23
|
INDEXCOOP: "INDEXCOOP";
|
23
24
|
DEFILLAMA: "DEFILLAMA";
|
25
|
+
ONCHAIN_CALL: "ONCHAIN_CALL";
|
24
26
|
}>>;
|
25
27
|
args: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{}>>;
|
26
28
|
}>;
|
@@ -48,9 +48,10 @@ export class PriceService {
|
|
48
48
|
}
|
49
49
|
return price;
|
50
50
|
}
|
51
|
-
catch {
|
51
|
+
catch (e) {
|
52
|
+
console.error(e);
|
52
53
|
await PriceRepository.deleteBySymbol(created.symbol);
|
53
|
-
throw new UnableToFindPrice();
|
54
|
+
throw new UnableToFindPrice(e.toString());
|
54
55
|
}
|
55
56
|
}
|
56
57
|
static async updatePriceSource(symbol, newPriceSource) {
|
@@ -229,7 +229,7 @@ export class RewardService {
|
|
229
229
|
return rewards;
|
230
230
|
}
|
231
231
|
static async getUserRewardsByChain(user, withToken, chainFilter = [], connectedChainId = null, withTestTokens = false, claimableOnly = false) {
|
232
|
-
const chains = await ChainService.
|
232
|
+
const chains = await ChainService.findAll();
|
233
233
|
let chainIds = !chainFilter || !chainFilter.length
|
234
234
|
? chains.map(({ id }) => id)
|
235
235
|
: chains.map(({ id }) => id).filter(id => chainFilter.includes(id));
|
@@ -3724,7 +3724,7 @@ export declare const v4: Elysia<"/v4", false, {
|
|
3724
3724
|
post: {
|
3725
3725
|
body: {
|
3726
3726
|
symbol: string;
|
3727
|
-
method: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA";
|
3727
|
+
method: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | "ONCHAIN_CALL";
|
3728
3728
|
args: {};
|
3729
3729
|
};
|
3730
3730
|
params: {};
|
@@ -3745,7 +3745,7 @@ export declare const v4: Elysia<"/v4", false, {
|
|
3745
3745
|
patch: {
|
3746
3746
|
body: {
|
3747
3747
|
symbol?: string | undefined;
|
3748
|
-
method?: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | undefined;
|
3748
|
+
method?: "COINGECKO" | "CONSTANT" | "EQUAL_TO" | "ERC4626" | "DEXSCREENER" | "INDEXCOOP" | "DEFILLAMA" | "ONCHAIN_CALL" | undefined;
|
3749
3749
|
args?: {} | undefined;
|
3750
3750
|
};
|
3751
3751
|
params: {
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { PriceSourceMethod } from "@db/api";
|
2
|
+
import OnChainCall from "./services/OnChainCallService";
|
2
3
|
import CoingeckoService from "./services/coinGeckoService";
|
3
4
|
import DefillamaService from "./services/defillamaService";
|
4
5
|
import DexScreenerService from "./services/dexScreenerService";
|
@@ -22,6 +23,8 @@ export default class PriceFetcherFactory {
|
|
22
23
|
return DexScreenerService.instance;
|
23
24
|
case PriceSourceMethod.INDEXCOOP:
|
24
25
|
return IndexCoop.instance;
|
26
|
+
case PriceSourceMethod.ONCHAIN_CALL:
|
27
|
+
return OnChainCall.instance;
|
25
28
|
default:
|
26
29
|
throw new Error(`Price reader service not found for ${type}`);
|
27
30
|
}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import { type PriceSource } from "@db/api";
|
2
|
+
import type PriceFetcher from "./priceFetcher";
|
3
|
+
import type { ResponsePriceType } from "./priceFetcher";
|
4
|
+
export default class OnChainCallService implements PriceFetcher {
|
5
|
+
static readonly instance: PriceFetcher;
|
6
|
+
private constructor();
|
7
|
+
getPrice(tokens: PriceSource[]): Promise<ResponsePriceType[]>;
|
8
|
+
}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
import { PriceService } from "@/modules/v4/price/price.service";
|
2
|
+
import { PriceSourceMethod } from "@db/api";
|
3
|
+
import { BN2Number, ChainInteractionService } from "@sdk";
|
4
|
+
import { Contract } from "ethers";
|
5
|
+
import { log } from "../../logger";
|
6
|
+
export default class OnChainCallService {
|
7
|
+
static instance = new OnChainCallService();
|
8
|
+
constructor() { }
|
9
|
+
async getPrice(tokens) {
|
10
|
+
const pricePromises = tokens
|
11
|
+
.filter(tokenPriceSource => tokenPriceSource.method === PriceSourceMethod.ONCHAIN_CALL)
|
12
|
+
.map(async (token) => {
|
13
|
+
const args = token.args;
|
14
|
+
if (!args?.chainId || !args.address || !args.abi || !args.call) {
|
15
|
+
log.warn(`❌ ONCHAIN_CALL price source incorrectly implemented for ${token.symbol}`);
|
16
|
+
return undefined;
|
17
|
+
}
|
18
|
+
try {
|
19
|
+
const onChainCall = await new Contract(args.address, args.abi, ChainInteractionService(args.chainId).provider())[args.call]();
|
20
|
+
const multiplicator = BN2Number(onChainCall, args.decimals ?? 18);
|
21
|
+
const base = await PriceService.fetchPriceBySymbol(args.base);
|
22
|
+
const price = base * multiplicator;
|
23
|
+
// 2 returned tokens as stUSD and STUSD (business requirement)
|
24
|
+
const res = [
|
25
|
+
{ token: token.symbol, rate: price },
|
26
|
+
{ token: token.symbol.toUpperCase(), rate: price },
|
27
|
+
];
|
28
|
+
return res;
|
29
|
+
}
|
30
|
+
catch (error) {
|
31
|
+
log.warn(`❌ ONCHAIN_CALL price source failed for ${token.symbol} with error: ${error}`);
|
32
|
+
return undefined;
|
33
|
+
}
|
34
|
+
});
|
35
|
+
const resolvedPrices = (await Promise.all(pricePromises)).filter(result => !!result);
|
36
|
+
return resolvedPrices.flat();
|
37
|
+
}
|
38
|
+
}
|