Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

TonCast/sdk

Repository files navigation

Toncast SDK monorepo

TypeScript packages + working demos for building on the Toncast prediction-market protocol:

Package Path What it does
@toncast/sdk packages/sdk Universal, framework-agnostic SDK: REST, WebSocket streams, betting flow via @toncast/tx-sdk. Browser + Node 20+.
@toncast/sdk-react packages/sdk-react Thin React wrapper on top of @tanstack/react-query: provider + hooks for every read / live / betting endpoint, plus optional useTonConnectClient bridge. Supports React 18 + 19. Pattern lifted from @ston-fi/omniston-sdk-react.
@toncast/widget packages/widget Embeddable betting widget with standalone and integrated TonConnect modes, live market views, and white-label CSS variable theming.
@toncast/widget-loader packages/widget-loader Lightweight CDN loader for apps that want to mount the hosted widget bundle at runtime.
Demo app examples/react-app Vite + React 19 + Tailwind 4 + Radix UI. Browse paris (live), open one (live odds), connect TonConnect, bet in any wallet coin (TON or any jetton with a STON.fi route).

Layout

.
├── packages/
│ ├── sdk/ # @toncast/sdk
│ │ ├── src/
│ │ ├── tests/
│ │ ├── scripts/ # smoke tests against the live API
│ │ ├── examples/
│ │ └── README.md # ← full SDK docs (start here)
│ ├── sdk-react/ # @toncast/sdk-react
│ │ ├── src/
│ │ ├── tests/
│ │ └── README.md # ← React hooks reference
│ ├── widget/ # @toncast/widget
│ └── widget-loader/ # @toncast/widget-loader
├── examples/
│ ├── react-app/ # Vite + React 19 demo
│ │ ├── src/ # pages, components, providers
│ │ ├── public/ # tonconnect-manifest.json
│ │ └── README.md # ← run + deploy guide
│ └── widget-constructor/ # configure, preview, export widget embeds
├── biome.json # shared lint + format config
├── package.json # npm workspaces root
└── README.md # you are here

Workspaces

The repo is an npm workspaces monorepo. One install handles both packages:

npm install

Run a script across every workspace:

npm run typecheck # tsc --noEmit in each package
npm run build # tsup → dist/ in each package
npm test # vitest in each package
npm run lint # biome over the whole tree

Or scope to one package:

npm run test --workspace @toncast/sdk
npm run build --workspace @toncast/sdk-react

Embedding the betting widget

Two ways to load the same hosted bundle; both expose the ToncastWidget class.

  1. Direct CDN script (no bundler): add one <script> tag; in modern browsers the bundle attaches to window.ToncastWidget.
  2. npm loader (@toncast/widget-loader): call load() to inject the CDN script and receive the constructor — handy for React apps and dynamic import.

CDN URLs are major-versioned (/v0/, /v1/, ...): you get non-breaking updates within a major; change the path for breaking releases.

Option A — CDN

Host a TON Connect manifest at {your-domain}/tonconnect-manifest.json. The widget’s standalone mode uses tonconnect.options.domain as that origin (manifest URL = domain + '/tonconnect-manifest.json').

<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="UTF-8" />
 <title>Toncast widget (CDN)</title>
 </head>
 <body>
 <div id="toncast-widget"></div>
 <script src="https://widget.toncast.me/v0/index.iife.js"></script>
 <script>
 const Widget = window.ToncastWidget.ToncastWidget;
 const widget = new Widget({
 tonconnect: {
 type: "standalone",
 options: { domain: "https://your-app.com" },
 },
 });
 widget.mount(document.getElementById("toncast-widget"));
 </script>
 </body>
</html>

Option B — npm loader (e.g. React + integrated TonConnect)

import { useEffect, useRef } from "react";
import { useTonConnectUI } from "@tonconnect/ui-react";
import ToncastWidgetLoader, {
 type ToncastWidgetInstance,
} from "@toncast/widget-loader";
function ToncastBettingWidget() {
 const [tonconnect] = useTonConnectUI();
 const containerRef = useRef<HTMLDivElement>(null);
 const widgetRef = useRef<ToncastWidgetInstance | null>(null);
 useEffect(() => {
 let active = true;
 ToncastWidgetLoader.load()
 .then((Widget) => {
 if (!active || !containerRef.current) return;
 widgetRef.current = new Widget({
 tonconnect: { type: "integrated", instance: tonconnect },
 });
 widgetRef.current.mount(containerRef.current);
 })
 .catch((err) => console.error("[ToncastWidget] load failed:", err));
 return () => {
 active = false;
 widgetRef.current?.unmount();
 widgetRef.current = null;
 };
 }, [tonconnect]);
 return <div ref={containerRef} style={{ width: "100%" }} />;
}

Wrap your tree in TonConnectUIProvider with a valid manifest URL for your domain when using integrated mode from a full app.

For visual setup and exported snippets, use examples/widget-constructor/.

Container id convention. mount(container) accepts any Element. The #toncast-widget id used in every snippet above is just a convention: widget-constructor’s exported style.css scopes per-instance overrides under #toncast-widget { ... }. Keep that id (or rewrite the CSS scope) when reusing the exported stylesheet.

Subscribing to bet events

The successful-bet event is exposed identically through both surfaces:

  • Class: widget.on("bet", ({ pariId, amount, side }) => ...) (and matching off).
  • React: <Widget onBet={({ pariId, amount, side }) => ...} /> from @toncast/widget/react.

Both deliver the same payload and fire after the wallet send call resolves. See packages/widget/README.md for the full snippets.

Widget white-label theming

@toncast/widget accepts widget.cssVars for per-instance visual customization and widget.layout.grid for responsive market-card columns. Source tokens such as accent, bg, success, danger, warn, and density are resolved into readable foregrounds, subtle backgrounds, hover/active states, surface/chrome colors, order-book fills, shadows, borders, and spacing variables.

const widget = new ToncastWidget({
 tonconnect: {
 type: "standalone",
 options: { domain: "https://your-app.com" },
 },
 widget: {
 theme: "system",
 cssVars: {
 accent: "#7c3aed",
 success: "#10b981",
 danger: "#ef4444",
 warn: "#f59e0b",
 density: "compact",
 light: { bg: "#ffffff" },
 dark: { bg: "#0b1020" },
 },
 layout: {
 grid: {
 mobile: 1,
 tablet: 2,
 desktop: 3,
 },
 },
 },
});

Explicit values always win. For example, if you pass successBg or successFillBg, the widget keeps that exact value instead of deriving one from success. Set deriveCssVars: false to disable all derivation, or use deriveCssVars: { colors: false } / { density: false } to disable one group.

Where to read next

License

MIT — see LICENSE.

About

Official Toncast SDK monorepo — REST & WebSocket client, React Query hooks, TonConnect betting (TON/jettons), and a white-label embeddable widget for TON prediction markets.

Topics

Resources

License

Stars

Watchers

Forks

Packages

Contributors

AltStyle によって変換されたページ (->オリジナル) /