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

@earthworm/wallet-sdk

v0.2.7

Published

EVM wallet utilities for browser DApps

Readme

@earthworm/wallet-sdk

Browser EVM wallet SDK for DApps (MetaMask, Coinbase, TronLink, TokenPocket, contract reads).

Install

pnpm add @earthworm/wallet-sdk ethers

Quick start

import {
  initWalletSdk,
  connectWallet,
  disconnectWallet,
  isWalletConnected,
  walletEvents,
  resolveMetaMaskInjectedProvider,
  switchToConfiguredNetwork,
  isEthereumProvider,
  isCoinbaseProvider,
  isTokenPocketProvider,
  isTronLinkProvider,
} from "@earthworm/wallet-sdk";

initWalletSdk({
  usdt: { address: "0x55d398326f99059fF775485246999027B3197955" },
});

const provider = resolveMetaMaskInjectedProvider();
if (!provider) throw new Error("MetaMask not found");

await connectWallet(provider, { chainId: "0x38" });
console.log("Connected:", isWalletConnected());

await disconnectWallet();

connectWallet() binds the provider and registers event listeners internally. You do not need to call setWalletEventProvider() separately after connect.

Restore session on page load

Some mobile wallets (e.g. TokenPocket App) reload the page when the user switches address. After reload, in-memory SDK state is lost even though the wallet still has an authorized session.

Call restoreWalletConnection() during initialization. It uses eth_accounts (no authorization popup). If authorized accounts exist, it binds the provider, restores the signer, and optionally switches chain — same as connectWallet() but without eth_requestAccounts.

import {
  initWalletSdk,
  restoreWalletConnection,
  isWalletConnected,
  resolveTokenPocketInjectedProvider,
} from "@earthworm/wallet-sdk";

initWalletSdk({
  usdt: { address: "0x55d398326f99059fF775485246999027B3197955" },
});

const provider = resolveTokenPocketInjectedProvider();
if (provider) {
  const session = await restoreWalletConnection(provider, { chainId: "0x38" });
  if (session) {
    console.log("Session restored:", session.address);
  }
}

console.log("Connected:", isWalletConnected());

| API | RPC | Popup | Use when | | --------------------------- | --------------------- | ---------- | ----------------------------------------------- | | connectWallet() | eth_requestAccounts | May prompt | User clicks Connect | | restoreWalletConnection() | eth_accounts | No | Page load / refresh with existing authorization |

Returns null when no authorized accounts are found. Event listeners are registered the same way as connectWallet().

Tip: Persist which wallet the user selected (e.g. localStorage) so after reload you know which resolve*InjectedProvider() to pass in.

Wallet detection

if (isEthereumProvider()) console.log("MetaMask is available");
if (isCoinbaseProvider()) console.log("Coinbase Wallet is available");
if (isTokenPocketProvider()) console.log("TokenPocket is available");
if (isTronLinkProvider()) console.log("TronLink is available");

Events

All walletEvents.on(...) listeners receive (wallet, event):

  • wallet: "metamask" | "coinbase" | "tokenpocket" | "tronlink" | "unknown"
  • event.name: native wallet event name (e.g. "accountsChanged", "setAccount", "disconnectWeb")
  • event.payload: normalized SDK payload for that event
  • event.raw: raw provider / postMessage arguments
walletEvents.on("accountsChanged", (wallet, event) => {
  console.log(wallet, event.name, event.payload); // string[] — current account address(es)
});

walletEvents.on("chainChanged", (wallet, event) => {
  console.log(wallet, event.payload); // hex chainId, e.g. "0x38"
});

walletEvents.on("networkSwitched", (wallet, event) => {
  console.log(wallet, event.payload); // { chainId, previousChainId, switched }
});

walletEvents.on("walletDisconnected", (wallet, event) => {
  console.log(wallet, event.payload); // { source: "app" | "provider" }
});

Event summary

| Event | When it fires | | -------------------- | ------------------------------------------------------------------------------ | | accountsChanged | Active account updated (switch account, reconnect after TronLink revoke, etc.) | | chainChanged | Wallet network changed | | networkSwitched | SDK invoked switchToConfiguredNetwork() | | walletDisconnected | Wallet or DApp disconnected |

walletDisconnected

| Source | Trigger | | -------------------- | ---------------------------------- | | source: "app" | DApp called disconnectWallet() | | source: "provider" | Wallet revoked the site connection |

MetaMask

  • Site revoked in the extension → empty accountsChangedwalletDisconnected

TronLink / TokenPocket / Coinbase

On disconnect-like events (empty accountsChanged, disconnect, etc.), the SDK silently calls eth_accounts:

  • Still has authorized addresses → sync active account → accountsChanged (no disconnect)
  • No authorized addresses → clear connection state → walletDisconnected

This supports:

  1. Single address connected, then revoked → walletDisconnected
  2. Multiple addresses, one revoked but others remain → accountsChanged with remaining address
  3. After revoke, switch to another already-connected address → accountsChanged

When TronLink, TokenPocket, or Coinbase disconnects via provider, the SDK keeps the provider bound so a later account switch can still emit accountsChanged. Calling disconnectWallet() from the DApp performs a full disconnect.

App-initiated disconnect

disconnectWallet() clears local state and, by default, calls wallet_revokePermissions so MetaMask / Coinbase remove the site from connected dApps. TronLink does not support DApp-side revoke; local state is cleared only.

const { revoked } = await disconnectWallet();
console.log(revoked ? "Wallet permission revoked" : "Local disconnect only");

Pass { revokePermissions: false } to skip the wallet revoke request.

Switch network

import { switchToConfiguredNetwork } from "@earthworm/wallet-sdk";

await switchToConfiguredNetwork("0x38"); // BSC mainnet