Skip to content

Commit

Permalink
user tx history and transfer history dev is complete for now, this co…
Browse files Browse the repository at this point in the history
…mmit is ready for testing
  • Loading branch information
bcstryker committed Aug 24, 2022
1 parent 595f077 commit fbbe65b
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 67 deletions.
9 changes: 4 additions & 5 deletions v2/features/stats/JarStats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import FarmsTable from "v2/features/farms/FarmsTable";
import { JarSelectData } from "./JarSelect";
import { readyState } from "pages/stats";
import { useAccount } from "v2/hooks";
import TxHistoryTable from "./jar/userHistory/TxHistoryContainer";
import { JarDefinition } from "picklefinance-core/lib/model/PickleModelJson";
import { useTranslation } from "next-i18next";
import TxHistoryContainer from "./jar/userHistory/TxHistoryContainer";
Expand All @@ -38,7 +37,7 @@ const JarStats: FC<{

const addrs = Object.fromEntries(
Object.entries({
User: "0xfeedc450742ac0d9bb38341d9939449e3270f76f", //account,
User: account, //"0xfeedc450742ac0d9bb38341d9939449e3270f76f",
Jar: assetJar ? assetJar.contract.toLowerCase() : "jar not found",
Farm: assetJar && assetJar.farm ? assetJar.farm.farmAddress.toLowerCase() : "farm not found",
Null: "0x0000000000000000000000000000000000000000",
Expand All @@ -57,7 +56,7 @@ const JarStats: FC<{

useEffect(() => {
const getUserJarHistory = async (account: string | null | undefined): Promise<void> => {
account = "0xfeedc450742ac0d9bb38341d9939449e3270f76f";
// account = "0xfeedc450742ac0d9bb38341d9939449e3270f76f";
account &&
(await fetch(`https://api.pickle.finance/prod/protocol/userhistory/${account}`)
.then((resp) => resp.json())
Expand All @@ -79,8 +78,8 @@ const JarStats: FC<{
<ChartContainer jarData={jarData} />
{jarData && jarData.documentation && <DocContainer docs={jarData.documentation} />}
<div className="flex">
{userJarHistory && userJarHistory.length > 0 && (
<TxHistoryContainer txHistory={userJarHistory} addrs={addrs} t={t} />
{userJarHistory && userJarHistory.length > 0 && core && (
<TxHistoryContainer txHistory={userJarHistory} core={core} addrs={addrs} t={t} />
)}
<div>
{jarData && jarData.documentation && (
Expand Down
6 changes: 4 additions & 2 deletions v2/features/stats/jar/userHistory/TxHistoryContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import { TFunction } from "next-i18next";
import { PickleModelJson } from "picklefinance-core";
import { FC } from "react";
import { UserTx } from "v2/types";
import { classNames } from "v2/utils";
import TxHistoryTable from "./TxHistoryTable";

const TxHistoryContainer: FC<{
txHistory: UserTx[];
core: PickleModelJson.PickleModelJson;
addrs: { [key: string]: string };
t: TFunction;
className?: string;
}> = ({ txHistory, addrs, t, className }) => (
}> = ({ txHistory, core, addrs, t, className }) => (
<div className={classNames("pr-5", className)}>
<h2 className="font-body font-bold text-xl text-foreground-alt-200 mt-3 mb-5">
{"User History"}
</h2>
<TxHistoryTable txHistory={txHistory} addrs={addrs} />
{core && <TxHistoryTable txHistory={txHistory} core={core} addrs={addrs} />}
</div>
);

Expand Down
6 changes: 4 additions & 2 deletions v2/features/stats/jar/userHistory/TxHistoryTable.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { PickleModelJson } from "picklefinance-core";
import { FC } from "react";
import { UserTx } from "v2/types";
import { classNames } from "v2/utils";
import TxTableBody from "./TxTableBody";

const TxHistoryTable: FC<{
txHistory: UserTx[];
core: PickleModelJson.PickleModelJson;
addrs: { [key: string]: string };
className?: string;
}> = ({ txHistory, addrs, className }) => {
}> = ({ txHistory, core, addrs, className }) => {
return (
<div className={classNames("flex flex-col", className)}>
<div className="-my-2 overflow-x-auto">
Expand All @@ -23,7 +25,7 @@ const TxHistoryTable: FC<{
</tr>
</thead>
<tbody className="text-foreground">
<TxTableBody txs={txHistory} addrs={addrs} />
<TxTableBody txs={txHistory} core={core} addrs={addrs} />
</tbody>
</table>
{/* <div className="flex justify-center mt-4">
Expand Down
86 changes: 53 additions & 33 deletions v2/features/stats/jar/userHistory/TxTableBody.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,66 @@
import { Disclosure, Transition } from "@headlessui/react";
import { PickleModelJson } from "picklefinance-core";
import { RawChain } from "picklefinance-core/lib/chain/Chains";
import { FC, Fragment } from "react";
import { UserTx } from "v2/types";
import { classNames } from "v2/utils";
import TxTableRowBody from "./TxTableRowBody";
import TxTableRowHeader from "./TxTableRowHeader";
import TxTableSpacerRow from "./TxTableSpacerRow";

const TxTableBody: FC<{ txs: UserTx[]; addrs: { [key: string]: string } }> = ({ txs, addrs }) => (
<>{txs && txs.map((tx) => <TxTableRow key={tx.hash} tx={tx} addrs={addrs} />)}</>
const TxTableBody: FC<{
txs: UserTx[];
core: PickleModelJson.PickleModelJson;
addrs: { [key: string]: string };
}> = ({ txs, core, addrs }) => (
<>{txs && txs.map((tx) => <TxTableRow key={tx.hash} core={core} tx={tx} addrs={addrs} />)}</>
);

const TxTableRow: FC<{ tx: UserTx; addrs: { [key: string]: string } }> = ({ tx, addrs }) => (
<>
<Disclosure as={Fragment}>
{({ open }) => (
<>
<Disclosure.Button
as="tr"
// No hover state when the row is expaned.
className={classNames(!open && "group", "cursor-pointer")}
>
<TxTableRowHeader tx={tx} open={open} />
</Disclosure.Button>
const TxTableRow: FC<{
tx: UserTx;
core: PickleModelJson.PickleModelJson;
addrs: { [key: string]: string };
}> = ({ tx, core, addrs }) => {
const chain: RawChain | undefined = core.chains.filter((c) => c.chainId === tx.chain_id)[0];
return (
<>
<Disclosure as={Fragment}>
{({ open }) => (
<>
<Disclosure.Button
as="tr"
// No hover state when the row is expaned.
className={classNames(!open && "group", "cursor-pointer")}
>
{core && <TxTableRowHeader tx={tx} core={core} open={open} />}
</Disclosure.Button>

<Transition
as={Fragment}
enter="transition duration-100 ease-out"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition duration-100 ease-out"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Disclosure.Panel as="tr">
<TxTableRowBody transfers={tx.transfers} addrs={addrs} />
</Disclosure.Panel>
</Transition>
</>
)}
</Disclosure>
<TxTableSpacerRow />
</>
);
<Transition
as={Fragment}
enter="transition duration-100 ease-out"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition duration-100 ease-out"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Disclosure.Panel as="tr">
{core && chain && (
<TxTableRowBody
transfers={tx.transfers}
core={core}
chain={chain}
addrs={addrs}
/>
)}
</Disclosure.Panel>
</Transition>
</>
)}
</Disclosure>
<TxTableSpacerRow />
</>
);
};

export default TxTableBody;
159 changes: 141 additions & 18 deletions v2/features/stats/jar/userHistory/TxTableRowBody.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,170 @@
import { PickleModelJson } from "picklefinance-core";
import { RawChain } from "picklefinance-core/lib/chain/Chains";
import { FC } from "react";
import { UserTransfer } from "v2/types";
import { formatNumber } from "v2/utils";
import { classNames, formatNumber } from "v2/utils";
import Link from "v2/components/Link";

const TxTableRowBody: FC<{ transfers: UserTransfer[]; addrs: { [key: string]: string } }> = ({
transfers,
addrs,
}) => (
const TxTableRowBody: FC<{
transfers: UserTransfer[];
core: PickleModelJson.PickleModelJson;
chain: RawChain;
addrs: { [key: string]: string };
}> = ({ transfers, core, chain, addrs }) => (
<td
colSpan={6}
className="bg-background-light rounded-b-xl p-6 border-t border-foreground-alt-500"
className="bg-background-light rounded-b-xl p-2 border-t border-foreground-alt-500"
>
<div className="flex justify-evenly">
<div className="py-2 flex-shrink-0 mr-6">
{transfers.map((t) => (
<p className="text-foreground-alt-200" key={t.log_index}>
{transferToString(t, addrs)}
</p>
<TransferDescription
key={t.log_index}
transfer={t}
core={core}
chain={chain}
tmpAddrs={addrs}
/>
))}
</div>
</div>
</td>
);

const transferToString = (transfer: UserTransfer, addrs: { [key: string]: string }) => {
const TransferDescription: FC<{
transfer: UserTransfer;
core: PickleModelJson.PickleModelJson;
chain: RawChain;
tmpAddrs: { [addr: string]: string };
}> = ({ transfer, core, chain, tmpAddrs }) => {
const { fromAddr, toAddr, burned, minted, nTokens, value, tokenName } = transferData(
transfer,
core,
tmpAddrs,
);
const useFromLink = fromAddr.includes("...") && chain !== undefined;
const useToLink = toAddr.includes("...") && chain !== undefined;

return (
<>
{burned && (
<p className="text-xs text-foreground-alt-200">{`${nTokens}${
" " + tokenName
} tokens ${value} were burned.`}</p>
)}
{minted && (
<>
{useToLink ? (
<span className="whitespace-nowrap flex">
<p className="text-xs text-foreground-alt-200">
{`${nTokens}${" " + tokenName} tokens ${value} were minted and sent to`}
</p>
<AddrLink chain={chain} addr={toAddr} className="pl-1" />
</span>
) : (
<p className="text-xs text-foreground-alt-200">
{`${nTokens}${" " + tokenName} tokens ${value} were minted and sent to ${toAddr}`}
</p>
)}
</>
)}
{!minted && !burned && (
<>
{useFromLink && useToLink && (
<div className="flex inline whitespace-nowrap">
<AddrLink chain={chain} addr={fromAddr} className="pr-1" />
<p className="text-xs pl-1 text-foreground-alt-200">
{`sent ${nTokens}${" " + tokenName} tokens ${value} to `}
</p>
<AddrLink chain={chain} addr={toAddr} className="pl-1" />
</div>
)}
{useFromLink && !useToLink && (
<div className="flex inline whitespace-nowrap">
<AddrLink chain={chain} addr={fromAddr} className="pr-1" />
<p className="text-xs pl-1 text-foreground-alt-200">
{`sent ${nTokens}${" " + tokenName} tokens ${value} to ${toAddr}`}
</p>
</div>
)}
{!useFromLink && useToLink && (
<div className="flex inline whitespace-nowrap">
<p className="text-xs text-foreground-alt-200">
{`${fromAddr} sent ${nTokens}${" " + tokenName} tokens ${value} to`}
</p>
<AddrLink chain={chain} addr={toAddr} className="pl-1" />
</div>
)}
{!useFromLink && !useToLink && (
<p className="text-xs text-foreground-alt-200">
{`${fromAddr} sent ${nTokens}${" " + tokenName} tokens ${value} to ${toAddr}`}
</p>
)}
</>
)}
</>
);
};

const AddrLink: FC<{ chain: RawChain; addr: string; className?: string }> = ({
chain,
addr,
className,
}) => (
<Link href={`${chain.explorer}/${addr}`} primary className={className}>
{addr}
</Link>
);

const transferData = (
transfer: UserTransfer,
core: PickleModelJson.PickleModelJson,
addrs: { [addr: string]: string },
) => {
const tmp = core && coreToAddrMap(core);
addrs = tmp && { ...tmp, ...addrs };
const fromAddr =
addrs[transfer.fromAddress] ||
addrs[transfer.fromAddress.toLowerCase()] ||
transfer.fromAddress.slice(0, 5) + "..." + transfer.fromAddress.slice(-3);
const toAddr =
addrs[transfer.toAddress] ||
addrs[transfer.toAddress.toLowerCase()] ||
transfer.toAddress.slice(0, 5) + "..." + transfer.toAddress.slice(-3);

const burned = toAddr === "Null";
const minted = fromAddr === "Null";
const nTokens =
transfer.price && transfer.value
? formatNumber(+transfer.price / transfer.value, 8)
: "an unknown number of";
const value = transfer.value ? "(" + formatNumber(transfer.value, 2) + " USD)" : "";
return burned
? `${fromAddr} burned ${nTokens} tokens ${value}`
: minted
? `${nTokens} ${value} were minted and sent to ${toAddr}`
: `${fromAddr} sent ${nTokens} tokens ${value} to ${toAddr}`;
const tokenName = addrs[transfer.tokenAddress.toLowerCase()] || "";
return {
addrs: addrs,
fromAddr: fromAddr,
toAddr: toAddr,
burned: burned,
minted: minted,
nTokens: nTokens,
value: value,
tokenName: tokenName,
};
};

const coreToAddrMap = (core: PickleModelJson.PickleModelJson) => {
let addrs: { [addr: string]: string } = {};
core.assets.jars.forEach((a) => {
const depositTokenAddr = a.depositToken.addr.toLowerCase();
const depositTokenName = a.depositToken.name;
const pTokenAddr = a.contract.toLowerCase();
const pTokenName = "p" + depositTokenName;
addrs[depositTokenAddr] = depositTokenName;
addrs[pTokenAddr] = pTokenName;
});
core.tokens.forEach((t) => {
const tokenAddr = t.contractAddr.toLowerCase();
const tokenName = t.name ? t.name : t.id;
addrs[tokenAddr] = tokenName;
});
return addrs;
};

export default TxTableRowBody;
Loading

0 comments on commit fbbe65b

Please sign in to comment.