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

@thetanuts-finance/widget

v0.1.3

Published

Embeddable Thetanuts trading widgets (Web Components). First widget: an Up/Down options card for BTC, SOL and more on Base.

Readme

@thetanuts-finance/widget

Embeddable Thetanuts trading widgets, shipped as framework-agnostic Web Components. The first widget is <thetanuts-updown> — a compact "Up or Down" options card (BTC, SOL, ETH and more) that fills instantly against the Thetanuts OptionBook on Base.

  • Works in any framework — React, Vue, Svelte, Angular, or plain HTML. It's a native custom element, so no framework runtime is shipped to your host.
  • Style-isolated — renders in Shadow DOM; your CSS and the widget's never collide.
  • Two ways to embed — a <script> tag with a global mount(), or an npm import.
  • Host-owned wallet — you pass in an EIP-1193 provider; the widget never bundles a wallet UI.

Up/Down card


Install

npm install @thetanuts-finance/widget

or use the standalone build straight from a CDN (no bundler needed):

<script src="https://unpkg.com/@thetanuts-finance/widget/standalone"></script>

Quick start

1. Plain HTML / vanilla JS (<script>)

<script src="https://unpkg.com/@thetanuts-finance/widget/standalone"></script>

<!-- declaratively -->
<thetanuts-updown asset="SOL"></thetanuts-updown>

<!-- or imperatively -->
<div id="card"></div>
<script>
  const handle = window.ThetanutsWidgets.updown.mount(
    document.getElementById("card"),
    {
      provider: myEip1193Provider, // e.g. web3-onboard wallet.provider
      defaultAsset: "BTC",
      onTrade: (t) => console.log("filled", t.txHash),
    },
  );
  // handle.update({ provider: newProvider }); handle.unmount();
</script>

2. React

import "@thetanuts-finance/widget/updown"; // registers <thetanuts-updown>

function Card({ provider }) {
  const ref = useRef(null);
  useEffect(() => {
    if (ref.current) ref.current.provider = provider; // object props set imperatively
  }, [provider]);
  return <thetanuts-updown ref={ref} default-asset="SOL" />;
}

3. Vue / Svelte / Angular

Import the package once (import "@thetanuts-finance/widget/updown") and use <thetanuts-updown> in your template. Bind scalar attributes (asset, referrer) directly; set object props (provider, signer, theme) via a ref/element reference.


Configuration

Props (React/JS properties) ≡ mount options ≡ kebab-case HTML attributes.

| Prop | Attribute | Type | Default | Notes | |---|---|---|---|---| | provider | — | EIP-1193 | — | Host wallet provider. Read + write. | | signer | — | ethers v6 Signer | — | Alternative to provider. | | referrer | referrer | string | Thetanuts referrer | Fee-share address. | | feeBps | fee-bps | number | read from broker | Partner fee (bps). | | chainId | chain-id | number | 8453 | Base only today. | | rpcUrl | rpc-url | string | public Base RPC | Read fallback if no wallet. | | defaultAsset / asset | default-asset / asset | string | first with orders | e.g. "SOL". | | defaultAmount | default-amount | number | 1 | USDC amount prefilled in the input. | | targetMove | target-move | number | 10 | Default % move for the payout scenario ("if {ASSET} +X%"). | | variant | variant | "full" | "simple" | "compact" | "full" | full = detailed quote; simple = one prominent payout callout; compact = tiny Jupiter-style card (price-to-beat + Up/Down premiums, one-tap trade at defaultAmount; no switcher/slider). | | popup | popup | boolean | false | Render as a floating popup with minimize (→ logo bubble), close, and drag. | | position | position | bottom-right | bottom-left | top-right | top-left | bottom-right | Corner the popup docks to (popup mode). Users can also drag it; on release it snaps to the nearest side and slides up/down along that edge. Position persists in localStorage. | | assets | — | string[] | all supported | Allowlist of assets to show. | | theme | — | object | v4 palette | Color overrides (validated CSS color tokens only). | | apiBaseUrl | api-base-url | string | Thetanuts API | See CORS note. | | indexerApiUrl | indexer-api-url | string | Thetanuts indexer | See CORS note. | | pricingApiUrl | pricing-api-url | string | Thetanuts pricing | See CORS note. | | onTrade | — | fn | — | Also emits tnw:trade CustomEvent. | | onError | — | fn | — | Also emits tnw:error CustomEvent. |

Payout is concrete, not "unlimited". A call (Up) has unbounded upside in theory, so instead of showing "Unlimited" the widget shows the payout at a chosen target move — e.g. "if SOL hits +10% ($82.90) you receive ~$5.73" — with a +5% / +10% / +25% selector and the break-even price. The bet amount has a slider + presets ($1/$5/$25/MAX), bounded by the order's capacity (and your balance if a wallet is connected).

Events bubble and cross shadow boundaries:

el.addEventListener("tnw:trade", (e) => console.log(e.detail));    // {txHash, asset, isCall, usdcAmount, numContracts}
el.addEventListener("tnw:error", (e) => console.warn(e.detail));   // {code?, message}
// popup lifecycle:
el.addEventListener("tnw:minimize", () => {});
el.addEventListener("tnw:expand",   () => {});
el.addEventListener("tnw:close",    () => {});

⚠️ Requirement: the host must supply a wallet connector

This widget does not include a wallet UI or connect button. It is wallet-provider–agnostic on purpose: the host app owns wallet connection and passes the connected wallet into the widget.

  • To trade (approve + fill), the host MUST provide a connected EIP-1193 provider (e.g. from web3-onboard, RainbowKit/wagmi, Reown/WalletConnect, Privy, or window.ethereum) or an ethers v6 signer.
  • With no provider/signer, the widget still renders and shows live prices, quotes, and payouts read-only, but the action button reads "Connect wallet in host app" and is disabled.
  • The connected wallet must be on Base (chainId 8453); the widget will request a chain switch (wallet_switchEthereumChain) when needed.
  • Pass the provider via the provider property / mount option (not an attribute). When the user connects or switches wallets in your app, update it: el.provider = newProvider (or handle.update({ provider })).
// e.g. web3-onboard
const provider = onboard.state.get().wallets[0]?.provider;
ThetanutsWidgets.updown.mount(el, { provider });

⚠️ CORS / API access

The Thetanuts market APIs (orders + prices) allow-list only thetanuts.finance origins. The widget therefore works out-of-the-box when embedded on a Thetanuts-owned origin.

To embed on any other origin (e.g. your own app), route the API calls through a same-origin proxy and point the widget at it:

mount(el, {
  provider,
  apiBaseUrl:   "/thetanuts/api",      // → https://round-snowflake-9c31.devops-118.workers.dev
  indexerApiUrl:"/thetanuts/indexer",  // → https://indexer.thetanuts.finance/api/v1/book
  pricingApiUrl:"/thetanuts/pricing",  // → https://pricing.thetanuts.finance
});

examples/dev-proxy.mjs is a minimal Node CORS proxy you can copy for local development. (Alternatively, ask Thetanuts to add your origin to the API CORS allow-list.)


How it works

The Up/Down card buys the nearest-expiry, at-the-money call (Up) or put (Down) listed on the OptionBook:

  1. fetchOrders() → filter to vanilla, USDC-collateral orders for the asset.
  2. Split by call/put, pick the nearest expiry closest to spot.
  3. previewFillOrder() computes contracts / greeks synchronously; the widget derives the concrete payout at your chosen target move, break-even, and the order's capacity (used as the amount slider's max).
  4. On buy: approve USDC → fillOrder routed through the PartnerFeeBroker so the referrer earns a fee split → tnw:trade.

Expiries are Thetanuts' native daily series (08:00 UTC); the card shows the real nearest expiry with a live countdown.


Development

npm install
npm run build        # → dist/ (ESM + CJS + IIFE + d.ts)
npm run typecheck
npm run smoke        # read-only check against Base mainnet (no wallet)

# examples (in separate terminals):
node examples/dev-proxy.mjs                 # CORS proxy on :8811
npx serve . # or any static server, then open examples/vanilla.html

Bundle size: the standalone IIFE bundles Lit + ethers v6 + the Thetanuts SDK (~753 KB raw, ~230 KB gzipped). The npm/ESM build keeps ethers external, so apps that already ship ethers pay far less.

Security note: the widget opens no WebSocket, so the transitive ws DoS advisory (pulled in by the SDK's viem dependency, no upstream fix) is not reachable from this package's code paths.

License

MIT