Files
extractor/full-extractor.ts
2025-05-04 17:28:00 +05:00

100 lines
2.8 KiB
TypeScript

import { APIClient, Name } from "@wharfkit/antelope";
import fs from "fs-extra";
import { config } from "./config2.js";
import dotenv from "dotenv";
dotenv.config();
const client = new APIClient({ url: config.endpoint });
async function fetchContractABI(contractName: string) {
try {
const response = await client.v1.chain.get_abi(Name.from(contractName));
return response.abi;
} catch (error) {
console.error(`Error fetching ABI for ${contractName}:`, error);
return null;
}
}
async function fetchTable(contract: string, table: string, scope: string) {
try {
const response = await client.v1.chain.get_table_rows({
code: contract,
table: table,
scope: scope,
json: true,
limit: config.limit_per_request
});
return response.rows;
} catch (error) {
console.error(`Error fetching table ${contract}/${table}/${scope}:`, error);
return [];
}
}
function containsTargetFields(data: any): boolean {
if (typeof data !== 'object' || data === null) return false;
// Check if object contains both hash and public_key
const hasHash = 'hash' in data;
const hasPublicKey = 'public_key' in data || 'publicKey' in data;
if (hasHash && hasPublicKey) return true;
// Recursively check nested objects
for (const key in data) {
if (containsTargetFields(data[key])) {
return true;
}
}
return false;
}
async function processContract(contractName: string, baseDir: string) {
const abi = await fetchContractABI(contractName);
if (!abi) return;
const tables = abi.tables;
if (!tables) return;
console.log(`Processing contract ${contractName} with ${tables.length} tables`);
for (const table of tables) {
for (const scope of config.scopes) {
try {
const tableData = await fetchTable(contractName, table.name, scope);
if (!tableData.length) continue;
// Filter rows if search_fields is specified
const filteredData = config.search_fields
? tableData.filter(row => containsTargetFields(row))
: tableData;
if (!filteredData.length) continue;
const scopeDir = `${baseDir}/${scope}`;
await fs.ensureDir(scopeDir);
const filePath = `${scopeDir}/${contractName}_${table.name}.json`;
await fs.writeJson(filePath, filteredData, { spaces: 2 });
console.log(`Saved: ${filePath} with ${filteredData.length} records`);
} catch (error) {
console.error(`Error processing ${contractName}/${table.name}/${scope}:`, error);
}
}
}
}
async function extractAllTables() {
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
const baseDir = `./extracted_data/${config.environment}/${timestamp}`;
await fs.ensureDir(baseDir);
for (const contract of config.contracts) {
await processContract(contract, baseDir);
}
}
extractAllTables();