-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmdw.ts
More file actions
129 lines (109 loc) · 4.19 KB
/
mdw.ts
File metadata and controls
129 lines (109 loc) · 4.19 KB
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
import {
ContractAddress,
ContractLog,
MdwPaginatedResponse,
PayingForTx,
Transaction,
TransactionWithContext, TxHash
} from "./model";
import fs from 'fs';
const LIMIT = 100;
const DIRECTION = 'forward';
const INT_AS_STRING = true;
const MDW_URL = 'https://mainnet.aeternity.io/mdw'
const defaultParams = `direction=${DIRECTION}&limit=${LIMIT}&int-as-string=${INT_AS_STRING}`;
const MAINNET_ROUTER = 'ct_azbNZ1XrPjXfqBqbAh1ffLNTQ1sbnuUDFvJrXjYz7JQA1saQ3';
export const transactionSenderMapping = new Map<string, string>();
export function getContractLogsUntilCondition(
condition: (contractLog: ContractLog) => boolean,
contractAddress: ContractAddress,
): Promise<ContractLog[]> {
return getPagesUntilCondition<ContractLog>(
condition,
`/v2/contracts/logs?contract_id=${contractAddress}&direction=backward&limit=${LIMIT}&int-as-string=${INT_AS_STRING}`,
);
}
export function getAllContractLogs(contractAddress: ContractAddress): Promise<ContractLog[]> {
return getAllPages<ContractLog>(
`/v2/contracts/logs?contract_id=${contractAddress}&direction=backward&limit=${LIMIT}&int-as-string=${INT_AS_STRING}`,
);
}
async function get<T>(url: string): Promise<T> {
const fullUrl = `${MDW_URL}${url}`;
return fetch(fullUrl).then(res => res.json()) as Promise<T>;
}
// Fetches pages from middleware until the page contains at least one entry that meets the condition
async function getPagesUntilCondition<T>(
condition: (data: T) => boolean,
next: string,
): Promise<T[]> {
const result = await get<MdwPaginatedResponse<T>>(
next + `&int-as-string=${INT_AS_STRING}`,
);
if (result.data.filter(condition).length === 0 && result.next) {
return result.data.concat(
await getPagesUntilCondition<T>(condition, result.next),
);
}
return result.data;
}
export async function getSenderAccountForTransaction(txHash: TxHash): Promise<string> {
if (!transactionSenderMapping.has(txHash)) {
const tx = await getTransaction(txHash);
transactionSenderMapping.set(
txHash,
getSenderFromTransaction(tx),
);
}
return transactionSenderMapping.get(txHash)!;
}
export async function getTransaction(txHash: string): Promise<TransactionWithContext> {
return get(`/v3/transactions/${txHash}`);
}
async function getAllPages<T>(next: string): Promise<T[]> {
const result = await get<MdwPaginatedResponse<T>>(next);
if (result.next) {
return result.data.concat(await getAllPages(result.next));
}
return result.data;
}
export async function fillTransactionSenderMapping(): Promise<void> {
// load all transactions from json cache
const oldTxs: string = fs.readFileSync('./transactions_router.json', 'utf8');
const oldTxsParsed: TransactionWithContext[] = JSON.parse(oldTxs);
// create a map of transaction hash to transaction
const txHashMap = new Map<string, TransactionWithContext>();
oldTxsParsed.forEach((tx) => {
txHashMap.set(tx.hash, tx);
});
const fetchedTransactions = await getPagesUntilCondition<TransactionWithContext>(
(tx) => {
const txHash = tx.hash;
return txHashMap.has(txHash);
},
`/v3/transactions?contract_id=${MAINNET_ROUTER}&direction=backward&limit=${LIMIT}`,
);
// filter out transactions that are already in the map
const newTransactions = fetchedTransactions.filter((tx) => {
return !txHashMap.has(tx.hash);
});
const transactions = [...newTransactions, ...oldTxsParsed];
// save all transactions to json cache
console.log('Saving transactions to json cache');
fs.writeFileSync('./transactions_router.json', JSON.stringify(transactions));
transactions.forEach((tx) => {
transactionSenderMapping.set(
tx.hash,
getSenderFromTransaction(tx),
);
});
}
function getSenderFromTransaction(
transactionWithContext: TransactionWithContext,
): string {
if (transactionWithContext.tx.type === 'PayingForTx') {
return (transactionWithContext.tx as PayingForTx).tx.tx.caller_id;
} else {
return (transactionWithContext.tx as Transaction).caller_id;
}
}