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 { Dispatch, FunctionComponent, SetStateAction } from "react";
|
||||
|
||||
import { ChainImage } from "./chain-image";
|
||||
import { Flex1 } from "../../styles/flex-1";
|
||||
import {
|
||||
ChangeEvent,
|
||||
Dispatch,
|
||||
FunctionComponent,
|
||||
SetStateAction,
|
||||
useEffect,
|
||||
useState,
|
||||
} from "react";
|
||||
import {
|
||||
ChainCheckBox,
|
||||
ChainImageContainer,
|
||||
ChainInfoContainer,
|
||||
ChainItemContainer,
|
||||
} from "./chain-list";
|
||||
import { ChainImage } from "./chain-image";
|
||||
import { Flex1 } from "../../styles/flex-1";
|
||||
import { ChainCheckBox, ChainName, WalletAddress } from "./chain-item";
|
||||
ChainName,
|
||||
WalletAddress,
|
||||
} from "./chain-item";
|
||||
import color from "../../styles/color";
|
||||
import styled from "styled-components";
|
||||
|
||||
|
@ -1,17 +1,5 @@
|
||||
import { ChainItemType } from "../../types";
|
||||
import {
|
||||
ChangeEvent,
|
||||
Dispatch,
|
||||
FunctionComponent,
|
||||
SetStateAction,
|
||||
useEffect,
|
||||
useState,
|
||||
} from "react";
|
||||
import {
|
||||
ChainImageContainer,
|
||||
ChainInfoContainer,
|
||||
ChainItemContainer,
|
||||
} from "./chain-list";
|
||||
import { ChainItemType, WidthHeightProps } from "../../types";
|
||||
import { FunctionComponent, useEffect, useState } from "react";
|
||||
|
||||
import color from "../../styles/color";
|
||||
import { Flex1 } from "../../styles/flex-1";
|
||||
@ -22,26 +10,31 @@ interface Props {
|
||||
chainItem: ChainItemType;
|
||||
checkedItemHandler: (chainItem: ChainItemType, isChecked: boolean) => void;
|
||||
checkedItems: Set<unknown>;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export const ChainItem: FunctionComponent<Props> = (props) => {
|
||||
const { chainItem, checkedItemHandler, checkedItems } = props;
|
||||
const [checked, setChecked] = useState(false);
|
||||
const { chainItem, checkedItemHandler, checkedItems, disabled } = props;
|
||||
const [checked, setChecked] = useState(disabled);
|
||||
|
||||
const checkHandler = () => {
|
||||
setChecked(!checked);
|
||||
checkedItemHandler(chainItem, !checked);
|
||||
if (!disabled) {
|
||||
setChecked(!checked);
|
||||
checkedItemHandler(chainItem, !checked);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setChecked(checkedItems.has(chainItem));
|
||||
if (!disabled) {
|
||||
setChecked(checkedItems.has(chainItem));
|
||||
}
|
||||
}, [checkedItems]);
|
||||
|
||||
return (
|
||||
<ChainItemContainer
|
||||
key={chainItem.prefix}
|
||||
isLoading={false}
|
||||
checked={checked}
|
||||
disabled={disabled}
|
||||
onClick={checkHandler}
|
||||
>
|
||||
<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`
|
||||
font-weight: 600;
|
||||
font-size: 0.8rem;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Dispatch, FunctionComponent, SetStateAction, useEffect } from "react";
|
||||
import { ChainItemType, WidthHeightProps } from "../../types";
|
||||
import { ChainItemType } from "../../types";
|
||||
import color from "../../styles/color";
|
||||
import styled from "styled-components";
|
||||
import { ChainItem } from "./chain-item";
|
||||
@ -8,6 +8,7 @@ interface Props {
|
||||
allChecked: boolean;
|
||||
setAllChecked: Dispatch<SetStateAction<boolean>>;
|
||||
chainList: ChainItemType[];
|
||||
disabledChainList: ChainItemType[];
|
||||
checkedItems: Set<unknown>;
|
||||
setCheckedItems: Dispatch<SetStateAction<Set<unknown>>>;
|
||||
}
|
||||
@ -17,6 +18,7 @@ export const ChainList: FunctionComponent<Props> = (props) => {
|
||||
allChecked,
|
||||
setAllChecked,
|
||||
chainList,
|
||||
disabledChainList,
|
||||
checkedItems,
|
||||
setCheckedItems,
|
||||
} = props;
|
||||
@ -59,6 +61,15 @@ export const ChainList: FunctionComponent<Props> = (props) => {
|
||||
checkedItems={checkedItems}
|
||||
/>
|
||||
))}
|
||||
{disabledChainList.map((chainItem) => (
|
||||
<ChainItem
|
||||
key={chainItem.address}
|
||||
chainItem={chainItem}
|
||||
checkedItemHandler={checkedItemHandler}
|
||||
checkedItems={checkedItems}
|
||||
disabled={true}
|
||||
/>
|
||||
))}
|
||||
</ChainContainer>
|
||||
);
|
||||
};
|
||||
@ -72,35 +83,3 @@ export const ChainContainer = styled.div`
|
||||
|
||||
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,
|
||||
} from "../../constants/wallet";
|
||||
import { getKeplrFromWindow, KeplrWallet } from "../../wallets";
|
||||
import { loginWithTwitter } from "../../repository";
|
||||
import { loginWithTwitter } from "../../queries";
|
||||
|
||||
interface Props {
|
||||
wallet: WalletType;
|
||||
}
|
||||
|
||||
// Todo: Wallet 관련된 부분을 Context로 빼는 부분
|
||||
export const WalletItem: FunctionComponent<Props> = (props: 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 REST_URL = "https://lcd.testnet.osmosis.zone";
|
||||
|
||||
// TODO: .evn에 없으면 디폴트값 설정
|
||||
export const REGISTRAR_ADDRESS =
|
||||
"osmo1npn97g7hsgqlp70rw8nhd7c7vyvkukv9x0n25sn4fk5mgcjlz4gq9zlgf3";
|
||||
export const RESOLVER_ADDRESS =
|
||||
|
@ -1,51 +1,8 @@
|
||||
import { request } from "../utils/url";
|
||||
import {
|
||||
REGISTRAR_ADDRESS,
|
||||
RESOLVER_ADDRESS,
|
||||
REST_URL,
|
||||
} from "../constants/icns";
|
||||
import { Buffer } from "buffer/";
|
||||
import {
|
||||
AddressesQueryResponse,
|
||||
CosmwasmExecuteMessageResult,
|
||||
NameByTwitterIdQueryResponse,
|
||||
QueryError,
|
||||
} from "../types";
|
||||
import { CosmwasmExecuteMessageResult } from "../types";
|
||||
import { makeCosmwasmExecMsg } from "../wallets";
|
||||
import { REGISTRAR_ADDRESS, RESOLVER_ADDRESS } from "../constants/icns";
|
||||
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 = (
|
||||
senderAddress: 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"));
|
||||
|
||||
console.log(result);
|
||||
|
||||
// Todo rsult => 확인 후에 확인
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -2,8 +2,12 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
// Types
|
||||
import { ChainItemType, TwitterProfileType } from "../../types";
|
||||
import { checkTwitterAuthQueryParameter, request } from "../../utils/url";
|
||||
import {
|
||||
ChainItemType,
|
||||
RegisteredAddresses,
|
||||
TwitterProfileType,
|
||||
} from "../../types";
|
||||
import { checkTwitterAuthQueryParameter } from "../../utils/url";
|
||||
|
||||
// Styles
|
||||
import styled from "styled-components";
|
||||
@ -20,7 +24,6 @@ import { useRouter } from "next/router";
|
||||
import {
|
||||
getKeplrFromWindow,
|
||||
KeplrWallet,
|
||||
makeCosmwasmExecMsg,
|
||||
sendMsgs,
|
||||
simulateMsgs,
|
||||
} from "../../wallets";
|
||||
@ -29,26 +32,20 @@ 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 {
|
||||
MainChainId,
|
||||
REGISTRAR_ADDRESS,
|
||||
RESOLVER_ADDRESS,
|
||||
REST_URL,
|
||||
} from "../../constants/icns";
|
||||
import { MainChainId, RESOLVER_ADDRESS, REST_URL } from "../../constants/icns";
|
||||
|
||||
import {
|
||||
fetchTwitterInfo,
|
||||
makeClaimMessage,
|
||||
makeSetRecordMessage,
|
||||
queryAddressesFromTwitterName,
|
||||
queryRegisteredTwitterId,
|
||||
verifyTwitterAccount,
|
||||
} from "../../repository";
|
||||
} from "../../queries";
|
||||
import { ErrorHandler } from "../../utils/error";
|
||||
import {
|
||||
KEPLR_NOT_FOUND_ERROR,
|
||||
TWITTER_LOGIN_ERROR,
|
||||
} from "../../constants/error-message";
|
||||
import { makeClaimMessage, makeSetRecordMessage } from "../../messages";
|
||||
|
||||
export default function VerificationPage() {
|
||||
const router = useRouter();
|
||||
@ -57,13 +54,19 @@ export default function VerificationPage() {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const [wallet, setWallet] = useState<KeplrWallet>();
|
||||
const [allChains, setAllChains] = 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 [checkedItems, setCheckedItems] = useState(new Set());
|
||||
|
||||
const [searchValue, setSearchValue] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
@ -80,7 +83,7 @@ export default function VerificationPage() {
|
||||
// Fetch Twitter Profile
|
||||
const twitterInfo = await fetchTwitterInfo(state, code);
|
||||
|
||||
// check registered
|
||||
// contract check registered
|
||||
const registeredQueryResponse = await queryRegisteredTwitterId(
|
||||
twitterInfo.id,
|
||||
);
|
||||
@ -95,11 +98,7 @@ export default function VerificationPage() {
|
||||
registeredQueryResponse.data.name,
|
||||
);
|
||||
|
||||
setRegisteredAddressList(
|
||||
addressesQueryResponse.data.addresses.map(
|
||||
(address) => address.address,
|
||||
),
|
||||
);
|
||||
setRegisteredChainList(addressesQueryResponse.data.addresses);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.message === TWITTER_LOGIN_ERROR) {
|
||||
@ -117,89 +116,96 @@ export default function VerificationPage() {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
// After Wallet Initialize
|
||||
if (wallet) {
|
||||
fetchChainList();
|
||||
}
|
||||
}, [wallet]);
|
||||
const disabledChainList = chainList.filter((chain) => {
|
||||
for (const registeredChain of registeredChainList) {
|
||||
if (
|
||||
chain.prefix === registeredChain.bech32_prefix &&
|
||||
chain.address === registeredChain.address
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
// To check registered chain
|
||||
const filteredChainList = chainList.filter((chain) => {
|
||||
return registeredAddressList.includes(chain.address);
|
||||
return false;
|
||||
});
|
||||
|
||||
setCheckedItems(new Set(filteredChainList));
|
||||
}, [registeredAddressList]);
|
||||
const filteredChainList = chainList.filter(
|
||||
(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 keplr = await getKeplrFromWindow();
|
||||
|
||||
if (keplr) {
|
||||
const keplrWallet = new KeplrWallet(keplr);
|
||||
|
||||
await fetchChainList(keplrWallet);
|
||||
setWallet(keplrWallet);
|
||||
} else {
|
||||
ErrorHandler(KEPLR_NOT_FOUND_ERROR);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchChainList = async () => {
|
||||
if (wallet) {
|
||||
const chainIds = (await wallet.getChainInfosWithoutEndpoints()).map(
|
||||
(c) => c.chainId,
|
||||
);
|
||||
const chainKeys = await Promise.all(
|
||||
chainIds.map((chainId) => wallet.getKey(chainId)),
|
||||
);
|
||||
const fetchChainList = async (wallet: KeplrWallet) => {
|
||||
const chainIds = (await wallet.getChainInfosWithoutEndpoints()).map(
|
||||
(c) => c.chainId,
|
||||
);
|
||||
const chainKeys = await Promise.all(
|
||||
chainIds.map((chainId) => wallet.getKey(chainId)),
|
||||
);
|
||||
|
||||
const chainInfos = (await wallet.getChainInfosWithoutEndpoints()).map(
|
||||
(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
|
||||
}/chain.png`,
|
||||
};
|
||||
},
|
||||
);
|
||||
const chainInfos = (await wallet.getChainInfosWithoutEndpoints()).map(
|
||||
(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
|
||||
}/chain.png`,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
const chainArray = [];
|
||||
for (let i = 0; i < chainKeys.length; i++) {
|
||||
chainArray.push({
|
||||
address: chainKeys[i].bech32Address,
|
||||
...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;
|
||||
})
|
||||
);
|
||||
const chainArray = [];
|
||||
for (let i = 0; i < chainKeys.length; i++) {
|
||||
chainArray.push({
|
||||
address: chainKeys[i].bech32Address,
|
||||
...chainInfos[i],
|
||||
});
|
||||
|
||||
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 () => {
|
||||
@ -224,7 +230,6 @@ export default function VerificationPage() {
|
||||
const { state, code } = checkTwitterAuthQueryParameter(
|
||||
window.location.search,
|
||||
);
|
||||
|
||||
const twitterInfo = await fetchTwitterInfo(state, code);
|
||||
|
||||
const adr36Infos = await checkAdr36();
|
||||
@ -336,6 +341,12 @@ export default function VerificationPage() {
|
||||
chain.address.includes(searchValue) ||
|
||||
chain.prefix.includes(searchValue),
|
||||
)}
|
||||
disabledChainList={disabledChainList.filter(
|
||||
(chain) =>
|
||||
chain.chainId.includes(searchValue) ||
|
||||
chain.address.includes(searchValue) ||
|
||||
chain.prefix.includes(searchValue),
|
||||
)}
|
||||
checkedItems={checkedItems}
|
||||
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";
|
||||
|
||||
export const loginWithTwitter = async () => {
|
||||
const { authUrl }: TwitterAuthUrlResponse = await (
|
||||
await fetch("/api/twitter-auth-url")
|
||||
).json();
|
||||
const { authUrl } = await request<TwitterAuthUrlResponse>(
|
||||
"/api/twitter-auth-url",
|
||||
);
|
||||
|
||||
window.location.href = authUrl;
|
||||
};
|
@ -1,5 +1,6 @@
|
||||
export interface ChainItemType {
|
||||
chainId: string;
|
||||
chainName: string;
|
||||
prefix: string;
|
||||
chainImageUrl: string;
|
||||
address: string;
|
||||
|
Loading…
Reference in New Issue
Block a user