@certik/skynet 0.11.3 → 0.12.0
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/CHANGELOG.md +13 -0
- package/api.js +1 -1
- package/bun.lockb +0 -0
- package/kafka.js +1 -4
- package/package.json +10 -10
- package/block.d.ts +0 -49
- package/block.js +0 -82
- package/distributed-lock.d.ts +0 -1
- package/distributed-lock.js +0 -109
- package/price.d.ts +0 -8
- package/price.js +0 -46
- package/primitive.d.ts +0 -29
- package/primitive.js +0 -78
- package/token.d.ts +0 -5
- package/token.js +0 -46
- package/transaction.d.ts +0 -30
- package/transaction.js +0 -42
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.12.0
|
|
4
|
+
|
|
5
|
+
- BREAKING: removed token module (@certik/skynet/token)
|
|
6
|
+
- BREAKING: removed block module (@certik/skynet/block)
|
|
7
|
+
- BREAKING: removed transaction module (@certik/skynet/transaction)
|
|
8
|
+
- BREAKING: removed primitive module (@certik/skynet/primitive)
|
|
9
|
+
- BREAKING: removed price module (@certik/skynet/price)
|
|
10
|
+
- BREAKING: removed distributed-lock module (@certik/skynet/distributed-lock)
|
|
11
|
+
|
|
12
|
+
## 0.11.4
|
|
13
|
+
|
|
14
|
+
- support api key in query string
|
|
15
|
+
|
|
3
16
|
## 0.11.3
|
|
4
17
|
|
|
5
18
|
- Fixed: get aws credential for production
|
package/api.js
CHANGED
|
@@ -42,7 +42,7 @@ async function logEndMiddleware(req, res, next) {
|
|
|
42
42
|
const apiKeyMiddleware = (key) => {
|
|
43
43
|
async function requireAPIKey(req, res, next) {
|
|
44
44
|
try {
|
|
45
|
-
const apiKey = req.get("x-api-key");
|
|
45
|
+
const apiKey = req.get("x-api-key") || req.query["api-key"]; // api key present either in header or query string
|
|
46
46
|
|
|
47
47
|
if (!apiKey) {
|
|
48
48
|
inline.log("request without api key");
|
package/bun.lockb
CHANGED
|
Binary file
|
package/kafka.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import meow from "meow";
|
|
2
2
|
import { Kafka, logLevel } from "kafkajs";
|
|
3
3
|
import { getEnvironment, getEnvOrThrow } from "./env.js";
|
|
4
|
-
import {
|
|
4
|
+
import { getSelectorFlags, getSelectorDesc, toSelectorString } from "./selector.js";
|
|
5
5
|
import { createRecord, getRecordByKey, deleteRecordsByHashKey } from "./dynamodb.js";
|
|
6
6
|
import { wait, exponentialRetry } from "./availability.js";
|
|
7
|
-
import { useLock } from "./distributed-lock.js";
|
|
8
7
|
import { getBinaryName } from "./cli.js";
|
|
9
8
|
import { inline } from "./log.js";
|
|
10
9
|
|
|
@@ -219,8 +218,6 @@ ${getSelectorDesc(selector)}
|
|
|
219
218
|
process.exit(0);
|
|
220
219
|
}
|
|
221
220
|
|
|
222
|
-
await useLock({ name: getJobName(name, selectorFlags), ttl: 50, verbose });
|
|
223
|
-
|
|
224
221
|
if (!from) {
|
|
225
222
|
const prevId = await getProducerLatestId(name, selectorFlags);
|
|
226
223
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@certik/skynet",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Skynet Shared JS library",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
"node": ">= 18"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@aws-sdk/client-dynamodb": "^3.
|
|
19
|
-
"@aws-sdk/client-s3": "^3.
|
|
20
|
-
"@aws-sdk/client-sqs": "^3.
|
|
21
|
-
"@aws-sdk/lib-dynamodb": "^3.
|
|
22
|
-
"@opensearch-project/opensearch": "^2.
|
|
23
|
-
"@slack/web-api": "^6.9.
|
|
24
|
-
"ably": "^1.2.
|
|
18
|
+
"@aws-sdk/client-dynamodb": "^3.449.0",
|
|
19
|
+
"@aws-sdk/client-s3": "^3.449.0",
|
|
20
|
+
"@aws-sdk/client-sqs": "^3.449.0",
|
|
21
|
+
"@aws-sdk/lib-dynamodb": "^3.449.0",
|
|
22
|
+
"@opensearch-project/opensearch": "^2.4.0",
|
|
23
|
+
"@slack/web-api": "^6.9.1",
|
|
24
|
+
"ably": "^1.2.47",
|
|
25
25
|
"bottleneck": "^2.19.5",
|
|
26
26
|
"chalk": "^5.3.0",
|
|
27
27
|
"execa": "^8.0.1",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"kafkajs": "^2.2.4",
|
|
30
30
|
"md5": "^2.3.0",
|
|
31
31
|
"meow": "^12.1.1",
|
|
32
|
-
"snowflake-sdk": "^1.
|
|
33
|
-
"web3": "^4.
|
|
32
|
+
"snowflake-sdk": "^1.9.0",
|
|
33
|
+
"web3": "^4.2.2",
|
|
34
34
|
"which": "^4.0.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
package/block.d.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
// See https://www.quicknode.com/docs/ethereum/eth_getBlockByNumber for a complete reference.
|
|
2
|
-
|
|
3
|
-
type Transaction = {
|
|
4
|
-
blockHash: string;
|
|
5
|
-
blockNumber: string;
|
|
6
|
-
hash: string;
|
|
7
|
-
to: string;
|
|
8
|
-
from: string;
|
|
9
|
-
transactionIndex: string;
|
|
10
|
-
value: string | undefined;
|
|
11
|
-
nonce: string;
|
|
12
|
-
gas: string;
|
|
13
|
-
gasPrice: string;
|
|
14
|
-
input: string;
|
|
15
|
-
type: string;
|
|
16
|
-
chainId: string | undefined;
|
|
17
|
-
v: string;
|
|
18
|
-
r: string;
|
|
19
|
-
s: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
type BlockInfo = {
|
|
23
|
-
number: string;
|
|
24
|
-
timestamp: string;
|
|
25
|
-
difficulty: string;
|
|
26
|
-
extraData: string;
|
|
27
|
-
gasLimit: string;
|
|
28
|
-
gasUsed: string;
|
|
29
|
-
hash: string;
|
|
30
|
-
logsBloom: string;
|
|
31
|
-
miner: string;
|
|
32
|
-
mixHash: string;
|
|
33
|
-
nonce: string;
|
|
34
|
-
parentHash: string;
|
|
35
|
-
receiptsRoot: string;
|
|
36
|
-
sha3Uncles: string;
|
|
37
|
-
size: string;
|
|
38
|
-
stateRoot: string;
|
|
39
|
-
totalDifficulty: string;
|
|
40
|
-
transactions: Transaction[];
|
|
41
|
-
transactionsRoot: string;
|
|
42
|
-
uncles: string[];
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function getLatestBlockHeight(protocol: string): Promise<number>;
|
|
46
|
-
export function getBlock(protocol: string, height: number): Promise<BlockInfo>;
|
|
47
|
-
export function getBlockS3Path(protocol: string, height: number): string;
|
|
48
|
-
export function getLatestS3BlockHeight(protocol: string): Promise<number>;
|
|
49
|
-
export function getBlockFromS3(protocol: string, height: number): Promise<BlockInfo>;
|
package/block.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { Web3 } from "web3";
|
|
2
|
-
import { getEnvironment } from "./env.js";
|
|
3
|
-
import { PROTOCOLS } from "./const.js";
|
|
4
|
-
import { readFile } from "./s3.js";
|
|
5
|
-
import { getRecordByKey } from "./dynamodb.js";
|
|
6
|
-
|
|
7
|
-
const S3_BUCKET_NAME =
|
|
8
|
-
getEnvironment() === "prd" ? "certik-skynet" : "certik-skynet-dev";
|
|
9
|
-
const INDEXER_STATE_TABLE = `skynet-${getEnvironment()}-indexer-state`;
|
|
10
|
-
|
|
11
|
-
function leftPad3(num) {
|
|
12
|
-
if (num === 0) {
|
|
13
|
-
return "000";
|
|
14
|
-
} else if (num < 10) {
|
|
15
|
-
return "00" + String(num);
|
|
16
|
-
} else if (num < 100) {
|
|
17
|
-
return "0" + String(num);
|
|
18
|
-
} else {
|
|
19
|
-
return String(num);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function getBlockS3Path(protocol, height) {
|
|
24
|
-
return `chaindata/${protocol}/${Math.floor(height / 1_000_000)}/${leftPad3(
|
|
25
|
-
Math.floor(height / 1_000) % 1000
|
|
26
|
-
)}/${leftPad3(height % 1000)}.json`;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// We use this function instead of web3 because the gas limits on bsc exceed
|
|
30
|
-
// the size supported by javascript numbers, and web3 does not support this
|
|
31
|
-
async function getBlock(protocol, height) {
|
|
32
|
-
const body = {
|
|
33
|
-
jsonrpc: "2.0",
|
|
34
|
-
method: "eth_getBlockByNumber",
|
|
35
|
-
params: [`0x${height.toString(16)}`, true],
|
|
36
|
-
id: 1
|
|
37
|
-
};
|
|
38
|
-
const response = await fetch(PROTOCOLS[protocol].endpoint, {
|
|
39
|
-
method: "POST",
|
|
40
|
-
headers: {
|
|
41
|
-
"Content-Type": "application/json"
|
|
42
|
-
},
|
|
43
|
-
body: JSON.stringify(body)
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
const { result: block } = await response.json();
|
|
47
|
-
|
|
48
|
-
return block;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async function getLatestBlockHeight(protocol) {
|
|
52
|
-
const web3 = new Web3(PROTOCOLS[protocol].endpoint);
|
|
53
|
-
const isSyncing = await web3.eth.isSyncing();
|
|
54
|
-
|
|
55
|
-
if (isSyncing) {
|
|
56
|
-
return isSyncing.currentBlock;
|
|
57
|
-
} else {
|
|
58
|
-
const latestBlock = await web3.eth.getBlock("latest");
|
|
59
|
-
|
|
60
|
-
return latestBlock.number;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async function getLatestS3BlockHeight(protocol) {
|
|
65
|
-
const name = `AMLBlockIndexerSince(protocol=${protocol})`;
|
|
66
|
-
const { value: height } = await getRecordByKey(INDEXER_STATE_TABLE, { name });
|
|
67
|
-
return height;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async function getBlockFromS3(protocol, height) {
|
|
71
|
-
const body = await readFile(S3_BUCKET_NAME, getBlockS3Path(protocol, height));
|
|
72
|
-
|
|
73
|
-
return JSON.parse(body);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export {
|
|
77
|
-
getLatestBlockHeight,
|
|
78
|
-
getBlock,
|
|
79
|
-
getBlockS3Path,
|
|
80
|
-
getLatestS3BlockHeight,
|
|
81
|
-
getBlockFromS3
|
|
82
|
-
};
|
package/distributed-lock.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export function useLock(useLockParams: { name: string, ttl: string, verbose: boolean }): Promise<string | null>
|
package/distributed-lock.js
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
async function acquireLock(name, ttl) {
|
|
2
|
-
try {
|
|
3
|
-
const res = await fetch("http://localhost:8500/v1/session/create", {
|
|
4
|
-
method: "PUT",
|
|
5
|
-
body: JSON.stringify({
|
|
6
|
-
Name: name,
|
|
7
|
-
TTL: `${ttl}s`,
|
|
8
|
-
Behavior: "delete",
|
|
9
|
-
}),
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
if (res.ok) {
|
|
13
|
-
const { ID: id } = await res.json();
|
|
14
|
-
|
|
15
|
-
return id;
|
|
16
|
-
} else {
|
|
17
|
-
console.log(res, await res.text());
|
|
18
|
-
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
} catch (fetchErr) {
|
|
22
|
-
// console.log("error fetching", fetchErr);
|
|
23
|
-
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async function renewLock(uid) {
|
|
29
|
-
try {
|
|
30
|
-
const res = await fetch(`http://localhost:8500/v1/session/renew/${uid}`, {
|
|
31
|
-
method: "PUT",
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
if (res.ok) {
|
|
35
|
-
return uid;
|
|
36
|
-
} else {
|
|
37
|
-
console.log(res, await res.text());
|
|
38
|
-
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
} catch (fetchErr) {
|
|
42
|
-
// console.log("error fetching", fetchErr);
|
|
43
|
-
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async function hasLock(name, uid = null) {
|
|
49
|
-
try {
|
|
50
|
-
const res = await fetch(`http://localhost:8500/v1/session/list`);
|
|
51
|
-
|
|
52
|
-
if (res.ok) {
|
|
53
|
-
const sessions = await res.json();
|
|
54
|
-
|
|
55
|
-
const sessionsWithTheSameName = sessions.filter((s) => s.Name === name);
|
|
56
|
-
|
|
57
|
-
if (!uid) {
|
|
58
|
-
return sessionsWithTheSameName.length === 0;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (sessionsWithTheSameName.length !== 1) {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// only one should have the same uid
|
|
66
|
-
return sessionsWithTheSameName[0].ID === uid;
|
|
67
|
-
} else {
|
|
68
|
-
console.log(await res.text());
|
|
69
|
-
|
|
70
|
-
return true;
|
|
71
|
-
}
|
|
72
|
-
} catch (fetchErr) {
|
|
73
|
-
// console.log("error fetching", fetchErr);
|
|
74
|
-
|
|
75
|
-
return true;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export async function useLock({ name, ttl, verbose }) {
|
|
80
|
-
const lockWarningMessage = `only one process with the same lock name ${name} should be running, terminate current process`;
|
|
81
|
-
|
|
82
|
-
const lockAvailable = await hasLock(name);
|
|
83
|
-
|
|
84
|
-
if (!lockAvailable) {
|
|
85
|
-
console.log(lockWarningMessage);
|
|
86
|
-
process.exit(0);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
let uid = await acquireLock(name, ttl);
|
|
90
|
-
|
|
91
|
-
setInterval(async () => {
|
|
92
|
-
if (!(await hasLock(name, uid))) {
|
|
93
|
-
console.log(lockWarningMessage);
|
|
94
|
-
process.exit(0);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (uid) {
|
|
98
|
-
if (verbose) {
|
|
99
|
-
console.log("renewing", name, uid);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
uid = await renewLock(uid);
|
|
103
|
-
} else {
|
|
104
|
-
uid = await acquireLock(name, ttl);
|
|
105
|
-
}
|
|
106
|
-
}, (ttl * 1000) / 2);
|
|
107
|
-
|
|
108
|
-
return uid;
|
|
109
|
-
}
|
package/price.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
type PricePreviousRecord = {
|
|
2
|
-
address: string;
|
|
3
|
-
price: number;
|
|
4
|
-
timestamp: number;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export function getPriceClosestTo(tableName: string, address: string, timestamp: number): Promise<number>;
|
|
8
|
-
export function getPricePreviousRecord(tableName: string, address: string, timestamp: number): Promise<PricePreviousRecord | null>;
|
package/price.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { QueryCommand } from "@aws-sdk/lib-dynamodb";
|
|
2
|
-
import { getDocClient } from "./dynamodb.js";
|
|
3
|
-
|
|
4
|
-
async function queryPrice(tableName, address, timestamp, op = "<") {
|
|
5
|
-
const docClient = getDocClient();
|
|
6
|
-
|
|
7
|
-
return await docClient.send(
|
|
8
|
-
new QueryCommand({
|
|
9
|
-
TableName: tableName,
|
|
10
|
-
KeyConditionExpression: `#address = :address and #timestamp ${op} :timestamp`,
|
|
11
|
-
ExpressionAttributeNames: {
|
|
12
|
-
"#timestamp": "timestamp",
|
|
13
|
-
"#address": "address",
|
|
14
|
-
},
|
|
15
|
-
ExpressionAttributeValues: {
|
|
16
|
-
":timestamp": timestamp,
|
|
17
|
-
":address": address,
|
|
18
|
-
},
|
|
19
|
-
Limit: 1,
|
|
20
|
-
ScanIndexForward: false,
|
|
21
|
-
}),
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async function getPricePreviousRecord(tableName, address, timestamp) {
|
|
26
|
-
const query = await queryPrice(tableName, address, timestamp, "<");
|
|
27
|
-
|
|
28
|
-
if (query.Count === 0) {
|
|
29
|
-
return null;
|
|
30
|
-
} else {
|
|
31
|
-
return query.Items[0];
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async function getPriceClosestTo(tableName, address, timestamp) {
|
|
36
|
-
const query = await queryPrice(tableName, address, timestamp, "<=");
|
|
37
|
-
|
|
38
|
-
if (query.Count === 0) {
|
|
39
|
-
return 0;
|
|
40
|
-
} else {
|
|
41
|
-
const { price } = query.Items[0];
|
|
42
|
-
return price;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export { getPriceClosestTo, getPricePreviousRecord };
|
package/primitive.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { DynamoDB } from "aws-sdk";
|
|
2
|
-
|
|
3
|
-
type Issue = {
|
|
4
|
-
code: string;
|
|
5
|
-
link: string;
|
|
6
|
-
reduction: number;
|
|
7
|
-
title: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function getOverrides(
|
|
11
|
-
docClient: DynamoDB.DocumentClient,
|
|
12
|
-
projectId: string,
|
|
13
|
-
address: string,
|
|
14
|
-
log: (...data: any[]) => void,
|
|
15
|
-
primitive: string
|
|
16
|
-
): Promise<string[] | null>;
|
|
17
|
-
|
|
18
|
-
export function overrideScoreAndIssues(
|
|
19
|
-
docClient: DynamoDB.DocumentClient,
|
|
20
|
-
projectId: string,
|
|
21
|
-
address: string,
|
|
22
|
-
score: number,
|
|
23
|
-
issues: Issue[],
|
|
24
|
-
log: (...data: any[]) => void,
|
|
25
|
-
primitive: string
|
|
26
|
-
): Promise<{
|
|
27
|
-
score: number;
|
|
28
|
-
issues: Issue[];
|
|
29
|
-
}>
|
package/primitive.js
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
async function getOverrides(docClient, projectId, address, log, primitive) {
|
|
2
|
-
try {
|
|
3
|
-
console.log("ProjectId:" + projectId + " address:" + address);
|
|
4
|
-
|
|
5
|
-
const whitelist = [];
|
|
6
|
-
const queryProjectOverrides = await docClient
|
|
7
|
-
.get({
|
|
8
|
-
TableName: "skynet-prd-primitive-manual-overrides",
|
|
9
|
-
Key: {
|
|
10
|
-
primitive: primitive,
|
|
11
|
-
overrideId: "project/" + projectId,
|
|
12
|
-
},
|
|
13
|
-
})
|
|
14
|
-
.promise();
|
|
15
|
-
if (queryProjectOverrides.Item && queryProjectOverrides.Item.whitelist) {
|
|
16
|
-
whitelist.push(...queryProjectOverrides.Item.whitelist);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const queryAddressOverrides = await docClient
|
|
20
|
-
.get({
|
|
21
|
-
TableName: "skynet-prd-primitive-manual-overrides",
|
|
22
|
-
Key: {
|
|
23
|
-
primitive: primitive,
|
|
24
|
-
overrideId: "address/" + address,
|
|
25
|
-
},
|
|
26
|
-
})
|
|
27
|
-
.promise();
|
|
28
|
-
|
|
29
|
-
if (queryAddressOverrides.Item && queryAddressOverrides.Item.whitelist) {
|
|
30
|
-
console.log(queryAddressOverrides.Item.whitelist);
|
|
31
|
-
whitelist.push(...queryAddressOverrides.Item.whitelist);
|
|
32
|
-
}
|
|
33
|
-
if (whitelist.length === 0) {
|
|
34
|
-
log(
|
|
35
|
-
"ProjectId " + projectId + " ,Address " + address + " has no override"
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
console.log("Whitelist:" + whitelist);
|
|
39
|
-
return whitelist;
|
|
40
|
-
} catch (scanFeedErr) {
|
|
41
|
-
log("scan feed error, check dynamodb table", scanFeedErr);
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async function overrideScoreAndIssues(
|
|
47
|
-
docClient,
|
|
48
|
-
projectId,
|
|
49
|
-
address,
|
|
50
|
-
score,
|
|
51
|
-
issues,
|
|
52
|
-
log,
|
|
53
|
-
primitive
|
|
54
|
-
) {
|
|
55
|
-
const overrides = await getOverrides(
|
|
56
|
-
docClient,
|
|
57
|
-
projectId,
|
|
58
|
-
address,
|
|
59
|
-
log,
|
|
60
|
-
primitive
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
issues = issues.filter((issue) => {
|
|
64
|
-
if (overrides.includes(issue.code)) {
|
|
65
|
-
score += issue.reduction;
|
|
66
|
-
return false;
|
|
67
|
-
} else return true;
|
|
68
|
-
});
|
|
69
|
-
return {
|
|
70
|
-
score,
|
|
71
|
-
issues,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export {
|
|
76
|
-
getOverrides,
|
|
77
|
-
overrideScoreAndIssues,
|
|
78
|
-
};
|
package/token.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { BigNumber } from "bignumber.js";
|
|
2
|
-
|
|
3
|
-
export function getTokenPriceAt(tokenAddress: string, timestamp: number, useCache: boolean | undefined): Promise<number>;
|
|
4
|
-
export function toNativeDecimal(bigNumber: BigNumber, decimals: number): Promise<BigNumber>;
|
|
5
|
-
export function toHumanDecimal(bigNumber: BigNumber, decimals: number): Promise<BigNumber>;
|
package/token.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { getEnvironment } from "./env.js";
|
|
2
|
-
import { getPriceClosestTo } from "./price.js";
|
|
3
|
-
import BigNumber from "bignumber.js";
|
|
4
|
-
|
|
5
|
-
const TOKEN_PRICE_TABLE_NAME = `skynet-${getEnvironment()}-token-prices`;
|
|
6
|
-
const TOKEN_PRICE_CACHE = {};
|
|
7
|
-
|
|
8
|
-
async function getTokenPriceAt(tokenAddress, timestamp, useCache = true) {
|
|
9
|
-
// to avoid huge amount of dynamodb query
|
|
10
|
-
// "ceil" timestamp to the closest proximate timestamp
|
|
11
|
-
// 100_000 seconds ~= a bit more than 1 day 86_400 seconds
|
|
12
|
-
// and use cache
|
|
13
|
-
const proximateTimestamp = timestamp + 100_000 - (timestamp % 100_000);
|
|
14
|
-
|
|
15
|
-
if (useCache && TOKEN_PRICE_CACHE[tokenAddress] && TOKEN_PRICE_CACHE[tokenAddress][proximateTimestamp]) {
|
|
16
|
-
return TOKEN_PRICE_CACHE[tokenAddress][proximateTimestamp];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const price = await getPriceClosestTo(TOKEN_PRICE_TABLE_NAME, tokenAddress, proximateTimestamp);
|
|
20
|
-
|
|
21
|
-
if (useCache) {
|
|
22
|
-
if (!TOKEN_PRICE_CACHE[tokenAddress]) {
|
|
23
|
-
TOKEN_PRICE_CACHE[tokenAddress] = {};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
TOKEN_PRICE_CACHE[tokenAddress][proximateTimestamp] = price;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return price;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function toNativeDecimal(bigNumber, decimals) {
|
|
33
|
-
const dividend = new BigNumber(10).exponentiatedBy(new BigNumber(decimals));
|
|
34
|
-
return new BigNumber(bigNumber).multipliedBy(dividend);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function toHumanDecimal(bigNumber, decimals) {
|
|
38
|
-
const dividend = new BigNumber(10).exponentiatedBy(new BigNumber(decimals));
|
|
39
|
-
return new BigNumber(bigNumber).dividedBy(dividend);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export {
|
|
43
|
-
getTokenPriceAt,
|
|
44
|
-
toNativeDecimal,
|
|
45
|
-
toHumanDecimal,
|
|
46
|
-
};
|
package/transaction.d.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
type Log = {
|
|
2
|
-
address: string,
|
|
3
|
-
topics: string[],
|
|
4
|
-
data: string,
|
|
5
|
-
blockNumber: string,
|
|
6
|
-
transactionHash: string,
|
|
7
|
-
transactionIndex: string,
|
|
8
|
-
blockHash: string,
|
|
9
|
-
logIndex: string,
|
|
10
|
-
removed: boolean
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
type TransactionReceipt = {
|
|
14
|
-
blockHash: string,
|
|
15
|
-
blockNumber: string,
|
|
16
|
-
contractAddress: string | null,
|
|
17
|
-
cumulativeGasUsed: string,
|
|
18
|
-
effectiveGasPrice: string,
|
|
19
|
-
from: string,
|
|
20
|
-
gasUsed: string,
|
|
21
|
-
logs: Log[],
|
|
22
|
-
logsBloom: string,
|
|
23
|
-
status: string,
|
|
24
|
-
to: string,
|
|
25
|
-
transactionHash: string,
|
|
26
|
-
transactionIndex: string,
|
|
27
|
-
type: string
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function getTxReceipt(protocol: string, txHash: string, verbose: boolean): Promise<TransactionReceipt | null>;
|
package/transaction.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { PROTOCOLS } from "./const.js";
|
|
2
|
-
import { exponentialRetry } from "./availability.js";
|
|
3
|
-
|
|
4
|
-
async function getTxReceipt(protocol, txHash, verbose = false) {
|
|
5
|
-
const { endpoint } = PROTOCOLS[protocol];
|
|
6
|
-
|
|
7
|
-
console.log("got endpoint", protocol, endpoint);
|
|
8
|
-
|
|
9
|
-
const body = {
|
|
10
|
-
jsonrpc: "2.0",
|
|
11
|
-
method: "eth_getTransactionReceipt",
|
|
12
|
-
params: [txHash],
|
|
13
|
-
id: 1
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const response = await exponentialRetry(
|
|
17
|
-
() => {
|
|
18
|
-
return fetch(endpoint, {
|
|
19
|
-
method: "POST",
|
|
20
|
-
headers: { "Content-Type": "application/json" },
|
|
21
|
-
body: JSON.stringify(body)
|
|
22
|
-
});
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
maxRetry: 6,
|
|
26
|
-
test: r => r.ok,
|
|
27
|
-
verbose
|
|
28
|
-
}
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
if (!response.ok) {
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const { result } = await response.json();
|
|
36
|
-
|
|
37
|
-
return result;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export {
|
|
41
|
-
getTxReceipt
|
|
42
|
-
};
|