Add support for multiple log emitter addresses
This commit is contained in:
parent
18275f86a2
commit
7f15a12f4a
|
@ -3,7 +3,8 @@ import { Interface } from "@ethersproject/abi";
|
|||
import ContentFrame from "../ContentFrame";
|
||||
import LogEntry from "./LogEntry";
|
||||
import { TransactionData } from "../types";
|
||||
import { Metadata } from "../useSourcify";
|
||||
import { Metadata, useMultipleMetadata } from "../useSourcify";
|
||||
import { SourcifySource } from "../url";
|
||||
|
||||
type LogsProps = {
|
||||
txData: TransactionData;
|
||||
|
@ -11,22 +12,45 @@ type LogsProps = {
|
|||
};
|
||||
|
||||
const Logs: React.FC<LogsProps> = ({ txData, metadata }) => {
|
||||
const baseMetadatas = useMemo((): Record<string, Metadata | null> => {
|
||||
if (!txData.to || metadata === undefined) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const md: Record<string, Metadata | null> = {};
|
||||
md[txData.to] = metadata;
|
||||
return md;
|
||||
}, [txData.to, metadata]);
|
||||
|
||||
const logAddresses = useMemo(
|
||||
() => txData.confirmedData?.logs.map((l) => l.address) ?? [],
|
||||
[txData]
|
||||
);
|
||||
const metadatas = useMultipleMetadata(
|
||||
baseMetadatas,
|
||||
logAddresses,
|
||||
1,
|
||||
SourcifySource.CUSTOM_SNAPSHOT_SERVER
|
||||
);
|
||||
const logDesc = useMemo(() => {
|
||||
if (!metadata || !txData) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const abi = metadata.output.abi;
|
||||
const intf = new Interface(abi as any);
|
||||
return txData.confirmedData?.logs.map((l) =>
|
||||
l.address === txData.to
|
||||
? intf.parseLog({
|
||||
topics: l.topics,
|
||||
data: l.data,
|
||||
})
|
||||
: undefined
|
||||
);
|
||||
}, [metadata, txData]);
|
||||
return txData.confirmedData?.logs.map((l) => {
|
||||
const mt = metadatas[l.address];
|
||||
if (!mt) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const abi = mt.output.abi;
|
||||
const intf = new Interface(abi as any);
|
||||
return intf.parseLog({
|
||||
topics: l.topics,
|
||||
data: l.data,
|
||||
});
|
||||
});
|
||||
}, [metadatas, metadata, txData]);
|
||||
|
||||
return (
|
||||
<ContentFrame tabs>
|
||||
|
|
|
@ -38,11 +38,38 @@ export type Metadata = {
|
|||
};
|
||||
};
|
||||
|
||||
export const fetchSourcifyMetadata = async (
|
||||
checksummedAddress: string,
|
||||
chainId: number,
|
||||
source: SourcifySource,
|
||||
abortController: AbortController
|
||||
): Promise<Metadata | null> => {
|
||||
try {
|
||||
const contractMetadataURL = sourcifyMetadata(
|
||||
checksummedAddress,
|
||||
chainId,
|
||||
source
|
||||
);
|
||||
const result = await fetch(contractMetadataURL, {
|
||||
signal: abortController.signal,
|
||||
});
|
||||
if (result.ok) {
|
||||
const _metadata = await result.json();
|
||||
return _metadata;
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const useSourcify = (
|
||||
checksummedAddress: string | undefined,
|
||||
chainId: number | undefined,
|
||||
source: SourcifySource
|
||||
) => {
|
||||
): Metadata | null | undefined => {
|
||||
const [rawMetadata, setRawMetadata] = useState<Metadata | null | undefined>();
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -53,25 +80,13 @@ export const useSourcify = (
|
|||
|
||||
const abortController = new AbortController();
|
||||
const fetchMetadata = async () => {
|
||||
try {
|
||||
const contractMetadataURL = sourcifyMetadata(
|
||||
checksummedAddress,
|
||||
chainId,
|
||||
source
|
||||
);
|
||||
const result = await fetch(contractMetadataURL, {
|
||||
signal: abortController.signal,
|
||||
});
|
||||
if (result.ok) {
|
||||
const _metadata = await result.json();
|
||||
setRawMetadata(_metadata);
|
||||
} else {
|
||||
setRawMetadata(null);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
setRawMetadata(null);
|
||||
}
|
||||
const _metadata = await fetchSourcifyMetadata(
|
||||
checksummedAddress,
|
||||
chainId,
|
||||
source,
|
||||
abortController
|
||||
);
|
||||
setRawMetadata(_metadata);
|
||||
};
|
||||
fetchMetadata();
|
||||
|
||||
|
@ -83,6 +98,54 @@ export const useSourcify = (
|
|||
return rawMetadata;
|
||||
};
|
||||
|
||||
export const useMultipleMetadata = (
|
||||
baseMetadatas: Record<string, Metadata | null>,
|
||||
checksummedAddress: (string | undefined)[],
|
||||
chainId: number | undefined,
|
||||
source: SourcifySource
|
||||
): Record<string, Metadata | null | undefined> => {
|
||||
const [rawMetadata, setRawMetadata] = useState<
|
||||
Record<string, Metadata | null | undefined>
|
||||
>({});
|
||||
|
||||
useEffect(() => {
|
||||
if (!checksummedAddress || chainId === undefined) {
|
||||
return;
|
||||
}
|
||||
setRawMetadata({});
|
||||
|
||||
const abortController = new AbortController();
|
||||
const fetchMetadata = async (addresses: string[]) => {
|
||||
const promises: Promise<Metadata | null>[] = [];
|
||||
for (const addr of addresses) {
|
||||
promises.push(
|
||||
fetchSourcifyMetadata(addr, chainId, source, abortController)
|
||||
);
|
||||
}
|
||||
|
||||
const results = await Promise.all(promises);
|
||||
const metadatas: Record<string, Metadata | null> = { ...baseMetadatas };
|
||||
for (let i = 0; i < results.length; i++) {
|
||||
metadatas[addresses[i]] = results[i];
|
||||
}
|
||||
setRawMetadata(metadatas);
|
||||
};
|
||||
|
||||
const deduped = new Set(
|
||||
checksummedAddress.filter(
|
||||
(a): a is string => a !== undefined && baseMetadatas[a] === undefined
|
||||
)
|
||||
);
|
||||
fetchMetadata(Array.from(deduped));
|
||||
|
||||
return () => {
|
||||
abortController.abort();
|
||||
};
|
||||
}, [baseMetadatas, checksummedAddress, chainId, source]);
|
||||
|
||||
return rawMetadata;
|
||||
};
|
||||
|
||||
export const useContract = (
|
||||
checksummedAddress: string,
|
||||
networkId: number,
|
||||
|
|
Loading…
Reference in New Issue