First working prototype
This commit is contained in:
parent
d5e9f303a1
commit
9f818d36b2
|
@ -11,6 +11,8 @@ import { RuntimeContext } from "./useRuntime";
|
||||||
import { SelectionContext, useSelection } from "./useSelection";
|
import { SelectionContext, useSelection } from "./useSelection";
|
||||||
import { useInternalOperations, useTxData } from "./useErigonHooks";
|
import { useInternalOperations, useTxData } from "./useErigonHooks";
|
||||||
import { useETHUSDOracle } from "./usePriceOracle";
|
import { useETHUSDOracle } from "./usePriceOracle";
|
||||||
|
import { useSourcify, useTransactionDescription } from "./useSourcify";
|
||||||
|
import { SourcifySource } from "./url";
|
||||||
|
|
||||||
type TransactionParams = {
|
type TransactionParams = {
|
||||||
txhash: string;
|
txhash: string;
|
||||||
|
@ -44,6 +46,13 @@ const Transaction: React.FC = () => {
|
||||||
txData?.confirmedData?.blockNumber
|
txData?.confirmedData?.blockNumber
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const metadata = useSourcify(
|
||||||
|
txData?.to,
|
||||||
|
provider?.network.chainId,
|
||||||
|
SourcifySource.CUSTOM_SNAPSHOT_SERVER // TODO: use dynamic selector
|
||||||
|
);
|
||||||
|
const txDesc = useTransactionDescription(metadata, txData);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StandardFrame>
|
<StandardFrame>
|
||||||
<StandardSubtitle>Transaction Details</StandardSubtitle>
|
<StandardSubtitle>Transaction Details</StandardSubtitle>
|
||||||
|
@ -71,6 +80,7 @@ const Transaction: React.FC = () => {
|
||||||
<Route path="/tx/:txhash/" exact>
|
<Route path="/tx/:txhash/" exact>
|
||||||
<Details
|
<Details
|
||||||
txData={txData}
|
txData={txData}
|
||||||
|
txDesc={txDesc}
|
||||||
internalOps={internalOps}
|
internalOps={internalOps}
|
||||||
sendsEthToMiner={sendsEthToMiner}
|
sendsEthToMiner={sendsEthToMiner}
|
||||||
ethUSDPrice={blockETHUSDPrice}
|
ethUSDPrice={blockETHUSDPrice}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React, { useMemo, useState } from "react";
|
import React, { useMemo, useState } from "react";
|
||||||
|
import { TransactionDescription } from "@ethersproject/abi";
|
||||||
import { BigNumber } from "@ethersproject/bignumber";
|
import { BigNumber } from "@ethersproject/bignumber";
|
||||||
import { toUtf8String } from "@ethersproject/strings";
|
import { toUtf8String } from "@ethersproject/strings";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
@ -31,6 +32,7 @@ import PercentagePosition from "../components/PercentagePosition";
|
||||||
|
|
||||||
type DetailsProps = {
|
type DetailsProps = {
|
||||||
txData: TransactionData;
|
txData: TransactionData;
|
||||||
|
txDesc: TransactionDescription | null | undefined;
|
||||||
internalOps?: InternalOperation[];
|
internalOps?: InternalOperation[];
|
||||||
sendsEthToMiner: boolean;
|
sendsEthToMiner: boolean;
|
||||||
ethUSDPrice: BigNumber | undefined;
|
ethUSDPrice: BigNumber | undefined;
|
||||||
|
@ -38,6 +40,7 @@ type DetailsProps = {
|
||||||
|
|
||||||
const Details: React.FC<DetailsProps> = ({
|
const Details: React.FC<DetailsProps> = ({
|
||||||
txData,
|
txData,
|
||||||
|
txDesc,
|
||||||
internalOps,
|
internalOps,
|
||||||
sendsEthToMiner,
|
sendsEthToMiner,
|
||||||
ethUSDPrice,
|
ethUSDPrice,
|
||||||
|
@ -333,6 +336,26 @@ const Details: React.FC<DetailsProps> = ({
|
||||||
value={inputMode === 0 ? txData.data : utfInput}
|
value={inputMode === 0 ? txData.data : utfInput}
|
||||||
readOnly
|
readOnly
|
||||||
/>
|
/>
|
||||||
|
{txDesc && (
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<th>#</th>
|
||||||
|
<th>name</th>
|
||||||
|
<th>type</th>
|
||||||
|
<th>value</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{txDesc.args.map((r, i) => (
|
||||||
|
<tr key={i}>
|
||||||
|
<td>{i}</td>
|
||||||
|
<td>{txDesc.functionFragment.inputs[i].name}</td>
|
||||||
|
<td>{txDesc.functionFragment.inputs[i].type}</td>
|
||||||
|
<td>{r}</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</InfoRow>
|
</InfoRow>
|
||||||
</ContentFrame>
|
</ContentFrame>
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect, useMemo } from "react";
|
||||||
|
import { Interface } from "@ethersproject/abi";
|
||||||
|
import { TransactionData } from "./types";
|
||||||
import { sourcifyMetadata, SourcifySource, sourcifySourceFile } from "./url";
|
import { sourcifyMetadata, SourcifySource, sourcifySourceFile } from "./url";
|
||||||
|
|
||||||
export type Metadata = {
|
export type Metadata = {
|
||||||
|
@ -119,3 +121,30 @@ export const useContract = (
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useTransactionDescription = (
|
||||||
|
metadata: Metadata | null | undefined,
|
||||||
|
txData: TransactionData | null | undefined
|
||||||
|
) => {
|
||||||
|
const txDesc = useMemo(() => {
|
||||||
|
if (!metadata || !txData) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const abi = metadata.output.abi;
|
||||||
|
const intf = new Interface(abi as any);
|
||||||
|
console.log(intf);
|
||||||
|
return intf.parseTransaction({
|
||||||
|
data: txData.data,
|
||||||
|
value: txData.value,
|
||||||
|
});
|
||||||
|
}, [metadata, txData]);
|
||||||
|
|
||||||
|
console.log(metadata);
|
||||||
|
console.log(txDesc);
|
||||||
|
if (txDesc?.functionFragment) {
|
||||||
|
console.log(txDesc.functionFragment.inputs);
|
||||||
|
console.log(txDesc.args.toString());
|
||||||
|
}
|
||||||
|
return txDesc;
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue