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

@asentum/connect

v0.1.9

Published

Drop-in wallet connect for AsentumChain dapps — <ConnectButton /> + hooks (useWallet, useAsentum). Zero CSS imports, zero heavy deps.

Readme

@asentum/connect

Wallet connect for AsentumChain dapps: a <ConnectButton />, a connect modal (browser extension, Telegram, create-new), and hooks (useWallet, useAsentum, useContract, useBalance). No CSS to import, react as the only peer dep. Styling is via props and inline styles.

npm install @asentum/connect

Full guide with worked examples: https://asentum.com/docs/guides/wallet-connect

Quick start

Wrap your app once, then drop the button anywhere:

import { AsentumProvider, ConnectButton } from '@asentum/connect';

export default function App({ children }) {
  return (
    <AsentumProvider
      rpc="https://testnet.asentum.com"
      dappName="My Dapp"                       // shown in the wallet's approval prompt
      telegramBot="AsentumWalletBot"           // optional: adds the Telegram option
      onConnect={(address) => console.log('linked', address)}
    >
      <ConnectButton />
      {children}
    </AsentumProvider>
  );
}

In Next.js the provider is a client component, so it needs 'use client' at the top of the file that renders it.

Styling the button

<ConnectButton text="Sign in" bg="#111318" color="#fff" border="1px solid #333" radius={8} />

Props: text, bg, color, border, radius, menu (copy/disconnect menu when connected, on by default; with it off a second click disconnects), plus className / style escape hatches. style is merged last, so it wins over every other prop.

The modal itself is not themeable. It is deliberately the same across Asentum dapps so users recognise it. For a different look, use your own trigger.

Your own trigger

<ConnectButton> renders the modal for you. If you replace the button with your own markup, mount <ConnectModal /> yourself once inside the provider, or nothing will open:

import { ConnectModal, useWallet } from '@asentum/connect';

function Header() {
  const { connected, address, openConnect, disconnect } = useWallet();
  return (
    <>
      {connected
        ? <button onClick={disconnect}>{address.slice(0, 10)}…</button>
        : <button onClick={openConnect}>Connect</button>}
      <ConnectModal />
    </>
  );
}

Hooks

import { useWallet, useAsentum, useContract, useBalance } from '@asentum/connect';

function Swap() {
  const { address, connected, openConnect } = useWallet();
  const client = useAsentum();
  const dex = useContract('ase1yourcontract...');
  const { balance, refresh } = useBalance();      // native ASE, wei string, polls every 12s

  async function trade() {
    if (!connected) return openConnect();
    const out = await dex.view('quote', ['1', tokenIn, amountIn]);            // read, free
    const tx  = await dex.call('swapExactIn', ['1', tokenIn, amountIn, '1']); // write, signed
    const receipt = await client.waitReceipt(tx);
    if (!receipt.success) throw new Error('swap reverted');
    refresh();
  }
}

API

  • <AsentumProvider> — rpc? (default https://testnet.asentum.com), dappName?, telegramBot?, botApi? (default https://wallet.asentum.com), onCreateWallet?, onConnect?, onDisconnect?, persist? (remember the address across page loads, on by default), extensionStatus? ('ready' by default: the browser-extension option is offered and connectable; pass 'soon' to render it disabled with a Soon chip), allowCustomRpc? (on by default: lets the person using your dapp point reads at their own node; see "Custom RPC" below).
  • <ConnectButton> — the button; renders the modal automatically.
  • <ConnectModal> — the modal on its own, for custom triggers.
  • useWallet() → { address, ase1Address, connected, connecting, error, hasWallet, connect, disconnect, openConnect }.
  • useAsentum() → AsentumClient (view, call, transfer, deploy, waitReceipt, balanceOf).
  • useContract(addr) → { address, view(method,args), call(method,args,value) }.
  • useBalance(addr?, pollMs?) → { balance, loading, refresh }. balance is a wei decimal string.
  • useRpc() → { rpc, defaultRpc, isCustom, allowed, failing, readingFromDefault, setRpc(url), resetRpc(), readFromDefault(on) }. setRpc resolves to { ok, height?, error?, checks?, note? }.
  • <NetworkSettings />: the Network row on its own, for custom menus.
  • normalizeRpcUrl, validateRpc, formatHeight: the checks setRpc runs, usable on their own.
  • AsentumClient — the client class, usable without React for read-only scripts and back-ends. Writes need a signer, so they only work in a browser with the extension present or a paired Telegram session; to sign server-side use @asentum/sdk, which holds a key directly.
  • shortAddress(addr, lead?, tail?) and DEFAULT_RPC — small helpers. shortAddress always renders ase1.
  • toAse1, hexToAse1, ase1ToHex, isAse1, shortAse1 — ase1 (bech32, HRP ase) helpers. Show users ase1Address or toAse1(x); never show hex. address stays in the form the wallet returned it, for RPC calls. Client methods accept ase1 or hex addresses.

How it works

Reads (view, balanceOf) hit the RPC's /view and /balance (your rpc, or the user's own node if they chose one), so they need no wallet at all. Writes are routed to whichever signer the user connected with: the Asentum browser extension (window.asentum) or a paired Telegram wallet session. Either way the user is prompted to approve, and private keys never touch this library.

Custom RPC

Anyone can run an Asentum node, and validators often serve their own RPC. With allowCustomRpc on (the default) the person using your dapp can switch to their own node from the Network row in the connected menu of <ConnectButton> (also shown at the bottom of the connect modal): Change, paste the address, Save. Reset to default goes back to your rpc.

Before saving, the kit checks the node:

  1. the address is https:// (plain http:// is only accepted for localhost, 127.0.0.1 or a private network address, and an https page cannot reach a plain http node on the network anyway);
  2. GET <url>/metadata answers within 5 seconds with chain 1423 (chainIdDecimal: "1423" or chainId: "0x58f");
  3. GET <url>/v3/heads reports a numeric finalized block height.

Trailing slashes are stripped. On success the row shows Connected: block 309,120. The choice is saved in localStorage under asentum.rpc (read after mount, so server rendering always uses your rpc).

What it covers:

  • Reads from this dapp: view, balanceOf, useBalance, useContract().view and the receipt polling in waitReceipt, including after a Telegram-signed transaction.
  • Not extension-signed transactions. The Asentum browser extension signs and sends through its own RPC setting (Settings, Network RPC, in the extension). The Telegram wallet likewise broadcasts through the node set in the Telegram wallet; the kit never passes an RPC to the signer.

If the saved node stops answering, the kit does not quietly switch to another node. useRpc().failing turns true and the Network row says "Your custom RPC is not answering. Switch back to the default?" with Switch to default and Read from default for now (reads only, for this page load).

import { useRpc } from '@asentum/connect';

function NodePicker() {
  const { rpc, isCustom, setRpc, resetRpc } = useRpc();
  async function use(url: string) {
    const r = await setRpc(url);
    alert(r.ok ? `Connected: block ${r.height}` : r.error);
  }
  return isCustom ? <button onClick={resetRpc}>Back to default ({rpc})</button> : null;
}

Pass allowCustomRpc={false} to keep every read on your rpc (the Network row then only shows the host).

The create-new and telegram options are opt-in: the modal only shows them if you pass onCreateWallet / telegramBot to the provider.

License

MIT, © Asentum. Use it in your own dapp.