npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nemoprotocol/wallet-kit

v0.3.9

Published

<p align="center"><a href="https://www.nemoprotocol.com/"> <img width="480" src="https://www.nemoprotocol.com/assets/logo-3l5o1FE6.svg"/> </a></p>

Readme

Nemo Wallet Kit — Connect Sui wallets in minutes

Nemo Wallet Kit is a React toolkit that makes it easy for DApps to interact with Sui wallets. It supports the Sui Wallet Standard for automatic wallet discovery and provides a complete React integration via Provider, Hooks, and UI components.

Playground and examples: Website · Vite · Next.js (pages) · Next.js (app router)

Features

  • Wallet Standard support with auto-detection
  • React Provider and Hooks for end-to-end wallet workflows
  • Prebuilt UI components: WalletProvider, ConnectButton, ConnectModal
  • Transaction signing and execution helpers
  • Account, chain, and wallet event handling
  • Out-of-the-box styling with light/dark themes

Installation

# npm
npm install @nemoprotocol/wallet-kit @nemoprotocol/wallet-sdk @mysten/sui react react-dom

# or yarn
yarn add @nemoprotocol/wallet-kit @nemoprotocol/wallet-sdk @mysten/sui react react-dom

# or pnpm
pnpm add @nemoprotocol/wallet-kit @nemoprotocol/wallet-sdk @mysten/sui react react-dom

Then import the default styles once in your app entry:

import "@nemoprotocol/wallet-kit/style.css";

Peer dependencies: react, react-dom, @mysten/sui (tested around 1.28.x).

Quick Start

Wrap your app with WalletProvider, then render ConnectButton.

// App.tsx
import React from "react";
import { WalletProvider, ConnectButton } from "@nemoprotocol/wallet-kit";
import "@nemoprotocol/wallet-kit/style.css";

export default function App() {
  return (
    <WalletProvider>
      <div style={{ padding: 24 }}>
        <ConnectButton label="Connect Wallet" />
      </div>
    </WalletProvider>
  );
}

Use the useWallet hook anywhere under the provider:

import { useWallet } from "@nemoprotocol/wallet-kit";

export function Profile() {
  const { address, connected, disconnect } = useWallet();
  if (!connected) return null;
  return (
    <div>
      <div>Address: {address}</div>
      <button onClick={disconnect}>Disconnect</button>
    </div>
  );
}

Examples

Programmatic connect and sign + execute

import { useWallet } from "@nemoprotocol/wallet-kit";
import { Transaction } from "@mysten/sui/transactions";

export function TransferButton() {
  const { select, connected, signAndExecuteTransaction } = useWallet();

  async function handleTransfer() {
    if (!connected) {
      await select("Suiet"); // pick any available wallet name
    }

    const tx = new Transaction();
    // ... build your moves / transfers here
    const res = await signAndExecuteTransaction({ transaction: tx });
    console.log("Digest:", res.digest);
  }

  return <button onClick={handleTransfer}>Send</button>;
}

Sign a personal message

import { useWallet } from "@nemoprotocol/wallet-kit";

export function SignMessage() {
  const { connected, select, signPersonalMessage } = useWallet();

  async function onSign() {
    if (!connected) await select("Suiet");
    const message = new TextEncoder().encode("Hello Sui");
    const { messageBytes, signature } = await signPersonalMessage({ message });
    console.log({ messageBytes, signature });
  }

  return <button onClick={onSign}>Sign Message</button>;
}

Balances with hooks

import { useAccountBalance, useCoinBalance } from "@nemoprotocol/wallet-kit";

export function Balances() {
  const sui = useAccountBalance();
  const usdc = useCoinBalance({ typeArg: "0x...::usdc::USDC" });
  return (
    <div>
      <div>SUI balance: {sui.data?.toString()}</div>
      <div>USDC balance: {usdc.data?.toString()}</div>
    </div>
  );
}

Access the Sui client bound to current chain

import { useSuiClient } from "@nemoprotocol/wallet-kit";

export function LatestCheckpoint() {
  const client = useSuiClient();
  const [cp, setCp] = React.useState<string>("-");
  React.useEffect(() => {
    client.getLatestCheckpointSequenceNumber().then(setCp);
  }, [client]);
  return <span>Latest checkpoint: {cp}</span>;
}

API Reference

Components

WalletProvider

Wraps your React tree and exposes wallet state/actions via context.

Props:

  • defaultWallets?: IDefaultWallet[] — default supported wallets (from SDK)
  • chains?: Chain[] — supported chains (defaults to DefaultChains)
  • autoConnect?: boolean — auto-connect last used wallet (default: true)

ConnectButton

One-click connect button with built-in modal and account display.

Props:

  • label?: string
  • onConnectSuccess?: (walletName: string) => void
  • onConnectError?: (error: BaseError) => void
  • onDisconnectSuccess?: (walletName: string) => void
  • onDisconnectError?: (error: BaseError) => void

ConnectModal

Wallet selection modal. You can use it directly for custom triggers.

Props:

  • open?: boolean
  • theme?: "dark" | "light"
  • onOpenChange?: (open: boolean) => void
  • onConnectSuccess?: (walletName: string) => void
  • onConnectError?: (error: BaseError) => void

Hooks

useWallet()

Returns the full wallet context:

type WalletContextState = {
  // wallets & chain
  configuredWallets: IWallet[];
  detectedWallets: IWallet[];
  allAvailableWallets: IWallet[];
  chains: Chain[];
  chain: Chain | undefined;

  // connection
  name?: string;
  adapter?: IWalletAdapter;
  account?: WalletAccount;
  accounts?: WalletAccount[];
  address?: string;
  connecting: boolean;
  connected: boolean;
  status: "disconnected" | "connected" | "connecting";

  select(walletName: string): Promise<void>;
  disconnect(): Promise<void>;
  getAccounts(): readonly WalletAccount[];
  on<E extends WalletEvent>(event: E, listener: WalletEventListeners[E]): () => void;

  // signing
  signAndExecuteTransaction<Output extends SuiSignAndExecuteTransactionOutput>(
    input: { transaction: any },
    options?: ExecuteTransactionOptions
  ): Promise<Output>;
  signTransaction(input: { transaction: any }): Promise<SignedTransaction>;
  signPersonalMessage(input: { message: Uint8Array }): Promise<SuiSignPersonalMessageOutput>;

  // deprecated: prefer the methods above
  signMessage(input: { message: Uint8Array }): Promise<SuiSignMessageOutput>;
  signTransactionBlock(input: { transactionBlock: any }): Promise<SuiSignTransactionBlockOutput>;
  signAndExecuteTransactionBlock(input: { transactionBlock: any }): Promise<SuiSignAndExecuteTransactionBlockOutput>;

  // utils
  verifySignedMessage(
    input: SuiSignPersonalMessageOutput | SuiSignMessageOutput,
    publicKey: Uint8Array
  ): Promise<boolean>;
  reportTransactionEffects(input: { effects: string }): Promise<void>;
};

useAccountBalance(params?)

Convenience wrapper over useCoinBalance for a single coin (SUI by default).

Params: { typeArg?: string; chainId?: string; } — returns React Query result with data: bigint.

useCoinBalance({ address?, typeArg?, chainId? })

Returns React Query result with the coin balance as bigint.

useSuiClient()

Returns a SuiClient bound to the current chain from WalletProvider.

Styling and Theming

  • Import @nemoprotocol/wallet-kit/style.css once in your app.
  • ConnectModal supports a theme prop ("dark" | "light").
  • You can override CSS classes prefixed with wkit- in your app CSS.

Framework Notes

  • Next.js App Router: ensure client components ("use client") where you use hooks/components.
  • SSR: guard any direct window usage to client-side only; the kit itself is client-side.

FAQ

  • Wallet not found in the list?
    • The kit auto-detects any wallet implementing Wallet Standard. Ensure the extension is installed and the page is refreshed.
  • Getting chain mismatch after connecting?
    • The provider syncs to wallet chain on chainChange. Ensure your app handles chain from useWallet() instead of assuming a fixed RPC.
  • How do I customize the wallet list?
    • Pass a custom defaultWallets array to WalletProvider.

License

MIT License