diff --git a/examples/chain-template/components/contract/EmptyState.tsx b/examples/chain-template/components/contract/EmptyState.tsx
new file mode 100644
index 00000000..eab98f75
--- /dev/null
+++ b/examples/chain-template/components/contract/EmptyState.tsx
@@ -0,0 +1,17 @@
+import Image from 'next/image';
+import { Box, Text } from '@interchain-ui/react';
+
+export const EmptyState = ({ text }: { text: string }) => (
+
+
+
+ {text}
+
+
+);
diff --git a/examples/chain-template/components/contract/ExecuteTab.tsx b/examples/chain-template/components/contract/ExecuteTab.tsx
new file mode 100644
index 00000000..3b7082a4
--- /dev/null
+++ b/examples/chain-template/components/contract/ExecuteTab.tsx
@@ -0,0 +1,19 @@
+import { Box, Text } from '@interchain-ui/react';
+
+type ExecuteTabProps = {
+ show: boolean;
+ initialAddress: string;
+ clearInitAddress: () => void;
+};
+
+export const ExecuteTab = ({
+ show,
+ initialAddress,
+ clearInitAddress,
+}: ExecuteTabProps) => {
+ return (
+
+ Execute Contract
+
+ );
+};
diff --git a/examples/chain-template/components/contract/MyContractsTab.tsx b/examples/chain-template/components/contract/MyContractsTab.tsx
new file mode 100644
index 00000000..f8707337
--- /dev/null
+++ b/examples/chain-template/components/contract/MyContractsTab.tsx
@@ -0,0 +1,129 @@
+import { useState } from 'react';
+import { useChain } from '@cosmos-kit/react';
+import { Box, Icon, Spinner, Text } from '@interchain-ui/react';
+
+import { useCopyToClipboard, useMyContracts } from '@/hooks';
+import { Button, Table } from '../common';
+import { shortenAddress } from '@/utils';
+import { TabLabel } from '@/pages/contract';
+import { EmptyState } from './EmptyState';
+import { useChainStore } from '@/contexts';
+
+type MyContractsTabProps = {
+ show: boolean;
+ switchTab: (initialAddress: string, tabId: number) => void;
+};
+
+export const MyContractsTab = ({ show, switchTab }: MyContractsTabProps) => {
+ const { selectedChain } = useChainStore();
+ const { address } = useChain(selectedChain);
+ const { data: myContracts = [], isLoading } = useMyContracts();
+
+ return (
+
+
+ My contracts
+
+
+ {!address ? (
+
+ ) : isLoading ? (
+
+ ) : myContracts.length === 0 ? (
+
+ ) : (
+
+
+
+
+
+ Contract Address
+
+ Contract Name
+ Code ID
+
+
+
+
+ {myContracts.map(({ address, contractInfo }) => (
+
+
+
+
+ {contractInfo?.label}
+
+ {Number(contractInfo?.codeId)}
+
+
+
+
+
+
+
+
+ ))}
+
+
+
+ )}
+
+
+ );
+};
+
+const CopyText = ({
+ copyValue,
+ displayValue,
+}: {
+ displayValue: string;
+ copyValue: string;
+}) => {
+ const [isHover, setIsHover] = useState(false);
+ const { copyToClipboard, isCopied } = useCopyToClipboard();
+
+ return (
+ setIsHover(true),
+ onMouseLeave: () => setIsHover(false),
+ onClick: () => copyToClipboard(copyValue),
+ }}
+ >
+
+ {displayValue}
+
+ {isHover && (
+
+
+
+ )}
+
+ );
+};
diff --git a/examples/chain-template/components/contract/QueryTab.tsx b/examples/chain-template/components/contract/QueryTab.tsx
new file mode 100644
index 00000000..745c1f21
--- /dev/null
+++ b/examples/chain-template/components/contract/QueryTab.tsx
@@ -0,0 +1,19 @@
+import { Box, Text } from '@interchain-ui/react';
+
+type QueryTabProps = {
+ show: boolean;
+ initialAddress: string;
+ clearInitAddress: () => void;
+};
+
+export const QueryTab = ({
+ show,
+ initialAddress,
+ clearInitAddress,
+}: QueryTabProps) => {
+ return (
+
+ Query Contract
+
+ );
+};
diff --git a/examples/chain-template/components/contract/index.ts b/examples/chain-template/components/contract/index.ts
new file mode 100644
index 00000000..1848e3e4
--- /dev/null
+++ b/examples/chain-template/components/contract/index.ts
@@ -0,0 +1,3 @@
+export * from './QueryTab';
+export * from './ExecuteTab';
+export * from './MyContractsTab';
diff --git a/examples/chain-template/components/index.ts b/examples/chain-template/components/index.ts
index faa582f0..9b9594a6 100644
--- a/examples/chain-template/components/index.ts
+++ b/examples/chain-template/components/index.ts
@@ -2,3 +2,4 @@ export * from './common';
export * from './staking';
export * from './voting';
export * from './asset-list';
+export * from './contract';
diff --git a/examples/chain-template/hooks/contract/useStoreCodeTx.tsx b/examples/chain-template/hooks/contract/useStoreCodeTx.tsx
index 48e32af1..6aa79303 100644
--- a/examples/chain-template/hooks/contract/useStoreCodeTx.tsx
+++ b/examples/chain-template/hooks/contract/useStoreCodeTx.tsx
@@ -40,7 +40,7 @@ export const useStoreCodeTx = (chainName: string) => {
});
const wasmCode = await wasmFile.arrayBuffer();
- const wasmByteCode = await gzip(new Uint8Array(wasmCode));
+ const wasmByteCode = new Uint8Array(await gzip(new Uint8Array(wasmCode)));
const message = storeCode({
sender: address,
diff --git a/examples/chain-template/pages/contract.tsx b/examples/chain-template/pages/contract.tsx
index 005f8697..07e75e91 100644
--- a/examples/chain-template/pages/contract.tsx
+++ b/examples/chain-template/pages/contract.tsx
@@ -1,5 +1,65 @@
-import { Box } from '@interchain-ui/react';
+import { useEffect, useState } from 'react';
+import { Box, Tabs } from '@interchain-ui/react';
+
+import { ExecuteTab, MyContractsTab, QueryTab } from '@/components';
+import { splitCamelCase } from '@/utils';
+import styles from '@/styles/comp.module.css';
+
+export enum TabLabel {
+ MyContracts,
+ Query,
+ Execute,
+}
export default function Contract() {
- return Contract;
+ const [activeTab, setActiveTab] = useState(TabLabel.MyContracts);
+ const [initQueryAddress, setInitQueryAddress] = useState('');
+ const [initExecuteAddress, setInitExecuteAddress] = useState('');
+
+ useEffect(() => {
+ if (activeTab !== TabLabel.Query) setInitQueryAddress('');
+ if (activeTab !== TabLabel.Execute) setInitExecuteAddress('');
+ }, [activeTab]);
+
+ const switchTabWithAddress = (address: string, tabId: TabLabel) => {
+ setActiveTab(tabId);
+ if (tabId === TabLabel.Query) setInitQueryAddress(address);
+ if (tabId === TabLabel.Execute) setInitExecuteAddress(address);
+ };
+
+ return (
+ <>
+ typeof v === 'string')
+ .map((label) => ({
+ label: splitCamelCase(label as string),
+ content: undefined,
+ }))}
+ activeTab={activeTab}
+ onActiveTabChange={(tabId) => setActiveTab(tabId)}
+ className={styles.tabs}
+ />
+
+
+ {
+ if (initQueryAddress) setInitQueryAddress('');
+ }}
+ />
+ {
+ if (initExecuteAddress) setInitExecuteAddress('');
+ }}
+ />
+
+ >
+ );
}