Wattfare / Docs
Dashboard
SDK reference

React SDK

Import from wattfare/react. A provider that owns one client, and a useWattfare() hook that exposes reactive connection state and the connect / disconnect / refresh actions.

<WattfareProvider>

Wrap your app (or the subtree that needs budget state) once. It creates a single WattfareClient via createWattfare() and memoizes it — stable across re-renders, only re-created when its config changes.

provider
import { WattfareProvider } from "wattfare/react";

<WattfareProvider
  publishableKey="pk_live_…"          // required
  session="/api/wattfare-token"        // required: route path or token fn
  baseURL="https://wattfare.com"       // optional
  consentURL="https://wattfare.com"    // optional
  loadOnMount={true}                   // optional, default true
>
  {children}
</WattfareProvider>
PropTypeDefaultNotes
publishableKeystringRequired. Starts with pk_.
sessionstring | () => string | Promise<string>Required. Backend route path or a token-returning function.
baseURLstringhttps://wattfare.comOverride the Wattfare service URL.
consentURLstringhttps://wattfare.comOverride the consent popup origin.
loadOnMountbooleantrueFetch status once on mount. First-run “not connected” is swallowed, not surfaced as an error.

useWattfare()

Must be called inside a <WattfareProvider> (it throws otherwise). Returns the live connection snapshot plus the three actions.

useWattfare
import { useWattfare } from "wattfare/react";

function BudgetBar() {
  const { connected, connect, disconnect, remainingUsd, loading } = useWattfare();

  if (loading) return <Spinner />;
  if (!connected) return <button onClick={connect}>⚡ Connect AI budget</button>;

  return (
    <div className="budget">
      <span>{remainingUsd !== null ? `$${remainingUsd.toFixed(2)} left` : "Unlimited"}</span>
      <button onClick={disconnect}>Disconnect</button>
    </div>
  );
}
FieldTypeDescription
connectedbooleanWhether the user has an active budget connection.
remainingUsdnumber | nullRemaining spend for the period. null = unlimited.
statusConnectionStatusThe full snapshot (limits, usage, remainingUsd).
loadingbooleanTrue while any connect / disconnect / refresh is in flight.
errorError | nullThe last error, if any.
connect()() => Promise<void>Open the consent popup, then refresh status. Call from a click handler.
disconnect()() => Promise<void>Revoke the connection and reset to not-connected.
refresh()() => Promise<void>Re-fetch the connection + budget snapshot.
requestGrant(options)(options: RequestGrantOptions) => Promise<GrantResult | null>Open the consent popup for a one-time access grant. Returns the grant result or null if denied. Does not affect connection state.
keeping budget fresh
function Chat() {
  const { connect, refresh, remainingUsd } = useWattfare();

  async function send(prompt: string) {
    await fetch("/api/chat", { method: "POST", body: JSON.stringify({ prompt }) });
    await refresh();              // pull the new remaining budget after a call
  }
  // …
}

One-time grants

requestGrant() opens the consent popup for a disposable access grant — it doesn't affect connected or any other hook state. See One-time grants for the full guide and examples.

SSR & “use client”

The provider and hook are client components — they use React context and effects. In Next.js App Router, render <WattfareProvider> in a file marked "use client" (or a client boundary) and keep your secret-key code in server route handlers. See the Next.js guide for a full layout.