Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[after #696] feat: api v1 - contract migration table #697

Merged
merged 8 commits into from
Dec 27, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Improvements

- [#697](https://github.com/alleslabs/celatone-frontend/pull/697) api v1 - contract tables (migrations and related proposals)
- [#696](https://github.com/alleslabs/celatone-frontend/pull/696) api v1 - block details
- [#695](https://github.com/alleslabs/celatone-frontend/pull/695) api v1 - contract states
- [#678](https://github.com/alleslabs/celatone-frontend/pull/678) api v1 - contract table counts
Expand Down
4 changes: 2 additions & 2 deletions src/lib/app-provider/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export enum CELATONE_QUERY_KEYS {
INSTANTIATED_COUNT_BY_WALLET_ADDRESS = "CELATONE_QUERY_INSTANTIATED_COUNT_BY_WALLET_ADDRESS",
INSTANTIATED_LIST_BY_WALLET_ADDRESS = "CELATONE_QUERY_INSTANTIATED_LIST_BY_WALLET_ADDRESS",
ADMINS_BY_CONTRACTS = "CELATONE_QUERY_ADMINS_BY_CONTRACTS",
CONTRACT_MIGRATION_HISTORIES_PAGINATION = "CELATONE_QUERY_CONTRACT_MIGRATION_HISTORIES_PAGINATION",
CONTRACT_MIGRATION_HISTORIES_BY_CONTRACT_ADDRESS = "CELATONE_QUERY_CONTRACT_MIGRATION_HISTORIES_BY_CONTRACT_ADDRESS",
CONTRACTS_BY_CODE_ID_PAGINATION = "CELATONE_QUERY_CONTRACTS_BY_CODE_ID_PAGINATION",
CONTRACTS_BY_CODE_ID_COUNT = "CELATONE_QUERY_CONTRACTS_BY_CODE_ID_COUNT",
// X/STAKING
Expand All @@ -52,7 +52,7 @@ export enum CELATONE_QUERY_KEYS {
// FAUCET
FAUCET_INFO = "CELATONE_QUERY_FAUCET_INFO",
// X/GOV
RELATED_PROPOSALS_BY_CONTRACT_ADDRESS_PAGINATION = "CELATONE_QUERY_RELATED_PROPOSALS_BY_CONTRACT_ADDRESS_PAGINATION",
RELATED_PROPOSALS_BY_CONTRACT_ADDRESS = "CELATONE_QUERY_RELATED_PROPOSALS_BY_CONTRACT_ADDRESS",
PROPOSALS_BY_MODULE_ID = "CELATONE_QUERY_PROPOSALS_BY_MODULE_ID",
PROPOSALS_COUNT_BY_MODULE_ID = "CELATONE_QUERY_PROPOSALS_COUNT_BY_MODULE_ID",
PROPOSALS_BY_ADDRESS = "CELATONE_QUERY_PROPOSALS_BY_ADDRESS",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Pagination } from "lib/components/pagination";
import { usePaginator } from "lib/components/pagination/usePaginator";
import { EmptyState, ErrorFetching } from "lib/components/state";
import { ProposalsTable } from "lib/components/table";
import { useRelatedProposalsByContractAddressPagination } from "lib/services/proposalService";
import { useRelatedProposalsByContractAddress } from "lib/services/proposalService";
import type { ContractAddr, Option } from "lib/types";

interface RelatedProposalsTableProps {
Expand Down Expand Up @@ -40,11 +40,7 @@ export const RelatedProposalsTable = ({
data: relatedProposals,
isLoading,
error,
} = useRelatedProposalsByContractAddressPagination(
contractAddress,
offset,
pageSize
);
} = useRelatedProposalsByContractAddress(contractAddress, offset, pageSize);

const onPageChange = (nextPage: number) => {
refetchCount();
Expand All @@ -61,7 +57,7 @@ export const RelatedProposalsTable = ({
return (
<>
<ProposalsTable
proposals={relatedProposals}
proposals={relatedProposals?.items}
isLoading={isLoading}
emptyState={
error ? (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import type { ChangeEvent } from "react";

import { useMobile } from "lib/app-provider";
import { Loading } from "lib/components/Loading";
import { Pagination } from "lib/components/pagination";
import { usePaginator } from "lib/components/pagination/usePaginator";
import { EmptyState } from "lib/components/state";
import { EmptyState, ErrorFetching } from "lib/components/state";
import { MobileTableContainer, TableContainer } from "lib/components/table";
import { useMigrationHistories } from "lib/pages/contract-details/data";
import type { ContractAddr, Option } from "lib/types";
Expand Down Expand Up @@ -42,26 +41,15 @@ export const MigrationTable = ({
},
});

// TODO: loading state
const migrationHistories = useMigrationHistories(
const { data, isLoading, error } = useMigrationHistories(
contractAddress,
offset,
pageSize
);

const onPageChange = (nextPage: number) => {
refetchCount();
setCurrentPage(nextPage);
};

const onPageSizeChange = (e: ChangeEvent<HTMLSelectElement>) => {
const size = Number(e.target.value);
refetchCount();
setPageSize(size);
setCurrentPage(1);
};

if (!migrationHistories?.length)
if (isLoading) return <Loading />;
if (error) return <ErrorFetching dataName="related proposals" />;
if (!data?.items.length)
return (
<EmptyState
imageVariant="empty"
Expand All @@ -77,7 +65,7 @@ export const MigrationTable = ({
<>
{isMobile ? (
<MobileTableContainer>
{migrationHistories.map((history, idx) => (
{data.items.map((history, idx) => (
<MigrationMobileCard
key={
history.codeId +
Expand All @@ -93,7 +81,7 @@ export const MigrationTable = ({
) : (
<TableContainer>
<MigrationHeader templateColumns={templateColumns} />
{migrationHistories.map((history, idx) => (
{data.items.map((history, idx) => (
<MigrationRow
key={
history.codeId +
Expand All @@ -117,8 +105,16 @@ export const MigrationTable = ({
totalData={totalData}
scrollComponentId={scrollComponentId}
pageSize={pageSize}
onPageChange={onPageChange}
onPageSizeChange={onPageSizeChange}
onPageChange={(nextPage) => {
refetchCount();
setCurrentPage(nextPage);
}}
onPageSizeChange={(e) => {
const size = Number(e.target.value);
refetchCount();
setPageSize(size);
setCurrentPage(1);
}}
/>
)}
</>
Expand Down
37 changes: 19 additions & 18 deletions src/lib/pages/contract-details/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import { queryContract, queryContractCw2Info } from "lib/services/contract";
import {
useContractDetailByContractAddress,
useInstantiateDetailByContractQuery,
useMigrationHistoriesByContractAddressPagination,
useMigrationHistoriesByContractAddress,
} from "lib/services/contractService";
import {
usePublicProjectByContractAddress,
usePublicProjectBySlug,
} from "lib/services/publicProjectService";
import type { ContractAddr, ContractMigrationHistory, Option } from "lib/types";
import type { ContractAddr, ContractMigrationHistory } from "lib/types";
import { coinToTokenWithValue, compareTokenWithValues } from "lib/utils";

import type { ContractData } from "./types";
Expand Down Expand Up @@ -101,22 +101,23 @@ export const useMigrationHistories = (
contractAddress: ContractAddr,
offset: number,
pageSize: number
): Option<ContractMigrationHistory[]> => {
const { data: migrationData } =
useMigrationHistoriesByContractAddressPagination(
contractAddress,
offset,
pageSize
);
) => {
const { data, ...res } = useMigrationHistoriesByContractAddress(
contractAddress,
offset,
pageSize
);
const { getCodeLocalInfo } = useCodeStore();

if (!migrationData) return undefined;

return migrationData.map<ContractMigrationHistory>((data) => {
const localInfo = getCodeLocalInfo(data.codeId);
return {
...data,
codeName: localInfo?.name,
};
});
return {
data: data
? {
items: data.items.map<ContractMigrationHistory>((migration) => ({
...migration,
codeName: getCodeLocalInfo(migration.codeId)?.name,
})),
}
: undefined,
...res,
};
};
32 changes: 0 additions & 32 deletions src/lib/query/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,35 +183,3 @@ export const getContractListCountByCodeId = graphql(`
}
}
`);

export const getMigrationHistoriesByContractAddressPagination = graphql(`
query getMigrationHistoriesByContractAddress(
$contractAddress: String!
$offset: Int!
$pageSize: Int!
) {
contract_histories(
where: { contract: { address: { _eq: $contractAddress } } }
order_by: { block: { timestamp: desc } }
limit: $pageSize
offset: $offset
) {
code_id
account {
address
}
block {
height
timestamp
}
remark
code {
account {
address
}
cw2_contract
cw2_version
}
}
}
`);
29 changes: 0 additions & 29 deletions src/lib/query/proposal.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,5 @@
import { graphql } from "lib/gql";

export const getRelatedProposalsByContractAddressPagination = graphql(`
query getRelatedProposalsByContractAddressPagination(
$contractAddress: String!
$offset: Int!
$pageSize: Int!
) {
contract_proposals(
where: { contract: { address: { _eq: $contractAddress } } }
order_by: { proposal_id: desc }
offset: $offset
limit: $pageSize
) {
proposal {
title
status
voting_end_time
deposit_end_time
type
account {
address
}
is_expedited
}
proposal_id
resolved_height
}
}
`);

export const getRelatedProposalsByModuleIdPagination = graphql(`
query getRelatedProposalsByModuleIdPagination(
$moduleId: Int!
Expand Down
4 changes: 2 additions & 2 deletions src/lib/services/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const getAccountInfo = async (
): Promise<AccountInfo> =>
axios
.get(`${endpoint}/${encodeURIComponent(address)}/info`)
.then((res) => zAccountInfo.parse(res.data));
.then(({ data }) => zAccountInfo.parse(data));

const zAccountTableCounts = z
.object({
Expand All @@ -56,4 +56,4 @@ export const getAccountTableCounts = async (
is_wasm: isWasm,
},
})
.then((res) => zAccountTableCounts.parse(res.data));
.then(({ data }) => zAccountTableCounts.parse(data));
2 changes: 1 addition & 1 deletion src/lib/services/asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ export const getAssetInfos = async (
with_prices: withPrices,
},
})
.then((res) => z.array(zAssetInfo).parse(res.data));
.then(({ data }) => z.array(zAssetInfo).parse(data));
2 changes: 1 addition & 1 deletion src/lib/services/balance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ export const getBalances = async (
): Promise<Coin[]> =>
axios
.get(`${endpoint}/${encodeURIComponent(address)}/balances`)
.then((res) => zBalancesResponse.parse(res.data));
.then(({ data }) => zBalancesResponse.parse(data));
2 changes: 1 addition & 1 deletion src/lib/services/code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,4 @@ export const getCodesByAddress = async (
offset,
},
})
.then((res) => zCodesResponse.parse(res.data));
.then(({ data }) => zCodesResponse.parse(data));
67 changes: 53 additions & 14 deletions src/lib/services/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ import type {
Addr,
ContractAddr,
ContractInfo,
ContractHistoryRemark,
RemarkType,
ContractMigrationHistory,
} from "lib/types";
import {
zAddr,
zContractAddr,
zContractHistoryRemark,
zUtcDate,
} from "lib/types";
import { RemarkOperation, zAddr, zContractAddr, zUtcDate } from "lib/types";
import { encode, libDecode, snakeToCamel } from "lib/utils";

interface ContractCw2InfoRaw {
Expand Down Expand Up @@ -76,17 +80,7 @@ const zContractsResponseItem = z
instantiator: zAddr,
latest_updated: zUtcDate,
latest_updater: zAddr,
remark: z
.object({
operation: z.nativeEnum(RemarkOperation),
type: z.string(),
value: z.string(),
})
.transform<ContractHistoryRemark>((val) => ({
operation: val.operation,
type: val.type as RemarkType, // TODO: remove type assertion,
value: val.value,
})),
remark: zContractHistoryRemark,
})
.transform<ContractInfo>((val) => ({
contractAddress: val.contract_address,
Expand Down Expand Up @@ -138,6 +132,51 @@ export const getAdminContractsByAddress = async (
})
.then(({ data }) => zContractsResponse.parse(data));

const zMigrationHistoriesResponseItem = z
.object({
code_id: z.number(),
songwongtp marked this conversation as resolved.
Show resolved Hide resolved
cw2_contract: z.string().nullable(),
cw2_version: z.string().nullable(),
height: z.number(),
remark: zContractHistoryRemark,
sender: zAddr,
timestamp: zUtcDate,
uploader: zAddr,
})
.transform<ContractMigrationHistory>((val) => ({
codeId: val.code_id,
cw2Contract: val.cw2_contract,
cw2Version: val.cw2_version,
height: val.height,
remark: val.remark,
sender: val.sender,
timestamp: val.timestamp,
uploader: val.uploader,
}));

const zMigrationHistoriesResponse = z.object({
items: z.array(zMigrationHistoriesResponseItem),
});

export type MigrationHistoriesResponse = z.infer<
typeof zMigrationHistoriesResponse
>;

export const getMigrationHistoriesByContractAddress = async (
endpoint: string,
contractAddress: ContractAddr,
limit: number,
offset: number
) =>
axios
.get(`${endpoint}/${encodeURIComponent(contractAddress)}/migrations`, {
params: {
limit,
offset,
},
})
.then(({ data }) => zMigrationHistoriesResponse.parse(data));

const zContractTableCounts = z
.object({
tx: z.number().nullish(),
Expand Down
Loading