From 75d50bbe891129f676e1ed2692f23adf3c74ad88 Mon Sep 17 00:00:00 2001 From: HeesungB Date: Wed, 14 Dec 2022 16:52:05 +0900 Subject: [PATCH] Refactor repository --- .../connect-wallet-modal/wallet-item.tsx | 11 +- constants/icns.ts | 2 + constants/twitter.ts | 10 -- constants/wallet.ts | 8 +- pages/complete/index.tsx | 24 ++++ pages/verification/index.tsx | 124 +++++++++++------- repository/icns.ts | 0 repository/index.ts | 1 + repository/twitter.ts | 21 +++ 9 files changed, 136 insertions(+), 65 deletions(-) create mode 100644 repository/icns.ts create mode 100644 repository/index.ts create mode 100644 repository/twitter.ts diff --git a/components/connect-wallet-modal/wallet-item.tsx b/components/connect-wallet-modal/wallet-item.tsx index 13885b1..65f08bd 100644 --- a/components/connect-wallet-modal/wallet-item.tsx +++ b/components/connect-wallet-modal/wallet-item.tsx @@ -4,9 +4,13 @@ import color from "../../styles/color"; import { Flex1 } from "../../styles/flex-1"; import styled from "styled-components"; import Image from "next/image"; -import { SELECTED_WALLET_KEY, WalletType } from "../../constants/wallet"; +import { + SELECTED_WALLET_KEY, + WALLET_INSTALL_URL, + WalletType, +} from "../../constants/wallet"; import { getKeplrFromWindow, KeplrWallet } from "../../wallets"; -import { loginWithTwitter } from "../../constants/twitter"; +import { loginWithTwitter } from "../../repository"; interface Props { wallet: WalletType; @@ -32,8 +36,7 @@ export const WalletItem: FunctionComponent = (props: Props) => { const keplr = await getKeplrFromWindow(); if (keplr === undefined) { - window.location.href = - "https://chrome.google.com/webstore/detail/keplr/dmkamcknogkgcdfhhbddcghachkejeap"; + window.location.href = WALLET_INSTALL_URL; } if (keplr) { diff --git a/constants/icns.ts b/constants/icns.ts index b708260..7043738 100644 --- a/constants/icns.ts +++ b/constants/icns.ts @@ -1,3 +1,5 @@ +export const MainChainId = "osmo-test-4"; + export const RPC_URL = ""; export const REST_URL = "https://lcd.testnet.osmosis.zone"; diff --git a/constants/twitter.ts b/constants/twitter.ts index 0b4d16f..9f91183 100644 --- a/constants/twitter.ts +++ b/constants/twitter.ts @@ -1,5 +1,3 @@ -import { TwitterAuthUrlResponse } from "../types"; - export const twitterOAuthBaseUrl = "https://twitter.com/i/oauth2/authorize"; export const twitterOAuthScopes = [ @@ -9,11 +7,3 @@ export const twitterOAuthScopes = [ ]; export const twitterApiBaseUrl = "https://api.twitter.com/2"; - -export const loginWithTwitter = async () => { - const { authUrl }: TwitterAuthUrlResponse = await ( - await fetch("/api/twitter-auth-url") - ).json(); - - window.location.href = authUrl; -}; diff --git a/constants/wallet.ts b/constants/wallet.ts index ed04ff2..64822a8 100644 --- a/constants/wallet.ts +++ b/constants/wallet.ts @@ -3,8 +3,9 @@ import { StaticImageData } from "next/image"; import KeplrIcon from "../public/images/svg/keplr-icon.svg"; import CosmostationIcon from "../public/images/svg/cosmostation-icon.svg"; +export const WALLET_INSTALL_URL = + "https://chrome.google.com/webstore/detail/keplr/dmkamcknogkgcdfhhbddcghachkejeap"; export const SELECTED_WALLET_KEY = "SELECTED_WALLET_KEY"; -export const MainChainId = "osmo-test-4"; export type WalletName = "Keplr" | "Cosmostation"; export interface WalletType { @@ -25,3 +26,8 @@ export const WalletList: WalletType[] = [ isReady: false, }, ]; + +export const ContractFee = { + denom: "uosmo", + amount: "500000", +}; diff --git a/pages/complete/index.tsx b/pages/complete/index.tsx index d34c78c..6ebbc7f 100644 --- a/pages/complete/index.tsx +++ b/pages/complete/index.tsx @@ -8,8 +8,32 @@ import color from "../../styles/color"; import AlertCircleOutlineIcon from "../../public/images/svg/alert-circle-outline.svg"; import TwitterIcon from "../../public/images/svg/twitter-icon.svg"; +import { useRouter } from "next/router"; +import { useEffect } from "react"; +import { TendermintTxTracer } from "@keplr-wallet/cosmos"; export default function CompletePage() { + const router = useRouter(); + + useEffect(() => { + const { txHash } = router.query; + + if (txHash) { + traceTX(txHash as string); + } + }, []); + + const traceTX = async (txHash: string) => { + const txTracer = new TendermintTxTracer( + "https://rpc.testnet.osmosis.zone", + "/websocket", + ); + + const result = await txTracer.traceTx(Buffer.from(txHash, "hex")); + + console.log(result); + }; + return ( diff --git a/pages/verification/index.tsx b/pages/verification/index.tsx index 8c510c0..98988d3 100644 --- a/pages/verification/index.tsx +++ b/pages/verification/index.tsx @@ -21,11 +21,12 @@ import { PrimaryButton } from "../../components/primary-button"; import { TwitterProfile } from "../../components/twitter-profile"; import { ChainList } from "../../components/chain-list"; import { useRouter } from "next/router"; -import { MainChainId } from "../../constants/wallet"; +import { ContractFee } from "../../constants/wallet"; import { getKeplrFromWindow, KeplrWallet, makeCosmwasmExecMsg, + sendMsgs, simulateMsgs, } from "../../wallets"; import { ChainIdHelper } from "@keplr-wallet/cosmos"; @@ -34,11 +35,14 @@ 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 { + MainChainId, REGISTRAR_ADDRESS, RESOLVER_ADDRESS, REST_URL, } from "../../constants/icns"; +import { fetchTwitterInfo } from "../../repository"; + export default function VerificationPage() { const router = useRouter(); const [twitterAuthInfo, setTwitterAuthInfo] = @@ -53,39 +57,44 @@ export default function VerificationPage() { const [allChecked, setAllChecked] = useState(false); const [searchValue, setSearchValue] = useState(""); + const fetchUrlQueryParameter = (): { state: string; code: string } => { + // Twitter state, auth code check + const [, state, code] = + window.location.search.match( + /^(?=.*state=([^&]+)|)(?=.*code=([^&]+)|).+$/, + ) || []; + + return { + state, + code, + }; + }; + useEffect(() => { - const handleVerification = async () => { + const init = async () => { if (window.location.search) { + // Twitter Login Error Check if (window.location.search.match("error")) { await router.push("/"); return; } - const twitterInfo = await fetchTwitterInfo(); + const { state, code } = fetchUrlQueryParameter(); + + // Fetch Twitter Profile + const twitterInfo = await fetchTwitterInfo(state, code); setTwitterAuthInfo(twitterInfo); + // Initialize Wallet await initWallet(); setIsLoading(false); } }; - handleVerification(); + init(); }, []); - const fetchTwitterInfo = async (): Promise => { - const [, state, code] = - window.location.search.match( - /^(?=.*state=([^&]+)|)(?=.*code=([^&]+)|).+$/, - ) || []; - - const newTwitterAuthInfo = await request( - `/api/twitter-auth-info?state=${state}&code=${code}`, - ); - - return newTwitterAuthInfo; - }; - const initWallet = async () => { const keplr = await getKeplrFromWindow(); @@ -96,27 +105,12 @@ export default function VerificationPage() { }; useEffect(() => { + // After Wallet Initialize if (wallet) { - fetchAllChains(); fetchChainList(); } }, [wallet]); - const fetchAllChains = async () => { - if (wallet) { - const chainNames = (await wallet.getChainInfosWithoutEndpoints()).map( - (chainInfo) => chainInfo.chainName, - ); - - setAllChains({ - chainId: "all chains", - prefix: `all chains(${chainNames.length})`, - address: chainNames.join(", "), - chainImageUrl: AllChainsIcon, - }); - } - }; - const fetchChainList = async () => { if (wallet) { const chainIds = (await wallet.getChainInfosWithoutEndpoints()).map( @@ -130,6 +124,7 @@ export default function VerificationPage() { (chainInfo) => { return { chainId: chainInfo.chainId, + chainName: chainInfo.chainName, prefix: chainInfo.bech32Config.bech32PrefixAccAddr, chainImageUrl: `https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/${ ChainIdHelper.parse(chainInfo.chainId).identifier @@ -138,7 +133,7 @@ export default function VerificationPage() { }, ); - const chainArray: ChainItemType[] = []; + const chainArray = []; for (let i = 0; i < chainKeys.length; i++) { chainArray.push({ address: chainKeys[i].bech32Address, @@ -147,8 +142,28 @@ export default function VerificationPage() { } // remove duplicated item - const filteredChainList = chainArray.filter((chain, index, self) => { - return index === self.findIndex((t) => chain.prefix === t.prefix); + 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); @@ -159,7 +174,7 @@ export default function VerificationPage() { if (wallet) { const key = await wallet.getKey(MainChainId); - const icnsVerificationList = ( + return ( await request("/api/icns-verification", { method: "post", headers: { @@ -171,8 +186,6 @@ export default function VerificationPage() { }), }) ).verificationList; - - return icnsVerificationList; } }; @@ -184,20 +197,19 @@ export default function VerificationPage() { (chain) => (chain as ChainItemType).chainId, ); - const adr36Infos = await wallet.signICNSAdr36( + return await wallet.signICNSAdr36( MainChainId, RESOLVER_ADDRESS, key.bech32Address, twitterAuthInfo.username, chainIds, ); - - return adr36Infos; } }; const onClickRegistration = async () => { - const twitterInfo = await fetchTwitterInfo(); + const { state, code } = fetchUrlQueryParameter(); + const twitterInfo = await fetchTwitterInfo(state, code); const adr36Infos = await checkAdr36(); @@ -228,12 +240,7 @@ export default function VerificationPage() { }), }, }, - [ - { - denom: "uosmo", - amount: "500000", - }, - ], + [ContractFee], ); const addressMsgs = adr36Infos.map((adr36Info) => { @@ -280,7 +287,24 @@ export default function VerificationPage() { }, ); - console.log("simulated", simulated); + const txHash = await sendMsgs( + wallet, + chainInfo, + key.bech32Address, + { + amino: aminoMsgs, + proto: protoMsgs, + }, + { + amount: [], + gas: Math.floor(simulated.gasUsed * 1.5).toString(), + }, + ); + + router.push({ + pathname: "complete", + query: { txHash: Buffer.from(txHash).toString("hex") }, + }); } }; diff --git a/repository/icns.ts b/repository/icns.ts new file mode 100644 index 0000000..e69de29 diff --git a/repository/index.ts b/repository/index.ts new file mode 100644 index 0000000..5517f2d --- /dev/null +++ b/repository/index.ts @@ -0,0 +1 @@ +export * from "./twitter"; diff --git a/repository/twitter.ts b/repository/twitter.ts new file mode 100644 index 0000000..6c141a4 --- /dev/null +++ b/repository/twitter.ts @@ -0,0 +1,21 @@ +import { TwitterAuthInfoResponse, TwitterAuthUrlResponse } from "../types"; +import { request } from "../utils/url"; + +export const loginWithTwitter = async () => { + const { authUrl }: TwitterAuthUrlResponse = await ( + await fetch("/api/twitter-auth-url") + ).json(); + + window.location.href = authUrl; +}; + +export const fetchTwitterInfo = async ( + state: string, + code: string, +): Promise => { + const newTwitterAuthInfo = await request( + `/api/twitter-auth-info?state=${state}&code=${code}`, + ); + + return newTwitterAuthInfo; +};