[WIP] Refactoring Logics
This commit is contained in:
parent
13de62028d
commit
7de3767d03
4
constants/error-message.ts
Normal file
4
constants/error-message.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export const TWITTER_LOGIN_ERROR = "Twitter login access denied";
|
||||
export const TWITTER_PROFILE_ERROR = "Twitter auth code is not valid";
|
||||
|
||||
export const KEPLR_NOT_FOUND_ERROR = "Can't fount window.keplr";
|
@ -2,14 +2,8 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
// Types
|
||||
import {
|
||||
ChainItemType,
|
||||
IcnsVerificationResponse,
|
||||
RegisteredAddresses,
|
||||
TwitterAuthInfoResponse,
|
||||
TwitterProfileType,
|
||||
} from "../../types";
|
||||
import { request } from "../../utils/url";
|
||||
import { ChainItemType, TwitterProfileType } from "../../types";
|
||||
import { checkTwitterAuthQueryParameter, request } from "../../utils/url";
|
||||
|
||||
// Styles
|
||||
import styled from "styled-components";
|
||||
@ -23,7 +17,6 @@ import { PrimaryButton } from "../../components/primary-button";
|
||||
import { TwitterProfile } from "../../components/twitter-profile";
|
||||
import { ChainList } from "../../components/chain-list";
|
||||
import { useRouter } from "next/router";
|
||||
import { ContractFee } from "../../constants/wallet";
|
||||
import {
|
||||
getKeplrFromWindow,
|
||||
KeplrWallet,
|
||||
@ -45,9 +38,17 @@ import {
|
||||
|
||||
import {
|
||||
fetchTwitterInfo,
|
||||
makeClaimMessage,
|
||||
makeSetRecordMessage,
|
||||
queryAddressesFromTwitterName,
|
||||
queryRegisteredTwitterId,
|
||||
verifyTwitterAccount,
|
||||
} from "../../repository";
|
||||
import { ErrorHandler } from "../../utils/error";
|
||||
import {
|
||||
KEPLR_NOT_FOUND_ERROR,
|
||||
TWITTER_LOGIN_ERROR,
|
||||
} from "../../constants/error-message";
|
||||
|
||||
export default function VerificationPage() {
|
||||
const router = useRouter();
|
||||
@ -65,37 +66,21 @@ 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 init = async () => {
|
||||
if (window.location.search) {
|
||||
// Twitter Login Error Check
|
||||
if (window.location.search.match("error")) {
|
||||
await router.push("/");
|
||||
return;
|
||||
}
|
||||
|
||||
const { state, code } = fetchUrlQueryParameter();
|
||||
|
||||
try {
|
||||
const { state, code } = checkTwitterAuthQueryParameter(
|
||||
window.location.search,
|
||||
);
|
||||
|
||||
// Initialize Wallet
|
||||
await initWallet();
|
||||
|
||||
// Fetch Twitter Profile
|
||||
const twitterInfo = await fetchTwitterInfo(state, code);
|
||||
|
||||
// check registered
|
||||
const registeredQueryResponse = await queryRegisteredTwitterId(
|
||||
twitterInfo.id,
|
||||
);
|
||||
@ -116,8 +101,12 @@ export default function VerificationPage() {
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.message === TWITTER_LOGIN_ERROR) {
|
||||
await router.push("/");
|
||||
}
|
||||
|
||||
console.error(error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
@ -127,15 +116,6 @@ export default function VerificationPage() {
|
||||
init();
|
||||
}, []);
|
||||
|
||||
const initWallet = async () => {
|
||||
const keplr = await getKeplrFromWindow();
|
||||
|
||||
if (keplr) {
|
||||
const keplrWallet = new KeplrWallet(keplr);
|
||||
setWallet(keplrWallet);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// After Wallet Initialize
|
||||
if (wallet) {
|
||||
@ -144,6 +124,7 @@ export default function VerificationPage() {
|
||||
}, [wallet]);
|
||||
|
||||
useEffect(() => {
|
||||
// To check registered chain
|
||||
const filteredChainList = chainList.filter((chain) => {
|
||||
return registeredAddressList.includes(chain.address);
|
||||
});
|
||||
@ -151,6 +132,17 @@ export default function VerificationPage() {
|
||||
setCheckedItems(new Set(filteredChainList));
|
||||
}, [registeredAddressList]);
|
||||
|
||||
const initWallet = async () => {
|
||||
const keplr = await getKeplrFromWindow();
|
||||
|
||||
if (keplr) {
|
||||
const keplrWallet = new KeplrWallet(keplr);
|
||||
setWallet(keplrWallet);
|
||||
} else {
|
||||
ErrorHandler(KEPLR_NOT_FOUND_ERROR);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchChainList = async () => {
|
||||
if (wallet) {
|
||||
const chainIds = (await wallet.getChainInfosWithoutEndpoints()).map(
|
||||
@ -210,25 +202,6 @@ export default function VerificationPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const verifyTwitterAccount = async (accessToken: string) => {
|
||||
if (wallet) {
|
||||
const key = await wallet.getKey(MainChainId);
|
||||
|
||||
return (
|
||||
await request<IcnsVerificationResponse>("/api/icns-verification", {
|
||||
method: "post",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
claimer: key.bech32Address,
|
||||
authToken: accessToken,
|
||||
}),
|
||||
})
|
||||
).verificationList;
|
||||
}
|
||||
};
|
||||
|
||||
const checkAdr36 = async () => {
|
||||
if (twitterAuthInfo && wallet) {
|
||||
const key = await wallet.getKey(MainChainId);
|
||||
@ -237,7 +210,7 @@ export default function VerificationPage() {
|
||||
return (chain as ChainItemType).chainId;
|
||||
});
|
||||
|
||||
return await wallet.signICNSAdr36(
|
||||
return wallet.signICNSAdr36(
|
||||
MainChainId,
|
||||
RESOLVER_ADDRESS,
|
||||
key.bech32Address,
|
||||
@ -248,59 +221,33 @@ export default function VerificationPage() {
|
||||
};
|
||||
|
||||
const onClickRegistration = async () => {
|
||||
const { state, code } = fetchUrlQueryParameter();
|
||||
const { state, code } = checkTwitterAuthQueryParameter(
|
||||
window.location.search,
|
||||
);
|
||||
|
||||
const twitterInfo = await fetchTwitterInfo(state, code);
|
||||
|
||||
const adr36Infos = await checkAdr36();
|
||||
|
||||
const icnsVerificationList = await verifyTwitterAccount(
|
||||
twitterInfo.accessToken,
|
||||
);
|
||||
|
||||
if (wallet && icnsVerificationList && adr36Infos) {
|
||||
if (wallet && adr36Infos) {
|
||||
const key = await wallet.getKey(MainChainId);
|
||||
|
||||
const registerMsg = makeCosmwasmExecMsg(
|
||||
const icnsVerificationList = await verifyTwitterAccount(
|
||||
key.bech32Address,
|
||||
REGISTRAR_ADDRESS,
|
||||
{
|
||||
claim: {
|
||||
name: twitterInfo.username,
|
||||
verifying_msg:
|
||||
icnsVerificationList[0].status === "fulfilled"
|
||||
? icnsVerificationList[0].value.data.verifying_msg
|
||||
: "",
|
||||
verifications: icnsVerificationList.map((verification) => {
|
||||
if (verification.status === "fulfilled") {
|
||||
return {
|
||||
public_key: verification.value.data.public_key,
|
||||
signature: verification.value.data.signature,
|
||||
};
|
||||
}
|
||||
}),
|
||||
},
|
||||
},
|
||||
[ContractFee],
|
||||
twitterInfo.accessToken,
|
||||
);
|
||||
|
||||
const registerMsg = makeClaimMessage(
|
||||
key.bech32Address,
|
||||
twitterInfo.username,
|
||||
icnsVerificationList,
|
||||
);
|
||||
|
||||
const addressMsgs = adr36Infos.map((adr36Info) => {
|
||||
return makeCosmwasmExecMsg(
|
||||
return makeSetRecordMessage(
|
||||
key.bech32Address,
|
||||
RESOLVER_ADDRESS,
|
||||
{
|
||||
set_record: {
|
||||
name: twitterInfo.username,
|
||||
bech32_prefix: adr36Info.bech32Prefix,
|
||||
adr36_info: {
|
||||
signer_bech32_address: adr36Info.bech32Address,
|
||||
address_hash: adr36Info.addressHash,
|
||||
pub_key: Buffer.from(adr36Info.pubKey).toString("base64"),
|
||||
signature: Buffer.from(adr36Info.signature).toString("base64"),
|
||||
signature_salt: adr36Info.signatureSalt.toString(),
|
||||
},
|
||||
},
|
||||
},
|
||||
[],
|
||||
twitterInfo.username,
|
||||
adr36Info,
|
||||
);
|
||||
});
|
||||
|
||||
@ -316,8 +263,6 @@ export default function VerificationPage() {
|
||||
protoMsgs.push(addressMsg.proto);
|
||||
}
|
||||
|
||||
console.log(aminoMsgs);
|
||||
|
||||
const chainInfo = {
|
||||
chainId: MainChainId,
|
||||
rest: REST_URL,
|
||||
@ -348,7 +293,7 @@ export default function VerificationPage() {
|
||||
},
|
||||
);
|
||||
|
||||
router.push({
|
||||
await router.push({
|
||||
pathname: "complete",
|
||||
query: { txHash: Buffer.from(txHash).toString("hex") },
|
||||
});
|
||||
|
@ -7,9 +7,12 @@ import {
|
||||
import { Buffer } from "buffer/";
|
||||
import {
|
||||
AddressesQueryResponse,
|
||||
CosmwasmExecuteMessageResult,
|
||||
NameByTwitterIdQueryResponse,
|
||||
QueryError,
|
||||
} from "../types";
|
||||
import { makeCosmwasmExecMsg } from "../wallets";
|
||||
import { ContractFee } from "../constants/wallet";
|
||||
|
||||
const getCosmwasmQueryUrl = (contractAddress: string, queryMsg: string) =>
|
||||
`${REST_URL}/cosmwasm/wasm/v1/contract/${contractAddress}/smart/${queryMsg}`;
|
||||
@ -34,10 +37,65 @@ export const queryAddressesFromTwitterName = async (
|
||||
const msg = {
|
||||
addresses: { name: twitterUsername },
|
||||
};
|
||||
return request<any>(
|
||||
|
||||
return request<AddressesQueryResponse>(
|
||||
getCosmwasmQueryUrl(
|
||||
RESOLVER_ADDRESS,
|
||||
Buffer.from(JSON.stringify(msg)).toString("base64"),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
export const makeClaimMessage = (
|
||||
senderAddress: string,
|
||||
twitterUserName: string,
|
||||
verificationList: any[],
|
||||
): CosmwasmExecuteMessageResult => {
|
||||
return makeCosmwasmExecMsg(
|
||||
senderAddress,
|
||||
REGISTRAR_ADDRESS,
|
||||
{
|
||||
claim: {
|
||||
name: twitterUserName,
|
||||
verifying_msg:
|
||||
verificationList[0].status === "fulfilled"
|
||||
? verificationList[0].value.data.verifying_msg
|
||||
: "",
|
||||
verifications: verificationList.map((verification) => {
|
||||
if (verification.status === "fulfilled") {
|
||||
return {
|
||||
public_key: verification.value.data.public_key,
|
||||
signature: verification.value.data.signature,
|
||||
};
|
||||
}
|
||||
}),
|
||||
},
|
||||
},
|
||||
[ContractFee],
|
||||
);
|
||||
};
|
||||
|
||||
export const makeSetRecordMessage = (
|
||||
senderAddress: string,
|
||||
twitterUserName: string,
|
||||
adr36Info: any,
|
||||
): CosmwasmExecuteMessageResult => {
|
||||
return makeCosmwasmExecMsg(
|
||||
senderAddress,
|
||||
RESOLVER_ADDRESS,
|
||||
{
|
||||
set_record: {
|
||||
name: twitterUserName,
|
||||
bech32_prefix: adr36Info.bech32Prefix,
|
||||
adr36_info: {
|
||||
signer_bech32_address: adr36Info.bech32Address,
|
||||
address_hash: adr36Info.addressHash,
|
||||
pub_key: Buffer.from(adr36Info.pubKey).toString("base64"),
|
||||
signature: Buffer.from(adr36Info.signature).toString("base64"),
|
||||
signature_salt: adr36Info.signatureSalt.toString(),
|
||||
},
|
||||
},
|
||||
},
|
||||
[],
|
||||
);
|
||||
};
|
||||
|
@ -1,4 +1,8 @@
|
||||
import { TwitterAuthInfoResponse, TwitterAuthUrlResponse } from "../types";
|
||||
import {
|
||||
IcnsVerificationResponse,
|
||||
TwitterAuthInfoResponse,
|
||||
TwitterAuthUrlResponse,
|
||||
} from "../types";
|
||||
import { request } from "../utils/url";
|
||||
|
||||
export const loginWithTwitter = async () => {
|
||||
@ -13,9 +17,25 @@ export const fetchTwitterInfo = async (
|
||||
state: string,
|
||||
code: string,
|
||||
): Promise<TwitterAuthInfoResponse> => {
|
||||
const newTwitterAuthInfo = await request<TwitterAuthInfoResponse>(
|
||||
return await request<TwitterAuthInfoResponse>(
|
||||
`/api/twitter-auth-info?state=${state}&code=${code}`,
|
||||
);
|
||||
|
||||
return newTwitterAuthInfo;
|
||||
};
|
||||
|
||||
export const verifyTwitterAccount = async (
|
||||
claimer: string,
|
||||
accessToken: string,
|
||||
) => {
|
||||
return (
|
||||
await request<IcnsVerificationResponse>("/api/icns-verification", {
|
||||
method: "post",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
claimer: claimer,
|
||||
authToken: accessToken,
|
||||
}),
|
||||
})
|
||||
).verificationList;
|
||||
};
|
||||
|
9
types/icns.ts
Normal file
9
types/icns.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { Any } from "@keplr-wallet/proto-types/google/protobuf/any";
|
||||
|
||||
export interface CosmwasmExecuteMessageResult {
|
||||
amino: {
|
||||
readonly type: string;
|
||||
readonly value: any;
|
||||
};
|
||||
proto: Any;
|
||||
}
|
@ -3,3 +3,4 @@ export * from "./api-response";
|
||||
export * from "./chain-item-type";
|
||||
export * from "./msg";
|
||||
export * from "./twitter";
|
||||
export * from "./icns";
|
||||
|
@ -3,3 +3,8 @@ import { TwitterAuthInfoResponse } from "./api-response";
|
||||
export interface TwitterProfileType extends TwitterAuthInfoResponse {
|
||||
isRegistered: boolean;
|
||||
}
|
||||
|
||||
export interface TwitterLoginSuccess {
|
||||
code: string;
|
||||
state: string;
|
||||
}
|
||||
|
3
utils/error.ts
Normal file
3
utils/error.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export const ErrorHandler = (message: string) => {
|
||||
console.error(message);
|
||||
};
|
21
utils/url.ts
21
utils/url.ts
@ -1,3 +1,6 @@
|
||||
import { TwitterLoginSuccess } from "../types";
|
||||
import { TWITTER_LOGIN_ERROR } from "../constants/error-message";
|
||||
|
||||
export function request<TResponse>(
|
||||
url: string,
|
||||
config: RequestInit = {},
|
||||
@ -23,3 +26,21 @@ export function buildQueryString(query: Record<string, any>): string {
|
||||
)
|
||||
.join("&");
|
||||
}
|
||||
|
||||
export const checkTwitterAuthQueryParameter = (
|
||||
query: string,
|
||||
): TwitterLoginSuccess => {
|
||||
// Twitter Login Error Check
|
||||
if (query.match("error")) {
|
||||
throw new Error(TWITTER_LOGIN_ERROR);
|
||||
}
|
||||
|
||||
// Twitter state, auth code check
|
||||
const [, state, code] =
|
||||
query.match(/^(?=.*state=([^&]+)|)(?=.*code=([^&]+)|).+$/) || [];
|
||||
|
||||
return {
|
||||
state,
|
||||
code,
|
||||
};
|
||||
};
|
||||
|
@ -15,6 +15,7 @@ import { Any } from "@keplr-wallet/proto-types/google/protobuf/any";
|
||||
import { PubKey } from "@keplr-wallet/proto-types/cosmos/crypto/secp256k1/keys";
|
||||
import { SignMode } from "@keplr-wallet/proto-types/cosmos/tx/signing/v1beta1/signing";
|
||||
import { MsgExecuteContract } from "@keplr-wallet/proto-types/cosmwasm/wasm/v1/tx";
|
||||
import { CosmwasmExecuteMessageResult } from "../types";
|
||||
|
||||
export async function sendMsgs(
|
||||
wallet: Wallet,
|
||||
@ -189,13 +190,7 @@ export function makeCosmwasmExecMsg(
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
obj: object,
|
||||
funds: { readonly amount: string; readonly denom: string }[],
|
||||
): {
|
||||
amino: {
|
||||
readonly type: string;
|
||||
readonly value: any;
|
||||
};
|
||||
proto: Any;
|
||||
} {
|
||||
): CosmwasmExecuteMessageResult {
|
||||
const amino = {
|
||||
type: "wasm/MsgExecuteContract",
|
||||
value: {
|
||||
|
Loading…
Reference in New Issue
Block a user