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

feat: initia select module drawer wireup #515

Merged
merged 9 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from 8 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 @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Features

- [#515](https://github.com/alleslabs/celatone-frontend/pull/515) Initia select module drawer wireup
- [#494](https://github.com/alleslabs/celatone-frontend/pull/494) Initia select module drawer UI
- [#490](https://github.com/alleslabs/celatone-frontend/pull/490) Add initia module interaction page
- [#488](https://github.com/alleslabs/celatone-frontend/pull/488) Add initia navigation and sidebar
Expand Down
11 changes: 5 additions & 6 deletions src/config/chain/initia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ import type { ChainConfigs } from "./types";
export const INITIA_CHAIN_CONFIGS: ChainConfigs = {
"stone-9": {
chain: "initia",
registryChainName: "osmosis",
registryChainName: "initiatestnet",
prettyName: "Initia Testnet",
// TODO change to initia
lcd: "https://lcd.osmosis.zone",
rpc: "https://rpc.osmosis.zone:443",
indexer: "https://osmosis-mainnet-graphql.alleslabs.dev/v1/graphql",
lcd: "https://stone-rest.initia.tech",
rpc: "https://stone-rpc.initia.tech:443",
indexer: "https://initia-tesnet-graphql.alleslabs.dev/v1/graphql",
api: "https://celatone-api.alleslabs.dev",
wallets: [...keplrWallets],
features: {
Expand Down Expand Up @@ -39,7 +38,7 @@ export const INITIA_CHAIN_CONFIGS: ChainConfigs = {
gas: {
gasPrice: {
tokenPerGas: 0.025,
denom: "init",
denom: "uinit",
},
gasAdjustment: 1.5,
maxGasLimit: 25_000_000,
Expand Down
3 changes: 3 additions & 0 deletions src/lib/app-provider/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,7 @@ export enum CELATONE_QUERY_KEYS {
POOL_INFO_BY_IDS = "CELATONE_QUERY_POOL_INFO_BY_IDS",
POOL_TRANSACTION_BY_ID = "CELATONE_QUERY_POOL_TRANSACTION_BY_ID",
POOL_TRANSACTION_BY_ID_COUNT = "CELATONE_QUERY_POOL_TRANSACTION_BY_ID_COUNT",
// MODULES
ACCOUNT_MODULES = "CELATONE_QUERY_ACCOUNT_MODULES",
MODULE_VERIFICATION = "CELATONE_QUERY_MODULE_VERIFICATION",
}
1 change: 1 addition & 0 deletions src/lib/app-provider/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ export * from "./useBaseApiRoute";
export * from "./useRPCEndpoint";
export * from "./useConfig";
export * from "./useCurrentChain";
export * from "./useConvertHexAddress";
6 changes: 6 additions & 0 deletions src/lib/app-provider/hooks/useAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { fromBech32 } from "@cosmjs/encoding";
import { useCallback, useMemo } from "react";

import type { Option } from "lib/types";
import { isHexAddress } from "lib/utils";

import { useCurrentChain } from "./useCurrentChain";
import { useExampleAddresses } from "./useExampleAddresses";
Expand Down Expand Up @@ -134,5 +135,10 @@ export const useValidateAddress = () => {
),
[bech32Prefix, getAddressTypeByLength]
),
validateHexAddress: useCallback(
(address: string) =>
!address.startsWith(bech32Prefix) && isHexAddress(address),
[bech32Prefix]
),
};
};
17 changes: 17 additions & 0 deletions src/lib/app-provider/hooks/useConvertHexAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useCallback } from "react";

import type { HexAddr } from "lib/types";
import { hexToBech32Address } from "lib/utils";

import { useCurrentChain } from "./useCurrentChain";

export const useConvertHexAddress = () => {
const {
chain: { bech32_prefix: bech32Prefix },
} = useCurrentChain();

return useCallback(
(hexAddr: HexAddr) => hexToBech32Address(bech32Prefix, hexAddr),
[bech32Prefix]
);
};
72 changes: 72 additions & 0 deletions src/lib/chain-registry/initiatestnet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import type { Chain, AssetList } from "@chain-registry/types";

export const initiatestnet: Chain = {
$schema: "../chain.schema.json",
chain_name: "initiatestnet",
status: "live",
network_type: "testnet",
pretty_name: "Initia Testnet",
chain_id: "stone-9",
bech32_prefix: "init",
daemon_name: "initd",
node_home: "$HOME/.init",
key_algos: ["secp256k1"],
slip44: 118,
fees: {
fee_tokens: [
{
denom: "uinit",
fixed_min_gas_price: 0,
low_gas_price: 0,
average_gas_price: 0.025,
high_gas_price: 0.04,
},
],
},
staking: {
staking_tokens: [
{
denom: "uinit",
},
],
},
logo_URIs: {
png: "",
svg: "",
},
apis: {
rpc: [
{
address: "https://stone-rpc.initia.tech:443",
},
],
rest: [
{
address: "https://stone-rest.initia.tech",
},
],
},
};
export const initiatestnetAssets: AssetList = {
$schema: "../assetlist.schema.json",
chain_name: "initiatestnet",
assets: [
{
description: "The native staking token of Initia.",
denom_units: [
{
denom: "uinit",
exponent: 0,
},
{
denom: "init",
exponent: 6,
},
],
base: "uinit",
name: "Init",
display: "init",
symbol: "INIT",
},
],
};
8 changes: 6 additions & 2 deletions src/lib/components/CopyLink.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { FlexProps, IconProps } from "@chakra-ui/react";
import { Flex, Text, useClipboard } from "@chakra-ui/react";
import { useMemo, useState } from "react";
import { useEffect, useMemo, useState } from "react";

import { useCurrentChain } from "lib/app-provider";
import { AmpTrackCopier } from "lib/services/amplitude";
Expand All @@ -25,7 +25,7 @@ export const CopyLink = ({
...flexProps
}: CopyLinkProps) => {
const { address } = useCurrentChain();
const { onCopy, hasCopied } = useClipboard(value);
const { onCopy, hasCopied, setValue } = useClipboard(value);
const [isHover, setIsHover] = useState(false);

// TODO - Refactor
Expand All @@ -39,6 +39,10 @@ export const CopyLink = ({
return undefined;
}, [showCopyOnHover, isHover]);

useEffect(() => {
setValue(value);
}, [value, setValue]);

return (
<Tooltip
isOpen={isHover || hasCopied}
Expand Down
36 changes: 30 additions & 6 deletions src/lib/components/InputWithIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import type { InputProps } from "@chakra-ui/react";
import { Input, InputGroup, InputRightElement } from "@chakra-ui/react";
import {
InputLeftElement,
Input,
InputGroup,
InputRightElement,
} from "@chakra-ui/react";
import type { ChangeEvent } from "react";

import { AmpEvent, AmpTrack } from "lib/services/amplitude";
Expand All @@ -9,29 +14,48 @@ import { CustomIcon } from "./icon";
interface InputWithIconProps {
placeholder: string;
value: string;
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
size?: InputProps["size"];
my?: InputProps["my"];
action?: string;
iconPosition?: "start" | "end";
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
}

const SearchIcon = () => <CustomIcon name="search" color="gray.600" />;

const InputWithIcon = ({
placeholder,
value,
size,
my,
action,
iconPosition = "end",
onChange,
}: InputWithIconProps) => (
<InputGroup>
<InputGroup my={my}>
<Input
placeholder={placeholder}
value={value}
onChange={onChange}
size={size}
p={`8px ${iconPosition === "end" ? "40px" : "12px"} 8px ${
iconPosition === "start" ? "40px" : "12px"
} !important`}
onClick={action ? () => AmpTrack(AmpEvent.USE_SEARCH_INPUT) : undefined}
/>
<InputRightElement h="56px" alignItems="center" mr={1}>
<CustomIcon name="search" color="gray.600" />
</InputRightElement>
{iconPosition === "end" ? (
<InputRightElement
h={size === "lg" ? "56px" : "full"}
alignItems="center"
mr={1}
>
<SearchIcon />
</InputRightElement>
) : (
<InputLeftElement h={size === "lg" ? "56px" : "full"} alignItems="center">
<SearchIcon />
</InputLeftElement>
)}
</InputGroup>
);

Expand Down
9 changes: 7 additions & 2 deletions src/lib/components/forms/TextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { getResponseMsg, getStatusIcon } from "./FormStatus";
export interface TextInputProps extends FormControlProps {
value: string;
setInputState: Dispatch<SetStateAction<string>>;
autoFocus?: boolean;
label?: string;
labelBgColor?: string;
helperText?: string;
Expand All @@ -36,6 +37,7 @@ export interface TextInputProps extends FormControlProps {
export const TextInput = ({
value,
setInputState,
autoFocus,
label = "",
labelBgColor = "background.main",
helperText,
Expand All @@ -62,6 +64,7 @@ export const TextInput = ({

<InputGroup>
<Input
autoFocus={autoFocus}
size={size}
placeholder={placeholder}
type={type}
Expand All @@ -78,11 +81,13 @@ export const TextInput = ({
{error ? (
<FormErrorMessage className="error-text">{error}</FormErrorMessage>
) : (
<FormHelperText className="helper-text">
<FormHelperText className="helper-text" mt={0}>
{status?.message ? (
getResponseMsg(status, helperText)
) : (
<Text color="text.dark">{helperText}</Text>
<Text color="text.dark" variant="body3">
{helperText}
</Text>
)}
</FormHelperText>
)}
Expand Down
58 changes: 32 additions & 26 deletions src/lib/components/module/FunctionCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ import { Flex, Text } from "@chakra-ui/react";
import { DotSeparator } from "../DotSeparator";
import { CustomIcon } from "../icon";
import { Tooltip } from "lib/components/Tooltip";
import type { ExposedFunction, Visibility } from "lib/types";

interface FunctionCardProps {
isView?: boolean;
disabled?: boolean;
visibility?: "public" | "friends" | "script";
exposedFn: ExposedFunction;
onFunctionSelect: (fn: ExposedFunction) => void;
}

const getIcon = (visibility: FunctionCardProps["visibility"]) => {
const getIcon = (visibility: Visibility) => {
switch (visibility) {
case "friends":
return <CustomIcon name="friends" color="text.dark" boxSize={3} />;
case "friend":
return <CustomIcon name="friends" color="gray.600" boxSize={3} />;
case "script":
return <CustomIcon name="code" color="text.dark" boxSize={3} />;
return <CustomIcon name="code" color="gray.600" boxSize={3} />;
case "public":
default:
return <CustomIcon name="website" color="text.main" boxSize={3} />;
return <CustomIcon name="website" color="gray.600" boxSize={3} />;
}
};

Expand All @@ -28,6 +28,7 @@ const disabledStyle: { [key in `${boolean}`]: FlexProps } = {
bgColor: "gray.900",
_hover: { bg: "gray.900" },
cursor: "not-allowed",
pointerEvents: "none",
borderColor: "gray.700",
},
false: {
Expand All @@ -39,10 +40,12 @@ const disabledStyle: { [key in `${boolean}`]: FlexProps } = {
};

export const FunctionCard = ({
isView = true,
disabled = false,
visibility = "public",
exposedFn,
onFunctionSelect,
}: FunctionCardProps) => {
const { is_entry: isEntry, is_view: isView, visibility, name } = exposedFn;
const disabled = !isEntry || visibility !== "public";

return (
<Flex
borderRadius={8}
Expand All @@ -52,6 +55,7 @@ export const FunctionCard = ({
flexDirection="column"
gap={1}
border="1px solid"
onClick={() => onFunctionSelect(exposedFn)}
{...disabledStyle[String(disabled) as `${boolean}`]}
>
<Flex gap={1} justifyContent="space-between" w="full">
Expand All @@ -66,28 +70,30 @@ export const FunctionCard = ({
</Text>
</Flex>
<Flex alignItems="center" gap={2}>
<Tooltip
bg="primary.dark"
label="Only functions with “is_entry: true” and “visibility: public” are able to interacted through Celatone’s module interactions."
>
<Flex>
<CustomIcon name="check" color="success.main" boxSize={3} />
</Flex>
</Tooltip>
<DotSeparator bg="gray.600" />
{!disabled && (
<>
<Tooltip
bg="primary.dark"
label="Only functions with “is_entry: true” and “visibility: public” are interactable through Celatone’s module interactions."
>
<Flex>
<CustomIcon name="check" color="success.main" boxSize={3} />
</Flex>
</Tooltip>
<DotSeparator bg="gray.600" />
</>
)}
<Flex alignItems="center" gap={1}>
{getIcon(visibility)}
<Text
variant="body3"
color={visibility === "public" ? "text.main" : "text.dark"}
textTransform="capitalize"
>
<Text variant="body3" color="text.dark" textTransform="capitalize">
{visibility}
</Text>
</Flex>
</Flex>
</Flex>
<Text variant="body2">Function Name</Text>
<Text variant="body2" color={disabled ? "text.disabled" : "text.main"}>
{name}
</Text>
</Flex>
);
};
Loading