From 8897eac973968c26926c5f4f81480e96fa15c596 Mon Sep 17 00:00:00 2001 From: HeesungB Date: Wed, 14 Dec 2022 20:36:08 +0900 Subject: [PATCH] [WIP] : ICNS Query --- components/connect-wallet-modal/modal.tsx | 1 + constants/icns.ts | 2 +- pages/verification/index.tsx | 75 ++++++++++++++++++----- repository/icns.ts | 43 +++++++++++++ repository/index.ts | 1 + types/api-response.ts | 22 +++++++ types/index.ts | 1 + types/twitter.ts | 5 ++ 8 files changed, 135 insertions(+), 15 deletions(-) create mode 100644 repository/icns.ts create mode 100644 types/twitter.ts diff --git a/components/connect-wallet-modal/modal.tsx b/components/connect-wallet-modal/modal.tsx index 8797812..e346d65 100644 --- a/components/connect-wallet-modal/modal.tsx +++ b/components/connect-wallet-modal/modal.tsx @@ -17,6 +17,7 @@ export const ConnectWalletModal: FunctionComponent = (props) => { (); + const [twitterAuthInfo, setTwitterAuthInfo] = useState(); const [isLoading, setIsLoading] = useState(true); const [wallet, setWallet] = useState(); const [allChains, setAllChains] = useState(); const [chainList, setChainList] = useState([]); + const [registeredAddressList, setRegisteredAddressList] = useState( + [], + ); const [checkedItems, setCheckedItems] = useState(new Set()); const [allChecked, setAllChecked] = useState(false); const [searchValue, setSearchValue] = useState(""); @@ -81,14 +89,38 @@ export default function VerificationPage() { const { state, code } = fetchUrlQueryParameter(); - // Fetch Twitter Profile - const twitterInfo = await fetchTwitterInfo(state, code); - setTwitterAuthInfo(twitterInfo); + try { + // Initialize Wallet + await initWallet(); - // Initialize Wallet - await initWallet(); + // Fetch Twitter Profile + const twitterInfo = await fetchTwitterInfo(state, code); - setIsLoading(false); + const registeredQueryResponse = await queryRegisteredTwitterId( + twitterInfo.id, + ); + + setTwitterAuthInfo({ + ...twitterInfo, + isRegistered: "data" in registeredQueryResponse, + }); + + if ("data" in registeredQueryResponse) { + const addressesQueryResponse = await queryAddressesFromTwitterName( + registeredQueryResponse.data.name, + ); + + setRegisteredAddressList( + addressesQueryResponse.data.addresses.map( + (address) => address.address, + ), + ); + } + } catch (e) { + console.log(e); + } finally { + setIsLoading(false); + } } }; @@ -111,6 +143,14 @@ export default function VerificationPage() { } }, [wallet]); + useEffect(() => { + const filteredChainList = chainList.filter((chain) => { + return registeredAddressList.includes(chain.address); + }); + + setCheckedItems(new Set(filteredChainList)); + }, [registeredAddressList]); + const fetchChainList = async () => { if (wallet) { const chainIds = (await wallet.getChainInfosWithoutEndpoints()).map( @@ -193,9 +233,9 @@ export default function VerificationPage() { if (twitterAuthInfo && wallet) { const key = await wallet.getKey(MainChainId); - const chainIds = Array.from(checkedItems).map( - (chain) => (chain as ChainItemType).chainId, - ); + const chainIds = Array.from(checkedItems).map((chain) => { + return (chain as ChainItemType).chainId; + }); return await wallet.signICNSAdr36( MainChainId, @@ -264,13 +304,20 @@ export default function VerificationPage() { ); }); - const aminoMsgs = [registerMsg.amino]; - const protoMsgs = [registerMsg.proto]; + const aminoMsgs = twitterAuthInfo?.isRegistered + ? [] + : [registerMsg.amino]; + const protoMsgs = twitterAuthInfo?.isRegistered + ? [] + : [registerMsg.proto]; + for (const addressMsg of addressMsgs) { aminoMsgs.push(addressMsg.amino); protoMsgs.push(addressMsg.proto); } + console.log(aminoMsgs); + const chainInfo = { chainId: MainChainId, rest: REST_URL, diff --git a/repository/icns.ts b/repository/icns.ts new file mode 100644 index 0000000..cd51b39 --- /dev/null +++ b/repository/icns.ts @@ -0,0 +1,43 @@ +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 => { + const msg = { + name_by_twitter_id: { twitter_id: twitterId }, + }; + return request( + getCosmwasmQueryUrl( + REGISTRAR_ADDRESS, + Buffer.from(JSON.stringify(msg)).toString("base64"), + ), + ); +}; + +export const queryAddressesFromTwitterName = async ( + twitterUsername: string, +): Promise => { + const msg = { + addresses: { name: twitterUsername }, + }; + return request( + getCosmwasmQueryUrl( + RESOLVER_ADDRESS, + Buffer.from(JSON.stringify(msg)).toString("base64"), + ), + ); +}; diff --git a/repository/index.ts b/repository/index.ts index 5517f2d..186b3f4 100644 --- a/repository/index.ts +++ b/repository/index.ts @@ -1 +1,2 @@ export * from "./twitter"; +export * from "./icns"; diff --git a/types/api-response.ts b/types/api-response.ts index 0be5888..19f9117 100644 --- a/types/api-response.ts +++ b/types/api-response.ts @@ -37,3 +37,25 @@ export interface IcnsVerificationResponse { } )[]; } + +export interface NameByTwitterIdQueryResponse { + data: { + name: string; + }; +} + +export interface AddressesQueryResponse { + data: { + addresses: RegisteredAddresses[]; + }; +} + +export interface RegisteredAddresses { + address: string; + bech32_prefix: string; +} + +export interface QueryError { + code: number; + message: string; +} diff --git a/types/index.ts b/types/index.ts index 6656919..7de37b7 100644 --- a/types/index.ts +++ b/types/index.ts @@ -2,3 +2,4 @@ export * from "./width-height-props"; export * from "./api-response"; export * from "./chain-item-type"; export * from "./msg"; +export * from "./twitter"; diff --git a/types/twitter.ts b/types/twitter.ts new file mode 100644 index 0000000..3241069 --- /dev/null +++ b/types/twitter.ts @@ -0,0 +1,5 @@ +import { TwitterAuthInfoResponse } from "./api-response"; + +export interface TwitterProfileType extends TwitterAuthInfoResponse { + isRegistered: boolean; +}