Skip to content

Commit

Permalink
refactor: swr
Browse files Browse the repository at this point in the history
  • Loading branch information
yongenaelf committed Jul 30, 2024
1 parent 36f6877 commit 0638965
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 139 deletions.
60 changes: 37 additions & 23 deletions app/deployments/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"use client";

import { useWallet } from "@/data/wallet";
import useSWR from "swr";
import {
Table,
TableBody,
Expand All @@ -12,13 +11,11 @@ import {
} from "@/components/ui/table";
import { format } from "date-fns";
import Link from "next/link";
import { useLogs, useProposalInfo, useTransactions } from "@/data/client";

export default function Page() {
const wallet = useWallet();
const { data } = useSWR(
wallet ? `${wallet.wallet.address}-transactions` : undefined,
() => wallet?.getTransactions()
);
const { data } = useTransactions(wallet?.wallet.address);

return (
<div className="container px-4 py-12 md:px-6 lg:py-16">
Expand All @@ -27,7 +24,8 @@ export default function Page() {
<TableHeader>
<TableRow>
<TableHead className="w-1/3">Date and time</TableHead>
<TableHead>Contract Address</TableHead>
<TableHead className="w-1/3">Contract Address</TableHead>
<TableHead className="w-1/3">Proposal</TableHead>
</TableRow>
</TableHeader>
<TableBody>
Expand All @@ -40,6 +38,9 @@ export default function Page() {
<TableCell>
<ContractAddress id={i.tx_id} />
</TableCell>
<TableCell>
<Proposal id={i.tx_id} />
</TableCell>
</TableRow>
))
) : (
Expand All @@ -51,35 +52,34 @@ export default function Page() {
</Table>
<h1 className="text-2xl mb-2">Wallet information</h1>
<p>
Wallet address: <ViewOnExplorer address={wallet?.wallet.address} />
Wallet address:{" "}
<ViewAddressOnExplorer address={wallet?.wallet.address} />
</p>
</div>
);
}

function ContractAddress({ id }: { id: string }) {
const wallet = useWallet();
function Proposal({ id }: { id: string }) {
const { data, isLoading, error } = useLogs(id);

const { data, error, isLoading } = useSWR(
wallet ? `${id}-contract-address` : undefined,
async () => {
if (!wallet) return;
const logs = await wallet.getLogs(id);
if (typeof logs.proposalId !== "string") return;
const proposalInfo = await wallet.getProposalInfo(logs.proposalId);
const txId = proposalInfo.data.proposal.releasedTxId;
const txResult = await wallet.getLogs(txId);
return txResult.address;
}
);
if (isLoading) return <span>Loading...</span>;
if (error || !data || !data.proposalId) return <span>-</span>;

return <ViewProposalOnExplorer id={data.proposalId} />;
}

function ContractAddress({ id }: { id: string }) {
const { data: logs } = useLogs(id);
const { data: info } = useProposalInfo(logs?.proposalId);
const { data, isLoading, error } = useLogs(info?.proposal.releasedTxId);

if (isLoading) return <span>Loading...</span>;
if (error || !data) return <span>-</span>;

return <ViewOnExplorer address={data} />;
return <ViewAddressOnExplorer address={data.address} />;
}

function ViewOnExplorer({ address }: { address: string }) {
function ViewAddressOnExplorer({ address }: { address: string }) {
return (
<Link
className="hover:underline"
Expand All @@ -92,3 +92,17 @@ function ViewOnExplorer({ address }: { address: string }) {
</Link>
);
}

function ViewProposalOnExplorer({ id }: { id: string }) {
return (
<Link
className="hover:underline"
href={`https://explorer-test-side02.aelf.io/proposal/proposalsDetail/${id}`}
title="View on Explorer"
target="_blank"
rel="noopener noreferrer"
>
{id}
</Link>
);
}
51 changes: 38 additions & 13 deletions components/workspace/use-cli-commands.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"use client";
import { useLogs, useProposalInfo, useTransactionResult } from "@/data/client";
import { db } from "@/data/db";
import { useWallet } from "@/data/wallet";
import { Loader2 } from "lucide-react";
import { useParams } from "next/navigation";
import { useContext } from "react";
import { useContext, useEffect, useState } from "react";
import { TerminalContext } from "react-terminal";

export function useCliCommands() {
Expand Down Expand Up @@ -141,26 +142,50 @@ function Deploying() {
}

function Deployment({ id }: { id: string }) {
const { data } = useTransactionResult(id);
const [shouldPoll, setShouldPoll] = useState(true);
const { data, error } = useTransactionResult(
id,
shouldPoll ? 1000 : undefined
);
const { Status } = data || {};

if (!data)
return (
<>
<Deploying />
</>
);
if (data.Status === "PENDING") return <Deploying />;
useEffect(() => {
if (Status === "MINED" || !!error) setShouldPoll(false);
}, [Status, error]);

return <CheckProposalInfo id={id} />;
if (error) return <p>Error: {error.Error}</p>;
if (!data || Status === "PENDING") return <Deploying />;

return <CheckProposalId id={id} />;
}

function CheckProposalInfo({ id }: { id: string }) {
const { data } = useLogs(id);
function CheckProposalId({ id }: { id: string }) {
const [shouldPoll, setShouldPoll] = useState(true);
const { data } = useLogs(id, shouldPoll ? 1000 : undefined);
const { proposalId } = data || {};

const { data: proposalInfo } = useProposalInfo(proposalId);
useEffect(() => {
if (proposalId) setShouldPoll(false);
}, [proposalId]);

if (!proposalId) return <Deploying />;

return <CheckProposalInfo id={proposalId} />;
}

function CheckProposalInfo({ id }: { id: string }) {
const [shouldPoll, setShouldPoll] = useState(true);

const { data: proposalInfo } = useProposalInfo(
id,
shouldPoll ? 1000 : undefined
);
const { status, releasedTxId } = proposalInfo?.proposal || {};

useEffect(() => {
if (status === "expired" || status === "released") setShouldPoll(false);
}, [status]);

return (
<>
<p>Proposal status: {status || "pending"}</p>
Expand Down
90 changes: 76 additions & 14 deletions data/client.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,79 @@
"use client";

import useSWR from "swr";
import { db } from "./db";
import { aelf } from "./wallet";
import { ProposalInfo } from "./proposal-info-types";
import AElf from "aelf-sdk";
import { Transactions } from "./transactions-types";
const { deserializeLog } = AElf.pbUtils;

const aelf = new AElf(
new AElf.providers.HttpProvider("https://tdvw-test-node.aelf.io")
);

export function useWorkspaces() {
return useSWR("workspaces", async () => {
return await db.workspaces.toArray();
});
}

export function useTransactionResult(id?: string) {
return useSWR(
export function useTransactionResult(id?: string, refreshInterval?: number) {
return useSWR<
{
TransactionId: string;
Status: string;
Logs: Array<{
Address: string;
Name: string;
Indexed: Array<string>;
NonIndexed: string;
}>;
Bloom: string;
BlockNumber: number;
BlockHash: string;
Transaction: {
From: string;
To: string;
RefBlockNumber: number;
RefBlockPrefix: string;
MethodName: string;
Params: string;
Signature: string;
};
ReturnValue: string;
Error: any;
TransactionSize: number;
},
{
TransactionId: string;
Status: string;
Logs: [];
Bloom: null;
BlockNumber: 0;
BlockHash: null;
Transaction: null;
ReturnValue: "";
Error: string;
TransactionSize: 0;
}
>(
id ? `tx-${id}` : undefined,
async () => await aelf.chain.getTxResult(id),
{ refreshInterval: 1000 }
async () => {
const res = await aelf.chain.getTxResult(id);

switch (res?.Status) {
case "NOTEXISTED":
case "NODEVALIDATIONFAILED":
throw res;
}

return res;
},
{ refreshInterval }
);
}

export function useProposalInfo(id?: string) {
export function useProposalInfo(id?: string, refreshInterval?: number) {
return useSWR(
id ? `get-proposal-info-${id}` : undefined,
async () => {
Expand All @@ -28,32 +82,40 @@ export function useProposalInfo(id?: string) {

return data;
},
{ refreshInterval: 1000 }
{ refreshInterval }
);
}

export function useLogs(id?: string) {
export function useLogs(id?: string, refreshInterval?: number) {
const { data: txResult } = useTransactionResult(id);
return useSWR(
id ? `get-logs-${id}` : undefined,
id && !!txResult ? `get-logs-${id}` : undefined,
async () => {
const txResult = await aelf.chain.getTxResult(id);

const services = await Promise.all(
txResult.Logs.map(async ({ Address }: { Address: string }) =>
txResult!.Logs.map(async ({ Address }: { Address: string }) =>
AElf.pbjs.Root.fromDescriptor(
await aelf.chain.getContractFileDescriptorSet(Address)
)
)
);

const deserializedLogs: Array<{ proposalId: string }> =
await deserializeLog(txResult.Logs, services);
await deserializeLog(txResult!.Logs, services);

return deserializedLogs.reduce(
(acc, cur) => ({ ...acc, ...cur }),
{} as Record<string, string>
);
},
{ refreshInterval: 1000 }
{ refreshInterval }
);
}

export function useTransactions(address: string) {
return useSWR(address ? `transactions-${address}` : undefined, async () => {
const res = await fetch(`/api/get-transactions?address=${address}`);
const { transactions }: { transactions: Transactions } = await res.json();

return transactions;
});
}
Loading

0 comments on commit 0638965

Please sign in to comment.