@intuweb3/sdk
Version:
INTU SDK - Modern blockchain interaction toolkit
132 lines • 5.43 kB
JavaScript
import { ethers } from "ethers";
import { loadJson, JSON_PATHS } from "../../utils/json-imports.js";
let VaultJson;
(async () => {
VaultJson = await loadJson(JSON_PATHS.VAULT);
})();
export async function getBlockHeightFromRPC(provider) {
try {
const blockNumber = await provider.getBlockNumber();
return blockNumber;
}
catch (error) {
console.error("Failed to get block height from RPC:", error);
throw error;
}
}
export async function getBlockHeightFromIndexer(indexerUrl) {
try {
console.log("🔍 Querying block height from indexer:", indexerUrl);
const response = await fetch(indexerUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query: `{
chain_metadata {
block_height
}
}`,
}),
});
console.log("📡 Response status:", response.status, response.statusText);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
console.log("📄 Response data:", JSON.stringify(data, null, 2));
let blockHeight;
if (Array.isArray(data?.data?.chain_metadata)) {
blockHeight = data?.data?.chain_metadata?.[0]?.block_height;
}
else {
blockHeight = data?.data?.chain_metadata?.block_height;
}
if (blockHeight === undefined || blockHeight === null) {
console.warn("Block height not available from indexer response");
throw new Error("Block height not available from indexer");
}
console.log("✅ Block height retrieved:", blockHeight);
return blockHeight;
}
catch (error) {
console.error("Failed to get block height from indexer:", error);
throw error;
}
}
export async function isIndexerBehind(provider, indexerUrl, threshold = 60) {
try {
const rpcHeight = await getBlockHeightFromRPC(provider);
try {
const indexerHeight = await getBlockHeightFromIndexer(indexerUrl);
const difference = rpcHeight - indexerHeight;
console.log(`Block height difference: ${difference} (RPC: ${rpcHeight}, Indexer: ${indexerHeight})`);
return difference > threshold;
}
catch (indexerError) {
console.log(`Block height comparison skipped - indexer doesn't support block height queries (RPC: ${rpcHeight}, Indexer: unavailable)`);
return false;
}
}
catch (error) {
console.error("Error checking block heights:", error);
return true;
}
}
export async function getUserPreRegisterInfosDirect(vaultAddress, userAddress, provider) {
const vaultContract = new ethers.Contract(vaultAddress, VaultJson.abi, provider);
const [isRegistered, parisEncKey, megaPublicKey, encMegaSecretKey, dbKey] = await Promise.all([
vaultContract.isRegistered(userAddress),
vaultContract.getParisEncKey(userAddress),
vaultContract.getMegaPublicKey(userAddress),
vaultContract.getEncMegaSecretKey(userAddress),
vaultContract.getDbKey(userAddress),
]);
return {
user: userAddress,
registered: isRegistered,
parisEncKey: parisEncKey || "",
megaPublicKey: megaPublicKey || "",
encMegaSecretKey: encMegaSecretKey || "",
dbKey: dbKey || "",
};
}
export async function retryWithIndexerFallback(indexerFn, directFn, provider, indexerUrl, retries = 5, delay = 1000) {
try {
const indexerBehind = await isIndexerBehind(provider, indexerUrl);
if (indexerBehind) {
console.log("Indexer is behind, using direct RPC calls");
return await directFn();
}
return await indexerFn();
}
catch (error) {
console.log(`Attempt failed, retries left: ${retries}. Error:`, error?.message || error);
if (retries === 0) {
throw error;
}
await new Promise((resolve) => setTimeout(resolve, delay));
return retryWithIndexerFallback(indexerFn, directFn, provider, indexerUrl, retries - 1, delay);
}
}
export async function getDataWithFallback(indexerFn, provider, indexerUrl, blockThreshold = 25) {
try {
const rpcHeight = await getBlockHeightFromRPC(provider);
try {
const indexerHeight = await getBlockHeightFromIndexer(indexerUrl);
const blockDifference = rpcHeight - indexerHeight;
console.log(`Block height difference: ${blockDifference} (RPC: ${rpcHeight}, Indexer: ${indexerHeight})`);
if (blockDifference > blockThreshold) {
console.warn(`Indexer is ${blockDifference} blocks behind RPC. Proceeding anyway – fetchSubgraphData will attempt backup endpoint.`);
}
}
catch (indexerError) {
console.log(`Block height comparison skipped - indexer doesn't support block height queries (RPC: ${rpcHeight}, Indexer: unavailable)`);
}
return await indexerFn();
}
catch (error) {
console.warn("Block height check failed or indexer fetch threw an error, retrying indexer function:", error.message || error);
return await indexerFn();
}
}
//# sourceMappingURL=index.js.map