Skip to content

Commit

Permalink
feat: add view all contracts (#1235)
Browse files Browse the repository at this point in the history
* chore: update README

* feat: add suggested messages for execute contract

* chore: add suggested inputs for execute

* chore: execute contract messages

* chore: update message suggestion logic

* chore: add list codes and contracts

* chore

* chore: add all contracts option

* chore: review changes

* chore: review changes

* chore

* chore: review changes
  • Loading branch information
Hemanthghs authored May 10, 2024
1 parent 4a0af23 commit c1939db
Show file tree
Hide file tree
Showing 26 changed files with 1,294 additions and 175 deletions.
16 changes: 14 additions & 2 deletions frontend/src/app/(routes)/cosmwasm/[network]/PageContracts.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
'use client';
import TopNav from '@/components/TopNav';
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { useAppSelector } from '@/custom-hooks/StateHooks';
import Contracts from '../components/Contracts';
import AllContracts from '../components/AllContracts';
import DialogTxContractStatus from '../components/DialogTxUploadCodeStatus';
import DialogTxExecuteStatus from '../components/DialogTxExecuteStatus';
import DialogTxInstantiateStatus from '../components/DialogTxInstantiateStatus';
import { useRouter, useSearchParams } from 'next/navigation';

const PageContracts = ({ chainName }: { chainName: string }) => {
const router = useRouter();
const nameToChainIDs: Record<string, string> = useAppSelector(
(state) => state.wallet.nameToChainIDs
);
const chainID = nameToChainIDs[chainName];
const tabs = ['Contracts', 'All Contracts'];
const [selectedTab, setSelectedTab] = useState('Contracts');

const paramContractAddress = useSearchParams().get('contract');

useEffect(() => {
if (paramContractAddress?.length) {
setSelectedTab('Contracts');
}
}, [paramContractAddress]);

return (
<div className="h-screen flex flex-col p-6 px-10 gap-10">
<div className="flex flex-col gap-6">
Expand All @@ -35,6 +46,7 @@ const PageContracts = ({ chainName }: { chainName: string }) => {
}
onClick={() => {
setSelectedTab(tab);
router.push(`/cosmwasm/${chainName.toLowerCase()}`);
}}
>
{tab}
Expand All @@ -55,7 +67,7 @@ const PageContracts = ({ chainName }: { chainName: string }) => {
{selectedTab === 'Contracts' ? (
<Contracts chainID={chainID} />
) : (
<AllContracts />
<AllContracts chainID={chainID} />
)}
</div>
<DialogTxContractStatus chainID={chainID} />
Expand Down
27 changes: 25 additions & 2 deletions frontend/src/app/(routes)/cosmwasm/components/AllContracts.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
import useGetChainInfo from '@/custom-hooks/useGetChainInfo';
import { useSearchParams } from 'next/navigation';
import React from 'react';
import Contracts from './all-contracts/Contracts';
import Codes from './all-contracts/Codes';

const AllContracts = () => {
return <div className="h-1/2 flex-center-center">Comming Soon...</div>;
const AllContracts = (props: { chainID: string }) => {
const { chainID } = props;
const { getChainInfo } = useGetChainInfo();
const { restURLs, chainName } = getChainInfo(chainID);

const selectedCodeId = useSearchParams().get('code_id');

return (
<div>
{selectedCodeId ? (
<Contracts
codeId={selectedCodeId}
chainID={chainID}
baseURLs={restURLs}
chainName={chainName}
/>
) : (
<Codes chainID={chainID} baseURLs={restURLs} />
)}
</div>
);
};

export default AllContracts;
64 changes: 42 additions & 22 deletions frontend/src/app/(routes)/cosmwasm/components/ContractInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, { useState } from 'react';
import QueryContract from './QueryContract';
import useGetChainInfo from '@/custom-hooks/useGetChainInfo';
import ExecuteContract from './ExecuteContract';
import Image from 'next/image';

const ContractInfo = ({ chainID }: { chainID: string }) => {
const selectedContractAddress = useAppSelector(
Expand All @@ -11,39 +12,58 @@ const ContractInfo = ({ chainID }: { chainID: string }) => {
const selectedContractInfo = useAppSelector(
(state) => state.cosmwasm.chains?.[chainID]?.contractInfo
);
const tabs = ['Query Contract', 'Execute Contract'];
const [selectedTab, setSelectedTab] = useState('Query Contract');
const tabs = ['Execute Contract', 'Query Contract'];
const [selectedTab, setSelectedTab] = useState('Execute Contract');
const [infoOpen, setInfoOpen] = useState(false);

const { getChainInfo } = useGetChainInfo();
const {
restURLs,
rpcURLs,
address: walletAddress,
chainName,
} = getChainInfo(chainID);


return (
<div className="space-y-20">
<div className="space-y-12">
<div className="space-y-6">
<div className="pb-4 border-b-[1px] border-[#ffffff1e] font-bold text-[18px]">
{selectedContractInfo.label || selectedContractAddress}
{selectedContractInfo?.label || selectedContractAddress}
</div>
<div className="flex gap-10 bg-[#FFFFFF0D] p-10 rounded-2xl flex-wrap">
<ContractInfoAttribute name="Network" value={chainID} />
<ContractInfoAttribute
name="From Code"
value={selectedContractInfo.code_id}
/>
<ContractInfoAttribute
name="Admin Address"
value={selectedContractInfo.admin}
/>
<ContractInfoAttribute
name="Instantiated Block Height"
value={selectedContractInfo.created.block_height}
/>
<ContractInfoAttribute
name="Instantiated By"
value={selectedContractInfo.creator}
/>
<div className="bg-[#ffffff0D] rounded-2xl p-6 space-y-6">
<div className="flex justify-between items-center">
<div className="text-[14px]">Contract Info</div>
<Image
onClick={() => setInfoOpen((prev) => !prev)}
className="cursor-pointer"
src={'/expand-icon.svg'}
height={24}
width={24}
alt="Expand"
/>
</div>
{infoOpen ? (
<div className="flex gap-10 flex-wrap">
<ContractInfoAttribute name="Network" value={chainID} />
<ContractInfoAttribute
name="From Code"
value={selectedContractInfo.code_id}
/>
<ContractInfoAttribute
name="Admin Address"
value={selectedContractInfo.admin}
/>
<ContractInfoAttribute
name="Instantiated Block Height"
value={selectedContractInfo.created.block_height}
/>
<ContractInfoAttribute
name="Instantiated By"
value={selectedContractInfo.creator}
/>
</div>
) : null}
</div>
</div>
<div className="space-y-10 pb-10">
Expand Down
57 changes: 56 additions & 1 deletion frontend/src/app/(routes)/cosmwasm/components/Contracts.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import SearchContracts from './SearchContracts';
import DeployContract from './DeployContract';
import ContractInfo from './ContractInfo';
import { useSearchParams } from 'next/navigation';
import useContracts from '@/custom-hooks/useContracts';
import useGetChainInfo from '@/custom-hooks/useGetChainInfo';
import { setContract } from '@/store/features/cosmwasm/cosmwasmSlice';
import { useAppDispatch } from '@/custom-hooks/StateHooks';
import { CircularProgress } from '@mui/material';

const Contracts = ({ chainID }: { chainID: string }) => {
const dispatch = useAppDispatch();
const [deployContractOpen, setDeployContractOpen] = useState(false);
const [selectedContract, setSelectedContract] = useState({
address: '',
Expand All @@ -14,6 +21,44 @@ const Contracts = ({ chainID }: { chainID: string }) => {
setSelectedContract({ address, name });
};

const { getChainInfo } = useGetChainInfo();
const { restURLs } = getChainInfo(chainID);

const { getContractInfo, contractError, contractLoading } = useContracts();

const paramsContractAddress = useSearchParams().get('contract');

const fetchContractInfo = async () => {
try {
const { data } = await getContractInfo({
address: paramsContractAddress || '',
baseURLs: restURLs,
});
if (data) {
dispatch(
setContract({
chainID,
contractAddress: data?.address,
contractInfo: data?.contract_info,
})
);
setSelectedContract({
address: data?.address,
name: data?.contract_info?.label,
});
}
/* eslint-disable @typescript-eslint/no-explicit-any */
} catch (error: any) {
console.log(error);
}
};

useEffect(() => {
if (paramsContractAddress?.length) {
fetchContractInfo();
}
}, [paramsContractAddress]);

return (
<div className="h-full flex flex-col gap-10">
<div className="border-b-[1px] border-[#ffffff1e] pb-4 space-y-2">
Expand Down Expand Up @@ -52,6 +97,16 @@ const Contracts = ({ chainID }: { chainID: string }) => {
{deployContractOpen && !selectedContract.address ? (
<DeployContract chainID={chainID} />
) : null}
{contractLoading ? (
<div className="flex-center-center gap-2">
<CircularProgress sx={{ color: 'white' }} size={18} />
<div className="italic font-extralight text-[14px]">
Fetching contract info <span className="dots-flashing"></span>
</div>
</div>
) : contractError ? (
<div className="text-red-300 text-center py-6">{contractError}</div>
) : null}
{selectedContract.address ? <ContractInfo chainID={chainID} /> : null}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import CommonCopy from '@/components/CommonCopy';
import { dialogBoxPaperPropStyles } from '@/utils/commonStyles';
import { CLOSE_ICON_PATH } from '@/utils/constants';
import { Dialog, DialogContent } from '@mui/material';
import Image from 'next/image';
import React from 'react';

const DialogAddressesList = ({
addresses,
onClose,
open,
}: {
open: boolean;
onClose: () => void;
addresses: string[];
}) => {
const handleDialogClose = () => {
onClose();
};
return (
<Dialog
open={open}
onClose={handleDialogClose}
maxWidth="lg"
PaperProps={{
sx: dialogBoxPaperPropStyles,
}}
>
<DialogContent sx={{ padding: 0 }}>
<div className="w-[890px] text-white">
<div className="px-10 pb-6 pt-10 flex justify-end">
<div onClick={onClose}>
<Image
className="cursor-pointer"
src={CLOSE_ICON_PATH}
width={24}
height={24}
alt="close"
draggable={false}
/>
</div>
</div>
<div className="px-10 space-y-4 pb-10">
<div className="space-y-1">
<div className="flex items-center text-white text-xl not-italic font-bold leading-[normal]">
Allowed Addresses
</div>
<div className="text-[12px] font-light">
List of addresses that are allowed to instantiate contract{' '}
</div>
</div>
<div className="divider-line"></div>
<div className="flex flex-wrap gap-4">
{addresses.map((address) => (
<div key={address}>
<CommonCopy message={address} style="" plainIcon={true} />
</div>
))}
</div>
</div>
</div>
</DialogContent>
</Dialog>
);
};

export default DialogAddressesList;
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { setContract } from '@/store/features/cosmwasm/cosmwasmSlice';
import useContracts from '@/custom-hooks/useContracts';
import ContractItem from './ContractItem';
import SearchInputField from './SearchInputField';
import { useRouter } from 'next/navigation';

interface DialogSearchContractI {
open: boolean;
Expand All @@ -21,6 +22,7 @@ interface DialogSearchContractI {
const DialogSearchContract = (props: DialogSearchContractI) => {
const { onClose, open, chainID, restURLs, handleSelectContract } = props;
const dispatch = useAppDispatch();
const router = useRouter();
const handleClose = () => {
onClose();
setSearchTerm('');
Expand Down Expand Up @@ -54,6 +56,7 @@ const DialogSearchContract = (props: DialogSearchContractI) => {
contractInfo: searchResult?.contract_info,
})
);
router.push(`?contract=${searchResult?.address}`);
handleSelectContract(
searchResult?.address,
searchResult?.contract_info?.label
Expand Down
Loading

0 comments on commit c1939db

Please sign in to comment.