Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1812cd8f2 | ||
|
|
537e650c5e | ||
|
|
278ff37129 | ||
|
|
76b74d2c96 | ||
|
|
7b8f4910bb | ||
|
|
11a17e64b8 | ||
|
|
75c281fea5 | ||
|
|
70a58e9bdf | ||
|
|
1194ccb375 |
@@ -1,10 +1,15 @@
|
||||
import { ChainItemType } from "../../types";
|
||||
import { Dispatch, FunctionComponent, SetStateAction } from "react";
|
||||
import {
|
||||
Dispatch,
|
||||
FunctionComponent,
|
||||
SetStateAction,
|
||||
useEffect,
|
||||
useState,
|
||||
} from "react";
|
||||
|
||||
import { ChainImage } from "./chain-image";
|
||||
import { Flex1 } from "../../styles/flex-1";
|
||||
import {
|
||||
ChainImageContainer,
|
||||
ChainInfoContainer,
|
||||
ChainItemContainer,
|
||||
ChainName,
|
||||
@@ -13,43 +18,54 @@ import {
|
||||
import color from "../../styles/color";
|
||||
import styled from "styled-components";
|
||||
import { Checkbox } from "../checkbox";
|
||||
import AllChainsIcon from "../../public/images/svg/all-chains-icon.svg";
|
||||
|
||||
interface Props {
|
||||
allChecked: boolean;
|
||||
setAllChecked: Dispatch<SetStateAction<boolean>>;
|
||||
chainItem: ChainItemType;
|
||||
chainList: ChainItemType[];
|
||||
checkedItems: Set<unknown>;
|
||||
setCheckedItems: Dispatch<SetStateAction<Set<unknown>>>;
|
||||
}
|
||||
|
||||
export const AllChainsItem: FunctionComponent<Props> = (props) => {
|
||||
const { allChecked, setAllChecked, chainItem } = props;
|
||||
const { chainList, checkedItems, setCheckedItems } = props;
|
||||
|
||||
const [checked, setChecked] = useState(false);
|
||||
|
||||
const checkHandler = () => {
|
||||
setAllChecked(!allChecked);
|
||||
if (checked) {
|
||||
setCheckedItems(new Set());
|
||||
} else if (chainList.length !== checkedItems.size) {
|
||||
setCheckedItems(new Set(chainList));
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (chainList.length === checkedItems.size && checkedItems.size !== 0) {
|
||||
setChecked(true);
|
||||
} else {
|
||||
setChecked(false);
|
||||
}
|
||||
}, [checkedItems]);
|
||||
|
||||
return (
|
||||
<AllChainsContainer>
|
||||
<ChainItemContainer
|
||||
key={chainItem.prefix}
|
||||
key="all chains"
|
||||
isLoading={false}
|
||||
checked={allChecked}
|
||||
checked={checked}
|
||||
onClick={checkHandler}
|
||||
>
|
||||
<ChainImageContainer width="3rem" height="3rem">
|
||||
<ChainImage
|
||||
src={chainItem.chainImageUrl}
|
||||
fill={true}
|
||||
alt={`${chainItem.prefix} chain image`}
|
||||
/>
|
||||
</ChainImageContainer>
|
||||
<ChainImage src={AllChainsIcon} fill={true} alt={`all chain images`} />
|
||||
<ChainInfoContainer>
|
||||
<ChainName>{`.${chainItem.prefix}`}</ChainName>
|
||||
<WalletAddress>{chainItem.address}</WalletAddress>
|
||||
<ChainName>{`.all chains(${chainList.length})`}</ChainName>
|
||||
<WalletAddress>
|
||||
{chainList.map((chain) => chain.chainName).join(", ")}
|
||||
</WalletAddress>
|
||||
</ChainInfoContainer>
|
||||
|
||||
<Flex1 />
|
||||
|
||||
<Checkbox checked={allChecked} />
|
||||
<Checkbox checked={checked} />
|
||||
</ChainItemContainer>
|
||||
</AllChainsContainer>
|
||||
);
|
||||
|
||||
@@ -21,6 +21,10 @@ export const ChainImage = ({ src, ...props }: ImageProps) => {
|
||||
};
|
||||
|
||||
const ImageWrapper = styled.div`
|
||||
position: relative;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
|
||||
img {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ChainItemType, WidthHeightProps } from "../../types";
|
||||
import { ChainItemType } from "../../types";
|
||||
import { FunctionComponent, useEffect, useState } from "react";
|
||||
|
||||
import color from "../../styles/color";
|
||||
@@ -39,13 +39,11 @@ export const ChainItem: FunctionComponent<Props> = (props) => {
|
||||
checked={checked}
|
||||
onClick={checkHandler}
|
||||
>
|
||||
<ChainImageContainer width="3rem" height="3rem">
|
||||
<ChainImage
|
||||
src={chainItem.chainImageUrl}
|
||||
fill={true}
|
||||
alt={`${chainItem.prefix} chain image`}
|
||||
/>
|
||||
</ChainImageContainer>
|
||||
<ChainImage
|
||||
src={chainItem.chainImageUrl}
|
||||
fill={true}
|
||||
alt={`${chainItem.prefix} chain image`}
|
||||
/>
|
||||
<ChainInfoContainer>
|
||||
<ChainName>{`.${chainItem.prefix}`}</ChainName>
|
||||
<WalletAddress>{chainItem.address}</WalletAddress>
|
||||
@@ -90,13 +88,6 @@ export const ChainItemContainer = styled.div<{
|
||||
}
|
||||
`;
|
||||
|
||||
export const ChainImageContainer = styled.div<WidthHeightProps>`
|
||||
width: ${(props) => props.width};
|
||||
height: ${(props) => props.height};
|
||||
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
export const ChainInfoContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -5,8 +5,6 @@ import styled from "styled-components";
|
||||
import { ChainItem } from "./chain-item";
|
||||
|
||||
interface Props {
|
||||
allChecked: boolean;
|
||||
setAllChecked: Dispatch<SetStateAction<boolean>>;
|
||||
chainList: ChainItemType[];
|
||||
disabledChainList: ChainItemType[];
|
||||
checkedItems: Set<unknown>;
|
||||
@@ -14,14 +12,7 @@ interface Props {
|
||||
}
|
||||
|
||||
export const ChainList: FunctionComponent<Props> = (props) => {
|
||||
const {
|
||||
allChecked,
|
||||
setAllChecked,
|
||||
chainList,
|
||||
disabledChainList,
|
||||
checkedItems,
|
||||
setCheckedItems,
|
||||
} = props;
|
||||
const { chainList, disabledChainList, checkedItems, setCheckedItems } = props;
|
||||
|
||||
const checkedItemHandler = (chainItem: ChainItemType, isChecked: boolean) => {
|
||||
const tempSet = new Set(checkedItems);
|
||||
@@ -35,22 +26,6 @@ export const ChainList: FunctionComponent<Props> = (props) => {
|
||||
setCheckedItems(tempSet);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (allChecked) {
|
||||
setCheckedItems(new Set(chainList));
|
||||
} else if (chainList.length === checkedItems.size) {
|
||||
setCheckedItems(new Set());
|
||||
}
|
||||
}, [allChecked]);
|
||||
|
||||
useEffect(() => {
|
||||
if (chainList.length === checkedItems.size && checkedItems.size !== 0) {
|
||||
setAllChecked(true);
|
||||
} else {
|
||||
setAllChecked(false);
|
||||
}
|
||||
}, [checkedItems]);
|
||||
|
||||
return (
|
||||
<ChainContainer color={color.grey["900"]}>
|
||||
{chainList.map((chainItem) => (
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
} from "../twitter-profile";
|
||||
import {
|
||||
ChainContainer,
|
||||
ChainImageContainer,
|
||||
ChainInfoContainer,
|
||||
ChainItemContainer,
|
||||
} from "../chain-list";
|
||||
@@ -60,9 +59,9 @@ export const SkeletonChainList: FunctionComponent = () => (
|
||||
.map((_, index) => (
|
||||
<div key={index}>
|
||||
<ChainItemContainer isLoading={true} isSkeleton={true}>
|
||||
<ChainImageContainer width="3rem" height="3rem">
|
||||
<SkeletonImageContainer>
|
||||
<SkeletonCircle width="3rem" height="3rem" />
|
||||
</ChainImageContainer>
|
||||
</SkeletonImageContainer>
|
||||
<ChainInfoContainer>
|
||||
<SkeletonText width="4rem" height="1rem" />
|
||||
<SkeletonText width="12rem" height="1rem" />
|
||||
@@ -93,6 +92,13 @@ const SkeletonTitle = styled.div`
|
||||
background-color: ${color.grey["800"]};
|
||||
`;
|
||||
|
||||
const SkeletonImageContainer = styled.div`
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
const SkeletonButtonContainer = styled.div`
|
||||
margin-top: 1.5rem;
|
||||
`;
|
||||
|
||||
@@ -70,3 +70,21 @@ export const makeSetRecordMessage = (
|
||||
[],
|
||||
);
|
||||
};
|
||||
|
||||
export const makeRemoveRecordMessage = (
|
||||
twitterUserName: string,
|
||||
senderAddress: string,
|
||||
removeAddress: string,
|
||||
): CosmwasmExecuteMessageResult => {
|
||||
return makeCosmwasmExecMsg(
|
||||
senderAddress,
|
||||
RESOLVER_ADDRESS,
|
||||
{
|
||||
remove_record: {
|
||||
name: twitterUserName,
|
||||
bech32_address: removeAddress,
|
||||
},
|
||||
},
|
||||
[],
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { AppProps } from "next/app";
|
||||
import Head from "next/head";
|
||||
import { useRouter } from "next/router";
|
||||
import React, { useMemo } from "react";
|
||||
import { DefaultTheme, ThemeProvider } from "styled-components";
|
||||
@@ -23,8 +24,109 @@ export default function App({ Component, pageProps }: AppProps) {
|
||||
return router.pathname === "/" ? homePageTheme : defaultPageTheme;
|
||||
}, [router.pathname]);
|
||||
|
||||
const origin = typeof window !== "undefined" ? window.location.origin : "";
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={pageTheme}>
|
||||
<Head>
|
||||
<title>Interchain Name Service</title>
|
||||
<meta content="Interchain Name Service" property="og:title" />
|
||||
<meta content="Interchain Name Service" property="twitter:title" />
|
||||
<meta
|
||||
content="Your identity for the Interchain. Claim yours today."
|
||||
property="og:description"
|
||||
/>
|
||||
<meta
|
||||
content="Your identity for the Interchain. Claim yours today."
|
||||
property="twitter:description"
|
||||
/>
|
||||
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
|
||||
<meta
|
||||
content={`${origin}/images/og-image.webp`}
|
||||
property="twitter:image"
|
||||
/>
|
||||
<meta content={`${origin}/images/og-image.webp`} property="og:image" />
|
||||
<meta content="summary_large_image" name="twitter:card" />
|
||||
<meta property="og:type" content="website" />
|
||||
|
||||
{/* generated favicons */}
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="57x57"
|
||||
href="/images/favicon/apple-icon-57x57.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="60x60"
|
||||
href="/images/favicon/apple-icon-60x60.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="72x72"
|
||||
href="/images/favicon/apple-icon-72x72.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="76x76"
|
||||
href="/images/favicon/apple-icon-76x76.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="114x114"
|
||||
href="/images/favicon/apple-icon-114x114.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="120x120"
|
||||
href="/images/favicon/apple-icon-120x120.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="144x144"
|
||||
href="/images/favicon/apple-icon-144x144.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="152x152"
|
||||
href="/images/favicon/apple-icon-152x152.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="180x180"
|
||||
href="/images/favicon/apple-icon-180x180.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="192x192"
|
||||
href="/images/favicon/android-icon-192x192.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="32x32"
|
||||
href="/images/favicon/favicon-32x32.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="96x96"
|
||||
href="/images/favicon/favicon-96x96.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="16x16"
|
||||
href="/images/favicon/favicon-16x16.png"
|
||||
/>
|
||||
<link rel="manifest" href="/images/favicon/manifest.json" />
|
||||
<meta name="msapplication-TileColor" content="#ffffff" />
|
||||
<meta
|
||||
name="msapplication-TileImage"
|
||||
content="/images/favicon/ms-icon-144x144.png"
|
||||
/>
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
</Head>
|
||||
<React.Fragment>
|
||||
<GlobalStyle />
|
||||
<ErrorBoundary>
|
||||
|
||||
@@ -13,6 +13,7 @@ import { ConnectWalletModal } from "../components/connect-wallet-modal";
|
||||
import MainTitle from "../public/images/svg/main-title.svg";
|
||||
import MainLogo from "../public/images/svg/main-logo.svg";
|
||||
import CheckIcon from "../public/images/svg/check-icon.svg";
|
||||
import StarIcon from "../public/images/svg/bg-asset-3.svg";
|
||||
import { Logo } from "../components/logo";
|
||||
import { useEffect, useState } from "react";
|
||||
import { MINIMUM_OSMO_FEE, SELECTED_WALLET_KEY } from "../constants/wallet";
|
||||
@@ -48,6 +49,20 @@ export default function Home() {
|
||||
<MainContainer>
|
||||
<MainTitleContainer>
|
||||
<MainTitleImageBackground>
|
||||
<Image
|
||||
src={StarIcon}
|
||||
width={50}
|
||||
height={50}
|
||||
alt="Star Icon"
|
||||
className="starIcon first"
|
||||
/>
|
||||
<Image
|
||||
src={StarIcon}
|
||||
width={50}
|
||||
height={50}
|
||||
alt="Star Icon"
|
||||
className="starIcon last"
|
||||
/>
|
||||
<MainTitleImageContainer>
|
||||
<Image
|
||||
src={MainTitle}
|
||||
@@ -112,6 +127,15 @@ const Container = styled.div`
|
||||
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
|
||||
background-image: url("/images/svg/bg-asset-1.svg"),
|
||||
url("/images/svg/bg-asset-2.svg"), url("/images/svg/bg-asset-2.svg"),
|
||||
url("/images/svg/bg-asset-3.svg"), url("/images/svg/bg-asset-3.svg");
|
||||
background-size: 5rem 5rem, 5rem 5rem, 5rem 5rem, 3.125rem 3.125rem,
|
||||
3.125rem 3.125rem;
|
||||
background-position: 80px 640px, 960px 80px, 1200px 720px, 136px 776px,
|
||||
1016px 696px;
|
||||
background-repeat: no-repeat;
|
||||
`;
|
||||
|
||||
const MainContainer = styled.div`
|
||||
@@ -120,6 +144,20 @@ const MainContainer = styled.div`
|
||||
|
||||
margin-top: 15rem;
|
||||
margin-left: 10rem;
|
||||
|
||||
img.starIcon {
|
||||
position: absolute;
|
||||
|
||||
&.first {
|
||||
left: -24px;
|
||||
top: -24px;
|
||||
}
|
||||
|
||||
&.last {
|
||||
right: -23px;
|
||||
top: -24px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const MainTitleContainer = styled.div`
|
||||
|
||||
@@ -30,7 +30,6 @@ import {
|
||||
} from "../../wallets";
|
||||
import { ChainIdHelper } from "@keplr-wallet/cosmos";
|
||||
|
||||
import AllChainsIcon from "../../public/images/svg/all-chains-icon.svg";
|
||||
import { AllChainsItem } from "../../components/chain-list/all-chains-item";
|
||||
import { SearchInput } from "../../components/search-input";
|
||||
import {
|
||||
@@ -52,8 +51,12 @@ import {
|
||||
KEPLR_NOT_FOUND_ERROR,
|
||||
TWITTER_LOGIN_ERROR,
|
||||
} from "../../constants/error-message";
|
||||
import { makeClaimMessage, makeSetRecordMessage } from "../../messages";
|
||||
import Axios, { AxiosError } from "axios";
|
||||
import {
|
||||
makeClaimMessage,
|
||||
makeRemoveRecordMessage,
|
||||
makeSetRecordMessage,
|
||||
} from "../../messages";
|
||||
import Axios from "axios";
|
||||
import { BackButton } from "../../components/back-button";
|
||||
|
||||
export default function VerificationPage() {
|
||||
@@ -71,9 +74,6 @@ export default function VerificationPage() {
|
||||
const [registeredChainList, setRegisteredChainList] = useState<
|
||||
RegisteredAddresses[]
|
||||
>([]);
|
||||
|
||||
const [allChains, setAllChains] = useState<ChainItemType>();
|
||||
const [allChecked, setAllChecked] = useState(false);
|
||||
const [checkedItems, setCheckedItems] = useState(new Set());
|
||||
|
||||
const [searchValue, setSearchValue] = useState("");
|
||||
@@ -82,69 +82,16 @@ export default function VerificationPage() {
|
||||
const [isAgree, setIsAgree] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const init = async () => {
|
||||
if (window.location.search) {
|
||||
try {
|
||||
const { state, code } = checkTwitterAuthQueryParameter(
|
||||
window.location.search,
|
||||
);
|
||||
|
||||
// Initialize Wallet
|
||||
const keplrWallet = await initWallet();
|
||||
|
||||
// Fetch Twitter Profile
|
||||
const twitterInfo = await fetchTwitterInfo(state, code);
|
||||
|
||||
// contract check registered
|
||||
const registeredQueryResponse = await queryRegisteredTwitterId(
|
||||
twitterInfo.id,
|
||||
);
|
||||
|
||||
setTwitterAuthInfo({
|
||||
...twitterInfo,
|
||||
isRegistered: "data" in registeredQueryResponse,
|
||||
});
|
||||
|
||||
if ("data" in registeredQueryResponse) {
|
||||
const ownerOfQueryResponse = await queryOwnerOfTwitterName(
|
||||
registeredQueryResponse.data.name,
|
||||
);
|
||||
|
||||
const addressesQueryResponse = await queryAddressesFromTwitterName(
|
||||
registeredQueryResponse.data.name,
|
||||
);
|
||||
|
||||
if (keplrWallet) {
|
||||
const key = await keplrWallet.getKey(MainChainId);
|
||||
setIsOwner(ownerOfQueryResponse.data.owner === key.bech32Address);
|
||||
}
|
||||
|
||||
setRegisteredChainList(addressesQueryResponse.data.addresses);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.message === TWITTER_LOGIN_ERROR) {
|
||||
await router.push("/");
|
||||
}
|
||||
|
||||
console.error(error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
init();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setAllChains({
|
||||
chainId: "all chains",
|
||||
chainName: "all chains",
|
||||
prefix: `all chains(${chainList.length})`,
|
||||
address: chainList.map((chain) => chain.chainName).join(", "),
|
||||
chainImageUrl: AllChainsIcon,
|
||||
});
|
||||
}, [chainList]);
|
||||
if (wallet) {
|
||||
window.addEventListener("keplr_keystorechange", async () => {
|
||||
await init();
|
||||
});
|
||||
}
|
||||
}, [wallet]);
|
||||
|
||||
useEffect(() => {
|
||||
const disabledChainList = chainList.filter((chain) => {
|
||||
@@ -164,18 +111,67 @@ export default function VerificationPage() {
|
||||
(chain) => !disabledChainList.includes(chain),
|
||||
);
|
||||
|
||||
setAllChains({
|
||||
chainId: "all chains",
|
||||
chainName: "all chains",
|
||||
prefix: `all chains(${filteredChainList.length})`,
|
||||
address: filteredChainList.map((chain) => chain.chainName).join(", "),
|
||||
chainImageUrl: AllChainsIcon,
|
||||
});
|
||||
|
||||
setChainList(filteredChainList);
|
||||
setDisabledChainList(disabledChainList);
|
||||
|
||||
setCheckedItems(new Set(filteredChainList));
|
||||
}, [registeredChainList]);
|
||||
|
||||
useEffect(() => {
|
||||
setCheckedItems(new Set(chainList));
|
||||
}, [chainList]);
|
||||
|
||||
const init = async () => {
|
||||
if (window.location.search) {
|
||||
try {
|
||||
const { state, code } = checkTwitterAuthQueryParameter(
|
||||
window.location.search,
|
||||
);
|
||||
|
||||
// Initialize Wallet
|
||||
const keplrWallet = await initWallet();
|
||||
|
||||
// Fetch Twitter Profile
|
||||
const twitterInfo = await fetchTwitterInfo(state, code);
|
||||
|
||||
// contract check registered
|
||||
const registeredQueryResponse = await queryRegisteredTwitterId(
|
||||
twitterInfo.id,
|
||||
);
|
||||
|
||||
setTwitterAuthInfo({
|
||||
...twitterInfo,
|
||||
isRegistered: "data" in registeredQueryResponse,
|
||||
});
|
||||
|
||||
if ("data" in registeredQueryResponse) {
|
||||
const ownerOfQueryResponse = await queryOwnerOfTwitterName(
|
||||
registeredQueryResponse.data.name,
|
||||
);
|
||||
|
||||
const addressesQueryResponse = await queryAddressesFromTwitterName(
|
||||
registeredQueryResponse.data.name,
|
||||
);
|
||||
|
||||
if (keplrWallet) {
|
||||
const key = await keplrWallet.getKey(MainChainId);
|
||||
setIsOwner(ownerOfQueryResponse.data.owner === key.bech32Address);
|
||||
}
|
||||
|
||||
setRegisteredChainList(addressesQueryResponse.data.addresses);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.message === TWITTER_LOGIN_ERROR) {
|
||||
await router.push("/");
|
||||
}
|
||||
|
||||
console.error(error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const initWallet = async () => {
|
||||
const keplr = await getKeplrFromWindow();
|
||||
|
||||
@@ -348,10 +344,15 @@ export default function VerificationPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const isRegisterButtonDisable =
|
||||
checkedItems.size < 1 ||
|
||||
(!isOwner && registeredChainList.length > 0) ||
|
||||
!isAgree;
|
||||
const isRegisterButtonDisable = (() => {
|
||||
const hasCheckedItem = checkedItems.size > 0;
|
||||
|
||||
if (isOwner) {
|
||||
return !hasCheckedItem;
|
||||
} else {
|
||||
return !(isAgree && hasCheckedItem);
|
||||
}
|
||||
})();
|
||||
|
||||
return (
|
||||
<Container>
|
||||
@@ -363,6 +364,67 @@ export default function VerificationPage() {
|
||||
) : (
|
||||
<ContentContainer>
|
||||
<BackButton />
|
||||
<div>
|
||||
<button
|
||||
onClick={async () => {
|
||||
if (twitterAuthInfo && wallet) {
|
||||
const key = await wallet.getKey(MainChainId);
|
||||
|
||||
const removeMessages = registeredChainList.map((chain) => {
|
||||
return makeRemoveRecordMessage(
|
||||
twitterAuthInfo.username,
|
||||
key.bech32Address,
|
||||
chain.address,
|
||||
);
|
||||
});
|
||||
|
||||
const aminoMsgs = [];
|
||||
const protoMsgs = [];
|
||||
|
||||
for (const msg of removeMessages) {
|
||||
aminoMsgs.push(msg.amino);
|
||||
protoMsgs.push(msg.proto);
|
||||
}
|
||||
|
||||
console.log(aminoMsgs);
|
||||
|
||||
const chainInfo = {
|
||||
chainId: MainChainId,
|
||||
rest: REST_URL,
|
||||
};
|
||||
|
||||
const simulated = await simulateMsgs(
|
||||
chainInfo,
|
||||
key.bech32Address,
|
||||
{
|
||||
proto: protoMsgs,
|
||||
},
|
||||
{
|
||||
amount: [],
|
||||
},
|
||||
);
|
||||
|
||||
const txHash = await sendMsgs(
|
||||
wallet,
|
||||
chainInfo,
|
||||
key.bech32Address,
|
||||
{
|
||||
amino: aminoMsgs,
|
||||
proto: protoMsgs,
|
||||
},
|
||||
{
|
||||
amount: [],
|
||||
gas: Math.floor(simulated.gasUsed * 1.5).toString(),
|
||||
},
|
||||
);
|
||||
|
||||
console.log(txHash);
|
||||
}
|
||||
}}
|
||||
>
|
||||
All Remove
|
||||
</button>
|
||||
</div>
|
||||
<TwitterProfile twitterProfileInformation={twitterAuthInfo} />
|
||||
|
||||
<ChainListTitleContainer>
|
||||
@@ -373,17 +435,15 @@ export default function VerificationPage() {
|
||||
/>
|
||||
</ChainListTitleContainer>
|
||||
|
||||
{allChains && !searchValue ? (
|
||||
{!searchValue ? (
|
||||
<AllChainsItem
|
||||
allChecked={allChecked}
|
||||
setAllChecked={setAllChecked}
|
||||
chainItem={allChains}
|
||||
chainList={chainList}
|
||||
checkedItems={checkedItems}
|
||||
setCheckedItems={setCheckedItems}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<ChainList
|
||||
allChecked={allChecked}
|
||||
setAllChecked={setAllChecked}
|
||||
chainList={chainList.filter(
|
||||
(chain) =>
|
||||
chain.chainId.includes(searchValue) ||
|
||||
@@ -400,23 +460,27 @@ export default function VerificationPage() {
|
||||
setCheckedItems={setCheckedItems}
|
||||
/>
|
||||
|
||||
<AgreeContainer
|
||||
onClick={() => {
|
||||
setIsAgree(!isAgree);
|
||||
}}
|
||||
>
|
||||
<AgreeCheckBox type="checkbox" checked={isAgree} readOnly />I
|
||||
check that Osmo is required for this transaction
|
||||
</AgreeContainer>
|
||||
|
||||
<ButtonContainer disabled={isRegisterButtonDisable}>
|
||||
<PrimaryButton
|
||||
disabled={isRegisterButtonDisable}
|
||||
onClick={onClickRegistration}
|
||||
{!isOwner && (
|
||||
<AgreeContainer
|
||||
onClick={() => {
|
||||
setIsAgree(!isAgree);
|
||||
}}
|
||||
>
|
||||
Register
|
||||
</PrimaryButton>
|
||||
</ButtonContainer>
|
||||
<AgreeCheckBox type="checkbox" checked={isAgree} readOnly />I
|
||||
check that Osmo is required for this transaction
|
||||
</AgreeContainer>
|
||||
)}
|
||||
|
||||
{chainList.length > 0 && (
|
||||
<ButtonContainer disabled={isRegisterButtonDisable}>
|
||||
<PrimaryButton
|
||||
disabled={isRegisterButtonDisable}
|
||||
onClick={onClickRegistration}
|
||||
>
|
||||
Register
|
||||
</PrimaryButton>
|
||||
</ButtonContainer>
|
||||
)}
|
||||
</ContentContainer>
|
||||
)}
|
||||
</MainContainer>
|
||||
@@ -438,6 +502,13 @@ const MainContainer = styled.div`
|
||||
padding: 2.7rem 0;
|
||||
|
||||
color: white;
|
||||
|
||||
background-image: url("/images/svg/bg-asset-3.svg"),
|
||||
url("/images/svg/bg-asset-3.svg"), url("/images/svg/bg-asset-3.svg"),
|
||||
url("/images/svg/bg-asset-3.svg");
|
||||
background-size: 3.125rem 3.125rem;
|
||||
background-position: 296px 536px, 1256px 216px, 376px 776px, 1176px 856px;
|
||||
background-repeat: no-repeat;
|
||||
`;
|
||||
|
||||
export const ContentContainer = styled.div`
|
||||
|
||||
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig><msapplication><tile><square70x70logo src="/ms-icon-70x70.png"/><square150x150logo src="/ms-icon-150x150.png"/><square310x310logo src="/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "App",
|
||||
"icons": [
|
||||
{
|
||||
"src": "\/android-icon-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image\/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image\/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image\/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image\/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image\/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image\/png",
|
||||
"density": "4.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 0C-9.27438e-07 10.6087 4.21427 20.7828 11.7157 28.2843C19.2172 35.7857 29.3913 40 40 40C50.6087 40 60.7828 35.7857 68.2843 28.2843C75.7857 20.7828 80 10.6087 80 1.30337e-05L0 0Z" fill="#242424"/>
|
||||
<path d="M0 40C-9.27438e-07 50.6087 4.21427 60.7828 11.7157 68.2843C19.2172 75.7857 29.3913 80 40 80C50.6087 80 60.7828 75.7857 68.2843 68.2843C75.7857 60.7828 80 50.6087 80 40L0 40Z" fill="#242424"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 512 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 80C10.6087 80 20.7828 75.7857 28.2843 68.2843C35.7857 60.7828 40 50.6087 40 40C40 29.3913 35.7857 19.2172 28.2843 11.7157C20.7828 4.21428 10.6087 -4.6372e-07 9.53674e-06 0L0 80Z" fill="#242424"/>
|
||||
<path d="M40 80C50.6087 80 60.7828 75.7857 68.2843 68.2843C75.7857 60.7828 80 50.6087 80 40C80 29.3913 75.7857 19.2172 68.2843 11.7157C60.7828 4.21428 50.6087 -4.6372e-07 40 0L40 80Z" fill="#242424"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 512 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M25 0L25.3504 2.74704C26.8096 14.1848 35.8152 23.1904 47.253 24.6496L50 25L47.253 25.3504C35.8152 26.8096 26.8096 35.8152 25.3504 47.253L25 50L24.6496 47.253C23.1904 35.8152 14.1848 26.8096 2.74704 25.3504L0 25L2.74704 24.6496C14.1848 23.1904 23.1904 14.1848 24.6496 2.74704L25 0Z" fill="#2B2B2B"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 411 B |