Fanua.

Embeddable Widgets

Drop pre-built financial UI directly into your dashboard. Each widget is a sandboxed iframe — your brand colors, your users, zero custody risk.

Available widgets
Live
Wallet Open
Provisions a new EVM + Solana wallet for a user in one tap. Fires a signed event when the account is created.
fanua:account.created fanua:error
Try simulator Integrate
Live
Balance Display
Shows live wallet balances across EVM and Solana chains. Fires an event on load and on each refresh.
fanua:balance.updated fanua:error
Try simulator Integrate
Live
Trade Desk
An embeddable OTC settlement desk for a trade venue — shows open positions and blended rates, settles them via an on-chain swap, and reports PnL.
fanua:position.settled fanua:error
Try simulator Integrate

Simulator — Wallet Open

Step through mount → user action → result. Every API call and postMessage lands on the wire. Nothing real is created — this is a self-contained mock.

HOST PAGE
Your site. Mints a scoped token server-side, drops one script tag.
FANUA WIDGET
Sandboxed iframe. Handshakes with Fanua using the embed token.
FANUA API
Validates the single-use token, runs the operation.
PROVIDER
Privy — provisions the EVM + Solana wallets.
Host page — your chrome, Fanua's widget
https://yourapp.com/account
YOUR APP
// host page — your own code & nav
Fanua.WalletOpen
The wire — every request, response & event, in order
Nothing on the wire yetRun step 1 to mint a token and mount the widget.
Quick-start — Wallet Open
1

Load the snippet

Add one script tag to your page. No build step, no npm install.

<!-- In your <head> or before </body> -->
<script src="https://tdcoffee-b523e.web.app/fanua-widget.js"></script>
2

Mint an embed token (server-side)

Call your backend to create a short-lived, single-use token scoped to one widget. Never expose your API key in the browser.

import { FanuaSDK } from '@fanua/sdk';

const fanua = new FanuaSDK({ apiKey: process.env.FANUA_API_KEY });

// In your API route / server action
const { token } = await fanua.createEmbedToken({
  scope: ['wallet_open'],
});

// Return token to the browser
res.json({ token });
curl -X POST \
  https://us-central1-tdcoffee-b523e.cloudfunctions.net/createEmbedToken \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -d '{"data":{"scope":["wallet_open"]}}'
3

Mount the widget

Pass the token from step 2 and a target element. The widget sends a fanua:account.created event when the wallet is ready.

// Fetch the token from your backend
const { token } = await fetch('/api/embed-token').then(r => r.json());

const widget = window.Fanua.WalletOpen({
  target: '#wallet-container',  // any CSS selector or HTMLElement
  token,
  label: 'My App',
  onAccountCreated({ accountId, address, solanaAddress }) {
    console.log('Wallet ready', accountId, address);
  },
  onError({ code, message }) {
    console.error(code, message);
  },
});

// Unmount when done
// widget.destroy();

Simulator — Balance Display

Mount the widget, fetch balances across chains, and watch the fanua:balance.updated event fire. Self-contained mock — no live account is read.

HOST PAGE
Your site. Mints a token scoped to one account, drops one script tag.
FANUA WIDGET
Sandboxed iframe. Auto-fetches balances on mount.
FANUA API
Validates the token, aggregates balances per instrument.
PROVIDER
Chain RPC — wallet balanceOf · Aave aToken APY.
Host page — your chrome, Fanua's widget
https://yourapp.com/wallet
YOUR APP
// host page — your own code & nav
Fanua.BalanceDisplay
The wire — every request, response & event, in order
Nothing on the wire yetRun step 1 to mint a token and mount the widget.
Quick-start — Balance Display
1

Load the snippet

Same loader as every Fanua widget — add it once and skip this step if it's already on the page.

<!-- In your <head> or before </body> -->
<script src="https://tdcoffee-b523e.web.app/fanua-widget.js"></script>
2

Mint an embed token (server-side)

Scope the token to balance_read and tie it to the account whose balances you want to show.

const { token } = await fanua.createEmbedToken({
  scope: ['balance_read'],
  accountId: 'acc_...',
});
3

Mount the widget

The widget fires fanua:balance.updated on load and on every refresh.

const widget = window.Fanua.BalanceDisplay({
  target: '#balance-container',
  token,
  onBalanceUpdated({ amount, available, currency }) {
    console.log('Balance', amount, available, currency);
  },
  onError({ code, message }) {
    console.error(code, message);
  },
});

Simulator — Trade Desk

Mount the desk, watch customers trade against it and positions build, settle one on-chain, and watch the fanua:position.settled event fire. Self-contained mock — no real swap is broadcast.

HOST PAGE
Your venue console. Mints a token scoped to one venue, drops one script tag.
FANUA WIDGET
Sandboxed iframe. Renders positions, drives settlement.
FANUA API
Validates the token, computes positions, settles.
PROVIDER
Uniswap swap · pro-rata payouts to customer wallets.
Venue console — your chrome, Fanua's desk
https://venue.example.com/otc
VENUE CONSOLE
// host page — your own code & nav
Fanua.TradeDesk
The wire — every request, response & event, in order
Nothing on the wire yetRun step 1 to mint a token and mount the desk.
Quick-start — Trade Desk
1

Load the snippet

Same loader as every Fanua widget — add it once and skip this step if it's already on the page.

<!-- In your <head> or before </body> -->
<script src="https://tdcoffee-b523e.web.app/fanua-widget.js"></script>
2

Mint an embed token (server-side)

Scope the token to venue_desk. A venueId is required for this scope.

const { token } = await fanua.createEmbedToken({
  scope: ['venue_desk'],
  venueId: 'ven_...',
});
curl -X POST \
  https://us-central1-tdcoffee-b523e.cloudfunctions.net/createEmbedToken \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -d '{"data":{"scope":["venue_desk"],"venueId":"ven_..."}}'
3

Mount the widget

The desk fires fanua:position.settled each time a position is settled on-chain.

// Fetch the token from your backend
const { token } = await fetch('/api/embed-token').then(r => r.json());

const widget = window.Fanua.TradeDesk({
  target: '#trade-desk',  // any CSS selector or HTMLElement
  token,
  onPositionSettled({ pair, side, settlementId, pnl }) {
    console.log('Settled', pair, side, pnl);
  },
  onError({ code, message }) {
    console.error(code, message);
  },
});

// Unmount when done
// widget.destroy();