forked from LaconicNetwork/icns-frontend
Add disabled chain list
This commit is contained in:
parent
7de3767d03
commit
bb58fb54ea
@ -1,20 +1,16 @@
|
|||||||
import { ChainItemType } from "../../types";
|
import { ChainItemType } from "../../types";
|
||||||
|
import { Dispatch, FunctionComponent, SetStateAction } from "react";
|
||||||
|
|
||||||
|
import { ChainImage } from "./chain-image";
|
||||||
|
import { Flex1 } from "../../styles/flex-1";
|
||||||
import {
|
import {
|
||||||
ChangeEvent,
|
ChainCheckBox,
|
||||||
Dispatch,
|
|
||||||
FunctionComponent,
|
|
||||||
SetStateAction,
|
|
||||||
useEffect,
|
|
||||||
useState,
|
|
||||||
} from "react";
|
|
||||||
import {
|
|
||||||
ChainImageContainer,
|
ChainImageContainer,
|
||||||
ChainInfoContainer,
|
ChainInfoContainer,
|
||||||
ChainItemContainer,
|
ChainItemContainer,
|
||||||
} from "./chain-list";
|
ChainName,
|
||||||
import { ChainImage } from "./chain-image";
|
WalletAddress,
|
||||||
import { Flex1 } from "../../styles/flex-1";
|
} from "./chain-item";
|
||||||
import { ChainCheckBox, ChainName, WalletAddress } from "./chain-item";
|
|
||||||
import color from "../../styles/color";
|
import color from "../../styles/color";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
@ -1,17 +1,5 @@
|
|||||||
import { ChainItemType } from "../../types";
|
import { ChainItemType, WidthHeightProps } from "../../types";
|
||||||
import {
|
import { FunctionComponent, useEffect, useState } from "react";
|
||||||
ChangeEvent,
|
|
||||||
Dispatch,
|
|
||||||
FunctionComponent,
|
|
||||||
SetStateAction,
|
|
||||||
useEffect,
|
|
||||||
useState,
|
|
||||||
} from "react";
|
|
||||||
import {
|
|
||||||
ChainImageContainer,
|
|
||||||
ChainInfoContainer,
|
|
||||||
ChainItemContainer,
|
|
||||||
} from "./chain-list";
|
|
||||||
|
|
||||||
import color from "../../styles/color";
|
import color from "../../styles/color";
|
||||||
import { Flex1 } from "../../styles/flex-1";
|
import { Flex1 } from "../../styles/flex-1";
|
||||||
@ -22,26 +10,31 @@ interface Props {
|
|||||||
chainItem: ChainItemType;
|
chainItem: ChainItemType;
|
||||||
checkedItemHandler: (chainItem: ChainItemType, isChecked: boolean) => void;
|
checkedItemHandler: (chainItem: ChainItemType, isChecked: boolean) => void;
|
||||||
checkedItems: Set<unknown>;
|
checkedItems: Set<unknown>;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ChainItem: FunctionComponent<Props> = (props) => {
|
export const ChainItem: FunctionComponent<Props> = (props) => {
|
||||||
const { chainItem, checkedItemHandler, checkedItems } = props;
|
const { chainItem, checkedItemHandler, checkedItems, disabled } = props;
|
||||||
const [checked, setChecked] = useState(false);
|
const [checked, setChecked] = useState(disabled);
|
||||||
|
|
||||||
const checkHandler = () => {
|
const checkHandler = () => {
|
||||||
setChecked(!checked);
|
if (!disabled) {
|
||||||
checkedItemHandler(chainItem, !checked);
|
setChecked(!checked);
|
||||||
|
checkedItemHandler(chainItem, !checked);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setChecked(checkedItems.has(chainItem));
|
if (!disabled) {
|
||||||
|
setChecked(checkedItems.has(chainItem));
|
||||||
|
}
|
||||||
}, [checkedItems]);
|
}, [checkedItems]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChainItemContainer
|
<ChainItemContainer
|
||||||
key={chainItem.prefix}
|
key={chainItem.prefix}
|
||||||
isLoading={false}
|
isLoading={false}
|
||||||
checked={checked}
|
disabled={disabled}
|
||||||
onClick={checkHandler}
|
onClick={checkHandler}
|
||||||
>
|
>
|
||||||
<ChainImageContainer width="3rem" height="3rem">
|
<ChainImageContainer width="3rem" height="3rem">
|
||||||
@ -63,6 +56,41 @@ export const ChainItem: FunctionComponent<Props> = (props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ChainItemContainer = styled.div<{
|
||||||
|
isLoading: boolean;
|
||||||
|
checked?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
}>`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
gap: 1rem;
|
||||||
|
|
||||||
|
padding: 1.5rem;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
opacity: ${(props) => (props.disabled ? "0.3" : "1")};
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: ${(props) => (props.isLoading ? null : color.grey["600"])};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
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;
|
||||||
|
gap: 0.5rem;
|
||||||
|
`;
|
||||||
|
|
||||||
export const ChainName = styled.div`
|
export const ChainName = styled.div`
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Dispatch, FunctionComponent, SetStateAction, useEffect } from "react";
|
import { Dispatch, FunctionComponent, SetStateAction, useEffect } from "react";
|
||||||
import { ChainItemType, WidthHeightProps } from "../../types";
|
import { ChainItemType } from "../../types";
|
||||||
import color from "../../styles/color";
|
import color from "../../styles/color";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { ChainItem } from "./chain-item";
|
import { ChainItem } from "./chain-item";
|
||||||
@ -8,6 +8,7 @@ interface Props {
|
|||||||
allChecked: boolean;
|
allChecked: boolean;
|
||||||
setAllChecked: Dispatch<SetStateAction<boolean>>;
|
setAllChecked: Dispatch<SetStateAction<boolean>>;
|
||||||
chainList: ChainItemType[];
|
chainList: ChainItemType[];
|
||||||
|
disabledChainList: ChainItemType[];
|
||||||
checkedItems: Set<unknown>;
|
checkedItems: Set<unknown>;
|
||||||
setCheckedItems: Dispatch<SetStateAction<Set<unknown>>>;
|
setCheckedItems: Dispatch<SetStateAction<Set<unknown>>>;
|
||||||
}
|
}
|
||||||
@ -17,6 +18,7 @@ export const ChainList: FunctionComponent<Props> = (props) => {
|
|||||||
allChecked,
|
allChecked,
|
||||||
setAllChecked,
|
setAllChecked,
|
||||||
chainList,
|
chainList,
|
||||||
|
disabledChainList,
|
||||||
checkedItems,
|
checkedItems,
|
||||||
setCheckedItems,
|
setCheckedItems,
|
||||||
} = props;
|
} = props;
|
||||||
@ -59,6 +61,15 @@ export const ChainList: FunctionComponent<Props> = (props) => {
|
|||||||
checkedItems={checkedItems}
|
checkedItems={checkedItems}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
{disabledChainList.map((chainItem) => (
|
||||||
|
<ChainItem
|
||||||
|
key={chainItem.address}
|
||||||
|
chainItem={chainItem}
|
||||||
|
checkedItemHandler={checkedItemHandler}
|
||||||
|
checkedItems={checkedItems}
|
||||||
|
disabled={true}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</ChainContainer>
|
</ChainContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -72,35 +83,3 @@ export const ChainContainer = styled.div`
|
|||||||
|
|
||||||
background-color: ${(props) => props.color};
|
background-color: ${(props) => props.color};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const ChainItemContainer = styled.div<{
|
|
||||||
isLoading: boolean;
|
|
||||||
checked?: boolean;
|
|
||||||
}>`
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
gap: 1rem;
|
|
||||||
|
|
||||||
padding: 1.5rem;
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: ${(props) => (props.isLoading ? null : color.grey["700"])};
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
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;
|
|
||||||
gap: 0.5rem;
|
|
||||||
`;
|
|
||||||
|
@ -10,12 +10,13 @@ import {
|
|||||||
WalletType,
|
WalletType,
|
||||||
} from "../../constants/wallet";
|
} from "../../constants/wallet";
|
||||||
import { getKeplrFromWindow, KeplrWallet } from "../../wallets";
|
import { getKeplrFromWindow, KeplrWallet } from "../../wallets";
|
||||||
import { loginWithTwitter } from "../../repository";
|
import { loginWithTwitter } from "../../queries";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
wallet: WalletType;
|
wallet: WalletType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Todo: Wallet 관련된 부분을 Context로 빼는 부분
|
||||||
export const WalletItem: FunctionComponent<Props> = (props: Props) => {
|
export const WalletItem: FunctionComponent<Props> = (props: Props) => {
|
||||||
const { wallet } = props;
|
const { wallet } = props;
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ export const MainChainId = "osmo-test-4";
|
|||||||
export const RPC_URL = "https://rpc.testnet.osmosis.zone";
|
export const RPC_URL = "https://rpc.testnet.osmosis.zone";
|
||||||
export const REST_URL = "https://lcd.testnet.osmosis.zone";
|
export const REST_URL = "https://lcd.testnet.osmosis.zone";
|
||||||
|
|
||||||
|
// TODO: .evn에 없으면 디폴트값 설정
|
||||||
export const REGISTRAR_ADDRESS =
|
export const REGISTRAR_ADDRESS =
|
||||||
"osmo1npn97g7hsgqlp70rw8nhd7c7vyvkukv9x0n25sn4fk5mgcjlz4gq9zlgf3";
|
"osmo1npn97g7hsgqlp70rw8nhd7c7vyvkukv9x0n25sn4fk5mgcjlz4gq9zlgf3";
|
||||||
export const RESOLVER_ADDRESS =
|
export const RESOLVER_ADDRESS =
|
||||||
|
@ -1,51 +1,8 @@
|
|||||||
import { request } from "../utils/url";
|
import { CosmwasmExecuteMessageResult } from "../types";
|
||||||
import {
|
|
||||||
REGISTRAR_ADDRESS,
|
|
||||||
RESOLVER_ADDRESS,
|
|
||||||
REST_URL,
|
|
||||||
} from "../constants/icns";
|
|
||||||
import { Buffer } from "buffer/";
|
|
||||||
import {
|
|
||||||
AddressesQueryResponse,
|
|
||||||
CosmwasmExecuteMessageResult,
|
|
||||||
NameByTwitterIdQueryResponse,
|
|
||||||
QueryError,
|
|
||||||
} from "../types";
|
|
||||||
import { makeCosmwasmExecMsg } from "../wallets";
|
import { makeCosmwasmExecMsg } from "../wallets";
|
||||||
|
import { REGISTRAR_ADDRESS, RESOLVER_ADDRESS } from "../constants/icns";
|
||||||
import { ContractFee } from "../constants/wallet";
|
import { ContractFee } from "../constants/wallet";
|
||||||
|
|
||||||
const getCosmwasmQueryUrl = (contractAddress: string, queryMsg: string) =>
|
|
||||||
`${REST_URL}/cosmwasm/wasm/v1/contract/${contractAddress}/smart/${queryMsg}`;
|
|
||||||
|
|
||||||
export const queryRegisteredTwitterId = async (
|
|
||||||
twitterId: string,
|
|
||||||
): Promise<NameByTwitterIdQueryResponse | QueryError> => {
|
|
||||||
const msg = {
|
|
||||||
name_by_twitter_id: { twitter_id: twitterId },
|
|
||||||
};
|
|
||||||
return request<NameByTwitterIdQueryResponse>(
|
|
||||||
getCosmwasmQueryUrl(
|
|
||||||
REGISTRAR_ADDRESS,
|
|
||||||
Buffer.from(JSON.stringify(msg)).toString("base64"),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const queryAddressesFromTwitterName = async (
|
|
||||||
twitterUsername: string,
|
|
||||||
): Promise<AddressesQueryResponse> => {
|
|
||||||
const msg = {
|
|
||||||
addresses: { name: twitterUsername },
|
|
||||||
};
|
|
||||||
|
|
||||||
return request<AddressesQueryResponse>(
|
|
||||||
getCosmwasmQueryUrl(
|
|
||||||
RESOLVER_ADDRESS,
|
|
||||||
Buffer.from(JSON.stringify(msg)).toString("base64"),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const makeClaimMessage = (
|
export const makeClaimMessage = (
|
||||||
senderAddress: string,
|
senderAddress: string,
|
||||||
twitterUserName: string,
|
twitterUserName: string,
|
1
messages/index.ts
Normal file
1
messages/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from "./icns";
|
@ -32,6 +32,8 @@ export default function CompletePage() {
|
|||||||
const result = await txTracer.traceTx(Buffer.from(txHash, "hex"));
|
const result = await txTracer.traceTx(Buffer.from(txHash, "hex"));
|
||||||
|
|
||||||
console.log(result);
|
console.log(result);
|
||||||
|
|
||||||
|
// Todo rsult => 확인 후에 확인
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -2,8 +2,12 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { ChainItemType, TwitterProfileType } from "../../types";
|
import {
|
||||||
import { checkTwitterAuthQueryParameter, request } from "../../utils/url";
|
ChainItemType,
|
||||||
|
RegisteredAddresses,
|
||||||
|
TwitterProfileType,
|
||||||
|
} from "../../types";
|
||||||
|
import { checkTwitterAuthQueryParameter } from "../../utils/url";
|
||||||
|
|
||||||
// Styles
|
// Styles
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
@ -20,7 +24,6 @@ import { useRouter } from "next/router";
|
|||||||
import {
|
import {
|
||||||
getKeplrFromWindow,
|
getKeplrFromWindow,
|
||||||
KeplrWallet,
|
KeplrWallet,
|
||||||
makeCosmwasmExecMsg,
|
|
||||||
sendMsgs,
|
sendMsgs,
|
||||||
simulateMsgs,
|
simulateMsgs,
|
||||||
} from "../../wallets";
|
} from "../../wallets";
|
||||||
@ -29,26 +32,20 @@ import { ChainIdHelper } from "@keplr-wallet/cosmos";
|
|||||||
import AllChainsIcon from "../../public/images/svg/all-chains-icon.svg";
|
import AllChainsIcon from "../../public/images/svg/all-chains-icon.svg";
|
||||||
import { AllChainsItem } from "../../components/chain-list/all-chains-item";
|
import { AllChainsItem } from "../../components/chain-list/all-chains-item";
|
||||||
import { SearchInput } from "../../components/search-input";
|
import { SearchInput } from "../../components/search-input";
|
||||||
import {
|
import { MainChainId, RESOLVER_ADDRESS, REST_URL } from "../../constants/icns";
|
||||||
MainChainId,
|
|
||||||
REGISTRAR_ADDRESS,
|
|
||||||
RESOLVER_ADDRESS,
|
|
||||||
REST_URL,
|
|
||||||
} from "../../constants/icns";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
fetchTwitterInfo,
|
fetchTwitterInfo,
|
||||||
makeClaimMessage,
|
|
||||||
makeSetRecordMessage,
|
|
||||||
queryAddressesFromTwitterName,
|
queryAddressesFromTwitterName,
|
||||||
queryRegisteredTwitterId,
|
queryRegisteredTwitterId,
|
||||||
verifyTwitterAccount,
|
verifyTwitterAccount,
|
||||||
} from "../../repository";
|
} from "../../queries";
|
||||||
import { ErrorHandler } from "../../utils/error";
|
import { ErrorHandler } from "../../utils/error";
|
||||||
import {
|
import {
|
||||||
KEPLR_NOT_FOUND_ERROR,
|
KEPLR_NOT_FOUND_ERROR,
|
||||||
TWITTER_LOGIN_ERROR,
|
TWITTER_LOGIN_ERROR,
|
||||||
} from "../../constants/error-message";
|
} from "../../constants/error-message";
|
||||||
|
import { makeClaimMessage, makeSetRecordMessage } from "../../messages";
|
||||||
|
|
||||||
export default function VerificationPage() {
|
export default function VerificationPage() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -57,13 +54,19 @@ export default function VerificationPage() {
|
|||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
|
||||||
const [wallet, setWallet] = useState<KeplrWallet>();
|
const [wallet, setWallet] = useState<KeplrWallet>();
|
||||||
const [allChains, setAllChains] = useState<ChainItemType>();
|
|
||||||
const [chainList, setChainList] = useState<ChainItemType[]>([]);
|
const [chainList, setChainList] = useState<ChainItemType[]>([]);
|
||||||
const [registeredAddressList, setRegisteredAddressList] = useState<string[]>(
|
const [disabledChainList, setDisabledChainList] = useState<ChainItemType[]>(
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
const [checkedItems, setCheckedItems] = useState(new Set());
|
const [registeredChainList, setRegisteredChainList] = useState<
|
||||||
|
RegisteredAddresses[]
|
||||||
|
>([]);
|
||||||
|
|
||||||
|
const [allChains, setAllChains] = useState<ChainItemType>();
|
||||||
const [allChecked, setAllChecked] = useState(false);
|
const [allChecked, setAllChecked] = useState(false);
|
||||||
|
const [checkedItems, setCheckedItems] = useState(new Set());
|
||||||
|
|
||||||
const [searchValue, setSearchValue] = useState("");
|
const [searchValue, setSearchValue] = useState("");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -80,7 +83,7 @@ export default function VerificationPage() {
|
|||||||
// Fetch Twitter Profile
|
// Fetch Twitter Profile
|
||||||
const twitterInfo = await fetchTwitterInfo(state, code);
|
const twitterInfo = await fetchTwitterInfo(state, code);
|
||||||
|
|
||||||
// check registered
|
// contract check registered
|
||||||
const registeredQueryResponse = await queryRegisteredTwitterId(
|
const registeredQueryResponse = await queryRegisteredTwitterId(
|
||||||
twitterInfo.id,
|
twitterInfo.id,
|
||||||
);
|
);
|
||||||
@ -95,11 +98,7 @@ export default function VerificationPage() {
|
|||||||
registeredQueryResponse.data.name,
|
registeredQueryResponse.data.name,
|
||||||
);
|
);
|
||||||
|
|
||||||
setRegisteredAddressList(
|
setRegisteredChainList(addressesQueryResponse.data.addresses);
|
||||||
addressesQueryResponse.data.addresses.map(
|
|
||||||
(address) => address.address,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof Error && error.message === TWITTER_LOGIN_ERROR) {
|
if (error instanceof Error && error.message === TWITTER_LOGIN_ERROR) {
|
||||||
@ -117,89 +116,96 @@ export default function VerificationPage() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// After Wallet Initialize
|
const disabledChainList = chainList.filter((chain) => {
|
||||||
if (wallet) {
|
for (const registeredChain of registeredChainList) {
|
||||||
fetchChainList();
|
if (
|
||||||
}
|
chain.prefix === registeredChain.bech32_prefix &&
|
||||||
}, [wallet]);
|
chain.address === registeredChain.address
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
return false;
|
||||||
// To check registered chain
|
|
||||||
const filteredChainList = chainList.filter((chain) => {
|
|
||||||
return registeredAddressList.includes(chain.address);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
setCheckedItems(new Set(filteredChainList));
|
const filteredChainList = chainList.filter(
|
||||||
}, [registeredAddressList]);
|
(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);
|
||||||
|
}, [registeredChainList]);
|
||||||
|
|
||||||
const initWallet = async () => {
|
const initWallet = async () => {
|
||||||
const keplr = await getKeplrFromWindow();
|
const keplr = await getKeplrFromWindow();
|
||||||
|
|
||||||
if (keplr) {
|
if (keplr) {
|
||||||
const keplrWallet = new KeplrWallet(keplr);
|
const keplrWallet = new KeplrWallet(keplr);
|
||||||
|
|
||||||
|
await fetchChainList(keplrWallet);
|
||||||
setWallet(keplrWallet);
|
setWallet(keplrWallet);
|
||||||
} else {
|
} else {
|
||||||
ErrorHandler(KEPLR_NOT_FOUND_ERROR);
|
ErrorHandler(KEPLR_NOT_FOUND_ERROR);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchChainList = async () => {
|
const fetchChainList = async (wallet: KeplrWallet) => {
|
||||||
if (wallet) {
|
const chainIds = (await wallet.getChainInfosWithoutEndpoints()).map(
|
||||||
const chainIds = (await wallet.getChainInfosWithoutEndpoints()).map(
|
(c) => c.chainId,
|
||||||
(c) => c.chainId,
|
);
|
||||||
);
|
const chainKeys = await Promise.all(
|
||||||
const chainKeys = await Promise.all(
|
chainIds.map((chainId) => wallet.getKey(chainId)),
|
||||||
chainIds.map((chainId) => wallet.getKey(chainId)),
|
);
|
||||||
);
|
|
||||||
|
|
||||||
const chainInfos = (await wallet.getChainInfosWithoutEndpoints()).map(
|
const chainInfos = (await wallet.getChainInfosWithoutEndpoints()).map(
|
||||||
(chainInfo) => {
|
(chainInfo) => {
|
||||||
return {
|
return {
|
||||||
chainId: chainInfo.chainId,
|
chainId: chainInfo.chainId,
|
||||||
chainName: chainInfo.chainName,
|
chainName: chainInfo.chainName,
|
||||||
prefix: chainInfo.bech32Config.bech32PrefixAccAddr,
|
prefix: chainInfo.bech32Config.bech32PrefixAccAddr,
|
||||||
chainImageUrl: `https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/${
|
chainImageUrl: `https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/${
|
||||||
ChainIdHelper.parse(chainInfo.chainId).identifier
|
ChainIdHelper.parse(chainInfo.chainId).identifier
|
||||||
}/chain.png`,
|
}/chain.png`,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const chainArray = [];
|
const chainArray = [];
|
||||||
for (let i = 0; i < chainKeys.length; i++) {
|
for (let i = 0; i < chainKeys.length; i++) {
|
||||||
chainArray.push({
|
chainArray.push({
|
||||||
address: chainKeys[i].bech32Address,
|
address: chainKeys[i].bech32Address,
|
||||||
...chainInfos[i],
|
...chainInfos[i],
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove duplicated item
|
|
||||||
const filteredChainList = chainArray.filter((nextChain, index, self) => {
|
|
||||||
return (
|
|
||||||
index ===
|
|
||||||
self.findIndex((prevChain) => {
|
|
||||||
const isDuplicated = prevChain.prefix === nextChain.prefix;
|
|
||||||
|
|
||||||
if (isDuplicated && prevChain.chainName !== nextChain.chainName) {
|
|
||||||
console.log(
|
|
||||||
`${nextChain.chainName} has been deleted due to a duplicate name with ${prevChain.chainName}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return isDuplicated;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
setAllChains({
|
|
||||||
chainId: "all chains",
|
|
||||||
prefix: `all chains(${filteredChainList.length})`,
|
|
||||||
address: chainInfos.map((chainInfo) => chainInfo.chainName).join(", "),
|
|
||||||
chainImageUrl: AllChainsIcon,
|
|
||||||
});
|
|
||||||
|
|
||||||
setChainList(filteredChainList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove duplicated item
|
||||||
|
const filteredChainList = chainArray.filter((nextChain, index, self) => {
|
||||||
|
return (
|
||||||
|
index ===
|
||||||
|
self.findIndex((prevChain) => {
|
||||||
|
const isDuplicated = prevChain.prefix === nextChain.prefix;
|
||||||
|
|
||||||
|
if (isDuplicated && prevChain.chainName !== nextChain.chainName) {
|
||||||
|
console.log(
|
||||||
|
`${nextChain.chainName} has been deleted due to a duplicate name with ${prevChain.chainName}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isDuplicated;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
setChainList(filteredChainList);
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkAdr36 = async () => {
|
const checkAdr36 = async () => {
|
||||||
@ -224,7 +230,6 @@ export default function VerificationPage() {
|
|||||||
const { state, code } = checkTwitterAuthQueryParameter(
|
const { state, code } = checkTwitterAuthQueryParameter(
|
||||||
window.location.search,
|
window.location.search,
|
||||||
);
|
);
|
||||||
|
|
||||||
const twitterInfo = await fetchTwitterInfo(state, code);
|
const twitterInfo = await fetchTwitterInfo(state, code);
|
||||||
|
|
||||||
const adr36Infos = await checkAdr36();
|
const adr36Infos = await checkAdr36();
|
||||||
@ -336,6 +341,12 @@ export default function VerificationPage() {
|
|||||||
chain.address.includes(searchValue) ||
|
chain.address.includes(searchValue) ||
|
||||||
chain.prefix.includes(searchValue),
|
chain.prefix.includes(searchValue),
|
||||||
)}
|
)}
|
||||||
|
disabledChainList={disabledChainList.filter(
|
||||||
|
(chain) =>
|
||||||
|
chain.chainId.includes(searchValue) ||
|
||||||
|
chain.address.includes(searchValue) ||
|
||||||
|
chain.prefix.includes(searchValue),
|
||||||
|
)}
|
||||||
checkedItems={checkedItems}
|
checkedItems={checkedItems}
|
||||||
setCheckedItems={setCheckedItems}
|
setCheckedItems={setCheckedItems}
|
||||||
/>
|
/>
|
||||||
|
44
queries/icns.ts
Normal file
44
queries/icns.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { request } from "../utils/url";
|
||||||
|
import {
|
||||||
|
REGISTRAR_ADDRESS,
|
||||||
|
RESOLVER_ADDRESS,
|
||||||
|
REST_URL,
|
||||||
|
} from "../constants/icns";
|
||||||
|
import { Buffer } from "buffer/";
|
||||||
|
import {
|
||||||
|
AddressesQueryResponse,
|
||||||
|
NameByTwitterIdQueryResponse,
|
||||||
|
QueryError,
|
||||||
|
} from "../types";
|
||||||
|
|
||||||
|
const getCosmwasmQueryUrl = (contractAddress: string, queryMsg: string) =>
|
||||||
|
`${REST_URL}/cosmwasm/wasm/v1/contract/${contractAddress}/smart/${queryMsg}`;
|
||||||
|
|
||||||
|
export const queryRegisteredTwitterId = async (
|
||||||
|
twitterId: string,
|
||||||
|
): Promise<NameByTwitterIdQueryResponse | QueryError> => {
|
||||||
|
const msg = {
|
||||||
|
name_by_twitter_id: { twitter_id: twitterId },
|
||||||
|
};
|
||||||
|
return request<NameByTwitterIdQueryResponse>(
|
||||||
|
getCosmwasmQueryUrl(
|
||||||
|
REGISTRAR_ADDRESS,
|
||||||
|
Buffer.from(JSON.stringify(msg)).toString("base64"),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const queryAddressesFromTwitterName = async (
|
||||||
|
twitterUsername: string,
|
||||||
|
): Promise<AddressesQueryResponse> => {
|
||||||
|
const msg = {
|
||||||
|
addresses: { name: twitterUsername },
|
||||||
|
};
|
||||||
|
|
||||||
|
return request<AddressesQueryResponse>(
|
||||||
|
getCosmwasmQueryUrl(
|
||||||
|
RESOLVER_ADDRESS,
|
||||||
|
Buffer.from(JSON.stringify(msg)).toString("base64"),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
@ -6,9 +6,9 @@ import {
|
|||||||
import { request } from "../utils/url";
|
import { request } from "../utils/url";
|
||||||
|
|
||||||
export const loginWithTwitter = async () => {
|
export const loginWithTwitter = async () => {
|
||||||
const { authUrl }: TwitterAuthUrlResponse = await (
|
const { authUrl } = await request<TwitterAuthUrlResponse>(
|
||||||
await fetch("/api/twitter-auth-url")
|
"/api/twitter-auth-url",
|
||||||
).json();
|
);
|
||||||
|
|
||||||
window.location.href = authUrl;
|
window.location.href = authUrl;
|
||||||
};
|
};
|
@ -1,5 +1,6 @@
|
|||||||
export interface ChainItemType {
|
export interface ChainItemType {
|
||||||
chainId: string;
|
chainId: string;
|
||||||
|
chainName: string;
|
||||||
prefix: string;
|
prefix: string;
|
||||||
chainImageUrl: string;
|
chainImageUrl: string;
|
||||||
address: string;
|
address: string;
|
||||||
|
Loading…
Reference in New Issue
Block a user