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

@toncast/widget

v0.0.6

Published

Embeddable betting widget for Toncast — CDN-hosted IIFE bundle

Readme

@toncast/widget

Embeddable Toncast betting UI: market lists, pari detail, bet placement (TON or jetton via STON.fi routing), optional TonConnect (standalone or integrated with your app’s @tonconnect/ui-react).

  • CDN: major-versioned IIFE bundle (see root monorepo README for snippet).
  • npm: ESM/CJS builds plus @toncast/widget-loader for runtime script injection.
  • Theming: CSS variables and density presets — see root README “Widget white-label theming”. Responsive pari-card grid columns are set via widget.layout.grid (mobile / tablet / desktop); when mobile is 2 or 3, the widget stacks YES/NO actions vertically on narrow cards for readability.

Status: 0.0.1 (pre–1.0.0). Pin exact versions until 1.0.0. The IIFE bundle is large by design (~1.7 MB minified); monitor size on upgrades. See CHANGELOG.md.

Security: the widget prepares transactions for the user’s wallet; it does not hold keys. CDN users should prefer Subresource Integrity via the loader’s integrity option. See AGENTS.md for integrator obligations around confirmQuote and addresses.

Development: npm test runs pretest, which builds @toncast/sdk (npm --prefix ../sdk run build) so Vitest resolves an up-to-date dist from the SDK. The package-exports test that reads this package’s dist/index.js is skipped until you run npm run build here at least once.

Bet confirm / wallet errors

When confirmQuote or TonConnect sendTransaction throws, the widget uses classifyBetFlowError from @toncast/sdk, shows a localized message (bet.sendError.* keys via resolveBetSendErrorTranslationKey), and logs technicalSummary to the dev console as [ToncastWidget] Bet send failed: …. The inline card includes Close (bet.sendError.dismiss) and an optional Technical details disclosure with the same summary. Heuristics for wallet “user did not send” depend on @tonconnect/ui-react error strings; upgrade TonConnect alongside the widget if messages change.

Subscribing to bet events

Two surfaces, one event. Pick the one that matches how you mounted the widget — both deliver the same { pariId, amount, side } payload after a bet transaction is sent.

React component (<Widget> / @toncast/widget/react)

import { Widget } from "@toncast/widget/react";

<Widget
  config={config}
  onBet={({ pariId, amount, side }) => {
    analytics.track("bet_sent", { pariId, amount: amount.toString(), side });
  }}
/>;

The prop is forwarded through a stable context, so an inline arrow doesn’t re-render descendants.

Imperative class (ToncastWidget / CDN bundle)

import { ToncastWidget } from "@toncast/widget";

const widget = new ToncastWidget(config);
widget.on("bet", ({ pariId, amount, side }) => {
  // …
});
widget.mount(document.getElementById("toncast-widget")!);

Also exposes mount, unmount, and error events, plus a dispose() method for full teardown. Listeners that throw fire the error event instead of bubbling.

When you discard the imperative instance entirely, call dispose() — it unmounts if needed and clears all on() listeners. unmount() alone keeps listeners so a remount reuses the same handlers; use off() to remove individual listeners without disposing.

Removed in 0.0.1: the legacy widget.onBet config callback. Use one of the two channels above — they are functionally identical.

Render error hook

For host-side logging or analytics, set widget.onRenderError on the config object, or pass onRenderError on <Widget /> from @toncast/widget/react (the prop overrides config.widget.onRenderError when both are set). It is invoked from the internal ErrorBoundary after a render error is caught — the inline retry card is still shown to the user.

Bet amount input (locales)

In locales where the decimal separator is a comma (e.g. German), a lone dot with exactly three digits after it (e.g. 35.572) is treated as ambiguous (English-style fraction vs. thousands). The amount field shows a hint and does not apply the value until the user uses the locale’s decimal mark (e.g. 35,572 for thirty-five point five seven two).

Language: config vs in-widget picker

Two layers can set the language; they coexist by design.

| Source | When applied | Wins on conflict | | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | | config.widget.language (host) | Every render where the value changes — pushed via client.setLanguage(), the ToncastClient is not recreated and WS subscriptions stay alive | Yes — the host’s preference always trumps a stale picker selection because it is reapplied every render | | In-widget language picker (header) | User clicks a flag — calls the SDK’s setLanguage directly | Wins until the host changes config.widget.language again |

To lock the language entirely (no picker drift): pass config.widget.language and never change it. The picker still allows the user to switch locally, but any host-driven re-render with the same config.widget.language will snap it back.

To let the user choose freely: omit config.widget.language. The widget then honours the SDK’s persisted choice, falling back to navigator.language and finally "en".

widget.referral follows the same model — pushed via client.setReferral() on change. In standalone mode (you don’t pass a client.instance), removing widget.referral from config also clears it on the SDK client. In integrated mode (you pass your own ToncastClient), an absent widget.referral is treated as “host manages this directly” and is never cleared by the widget.