@particle-network/connectkit
Version:
654 lines (636 loc) • 20.2 kB
JavaScript
"use client";
import {
getChainDisplayName,
init_chains
} from "./chunk-6YIVRHUS.mjs";
import {
StyleChainItem,
StyleChainName,
StyleCheckIcon,
StyleDropdownContent,
StyleDropdownWrapper,
StyleHoverBg,
init_styles,
init_useClickAway,
useClickAway_default
} from "./chunk-K64L2X2L.mjs";
import {
init_useChains,
init_useWalletConnections,
useChains,
useWalletConnections
} from "./chunk-USPCWZQE.mjs";
import {
circleSpinner_default,
init_circleSpinner
} from "./chunk-LPKOMA4X.mjs";
import {
init_useConnect,
useConnect
} from "./chunk-I7EXWVJH.mjs";
import {
init_useConnectors,
useConnectors
} from "./chunk-QGF3ZKLH.mjs";
import {
CheckIcon_default,
init_CheckIcon
} from "./chunk-BUW2IG4Z.mjs";
import {
init_context,
init_useAccount,
init_useConnections,
init_useMutation,
init_web3Provider,
useAccount,
useConnections,
useContext,
useMutation,
useWeb3Context
} from "./chunk-ODGVUXUQ.mjs";
import {
__esm
} from "./chunk-Y7A564BU.mjs";
// src/actions/switchAccount.ts
import {
ConnectorNotConnectedError
} from "@particle-network/connector-core";
async function switchAccount(config, parameters) {
const { connector } = parameters;
const connection = config.state.connections.get(connector.uid);
if (!connection)
throw new ConnectorNotConnectedError();
await config.storage?.setItem("recentConnectorId", connector.id);
config.setState((x) => ({
...x,
current: connector.uid
}));
return {
accounts: connection.accounts,
chainId: connection.chainId
};
}
var init_switchAccount = __esm({
"src/actions/switchAccount.ts"() {
"use strict";
}
});
// src/hooks/useSwitchAccount.ts
function useSwitchAccount(parameters) {
const { config } = useContext();
const mutationFn = async (parameters2) => {
return await switchAccount(config, parameters2);
};
const { mutate, mutateAsync, ...result } = useMutation(mutationFn, parameters);
return {
...result,
connectors: useConnections().map((connection) => connection.connector),
switchAccount: mutate,
switchAccountAsync: mutateAsync
};
}
var init_useSwitchAccount = __esm({
"src/hooks/useSwitchAccount.ts"() {
"use strict";
init_switchAccount();
init_context();
init_useConnections();
init_useMutation();
}
});
// src/actions/switchChain.ts
import {
ChainNotConfiguredError,
SwitchChainNotSupportedError
} from "@particle-network/connector-core";
async function switchChain(config, parameters) {
const { addEthereumChainParameter, chainId } = parameters;
const connection = config.state.connections.get(parameters.connector?.uid ?? config.state.current);
if (connection) {
const connector = connection.connector;
if (!connector.switchChain)
throw new SwitchChainNotSupportedError({ connector });
const chain2 = await connector.switchChain({
addEthereumChainParameter,
chainId
});
return chain2;
}
const chain = config.chains.find((x) => x.id === chainId);
if (!chain)
throw new ChainNotConfiguredError();
config.setState((x) => ({ ...x, chainId }));
return chain;
}
var init_switchChain = __esm({
"src/actions/switchChain.ts"() {
"use strict";
}
});
// src/hooks/useSwitchChain.ts
var useSwitchChain;
var init_useSwitchChain = __esm({
"src/hooks/useSwitchChain.ts"() {
"use strict";
init_switchChain();
init_context();
init_useMutation();
useSwitchChain = (parameters) => {
const { config } = useContext();
const mutationFn = async (parameters2) => {
return await switchChain(config, parameters2);
};
const { status, data, error, mutate, mutateAsync } = useMutation(mutationFn, parameters);
return {
status,
data,
error,
switchChain: mutate,
switchChainAsync: mutateAsync
};
};
}
});
// src/actions/getChainId.ts
function getChainId(config) {
return config.state.chainId;
}
var init_getChainId = __esm({
"src/actions/getChainId.ts"() {
"use strict";
}
});
// src/actions/watchChainId.ts
function watchChainId(config, parameters) {
const { onChange } = parameters;
return config.subscribe((state) => state.chainId, onChange);
}
var init_watchChainId = __esm({
"src/actions/watchChainId.ts"() {
"use strict";
}
});
// src/hooks/useChainId.ts
import { useSyncExternalStore } from "react";
function useChainId() {
const { config } = useContext();
return useSyncExternalStore(
(onChange) => watchChainId(config, { onChange }),
() => getChainId(config),
() => getChainId(config)
);
}
var init_useChainId = __esm({
"src/hooks/useChainId.ts"() {
"use strict";
init_getChainId();
init_watchChainId();
init_context();
}
});
// src/components/chainDropdown/index.tsx
import { getChainIcon, getChainType, isEVMChain } from "@particle-network/connector-core";
import { AnimatePresence, motion } from "framer-motion";
import { useEffect, useMemo, useRef, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
var ChainDropdown, chainDropdown_default;
var init_chainDropdown = __esm({
"src/components/chainDropdown/index.tsx"() {
"use strict";
init_CheckIcon();
init_useChainId();
init_useChains();
init_useClickAway();
init_useConnect();
init_useConnections();
init_useConnectors();
init_useSwitchAccount();
init_useSwitchChain();
init_useWalletConnections();
init_chains();
init_circleSpinner();
init_styles();
ChainDropdown = ({
visible,
setVisible,
clickAwayElements,
maxHeight,
supportChain = true,
top
}) => {
const chainList = useChains();
const chainId = useChainId();
const { switchChainAsync, status: switchStatus } = useSwitchChain();
const [walletConnection] = useWalletConnections();
const { switchAccountAsync } = useSwitchAccount();
const connectors = useConnectors();
const { connectAsync } = useConnect();
const connections = useConnections();
const [hoverIndex, setHoverIndex] = useState(-1);
const [targetChainId, setTargetChainId] = useState();
const dropdownRef = useRef(null);
const timer = useRef(void 0);
const dropdownWrapperRef = useRef(null);
const selectedItemRef = useRef(null);
const isParticle = useMemo(() => {
return Boolean(walletConnection && walletConnection.walletProps.connector.walletConnectorType === "particleAuth");
}, [walletConnection]);
const currentChainId = useMemo(() => {
return supportChain ? chainId : -1;
}, [chainId, supportChain]);
const switchSuccess = useMemo(() => {
return targetChainId === currentChainId;
}, [targetChainId, currentChainId]);
const currentChainType = useMemo(() => {
if (chainList && chainList?.length && currentChainId) {
const chain = chainList.find((item) => item.id === currentChainId);
if (chain) {
return getChainType(chain);
}
return "";
} else {
return "";
}
}, [chainList, currentChainId]);
useEffect(() => {
if (switchSuccess && visible) {
setVisible(false);
setTargetChainId(void 0);
}
}, [switchSuccess, visible, setVisible]);
useEffect(() => {
}, [currentChainId]);
useClickAway_default(() => {
setVisible(false);
}, [dropdownRef, ...clickAwayElements]);
useEffect(() => {
setTimeout(() => {
if (visible && dropdownWrapperRef.current && selectedItemRef.current) {
const dropdownWrapper = dropdownWrapperRef.current;
const selectedItem = selectedItemRef.current;
const wrapperHeight = dropdownWrapper.clientHeight;
const itemHeight = selectedItem.clientHeight;
const itemTop = selectedItem.offsetTop;
const scrollTop = itemTop - wrapperHeight / 2 + itemHeight / 2;
const currentScrollTop = dropdownWrapper.scrollTop;
if (itemTop < currentScrollTop || itemTop + itemHeight > currentScrollTop + wrapperHeight) {
dropdownWrapper.scrollTop = scrollTop;
}
}
}, 50);
}, [visible, currentChainId]);
return /* @__PURE__ */ jsx(StyleDropdownContent, { ref: dropdownRef, top: top || 46, children: /* @__PURE__ */ jsx(AnimatePresence, { children: visible && /* @__PURE__ */ jsx(
motion.div,
{
style: {
overflow: "hidden"
},
initial: { height: 0, opacity: 0 },
animate: { height: "auto", opacity: 1 },
exit: { height: 0, opacity: 0 },
children: /* @__PURE__ */ jsxs(
StyleDropdownWrapper,
{
ref: dropdownWrapperRef,
style: {
maxHeight: maxHeight || 320
},
children: [
/* @__PURE__ */ jsx(StyleHoverBg, { index: hoverIndex }),
chainList.map((chain) => /* @__PURE__ */ jsxs(
StyleChainItem,
{
selected: currentChainId === chain.id,
ref: currentChainId === chain.id ? selectedItemRef : null,
onClick: async () => {
try {
if (chain.id === currentChainId)
return;
setTargetChainId(chain.id);
if (isParticle && getChainType(chain) !== currentChainType) {
const id = isEVMChain(chain) ? "particleEVM" : "particleSolana";
const connector = connectors.find((item) => item.id === id);
const isAuthorized = await connector.isAuthorized();
if (!isAuthorized) {
const provider = isEVMChain(chain) ? window.particle?.ethereum : window.particle?.solana;
await provider.connect();
await connectAsync({
connector,
chainId: chain.id
});
return;
} else {
if (connections.some((connection) => connection.connector.id === id)) {
await switchAccountAsync({ connector });
} else {
await connectAsync({
connector,
chainId: chain.id
});
return;
}
}
}
await switchChainAsync({
chainId: chain.id
});
} catch (error) {
setVisible(false);
setTargetChainId(void 0);
}
},
onMouseEnter: () => {
clearTimeout(timer.current);
setHoverIndex(chainList.findIndex((item) => item.id === chain.id));
},
onMouseLeave: () => {
timer.current = setTimeout(() => {
setHoverIndex(-1);
}, 100);
},
children: [
/* @__PURE__ */ jsx(
"div",
{
style: {
marginRight: "10px"
},
children: /* @__PURE__ */ jsx(
circleSpinner_default,
{
inset: 0,
width: 20,
height: 20,
connecting: Boolean(!switchSuccess && switchStatus === "loading" && chain.id === targetChainId),
logo: /* @__PURE__ */ jsx("img", { src: getChainIcon(chain), alt: chain.name })
}
)
}
),
/* @__PURE__ */ jsx(StyleChainName, { children: getChainDisplayName(chain) }),
/* @__PURE__ */ jsx(StyleCheckIcon, { children: currentChainId === chain.id && /* @__PURE__ */ jsx(CheckIcon_default, {}) })
]
},
chain.id
))
]
}
)
}
) }) });
};
chainDropdown_default = ChainDropdown;
}
});
// src/components/connectedWidget/styles.ts
import { styled } from "styled-components";
var StyleConnectedWidgetContainer, StyleInfoBox, StyleChainSection, StyleChainIcon, StyleChainName2, StyleDivider, StyleAddressSection, StyleIconWrapper, StyleWalletAddress, StyleSwitchNetwork;
var init_styles2 = __esm({
"src/components/connectedWidget/styles.ts"() {
"use strict";
StyleConnectedWidgetContainer = styled.div`
position: relative;
display: inline-block;
`;
StyleInfoBox = styled.div`
display: inline-block;
border-radius: var(--pcm-rounded-lg);
background: var(--pcm-body-background);
box-shadow: var(--pcm-modal-box-shadow);
max-width: 400px;
vertical-align: middle;
line-height: normal;
padding: 5px 0px;
box-sizing: content-box;
`;
StyleChainSection = styled.div`
cursor: ${(props) => props.selected ? "pointer" : "default"};
display: inline-block;
gap: 8px;
height: 28px;
margin: 0 10px;
padding: 0 6px;
border-radius: 6px;
background-color: var(--pcm-body-background);
transition: background-color 0.3s;
${(props) => props.selected && `
&:hover {
background-color: var(--pcm-body-background-secondary);
}
`}
.wrap {
display: flex;
align-items: center;
gap: 4px;
height: 100%;
}
`;
StyleChainIcon = styled.img`
width: 20px;
height: 20px;
border-radius: 50%;
`;
StyleChainName2 = styled.div`
font-size: 14px;
line-height: 1;
position: relative;
top: -1px;
`;
StyleDivider = styled.div`
display: inline-block;
width: 1px;
height: 19px;
background: var(--pcm-secondary-button-bankground);
`;
StyleAddressSection = styled.div`
display: inline-block;
gap: 8px;
height: 28px;
margin: 0 10px;
padding: 0 6px;
border-radius: 6px;
background-color: var(--pcm-body-background);
transition: background-color 0.3s;
position: relative;
top: 3px;
&:hover {
background-color: var(--pcm-body-background-secondary);
}
.wrap {
display: flex;
align-items: center;
gap: 4px;
height: 100%;
}
`;
StyleIconWrapper = styled.div`
width: 20px;
height: 20px;
`;
StyleWalletAddress = styled.div`
font-size: 14px;
`;
StyleSwitchNetwork = styled.div`
font-size: 14px;
color: var(--pcm-error-color);
display: flex;
gap: 6px;
align-items: center;
`;
}
});
// src/hooks/useEmbeddedWallet.ts
import { useMemo as useMemo2 } from "react";
var useEmbeddedWallet;
var init_useEmbeddedWallet = __esm({
"src/hooks/useEmbeddedWallet.ts"() {
"use strict";
init_context();
useEmbeddedWallet = () => {
const { config } = useContext();
const walletPlugin = useMemo2(() => {
const plugin = config.plugins.find((plugin2) => plugin2.id === "wallet");
if (plugin) {
return plugin;
}
return void 0;
}, []);
const isCanOpen = useMemo2(() => {
return walletPlugin?.getPlugin().walletOptions.widgetIntegration !== "embedded";
}, [walletPlugin]);
if (!walletPlugin) {
return null;
}
return {
openWallet: walletPlugin.openWallet.bind(walletPlugin),
destory: walletPlugin.destory.bind(walletPlugin),
getWalletIFrame: walletPlugin.getWalletIFrame.bind(walletPlugin),
isCanOpen
};
};
}
});
// src/hooks/useParticleAuth.ts
import { useCallback, useMemo as useMemo3 } from "react";
var useParticleAuth;
var init_useParticleAuth = __esm({
"src/hooks/useParticleAuth.ts"() {
"use strict";
init_useAccount();
useParticleAuth = () => {
const { connector } = useAccount();
const isParticle = useMemo3(() => {
return connector?.walletConnectorType === "particleAuth";
}, [connector]);
const particle = useMemo3(() => {
if (isParticle && "particle" in window && window.particle?._internal) {
return window?.particle;
}
return null;
}, [isParticle]);
const createParticleMethod = useCallback(
(methodName) => {
return (...args) => {
if (!isParticle || !particle || !particle._internal || !particle._internal[methodName]) {
throw new Error("The current wallet is not a particle wallet or particle is not initialized");
}
return (particle?._internal[methodName])(...args);
};
},
[isParticle, particle]
);
return {
needRestoreWallet: () => {
return Boolean(window?.particle?._internal?.needRestoreWallet);
},
hasMasterPassword: createParticleMethod("hasMasterPassword"),
hasPaymentPassword: createParticleMethod("hasPaymentPassword"),
openAccountAndSecurity: createParticleMethod("openAccountAndSecurity"),
openChangeMasterPassword: createParticleMethod("openChangeMasterPassword"),
openChangePaymentPassword: createParticleMethod("openChangePaymentPassword"),
openLinkLoginAccount: createParticleMethod("openLinkLoginAccount"),
openRestoreByMasterPassword: createParticleMethod("openRestoreByMasterPassword"),
openSetMasterPassword: createParticleMethod("openSetMasterPassword"),
openSetSecurityAccount: createParticleMethod("openSetSecurityAccount"),
openSetPaymentPassword: createParticleMethod("openSetPaymentPassword"),
getUserInfo: createParticleMethod("getUserInfo")
};
};
}
});
// src/actions/getClient.ts
import {
isEVMChain as isEVMChain2
} from "@particle-network/connector-core";
function getClient(config, parameters = {}) {
const chainId = parameters.chainId || config.state.chainId;
const chain = config.chains.find((chain2) => chain2.id === chainId);
if (!chain) {
return null;
}
const authWalletConnector = config.getWalletConnector("particleAuth");
if (authWalletConnector) {
return authWalletConnector.getClient(chainId);
}
if (isEVMChain2(chain)) {
return config.getWalletConnector("evmWallet").getClient(chainId);
}
return config.getWalletConnector("solanaWallet").getClient(chainId);
}
var init_getClient = __esm({
"src/actions/getClient.ts"() {
"use strict";
}
});
// src/hooks/usePublicClient.ts
function usePublicClient(parameters = {}) {
const { chainId } = parameters;
const { config } = useContext();
return getClient(config, { chainId });
}
var init_usePublicClient = __esm({
"src/hooks/usePublicClient.ts"() {
"use strict";
init_getClient();
init_context();
}
});
// src/hooks/useWallets.ts
var useWallets;
var init_useWallets = __esm({
"src/hooks/useWallets.ts"() {
"use strict";
init_web3Provider();
useWallets = () => {
const { wallets } = useWeb3Context();
return wallets;
};
}
});
export {
useSwitchAccount,
init_useSwitchAccount,
useSwitchChain,
init_useSwitchChain,
chainDropdown_default,
init_chainDropdown,
StyleConnectedWidgetContainer,
StyleInfoBox,
StyleChainSection,
StyleChainIcon,
StyleChainName2 as StyleChainName,
StyleDivider,
StyleAddressSection,
StyleWalletAddress,
StyleSwitchNetwork,
init_styles2 as init_styles,
useEmbeddedWallet,
init_useEmbeddedWallet,
useParticleAuth,
init_useParticleAuth,
usePublicClient,
init_usePublicClient,
useWallets,
init_useWallets
};
//# sourceMappingURL=chunk-GHYL2SS2.mjs.map