@levrbet/shared 0.1.163 → 0.1.165
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/core/config/urls.js +2 -2
- package/dist/core/indexers/envio.test.query.d.ts +5 -2
- package/dist/core/indexers/envio.test.query.js +10 -4
- package/dist/core/indexers/envio.test.query.js.map +1 -1
- package/dist/core/indexers/indexers.service.js +37 -10
- package/dist/core/indexers/indexers.service.js.map +1 -1
- package/dist/core/indexers/subsquid.test.query.d.ts +4 -1
- package/dist/core/indexers/subsquid.test.query.js +21 -2
- package/dist/core/indexers/subsquid.test.query.js.map +1 -1
- package/dist/core/prisma/generated/edge.js +10 -3
- package/dist/core/prisma/generated/index-browser.js +7 -0
- package/dist/core/prisma/generated/index.d.ts +109 -1
- package/dist/core/prisma/generated/index.js +10 -3
- package/dist/core/prisma/generated/package.json +1 -1
- package/dist/core/prisma/generated/schema.prisma +7 -0
- package/dist/core/prisma/generated/wasm.js +10 -3
- package/dist/server/config/redis.d.ts +1 -1
- package/dist/server/config/redis.js +9 -3
- package/dist/server/config/redis.js.map +1 -1
- package/dist/server/oracle/redis-cache-manager/channels.js +1 -1
- package/dist/server/oracle/redis-cache-manager/channels.js.map +1 -1
- package/package.json +3 -2
package/dist/core/config/urls.js
CHANGED
|
@@ -13,7 +13,7 @@ exports.allUrls = {
|
|
|
13
13
|
relayer: "https://relayer.dev.levr.bet",
|
|
14
14
|
indexers: {
|
|
15
15
|
[types_1.LevrChain.MONAD_TESTNET]: [
|
|
16
|
-
{ type: indexers_types_1.LevrIndexer.ENVIO, url: "https://indexer.dev.hyperindex.xyz/
|
|
16
|
+
{ type: indexers_types_1.LevrIndexer.ENVIO, url: "https://indexer.dev.hyperindex.xyz/c1eefd0/v1/graphql" },
|
|
17
17
|
{ type: indexers_types_1.LevrIndexer.SUBSQUID, url: "https://levrbet.squids.live/levr-v1-indexer-dev@v1/api/graphql" },
|
|
18
18
|
],
|
|
19
19
|
},
|
|
@@ -26,7 +26,7 @@ exports.allUrls = {
|
|
|
26
26
|
relayer: "http://levr-v1-openzeppeline-1018367603.ap-south-1.elb.amazonaws.com",
|
|
27
27
|
indexers: {
|
|
28
28
|
[types_1.LevrChain.MONAD_TESTNET]: [
|
|
29
|
-
{ type: indexers_types_1.LevrIndexer.ENVIO, url: "https://indexer.dev.hyperindex.xyz/
|
|
29
|
+
{ type: indexers_types_1.LevrIndexer.ENVIO, url: "https://indexer.dev.hyperindex.xyz/c1eefd0/v1/graphql" },
|
|
30
30
|
{ type: indexers_types_1.LevrIndexer.SUBSQUID, url: "https://levrbet.squids.live/levr-v1-indexer-dev@v1/api/graphql" },
|
|
31
31
|
],
|
|
32
32
|
},
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
export declare const HEALTH_CHECK_QUERY = "\n query {\n
|
|
2
|
-
export declare function checkEnvioGraphQlHealth(url: string, variables?: Record<string, any>, signal?: AbortSignal): Promise<
|
|
1
|
+
export declare const HEALTH_CHECK_QUERY = "\n query {\n LevrFullTimeMarket_PositionOpened(order_by: {timestamp: desc}, limit: 1) {\n timestamp\n }\n }\n";
|
|
2
|
+
export declare function checkEnvioGraphQlHealth(url: string, variables?: Record<string, any>, signal?: AbortSignal): Promise<{
|
|
3
|
+
ok: boolean;
|
|
4
|
+
block: any;
|
|
5
|
+
}>;
|
|
@@ -5,9 +5,9 @@ exports.checkEnvioGraphQlHealth = checkEnvioGraphQlHealth;
|
|
|
5
5
|
// GraphQL query to check if the endpoint is healthy by requesting LevrFullTimeMarket_PositionOpened
|
|
6
6
|
exports.HEALTH_CHECK_QUERY = `
|
|
7
7
|
query {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
LevrFullTimeMarket_PositionOpened(order_by: {timestamp: desc}, limit: 1) {
|
|
9
|
+
timestamp
|
|
10
|
+
}
|
|
11
11
|
}
|
|
12
12
|
`;
|
|
13
13
|
async function checkEnvioGraphQlHealth(url, variables, signal) {
|
|
@@ -21,6 +21,12 @@ async function checkEnvioGraphQlHealth(url, variables, signal) {
|
|
|
21
21
|
// forward AbortSignal so the request can be aborted by caller
|
|
22
22
|
signal,
|
|
23
23
|
});
|
|
24
|
-
|
|
24
|
+
const data = await response.json();
|
|
25
|
+
const dataParsed = response.ok ? JSON.parse(JSON.stringify(data)) : null;
|
|
26
|
+
console.dir(data, { depth: null, colors: true });
|
|
27
|
+
return {
|
|
28
|
+
ok: response.ok === true,
|
|
29
|
+
block: response.ok ? dataParsed.data.LevrFullTimeMarket_PositionOpened[0].timestamp : null,
|
|
30
|
+
};
|
|
25
31
|
}
|
|
26
32
|
//# sourceMappingURL=envio.test.query.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envio.test.query.js","sourceRoot":"","sources":["../../../src/core/indexers/envio.test.query.ts"],"names":[],"mappings":";;;AASA,
|
|
1
|
+
{"version":3,"file":"envio.test.query.js","sourceRoot":"","sources":["../../../src/core/indexers/envio.test.query.ts"],"names":[],"mappings":";;;AASA,0DAsBC;AA/BD,oGAAoG;AACvF,QAAA,kBAAkB,GAAG;;;;;;CAMjC,CAAA;AAEM,KAAK,UAAU,uBAAuB,CAAC,GAAW,EAAE,SAA+B,EAAE,MAAoB;IAC5G,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC9B,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACjB,KAAK,EAAE,0BAAkB;YACzB,SAAS;SACZ,CAAC;QACF,8DAA8D;QAC9D,MAAM;KACT,CAAC,CAAA;IAEF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;IAElC,MAAM,UAAU,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAExE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;IAEhD,OAAO;QACH,EAAE,EAAE,QAAQ,CAAC,EAAE,KAAK,IAAI;QACxB,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;KAC7F,CAAA;AACL,CAAC"}
|
|
@@ -14,8 +14,8 @@ const ms_1 = __importDefault(require("ms"));
|
|
|
14
14
|
const typescript_memoize_1 = require("typescript-memoize");
|
|
15
15
|
const _1 = require("../.");
|
|
16
16
|
const indexers_types_1 = require("../types/indexers.types");
|
|
17
|
-
const subsquid_test_query_1 = require("./subsquid.test.query");
|
|
18
17
|
const envio_test_query_1 = require("./envio.test.query");
|
|
18
|
+
const subsquid_test_query_1 = require("./subsquid.test.query");
|
|
19
19
|
class IndexersService {
|
|
20
20
|
/**
|
|
21
21
|
* Check the health of a single indexer with caching
|
|
@@ -33,13 +33,16 @@ class IndexersService {
|
|
|
33
33
|
}
|
|
34
34
|
catch (error) {
|
|
35
35
|
// node-fetch throws an AbortError when aborted; match on name to avoid noisy logs
|
|
36
|
-
if (error && (error.name ===
|
|
36
|
+
if (error && (error.name === "AbortError" || error.type === "aborted")) {
|
|
37
37
|
console.warn(`Health check aborted (timeout) for ${url}`);
|
|
38
38
|
}
|
|
39
39
|
else {
|
|
40
40
|
console.error(`Health check failed for ${url}:`, error);
|
|
41
41
|
}
|
|
42
|
-
return
|
|
42
|
+
return {
|
|
43
|
+
ok: false,
|
|
44
|
+
block: null,
|
|
45
|
+
};
|
|
43
46
|
}
|
|
44
47
|
finally {
|
|
45
48
|
clearTimeout(timeoutId);
|
|
@@ -51,16 +54,29 @@ class IndexersService {
|
|
|
51
54
|
*/
|
|
52
55
|
async getHealthyIndexer(env, chain) {
|
|
53
56
|
const indexers = _1.allUrls[env].indexers[chain] || [];
|
|
57
|
+
const typeToBlockMap = {
|
|
58
|
+
[indexers_types_1.LevrIndexer.ENVIO]: null,
|
|
59
|
+
[indexers_types_1.LevrIndexer.SUBSQUID]: null,
|
|
60
|
+
};
|
|
54
61
|
for (const indexer of indexers) {
|
|
55
62
|
const isHealthy = await this.checkIndexerHealth(indexer.url, indexer.type);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
typeToBlockMap[indexer.type] = isHealthy.block;
|
|
64
|
+
}
|
|
65
|
+
// use the one with the lastest block if multiple are healthy
|
|
66
|
+
const healthyIndexers = indexers.filter((idx) => typeToBlockMap[idx.type] !== null);
|
|
67
|
+
if (healthyIndexers.length > indexers.length - 1) {
|
|
68
|
+
healthyIndexers.sort((a, b) => {
|
|
69
|
+
const blockA = typeToBlockMap[a.type] || 0;
|
|
70
|
+
const blockB = typeToBlockMap[b.type] || 0;
|
|
71
|
+
return blockB - blockA;
|
|
72
|
+
});
|
|
73
|
+
const bestIndexer = healthyIndexers[0];
|
|
74
|
+
return { type: bestIndexer.type, url: bestIndexer.url };
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// return the first healthy one if only one is healthy
|
|
78
|
+
return { type: healthyIndexers[0].type, url: healthyIndexers[0].url };
|
|
62
79
|
}
|
|
63
|
-
throw new Error(`No healthy indexers found for ${env} - Chain ${chain}`);
|
|
64
80
|
}
|
|
65
81
|
getIndexer(env, chain, type) {
|
|
66
82
|
const indexers = _1.allUrls[env].indexers[chain] || [];
|
|
@@ -74,4 +90,15 @@ __decorate([
|
|
|
74
90
|
(0, typescript_memoize_1.MemoizeExpiring)((0, ms_1.default)("1m"))
|
|
75
91
|
], IndexersService.prototype, "checkIndexerHealth", null);
|
|
76
92
|
exports.indexersService = new IndexersService();
|
|
93
|
+
// let's run a simple test to ensure the memoization is working
|
|
94
|
+
// async function testMemoization() {
|
|
95
|
+
// const start = Date.now()
|
|
96
|
+
// const index = await indexersService.getHealthyIndexer(LevrEnv.DEV, LevrChain.MONAD_TESTNET)
|
|
97
|
+
// return { index }
|
|
98
|
+
// }
|
|
99
|
+
// const main = async () => {
|
|
100
|
+
// const result = await testMemoization()
|
|
101
|
+
// console.log("Test memoization result:", result)
|
|
102
|
+
// }
|
|
103
|
+
// main()
|
|
77
104
|
//# sourceMappingURL=indexers.service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"indexers.service.js","sourceRoot":"","sources":["../../../src/core/indexers/indexers.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,4CAAmB;AACnB,2DAAoD;AACpD,2BAAkD;AAClD,4DAAqD;AACrD,+DAAkE;
|
|
1
|
+
{"version":3,"file":"indexers.service.js","sourceRoot":"","sources":["../../../src/core/indexers/indexers.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export declare function checkSubsquidGraphQLHealth(url: string, variables?: Record<string, any>, signal?: AbortSignal): Promise<
|
|
1
|
+
export declare function checkSubsquidGraphQLHealth(url: string, variables?: Record<string, any>, signal?: AbortSignal): Promise<{
|
|
2
|
+
ok: boolean;
|
|
3
|
+
block: number | null;
|
|
4
|
+
}>;
|
|
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.checkSubsquidGraphQLHealth = checkSubsquidGraphQLHealth;
|
|
4
4
|
const HEALTH_CHECK_QUERY = `
|
|
5
5
|
query HealthCheck {
|
|
6
|
-
levrFullTimeMarketSchemaPositionOpeneds(limit: 1) {
|
|
6
|
+
levrFullTimeMarketSchemaPositionOpeneds(limit: 1, orderBy: timestamp_DESC) {
|
|
7
7
|
id
|
|
8
|
+
timestamp
|
|
8
9
|
}
|
|
9
10
|
}
|
|
10
11
|
`;
|
|
@@ -18,6 +19,24 @@ async function checkSubsquidGraphQLHealth(url, variables, signal) {
|
|
|
18
19
|
}),
|
|
19
20
|
signal,
|
|
20
21
|
});
|
|
21
|
-
|
|
22
|
+
const timestamp = response.ok ? (await response.json()).data.levrFullTimeMarketSchemaPositionOpeneds[0]?.timestamp : null;
|
|
23
|
+
const toUnix = (ts) => {
|
|
24
|
+
if (ts == null)
|
|
25
|
+
return null;
|
|
26
|
+
// numeric value or numeric string
|
|
27
|
+
const num = typeof ts === "number" ? ts : Number(ts);
|
|
28
|
+
if (!Number.isNaN(num) && Number.isFinite(num)) {
|
|
29
|
+
// if in milliseconds (likely > 1e12) convert to seconds, otherwise assume seconds
|
|
30
|
+
return num > 1e12 ? Math.floor(num / 1000) : Math.floor(num);
|
|
31
|
+
}
|
|
32
|
+
// try parsing ISO/date string
|
|
33
|
+
const parsed = Date.parse(String(ts));
|
|
34
|
+
return Number.isNaN(parsed) ? null : Math.floor(parsed / 1000);
|
|
35
|
+
};
|
|
36
|
+
console.log("Subsquid health check response status:", response.status, url, toUnix(timestamp));
|
|
37
|
+
return {
|
|
38
|
+
ok: response.ok === true,
|
|
39
|
+
block: toUnix(timestamp),
|
|
40
|
+
};
|
|
22
41
|
}
|
|
23
42
|
//# sourceMappingURL=subsquid.test.query.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subsquid.test.query.js","sourceRoot":"","sources":["../../../src/core/indexers/subsquid.test.query.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"subsquid.test.query.js","sourceRoot":"","sources":["../../../src/core/indexers/subsquid.test.query.ts"],"names":[],"mappings":";;AASA,gEAgCC;AAzCD,MAAM,kBAAkB,GAAG;;;;;;;CAO1B,CAAA;AAEM,KAAK,UAAU,0BAA0B,CAAC,GAAW,EAAE,SAA+B,EAAE,MAAoB;IAC/G,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC9B,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACjB,KAAK,EAAE,kBAAkB;YACzB,SAAS;SACZ,CAAC;QACF,MAAM;KACT,CAAC,CAAA;IAEF,MAAM,SAAS,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAA;IAEzH,MAAM,MAAM,GAAG,CAAC,EAAO,EAAiB,EAAE;QACtC,IAAI,EAAE,IAAI,IAAI;YAAE,OAAO,IAAI,CAAA;QAC3B,kCAAkC;QAClC,MAAM,GAAG,GAAG,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QACpD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7C,kFAAkF;YAClF,OAAO,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAChE,CAAC;QACD,8BAA8B;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;QACrC,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAClE,CAAC,CAAA;IAED,OAAO,CAAC,GAAG,CAAC,wCAAwC,EAAE,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAA;IAE9F,OAAO;QACH,EAAE,EAAE,QAAQ,CAAC,EAAE,KAAK,IAAI;QACxB,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC;KAC3B,CAAA;AACL,CAAC"}
|