diff --git a/CHANGELOG.md b/CHANGELOG.md index c2cb95945..832a73544 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Improvements +- [#421](https://github.com/alleslabs/celatone-frontend/pull/421) Generate example addresses from a fixed-bytes array - [#431](https://github.com/alleslabs/celatone-frontend/pull/431) Add new Osmosis v16 tx messages - [#414](https://github.com/alleslabs/celatone-frontend/pull/414) Add jest test cases for funds and assetValue in utils, and remove isDecimalNumber in utils - [#435](https://github.com/alleslabs/celatone-frontend/pull/435) Refactor chain's config, add new chain configs diff --git a/src/config/chain/default.ts b/src/config/chain/default.ts index 70e3100cf..50b437393 100644 --- a/src/config/chain/default.ts +++ b/src/config/chain/default.ts @@ -1,5 +1,3 @@ -import type { ContractAddr, HumanAddr, ValidatorAddr } from "lib/types"; - import type { ChainConfig } from "./types"; export const DEFAULT_CHAIN_CONFIG: ChainConfig = { @@ -32,11 +30,6 @@ export const DEFAULT_CHAIN_CONFIG: ChainConfig = { gasAdjustment: 1.0, maxGasLimit: 0, }, - exampleAddresses: { - user: "" as HumanAddr, - contract: "" as ContractAddr, - validator: "" as ValidatorAddr, - }, explorerLink: { validator: "", proposal: "", diff --git a/src/config/chain/neutron.ts b/src/config/chain/neutron.ts index b2e4ea601..b8545e19e 100644 --- a/src/config/chain/neutron.ts +++ b/src/config/chain/neutron.ts @@ -1,5 +1,3 @@ -import type { ContractAddr, HumanAddr, ValidatorAddr } from "lib/types"; - import type { ChainConfigs } from "./types"; export const NEUTRON_CHAIN_CONFIGS: ChainConfigs = { @@ -35,13 +33,6 @@ export const NEUTRON_CHAIN_CONFIGS: ChainConfigs = { gasAdjustment: 1.5, maxGasLimit: 25_000_000, }, - exampleAddresses: { - user: "neutron19glux3jzdfyyz6ylmuksgxfj5phdaxfr2uhy86" as HumanAddr, - contract: - "neutron1suhgf5svhu4usrurvxzlgn54ksxmn8gljarjtxqnapv8kjnp4nrstdxvff" as ContractAddr, - validator: - "neutronvaloper1c4k24jzduc365kywrsvf5ujz4ya6mwym69umfr" as ValidatorAddr, - }, explorerLink: { validator: "https://www.mintscan.io/neutron/validators", proposal: "", @@ -80,13 +71,6 @@ export const NEUTRON_CHAIN_CONFIGS: ChainConfigs = { gasAdjustment: 1.5, maxGasLimit: 25_000_000, }, - exampleAddresses: { - user: "neutron19glux3jzdfyyz6ylmuksgxfj5phdaxfr2uhy86" as HumanAddr, - contract: - "neutron1suhgf5svhu4usrurvxzlgn54ksxmn8gljarjtxqnapv8kjnp4nrstdxvff" as ContractAddr, - validator: - "neutronvaloper1c4k24jzduc365kywrsvf5ujz4ya6mwym69umfr" as ValidatorAddr, - }, explorerLink: { validator: "https://www.mintscan.io/neutron/validators", proposal: "", diff --git a/src/config/chain/osmosis.ts b/src/config/chain/osmosis.ts index 5ac9b0e1e..4ad4317df 100644 --- a/src/config/chain/osmosis.ts +++ b/src/config/chain/osmosis.ts @@ -1,5 +1,3 @@ -import type { ContractAddr, HumanAddr, ValidatorAddr } from "lib/types"; - import type { ChainConfigs } from "./types"; export const OSMOSIS_CHAIN_CONFIGS: ChainConfigs = { @@ -36,13 +34,6 @@ export const OSMOSIS_CHAIN_CONFIGS: ChainConfigs = { gasAdjustment: 1.5, maxGasLimit: 25_000_000, }, - exampleAddresses: { - user: "osmo14wk9zecqam9jsac7xwtf8e349ckquzzlx9k8c3" as HumanAddr, - contract: - "osmo1p0pxllmqjgl2tefy7grypt34jdpdltg3ka98n8unnl322wqps7lqtu576h" as ContractAddr, - validator: - "osmovaloper1hh0g5xf23e5zekg45cmerc97hs4n2004dy2t26" as ValidatorAddr, - }, explorerLink: { validator: "https://www.mintscan.io/osmosis/validators", proposal: "https://www.mintscan.io/osmosis/proposals", @@ -83,13 +74,6 @@ export const OSMOSIS_CHAIN_CONFIGS: ChainConfigs = { gasAdjustment: 1.5, maxGasLimit: 25_000_000, }, - exampleAddresses: { - user: "osmo14wk9zecqam9jsac7xwtf8e349ckquzzlx9k8c3" as HumanAddr, - contract: - "osmo1p0pxllmqjgl2tefy7grypt34jdpdltg3ka98n8unnl322wqps7lqtu576h" as ContractAddr, - validator: - "osmovaloper1hh0g5xf23e5zekg45cmerc97hs4n2004dy2t26" as ValidatorAddr, - }, explorerLink: { validator: "https://testnet.mintscan.io/osmosis-testnet/validators", proposal: "https://testnet.mintscan.io/osmosis-testnet/proposals", @@ -129,13 +113,6 @@ export const OSMOSIS_CHAIN_CONFIGS: ChainConfigs = { gasAdjustment: 1.5, maxGasLimit: 25_000_000, }, - exampleAddresses: { - user: "osmo14wk9zecqam9jsac7xwtf8e349ckquzzlx9k8c3" as HumanAddr, - contract: - "osmo1p0pxllmqjgl2tefy7grypt34jdpdltg3ka98n8unnl322wqps7lqtu576h" as ContractAddr, - validator: - "osmovaloper1hh0g5xf23e5zekg45cmerc97hs4n2004dy2t26" as ValidatorAddr, - }, explorerLink: { validator: "", proposal: "", diff --git a/src/config/chain/sei.ts b/src/config/chain/sei.ts index 083ce8ccd..d4bb7795d 100644 --- a/src/config/chain/sei.ts +++ b/src/config/chain/sei.ts @@ -1,5 +1,3 @@ -import type { ContractAddr, HumanAddr, ValidatorAddr } from "lib/types"; - import type { ChainConfigs } from "./types"; export const SEI_CHAIN_CONFIGS: ChainConfigs = { @@ -35,13 +33,6 @@ export const SEI_CHAIN_CONFIGS: ChainConfigs = { gasAdjustment: 1.5, maxGasLimit: 25_000_000, }, - exampleAddresses: { - user: "sei1acqpnvg2t4wmqfdv8hq47d3petfksjs5xjfnyj" as HumanAddr, - contract: - "sei18l6zzyyhrl7j9zw2lew50677va25rtsa2s4yy5gdpg4nxz3y3j9se47f0k" as ContractAddr, - validator: - "seivaloper1hh0g5xf23e5zekg45cmerc97hs4n2004dy2t26" as ValidatorAddr, - }, explorerLink: { validator: "", proposal: "", @@ -80,13 +71,6 @@ export const SEI_CHAIN_CONFIGS: ChainConfigs = { gasAdjustment: 1.5, maxGasLimit: 25_000_000, }, - exampleAddresses: { - user: "sei1acqpnvg2t4wmqfdv8hq47d3petfksjs5xjfnyj" as HumanAddr, - contract: - "sei18l6zzyyhrl7j9zw2lew50677va25rtsa2s4yy5gdpg4nxz3y3j9se47f0k" as ContractAddr, - validator: - "seivaloper1hh0g5xf23e5zekg45cmerc97hs4n2004dy2t26" as ValidatorAddr, - }, explorerLink: { validator: "https://testnet.mintscan.io/sei-testnet/validators", proposal: "https://testnet.mintscan.io/sei-testnet/proposals", diff --git a/src/config/chain/stargaze.ts b/src/config/chain/stargaze.ts index d040b699a..b38aa9c6e 100644 --- a/src/config/chain/stargaze.ts +++ b/src/config/chain/stargaze.ts @@ -1,5 +1,3 @@ -import type { ContractAddr, HumanAddr, ValidatorAddr } from "lib/types"; - import type { ChainConfigs } from "./types"; export const STARGAZE_CHAIN_CONFIGS: ChainConfigs = { @@ -35,13 +33,6 @@ export const STARGAZE_CHAIN_CONFIGS: ChainConfigs = { gasAdjustment: 1.5, maxGasLimit: 25_000_000, }, - exampleAddresses: { - user: "stars16hetkn089m2s8nsjwppwhjed4ecp4dqtvltv82" as HumanAddr, - contract: - "stars1m4ns69zvkk2zv0946mw298tlky5ckvu08rtxggtg29p784kc5sxqwgx4h0" as ContractAddr, - validator: - "starsvaloper1mz2qks48v486d9m8wp4l9fxm2e9l0e0kzk79m5" as ValidatorAddr, - }, explorerLink: { validator: "https://www.mintscan.io/stargaze/validators", proposal: "https://www.mintscan.io/stargaze/proposals", diff --git a/src/config/chain/types.ts b/src/config/chain/types.ts index c89dcc6b1..9b3d85f4d 100644 --- a/src/config/chain/types.ts +++ b/src/config/chain/types.ts @@ -1,5 +1,3 @@ -import type { HumanAddr, ValidatorAddr, ContractAddr } from "lib/types"; - type FaucetConfig = | { enabled: true; @@ -53,11 +51,6 @@ export interface ChainConfig { gasAdjustment: number; maxGasLimit: number; }; - exampleAddresses: { - user: HumanAddr; - validator: ValidatorAddr; - contract: ContractAddr; - }; explorerLink: ExplorerConfig; hasSubHeader: boolean; } diff --git a/src/env.ts b/src/env.ts index 2327f6798..edd7d9c21 100644 --- a/src/env.ts +++ b/src/env.ts @@ -16,7 +16,15 @@ export const SUPPORTED_CHAIN_IDS: string[] = (() => { // Remark: We've already checked that the first element is not empty on the above code export const DEFAULT_SUPPORTED_CHAIN_ID = SUPPORTED_CHAIN_IDS[0]; -export const DUMMY_MNEMONIC = process.env.NEXT_PUBLIC_DUMMY_MNEMONIC; +export const DUMMY_MNEMONIC = (() => { + const mnemonic = process.env.NEXT_PUBLIC_DUMMY_MNEMONIC; + if (!mnemonic) + throw new Error( + "NEXT_PUBLIC_DUMMY_MNEMONIC is empty. Please include a valid mnemonic." + ); + + return mnemonic; +})(); export const CELATONE_API_OVERRIDE = process.env.NEXT_PUBLIC_CELATONE_API_OVERRIDE; diff --git a/src/lib/app-provider/hooks/index.ts b/src/lib/app-provider/hooks/index.ts index 9f5478234..76a5b2de0 100644 --- a/src/lib/app-provider/hooks/index.ts +++ b/src/lib/app-provider/hooks/index.ts @@ -1,6 +1,7 @@ export * from "./useAddress"; export * from "./useAmplitude"; export * from "./useDummyWallet"; +export * from "./useExampleAddresses"; export * from "./useFabricateFee"; export * from "./useInternalNavigate"; export * from "./useLCDEndpoint"; diff --git a/src/lib/app-provider/hooks/useAddress.ts b/src/lib/app-provider/hooks/useAddress.ts index 3b1585b24..0762dae0d 100644 --- a/src/lib/app-provider/hooks/useAddress.ts +++ b/src/lib/app-provider/hooks/useAddress.ts @@ -1,10 +1,10 @@ import { fromBech32 } from "@cosmjs/encoding"; import { useCallback, useMemo } from "react"; -import { useCelatoneApp } from "../contexts"; import type { Option } from "lib/types"; import { useCurrentChain } from "./useCurrentChain"; +import { useExampleAddresses } from "./useExampleAddresses"; export type AddressReturnType = | "user_address" @@ -13,9 +13,8 @@ export type AddressReturnType = | "invalid_address"; export const useGetAddressTypeByLength = () => { - const { - chainConfig: { exampleAddresses }, - } = useCelatoneApp(); + const exampleAddresses = useExampleAddresses(); + const addressLengthMap = useMemo( () => Object.entries(exampleAddresses).reduce<{ diff --git a/src/lib/app-provider/hooks/useExampleAddresses.ts b/src/lib/app-provider/hooks/useExampleAddresses.ts new file mode 100644 index 000000000..6080346d0 --- /dev/null +++ b/src/lib/app-provider/hooks/useExampleAddresses.ts @@ -0,0 +1,37 @@ +import { toBech32 } from "@cosmjs/encoding"; +import { useMemo } from "react"; + +import type { ContractAddr, HumanAddr } from "lib/types"; +import { addrToValoper } from "lib/utils"; + +import { useCurrentChain } from "./useCurrentChain"; + +export const useExampleAddresses = () => { + const { + chain: { bech32_prefix: prefix }, + } = useCurrentChain(); + + const generateExampleAddresses = () => { + const bytes = Array.from(Array(32).keys()); + const user = toBech32( + prefix, + new Uint8Array(bytes.slice(0, 20)) + ) as HumanAddr; + + // reverse the bytes so the initial characters are different from the user address + const contract = toBech32( + prefix, + new Uint8Array(bytes.reverse()) + ) as ContractAddr; + + const validator = addrToValoper(user); + + return { + user, + contract, + validator, + }; + }; + + return useMemo(generateExampleAddresses, [prefix]); +}; diff --git a/src/lib/components/AddressInput.tsx b/src/lib/components/AddressInput.tsx index 996f383f3..630be8527 100644 --- a/src/lib/components/AddressInput.tsx +++ b/src/lib/components/AddressInput.tsx @@ -8,7 +8,7 @@ import type { } from "react-hook-form"; import { useWatch } from "react-hook-form"; -import { useCelatoneApp, useValidateAddress } from "lib/app-provider"; +import { useExampleAddresses, useValidateAddress } from "lib/app-provider"; import type { FormStatus, TextInputProps } from "lib/components/forms"; import { ControllerInput } from "lib/components/forms"; import type { Option } from "lib/types"; @@ -43,11 +43,7 @@ export const AddressInput = ({ helperAction, requiredText = "Address is empty", }: AddressInputProps) => { - const { - chainConfig: { - exampleAddresses: { user: exampleAddr }, - }, - } = useCelatoneApp(); + const { user: exampleUserAddress } = useExampleAddresses(); const { validateUserAddress, validateContractAddress } = useValidateAddress(); const validateAddress = useCallback( (input: string) => @@ -69,7 +65,7 @@ export const AddressInput = ({ name={name} control={control} label={label} - placeholder={placeholder ?? exampleAddr} + placeholder={placeholder ?? exampleUserAddress} type="text" variant="floating" status={status} diff --git a/src/lib/components/button/ResendButton.tsx b/src/lib/components/button/ResendButton.tsx index 33b28effb..53214019c 100644 --- a/src/lib/components/button/ResendButton.tsx +++ b/src/lib/components/button/ResendButton.tsx @@ -58,7 +58,7 @@ export const ResendButton = ({ messages }: ResendButtonProps) => { const { isFetching: isSimulating } = useSimulateFeeQuery({ enabled: isProcessing, messages: composedMsgs, - onSuccess: (estimatedGasUsed) => proceed(estimatedGasUsed), + onSuccess: proceed, onError: () => setIsProcessing(false), }); diff --git a/src/lib/components/modal/contract/SaveNewContract.tsx b/src/lib/components/modal/contract/SaveNewContract.tsx index e5f7506f0..3d4b5f592 100644 --- a/src/lib/components/modal/contract/SaveNewContract.tsx +++ b/src/lib/components/modal/contract/SaveNewContract.tsx @@ -9,6 +9,7 @@ import { ActionModal } from "../ActionModal"; import { useBaseApiRoute, useCelatoneApp, + useExampleAddresses, useValidateAddress, } from "lib/app-provider"; import type { FormStatus } from "lib/components/forms"; @@ -47,11 +48,7 @@ export function SaveNewContractModal({ const { getContractLocalInfo } = useContractStore(); const { validateContractAddress } = useValidateAddress(); - const { - chainConfig: { - exampleAddresses: { contract: exampleContractAddress }, - }, - } = useCelatoneApp(); + const { contract: exampleContractAddress } = useExampleAddresses(); const initialList = list.value === formatSlugName(INSTANTIATED_LIST_NAME) ? [] : [list]; diff --git a/src/lib/components/select-contract/SelectContractInstantiator.tsx b/src/lib/components/select-contract/SelectContractInstantiator.tsx index 7d1d16c55..63d1f9f1d 100644 --- a/src/lib/components/select-contract/SelectContractInstantiator.tsx +++ b/src/lib/components/select-contract/SelectContractInstantiator.tsx @@ -20,7 +20,7 @@ import { useState } from "react"; import { CustomIcon } from "../icon"; import { useBaseApiRoute, - useCelatoneApp, + useExampleAddresses, useMobile, useValidateAddress, } from "lib/app-provider"; @@ -43,11 +43,7 @@ export const SelectContractInstantiator = ({ notSelected, onContractSelect, }: SelectContractInstantiatorProps) => { - const { - chainConfig: { - exampleAddresses: { contract: exampleContractAddress }, - }, - } = useCelatoneApp(); + const { contract: exampleContractAddress } = useExampleAddresses(); const { isOpen, onOpen, onClose } = useDisclosure(); const [listSlug, setListSlug] = useState(""); const { validateContractAddress } = useValidateAddress(); diff --git a/src/lib/components/table/codes/CodesTableRow.tsx b/src/lib/components/table/codes/CodesTableRow.tsx index cc2a143d5..1cfb4201f 100644 --- a/src/lib/components/table/codes/CodesTableRow.tsx +++ b/src/lib/components/table/codes/CodesTableRow.tsx @@ -1,6 +1,7 @@ import { Text, Grid, HStack } from "@chakra-ui/react"; import { TableRow } from "../tableComponents"; +import { useGetAddressType } from "lib/app-provider"; import { InstantiateButton } from "lib/components/button"; import { ExplorerLink } from "lib/components/ExplorerLink"; import { SaveOrRemoveCodeModal } from "lib/components/modal"; @@ -23,6 +24,7 @@ export const CodesTableRow = ({ onRowSelect, isReadOnly, }: CodesTableRowProps) => { + const getAddressType = useGetAddressType(); const cw2Info = getCw2Info(codeInfo.cw2Contract, codeInfo.cw2Version); return ( diff --git a/src/lib/components/table/contracts/ContractsTableRow.tsx b/src/lib/components/table/contracts/ContractsTableRow.tsx index f64652662..dc0cd186c 100644 --- a/src/lib/components/table/contracts/ContractsTableRow.tsx +++ b/src/lib/components/table/contracts/ContractsTableRow.tsx @@ -37,7 +37,7 @@ export const InstantiatorRender = ({ return instantiator ? ( diff --git a/src/lib/pages/instantiate/instantiate.tsx b/src/lib/pages/instantiate/instantiate.tsx index 72105ade2..1e4202740 100644 --- a/src/lib/pages/instantiate/instantiate.tsx +++ b/src/lib/pages/instantiate/instantiate.tsx @@ -10,11 +10,11 @@ import { useForm } from "react-hook-form"; import { useFabricateFee, useInstantiateTx, - useCelatoneApp, useValidateAddress, useSimulateFeeQuery, useCurrentChain, useBaseApiRoute, + useExampleAddresses, } from "lib/app-provider"; import { useAttachFunds } from "lib/app-provider/hooks/useAttachFunds"; import { AssignMe } from "lib/components/AssignMe"; @@ -64,11 +64,8 @@ const Instantiate = ({ onComplete }: InstantiatePageProps) => { const router = useRouter(); const msgQuery = (router.query.msg as string) ?? ""; const codeIdQuery = (router.query["code-id"] as string) ?? ""; - const { - chainConfig: { - exampleAddresses: { contract: exampleContractAddress }, - }, - } = useCelatoneApp(); + const { user: exampleUserAddress } = useExampleAddresses(); + const { address = "" } = useCurrentChain(); const lcdEndpoint = useBaseApiRoute("rest"); @@ -329,7 +326,7 @@ const Instantiate = ({ onComplete }: InstantiatePageProps) => { name="adminAddress" control={control} label="Admin Address (optional)" - placeholder={`ex. ${exampleContractAddress}`} + placeholder={`ex. ${exampleUserAddress}`} helperText="The contract's admin will be able to migrate and update future admins." variant="floating" error={validateAdmin(adminAddress)} diff --git a/src/lib/pages/proposal/store-code/index.tsx b/src/lib/pages/proposal/store-code/index.tsx index f9832a320..650a93c54 100644 --- a/src/lib/pages/proposal/store-code/index.tsx +++ b/src/lib/pages/proposal/store-code/index.tsx @@ -25,6 +25,7 @@ import { getAlert } from "../utils"; import { useCelatoneApp, useCurrentChain, + useExampleAddresses, useFabricateFee, useSimulateFeeForProposalStoreCode, useSubmitStoreCodeProposalTx, @@ -96,8 +97,9 @@ const StoreCodeProposal = () => { useWasmConfig({ shouldRedirect: true }); const { constants, - chainConfig: { prettyName, exampleAddresses }, + chainConfig: { prettyName }, } = useCelatoneApp(); + const { user: exampleUserAddress } = useExampleAddresses(); const getMaxLengthError = useGetMaxLengthError(); const { address: walletAddress = "" } = useCurrentChain(); const fabricateFee = useFabricateFee(); @@ -404,7 +406,7 @@ const StoreCodeProposal = () => { control={control} label={PROPOSAL_STORE_CODE_TEXT.runAsLabel} labelBgColor="background.main" - placeholder={`ex. ${exampleAddresses.user}`} + placeholder={`ex. ${exampleUserAddress}`} variant="floating" helperText={PROPOSAL_STORE_CODE_TEXT.runAsHelperText} requiredText={PROPOSAL_STORE_CODE_TEXT.runAsRequired}