Full Guide & Reference

Integrate Omniston swaps using the core JavaScript widget package

Getting started

Integrate Omniston swaps into any JavaScript application by installing the @ston-fi/omniston-widget-loader package, loading the latest widget bundle at runtime, connecting TON Connect, and mounting the widget into a DOM node. Omniston Widget lets you embed a full swap experience in minutes and start earning referral fees right away. The widget is framework-agnostic, so it fits everything from static sites to Vue, Angular, Svelte, or other environments that can host DOM nodes.

Omniston Widget ships as a CDN-hosted bundle rather than a standalone npm package. Use the npm loader to fetch that bundle at runtime, or reference the CDN script directly—both expose the same OmnistonWidget constructor.

  • @ston-fi/omniston-widget-loader (npmarrow-up-right) – loader package that downloads the CDN bundle when you call load().

  • CDN bundle – served from https://swap.ston.fi/widget/v0/index.js (and future /v1/, etc.) and exposes window.OmnistonWidget in the browser.

CDN URLs are major-versioned (/v0/, /v1/, ...). You receive all non-breaking updates within a major; bump the major path in the URL and/or loader configuration when you adopt breaking changes.

Installation

Install the Omniston widget loader using your preferred package manager. The loader downloads the latest Omniston widget bundle at runtime and returns the OmnistonWidget constructor when you call load().

via npm

npm install @ston-fi/omniston-widget-loader

via yarn

yarn add @ston-fi/omniston-widget-loader

via pnpm

pnpm add @ston-fi/omniston-widget-loader

Already using TON Connect elsewhere (integrated mode)? You likely have @tonconnect/sdk installed, so just run the same commands above to add @ston-fi/omniston-widget-loader. Install @tonconnect/sdk only if your project does not already depend on it.

The widget bundles and loads its own styles automatically—no manual CSS import required.

Configure TON Connect access

OmnistonWidget expects a tonconnect descriptor that tells it how to authenticate swaps. You can choose between two modes.

IMPORTANT: You must create and host your own TON Connect manifestarrow-up-right file. The manifest URL must be hosted on the same domain as your application. Wallets will reject connections if the domains don't match.

Mode
Description
When to use

standalone

The widget internally spins up TON Connect using just your dApp manifest. No additional wallet UI is required.

Small sites or landing pages that only need the swap flow provided by the Omniston widget.

integrated

You reuse an already initialized TON Connect SDK instance (for example TonConnect from @tonconnect/sdk).

Complex apps that already keep TON Connect state elsewhere and need the widget to share that connection.

Standalone descriptor (simplest)

Standalone mode runs out of the box. Provide your TON Connect manifest URL and the widget does the rest—no TON Connect packages or additional widget config required.

Use this when you do not manage TON Connect elsewhere—the widget internally initializes TON Connect using only your manifest file, so no TON Connect packages are needed.

Integrated descriptor (reuse existing TON Connect SDK)

Choose this mode when your app already initialized TON Connect for other components and you want a shared session (wallet selection, connected account, etc.). Provide asset addresses as plain strings (e.g., jetton master addresses).

WARNING: Only one TON Connect instance can exist in your application due to TON Connect SDK limitations (this is not specific to the Omniston widget). You must reuse the same instance for both your app and the widget. Creating multiple instances will cause the application to crash. Always use integrated mode if your app already has a TON Connect instance.

Configuration options

Option
Type
Description

tonconnect.type

"standalone" | "integrated"

Standalone: Widget manages TON Connect internally. Integrated: Reuse existing TON Connect SDK instance.

tonconnect.options.manifestUrl

string (standalone only)

Public URL of your TON Connect manifest file. Required for standalone mode.

tonconnect.instance

TonConnect (from @tonconnect/sdk) or TonConnectUI (from @tonconnect/ui-react) (integrated only)

Pre-initialized TON Connect SDK instance. Required for integrated mode.

widget.defaultBidAsset

string

Asset preselected on the "You sell" side (ticker or token root address).

widget.defaultAskAsset

string

Asset preselected on the "You buy" side (ticker or token root address).

widget.defaultAssets

boolean

Controls whether the default Omniston asset list is shown. If set to false, the widget displays only assets from customAssets, so provide a non-empty customAssets array in that case.

widget.customAssets

string[]

TON token root addresses you supply. With defaultAssets: true (default), these are added on top of the built-in list. With defaultAssets: false, this array becomes the entire list shown in the selector.

widget.referrerAddress

string

Optional TON wallet address that should receive referral fees when swaps settle.

widget.referrerFeeBps

number

Optional referral fee expressed in basis points (1 bps = 0.01%). Range: 0.01% to 1% (1 to 100 bps). See the Referral Fees guide for details.

Note: If you set widget.defaultAssets to false without providing customAssets, the selector will contain no tradable assets.

Want to collect referral revenue? Provide both referrerAddress and referrerFeeBps. Referral fees range from 0.01% to 1% (1 to 100 basis points). Read the Referral Fees guide for payout mechanics and best practices. Remember that referrerFeeBps uses basis points: 50 equals 0.5%.

CDN distribution (no bundler required)

Prefer to skip npm installs? Include the CDN bundle directly in your page. The script exposes window.OmnistonWidget, which matches the constructor returned by the loader.

The v0 segment in the URL pins your integration to major version 0 while still receiving all non-breaking updates for that major. Future breaking changes will ship under /v1/, /v2/, and so on.

Customize widget styles

When you mount the widget, scope theme overrides to the exact element you pass into widget.mount(...) (for example, #swap-widget-container). This keeps styles isolated to the widget. Toggle icon shapes by setting data-icon-variant="rounded" (default) or data-icon-variant="square" on that container. To force dark mode, add a .dark class on the same element (e.g., #swap-widget-container.dark { ... }).

CSS custom properties

For general information about CSS custom properties (variables), see the MDN guide on using custom propertiesarrow-up-right. These variables inherit through the normal CSS cascade, so declaring them on the exact element you pass into widget.mount(...) (for example, #swap-widget-container) scopes overrides to that widget instance and its children. Only the following CSS custom properties can be customized. Layout, typography, the derived spacing scale, and motion tokens are compiled into the widget bundle and are not configurable.

Global tokens

  • --spacing-base

  • --border-width

  • --dialog-width

  • --snackbar-width

  • --breakpoint-md

Color palettes

  • Accent palette: --accent-1 through --accent-12

  • Grey palette: --grey-1 through --grey-12

Base colors

  • --background-color, --background-hover-color, --border-color

  • --success-color, --danger-color

Text colors

  • --text-primary-color, --text-secondary-color, --text-accent-color

Icon colors

  • --icon-primary-color, --icon-secondary-color, --icon-accent-color

Component-specific variables

  • Icon button: --icon-button-text-color, --icon-button-background-color, --icon-button-background-hover-color, --icon-button-border-width, --icon-button-border-color

  • Switch: --switch-track-border-width, --switch-track-checked-border-color, --switch-track-checked-background-color, --switch-track-checked-background-hover-color, --switch-track-unchecked-border-color, --switch-track-unchecked-background-color, --switch-track-unchecked-background-hover-color, --switch-thumb-background-color, --switch-thumb-border-width, --switch-thumb-checked-border-color, --switch-thumb-unchecked-border-color

  • Button (primary): --button-primary-text-color, --button-primary-text-hover-color, --button-primary-text-disabled-color, --button-primary-background-color, --button-primary-background-hover-color, --button-primary-background-disabled-color

  • Button (secondary): --button-secondary-text-color, --button-secondary-text-hover-color, --button-secondary-text-disabled-color, --button-secondary-background-color, --button-secondary-background-hover-color, --button-secondary-background-disabled-color, --button-secondary-border-width, --button-secondary-border-color, --button-secondary-border-hover-color, --button-secondary-border-disabled-color

  • Input: --input-border-width, --input-border-color, --input-background-color, --input-placeholder-color, --input-caret-color, --input-active-background-color, --input-active-border-color, --input-invalid-border-color

  • Form: --form-background-color, --form-border-color, --form-border-width

  • Dialog: --dialog-background-color, --dialog-border-color, --dialog-border-width, --dialog-overlay-background-color

  • Alert: --alert-text-color, --alert-icon-color, --alert-border-color, --alert-border-width, --alert-background-color

  • Tooltip: --tooltip-background-color, --tooltip-border-color, --tooltip-border-width, --tooltip-text-color

  • Toggle group: --toggle-group-border-width, --toggle-group-text-color, --toggle-group-border-color, --toggle-group-background-color, --toggle-group-hover-text-color, --toggle-group-hover-border-color, --toggle-group-hover-background-color, --toggle-group-selected-text-color, --toggle-group-selected-border-color, --toggle-group-selected-background-color

  • Snackbar: --snackbar-background-color, --snackbar-border-color, --snackbar-border-width

  • Swap button: --swap-button-icon-color, --swap-button-background-color, --swap-button-border-color, --swap-button-border-width, --swap-button-hover-background-color

Apply the same variables on a .dark class attached to your container to force the dark palette, or override light/dark values separately based on your own theme toggles.

Quick override example

Declare custom properties with the -- prefix on the same element you pass to widget.mount(...); they cascade to descendants, and while the widget consumes them internally, you can reference them with var(...) like any CSS variable.

Expanded example (scoped to the container element you mount)

All of these custom properties cascade immediately once the widget mounts, so you can keep them in a global stylesheet or inject them dynamically from JavaScript.

Advanced: lifecycle events and manual mount/unmount

Register lifecycle event handlers

Hook into widget events for analytics, logging, or UI state.

Available events:

  • mount – fires after the component attaches to the DOM.

  • unmount – fires when the widget is removed.

  • error – fires when initialization or runtime errors occur.

Mount and unmount the widget

Instantiate the widget and call mount whenever the container is available. You can mount and unmount the same instance as often as needed.

Ensure the container exists before calling mount:

Use the CDN option for static sites or quick experiments. For bundled apps, prefer the npm loader (@ston-fi/omniston-widget-loader) so you control when the widget assets load.

Full example

Configure the standalone widget with only your TON Connect manifest URL. The widget ships with sensible defaults, so you can skip extra options until you need custom behavior. For an integrated example that reuses an existing TON Connect SDK instance, see Configure TON Connect access above.

With these steps, you can embed the Omniston widget into any landing page, dashboard, or dApp without touching low-level swap logic.

Last updated