trufflesuite/truffle

View on GitHub
packages/db-kit/src/cli/decodeTransaction/Result.tsx

Summary

Maintainability
C
1 day
Test Coverage
import React, { useRef, useState, useEffect } from "react";
import { Box, Text, measureElement } from "ink";
import Spinner from "ink-spinner";
import Divider from "ink-divider";

import type { Transaction, TransactionReceipt } from "web3-core";
import type { ProjectDecoder } from "@truffle/decoder";

import * as Components from "@truffle/db-kit/cli/components";
import { DefinitionList } from "@truffle/db-kit/cli/components";

import { useDecodedTransaction } from "./useDecodedTransaction";

export interface Props {
  decoder: ProjectDecoder;
  transaction: Transaction;
  receipt: TransactionReceipt;
}

export const DecodeTransactionResult = ({
  decoder,
  transaction,
  receipt
}: Props) => {
  const [width, setWidth] = useState(80);
  const ref = useRef();

  useEffect(() => {
    // @ts-ignore
    setWidth(measureElement(ref.current).width);
  }, []);

  const { summary, events } = useDecodedTransaction({
    decoder,
    transaction,
    receipt
  });

  let summaryElement = (
    <Box>
      <Box paddingLeft={1} paddingRight={1}>
        <Text color="green">
          <Spinner />
        </Text>
      </Box>
      <Text>Decoding transaction summary...</Text>
    </Box>
  );
  if (summary.complete) {
    switch (summary.decoding?.kind) {
      case "function":
        summaryElement = (
          <Components.Codec.Function
            transaction={transaction}
            receipt={receipt}
            decoding={summary.decoding}
          />
        );
        break;
      case "constructor":
        summaryElement = (
          <Components.Codec.Constructor
            transaction={transaction}
            receipt={receipt}
            decoding={summary.decoding}
          />
        );
        break;
      default:
        summaryElement = <Text>{summary.decoding?.kind} </Text>;
        break;
    }
  }

  const eventEntries = events.map((event, index) => {
    const name = `[${index}]`;
    const node = !event.complete ? (
      <Box key={index}>
        <Box paddingLeft={1} paddingRight={1}>
          <Text color="green">
            <Spinner />
          </Text>
        </Box>
        <Text>Decoding...</Text>
      </Box>
    ) : (
      <Components.Codec.Event log={event.log} decoding={event.decoding} />
    );

    return { name, node };
  });

  const eventsElement =
    eventEntries.length === 0 ? (
      <Text dimColor italic>
        {"(no logs emitted)"}
      </Text>
    ) : (
      <DefinitionList
        spaceBetween={1}
        NameComponent={({ children }) => <Text dimColor>{children}</Text>}
        entries={eventEntries}
      />
    );

  return (
    // @ts-ignore
    <Box ref={ref} flexDirection="column" borderStyle="round" paddingBottom={1}>
      <Divider
        width={width - 2}
        titleColor="whiteBright"
        title="Decoded  Transaction"
        titlePadding={2}
        padding={0}
      />
      <Box marginX={2} marginY={1}>
        {summaryElement}
      </Box>
      <Divider
        width={width - 2}
        titleColor="whiteBright"
        title="Decoded Events"
        titlePadding={2}
        padding={0}
      />
      <Box marginX={2} marginTop={1} flexDirection="column">
        {eventsElement}
      </Box>
    </Box>
  );
};