2021-11-01 07:15:12 +00:00
|
|
|
import { useState, useEffect, useRef } from "react";
|
2021-10-31 00:49:23 +00:00
|
|
|
import { JsonRpcProvider } from "@ethersproject/providers";
|
2021-10-31 01:44:33 +00:00
|
|
|
import { ProcessedTransaction, TransactionData } from "./types";
|
2021-10-31 00:49:23 +00:00
|
|
|
import { batchPopulate, ResolvedAddresses } from "./api/address-resolver";
|
2021-11-01 20:09:47 +00:00
|
|
|
import { TraceGroup } from "./useErigonHooks";
|
2021-10-31 00:49:23 +00:00
|
|
|
|
|
|
|
export type AddressCollector = () => string[];
|
|
|
|
|
|
|
|
export const pageCollector =
|
|
|
|
(page: ProcessedTransaction[] | undefined): AddressCollector =>
|
|
|
|
() => {
|
|
|
|
if (!page) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
const uniqueAddresses = new Set<string>();
|
|
|
|
for (const tx of page) {
|
|
|
|
if (tx.from) {
|
|
|
|
uniqueAddresses.add(tx.from);
|
|
|
|
}
|
|
|
|
if (tx.to) {
|
|
|
|
uniqueAddresses.add(tx.to);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Array.from(uniqueAddresses);
|
|
|
|
};
|
|
|
|
|
2021-10-31 01:44:33 +00:00
|
|
|
export const transactionDataCollector =
|
|
|
|
(txData: TransactionData | null | undefined): AddressCollector =>
|
|
|
|
() => {
|
|
|
|
if (!txData) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
const uniqueAddresses = new Set<string>();
|
|
|
|
|
|
|
|
// Standard fields
|
|
|
|
uniqueAddresses.add(txData.from);
|
|
|
|
if (txData.to) {
|
|
|
|
uniqueAddresses.add(txData.to);
|
|
|
|
}
|
|
|
|
if (txData.confirmedData?.createdContractAddress) {
|
|
|
|
uniqueAddresses.add(txData.confirmedData?.createdContractAddress);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dig token transfers
|
|
|
|
for (const t of txData.tokenTransfers) {
|
|
|
|
uniqueAddresses.add(t.from);
|
|
|
|
uniqueAddresses.add(t.to);
|
|
|
|
uniqueAddresses.add(t.token);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dig log addresses
|
|
|
|
if (txData.confirmedData) {
|
|
|
|
for (const l of txData.confirmedData.logs) {
|
|
|
|
uniqueAddresses.add(l.address);
|
|
|
|
// TODO: find a way to dig over decoded address log attributes
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Array.from(uniqueAddresses);
|
|
|
|
};
|
|
|
|
|
2021-11-01 20:09:47 +00:00
|
|
|
export const tracesCollector =
|
|
|
|
(traces: TraceGroup[] | undefined): AddressCollector =>
|
|
|
|
() => {
|
|
|
|
if (traces === undefined) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
const uniqueAddresses = new Set<string>();
|
|
|
|
let searchTraces = [...traces];
|
|
|
|
while (searchTraces.length > 0) {
|
|
|
|
const nextSearch: TraceGroup[] = [];
|
|
|
|
|
|
|
|
for (const g of searchTraces) {
|
|
|
|
uniqueAddresses.add(g.from);
|
|
|
|
uniqueAddresses.add(g.to);
|
|
|
|
if (g.children) {
|
|
|
|
nextSearch.push(...g.children);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
searchTraces = nextSearch;
|
|
|
|
}
|
|
|
|
return Array.from(uniqueAddresses);
|
|
|
|
};
|
|
|
|
|
2021-10-31 00:49:23 +00:00
|
|
|
export const useResolvedAddresses = (
|
|
|
|
provider: JsonRpcProvider | undefined,
|
|
|
|
addrCollector: AddressCollector
|
|
|
|
) => {
|
|
|
|
const [names, setNames] = useState<ResolvedAddresses>();
|
2021-11-01 07:15:12 +00:00
|
|
|
const ref = useRef<ResolvedAddresses | undefined>();
|
2021-10-31 00:49:23 +00:00
|
|
|
useEffect(() => {
|
2021-11-01 07:15:12 +00:00
|
|
|
ref.current = names;
|
|
|
|
});
|
|
|
|
|
|
|
|
useEffect(
|
|
|
|
() => {
|
|
|
|
if (!provider) {
|
|
|
|
return;
|
|
|
|
}
|
2021-10-31 00:49:23 +00:00
|
|
|
|
2021-11-01 07:15:12 +00:00
|
|
|
const populate = async () => {
|
|
|
|
const _addresses = addrCollector();
|
|
|
|
const _names = await batchPopulate(provider, _addresses, ref.current);
|
|
|
|
setNames(_names);
|
|
|
|
};
|
|
|
|
populate();
|
|
|
|
},
|
|
|
|
// DON'T put names variables in dependency array; this is intentional; useRef
|
|
|
|
[provider, addrCollector]
|
|
|
|
);
|
2021-10-31 00:49:23 +00:00
|
|
|
|
|
|
|
return names;
|
|
|
|
};
|