-
Notifications
You must be signed in to change notification settings - Fork 5
/
index.ts
140 lines (123 loc) · 3.93 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import { CHAINS, PROTOCOLS } from "./sdk/config";
import {
getAccountStatesForAddressByPoolAtBlock,
getTimestampAtBlock,
} from "./sdk/subgraphDetails";
(BigInt.prototype as any).toJSON = function () {
return this.toString();
};
import fs from "fs";
import csv from "csv-parser";
import { write } from "fast-csv";
import { getMarketInfos, updateBorrowBalances } from "./sdk/marketDetails";
import { bigMath } from "./sdk/abi/helpers";
import { exit } from "process";
interface BlockData {
blockNumber: number;
blockTimestamp: number;
}
type OutputDataSchemaRow = {
user_address: string;
market: string;
token_address: string;
underlying_decimals: number;
token_symbol: string;
supply_token: number;
borrow_token: number;
block_number: number;
timestamp: number;
protocol: string;
etl_timestamp: number;
};
export const getUserTVLByBlock = async (blocks: BlockData) => {
const marketInfos = await getMarketInfos(
"0xEC53c830f4444a8A56455c6836b5D2aA794289Aa"
);
const csvRows: OutputDataSchemaRow[] = [];
const block = blocks.blockNumber;
let states = await getAccountStatesForAddressByPoolAtBlock(
block,
"",
"",
CHAINS.SCROLL,
PROTOCOLS.LAYERBANK
);
states = states.filter(
(s) => marketInfos.findIndex((lu) => lu.address == s.account) == -1
);
console.log(`Block: ${block}`);
console.log("States: ", states.length);
await updateBorrowBalances(states, BigInt(block));
states.forEach((state) => {
const marketInfo = marketInfos.find(
(mi) => mi.underlyingAddress.toLowerCase() == state.token.toLowerCase()
);
// Check if marketInfo is defined before pushing to csvRows
if (marketInfo) {
csvRows.push({
protocol: "Layerbank",
timestamp: blocks.blockTimestamp,
block_number: blocks.blockNumber,
etl_timestamp: Math.floor(Date.now() / 1000),
token_address: marketInfo.underlyingAddress.toLowerCase(),
underlying_decimals: marketInfo.underlyingDecimals,
token_symbol: marketInfo.underlyingSymbol,
user_address: state.account.toLowerCase(),
market: marketInfo.address.toLowerCase(),
supply_token: state.lentAmount,
borrow_token: state.borrowAmount,
});
} else {
console.warn(`Market info not found for token: ${state.token}`);
}
});
return csvRows;
};
const readBlocksFromCSV = async (filePath: string): Promise<BlockData[]> => {
const blocks: BlockData[] = [];
await new Promise<void>((resolve, reject) => {
fs.createReadStream(filePath)
.pipe(csv()) // Specify the separator as '\t' for TSV files
.on("data", (row) => {
const blockNumber = parseInt(row.number, 10);
const blockTimestamp = parseInt(row.timestamp, 10);
if (!isNaN(blockNumber) && blockTimestamp) {
blocks.push({ blockNumber: blockNumber, blockTimestamp });
}
})
.on("end", () => {
resolve();
})
.on("error", (err) => {
reject(err);
});
});
return blocks;
};
readBlocksFromCSV("hourly_blocks.csv")
.then(async (blocks: any[]) => {
console.log(blocks);
const allCsvRows: any[] = []; // Array to accumulate CSV rows for all blocks
for (const block of blocks) {
try {
const result = await getUserTVLByBlock(block);
for (let i = 0; i < result.length; i++) {
allCsvRows.push(result[i]);
}
} catch (error) {
console.error(`An error occurred for block ${block}:`, error);
}
}
await new Promise((resolve, reject) => {
const ws = fs.createWriteStream(`outputData.csv`, { flags: "w" });
write(allCsvRows, { headers: true })
.pipe(ws)
.on("finish", () => {
console.log(`CSV file has been written.`);
resolve;
});
});
})
.catch((err) => {
console.error("Error reading CSV file:", err);
});