-
Notifications
You must be signed in to change notification settings - Fork 84
/
index.ts
182 lines (157 loc) · 5.9 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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
import fs from "fs";
import { write } from "fast-csv";
/**
* The objective is to quantify:
* - TVL on Linea (size of collateral minting GRAI on Linea)
* - GRAI stability pool deposits on Linea
*
* For that, we'll be querying an existing Gravita Subgraph deployed on TheGraph.
*/
type OutputDataSchemaRow = {
block_number: number;
timestamp: number;
user_address: string;
token_address: string;
token_balance: bigint;
token_symbol: string;
};
const LINEA_RPC = "https://rpc.linea.build";
const GRAI_ADDRESS = "0x894134a25a5faC1c2C26F1d8fBf05111a3CB9487";
const GRAVITA_SUBGRAPH_QUERY_URL = "https://api.studio.thegraph.com/query/54829/gravita-sp-lp-linea-v1/version/latest";
const GRAVITA_STABILITY_POOL_QUERY = `
query StabilityPoolQuery {
poolDeposits(first: 1000, where: { poolName: "Gravita StabilityPool", withdrawTxHash: null }) {
user {
id
}
amountA
}
}
`;
const GRAVITA_VESSELS_QUERY = `
query VesselsQuery {
vessels(first: 1000, where: { closeTimestamp: null }) {
asset
user {
id
}
updates {
timestamp
assetAmount
}
}
}
`;
const post = async (url: string, data: any): Promise<any> => {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(data),
});
return await response.json();
};
const getLatestBlockNumberAndTimestamp = async () => {
const data = await post(LINEA_RPC, {
jsonrpc: "2.0",
method: "eth_getBlockByNumber",
params: ["latest", false],
id: 1,
});
const blockNumber = parseInt(data.result.number);
const blockTimestamp = parseInt(data.result.timestamp);
return { blockNumber, blockTimestamp };
};
const getBlockTimestamp = async (number: number): Promise<number> => {
const hexBlockNumber = "0x" + number.toString(16); // Convert decimal block number to hexadecimal
console.log(hexBlockNumber)
const data = await post(LINEA_RPC, {
jsonrpc: "2.0",
method: "eth_getBlockByNumber",
params: [hexBlockNumber, false],
id: 1,
});
const blockTimestampInt = parseInt(data.result.timestamp);
console.log(blockTimestampInt)
return blockTimestampInt;
};
const getStabilityPoolData = async (blockNumber: number, blockTimestamp: number): Promise<OutputDataSchemaRow[]> => {
const csvRows: OutputDataSchemaRow[] = [];
const responseJson = await post(GRAVITA_SUBGRAPH_QUERY_URL, { query: GRAVITA_STABILITY_POOL_QUERY });
for (const item of responseJson.data.poolDeposits) {
csvRows.push({
block_number: blockNumber,
timestamp: blockTimestamp,
user_address: item.user.id,
token_address: GRAI_ADDRESS,
token_balance: item.amountA,
token_symbol: "",
});
}
return csvRows;
};
const getVesselDepositsData = async (blockNumber: number, blockTimestamp: number): Promise<OutputDataSchemaRow[]> => {
const csvRows: OutputDataSchemaRow[] = [];
const responseJson = await post(GRAVITA_SUBGRAPH_QUERY_URL, { query: GRAVITA_VESSELS_QUERY });
for (const item of responseJson.data.vessels) {
const sortedUpdates = item.updates.sort((a: any, b: any) => b.timestamp - a.timestamp);
const updatedAssetAmount = sortedUpdates[0].assetAmount;
csvRows.push({
block_number: blockNumber,
timestamp: blockTimestamp,
user_address: item.user.id,
token_address: item.asset,
token_balance: updatedAssetAmount,
token_symbol: "",
});
}
return csvRows;
};
interface BlockData {
blockNumber: number;
blockTimestamp: number;
}
export const main = async (blocks: BlockData[]) => {
const allCsvRows: any[] = []; // Array to accumulate CSV rows for all blocks
const batchSize = 10; // Size of batch to trigger writing to the file
let i = 0;
for (const { blockNumber, blockTimestamp } of blocks) {
try {
// Retrieve data using block number and timestamp
const csvRowsStabilityPool = await getStabilityPoolData(blockNumber, blockTimestamp);
const csvRowsVessels = await getVesselDepositsData(blockNumber, blockTimestamp);
const csvRows = csvRowsStabilityPool.concat(csvRowsVessels);
// Accumulate CSV rows for all blocks
allCsvRows.push(...csvRows);
i++;
console.log(`Processed block ${i}`);
// Write to file when batch size is reached or at the end of loop
if (i % batchSize === 0 || i === blocks.length) {
const ws = fs.createWriteStream(`outputData.csv`, { flags: i === batchSize ? 'w' : 'a' });
write(allCsvRows, { headers: i === batchSize ? true : false })
.pipe(ws)
.on("finish", () => {
console.log(`CSV file has been written.`);
});
// Clear the accumulated CSV rows
allCsvRows.length = 0;
}
} catch (error) {
console.error(`An error occurred for block ${blockNumber}:`, error);
}
}
};
export const getUserTVLByBlock = async (blocks: BlockData) => {
const { blockNumber, blockTimestamp } = blocks
// Retrieve data using block number and timestamp
const csvRowsStabilityPool = await getStabilityPoolData(blockNumber, blockTimestamp);
const csvRowsVessels = await getVesselDepositsData(blockNumber, blockTimestamp);
const csvRows = csvRowsStabilityPool.concat(csvRowsVessels);
return csvRows
};
// main().then(() => {
// console.log("Done");
// });
// getBlockTimestamp(3041106).then(() => { console.log("done") });