UNPKG

eros-sdk-react

Version:

eros sdk

1,773 lines (1,724 loc) 264 kB
import { matchMain, matchTest } from "./chunk-JX73EY6V.mjs"; import { NumberFormatter, bytesToBase64, decodeBase64, encodeBase64, formatAddress, formatDate, getAppClientId, getVersion, isInTgApp, isValidEmail, isValidUsername, truncateAddress } from "./chunk-IZOOVZAD.mjs"; import { ArrowDownIcon, ArrowLeftIcon, ArrowRightIcon, ArrowSendIcon, BTCDarkIcon, BTCLightIcon, BitgetIcon, CheckIcon, CheckRoundIcon, CheckboxCheckedIcon, CheckboxIcon, CloseEyeIcon, CloseRoundIcon, CopyIcon, DeleteRoundIcon, DiscordIcon, EVMDarkIcon, EVMLightIcon, EmailIcon, EmailLineIcon, ErrorRoundIcon, FacebookIcon, GithubIcon, GoogleIcon, InfoLineIcon, InfoRoundIcon, InputLengthIcon, KakaoIcon, LeatherIcon, LinkedinIcon, LoadingIcon_default, LoginIcon_default, MatchIdIcon_default, OKXIcon, OpenEyeIcon, PhantomIcon, SOLDarkIcon, SOLLightIcon, TRXDarkIcon, TRXLightIcon, TelegramIcon, TonLightIcon, TonLightIcon2, TransferIcon, TronLinkIcon, UnLoginIcon_default, UnisatIcon, WalletIcon, XIcon, XverseIcon, YoutubeIcon } from "./chunk-FQ6PYZPD.mjs"; import { confirm_default, connecting_default, error_default, fail_default, pending_default, signing_default, success_default, wallet_default } from "./chunk-XM6CYEXN.mjs"; import { __export } from "./chunk-J5LGTIGS.mjs"; // src/components/index.tsx var components_exports = {}; __export(components_exports, { BTCModal: () => BTCModal, Button: () => Button, EVMModal: () => EVMModal, EmailModal: () => EmailModal, Field: () => Field, Input: () => Input, LoginBox: () => LoginBox, LoginButton: () => LoginButton, LoginModal: () => LoginModal, LoginPanel: () => LoginPanel, Modal: () => Modal, ModalWithHeader: () => ModalWithHeader, Overlay: () => Overlay, Popover: () => Popover, TONModal: () => TONModal, TRONModal: () => TRONModal, TokenDetail: () => TokenDetail, TokenSend: () => TokenSend, TokenSendList: () => TokenSendList, TransactionList: () => TransactionList, UsernameModal: () => UsernameModal, WalletAsset: () => WalletAsset, WalletModal: () => WalletModal }); // src/components/EmailModal/index.tsx import { useEffect as useEffect21, useState as useState19 } from "react"; // src/ui/Modal/index.tsx import { useEffect as useEffect3, useState as useState2 } from "react"; // src/hooks/useLayout.tsx var useLayout_exports = {}; __export(useLayout_exports, { useDownMd: () => useDownMd }); import { useState, useEffect } from "react"; function useDownMd() { const [isBelowMd, setIsBelowMd] = useState(window.matchMedia("(max-width: 767px)").matches); useEffect(() => { const handleResize = () => { setIsBelowMd(window.matchMedia("(max-width: 767px)").matches); }; window.addEventListener("resize", handleResize); return () => { window.removeEventListener("resize", handleResize); }; }, []); return isBelowMd; } // src/ui/Overlay/index.tsx import { useEffect as useEffect2 } from "react"; import { Fragment, jsx } from "react/jsx-runtime"; function Overlay({ isOpen = false, children, zIndex = 100 }) { useEffect2(() => { if (isOpen) { document.body.style.overflow = "hidden"; } else { document.body.style.overflow = ""; } return () => { document.body.style.overflow = ""; }; }, [isOpen]); return isOpen ? /* @__PURE__ */ jsx( "div", { className: "matchid-overlay", style: { zIndex }, children } ) : /* @__PURE__ */ jsx(Fragment, {}); } // src/ui/Modal/index.tsx import { useIntl } from "react-intl"; import { jsx as jsx2, jsxs } from "react/jsx-runtime"; function Modal({ children, isOpen, width = 480, zIndex = 100, className = "" }) { return /* @__PURE__ */ jsx2(Overlay, { isOpen, zIndex, children: /* @__PURE__ */ jsxs("div", { className: `matchid-modal ${className}`, style: { width }, children: [ /* @__PURE__ */ jsx2("div", { className: "matchid-modal-mobile-header" }), children ] }) }); } function ModalWithHeader({ children, onBack, onClose, title, showBorder = true, showClose = true, ...props }) { const isDownMd = useDownMd(); return /* @__PURE__ */ jsxs(Modal, { ...props, children: [ /* @__PURE__ */ jsxs("div", { className: `matchid-modal-header ${showBorder ? "matchid-modal-header-border" : ""}`, children: [ /* @__PURE__ */ jsxs("div", { className: "matchid-modal-header-content", children: [ onBack && /* @__PURE__ */ jsx2(ArrowLeftIcon, { height: isDownMd ? 20 : 25, width: isDownMd ? 20 : 24, className: "matchid-modal-header-back", onClick: onBack }), /* @__PURE__ */ jsx2("span", { className: "matchid-modal-header-title", children: title }) ] }), onClose && /* @__PURE__ */ jsx2(CloseRoundIcon, { size: isDownMd ? 24 : 30, className: "matchid-modal-header-close", onClick: onClose }) ] }), children ] }); } function ConfirmModal({ title, children, onClose, onConfirm, isOpen, confirmText, zIndex = 100 }) { const intl = useIntl(); const [loading, setLoading] = useState2(false); const [error, setError] = useState2(""); useEffect3(() => { if (isOpen) { setError(""); setLoading(false); } }, [isOpen]); const onSubmit = async () => { setError(""); setLoading(true); try { await onConfirm(); } catch (e) { setError(e.message); console.error(e); } finally { setLoading(false); } }; return /* @__PURE__ */ jsx2(ModalWithHeader, { isOpen, onClose, title, zIndex, children: /* @__PURE__ */ jsxs("div", { className: "matchid-confirm-modal", children: [ /* @__PURE__ */ jsx2("div", { className: "matchid-w-full", children }), error && /* @__PURE__ */ jsx2("div", { className: `matchid-error`, children: error }), /* @__PURE__ */ jsx2(Button, { size: "lg", onClick: onSubmit, loading, block: true, highlight: true, children: confirmText ?? intl.formatMessage({ id: "Confirm" }) }) ] }) }); } // src/components/EmailModal/StepEmail.tsx import { useEffect as useEffect5, useMemo, useState as useState4 } from "react"; // src/ui/Button/index.tsx import { jsx as jsx3 } from "react/jsx-runtime"; function Button({ size = "df", disabled = false, loading = false, children, onClick, highlight = false, block = false, type = "button", rounded = true, className = "", style = {}, dataset = {} }) { const onAction = () => { if (!disabled && !loading) { onClick && onClick(); } }; return /* @__PURE__ */ jsx3( "button", { type, className: `${className} matchid-btn ${"matchid-btn-" + size} ${highlight ? "matchid-btn-highlight" : ""} ${loading ? "matchid-btn-loading" : ""} ${block ? "matchid-btn-block" : ""} ${rounded ? "matchid-btn-rounded" : ""}`, disabled: disabled || loading, style: { ...style }, onClick: onAction, ...dataset, children: loading ? /* @__PURE__ */ jsx3(LoadingIcon_default, { className: "matchid-btn-loading-icon", color: "var(--matchid-btn-loading-color)" }) : children } ); } // src/ui/Input/index.tsx import { useEffect as useEffect4, useRef, useState as useState3 } from "react"; import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime"; function Input({ onChange, type, after, showLength = false, showClear = true, className = "", rows = 1, maxRows = 4, children, ...props }) { const [inputType, setInputType] = useState3(type); const isDownMd = useDownMd(); const textareaRef = useRef(null); useEffect4(() => { const textarea = textareaRef.current; if (textarea) { textarea.style.height = "auto"; const lineHeight = 24; const maxHeight = lineHeight * 4; textarea.style.height = Math.min(textarea.scrollHeight, maxHeight) + "px"; } }, [props.value]); return /* @__PURE__ */ jsxs2( "div", { className: `matchid-input-box matchid-input-${type} ${props.value && props.value.length > 0 ? "matchid-input-has-content" : ""} ${className}`, style: { // @ts-ignore "--max-rows": maxRows }, children: [ children ?? (type == "textarea" ? /* @__PURE__ */ jsx4("textarea", { rows: 1, onChange, ...props, className: "matchid-input-field", ref: textareaRef, style: { maxHeight: maxRows * 24 + "px" } }) : /* @__PURE__ */ jsx4("input", { type: inputType, onChange, ...props, className: "matchid-input-field" })), type != "textarea" && showClear && props.value && props.value.length > 0 && /* @__PURE__ */ jsx4("div", { className: "matchid-input-delete-icon", onClick: (e) => { if (onChange) { onChange({ target: { value: "" } }); } }, children: /* @__PURE__ */ jsx4( DeleteRoundIcon, { height: isDownMd ? 16 : 21, width: isDownMd ? 16 : 20, color: "var(--matchid-input-delete-icon-color)" } ) }), type === "password" && /* @__PURE__ */ jsx4("div", { className: "matchid-input-eye-icon", onClick: () => { setInputType(inputType === "password" ? "text" : "password"); }, children: inputType === "password" ? /* @__PURE__ */ jsx4(CloseEyeIcon, { size: isDownMd ? 16 : 20 }) : /* @__PURE__ */ jsx4(OpenEyeIcon, { size: isDownMd ? 16 : 20 }) }), showLength && props.maxLength && /* @__PURE__ */ jsxs2("div", { className: `matchid-input-length`, children: [ /* @__PURE__ */ jsxs2("span", { children: [ props.value?.length || 0, "/", props.maxLength ] }), /* @__PURE__ */ jsx4(InputLengthIcon, { color: "var(--icon-color)" }) ] }), after ] } ); } // src/ui/Field/index.tsx import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime"; function Field({ label, children, error, required, className = "" }) { return /* @__PURE__ */ jsxs3("div", { className: `matchid-field-box ${className}`, children: [ /* @__PURE__ */ jsxs3("div", { className: "matchid-field-label", children: [ required && /* @__PURE__ */ jsx5("span", { className: "matchid-field-required", children: "*" }), label ] }), children, error && /* @__PURE__ */ jsx5("div", { className: "matchid-field-error", children: error }) ] }); } // src/components/EmailModal/StepEmail.tsx import { FormattedMessage, useIntl as useIntl2 } from "react-intl"; import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime"; function StepEmail(props) { const intl = useIntl2(); const [emailVal, setEmailVal] = useState4(""); useEffect5(() => { if (props.email) { setEmailVal(props.email); } }, []); const canContinue = useMemo(() => { return isValidEmail(emailVal); }, [emailVal]); const onContinue = async () => { props.onContinue(emailVal); }; return /* @__PURE__ */ jsxs4("div", { className: "matchid-email-email-box", children: [ /* @__PURE__ */ jsx6(Field, { label: intl.formatMessage({ id: "emailAddress" }), children: /* @__PURE__ */ jsx6( Input, { placeholder: intl.formatMessage({ id: "emailAddressPlaceholder" }), onChange: (e) => setEmailVal(e.target.value), value: emailVal } ) }), /* @__PURE__ */ jsx6(Button, { disabled: !canContinue, style: { marginTop: "64px" }, onClick: onContinue, size: "lg", block: true, highlight: true, children: /* @__PURE__ */ jsx6(FormattedMessage, { id: "continue" }) }) ] }); } // src/store/useLocalStore.ts import { create } from "zustand"; import { devtools, persist } from "zustand/middleware"; // src/api/request.ts import axios from "axios"; // src/config/env/index.ts var env_default = { endpoints: { back: "https://api.matchid.ai/", auth: "https://auth.matchid.ai/" } }; // src/store/index.ts var getEndpoints = () => { try { const store = localStore.getState(); const env = store?.endpoints; if (env) { return env; } else { return env_default.endpoints; } } catch (e) { return env_default.endpoints; } }; var getAppid = () => { try { const store = localStore.getState(); const appid = store?.appid; if (appid) { return appid; } else { return ""; } } catch (e) { return ""; } }; var getLocale = () => { try { const store = localStore.getState(); const locale = store?.locale; if (locale) { return locale; } else { return "en"; } } catch (e) { return "en"; } }; var getToken = () => { try { const store = localStore.getState(); const token = store?.token; if (token) { return token; } else { return ""; } } catch (e) { return ""; } }; // src/utils/matchlog.ts var matchDevExists = () => localStorage.getItem("matchid-sdk-react-debug") !== null; var handler = { get(target, prop) { if (matchDevExists() && typeof target[prop] === "function") { return target[prop].bind(console); } return () => { }; } }; var matchlog = new Proxy(console, handler); var matchlog_default = matchlog; // src/api/request.ts import axiosRetry from "axios-retry"; var SUCCESS_CODE = 0; var isSuccess = (res) => { return res.code === SUCCESS_CODE; }; var instance = axios.create({ timeout: 6e4, validateStatus(status) { return status >= 200 && status <= 500; } }); var request = async (config) => { try { const endpoints = getEndpoints(); const token = getToken(); instance.defaults.baseURL = `${endpoints.back}`; instance.defaults.headers.common["Appid"] = getAppid(); if (token) { instance.defaults.headers.common["Authorization"] = token; } instance.defaults.headers.common["Accept-Language"] = getLocale(); const { data } = await instance.request(config); matchlog_default.log("api", data); if (data.code == 401001) { localStore.getState().logout(); throw new Error("Your session has expired, please log in again"); } return data; } catch (err) { console.error("qwe-err", err); const message = "Request Error"; console.error(message); return { code: -1, data: null, message, success: false, fail: true, result: null }; } }; var retryInstance = axios.create({ timeout: 6e4, validateStatus(status) { return status >= 200 && status <= 500; } }); axiosRetry(retryInstance, { retries: 3, retryDelay: (retryCount) => retryCount * 1e3, shouldResetTimeout: true, retryCondition: (error) => { return error.response.status >= 500 && error.response.status < 600 || error.code === "ECONNABORTED"; } }); var retryRequest = async (config) => { try { const endpoints = getEndpoints(); const token = getToken(); retryInstance.defaults.baseURL = `${endpoints.back}`; retryInstance.defaults.headers.common["Appid"] = getAppid(); if (token) { retryInstance.defaults.headers.common["Authorization"] = token; } retryInstance.defaults.headers.common["Accept-Language"] = getLocale(); const { data } = await retryInstance.request(config); matchlog_default.log("api", data); if (data.code == 401001) { localStore.getState().logout(); throw new Error("Your session has expired, please log in again"); } return data; } catch (err) { console.error("qwe-err", err); const message = "Request Error"; console.error(message); return { code: -1, data: null, message, success: false, fail: true, result: null }; } }; var request_default = request; // src/api/index.ts var getEmailCodeApi = (email) => { return request_default({ url: `/api/v1/email/code`, method: "POST", data: { email } }); }; var verifyEmailCodeApi = ({ email, verification_key, verification_code }) => { return request_default({ url: `/api/v1/user/email/login`, method: "POST", data: { email, verification_key, verification_code } }); }; var getOverviewInfoApi = () => { return retryRequest({ url: `/api/v1/user/overview`, method: "GET" }); }; var toLogoutApi = () => { return retryRequest({ url: `/api/v1/user/logout`, method: "POST" }); }; var setUserNameApi = (data) => { return request_default({ url: `/api/v1/user/name`, method: "POSt", data }); }; var getBindListApi = () => { return retryRequest({ url: `/api/v1/bind/list`, method: "GET" }); }; var getPohListApi = () => { return retryRequest({ url: `/api/v1/poh/list`, method: "GET" }); }; var getBindInfoApi = () => { return retryRequest({ url: `/api/v1/bind`, method: "GET" }); }; var bindCexApi = (data) => { return request_default({ url: `/api/v1/cex/subscribe`, method: "POST", data }); }; var unBindApi = ({ type }) => { return request_default({ url: `/api/v1/unbind`, method: "POST", data: { type } }); }; var unBindWalletApi = ({ address }) => { return request_default({ url: `/api/v1/wallet/unbind`, method: "POST", data: { address } }); }; var verifyPohApi = ({ taskId, schemaId, publicFields, allocatorAddress, publicFieldsHash, allocatorSignature, uHash, validatorAddress, validatorSignature }) => { return request_default({ url: `/api/v1/poh/zkpass`, method: "POST", data: { taskId, schemaId, publicFields, allocatorAddress, publicFieldsHash, allocatorSignature, uHash, validatorAddress, validatorSignature } }); }; var chooseIdentityApi = ({ identity }) => { return request_default({ url: `/api/v1/user/choose/identity`, method: "POST", data: { identity } }); }; var mintPassportNftApi = () => { return request_default({ url: `/api/v1/mint/passport/nft`, method: "POST" }); }; var getAuthInfoApi = () => { return retryRequest({ url: `/api/v1/user/auth`, method: "GET" }); }; var getWalletNonceApi = (data) => { return retryRequest({ url: `/api/v1/login/wallet/init`, method: "POST", data }); }; var loginByWalletApi = ({ type, address, signature, message, connector_type, wallet_client_type }) => { return request_default({ url: `/api/v1/login/wallet`, method: "POST", data: { type, address, signature, message, connector_type, wallet_client_type } }); }; var getWalletInitApi = (data) => { return retryRequest({ url: `/api/v1/wallet/init`, method: "POST", data }); }; var toBindWalletApi = ({ type, address, signature, message, connector_type, wallet_client_type }) => { return request_default({ url: `/api/v1/wallet/bind`, method: "POST", data: { type, address, signature, message, connector_type, wallet_client_type } }); }; var getAppConfigApi = () => { return retryRequest({ url: `/api/v1/app/config`, method: "GET" }); }; var getUserChainListApi = () => { return request_default({ url: `/api/v1/user/chain/list`, method: "GET" }); }; var userImportTokenApi = (data) => { return request_default({ url: `/api/v1/user/import/token`, method: "POST", data }); }; var getUserImportTokenListApi = (data) => { return request_default({ url: `/api/v1/user/import/token/list`, method: "POST", data }); }; var getUserWalletAssetApi = (data) => { return request_default({ url: `/api/v1/user/wallet/asset`, method: "POST", data }); }; var getUserWalletTransactionsApi = (data) => { return request_default({ url: `/api/v1/user/wallet/transactions`, method: "POST", data }); }; var getWalletAssetListApi = (data) => { return request_default({ url: `/api/v1/wallet/asset`, method: "POST", data }); }; var getWalletListApi = (data) => { return request_default({ url: `/api/v1/wallet/list`, method: "POST", data }); }; var getWalletChainListApi = () => { return request_default({ url: `/api/v1/wallet/chain`, method: "POST" }); }; var getWalletNftListApi = (data) => { return request_default({ url: `/api/v1/wallet/nfts`, method: "POST", data }); }; var tgAppLoginInitApi = () => { return retryRequest({ url: `/api/v1/tgapp/login/init`, method: "GET" }); }; var getTgAppLoginStatus = (data) => { return retryRequest({ url: `/api/v1/tgapp/login/status`, method: "POST", data }); }; var userInviteApi = (data) => { return request_default({ url: `/api/v1/user/invite`, method: "POST", data }); }; // src/store/useLocalStore.ts var persistedState = persist( (set) => ({ appid: "", token: "", did: "", mid: "", overview: null, theme: "light", setOverview: (overview) => set({ overview, address: overview.address, did: overview.did, mid: overview.mid }), refreshOverview: async () => { const res = await getOverviewInfoApi(); if (res.data) { set({ overview: res.data }); set({ address: res.data.address }); set({ did: res.data.did }); set({ mid: res.data.mid }); } }, endpoints: { back: "https://api.matchid.ai/", auth: "https://auth.matchid.ai/" }, setDid: (did) => set({ did }), setToken: (token) => set({ token }), setAppid: (appid) => set({ appid }), setMid: (mid) => set({ mid }), logout: () => set({ token: "", did: "", mid: "", address: "", overview: null, assets: [] }), setTheme: (theme) => set({ theme }), setEndpoints: (endpoints) => set({ endpoints }), address: "", setAddress: (address) => set({ address }), locale: "en", setLocale: (locale) => set({ locale }), wallet: { type: "UserPasscode" }, setWallet: (wallet) => set({ wallet }), chainId: 698, setChainId: (chainId) => set({ chainId }), assets: [], setAssets: (assets) => set({ assets }) }), { name: "match-local" } ); var useLocalStore = create(devtools(persistedState)); var localStore = useLocalStore; var useLocalStore_default = useLocalStore; // src/hooks/useUserInfo.tsx import { useMemo as useMemo8 } from "react"; // src/MatchContext.tsx import { createContext as createContext3, useContext as useContext3 } from "react"; // src/hooks/index.tsx var hooks_exports = {}; __export(hooks_exports, { useCopyClipboard: () => useCopyClipboard, useHash: () => useHash, useLayout: () => useLayout_exports, useMatchChain: () => useMatchChain, useMatchEvents: () => useMatchEvents, useMatchWallet: () => useMatchWallet, useMatchWalletAssetList: () => useMatchWalletAssetList, useMatchWalletAssets: () => useMatchWalletAssets, useMatchWalletRecords: () => useMatchWalletRecords, useModal: () => useModal, useReceipt: () => useReceipt, useToast: () => useToast, useTransaction: () => useTransaction, useUserInfo: () => useUserInfo, useWallet: () => useWallet }); // src/hooks/useMatchEvents.ts import { useEffect as useEffect6 } from "react"; // src/hooks/eventManager.ts var EventManager = class { constructor() { this.listeners = {}; } on(event, callback) { if (!this.listeners[event]) { this.listeners[event] = /* @__PURE__ */ new Set(); } this.listeners[event].add(callback); } off(event, callback) { if (this.listeners[event]) { this.listeners[event].delete(callback); if (this.listeners[event].size === 0) { delete this.listeners[event]; } } } emit(event, ...args) { if (this.listeners[event]) { this.listeners[event].forEach((callback) => callback(...args)); } } }; var eventManager = new EventManager(); var eventManager_default = eventManager; // src/hooks/useMatchEvents.ts function useMatchEvents(handlers) { useEffect6(() => { Object.entries(handlers).forEach(([event, handler2]) => { if (handler2) { eventManager_default.on(event, handler2); } }); return () => { Object.entries(handlers).forEach(([event, handler2]) => { if (handler2) { eventManager_default.off(event, handler2); } }); }; }, [handlers]); } // src/hooks/useWallet.tsx import { encodeFunctionData } from "viem"; // src/store/useStore.ts import { create as create2 } from "zustand"; var useStore = create2((set) => ({ walletReady: false, setWalletReady: (inited) => set({ walletReady: inited }), tgAppAuthCode: "", setTgAppAuthCode: (code) => set({ tgAppAuthCode: code }), emailLoginKey: "", setEmailLoginKey: (key) => set({ emailLoginKey: key }) })); var useStore_default = useStore; // src/hooks/useWallet.tsx import { toAccount } from "viem/accounts"; import { createWalletClient } from "viem"; import { useEffect as useEffect9, useMemo as useMemo3 } from "react"; import { encodeDeployData } from "viem"; // src/context/ModalContext.tsx import { useState as useState7, useCallback, createContext, useContext, useRef as useRef2 } from "react"; import { createPortal } from "react-dom"; // src/ui/index.ts var ui_exports = {}; __export(ui_exports, { AlphaAvatar: () => AlphaAvatar, Button: () => Button, Checkbox: () => Checkbox, ConfirmModal: () => ConfirmModal, Drawer: () => Drawer, Field: () => Field, HashPanel: () => HashPanel_default, Input: () => Input, Lottie: () => Lottie_default, Modal: () => Modal, ModalDrawer: () => ModalDrawer, ModalWithHeader: () => ModalWithHeader, Overlay: () => Overlay, Popover: () => Popover, Radio: () => Radio, Skeleton: () => Skeleton_default, Switch: () => Switch, Tabs: () => Tabs }); // src/ui/Drawer/index.tsx import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime"; function Drawer({ children, showClose = true, onClose, isOpen = false, title, zIndex = 100, onBack }) { if (!isOpen) { return /* @__PURE__ */ jsx7(Fragment2, {}); } return /* @__PURE__ */ jsx7(Overlay, { isOpen, zIndex, children: /* @__PURE__ */ jsxs5("div", { className: "matchid-drawer", children: [ /* @__PURE__ */ jsxs5("div", { className: `matchid-drawer-header matchid-flex`, children: [ /* @__PURE__ */ jsxs5("div", { className: `matchid-drawer-header-content matchid-flex`, children: [ onBack && /* @__PURE__ */ jsx7(ArrowLeftIcon, { height: 25, width: 24, className: "matchid-drawer-header-back", onClick: onBack }), title ] }), showClose && /* @__PURE__ */ jsx7(CloseRoundIcon, { className: "matchid-drawer-header-close", onClick: onClose }) ] }), children ] }) }); } // src/ui/HashPanel/index.tsx import { useEffect as useEffect7, useState as useState5 } from "react"; // src/ui/ModalDrawer/index.tsx import { jsx as jsx8 } from "react/jsx-runtime"; function ModalDrawer({ title, drawerTitleVisible = true, ...props }) { const isDownMd = useDownMd(); if (isDownMd) { return /* @__PURE__ */ jsx8(ModalWithHeader, { ...props, title }); } return /* @__PURE__ */ jsx8(Drawer, { ...props, title: drawerTitleVisible ? title : null }); } // src/hooks/useHash.ts import { useQuery } from "@tanstack/react-query"; import { createPublicClient, http } from "viem"; function useHash({ hash, chain, refetchInterval, enabled = true }) { return useQuery( { queryKey: ["txhash", hash, chain], queryFn: async () => { if (!chain || !hash) return false; const publicClient = createPublicClient({ chain, transport: http() }); try { const receipt = await publicClient.getTransactionReceipt({ hash }); if (!receipt) { return 0; } matchlog_default.log("getTransactionReceipt", receipt); if (receipt.status === "success") { return 1; } return -1; } catch (error) { console.error("getTransactionReceiptError", error); } return -99; }, enabled: !!chain && !!hash && enabled, refetchInterval // refetchIntervalInBackground: false } ); } // src/ui/HashPanel/index.tsx import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime"; function HashPanel({ hash, chain, isOpen, onClose, zIndex, error }) { const [status, setStatus] = useState5("confirm"); const statusMaps = { "confirm": { text: "Confirming...", color: "#FC802D", lottie: confirm_default }, "pending": { lottie: pending_default, text: "Pending...", color: "#FC802D" }, "success": { text: "Successful!", color: "#2CBF68", lottie: success_default }, "fail": { text: "Failed!", color: "#F14141", lottie: fail_default } }; const statusValue = error ? statusMaps.fail : statusMaps[status]; const [shouldRefetch, setShouldRefetch] = useState5(true); useEffect7(() => { if (hash) { setShouldRefetch(true); setStatus("pending"); } else { setStatus("confirm"); } }, [hash]); const hashQuery = useHash({ hash, chain, refetchInterval: shouldRefetch ? 3e3 : false }); useEffect7(() => { if (hashQuery.data == 1 || hashQuery.data == -1) { setShouldRefetch(false); } if (hashQuery.data == 1) { setStatus("success"); } else if (hashQuery.data == -1) { setStatus("fail"); } else if (hashQuery.data == 0) { setStatus("pending"); } }, [hashQuery.data]); const link = chain ? `${chain?.blockExplorers?.default.url}/tx/${hash}` : ""; return /* @__PURE__ */ jsx9( ModalDrawer, { isOpen, showClose: true, onClose, zIndex, title: /* @__PURE__ */ jsx9( "div", { className: "matchid-hashpanel-header", style: { color: statusValue.color }, children: statusValue.text } ), children: /* @__PURE__ */ jsxs6("div", { className: "matchid-hashpanel-box", children: [ /* @__PURE__ */ jsxs6("div", { className: "matchid-hashpanel-content", children: [ /* @__PURE__ */ jsx9("div", { className: `matchid-hashpanel-status`, style: { color: statusValue.color }, children: statusValue.text }), statusValue.lottie && /* @__PURE__ */ jsx9(Lottie_default, { animationData: statusValue.lottie, style: { width: "96px", height: "96px" } }), hash && /* @__PURE__ */ jsxs6("div", { className: "matchid-hashpanel-hash", children: [ "Hash:", /* @__PURE__ */ jsx9("a", { href: link, target: "_blank", children: hash }) ] }), error && /* @__PURE__ */ jsx9("div", { className: "matchid-hashpanel-text", children: error }) ] }), /* @__PURE__ */ jsx9(Button, { onClick: onClose, size: "lg", block: true, children: "Back" }) ] }) } ); } function HashPanel_default(props) { return props.isOpen && /* @__PURE__ */ jsx9(HashPanel, { ...props }); } // src/ui/Popover/index.tsx import { useState as useState6 } from "react"; import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime"; function Popover({ children, content, position = "right", type = "hover", className = "", gap = "20px" }) { const [active, setActive] = useState6(false); return children && /* @__PURE__ */ jsxs7( "div", { onClick: () => { if (type == "click") { setActive(!active); } }, className: `matchid-popover-box matchid-popover-${position} matchid-popover-${type} ${className} ${type == "click" && active ? "matchid-popover-click-active" : ""}`, children: [ children, /* @__PURE__ */ jsx10("div", { style: { paddingTop: gap }, className: `matchid-popover-area`, children: /* @__PURE__ */ jsx10("div", { className: `matchid-popover-content`, children: content }) }) ] } ); } // src/ui/Switch/index.tsx import { jsx as jsx11 } from "react/jsx-runtime"; function Switch({ size = "default", checked = false, loading = false, onChange, className, disabled = false, ...props }) { const onClick = () => { if (!disabled && !loading) { onChange && onChange(!checked); } }; return /* @__PURE__ */ jsx11("div", { onClick, className: `matchid-switch matchid-switch-${size} ${checked ? "matchid-switch-checked" : ""} ${disabled ? "matchid-switch-disabled" : ""} ${loading ? "matchid-switch-loading" : ""}`, ...props, children: loading ? /* @__PURE__ */ jsx11(LoadingIcon_default, { className: "matchid-switch-loading-icon", size: size == "default" ? 24 : 18, color: "var(--matchid-swicth-loading-color)" }) : /* @__PURE__ */ jsx11("div", { className: "matchid-switch-ball" }) }); } // src/ui/AlphaAvatar/index.tsx import { useMemo as useMemo2 } from "react"; import { jsx as jsx12 } from "react/jsx-runtime"; function AlphaAvatar({ name, size = "default", className = "", style }) { const avatar = useMemo2(() => { if (name) { const char = name[0].toUpperCase(); if (char.match(/[a-zA-Z0-9]/)) { return char; } } return ""; }, [name]); const numberSize = typeof size === "number" ? size : size === "sm" ? 24 : size === "default" ? 40 : 64; return /* @__PURE__ */ jsx12("div", { className: `matchid-alpha-avatar ${className}`, style: { width: numberSize, height: numberSize, fontSize: Math.ceil(numberSize / 2), ...style }, children: avatar }); } // src/ui/Radio/index.tsx import { jsx as jsx13 } from "react/jsx-runtime"; function Radio({ checked = false, onChange, size = 24, color = "#FC802D", className = "", style = {} }) { return /* @__PURE__ */ jsx13("div", { onClick: onChange, className: `matchid-radio ${className} ${checked ? "matchid-radio-checked" : ""}`, style: { width: size, height: size, ...style, // @ts-ignore "--matchid-radio-checked": color }, children: checked && /* @__PURE__ */ jsx13("div", { className: `matchid-radio-content`, style: { width: Math.floor(size * 0.7), height: Math.floor(size * 0.7) } }) }); } // src/ui/Skeleton/index.tsx import { Fragment as Fragment3, jsx as jsx14 } from "react/jsx-runtime"; var Skeleton = ({ style = {}, className = "", width = 40, height = 40, radius = 5, loading = true, children }) => { if (!loading) { return /* @__PURE__ */ jsx14(Fragment3, { children }); } const skeletonStyle = { width, height, borderRadius: radius, ...style }; return /* @__PURE__ */ jsx14( "div", { className: "matchid-skeleton " + className, style: skeletonStyle } ); }; var Skeleton_default = Skeleton; // src/ui/Tabs/index.tsx import { jsx as jsx15 } from "react/jsx-runtime"; function Tabs(props) { return /* @__PURE__ */ jsx15("div", { className: `matchid-tabs`, children: props.tabs.map((tab, index) => { return /* @__PURE__ */ jsx15("div", { onClick: () => props.setActiveTab(index), className: `matchid-tab ${props.activeTab === index ? "matchid-tab-active" : ""}`, children: tab }, index); }) }); } // src/ui/Lottie/index.tsx import { useLottie } from "lottie-react"; var LazyLottie = (props) => { const options = { animationData: props.animationData, loop: true, autoplay: true }; const { View } = useLottie(options, props.style); return View; }; var Lottie_default = LazyLottie; // src/ui/Checkbox/index.tsx import { jsx as jsx16 } from "react/jsx-runtime"; function Checkbox({ checked = false, onChange }) { return checked ? /* @__PURE__ */ jsx16(CheckboxCheckedIcon, { onClick: () => onChange?.(false) }) : /* @__PURE__ */ jsx16(CheckboxIcon, { onClick: () => onChange?.(true) }); } // src/context/ModalContext.tsx import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime"; var ModalContext = createContext(null); function ModalProvider({ children }) { const [modalState, setModalState] = useState7({ modals: [], highestZIndex: 100 }); const highestIndexRef = useRef2(100); const getNextIndex = useCallback(() => { highestIndexRef.current += 1; return highestIndexRef.current; }, []); const closeModal = useCallback((index) => { setModalState((prevState) => ({ modals: prevState.modals.filter((modal) => modal.index !== index), highestZIndex: prevState.highestZIndex })); }, []); const show = useCallback((content, index) => { setModalState((prevState) => { const modalIndex = index ?? getNextIndex(); const newZIndex = prevState.highestZIndex + 1; return { modals: [...prevState.modals, { visible: true, index: modalIndex, zIndex: newZIndex, content, close: () => closeModal(modalIndex) }], highestZIndex: newZIndex }; }); }, [getNextIndex, closeModal]); const open = useCallback((props) => { setModalState((prevState) => { const modalIndex = props.index ?? getNextIndex(); const newZIndex = prevState.highestZIndex + 1; return { modals: [...prevState.modals, { visible: true, index: modalIndex, zIndex: newZIndex, close: () => closeModal(modalIndex), content: ({ close, zIndex }) => /* @__PURE__ */ jsx17(ModalDrawer, { showClose: true, isOpen: true, onClose: close, title: props.title, zIndex, onBack: props.onBack, children: /* @__PURE__ */ jsx17(props.content, { close, zIndex }) }) }], highestZIndex: newZIndex }; }); }, [getNextIndex, closeModal]); const modalElements = modalState.modals.map( (modal) => modal.visible ? createPortal( /* @__PURE__ */ jsx17(modal.content, { zIndex: modal.zIndex, close: modal.close }, modal.index), document.body ) : null ); return /* @__PURE__ */ jsxs8(ModalContext.Provider, { value: { show, open }, children: [ children, modalElements ] }); } function useModal() { const context = useContext(ModalContext); if (!context) { throw new Error("useModal must be used within a ModalProvider"); } return context; } // src/store/useTransactionStore.ts import { create as create3 } from "zustand"; import { devtools as devtools2, persist as persist2 } from "zustand/middleware"; var persistedState2 = persist2( (set, get) => ({ transactions: {}, addTransaction: (data) => { set((state) => { const updatedTransactions = { ...state.transactions, [`${data.chainId}-${data.address}`]: [data.info, ...state.transactions[`${data.chainId}-${data.address}`] || []] }; return { transactions: updatedTransactions }; }); }, removeTransaction: (data) => { set((state) => { const updatedTransactions = { ...state.transactions, [`${data.chainId}-${data.address}`]: (state.transactions[`${data.chainId}-${data.address}`] || []).filter((tx) => tx.hash !== data.hash) }; return { transactions: updatedTransactions }; }); } }), { name: "match-transactions-local" } ); var useTransactionStore = create3(devtools2(persistedState2)); var useTransactionStore_default = useTransactionStore; // src/hooks/useWallet.tsx import { jsx as jsx18 } from "react/jsx-runtime"; var AppClientId = "react-sdk-" + getVersion(); function useWallet() { const { address, wallet: walletConfig } = useLocalStore_default(); const { walletReady } = useStore_default(); const modal = useModal(); const { addTransaction } = useTransactionStore_default(); const isRecovered = async () => { const res = await window.matchProvider.waitUntilWalletMessage({ method: "isRecovered" }); return res.isRecovered; }; const signMessage2 = async ({ message, chainType = "ethereum" /* Ethereum */ }) => { try { const res = await window.matchProvider.waitUntilWalletMessage({ method: "signMessage", data: { message, chainType } }); return res.message; } catch (error) { console.error("sdk.wallet.message", error); throw error; } }; const signTransaction = async ({ transaction, chainType = "ethereum" /* Ethereum */, chain }) => { try { const res = await window.matchProvider.waitUntilWalletMessage({ method: "signTransaction", data: { transaction, chainType, chain } }); return res.message; } catch (error) { console.error("sdk.wallet.transaction", error); throw error; } }; const evmAccount = useMemo3(() => { try { return address ? toAccount({ address, async signMessage({ message }) { return await signMessage2({ message, chainType: "ethereum" /* Ethereum */ }); }, async signTransaction(transaction, options) { const { account, chain, ...restTransaction } = transaction; console.log("qwe-sign-transaction", restTransaction, options); return await signTransaction({ transaction: { ...restTransaction }, chainType: "ethereum" /* Ethereum */, chain: { id: chain?.id || restTransaction.chainId, name: chain?.name, nativeCurrency: { name: chain?.nativeCurrency?.name || "ETH", symbol: chain?.nativeCurrency?.symbol || "ETH", decimals: chain?.nativeCurrency?.decimals || 18 }, rpcUrls: chain?.rpcUrls } }); }, async signTypedData(typedData) { return "0x"; } }) : void 0; } catch (error) { console.error(`qwe-evm-account-error ${address}`, error); return void 0; } }, [address]); useEffect9(() => { matchlog_default.log("qwe-evmAccount", evmAccount); }, [evmAccount]); const realCreateWalletClient = (parameters) => { if (!evmAccount) { return; } const obj = createWalletClient({ ...parameters, account: evmAccount }); const sendTransaction = async (transaction) => { const { chain, ...restTransaction } = transaction; const chainId = chain ? chain.id : await obj.getChainId(); const _chain = chain || obj.chain; const transactionId = Date.now().toString() + Math.random().toString().slice(6); window.matchProvider.transactionMessageIntervalMap[transactionId] = { transaction, func: async () => { try { const { chain: chain2, account, ...prepareTransactionRequest // @ts-ignore } = await obj.prepareTransactionRequest(window.matchProvider.transactionMessageIntervalMap[transactionId].transaction); window.matchProvider.sendWalletMessage({ method: "prepareTransactionRequest", data: { prepareTransactionRequest, transactionId } }); } catch (error) { console.error(error); } }, interval: setInterval(() => { window.matchProvider.transactionMessageIntervalMap[transactionId].func(); }, 1e4) }; try { const { chain: chain2, account, ...prepareTransactionRequest // @ts-ignore } = await obj.prepareTransactionRequest(transaction); const { serializedTransaction } = await window.matchProvider.waitUntilWalletMessage({ method: "sendTransaction", data: { transactionId, transaction: { ...restTransaction }, chainType: "ethereum" /* Ethereum */, chain: { id: chainId, name: _chain?.name, nativeCurrency: _chain?.nativeCurrency, rpcUrls: _chain?.rpcUrls }, prepareTransactionRequest } }); try { const txHash = await obj.sendRawTransaction({ serializedTransaction }); addTransaction({ chainId, hash: txHash, info: { from: evmAccount.address, to: restTransaction.to, value: (restTransaction.value || 0).toString(), input: restTransaction.data, timestamp: Math.floor(Date.now() / 1e3).toString(), hash: txHash, source: "local" }, address: evmAccount.address }); modal.show((props) => { return /* @__PURE__ */ jsx18(HashPanel_default, { isOpen: true, onClose: props.close, zIndex: props.zIndex, hash: txHash, chain: _chain }); }); return txHash; } catch (error) { modal.show((props) => { return /* @__PURE__ */ jsx18(HashPanel_default, { isOpen: true, onClose: props.close, zIndex: props.zIndex, error: typeof error == "string" ? error : error.details || error.message, chain: _chain }); }); throw error; } } catch (error) { console.error("matchid-send-error", error); throw error; } finally { clearInterval(window.matchProvider.transactionMessageIntervalMap[transactionId].interval); delete window.matchProvider.transactionMessageIntervalMap[transactionId]; } }; const deployContract = async (parameters2) => { const { abi, args, bytecode, ...request3 } = parameters2; const calldata = encodeDeployData({ abi, args, bytecode }); return await sendTransaction({ ...request3, data: calldata }); }; const writeContract = async (parameters2) => { const { abi, address: address2, args, dataSuffix, functionName, ...request3 } = parameters2; const data = encodeFunctionData({ abi, args, functionName }); return await sendTransaction({ data: `${data}${dataSuffix ? dataSuffix.replace("0x", "") : ""}`, to: address2, ...request3 }); }; return { ...obj, sendTransaction, deployContract, writeContract }; }; return { walletReady, evmAccount, address, signMessage: signMessage2, signTransaction, isRecovered, createWalletClient: realCreateWalletClient // exportWallet }; } // src/hooks/useCopyClipboard.ts import copy from "copy-to-clipboard"; import { useCallback as useCallback2, useEffect as useEffect10, useState as useState9 } from "react"; function useCopyClipboard(timeout = 500) { const [isCopied, setIsCopied] = useState9(false); const staticCopy = useCallback2((text) => { const didCopy = copy(text); setIsCopied(didCopy); }, []); useEffect10(() => { if (isCopied) { const hide = setTimeout(() => { setIsCopied(false); }, timeout); return () => { clearTimeout(hide); }; } return void 0; }, [isCopied, setIsCopied, timeout]); return [isCopied, staticCopy]; } // src/context/ToastContext.tsx import { useState as useState10, useCallback as useCallback3, createContext as createContext2, useContext as useContext2 } from "react"; import { createPortal as createPortal2 } from "react-dom"; import { jsx as jsx19, jsxs as jsxs9 } from "react/jsx-runtime"; var ToastContext = createContext2(null); function ToastProvider({ children, zIndex = 299 }) { const [toasts, setToasts] = useState10([]); const removeToast = useCallback3((id) => { setToasts((prev) => prev.filter((toast) => toast.id !== id)); }, []); const show = useCallback3(({ icon, timeout = 3e3, text }) => { const id = Date.now() + Math.random(); setToasts((prev) => [...prev, { id, icon, text }]); setTimeout(() => removeToast(id), timeout); }, [removeToast]); const success = useCallback3((text, timeout) => { show({ icon: /* @__PURE__ */ jsx19(CheckRoundIcon, { color: "#2FCC00", size: 24 }), text, timeout }); }, [show]); const error = useCallback3((text, timeout) => { show({ icon: /* @__PURE__ */ jsx19(ErrorRoundIcon, { size: 24 }), text, timeout }); }, [show]); const ToastComponent = createPortal2( /* @__PURE__ */ jsx19("div", { className: "matchid-toast-box", style: { zIndex }, children: toasts.reverse().map(({ id, icon, text }) => /* @__PURE__ */ jsxs9( "div", { className: "matchid-toast", children: [ icon && /* @__PURE__ */ jsx19("span", { children: icon }), /* @__PURE__ */ jsx19("span", { children: text }) ] }, id )) }), document.body ); return /* @__PURE__ */ jsxs9(ToastContext.Provider, { value: { show, success, error }, children: [ children, ToastComponent ] }); } function useToast() { const context = useContext2(ToastContext); if (!context) { throw new Error("useToast must be used within a ToastProvider"); } return context; } // src/hooks/api/wallet.ts var wallet_exports = {}; __export(wallet_exports, { USER_IMPORT_TOKEN_LIST_KEY: () => USER_IMPORT_TOKEN_LIST_KEY, getUserWalletTransactionsApi: () => getUserWalletTransactionsApi, getWalletAssetListApi: () => getWalletAssetListApi, getWalletListApi: () => getWalletListApi, useAssetListQuery: () => useAssetListQuery, useChainListQuery: () => useChainListQuery, useImportTokenListQuery: () => useImportTokenListQuery, useWalletAssetListQuery: () => useWalletAssetListQuery, useWalletChainListQuery: () => useWalletChainListQuery, useWalletNftListQuery: () => useWalletNftListQuery, userImportTokenApi: () => userIm