Embeddable Widgets#
Widgets let partner sites embed Seesaw without rebuilding the web app. The v2 surface is intentionally broad enough for vibecoded sites: partners can embed a single trading market, a full app launcher, portfolio, fees, referrals, leaderboards, watchlist, history, stats, or market creation.
Install#
Four packages, one shared core:
| Package | Use case |
|---|---|
@seesaw/widget-react | React component (<SeesawWidget />) |
@seesaw/widget-vanilla | Script-tag / UMD global (SeesawWidget.mount) |
@seesaw/widget-web-component | <seesaw-widget> custom element |
@seesaw/widget-core | Config validation, embed-URL builder, WidgetHandle — used by the three wrappers |
npm install @seesaw/widget-react
'use client';
import { SeesawWidget } from '@seesaw/widget-react';
export function PredictionMarket() {
return (
<SeesawWidget
surface="market"
marketId="MARKET_PUBKEY"
referralAddress="REFERRER_WALLET"
showFees
showConfidence
allowedActions={['connect-wallet', 'trade', 'share-referral']}
onReady={(widget) => {
console.log(widget.capabilities);
}}
/>
);
}
Surfaces#
| Surface | Requires marketId | Purpose |
|---|---|---|
market | Yes | Market detail and trading |
trade | Yes | Trading-focused market embed |
live | Yes | Live market screen |
markets | No | Browse markets |
create-market | No | Market creation |
portfolio | No | Wallet positions and activity |
earnings | No | Creator/referral earnings entry point |
fees | No | Fee schedule and split |
referral | No | Referral sharing and attribution |
leaderboard | No | Trader/creator/referrer leaderboards |
history | No | Trade and account history |
watchlist | No | Watchlist |
stats | No | Platform statistics |
full | No | App launcher with navigation |
Vanilla HTML#
<div id="seesaw-widget"></div>
<script src="https://cdn.seesaw.fi/widget/v2/widget.js"></script>
<script>
const widget = SeesawWidget.mount('#seesaw-widget', {
surface: 'full',
referralAddress: 'REFERRER_WALLET',
showNavigation: true,
theme: 'system',
});
widget.on((event) => {
if (event.type === 'seesaw:tx-confirmed') {
console.log('confirmed', event.signature);
}
});
</script>
Host Commands#
The returned widget handle can send common commands into the iframe:
widget.send({ type: 'seesaw:navigate', surface: 'fees' });
widget.send({ type: 'seesaw:refresh' });
widget.send({
type: 'seesaw:preview-order',
marketId: 'MARKET_PUBKEY',
side: 'buy-yes',
amount: '10',
});
Supported v2 commands:
| Command | Status | Notes |
|---|---|---|
seesaw:get-capabilities | Supported | Emits seesaw:capabilities. |
seesaw:navigate | Supported | Moves between widget surfaces. |
seesaw:refresh | Supported | Reloads the embedded surface. |
seesaw:share-referral | Supported | Uses Web Share or clipboard when a referrer is configured. |
seesaw:preview-order | Supported | Emits an order-preview event for host-side UX. It does not build a transaction. |
seesaw:connect-wallet | Supported | Reports the widget-local wallet when connected; otherwise directs users to the embedded wallet button. |
seesaw:place-order | Wallet signing | Builds, signs, submits, and confirms through the widget-local wallet when connected. Falls back to the assisted ticket when no wallet is connected. |
seesaw:cancel-order | Assisted UI | Opens Portfolio, where the embedded app owns cancellation and signing. |
seesaw:claim-creator-fees | Assisted UI | Opens Portfolio, where creator claims are signed. |
seesaw:claim-referral-earnings | Assisted UI | Opens Referrals, where referral claims are signed. |
seesaw:set-referrer | Assisted UI | Opens Referrals with the requested referrer attribution context. |
For a fully custom frontend, use widgets for embedded Seesaw surfaces and
@seesaw/core for typed reads, PDA derivation, and instruction builders —
or @seesaw/trustless if your integration must not depend
on Seesaw infrastructure for account resolution. The widget capability
handshake reports
transactionCommandMode: 'wallet-signing' for v2: the embedded Seesaw iframe
can build and submit supported transactions after the user connects a wallet
inside the widget. If no widget-local wallet is connected, transaction commands
fall back to assisted UI and open the relevant signed Seesaw flow.
seesaw:place-order emits the transaction lifecycle:
widget.on((event) => {
if (event.type === 'seesaw:tx-confirmed') {
console.log(event.signature, event.confirmationStatus);
}
});
Capabilities#
widget.send({ type: 'seesaw:get-capabilities', commandId: 'capabilities-1' });
widget.on((event) => {
if (event.type === 'seesaw:capabilities') {
console.log(event.capabilities.supportedCommands);
}
});
The vanilla bundle also exposes the static contract:
console.log(SeesawWidget.capabilities);
Attribution#
Use referralAddress, partnerId, campaignId, and source for attribution.
Production partners should prefer signedConfig, generated by:
seesaw widget sign-config --partner-id acme-1 --referral REFERRER_WALLET
The iframe host validates signed envelopes server-side before rendering.
Referral resolver integration#
The widget uses the resolveReferrer function from @seesaw/core internally. When a referralAddress
is passed to SeesawWidget, it is treated as a pendingReferrer and fed into the resolver before
every trade. If the user has an existing on-chain lock the widget honours that lock instead;
referralAddress is only used when no locked referrer exists. The resolved address (with
eligibleForTriple checked) is passed to attachReferralTriple when building place_order
instructions inside the widget.
If you are building a custom frontend alongside the widget, use resolveReferrer directly rather
than duplicating the precedence logic. See the Referral and creator fees guide
for the full resolver API and wire-level account semantics.