From 3057bbedc372e3d5bc85398d9f727ee7e33411b1 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Wed, 18 Jan 2023 15:29:12 +0700 Subject: [PATCH 1/9] feat: add clear admin menuitem --- CHANGELOG.md | 1 + src/lib/app-fns/tx/clearAdmin.tsx | 73 +++++++++++ src/lib/app-provider/tx/clearAdmin.ts | 35 ++++++ .../modal/contract/ClearAdminContract.tsx | 43 +++++++ src/lib/data/constant.ts | 4 +- src/lib/data/queries.ts | 16 +++ src/lib/gql/gql.ts | 11 +- src/lib/gql/graphql.ts | 118 ++++++++++++++++++ .../components/ContractListTable.tsx | 28 +++++ src/lib/services/codeService.ts | 1 + src/lib/services/contractService.ts | 28 +++++ src/lib/types/contract.ts | 1 + src/lib/types/tx/model.ts | 7 +- 13 files changed, 361 insertions(+), 5 deletions(-) create mode 100644 src/lib/app-fns/tx/clearAdmin.tsx create mode 100644 src/lib/app-provider/tx/clearAdmin.ts create mode 100644 src/lib/components/modal/contract/ClearAdminContract.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 34ffd59ff..240f44512 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features +- [#98](https://github.com/alleslabs/celatone-frontend/pull/98) Add clear admin menu in all contract list - [#89](https://github.com/alleslabs/celatone-frontend/pull/89) Update feedback link - [#90](https://github.com/alleslabs/celatone-frontend/pull/90) Add update admin (`/admin`) and migrate (`/migrate`) page routes - [#91](https://github.com/alleslabs/celatone-frontend/pull/91) Add migrate shortcut to the sidebar diff --git a/src/lib/app-fns/tx/clearAdmin.tsx b/src/lib/app-fns/tx/clearAdmin.tsx new file mode 100644 index 000000000..5e3294f9b --- /dev/null +++ b/src/lib/app-fns/tx/clearAdmin.tsx @@ -0,0 +1,73 @@ +import { Icon } from "@chakra-ui/react"; +import type { + SigningCosmWasmClient, + ChangeAdminResult, +} from "@cosmjs/cosmwasm-stargate"; +import type { StdFee } from "@cosmjs/stargate"; +import { pipe } from "@rx-stream/pipe"; +import { MdCheckCircle } from "react-icons/md"; +import type { Observable } from "rxjs"; + +import { ExplorerLink } from "lib/components/ExplorerLink"; +import { TxStreamPhase } from "lib/types"; +import type { TxResultRendering, ContractAddr } from "lib/types"; +import { formatUFee } from "lib/utils/formatter/denom"; + +import { catchTxError } from "./common/catchTxError"; +import { postTx } from "./common/post"; +import { sendingTx } from "./common/sending"; + +interface ClearAdminTxParams { + address: string; + contractAddress: ContractAddr; + fee: StdFee; + memo?: string; + client: SigningCosmWasmClient; + onTxSucceed?: (txHash: string) => void; +} + +export const clearAdminTx = ({ + address, + contractAddress, + fee, + memo, + client, + onTxSucceed, +}: ClearAdminTxParams): Observable => { + return pipe( + sendingTx(fee), + postTx({ + postFn: () => client.clearAdmin(address, contractAddress, fee, memo), + }), + ({ value: txInfo }) => { + onTxSucceed?.(txInfo.transactionHash); + return { + value: null, + phase: TxStreamPhase.SUCCEED, + receipts: [ + { + title: "Tx Hash", + value: txInfo.transactionHash, + html: ( + + ), + }, + { + title: "Tx Fee", + value: `${formatUFee( + txInfo.events.find((e) => e.type === "tx")?.attributes[0].value ?? + "0u" + )}`, + }, + ], + receiptInfo: { + header: "Transaction Complete", + headerIcon: ( + + ), + }, + actionVariant: "clear_admin", + } as TxResultRendering; + } + )().pipe(catchTxError()); +}; diff --git a/src/lib/app-provider/tx/clearAdmin.ts b/src/lib/app-provider/tx/clearAdmin.ts new file mode 100644 index 000000000..beaccfcb8 --- /dev/null +++ b/src/lib/app-provider/tx/clearAdmin.ts @@ -0,0 +1,35 @@ +import { useWallet } from "@cosmos-kit/react"; +import { useCallback } from "react"; + +import { useFabricateFee } from "../hooks"; +import { clearAdminTx } from "lib/app-fns/tx/clearAdmin"; +import { CLEAR_ADMIN_GAS } from "lib/data"; +import type { ContractAddr, Option } from "lib/types"; + +export interface ClearAdminStreamParams { + onTxSucceed?: (txHash: string) => void; +} + +export const useClearAdminTx = (contractAddress: Option) => { + const { address, getCosmWasmClient } = useWallet(); + const fabricateFee = useFabricateFee(); + const clearAdminFee = fabricateFee(CLEAR_ADMIN_GAS); + + return useCallback( + async ({ onTxSucceed }: ClearAdminStreamParams) => { + const client = await getCosmWasmClient(); + if (!address || !client) + throw new Error("Please check your wallet connection."); + if (!contractAddress) return null; + + return clearAdminTx({ + address, + contractAddress, + fee: clearAdminFee, + client, + onTxSucceed, + }); + }, + [address, clearAdminFee, contractAddress, getCosmWasmClient] + ); +}; diff --git a/src/lib/components/modal/contract/ClearAdminContract.tsx b/src/lib/components/modal/contract/ClearAdminContract.tsx new file mode 100644 index 000000000..da0fc5744 --- /dev/null +++ b/src/lib/components/modal/contract/ClearAdminContract.tsx @@ -0,0 +1,43 @@ +import { Text } from "@chakra-ui/react"; +import { useCallback } from "react"; +import { MdDeleteForever } from "react-icons/md"; + +import { ActionModal } from "../ActionModal"; +import { useClearAdminTx } from "lib/app-provider/tx/clearAdmin"; +import { useTxBroadcast } from "lib/providers/tx-broadcast"; +import type { ContractAddr } from "lib/types"; + +interface ClearAdminContractProps { + contractAddress: ContractAddr; + triggerElement: JSX.Element; +} + +export const ClearAdminContract = ({ + contractAddress, + triggerElement, +}: ClearAdminContractProps) => { + const { broadcast } = useTxBroadcast(); + const clearAdminTx = useClearAdminTx(contractAddress); + + const proceed = useCallback(async () => { + const stream = await clearAdminTx({ onTxSucceed: () => {} }); + if (stream) broadcast(stream); + }, [broadcast, clearAdminTx]); + + return ( + + + Clear Admin will set the admin of the contract to `nil`, while will + disable further migrations/updates on this contract. + + + ); +}; diff --git a/src/lib/data/constant.ts b/src/lib/data/constant.ts index 42eb4d9c0..8fcf3135a 100644 --- a/src/lib/data/constant.ts +++ b/src/lib/data/constant.ts @@ -53,7 +53,9 @@ export const DEFAULT_ADDRESS = "default-address"; export const MAX_FILE_SIZE = 800_000; -export const MICRO = 1000000; +export const CLEAR_ADMIN_GAS = 50_000; + +export const MICRO = 1_000_000; export const typeUrlDict = { [MsgType.STORE_CODE]: "/cosmwasm.wasm.v1.MsgStoreCode", diff --git a/src/lib/data/queries.ts b/src/lib/data/queries.ts index 4bf1cf466..2db6f21d8 100644 --- a/src/lib/data/queries.ts +++ b/src/lib/data/queries.ts @@ -117,6 +117,19 @@ export const getInstantiateDetailByContractQueryDocument = graphql(` } `); +export const getAdminByContractAddressesQueryDocument = graphql(` + query getAdminByContractAddressesQueryDocument( + $contractAddresses: [String!] + ) { + contracts(where: { address: { _in: $contractAddresses } }) { + address + account { + address + } + } + } +`); + export const getExecuteTxsByContractAddress = graphql(` query getExecuteTxsByContractAddress( $contractAddress: String! @@ -250,6 +263,9 @@ export const getContractListByCodeId = graphql(` ) { address label + account { + address + } transaction { block { timestamp diff --git a/src/lib/gql/gql.ts b/src/lib/gql/gql.ts index 5cc62265a..ee1b2fcfd 100644 --- a/src/lib/gql/gql.ts +++ b/src/lib/gql/gql.ts @@ -17,6 +17,8 @@ const documents = { types.GetInstantiatedListByUserQueryDocumentDocument, '\n query getInstantiateDetailByContractQueryDocument($contractAddress: String!) {\n contracts_by_pk(address: $contractAddress) {\n init_msg\n transaction {\n hash\n }\n contract_proposals(\n where: {\n proposal: {\n type: { _in: ["InstantiateContract", "InstantiateContract2"] }\n }\n }\n limit: 1\n ) {\n proposal {\n id\n title\n }\n }\n }\n }\n': types.GetInstantiateDetailByContractQueryDocumentDocument, + "\n query getAdminByContractAddressesQueryDocument(\n $contractAddresses: [String!]\n ) {\n contracts(where: { address: { _in: $contractAddresses } }) {\n address\n account {\n address\n }\n }\n }\n": + types.GetAdminByContractAddressesQueryDocumentDocument, "\n query getExecuteTxsByContractAddress(\n $contractAddress: String!\n $offset: Int!\n $pageSize: Int!\n ) {\n contract_transactions(\n where: {\n contract: { address: { _eq: $contractAddress } }\n transaction: { is_execute: { _eq: true } }\n }\n order_by: { transaction: { block: { timestamp: desc } } }\n limit: $pageSize\n offset: $offset\n ) {\n transaction {\n hash\n messages\n success\n account {\n address\n }\n block {\n height\n timestamp\n }\n }\n }\n }\n": types.GetExecuteTxsByContractAddressDocument, "\n query getExecuteTxsCountByContractAddress($contractAddress: String!) {\n contract_transactions_aggregate(\n where: {\n contract: { address: { _eq: $contractAddress } }\n transaction: { is_execute: { _eq: true } }\n }\n ) {\n aggregate {\n count\n }\n }\n }\n": @@ -29,7 +31,7 @@ const documents = { types.GetRelatedProposalsByContractAddressDocument, "\n query getRelatedProposalsCountByContractAddress($contractAddress: String!) {\n contract_proposals_aggregate(\n where: { contract: { address: { _eq: $contractAddress } } }\n ) {\n aggregate {\n count\n }\n }\n }\n": types.GetRelatedProposalsCountByContractAddressDocument, - "\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { transaction: { block: { timestamp: desc } } }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n transaction {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n": + "\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { transaction: { block: { timestamp: desc } } }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n account {\n address\n }\n transaction {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n": types.GetContractListByCodeIdDocument, "\n query getContractListCountByCodeId($codeId: Int!) {\n contracts_aggregate(where: { code_id: { _eq: $codeId } }) {\n aggregate {\n count\n }\n }\n }\n": types.GetContractListCountByCodeIdDocument, @@ -62,6 +64,9 @@ export function graphql( export function graphql( source: '\n query getInstantiateDetailByContractQueryDocument($contractAddress: String!) {\n contracts_by_pk(address: $contractAddress) {\n init_msg\n transaction {\n hash\n }\n contract_proposals(\n where: {\n proposal: {\n type: { _in: ["InstantiateContract", "InstantiateContract2"] }\n }\n }\n limit: 1\n ) {\n proposal {\n id\n title\n }\n }\n }\n }\n' ): typeof documents['\n query getInstantiateDetailByContractQueryDocument($contractAddress: String!) {\n contracts_by_pk(address: $contractAddress) {\n init_msg\n transaction {\n hash\n }\n contract_proposals(\n where: {\n proposal: {\n type: { _in: ["InstantiateContract", "InstantiateContract2"] }\n }\n }\n limit: 1\n ) {\n proposal {\n id\n title\n }\n }\n }\n }\n']; +export function graphql( + source: "\n query getAdminByContractAddressesQueryDocument(\n $contractAddresses: [String!]\n ) {\n contracts(where: { address: { _in: $contractAddresses } }) {\n address\n account {\n address\n }\n }\n }\n" +): typeof documents["\n query getAdminByContractAddressesQueryDocument(\n $contractAddresses: [String!]\n ) {\n contracts(where: { address: { _in: $contractAddresses } }) {\n address\n account {\n address\n }\n }\n }\n"]; export function graphql( source: "\n query getExecuteTxsByContractAddress(\n $contractAddress: String!\n $offset: Int!\n $pageSize: Int!\n ) {\n contract_transactions(\n where: {\n contract: { address: { _eq: $contractAddress } }\n transaction: { is_execute: { _eq: true } }\n }\n order_by: { transaction: { block: { timestamp: desc } } }\n limit: $pageSize\n offset: $offset\n ) {\n transaction {\n hash\n messages\n success\n account {\n address\n }\n block {\n height\n timestamp\n }\n }\n }\n }\n" ): typeof documents["\n query getExecuteTxsByContractAddress(\n $contractAddress: String!\n $offset: Int!\n $pageSize: Int!\n ) {\n contract_transactions(\n where: {\n contract: { address: { _eq: $contractAddress } }\n transaction: { is_execute: { _eq: true } }\n }\n order_by: { transaction: { block: { timestamp: desc } } }\n limit: $pageSize\n offset: $offset\n ) {\n transaction {\n hash\n messages\n success\n account {\n address\n }\n block {\n height\n timestamp\n }\n }\n }\n }\n"]; @@ -81,8 +86,8 @@ export function graphql( source: "\n query getRelatedProposalsCountByContractAddress($contractAddress: String!) {\n contract_proposals_aggregate(\n where: { contract: { address: { _eq: $contractAddress } } }\n ) {\n aggregate {\n count\n }\n }\n }\n" ): typeof documents["\n query getRelatedProposalsCountByContractAddress($contractAddress: String!) {\n contract_proposals_aggregate(\n where: { contract: { address: { _eq: $contractAddress } } }\n ) {\n aggregate {\n count\n }\n }\n }\n"]; export function graphql( - source: "\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { transaction: { block: { timestamp: desc } } }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n transaction {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n" -): typeof documents["\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { transaction: { block: { timestamp: desc } } }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n transaction {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n"]; + source: "\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { transaction: { block: { timestamp: desc } } }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n account {\n address\n }\n transaction {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n" +): typeof documents["\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { transaction: { block: { timestamp: desc } } }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n account {\n address\n }\n transaction {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n"]; export function graphql( source: "\n query getContractListCountByCodeId($codeId: Int!) {\n contracts_aggregate(where: { code_id: { _eq: $codeId } }) {\n aggregate {\n count\n }\n }\n }\n" ): typeof documents["\n query getContractListCountByCodeId($codeId: Int!) {\n contracts_aggregate(where: { code_id: { _eq: $codeId } }) {\n aggregate {\n count\n }\n }\n }\n"]; diff --git a/src/lib/gql/graphql.ts b/src/lib/gql/graphql.ts index 7109585e7..7065eeb8b 100644 --- a/src/lib/gql/graphql.ts +++ b/src/lib/gql/graphql.ts @@ -6365,6 +6365,19 @@ export type GetInstantiateDetailByContractQueryDocumentQuery = { } | null; }; +export type GetAdminByContractAddressesQueryDocumentQueryVariables = Exact<{ + contractAddresses?: InputMaybe | Scalars["String"]>; +}>; + +export type GetAdminByContractAddressesQueryDocumentQuery = { + __typename?: "query_root"; + contracts: Array<{ + __typename?: "contracts"; + address: string; + account?: { __typename?: "accounts"; address: string } | null; + }>; +}; + export type GetExecuteTxsByContractAddressQueryVariables = Exact<{ contractAddress: Scalars["String"]; offset: Scalars["Int"]; @@ -6484,6 +6497,7 @@ export type GetContractListByCodeIdQuery = { __typename?: "contracts"; address: string; label: string; + account?: { __typename?: "accounts"; address: string } | null; transaction?: { __typename?: "transactions"; block: { __typename?: "blocks"; timestamp: any }; @@ -7382,6 +7396,97 @@ export const GetInstantiateDetailByContractQueryDocumentDocument = { GetInstantiateDetailByContractQueryDocumentQuery, GetInstantiateDetailByContractQueryDocumentQueryVariables >; +export const GetAdminByContractAddressesQueryDocumentDocument = { + kind: "Document", + definitions: [ + { + kind: "OperationDefinition", + operation: "query", + name: { kind: "Name", value: "getAdminByContractAddressesQueryDocument" }, + variableDefinitions: [ + { + kind: "VariableDefinition", + variable: { + kind: "Variable", + name: { kind: "Name", value: "contractAddresses" }, + }, + type: { + kind: "ListType", + type: { + kind: "NonNullType", + type: { + kind: "NamedType", + name: { kind: "Name", value: "String" }, + }, + }, + }, + }, + ], + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { kind: "Name", value: "contracts" }, + arguments: [ + { + kind: "Argument", + name: { kind: "Name", value: "where" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "address" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "_in" }, + value: { + kind: "Variable", + name: { + kind: "Name", + value: "contractAddresses", + }, + }, + }, + ], + }, + }, + ], + }, + }, + ], + selectionSet: { + kind: "SelectionSet", + selections: [ + { kind: "Field", name: { kind: "Name", value: "address" } }, + { + kind: "Field", + name: { kind: "Name", value: "account" }, + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { kind: "Name", value: "address" }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + }, + ], +} as unknown as DocumentNode< + GetAdminByContractAddressesQueryDocumentQuery, + GetAdminByContractAddressesQueryDocumentQueryVariables +>; export const GetExecuteTxsByContractAddressDocument = { kind: "Document", definitions: [ @@ -8395,6 +8500,19 @@ export const GetContractListByCodeIdDocument = { selections: [ { kind: "Field", name: { kind: "Name", value: "address" } }, { kind: "Field", name: { kind: "Name", value: "label" } }, + { + kind: "Field", + name: { kind: "Name", value: "account" }, + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { kind: "Name", value: "address" }, + }, + ], + }, + }, { kind: "Field", name: { kind: "Name", value: "transaction" }, diff --git a/src/lib/pages/contract-list/components/ContractListTable.tsx b/src/lib/pages/contract-list/components/ContractListTable.tsx index f5862a65e..6c57a5b99 100644 --- a/src/lib/pages/contract-list/components/ContractListTable.tsx +++ b/src/lib/pages/contract-list/components/ContractListTable.tsx @@ -16,6 +16,7 @@ import { chakra, MenuItem, } from "@chakra-ui/react"; +import { useWallet } from "@cosmos-kit/react"; import Link from "next/link"; import { useRouter } from "next/router"; import { @@ -23,6 +24,7 @@ import { MdMode, MdOutlineBookmark, MdDelete, + MdPersonRemove, } from "react-icons/md"; import { ExplorerLink } from "lib/components/ExplorerLink"; @@ -31,6 +33,8 @@ import { EditContractDetails, RemoveContract, } from "lib/components/modal/contract"; +import { ClearAdminContract } from "lib/components/modal/contract/ClearAdminContract"; +import { useAdminByContractAddresses } from "lib/services/contractService"; import type { ContractLocalInfo } from "lib/stores/contract"; import type { LVPair } from "lib/types"; @@ -55,6 +59,11 @@ export const ContractListTable = ({ contractRemovalInfo, }: ContractListTableProps) => { const router = useRouter(); + const { address } = useWallet(); + const { data: admins = {} } = useAdminByContractAddresses( + contracts.map((contract) => contract.contractAddress) + ); + return ( @@ -170,6 +179,25 @@ export const ContractListTable = ({ } /> + + } + isDisabled={ + !address || + address !== admins[item.contractAddress] + } + > + Clear Admin + + } + /> {!!contractRemovalInfo && ( <> diff --git a/src/lib/services/codeService.ts b/src/lib/services/codeService.ts index 757a940ef..982000c8f 100644 --- a/src/lib/services/codeService.ts +++ b/src/lib/services/codeService.ts @@ -160,6 +160,7 @@ export const useContractListByCodeId = ( contractAddress: contract.address as ContractAddr, instantiator: unwrap(contract.transaction?.account.address), label: contract.label, + admin: contract.account?.address, instantiated: parseDateDefault(contract.transaction?.block.timestamp), // TODO: handle Genesis case latestUpdator: contract.contract_histories.at(0)?.account.address, diff --git a/src/lib/services/contractService.ts b/src/lib/services/contractService.ts index 08a4bce3a..124da6d85 100644 --- a/src/lib/services/contractService.ts +++ b/src/lib/services/contractService.ts @@ -15,6 +15,7 @@ import { getTxsByContractAddress, getRelatedProposalsCountByContractAddress, getRelatedProposalsByContractAddress, + getAdminByContractAddressesQueryDocument, } from "lib/data/queries"; import type { ContractLocalInfo } from "lib/stores/contract"; import type { @@ -115,6 +116,33 @@ export const useInstantiateDetailByContractQuery = ( ); }; +export const useAdminByContractAddresses = ( + contractAddresses: Option +): UseQueryResult>> => { + const queryFn = useCallback(async () => { + if (!contractAddresses) return undefined; + + return indexerGraphClient + .request(getAdminByContractAddressesQueryDocument, { + contractAddresses, + }) + .then(({ contracts }) => + contracts.reduce( + (prev, contract) => ({ + ...prev, + [contract.address as ContractAddr]: contract.account?.address, + }), + {} + ) + ); + }, [contractAddresses]); + + return useQuery(["admin_by_contracts", contractAddresses], queryFn, { + keepPreviousData: true, + enabled: !!contractAddresses, + }); +}; + export const useExecuteTxsByContractAddress = ( contractAddress: ContractAddr, offset: number, diff --git a/src/lib/types/contract.ts b/src/lib/types/contract.ts index 145eef071..2027a23ef 100644 --- a/src/lib/types/contract.ts +++ b/src/lib/types/contract.ts @@ -2,6 +2,7 @@ import type { ContractLocalInfo } from "lib/stores/contract"; import type { ContractAddr, HumanAddr, Option } from "lib/types"; export interface ContractInfo extends ContractLocalInfo { + admin: Option; instantiated: Date; latestUpdator?: string; latestUpdated: Date; diff --git a/src/lib/types/tx/model.ts b/src/lib/types/tx/model.ts index a2f3fbf2c..4ece9dabd 100644 --- a/src/lib/types/tx/model.ts +++ b/src/lib/types/tx/model.ts @@ -23,7 +23,12 @@ export interface ReceiptInfo { description?: ReactNode; } -export type ActionVariant = "sending" | "upload" | "rejected" | "resend"; +export type ActionVariant = + | "sending" + | "upload" + | "rejected" + | "resend" + | "clear_admin"; export interface TxResultRendering { /** From 4862c336d3d7969ed2abca800a9d78f10e73c99f Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Wed, 18 Jan 2023 16:34:31 +0700 Subject: [PATCH 2/9] fix: modal btns and text --- src/lib/components/modal/ActionModal.tsx | 11 ++++++----- .../components/modal/contract/ClearAdminContract.tsx | 11 +++++++---- src/lib/styles/theme/components/button.ts | 9 +++++++++ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/lib/components/modal/ActionModal.tsx b/src/lib/components/modal/ActionModal.tsx index 09f29367c..a3bb4f68a 100644 --- a/src/lib/components/modal/ActionModal.tsx +++ b/src/lib/components/modal/ActionModal.tsx @@ -28,9 +28,11 @@ export interface ActionModalProps { children?: ReactNode; mainBtnTitle?: string; mainAction: () => void; + mainVariant?: string; disabledMain?: boolean; otherBtnTitle?: string; otherAction?: () => void; + otherVariant?: string; noHeaderBorder?: boolean; noCloseButton?: boolean; } @@ -44,9 +46,11 @@ export function ActionModal({ children, mainBtnTitle = "Proceed", mainAction, + mainVariant = "primary", disabledMain = false, otherBtnTitle = "Cancel", otherAction, + otherVariant = "outline-primary", noHeaderBorder = false, noCloseButton = false, }: ActionModalProps) { @@ -93,15 +97,12 @@ export function ActionModal({ - diff --git a/src/lib/components/modal/contract/ClearAdminContract.tsx b/src/lib/components/modal/contract/ClearAdminContract.tsx index da0fc5744..721f48477 100644 --- a/src/lib/components/modal/contract/ClearAdminContract.tsx +++ b/src/lib/components/modal/contract/ClearAdminContract.tsx @@ -1,4 +1,4 @@ -import { Text } from "@chakra-ui/react"; +import { Code, Text } from "@chakra-ui/react"; import { useCallback } from "react"; import { MdDeleteForever } from "react-icons/md"; @@ -30,13 +30,16 @@ export const ClearAdminContract = ({ icon={MdDeleteForever} iconColor="error.light" trigger={triggerElement} - mainBtnTitle="Yes" + mainBtnTitle="Yes, clear it" mainAction={proceed} + mainVariant="error" otherBtnTitle="No, keep it" + otherVariant="ghost-primary" > - Clear Admin will set the admin of the contract to `nil`, while will - disable further migrations/updates on this contract. + ‘Clear Admin’ will set the admin of the contract to{" "} + nil , while will disable further migrations/updates on this + contract. ); diff --git a/src/lib/styles/theme/components/button.ts b/src/lib/styles/theme/components/button.ts index ce0417c9f..2c86ed2e4 100644 --- a/src/lib/styles/theme/components/button.ts +++ b/src/lib/styles/theme/components/button.ts @@ -71,6 +71,15 @@ export const Button: ComponentStyleConfig = { hoverBg: "primary.dark", activeBg: "primary.light", }), + error: generateStyle({ + basic: { background: "error.main", color: "black" }, + disabled: { + background: white12, + color: white50, + }, + hoverBg: "error.dark", + activeBg: "error.light", + }), "outline-primary": generateStyle({ basic: { border: "1px solid", From a6a6464a284a583ae661136d8f5169f27c2a76d7 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Fri, 20 Jan 2023 01:05:24 +0700 Subject: [PATCH 3/9] feat: add admin fns on contract detail and list --- CHANGELOG.md | 2 +- .../components/ContractTop.tsx | 79 +++++++++++++++++-- .../components/ContractListTable.tsx | 45 +++++++++-- 3 files changed, 111 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 497f15941..9a6dda7f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,7 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features -- [#98](https://github.com/alleslabs/celatone-frontend/pull/98) Add clear admin menu in all contract list +- [#98](https://github.com/alleslabs/celatone-frontend/pull/98) Add migrate, update admin, clear admin menu on contract list and detail - [#107](https://github.com/alleslabs/celatone-frontend/pull/107) Remove osmosis mainnet from chain list - [#99](https://github.com/alleslabs/celatone-frontend/pull/99) Validate label and codeId field in instantiate page - [#103](https://github.com/alleslabs/celatone-frontend/pull/103) Add check mark to selected network diff --git a/src/lib/pages/contract-details/components/ContractTop.tsx b/src/lib/pages/contract-details/components/ContractTop.tsx index d844738e2..7a8205476 100644 --- a/src/lib/pages/contract-details/components/ContractTop.tsx +++ b/src/lib/pages/contract-details/components/ContractTop.tsx @@ -6,12 +6,21 @@ import { Button, Icon, IconButton, + MenuItem, + chakra, + MenuButton, + Menu, + MenuList, } from "@chakra-ui/react"; +import { useWallet } from "@cosmos-kit/react"; import { MdBookmark, MdBookmarkBorder, MdInput, MdKeyboardArrowDown, + MdPerson, + MdPersonRemove, + MdReadMore, } from "react-icons/md"; import { RiPencilFill } from "react-icons/ri"; @@ -22,17 +31,34 @@ import { EditContractDetails, SaveContractDetails, } from "lib/components/modal"; +import { ClearAdminContract } from "lib/components/modal/contract/ClearAdminContract"; import type { ContractData } from "lib/model/contract"; import type { ContractAddr } from "lib/types"; +const StyledMenuItem = chakra(MenuItem, { + baseStyle: { + fontSize: "14px", + }, +}); + +const StyledIcon = chakra(Icon, { + baseStyle: { + boxSize: "4", + display: "flex", + alignItems: "center", + }, +}); + interface ContractTopProps { contractData: ContractData; } export const ContractTop = ({ contractData }: ContractTopProps) => { const navigate = useInternalNavigate(); + const { address } = useWallet(); const { contractLocalInfo, instantiateInfo, publicInfo } = contractData; const contractAddress = instantiateInfo?.contractAddress as ContractAddr; + const admin = instantiateInfo?.admin; const displayName = contractLocalInfo?.name || publicInfo?.name || instantiateInfo?.label; @@ -134,14 +160,51 @@ export const ContractTop = ({ contractData }: ContractTopProps) => { )} - - {/* TODO - Revisit, implement admin button */} - + + + } + > + Admin + + + } + onClick={() => { + navigate({ + pathname: "/migrate", + query: { contract: contractAddress }, + }); + }} + > + Migrate + + } + onClick={() => { + navigate({ + pathname: "/admin", + query: { contract: contractAddress }, + }); + }} + > + Update Admin + + } + > + Clear Admin + + } + /> + + + + + } > Edit details - + } /> Add or remove from other lists - + } /> + } + onClick={() => { + navigate({ + pathname: "/admin", + query: { contract: item.contractAddress }, + }); + }} + isDisabled={ + !address || address !== admins[item.contractAddress] + } + > + Update Admin + Clear Admin - + } /> {!!contractRemovalInfo && ( @@ -205,6 +237,7 @@ export const ContractListTable = ({ contractLocalInfo={item} contractRemovalInfo={contractRemovalInfo} menuItemProps={{ + fontSize: "14px", icon: ( ), From 7056199ca3a8e38b4231b43f27fd4df6e7b568b7 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Fri, 20 Jan 2023 01:18:38 +0700 Subject: [PATCH 4/9] fix: clear admin text + add tooltip on detail page --- .../modal/contract/ClearAdminContract.tsx | 7 +++--- .../components/ContractTop.tsx | 24 +++++++++++++------ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/lib/components/modal/contract/ClearAdminContract.tsx b/src/lib/components/modal/contract/ClearAdminContract.tsx index 721f48477..3d6d71f9d 100644 --- a/src/lib/components/modal/contract/ClearAdminContract.tsx +++ b/src/lib/components/modal/contract/ClearAdminContract.tsx @@ -1,4 +1,4 @@ -import { Code, Text } from "@chakra-ui/react"; +import { Text } from "@chakra-ui/react"; import { useCallback } from "react"; import { MdDeleteForever } from "react-icons/md"; @@ -37,9 +37,8 @@ export const ClearAdminContract = ({ otherVariant="ghost-primary" > - ‘Clear Admin’ will set the admin of the contract to{" "} - nil , while will disable further migrations/updates on this - contract. + Clearing the admin is a permanent action. You'll not be able to + reassign an admin and migrations will no longer be possible. ); diff --git a/src/lib/pages/contract-details/components/ContractTop.tsx b/src/lib/pages/contract-details/components/ContractTop.tsx index 7a8205476..941d7af59 100644 --- a/src/lib/pages/contract-details/components/ContractTop.tsx +++ b/src/lib/pages/contract-details/components/ContractTop.tsx @@ -11,6 +11,7 @@ import { MenuButton, Menu, MenuList, + Tooltip, } from "@chakra-ui/react"; import { useWallet } from "@cosmos-kit/react"; import { @@ -162,14 +163,23 @@ export const ContractTop = ({ contractData }: ContractTopProps) => { - } + - Admin - + } + > + Admin + + } From cbfb87c6fb82d86ebf480d4a7f5ea2b20cfa4af2 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Fri, 20 Jan 2023 01:19:16 +0700 Subject: [PATCH 5/9] fix: text --- src/lib/pages/contract-details/components/ContractTop.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/pages/contract-details/components/ContractTop.tsx b/src/lib/pages/contract-details/components/ContractTop.tsx index 941d7af59..3883429ad 100644 --- a/src/lib/pages/contract-details/components/ContractTop.tsx +++ b/src/lib/pages/contract-details/components/ContractTop.tsx @@ -165,7 +165,7 @@ export const ContractTop = ({ contractData }: ContractTopProps) => { Date: Tue, 24 Jan 2023 12:01:20 +0700 Subject: [PATCH 6/9] fix: as commented --- src/lib/app-fns/tx/clearAdmin.tsx | 1 - src/lib/app-provider/tx/clearAdmin.ts | 4 +- src/lib/components/button/AdminButton.tsx | 101 ++++++ src/lib/components/button/index.ts | 1 + .../code-details/components/CTASection.tsx | 2 +- src/lib/pages/codes/components/CodesTable.tsx | 2 +- .../components/ContractTop.tsx | 94 +---- .../components/ContractListTable.tsx | 326 +++++++++--------- src/lib/types/tx/model.ts | 7 +- 9 files changed, 278 insertions(+), 260 deletions(-) create mode 100644 src/lib/components/button/AdminButton.tsx diff --git a/src/lib/app-fns/tx/clearAdmin.tsx b/src/lib/app-fns/tx/clearAdmin.tsx index 5e3294f9b..06384006a 100644 --- a/src/lib/app-fns/tx/clearAdmin.tsx +++ b/src/lib/app-fns/tx/clearAdmin.tsx @@ -66,7 +66,6 @@ export const clearAdminTx = ({ ), }, - actionVariant: "clear_admin", } as TxResultRendering; } )().pipe(catchTxError()); diff --git a/src/lib/app-provider/tx/clearAdmin.ts b/src/lib/app-provider/tx/clearAdmin.ts index beaccfcb8..96ef01d8a 100644 --- a/src/lib/app-provider/tx/clearAdmin.ts +++ b/src/lib/app-provider/tx/clearAdmin.ts @@ -4,13 +4,13 @@ import { useCallback } from "react"; import { useFabricateFee } from "../hooks"; import { clearAdminTx } from "lib/app-fns/tx/clearAdmin"; import { CLEAR_ADMIN_GAS } from "lib/data"; -import type { ContractAddr, Option } from "lib/types"; +import type { ContractAddr } from "lib/types"; export interface ClearAdminStreamParams { onTxSucceed?: (txHash: string) => void; } -export const useClearAdminTx = (contractAddress: Option) => { +export const useClearAdminTx = (contractAddress: ContractAddr) => { const { address, getCosmWasmClient } = useWallet(); const fabricateFee = useFabricateFee(); const clearAdminFee = fabricateFee(CLEAR_ADMIN_GAS); diff --git a/src/lib/components/button/AdminButton.tsx b/src/lib/components/button/AdminButton.tsx new file mode 100644 index 000000000..2732ab8aa --- /dev/null +++ b/src/lib/components/button/AdminButton.tsx @@ -0,0 +1,101 @@ +import { + Button, + chakra, + Icon, + Menu, + MenuButton, + MenuItem, + MenuList, + Tooltip, +} from "@chakra-ui/react"; +import { useWallet } from "@cosmos-kit/react"; +import { + MdKeyboardArrowDown, + MdPerson, + MdPersonRemove, + MdReadMore, +} from "react-icons/md"; + +import { ClearAdminContract } from "../modal/contract/ClearAdminContract"; +import { useInternalNavigate } from "lib/app-provider"; +import type { ContractAddr, HumanAddr, Option } from "lib/types"; + +const StyledMenuItem = chakra(MenuItem, { + baseStyle: { + fontSize: "14px", + }, +}); + +const StyledIcon = chakra(Icon, { + baseStyle: { + boxSize: "4", + display: "flex", + alignItems: "center", + }, +}); + +interface AdminButtonProps { + contractAddress: ContractAddr; + admin: Option; +} + +export const AdminButton = ({ contractAddress, admin }: AdminButtonProps) => { + const { address } = useWallet(); + const navigate = useInternalNavigate(); + + return ( + + + } + > + Admin + + + + } + onClick={() => { + navigate({ + pathname: "/migrate", + query: { contract: contractAddress }, + }); + }} + > + Migrate + + } + onClick={() => { + navigate({ + pathname: "/admin", + query: { contract: contractAddress }, + }); + }} + > + Update Admin + + } + > + Clear Admin + + } + /> + + + ); +}; diff --git a/src/lib/components/button/index.ts b/src/lib/components/button/index.ts index 5bd24bce8..91be0edd1 100644 --- a/src/lib/components/button/index.ts +++ b/src/lib/components/button/index.ts @@ -1,3 +1,4 @@ export * from "./BackButton"; export * from "./ConnectWallet"; +export * from "./InstantiateButton"; export * from "./ShowMoreButton"; diff --git a/src/lib/pages/code-details/components/CTASection.tsx b/src/lib/pages/code-details/components/CTASection.tsx index 856602d3a..d4e6e7b9b 100644 --- a/src/lib/pages/code-details/components/CTASection.tsx +++ b/src/lib/pages/code-details/components/CTASection.tsx @@ -2,7 +2,7 @@ import { Flex, Button, chakra, Icon } from "@chakra-ui/react"; import { observer } from "mobx-react-lite"; import { MdCheck } from "react-icons/md"; -import { InstantiateButton } from "lib/components/button/InstantiateButton"; +import { InstantiateButton } from "lib/components/button"; import { RemoveCode } from "lib/components/modal/code/RemoveCode"; import { SaveOrEditCodeModal } from "lib/components/modal/code/SaveOrEditCode"; import { useCodeStore } from "lib/hooks"; diff --git a/src/lib/pages/codes/components/CodesTable.tsx b/src/lib/pages/codes/components/CodesTable.tsx index 0e3548c5d..9c039a7c3 100644 --- a/src/lib/pages/codes/components/CodesTable.tsx +++ b/src/lib/pages/codes/components/CodesTable.tsx @@ -19,7 +19,7 @@ import type { ReactNode } from "react"; import { MdSearchOff } from "react-icons/md"; import { useInternalNavigate } from "lib/app-provider"; -import { InstantiateButton } from "lib/components/button/InstantiateButton"; +import { InstantiateButton } from "lib/components/button"; import { ExplorerLink } from "lib/components/ExplorerLink"; import { RemoveCode } from "lib/components/modal/code/RemoveCode"; import { SaveOrRemoveCode } from "lib/components/modal/code/SaveOrRemoveCode"; diff --git a/src/lib/pages/contract-details/components/ContractTop.tsx b/src/lib/pages/contract-details/components/ContractTop.tsx index 3883429ad..ab504c810 100644 --- a/src/lib/pages/contract-details/components/ContractTop.tsx +++ b/src/lib/pages/contract-details/components/ContractTop.tsx @@ -6,61 +6,30 @@ import { Button, Icon, IconButton, - MenuItem, - chakra, - MenuButton, - Menu, - MenuList, - Tooltip, } from "@chakra-ui/react"; -import { useWallet } from "@cosmos-kit/react"; -import { - MdBookmark, - MdBookmarkBorder, - MdInput, - MdKeyboardArrowDown, - MdPerson, - MdPersonRemove, - MdReadMore, -} from "react-icons/md"; +import { MdBookmark, MdBookmarkBorder, MdInput } from "react-icons/md"; import { RiPencilFill } from "react-icons/ri"; import { useInternalNavigate } from "lib/app-provider"; +import { AdminButton } from "lib/components/button/AdminButton"; import { ExplorerLink } from "lib/components/ExplorerLink"; import { AddToOtherList, EditContractDetails, SaveContractDetails, } from "lib/components/modal"; -import { ClearAdminContract } from "lib/components/modal/contract/ClearAdminContract"; import type { ContractData } from "lib/model/contract"; import type { ContractAddr } from "lib/types"; -const StyledMenuItem = chakra(MenuItem, { - baseStyle: { - fontSize: "14px", - }, -}); - -const StyledIcon = chakra(Icon, { - baseStyle: { - boxSize: "4", - display: "flex", - alignItems: "center", - }, -}); - interface ContractTopProps { contractData: ContractData; } export const ContractTop = ({ contractData }: ContractTopProps) => { const navigate = useInternalNavigate(); - const { address } = useWallet(); + const { contractLocalInfo, instantiateInfo, publicInfo } = contractData; const contractAddress = instantiateInfo?.contractAddress as ContractAddr; - const admin = instantiateInfo?.admin; - const displayName = contractLocalInfo?.name || publicInfo?.name || instantiateInfo?.label; @@ -162,59 +131,10 @@ export const ContractTop = ({ contractData }: ContractTopProps) => { )} - - - } - > - Admin - - - - } - onClick={() => { - navigate({ - pathname: "/migrate", - query: { contract: contractAddress }, - }); - }} - > - Migrate - - } - onClick={() => { - navigate({ - pathname: "/admin", - query: { contract: contractAddress }, - }); - }} - > - Update Admin - - } - > - Clear Admin - - } - /> - - + - {contracts.map((item) => ( - - navigate({ pathname: `/contract/${item.contractAddress}` }) - } - key={ - item.name + - item.contractAddress + - item.description + - item.tags + - item.lists - } - sx={{ - "& td:first-of-type": { pl: "48px" }, - "& td:last-of-type": { pr: "48px" }, - "> td": { borderColor: "divider.main" }, - }} - > - - - - {/* Instantiator */} - - + navigate({ pathname: `/contract/${item.contractAddress}` }) + } + key={ + item.name + + item.contractAddress + + item.description + + item.tags + + item.lists + } + sx={{ + "& td:first-of-type": { pl: "48px" }, + "& td:last-of-type": { pr: "48px" }, + "> td": { borderColor: "divider.main" }, + }} + > + + + + {/* Instantiator */} + + - - ))} + Migrate + + + + + + + + } + > + Edit details + + } + /> + + } + > + Add or remove from other lists + + } + /> + } + onClick={() => { + navigate({ + pathname: "/admin", + query: { contract: item.contractAddress }, + }); + }} + isDisabled={!isAdmin} + > + Update Admin + + + } + isDisabled={ + !address || + address !== admins[item.contractAddress] + } + > + Clear Admin + + } + /> + {!!contractRemovalInfo && ( + <> + + + ), + children: "Remove from this list", + }} + /> + + )} + + + + + + ); + })}
- - - - - - - - - e.stopPropagation()} - > - - - - - - - - - - - - - - - } - > - Edit details - - } - /> - - } - > - Add or remove from other lists - - } - /> - } - onClick={() => { - navigate({ - pathname: "/admin", - query: { contract: item.contractAddress }, - }); - }} - isDisabled={ - !address || address !== admins[item.contractAddress] - } + {contracts.map((item) => { + const isAdmin = address && address === admins[item.contractAddress]; + return ( +
+ + + + + + + + + e.stopPropagation()} + > + + + + + + + +
diff --git a/src/lib/types/tx/model.ts b/src/lib/types/tx/model.ts index 4ece9dabd..a2f3fbf2c 100644 --- a/src/lib/types/tx/model.ts +++ b/src/lib/types/tx/model.ts @@ -23,12 +23,7 @@ export interface ReceiptInfo { description?: ReactNode; } -export type ActionVariant = - | "sending" - | "upload" - | "rejected" - | "resend" - | "clear_admin"; +export type ActionVariant = "sending" | "upload" | "rejected" | "resend"; export interface TxResultRendering { /** From 885f3d45d599517a902493b90b5bdb6f14e8a666 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Wed, 25 Jan 2023 11:22:14 +0700 Subject: [PATCH 7/9] fix: comments --- src/lib/app-provider/tx/clearAdmin.ts | 1 - src/lib/components/button/index.ts | 1 + src/lib/pages/contract-details/components/ContractTop.tsx | 2 +- src/lib/pages/contract-list/components/ContractListTable.tsx | 5 +---- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/lib/app-provider/tx/clearAdmin.ts b/src/lib/app-provider/tx/clearAdmin.ts index 96ef01d8a..601538350 100644 --- a/src/lib/app-provider/tx/clearAdmin.ts +++ b/src/lib/app-provider/tx/clearAdmin.ts @@ -20,7 +20,6 @@ export const useClearAdminTx = (contractAddress: ContractAddr) => { const client = await getCosmWasmClient(); if (!address || !client) throw new Error("Please check your wallet connection."); - if (!contractAddress) return null; return clearAdminTx({ address, diff --git a/src/lib/components/button/index.ts b/src/lib/components/button/index.ts index 91be0edd1..2833e104d 100644 --- a/src/lib/components/button/index.ts +++ b/src/lib/components/button/index.ts @@ -2,3 +2,4 @@ export * from "./BackButton"; export * from "./ConnectWallet"; export * from "./InstantiateButton"; export * from "./ShowMoreButton"; +export * from "./AdminButton"; diff --git a/src/lib/pages/contract-details/components/ContractTop.tsx b/src/lib/pages/contract-details/components/ContractTop.tsx index ab504c810..dab7a4dc7 100644 --- a/src/lib/pages/contract-details/components/ContractTop.tsx +++ b/src/lib/pages/contract-details/components/ContractTop.tsx @@ -11,7 +11,7 @@ import { MdBookmark, MdBookmarkBorder, MdInput } from "react-icons/md"; import { RiPencilFill } from "react-icons/ri"; import { useInternalNavigate } from "lib/app-provider"; -import { AdminButton } from "lib/components/button/AdminButton"; +import { AdminButton } from "lib/components/button"; import { ExplorerLink } from "lib/components/ExplorerLink"; import { AddToOtherList, diff --git a/src/lib/pages/contract-list/components/ContractListTable.tsx b/src/lib/pages/contract-list/components/ContractListTable.tsx index a46029775..f2006a236 100644 --- a/src/lib/pages/contract-list/components/ContractListTable.tsx +++ b/src/lib/pages/contract-list/components/ContractListTable.tsx @@ -219,10 +219,7 @@ export const ContractListTable = ({ color="gray.600" /> } - isDisabled={ - !address || - address !== admins[item.contractAddress] - } + isDisabled={!isAdmin} > Clear Admin From 73b05687b601769a451cc7af10f10b9ec561cabc Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Wed, 25 Jan 2023 13:50:44 +0700 Subject: [PATCH 8/9] fix: as comments --- src/lib/app-fns/tx/clearAdmin.tsx | 2 +- src/lib/data/queries.ts | 2 +- src/lib/gql/gql.ts | 6 +++--- src/lib/gql/graphql.ts | 3 ++- src/lib/services/contractService.ts | 4 ++-- src/lib/types/contract.ts | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/lib/app-fns/tx/clearAdmin.tsx b/src/lib/app-fns/tx/clearAdmin.tsx index 06384006a..52e0a156a 100644 --- a/src/lib/app-fns/tx/clearAdmin.tsx +++ b/src/lib/app-fns/tx/clearAdmin.tsx @@ -11,7 +11,7 @@ import type { Observable } from "rxjs"; import { ExplorerLink } from "lib/components/ExplorerLink"; import { TxStreamPhase } from "lib/types"; import type { TxResultRendering, ContractAddr } from "lib/types"; -import { formatUFee } from "lib/utils/formatter/denom"; +import { formatUFee } from "lib/utils"; import { catchTxError } from "./common/catchTxError"; import { postTx } from "./common/post"; diff --git a/src/lib/data/queries.ts b/src/lib/data/queries.ts index 28eb48b66..0b69984a0 100644 --- a/src/lib/data/queries.ts +++ b/src/lib/data/queries.ts @@ -136,7 +136,7 @@ export const getAdminByContractAddressesQueryDocument = graphql(` ) { contracts(where: { address: { _in: $contractAddresses } }) { address - account { + admin: account { address } } diff --git a/src/lib/gql/gql.ts b/src/lib/gql/gql.ts index 1e462e98e..729039a7c 100644 --- a/src/lib/gql/gql.ts +++ b/src/lib/gql/gql.ts @@ -17,7 +17,7 @@ const documents = { types.GetInstantiatedListByUserQueryDocumentDocument, '\n query getInstantiateDetailByContractQueryDocument($contractAddress: String!) {\n contracts_by_pk(address: $contractAddress) {\n init_msg\n transaction {\n hash\n }\n contract_proposals(\n where: {\n proposal: {\n type: {\n _in: [\n "InstantiateContract"\n "InstantiateContract2"\n "SoftwareUpgrade"\n ]\n }\n }\n }\n order_by: { proposal: { id: asc } }\n limit: 1\n ) {\n proposal {\n id\n title\n }\n }\n }\n }\n': types.GetInstantiateDetailByContractQueryDocumentDocument, - "\n query getAdminByContractAddressesQueryDocument(\n $contractAddresses: [String!]\n ) {\n contracts(where: { address: { _in: $contractAddresses } }) {\n address\n account {\n address\n }\n }\n }\n": + "\n query getAdminByContractAddressesQueryDocument(\n $contractAddresses: [String!]\n ) {\n contracts(where: { address: { _in: $contractAddresses } }) {\n address\n admin: account {\n address\n }\n }\n }\n": types.GetAdminByContractAddressesQueryDocumentDocument, "\n query getExecuteTxsByContractAddress(\n $contractAddress: String!\n $offset: Int!\n $pageSize: Int!\n ) {\n contract_transactions(\n where: {\n contract: { address: { _eq: $contractAddress } }\n transaction: { is_execute: { _eq: true } }\n }\n order_by: { transaction: { block: { timestamp: desc } } }\n limit: $pageSize\n offset: $offset\n ) {\n transaction {\n hash\n messages\n success\n account {\n address\n }\n block {\n height\n timestamp\n }\n }\n }\n }\n": types.GetExecuteTxsByContractAddressDocument, @@ -67,8 +67,8 @@ export function graphql( source: '\n query getInstantiateDetailByContractQueryDocument($contractAddress: String!) {\n contracts_by_pk(address: $contractAddress) {\n init_msg\n transaction {\n hash\n }\n contract_proposals(\n where: {\n proposal: {\n type: {\n _in: [\n "InstantiateContract"\n "InstantiateContract2"\n "SoftwareUpgrade"\n ]\n }\n }\n }\n order_by: { proposal: { id: asc } }\n limit: 1\n ) {\n proposal {\n id\n title\n }\n }\n }\n }\n' ): typeof documents['\n query getInstantiateDetailByContractQueryDocument($contractAddress: String!) {\n contracts_by_pk(address: $contractAddress) {\n init_msg\n transaction {\n hash\n }\n contract_proposals(\n where: {\n proposal: {\n type: {\n _in: [\n "InstantiateContract"\n "InstantiateContract2"\n "SoftwareUpgrade"\n ]\n }\n }\n }\n order_by: { proposal: { id: asc } }\n limit: 1\n ) {\n proposal {\n id\n title\n }\n }\n }\n }\n']; export function graphql( - source: "\n query getAdminByContractAddressesQueryDocument(\n $contractAddresses: [String!]\n ) {\n contracts(where: { address: { _in: $contractAddresses } }) {\n address\n account {\n address\n }\n }\n }\n" -): typeof documents["\n query getAdminByContractAddressesQueryDocument(\n $contractAddresses: [String!]\n ) {\n contracts(where: { address: { _in: $contractAddresses } }) {\n address\n account {\n address\n }\n }\n }\n"]; + source: "\n query getAdminByContractAddressesQueryDocument(\n $contractAddresses: [String!]\n ) {\n contracts(where: { address: { _in: $contractAddresses } }) {\n address\n admin: account {\n address\n }\n }\n }\n" +): typeof documents["\n query getAdminByContractAddressesQueryDocument(\n $contractAddresses: [String!]\n ) {\n contracts(where: { address: { _in: $contractAddresses } }) {\n address\n admin: account {\n address\n }\n }\n }\n"]; export function graphql( source: "\n query getExecuteTxsByContractAddress(\n $contractAddress: String!\n $offset: Int!\n $pageSize: Int!\n ) {\n contract_transactions(\n where: {\n contract: { address: { _eq: $contractAddress } }\n transaction: { is_execute: { _eq: true } }\n }\n order_by: { transaction: { block: { timestamp: desc } } }\n limit: $pageSize\n offset: $offset\n ) {\n transaction {\n hash\n messages\n success\n account {\n address\n }\n block {\n height\n timestamp\n }\n }\n }\n }\n" ): typeof documents["\n query getExecuteTxsByContractAddress(\n $contractAddress: String!\n $offset: Int!\n $pageSize: Int!\n ) {\n contract_transactions(\n where: {\n contract: { address: { _eq: $contractAddress } }\n transaction: { is_execute: { _eq: true } }\n }\n order_by: { transaction: { block: { timestamp: desc } } }\n limit: $pageSize\n offset: $offset\n ) {\n transaction {\n hash\n messages\n success\n account {\n address\n }\n block {\n height\n timestamp\n }\n }\n }\n }\n"]; diff --git a/src/lib/gql/graphql.ts b/src/lib/gql/graphql.ts index 628bea459..87dc97aef 100644 --- a/src/lib/gql/graphql.ts +++ b/src/lib/gql/graphql.ts @@ -6375,7 +6375,7 @@ export type GetAdminByContractAddressesQueryDocumentQuery = { contracts: Array<{ __typename?: "contracts"; address: string; - account?: { __typename?: "accounts"; address: string } | null; + admin?: { __typename?: "accounts"; address: string } | null; }>; }; @@ -7562,6 +7562,7 @@ export const GetAdminByContractAddressesQueryDocumentDocument = { { kind: "Field", name: { kind: "Name", value: "address" } }, { kind: "Field", + alias: { kind: "Name", value: "admin" }, name: { kind: "Name", value: "account" }, selectionSet: { kind: "SelectionSet", diff --git a/src/lib/services/contractService.ts b/src/lib/services/contractService.ts index 39de77376..983c901e3 100644 --- a/src/lib/services/contractService.ts +++ b/src/lib/services/contractService.ts @@ -152,7 +152,7 @@ export const useAdminByContractAddresses = ( ): UseQueryResult>> => { const { indexerGraphClient } = useCelatoneApp(); const queryFn = useCallback(async () => { - if (!contractAddresses) return undefined; + if (!contractAddresses) throw new Error("No contract selected"); return indexerGraphClient .request(getAdminByContractAddressesQueryDocument, { @@ -162,7 +162,7 @@ export const useAdminByContractAddresses = ( contracts.reduce( (prev, contract) => ({ ...prev, - [contract.address as ContractAddr]: contract.account?.address, + [contract.address as ContractAddr]: contract.admin?.address, }), {} ) diff --git a/src/lib/types/contract.ts b/src/lib/types/contract.ts index 2027a23ef..ed13500ca 100644 --- a/src/lib/types/contract.ts +++ b/src/lib/types/contract.ts @@ -4,7 +4,7 @@ import type { ContractAddr, HumanAddr, Option } from "lib/types"; export interface ContractInfo extends ContractLocalInfo { admin: Option; instantiated: Date; - latestUpdator?: string; + latestUpdator: Option; latestUpdated: Date; } From a6ca739cced58145bcf90c304894b89c0dd9f220 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Thu, 26 Jan 2023 10:57:37 +0700 Subject: [PATCH 9/9] fix: comments --- src/lib/app-provider/tx/index.ts | 3 +++ src/lib/components/button/AdminButton.tsx | 5 +++-- .../modal/contract/ClearAdminContract.tsx | 2 +- src/lib/data/queries.ts | 4 ++-- src/lib/gql/gql.ts | 12 ++++++------ src/lib/gql/graphql.ts | 16 ++++++++++------ src/lib/pages/execute/components/ExecuteArea.tsx | 7 +++++-- src/lib/pages/instantiate/instantiate.tsx | 2 +- src/lib/services/codeService.ts | 2 +- src/lib/services/contractService.ts | 3 ++- 10 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/lib/app-provider/tx/index.ts b/src/lib/app-provider/tx/index.ts index 8f7fec410..de35b0c2e 100644 --- a/src/lib/app-provider/tx/index.ts +++ b/src/lib/app-provider/tx/index.ts @@ -1,2 +1,5 @@ export * from "./upload"; export * from "./resend"; +export * from "./clearAdmin"; +export * from "./execute"; +export * from "./instantiate"; diff --git a/src/lib/components/button/AdminButton.tsx b/src/lib/components/button/AdminButton.tsx index 2732ab8aa..22883b6bc 100644 --- a/src/lib/components/button/AdminButton.tsx +++ b/src/lib/components/button/AdminButton.tsx @@ -43,6 +43,7 @@ export const AdminButton = ({ contractAddress, admin }: AdminButtonProps) => { const { address } = useWallet(); const navigate = useInternalNavigate(); + const isAdmin = !!address && address === admin; return ( { placement="top" bg="primary.dark" arrowSize={8} - isDisabled={!!address && address === admin} + isDisabled={isAdmin} > } > Admin diff --git a/src/lib/components/modal/contract/ClearAdminContract.tsx b/src/lib/components/modal/contract/ClearAdminContract.tsx index 3d6d71f9d..1644d903d 100644 --- a/src/lib/components/modal/contract/ClearAdminContract.tsx +++ b/src/lib/components/modal/contract/ClearAdminContract.tsx @@ -3,7 +3,7 @@ import { useCallback } from "react"; import { MdDeleteForever } from "react-icons/md"; import { ActionModal } from "../ActionModal"; -import { useClearAdminTx } from "lib/app-provider/tx/clearAdmin"; +import { useClearAdminTx } from "lib/app-provider"; import { useTxBroadcast } from "lib/providers/tx-broadcast"; import type { ContractAddr } from "lib/types"; diff --git a/src/lib/data/queries.ts b/src/lib/data/queries.ts index 0b69984a0..5a15c6fa0 100644 --- a/src/lib/data/queries.ts +++ b/src/lib/data/queries.ts @@ -132,7 +132,7 @@ export const getInstantiateDetailByContractQueryDocument = graphql(` export const getAdminByContractAddressesQueryDocument = graphql(` query getAdminByContractAddressesQueryDocument( - $contractAddresses: [String!] + $contractAddresses: [String!]! ) { contracts(where: { address: { _in: $contractAddresses } }) { address @@ -291,7 +291,7 @@ export const getContractListByCodeId = graphql(` ) { address label - account { + admin: account { address } init_by: contract_histories( diff --git a/src/lib/gql/gql.ts b/src/lib/gql/gql.ts index 729039a7c..db3703f43 100644 --- a/src/lib/gql/gql.ts +++ b/src/lib/gql/gql.ts @@ -17,7 +17,7 @@ const documents = { types.GetInstantiatedListByUserQueryDocumentDocument, '\n query getInstantiateDetailByContractQueryDocument($contractAddress: String!) {\n contracts_by_pk(address: $contractAddress) {\n init_msg\n transaction {\n hash\n }\n contract_proposals(\n where: {\n proposal: {\n type: {\n _in: [\n "InstantiateContract"\n "InstantiateContract2"\n "SoftwareUpgrade"\n ]\n }\n }\n }\n order_by: { proposal: { id: asc } }\n limit: 1\n ) {\n proposal {\n id\n title\n }\n }\n }\n }\n': types.GetInstantiateDetailByContractQueryDocumentDocument, - "\n query getAdminByContractAddressesQueryDocument(\n $contractAddresses: [String!]\n ) {\n contracts(where: { address: { _in: $contractAddresses } }) {\n address\n admin: account {\n address\n }\n }\n }\n": + "\n query getAdminByContractAddressesQueryDocument(\n $contractAddresses: [String!]!\n ) {\n contracts(where: { address: { _in: $contractAddresses } }) {\n address\n admin: account {\n address\n }\n }\n }\n": types.GetAdminByContractAddressesQueryDocumentDocument, "\n query getExecuteTxsByContractAddress(\n $contractAddress: String!\n $offset: Int!\n $pageSize: Int!\n ) {\n contract_transactions(\n where: {\n contract: { address: { _eq: $contractAddress } }\n transaction: { is_execute: { _eq: true } }\n }\n order_by: { transaction: { block: { timestamp: desc } } }\n limit: $pageSize\n offset: $offset\n ) {\n transaction {\n hash\n messages\n success\n account {\n address\n }\n block {\n height\n timestamp\n }\n }\n }\n }\n": types.GetExecuteTxsByContractAddressDocument, @@ -33,7 +33,7 @@ const documents = { types.GetRelatedProposalsCountByContractAddressDocument, "\n query getContractListByAdmin($address: String!) {\n contracts(\n where: { account: { address: { _eq: $address } } }\n order_by: { id: desc }\n ) {\n address\n label\n accountByInitBy {\n address\n }\n }\n }\n": types.GetContractListByAdminDocument, - "\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { id: desc }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n account {\n address\n }\n init_by: contract_histories(\n order_by: { block: { timestamp: asc } }\n limit: 1\n ) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n": + "\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { id: desc }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n admin: account {\n address\n }\n init_by: contract_histories(\n order_by: { block: { timestamp: asc } }\n limit: 1\n ) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n": types.GetContractListByCodeIdDocument, "\n query getContractListCountByCodeId($codeId: Int!) {\n contracts_aggregate(where: { code_id: { _eq: $codeId } }) {\n aggregate {\n count\n }\n }\n }\n": types.GetContractListCountByCodeIdDocument, @@ -67,8 +67,8 @@ export function graphql( source: '\n query getInstantiateDetailByContractQueryDocument($contractAddress: String!) {\n contracts_by_pk(address: $contractAddress) {\n init_msg\n transaction {\n hash\n }\n contract_proposals(\n where: {\n proposal: {\n type: {\n _in: [\n "InstantiateContract"\n "InstantiateContract2"\n "SoftwareUpgrade"\n ]\n }\n }\n }\n order_by: { proposal: { id: asc } }\n limit: 1\n ) {\n proposal {\n id\n title\n }\n }\n }\n }\n' ): typeof documents['\n query getInstantiateDetailByContractQueryDocument($contractAddress: String!) {\n contracts_by_pk(address: $contractAddress) {\n init_msg\n transaction {\n hash\n }\n contract_proposals(\n where: {\n proposal: {\n type: {\n _in: [\n "InstantiateContract"\n "InstantiateContract2"\n "SoftwareUpgrade"\n ]\n }\n }\n }\n order_by: { proposal: { id: asc } }\n limit: 1\n ) {\n proposal {\n id\n title\n }\n }\n }\n }\n']; export function graphql( - source: "\n query getAdminByContractAddressesQueryDocument(\n $contractAddresses: [String!]\n ) {\n contracts(where: { address: { _in: $contractAddresses } }) {\n address\n admin: account {\n address\n }\n }\n }\n" -): typeof documents["\n query getAdminByContractAddressesQueryDocument(\n $contractAddresses: [String!]\n ) {\n contracts(where: { address: { _in: $contractAddresses } }) {\n address\n admin: account {\n address\n }\n }\n }\n"]; + source: "\n query getAdminByContractAddressesQueryDocument(\n $contractAddresses: [String!]!\n ) {\n contracts(where: { address: { _in: $contractAddresses } }) {\n address\n admin: account {\n address\n }\n }\n }\n" +): typeof documents["\n query getAdminByContractAddressesQueryDocument(\n $contractAddresses: [String!]!\n ) {\n contracts(where: { address: { _in: $contractAddresses } }) {\n address\n admin: account {\n address\n }\n }\n }\n"]; export function graphql( source: "\n query getExecuteTxsByContractAddress(\n $contractAddress: String!\n $offset: Int!\n $pageSize: Int!\n ) {\n contract_transactions(\n where: {\n contract: { address: { _eq: $contractAddress } }\n transaction: { is_execute: { _eq: true } }\n }\n order_by: { transaction: { block: { timestamp: desc } } }\n limit: $pageSize\n offset: $offset\n ) {\n transaction {\n hash\n messages\n success\n account {\n address\n }\n block {\n height\n timestamp\n }\n }\n }\n }\n" ): typeof documents["\n query getExecuteTxsByContractAddress(\n $contractAddress: String!\n $offset: Int!\n $pageSize: Int!\n ) {\n contract_transactions(\n where: {\n contract: { address: { _eq: $contractAddress } }\n transaction: { is_execute: { _eq: true } }\n }\n order_by: { transaction: { block: { timestamp: desc } } }\n limit: $pageSize\n offset: $offset\n ) {\n transaction {\n hash\n messages\n success\n account {\n address\n }\n block {\n height\n timestamp\n }\n }\n }\n }\n"]; @@ -91,8 +91,8 @@ export function graphql( source: "\n query getContractListByAdmin($address: String!) {\n contracts(\n where: { account: { address: { _eq: $address } } }\n order_by: { id: desc }\n ) {\n address\n label\n accountByInitBy {\n address\n }\n }\n }\n" ): typeof documents["\n query getContractListByAdmin($address: String!) {\n contracts(\n where: { account: { address: { _eq: $address } } }\n order_by: { id: desc }\n ) {\n address\n label\n accountByInitBy {\n address\n }\n }\n }\n"]; export function graphql( - source: "\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { id: desc }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n account {\n address\n }\n init_by: contract_histories(\n order_by: { block: { timestamp: asc } }\n limit: 1\n ) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n" -): typeof documents["\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { id: desc }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n account {\n address\n }\n init_by: contract_histories(\n order_by: { block: { timestamp: asc } }\n limit: 1\n ) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n"]; + source: "\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { id: desc }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n admin: account {\n address\n }\n init_by: contract_histories(\n order_by: { block: { timestamp: asc } }\n limit: 1\n ) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n" +): typeof documents["\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { id: desc }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n admin: account {\n address\n }\n init_by: contract_histories(\n order_by: { block: { timestamp: asc } }\n limit: 1\n ) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n"]; export function graphql( source: "\n query getContractListCountByCodeId($codeId: Int!) {\n contracts_aggregate(where: { code_id: { _eq: $codeId } }) {\n aggregate {\n count\n }\n }\n }\n" ): typeof documents["\n query getContractListCountByCodeId($codeId: Int!) {\n contracts_aggregate(where: { code_id: { _eq: $codeId } }) {\n aggregate {\n count\n }\n }\n }\n"]; diff --git a/src/lib/gql/graphql.ts b/src/lib/gql/graphql.ts index 87dc97aef..3a76e2b74 100644 --- a/src/lib/gql/graphql.ts +++ b/src/lib/gql/graphql.ts @@ -6367,7 +6367,7 @@ export type GetInstantiateDetailByContractQueryDocumentQuery = { }; export type GetAdminByContractAddressesQueryDocumentQueryVariables = Exact<{ - contractAddresses?: InputMaybe | Scalars["String"]>; + contractAddresses: Array | Scalars["String"]; }>; export type GetAdminByContractAddressesQueryDocumentQuery = { @@ -6512,7 +6512,7 @@ export type GetContractListByCodeIdQuery = { __typename?: "contracts"; address: string; label: string; - account?: { __typename?: "accounts"; address: string } | null; + admin?: { __typename?: "accounts"; address: string } | null; init_by: Array<{ __typename?: "contract_histories"; block: { __typename?: "blocks"; timestamp: any }; @@ -7508,12 +7508,15 @@ export const GetAdminByContractAddressesQueryDocumentDocument = { name: { kind: "Name", value: "contractAddresses" }, }, type: { - kind: "ListType", + kind: "NonNullType", type: { - kind: "NonNullType", + kind: "ListType", type: { - kind: "NamedType", - name: { kind: "Name", value: "String" }, + kind: "NonNullType", + type: { + kind: "NamedType", + name: { kind: "Name", value: "String" }, + }, }, }, }, @@ -8691,6 +8694,7 @@ export const GetContractListByCodeIdDocument = { { kind: "Field", name: { kind: "Name", value: "label" } }, { kind: "Field", + alias: { kind: "Name", value: "admin" }, name: { kind: "Name", value: "account" }, selectionSet: { kind: "SelectionSet", diff --git a/src/lib/pages/execute/components/ExecuteArea.tsx b/src/lib/pages/execute/components/ExecuteArea.tsx index 53b2e6fed..810bff6f0 100644 --- a/src/lib/pages/execute/components/ExecuteArea.tsx +++ b/src/lib/pages/execute/components/ExecuteArea.tsx @@ -9,9 +9,12 @@ import { IoIosWarning } from "react-icons/io"; import { MdInput } from "react-icons/md"; import type { ExecutePageState } from "../types"; -import { useFabricateFee, useNativeTokensInfo } from "lib/app-provider"; +import { + useFabricateFee, + useNativeTokensInfo, + useExecuteContractTx, +} from "lib/app-provider"; import { useSimulateFeeQuery } from "lib/app-provider/queries"; -import { useExecuteContractTx } from "lib/app-provider/tx/execute"; import { ContractCmdButton } from "lib/components/ContractCmdButton"; import { CopyButton } from "lib/components/CopyButton"; import { EstimatedFeeRender } from "lib/components/EstimatedFeeRender"; diff --git a/src/lib/pages/instantiate/instantiate.tsx b/src/lib/pages/instantiate/instantiate.tsx index 466e9a4ea..e0d5a8d63 100644 --- a/src/lib/pages/instantiate/instantiate.tsx +++ b/src/lib/pages/instantiate/instantiate.tsx @@ -17,8 +17,8 @@ import { useFabricateFee, useNativeTokensInfo, useSimulateFee, + useInstantiateTx, } from "lib/app-provider"; -import { useInstantiateTx } from "lib/app-provider/tx/instantiate"; import { ControllerInput } from "lib/components/forms"; import { AssetInput } from "lib/components/forms/AssetInput"; import JsonInput from "lib/components/json/JsonInput"; diff --git a/src/lib/services/codeService.ts b/src/lib/services/codeService.ts index 7db26f15d..f58f4ae68 100644 --- a/src/lib/services/codeService.ts +++ b/src/lib/services/codeService.ts @@ -167,7 +167,7 @@ export const useContractListByCodeId = ( contractAddress: contract.address as ContractAddr, instantiator: unwrap(contract.init_by.at(0)?.account.address), label: contract.label, - admin: contract.account?.address, + admin: contract.admin?.address, instantiated: parseDateDefault( contract.init_by.at(0)?.block.timestamp ), diff --git a/src/lib/services/contractService.ts b/src/lib/services/contractService.ts index 983c901e3..ac8703e04 100644 --- a/src/lib/services/contractService.ts +++ b/src/lib/services/contractService.ts @@ -30,6 +30,7 @@ import type { Option, ProposalStatus, ProposalType, + Dict, } from "lib/types"; import { parseDate, @@ -149,7 +150,7 @@ export const useInstantiateDetailByContractQuery = ( export const useAdminByContractAddresses = ( contractAddresses: Option -): UseQueryResult>> => { +): UseQueryResult>> => { const { indexerGraphClient } = useCelatoneApp(); const queryFn = useCallback(async () => { if (!contractAddresses) throw new Error("No contract selected");