@mysten/dapp-kit
Version:
A collection of React hooks and components for interacting with the Sui blockchain and wallets.
416 lines (383 loc) • 17.4 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
// vanilla-extract-css-ns:src/components/styling/StyleMarker.css.ts.vanilla.css?source=OndoZXJlKCopIHsKICBib3gtc2l6aW5nOiBib3JkZXItYm94OwogIGNvbG9yOiB2YXIoLS1kYXBwLWtpdC1jb2xvcnMtYm9keSk7CiAgZm9udC1mYW1pbHk6IHZhcigtLWRhcHAta2l0LXR5cG9ncmFwaHktZm9udEZhbWlseSk7CiAgZm9udC1zaXplOiB2YXIoLS1kYXBwLWtpdC1mb250V2VpZ2h0cy1ub3JtYWwpOwogIGZvbnQtc3R5bGU6IHZhcigtLWRhcHAta2l0LXR5cG9ncmFwaHktZm9udFN0eWxlKTsKICBmb250LXdlaWdodDogdmFyKC0tZGFwcC1raXQtZm9udFdlaWdodHMtbm9ybWFsKTsKICBsaW5lLWhlaWdodDogdmFyKC0tZGFwcC1raXQtdHlwb2dyYXBoeS1saW5lSGVpZ2h0KTsKICBsZXR0ZXItc3BhY2luZzogdmFyKC0tZGFwcC1raXQtdHlwb2dyYXBoeS1sZXR0ZXJTcGFjaW5nKTsKfQo6d2hlcmUoYnV0dG9uKSB7CiAgYXBwZWFyYW5jZTogbm9uZTsKICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDsKICBmb250LXNpemU6IGluaGVyaXQ7CiAgZm9udC1mYW1pbHk6IGluaGVyaXQ7CiAgbGluZS1oZWlnaHQ6IGluaGVyaXQ7CiAgbGV0dGVyLXNwYWNpbmc6IGluaGVyaXQ7CiAgY29sb3I6IGluaGVyaXQ7CiAgYm9yZGVyOiAwOwogIHBhZGRpbmc6IDA7CiAgbWFyZ2luOiAwOwp9Cjp3aGVyZShhKSB7CiAgdGV4dC1kZWNvcmF0aW9uOiBub25lOwogIGNvbG9yOiBpbmhlcml0OwogIG91dGxpbmU6IG5vbmU7Cn0KOndoZXJlKG9sLCB1bCkgewogIGxpc3Qtc3R5bGU6IG5vbmU7CiAgbWFyZ2luOiAwOwogIHBhZGRpbmc6IDA7Cn0KOndoZXJlKGgxLCBoMiwgaDMsIGg0LCBoNSwgaDYpIHsKICBmb250LXNpemU6IGluaGVyaXQ7CiAgZm9udC13ZWlnaHQ6IGluaGVyaXQ7CiAgbWFyZ2luOiAwOwp9
var init_StyleMarker_css_ts_vanilla = __esm({
"vanilla-extract-css-ns:src/components/styling/StyleMarker.css.ts.vanilla.css?source=OndoZXJlKCopIHsKICBib3gtc2l6aW5nOiBib3JkZXItYm94OwogIGNvbG9yOiB2YXIoLS1kYXBwLWtpdC1jb2xvcnMtYm9keSk7CiAgZm9udC1mYW1pbHk6IHZhcigtLWRhcHAta2l0LXR5cG9ncmFwaHktZm9udEZhbWlseSk7CiAgZm9udC1zaXplOiB2YXIoLS1kYXBwLWtpdC1mb250V2VpZ2h0cy1ub3JtYWwpOwogIGZvbnQtc3R5bGU6IHZhcigtLWRhcHAta2l0LXR5cG9ncmFwaHktZm9udFN0eWxlKTsKICBmb250LXdlaWdodDogdmFyKC0tZGFwcC1raXQtZm9udFdlaWdodHMtbm9ybWFsKTsKICBsaW5lLWhlaWdodDogdmFyKC0tZGFwcC1raXQtdHlwb2dyYXBoeS1saW5lSGVpZ2h0KTsKICBsZXR0ZXItc3BhY2luZzogdmFyKC0tZGFwcC1raXQtdHlwb2dyYXBoeS1sZXR0ZXJTcGFjaW5nKTsKfQo6d2hlcmUoYnV0dG9uKSB7CiAgYXBwZWFyYW5jZTogbm9uZTsKICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDsKICBmb250LXNpemU6IGluaGVyaXQ7CiAgZm9udC1mYW1pbHk6IGluaGVyaXQ7CiAgbGluZS1oZWlnaHQ6IGluaGVyaXQ7CiAgbGV0dGVyLXNwYWNpbmc6IGluaGVyaXQ7CiAgY29sb3I6IGluaGVyaXQ7CiAgYm9yZGVyOiAwOwogIHBhZGRpbmc6IDA7CiAgbWFyZ2luOiAwOwp9Cjp3aGVyZShhKSB7CiAgdGV4dC1kZWNvcmF0aW9uOiBub25lOwogIGNvbG9yOiBpbmhlcml0OwogIG91dGxpbmU6IG5vbmU7Cn0KOndoZXJlKG9sLCB1bCkgewogIGxpc3Qtc3R5bGU6IG5vbmU7CiAgbWFyZ2luOiAwOwogIHBhZGRpbmc6IDA7Cn0KOndoZXJlKGgxLCBoMiwgaDMsIGg0LCBoNSwgaDYpIHsKICBmb250LXNpemU6IGluaGVyaXQ7CiAgZm9udC13ZWlnaHQ6IGluaGVyaXQ7CiAgbWFyZ2luOiAwOwp9"() {
}
});
// src/components/styling/StyleMarker.css.ts
var require_StyleMarker_css = __commonJS({
"src/components/styling/StyleMarker.css.ts"() {
"use strict";
init_StyleMarker_css_ts_vanilla();
}
});
// src/components/AccountDropdownMenu.tsx
import { formatAddress } from "@mysten/sui/utils";
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import clsx3 from "clsx";
// src/hooks/useSuiClientQuery.ts
import { queryOptions, useQuery, useSuspenseQuery } from "@tanstack/react-query";
import { useMemo as useMemo2 } from "react";
// src/hooks/useSuiClient.ts
import { useContext } from "react";
// src/components/SuiClientProvider.tsx
import { getFullnodeUrl, isSuiClient, SuiClient } from "@mysten/sui/client";
import { createContext, useMemo, useState } from "react";
import { jsx } from "react/jsx-runtime";
var SuiClientContext = createContext(null);
var DEFAULT_NETWORKS = {
localnet: { url: getFullnodeUrl("localnet") }
};
// src/hooks/useSuiClient.ts
function useSuiClientContext() {
const suiClient = useContext(SuiClientContext);
if (!suiClient) {
throw new Error(
"Could not find SuiClientContext. Ensure that you have set up the SuiClientProvider"
);
}
return suiClient;
}
// src/hooks/useSuiClientQuery.ts
function useSuiClientQuery(...args) {
const [method, params, { queryKey = [], ...options } = {}] = args;
const suiContext = useSuiClientContext();
return useQuery({
...options,
queryKey: [suiContext.network, method, params, ...queryKey],
queryFn: async () => {
return await suiContext.client[method](params);
}
});
}
// src/hooks/useResolveSuiNSNames.ts
function useResolveSuiNSName(address, options) {
return useSuiClientQuery(
"resolveNameServiceNames",
{
address,
limit: 1
},
{
...options,
refetchOnWindowFocus: false,
retry: false,
select: (data) => data.data.length > 0 ? data.data[0] : null,
enabled: !!address && options?.enabled !== false
}
);
}
// src/hooks/wallet/useWalletStore.ts
import { useContext as useContext2 } from "react";
import { useStore } from "zustand";
// src/contexts/walletContext.ts
import { createContext as createContext2 } from "react";
var WalletContext = createContext2(null);
// src/hooks/wallet/useWalletStore.ts
function useWalletStore(selector) {
const store = useContext2(WalletContext);
if (!store) {
throw new Error(
"Could not find WalletContext. Ensure that you have set up the WalletProvider."
);
}
return useStore(store, selector);
}
// src/hooks/wallet/useAccounts.ts
function useAccounts() {
return useWalletStore((state) => state.accounts);
}
// src/hooks/wallet/useDisconnectWallet.ts
import { useMutation } from "@tanstack/react-query";
// src/constants/walletMutationKeys.ts
var walletMutationKeys = {
all: { baseScope: "wallet" },
connectWallet: formMutationKeyFn("connect-wallet"),
autoconnectWallet: formMutationKeyFn("autoconnect-wallet"),
disconnectWallet: formMutationKeyFn("disconnect-wallet"),
signPersonalMessage: formMutationKeyFn("sign-personal-message"),
signTransaction: formMutationKeyFn("sign-transaction"),
signAndExecuteTransaction: formMutationKeyFn("sign-and-execute-transaction"),
switchAccount: formMutationKeyFn("switch-account"),
reportTransactionEffects: formMutationKeyFn("report-transaction-effects")
};
function formMutationKeyFn(baseEntity) {
return function mutationKeyFn(additionalKeys = []) {
return [{ ...walletMutationKeys.all, baseEntity }, ...additionalKeys];
};
}
// src/errors/walletErrors.ts
var WalletNotConnectedError = class extends Error {
};
var WalletAccountNotFoundError = class extends Error {
};
// src/hooks/wallet/useCurrentWallet.ts
function useCurrentWallet() {
const currentWallet = useWalletStore((state) => state.currentWallet);
const connectionStatus = useWalletStore((state) => state.connectionStatus);
const supportedIntents = useWalletStore((state) => state.supportedIntents);
switch (connectionStatus) {
case "connecting":
return {
connectionStatus,
currentWallet: null,
isDisconnected: false,
isConnecting: true,
isConnected: false,
supportedIntents: []
};
case "disconnected":
return {
connectionStatus,
currentWallet: null,
isDisconnected: true,
isConnecting: false,
isConnected: false,
supportedIntents: []
};
case "connected": {
return {
connectionStatus,
currentWallet,
isDisconnected: false,
isConnecting: false,
isConnected: true,
supportedIntents
};
}
}
}
// src/hooks/wallet/useDisconnectWallet.ts
function useDisconnectWallet({
mutationKey,
...mutationOptions
} = {}) {
const { currentWallet } = useCurrentWallet();
const setWalletDisconnected = useWalletStore((state) => state.setWalletDisconnected);
return useMutation({
mutationKey: walletMutationKeys.disconnectWallet(mutationKey),
mutationFn: async () => {
if (!currentWallet) {
throw new WalletNotConnectedError("No wallet is connected.");
}
try {
await currentWallet.features["standard:disconnect"]?.disconnect();
} catch (error) {
console.error("Failed to disconnect the application from the current wallet.", error);
}
setWalletDisconnected();
},
...mutationOptions
});
}
// src/hooks/wallet/useSwitchAccount.ts
import { useMutation as useMutation2 } from "@tanstack/react-query";
function useSwitchAccount({
mutationKey,
...mutationOptions
} = {}) {
const { currentWallet } = useCurrentWallet();
const setAccountSwitched = useWalletStore((state) => state.setAccountSwitched);
return useMutation2({
mutationKey: walletMutationKeys.switchAccount(mutationKey),
mutationFn: async ({ account }) => {
if (!currentWallet) {
throw new WalletNotConnectedError("No wallet is connected.");
}
const accountToSelect = currentWallet.accounts.find(
(walletAccount) => walletAccount.address === account.address
);
if (!accountToSelect) {
throw new WalletAccountNotFoundError(
`No account with address ${account.address} is connected to ${currentWallet.name}.`
);
}
setAccountSwitched(accountToSelect);
},
...mutationOptions
});
}
// src/components/AccountDropdownMenu.css.ts
var connectedAccount = "AccountDropdownMenu_connectedAccount__div2ql0";
var menuContainer = "AccountDropdownMenu_menuContainer__div2ql1";
var menuContent = "AccountDropdownMenu_menuContent__div2ql2";
var menuItem = "AccountDropdownMenu_menuItem__div2ql3";
var separator = "AccountDropdownMenu_separator__div2ql5";
var switchAccountMenuItem = "AccountDropdownMenu_switchAccountMenuItem__div2ql4";
// src/components/icons/CheckIcon.tsx
import { jsx as jsx2 } from "react/jsx-runtime";
function CheckIcon(props) {
return /* @__PURE__ */ jsx2("svg", { xmlns: "http://www.w3.org/2000/svg", width: 16, height: 16, fill: "none", ...props, children: /* @__PURE__ */ jsx2(
"path",
{
fill: "currentColor",
d: "m11.726 5.048-4.73 5.156-1.722-1.879a.72.72 0 0 0-.529-.23.722.722 0 0 0-.525.24.858.858 0 0 0-.22.573.86.86 0 0 0 .211.576l2.255 2.458c.14.153.332.24.53.24.2 0 .391-.087.532-.24l5.261-5.735A.86.86 0 0 0 13 5.63a.858.858 0 0 0-.22-.572.722.722 0 0 0-.525-.24.72.72 0 0 0-.529.23Z"
}
) });
}
// src/components/icons/ChevronIcon.tsx
import { jsx as jsx3 } from "react/jsx-runtime";
function ChevronIcon(props) {
return /* @__PURE__ */ jsx3("svg", { xmlns: "http://www.w3.org/2000/svg", width: 16, height: 16, fill: "none", ...props, children: /* @__PURE__ */ jsx3(
"path",
{
stroke: "#A0B6C3",
strokeLinecap: "round",
strokeLinejoin: "round",
strokeWidth: 1.5,
d: "m4 6 4 4 4-4"
}
) });
}
// src/components/styling/StyleMarker.tsx
import { Slot } from "@radix-ui/react-slot";
import { forwardRef } from "react";
// src/constants/styleDataAttribute.ts
var styleDataAttributeName = "data-dapp-kit";
var styleDataAttributeSelector = `[${styleDataAttributeName}]`;
var styleDataAttribute = { [styleDataAttributeName]: "" };
// src/components/styling/StyleMarker.tsx
var import_StyleMarker_css = __toESM(require_StyleMarker_css());
import { jsx as jsx4 } from "react/jsx-runtime";
var StyleMarker = forwardRef(({ children, ...props }, forwardedRef) => /* @__PURE__ */ jsx4(Slot, { ref: forwardedRef, ...props, ...styleDataAttribute, children }));
StyleMarker.displayName = "StyleMarker";
// src/components/ui/Button.tsx
import { Slot as Slot2 } from "@radix-ui/react-slot";
import clsx from "clsx";
import { forwardRef as forwardRef2 } from "react";
// src/components/ui/Button.css.ts
import { createRuntimeFn as _7a468 } from "@vanilla-extract/recipes/createRuntimeFn";
var buttonVariants = _7a468({ defaultClassName: "Button_buttonVariants__x1s81q0", variantClassNames: { variant: { primary: "Button_buttonVariants_variant_primary__x1s81q1", outline: "Button_buttonVariants_variant_outline__x1s81q2" }, size: { md: "Button_buttonVariants_size_md__x1s81q3", lg: "Button_buttonVariants_size_lg__x1s81q4" } }, defaultVariants: { variant: "primary", size: "md" }, compoundVariants: [] });
// src/components/ui/Button.tsx
import { jsx as jsx5 } from "react/jsx-runtime";
var Button = forwardRef2(
({ className, variant, size, asChild = false, ...props }, forwardedRef) => {
const Comp = asChild ? Slot2 : "button";
return /* @__PURE__ */ jsx5(
Comp,
{
...props,
className: clsx(buttonVariants({ variant, size }), className),
ref: forwardedRef
}
);
}
);
Button.displayName = "Button";
// src/components/ui/Text.tsx
import { Slot as Slot3 } from "@radix-ui/react-slot";
import clsx2 from "clsx";
import { forwardRef as forwardRef3 } from "react";
// src/components/ui/Text.css.ts
import { createRuntimeFn as _7a4682 } from "@vanilla-extract/recipes/createRuntimeFn";
var textVariants = _7a4682({ defaultClassName: "Text__2bv1ur0", variantClassNames: { size: { sm: "Text_textVariants_size_sm__2bv1ur1" }, weight: { normal: "Text_textVariants_weight_normal__2bv1ur2", medium: "Text_textVariants_weight_medium__2bv1ur3", bold: "Text_textVariants_weight_bold__2bv1ur4" }, color: { muted: "Text_textVariants_color_muted__2bv1ur5", danger: "Text_textVariants_color_danger__2bv1ur6" }, mono: { true: "Text_textVariants_mono_true__2bv1ur7" } }, defaultVariants: { size: "sm", weight: "normal" }, compoundVariants: [] });
// src/components/ui/Text.tsx
import { jsx as jsx6 } from "react/jsx-runtime";
var Text = forwardRef3(
({
children,
className,
asChild = false,
as: Tag = "div",
size,
weight,
color,
mono,
...textProps
}, forwardedRef) => {
return /* @__PURE__ */ jsx6(
Slot3,
{
...textProps,
ref: forwardedRef,
className: clsx2(textVariants({ size, weight, color, mono }), className),
children: asChild ? children : /* @__PURE__ */ jsx6(Tag, { children })
}
);
}
);
Text.displayName = "Text";
// src/components/AccountDropdownMenu.tsx
import { jsx as jsx7, jsxs } from "react/jsx-runtime";
function AccountDropdownMenu({ currentAccount }) {
const { mutate: disconnectWallet } = useDisconnectWallet();
const { data: domain } = useResolveSuiNSName(
currentAccount.label ? null : currentAccount.address
);
const accounts = useAccounts();
return /* @__PURE__ */ jsxs(DropdownMenu.Root, { modal: false, children: [
/* @__PURE__ */ jsx7(StyleMarker, { children: /* @__PURE__ */ jsx7(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { size: "lg", className: connectedAccount, children: [
/* @__PURE__ */ jsx7(Text, { mono: true, weight: "bold", children: currentAccount.label ?? domain ?? formatAddress(currentAccount.address) }),
/* @__PURE__ */ jsx7(ChevronIcon, {})
] }) }) }),
/* @__PURE__ */ jsx7(DropdownMenu.Portal, { children: /* @__PURE__ */ jsx7(StyleMarker, { className: menuContainer, children: /* @__PURE__ */ jsxs(DropdownMenu.Content, { className: menuContent, children: [
accounts.map((account) => /* @__PURE__ */ jsx7(
AccountDropdownMenuItem,
{
account,
active: currentAccount.address === account.address
},
account.address
)),
/* @__PURE__ */ jsx7(DropdownMenu.Separator, { className: separator }),
/* @__PURE__ */ jsx7(
DropdownMenu.Item,
{
className: clsx3(menuItem),
onSelect: () => disconnectWallet(),
children: "Disconnect"
}
)
] }) }) })
] });
}
function AccountDropdownMenuItem({
account,
active
}) {
const { mutate: switchAccount } = useSwitchAccount();
const { data: domain } = useResolveSuiNSName(account.label ? null : account.address);
return /* @__PURE__ */ jsxs(
DropdownMenu.Item,
{
className: clsx3(menuItem, switchAccountMenuItem),
onSelect: () => switchAccount({ account }),
children: [
/* @__PURE__ */ jsx7(Text, { mono: true, children: account.label ?? domain ?? formatAddress(account.address) }),
active ? /* @__PURE__ */ jsx7(CheckIcon, {}) : null
]
}
);
}
export {
AccountDropdownMenu,
AccountDropdownMenuItem
};
//# sourceMappingURL=AccountDropdownMenu.js.map