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

@chipi-stack/starknet-connector

v0.5.0

Published

Connect with Chipi: a starknet-react / get-starknet connector and Wallet Standard wallet for the Chipi hosted smart-account wallet (passkey, gasless). Works next to injected wallets like Bramble, Ready and Braavos. No browser extension, no WalletConnect.

Readme

@chipi-stack/starknet-connector

"Connect with Chipi" for Starknet dApps. A starknet-react / get-starknet connector that opens the user's Chipi wallet (passkey, gasless) in a popup. No browser extension, no WalletConnect, no whitelisting. It works next to injected wallets such as Bramble, Ready and Braavos.

npm install @chipi-stack/starknet-connector

Ships ESM and CommonJS. Versions before 0.3.0 were ESM-only and failed under CommonJS resolvers (plain Node, tsx, ts-node, Jest) with ERR_PACKAGE_PATH_NOT_EXPORTED.

Use it with starknet-react

Offer Chipi next to Bramble, Ready and Braavos:

import type { ReactNode } from "react";
import {
  StarknetConfig,
  InjectedConnector,
  publicProvider,
  ready,
  braavos,
} from "@starknet-react/core";
import { mainnet } from "@starknet-react/chains";
import { chipi } from "@chipi-stack/starknet-connector";

const connectors = [
  chipi(), // "Connect with Chipi"
  new InjectedConnector({ options: { id: "bramble", name: "Bramble" } }),
  ready(), // Ready (formerly Argent X)
  braavos(),
];

export function Providers({ children }: { children: ReactNode }) {
  return (
    <StarknetConfig chains={[mainnet]} provider={publicProvider()} connectors={connectors}>
      {children}
    </StarknetConfig>
  );
}

Your useConnect / useAccount flow now offers all four. With Chipi, account.execute(...) and account.signMessage(...) go to the user's Chipi wallet: gasless, signed with their passkey.

Notes for @starknet-react/core 5:

  • List every wallet yourself. useInjectedConnectors only picks up objects with the legacy keys (provider, isConnected, enable, isPreauthorized). Neither window.starknet_chipi nor window.starknet_bramble has all of them, so it finds neither.
  • injected({ id: "bramble" }) also works, but in 5.0.3 injected() takes only id. The label is then the wallet's own name once Bramble has injected, and "bramble" before that.
  • argent() is an alias of ready(). Use ready().
  • InjectedConnector looks up window.starknet_bramble each time it is used, so Bramble's late injection is fine. autoConnect runs once on mount, though: if Bramble has not injected by then, the last Bramble session is not restored.

Use it with get-starknet v4

get-starknet v4 (@starknet-io/get-starknet-core) lists every window.starknet* object that has id, name, version, icon, request, on and off. Creating a Chipi connector puts window.starknet_chipi on the page, so both wallets show up:

import { getStarknet } from "@starknet-io/get-starknet-core";
import { chipi } from "@chipi-stack/starknet-connector";

declare const connectButton: HTMLButtonElement;
declare function pickedWalletId(): "chipi" | "bramble"; // from your wallet picker

// Puts window.starknet_chipi on the page.
chipi();

// Bramble injects window.starknet_bramble after page load, then fires
// "starknet#initialized". Scan after that, or after a short timeout.
function waitForInjectedWallets(timeoutMs = 3000): Promise<void> {
  return new Promise((resolve) => {
    if ("starknet_bramble" in window) return resolve();
    const done = () => {
      clearTimeout(timer);
      window.removeEventListener("starknet#initialized", done);
      resolve();
    };
    const timer = setTimeout(done, timeoutMs);
    window.addEventListener("starknet#initialized", done);
  });
}

await waitForInjectedWallets();
const gsc = getStarknet();
const wallets = await gsc.getAvailableWallets();
// Both are listed: wallets.map((w) => w.id) includes "chipi" and "bramble".

// Prompts only from a click: Chipi opens its popup, Bramble its side panel.
connectButton.onclick = async () => {
  const wallet = wallets.find((w) => w.id === pickedWalletId());
  if (wallet) await gsc.enable(wallet);
};

getAuthorizedWallets() and getLastConnectedWallet() send wallet_getPermissions to every wallet at page load. Chipi answers that locally with [] and does not open its popup (see Passive calls). There is no silent reconnect: the user clicks connect again on each page load.

Bramble's guide notes that get-starknet v3 also requires a provider key, which Bramble lacks. Chipi's object lacks it too.

Wallet Standard (get-starknet v5 and v6)

@starknet-io/get-starknet-discovery (5.0.0 and 6.0.6 ship the same code) builds its list in createStore():

  • Wallet Standard wallets register through wallet-standard:register-wallet, at any time.
  • window.starknet* objects are scanned once, when createStore() runs, and wrapped as injected wallets. Entries are de-duplicated by name, and a Wallet Standard entry wins.

Bramble has no Wallet Standard registration, so get-starknet v5/v6 lists it only if window.starknet_bramble exists when createStore() runs. Register Chipi as a Wallet Standard wallet so the order does not matter:

import { registerChipiStandardWallet } from "@chipi-stack/starknet-connector";

const unregister = registerChipiStandardWallet({
  walletUrl: "https://wallet.chipipay.com", // default
});
// later: unregister();

It dispatches wallet-standard:register-wallet and answers wallet-standard:app-ready, with no extra dependency. It exposes starknet:walletApi, standard:connect, standard:disconnect and standard:events on starknet:0x534e5f4d41494e (mainnet), backed by the same popup. connect({ silent: true }) never opens the popup. Its default name is "Chipi"; the connector's is "Connect with Chipi". If window.starknet_chipi also exists when the store is created, the store lists two Chipi entries: pass register: false to the connector, or give both the same name. createChipiStandardWallet(options) builds the wallet without registering it.

Works next to Bramble

  • No id collision. Chipi is window.starknet_chipi with id "chipi". Bramble is window.starknet_bramble with id "bramble". get-starknet v4 and starknet-react key wallets by id, so both are listed.
  • Neither writes window.starknet.
  • When each object exists. window.starknet_chipi exists only after a ChipiConnector is created (unless register: false). disconnect() removes it until the next connect(). window.starknet_bramble appears after page load, followed by a starknet#initialized event.
  • A wallet scan never opens Chipi. Since 0.5.0, the calls scanners send at page load are answered without opening the popup (see Passive calls).
  • Bramble's own rules apply to Bramble. Prompts only from a click, at most 5 pending prompts per site, strict params (an extra key fails with 114), a typed-data chainId equal to its active network, no wallet_disconnect (114), one account per site. Signatures are [r, s] for OpenZeppelin and Braavos accounts and ["1", "0", pub, r, s] for Argent accounts: verify them with the account's is_valid_signature, not by length. starknet-react's InjectedConnector.disconnect() does not send wallet_disconnect. See Bramble rules to follow.

How it works

your dApp                         Chipi hosted wallet (wallet.chipipay.com)
─────────                         ──────────────────────────────────────────
ChipiConnector.connect()
   └─ opens a popup ───────────►  /connect  (the user's authenticated wallet)
   └─ postMessage  ◄──────────►   approval UI (passkey + gasless paymaster)
account.execute(calls)
   └─ wallet_addInvokeTransaction ─► user approves ─► sponsored tx ─► tx hash
  • The connector only carries messages. It opens the hosted wallet in a popup and forwards get-starknet wallet_* calls over postMessage. It holds no keys and signs nothing.
  • Each request is posted right away and matched to its answer by id. Several can be in flight at once; the connector neither queues nor rejects them.
  • account() wraps the channel in a starknet.js WalletAccount, so the dApp gets a standard AccountInterface.
  • There is no silent reconnect. ready() is true only after connect() succeeded on this page. Call connect() from a click: it opens a popup.
  • Chipi is mainnet-only. chainId() always returns SN_MAIN.

Passive calls

While no wallet window is open (before connect(), or after the user closed it), the connector answers these calls itself and does not open the popup. Once the window is open, they go to the wallet.

| Call | Answer with no wallet window open | | ------------------------------------------------- | --------------------------------- | | wallet_getPermissions | [] | | wallet_requestAccounts with silent_mode: true | [] | | wallet_requestChainId | "0x534e5f4d41494e" (SN_MAIN) |

wallet_requestAccounts without silent_mode: true opens the popup, so send it from a click.

Options

import { chipi } from "@chipi-stack/starknet-connector";

chipi({
  walletUrl: "https://wallet.chipipay.com", // hosted wallet base URL (default)
  id: "chipi", // connector id (default); the window key stays starknet_chipi
  name: "Connect with Chipi", // display name (default)
  icon: "data:image/png;base64,...", // default: a 48x48 PNG data URI
  register: true, // put window.starknet_chipi on the page (default; no-op in SSR)
  transport: {
    windowName: "chipi-wallet", // default: a new random name per open
    windowFeatures: "popup=yes,width=420,height=680", // default
    openTimeoutMs: 180_000, // wait for the wallet page to load (default)
    requestTimeoutMs: 120_000, // per request; 0 disables (default)
  },
});

chipi(options) is the same as new ChipiConnector(options).

Errors

The connector rejects with an Error. Check err.code first, then err.message.

| code or message | When | | ----------------------------------------------- | ---------------------------------------------------------------------------------------- | | code "UNSUPPORTED_CHAIN" | connect({ chainIdHint }) with a chain other than SN_MAIN. No popup opens. | | code "popup_blocked" | The browser blocked the popup: connect() did not run from a click. | | message "wallet_open_timeout" | The wallet page did not load within transport.openTimeoutMs (180 s). The popup closes. | | code "REQUEST_TIMEOUT" | No answer within transport.requestTimeoutMs (120 s). | | code "POPUP_CLOSED" | A request after the user closed the wallet window. Call connect() again from a click. | | code 4001, message "User closed the wallet" | The user closed the wallet window while a request was waiting. | | code 4001, message "disconnected" | disconnect() ran while a request, or the wallet page load, was waiting. | | message "chipi_no_account" | The wallet returned no account on connect. | | message "chipi_not_connected" | account() before connect(). | | message "chipi_connector_requires_browser" | The popup was requested without window (SSR). | | numeric code from the wallet (113 … 163) | The wallet's own error, passed through with its message (see below). |

Wallets built on createChipiWindowObject from @chipi-stack/chipi-react answer 113 (the user refused), 114 (no calls, or typed data with no chainId or one for another chain), 115 (account already deployed), 116 (deployment data not available) and 163 (unsupported method, including wallet_disconnect and wallet_switchStarknetChain, or another failure).

Events

  • The wallet's accountsChanged / networkChanged become starknet-react change events ({ account, chainId }). An empty account list emits disconnect.
  • disconnect() closes the popup and removes window.starknet_chipi. The next connect() puts it back.

Compatibility

  • @starknet-react/core >= 3 (peer), tested against 5.0.3.
  • starknet >= 8.1.2 (peer). WalletAccount.connect is the same in 8 and 9.
  • Starknet mainnet only.
  • Popup only. The in-app-browser ("parent") mode is in the transport but not exposed.

MIT · docs.chipipay.com · example