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

unimove-dapp-kit

v0.7.0

Published

A comprehensive dApp kit for building cross-chain dApps on Sui and IOTA with runtime chain switching, built-in UI components, and unified APIs.

Readme

Unimove dApp Kit

Ask DeepWiki

Unimove dApp Kit is a React toolkit that unifies the app experience for both Sui and IOTA. It provides a single surface of providers, hooks, and UI components that keep full type safety while letting you switch chains at runtime.

Highlights

  • 🔗 Unified API – the same hook/component works for Sui and IOTA
  • 🧠 Strong typing – hook arguments/returns are inferred from the active chain
  • 🔁 Runtime chain switching – flip between chains without re-wiring your app
  • 🧰 First-party wallet UI – drop-in ConnectButton, ConnectModal, etc.
  • 📦 Tree-shakeable – ships both ESM and CJS bundles

Installation

npm install unimove-dapp-kit
# or
yarn add unimove-dapp-kit
# or
pnpm add unimove-dapp-kit

Peer dependencies

Install the SDKs for the chains you plan to support (plus React / React Query):

# Sui support
npm install @mysten/dapp-kit @mysten/sui @tanstack/react-query

# IOTA support
npm install @iota/dapp-kit @iota/iota-sdk @tanstack/react-query

# React runtime (if not already present)
npm install react react-dom

# Optional (Next.js projects)
npm install next

Concepts

Unimove exposes two core providers and a suite of hooks/components. Internally a shared chain registry resolves the correct implementation based on the active chain, so you interact with a single API surface.

Chain context

ClientProvider sets the active chain ("sui" | "iota") and exposes it through the useChain() hook. All other hooks/components automatically read from this context unless you explicitly pass a chain argument.

Networks

Provide a networks map describing the RPC endpoints you care about. The structure matches the underlying dApp kits:

const networks = {
  testnet: { url: "https://fullnode.testnet.sui.io" },
};

The same structure can include additional metadata (variables) if required by your app.


Quick start

1. Wrap your application

import { ClientProvider, WalletProvider } from "unimove-dapp-kit";
import { getFullnodeUrl as suiUrl } from "@mysten/sui/client";

const suiNetworks = {
  testnet: { url: suiUrl("testnet") },
};

export function App() {
  return (
    <ClientProvider
      chain="sui"
      networks={suiNetworks}
      defaultNetwork="testnet"
    >
      <WalletProvider>
        <YourRoutes />
      </WalletProvider>
    </ClientProvider>
  );
}

2. Drop in wallet UI

import { ConnectButton } from "unimove-dapp-kit";

export function WalletSection() {
  return <ConnectButton />;
}

3. Query on-chain data

import { useClientQuery } from "unimove-dapp-kit";

export function Balance({ owner }: { owner: string }) {
  const { data, isPending, error } = useClientQuery("getBalance", { owner });

  if (isPending) return <div>Loading…</div>;
  if (error) return <div>Error: {String(error.message ?? error)}</div>;

  return <div>Balance: {data?.totalBalance}</div>;
}

4. Switching chains at runtime

import { useState } from "react";
import { ClientProvider, WalletProvider } from "unimove-dapp-kit";
import { getFullnodeUrl as suiUrl } from "@mysten/sui/client";
import { getNetwork, Network as IotaNetwork } from "@iota/iota-sdk/client";

const chainNetworks = {
  sui: {
    testnet: { url: suiUrl("testnet") },
  },
  iota: {
    testnet: { url: getNetwork(IotaNetwork.Testnet)?.url ?? "" },
  },
};

export function MultiChainApp() {
  const [chain, setChain] = useState<"sui" | "iota">("sui");

  return (
    <ClientProvider
      chain={chain}
      networks={chainNetworks[chain]}
      defaultNetwork="testnet"
    >
      <WalletProvider>
        <button onClick={() => setChain((c) => (c === "sui" ? "iota" : "sui"))}>
          Switch chain
        </button>
        <ConnectButton />
      </WalletProvider>
    </ClientProvider>
  );
}

API reference

Providers

| Provider | Description | | --- | --- | | ClientProvider | Configures the active chain and RPC networks. Accepts all props from the underlying chain provider. | | WalletProvider | Enables wallet discovery, connection, and theming. Props are unioned from Sui/IOTA implementations (unsupported props are ignored per chain). |

Components

| Component | Description | | --- | --- | | ConnectButton | Unified wallet connection button. Automatically renders the correct chain-specific UI. | | ConnectModal | Full-screen wallet chooser/dialog. | | ClientQuery | Render-prop component that executes a client query and passes loading/data/error state to children. |

Hooks

Wallet hooks

  • useAccounts()
  • useAutoConnectWallet()
  • useConnectWallet()
  • useCurrentAccount()
  • useCurrentWallet()
  • useDisconnectWallet()
  • useSignAndExecuteTransaction()
  • useSignPersonalMessage()
  • useSignTransaction()
  • useSwitchAccount()
  • useWallets()

Client hooks

  • useClient() – access the raw RPC client instance
  • useClientQuery() – single RPC query (with typing)
  • useClientInfiniteQuery() – infinite/paginated queries
  • useClientMutation() – RPC mutations (writes)
  • useClientQueries() – execute multiple queries at once

Each hook accepts an optional chain argument if you need to call a different chain than the current context.

Context hook

  • useChain() – returns the active chain identifier

Types & Themes

The package re-exports all shared types and theme helpers so you can type your own wrappers or apply consistent styling:

import type {
  ChainType,
  NetworkName,
  Networks,
  UnimoveClientConfig,
  UnimoveSignedTransaction,
  // …other unified types
} from "unimove-dapp-kit";

import { lightTheme, darkTheme } from "unimove-dapp-kit";

Refer to src/types and src/themes for the full catalog.


Usage snippets

Wallet workflow

import {
  useCurrentAccount,
  useConnectWallet,
  useDisconnectWallet,
} from "unimove-dapp-kit";

function WalletInfo() {
  const account = useCurrentAccount();
  const { mutate: connect } = useConnectWallet();
  const { mutate: disconnect } = useDisconnectWallet();

  return (
    <section>
      {account ? (
        <>
          <p>Address: {account.address}</p>
          <button onClick={() => disconnect()}>Disconnect</button>
        </>
      ) : (
        <button onClick={() => connect({ wallet: account?.wallet })}>
          Connect Wallet
        </button>
      )}
    </section>
  );
}

Execute a transaction

import { useSignAndExecuteTransaction } from "unimove-dapp-kit";

function SubmitTransaction({ transaction }: { transaction: unknown }) {
  const { mutate: signAndExecute, isPending } = useSignAndExecuteTransaction();

  return (
    <button
      disabled={isPending}
      onClick={() => signAndExecute({ transaction })}
    >
      {isPending ? "Submitting…" : "Submit"}
    </button>
  );
}

Scripts

| Script | Description | | --- | --- | | npm run build | Build the package (tsup) | | npm run check | Run ESLint and TypeScript checks | | npm run typecheck | TypeScript only | | npm run lint | ESLint only |


License

Apache-2.0