npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@socket.tech/widget

v1.0.5

Published

Socket Widget is a swap and bridge widget for moving tokens across blockchains. The `@socket.tech/widget` package exposes a React component you can embed in your app.

Readme

Socket Widget

What is Socket Widget?

Socket Widget is a swap and bridge widget for moving tokens across blockchains. The @socket.tech/widget package exposes a React component you can embed in your app.

v1.0.0: The widget is wallet-provider-agnostic. Your app provides a minimal wallet adapter via config.wallet, and the widget handles routing, reads, writes, balances, receipts, and signing internally.

Before You Start

Socket Widget handles swap and bridge flows, while your app owns wallet connection.

  • Provide wallet state and wallet connect UI.
  • Mount QueryClientProvider above <SocketWidget />.
  • Pass a minimal wallet adapter via config.wallet.
  • Support EVM only, Solana only, Tron only, or any combination by providing the matching adapter methods. You only need to pass the methods for the chains you support — e.g. for EVM-only apps, provide getEVMWalletClient and switchChain; you do not need to pass getSolanaSigner or getTronWeb.

Minimal React Query setup:

import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

const queryClient = new QueryClient();

root.render(
  <QueryClientProvider client={queryClient}>
    <App />
  </QueryClientProvider>
);

Install

Install the package and its peer dependencies:

pnpm install @socket.tech/widget react react-dom viem @tanstack/react-query

Peer dependencies are not installed automatically.

This installs the widget, not a wallet/connect solution. You must already have, or choose, wallet infrastructure in your app.

Import the widget styles in your app entrypoint:

import "@socket.tech/widget/styles.css";
import "@socket.tech/widget/fonts.css";

Quickstart

For a transaction-capable integration, the setup is:

  1. Install the package and peer dependencies.
  2. Mount QueryClientProvider.
  3. Import the widget CSS.
  4. Add a minimal wallet adapter.
  5. Render <SocketWidget config={config} />.

Choose the smallest path that matches your app:

  • EVM only: provide accounts, getEVMWalletClient, and usually switchChain. You do not need to pass getSolanaSigner or getTronWeb.
  • Solana only: provide accounts and getSolanaSigner. You only need rpcs.solana if you want to override the default Solana RPC.
  • Tron: provide accounts (including a TRON account) and getTronWeb.
  • EVM + Solana: combine EVM and Solana adapters in the same wallet object.
  • EVM + Tron: add getTronWeb and TRON accounts for Tron-supported routes.

EVM-Only Example

This is the smallest recommended setup if your app already uses an EVM wallet library such as wagmi.

Your connect modal or connect button still belongs to your app.

import { SocketWidget, type WidgetConfig } from "@socket.tech/widget";
import { getWalletClient } from "@wagmi/core";
import { useMemo } from "react";
import { useAccount, useConfig, useSwitchChain } from "wagmi";

export function BungeeWidget() {
  const { address, chain, isConnected } = useAccount();
  const { switchChainAsync } = useSwitchChain();
  const wagmiConfig = useConfig();

  const accounts = useMemo(
    () =>
      address && isConnected
        ? [
            {
              address,
              chainType: "EVM" as const,
              chainId: chain?.id,
              isConnected: true,
            },
          ]
        : [],
    [address, chain?.id, isConnected],
  );

  const config: WidgetConfig = {
    affiliateId: "your-affiliate-id",
    wallet: {
      accounts,
      getEVMWalletClient: async (chainId) => {
        return getWalletClient(wagmiConfig, { chainId });
      },
      switchChain: async (chainId) => {
        await switchChainAsync({ chainId });
        return true;
      },
    },
    eventHandlers: {
      onOpenWalletConnect: () => {
        // Open your app's wallet modal or navigate to your connect screen.
        openYourWalletModal();
      },
    },
  };

  return <SocketWidget config={config} />;
}

Solana-Only Example

This example assumes Solana wallet-adapter providers are already mounted higher in your app.

import { SocketWidget, type WidgetConfig } from "@socket.tech/widget";
import { useMemo } from "react";
import { useWallet } from "@solana/wallet-adapter-react";
import { useWalletModal } from "@solana/wallet-adapter-react-ui";

export function BungeeSolanaWidget() {
  const wallet = useWallet();
  const { setVisible } = useWalletModal();

  const accounts = useMemo(
    () =>
      wallet.publicKey
        ? [
            {
              address: wallet.publicKey.toBase58(),
              chainType: "SVM" as const,
              isConnected: wallet.connected,
            },
          ]
        : [],
    [wallet.connected, wallet.publicKey],
  );

  const config: WidgetConfig = {
    affiliateId: "your-affiliate-id",
    rpcs: {
      solana: "https://api.mainnet-beta.solana.com",
    },
    wallet: {
      accounts,
      getSolanaSigner: async () => {
        if (!wallet.connected) return null;
        return {
          signAndSendTransaction: wallet.sendTransaction ?? undefined,
          signTransaction: wallet.signTransaction ?? undefined,
        };
      },
    },
    eventHandlers: {
      onOpenWalletConnect: () => {
        setVisible(true);
      },
    },
  };

  return <SocketWidget config={config} />;
}

To support both EVM and Solana, combine this signer with the EVM adapter shown above in the same wallet object.

Both EVM and Solana

If your app supports both networks:

  • pass both account types in wallet.accounts
  • provide both getEVMWalletClient and getSolanaSigner
  • keep switchChain for EVM
  • route eventHandlers.onOpenWalletConnect(network) to the correct host wallet modal

Adding Tron (optional)

To support Tron deposit or direct-deposit flows:

  • include TRON accounts in wallet.accounts (with chainType: "TRON")
  • provide getTronWeb returning your app's TronWeb instance (must satisfy the TronWebLike interface)
  • route eventHandlers.onOpenWalletConnect("tron") to open your Tron wallet/connect UI

If you do not pass getTronWeb, the widget works as before; Tron routes simply won't be available for sending.

Configuration Reference

Widget Config Interface

Required Properties

  • wallet (WalletAdapter): Minimal wallet adapter for connected-wallet flows. Required. See Wallet Adapter.
  • affiliateId (string): Integrator tracking identifier. Required for every widget instance.

Optional Properties

  • baseUrl (string): API root URL. If not passed, the widget uses https://backend.socket.tech/v3.
  • turnstileSiteKey (string): Cloudflare Turnstile site key. When provided, the widget loads Turnstile and uses JWT auth for requests. When omitted, the widget uses affiliate-only requests.
  • theme (Theme): Theming configuration. See Theme Configuration.
  • widgetTitle (string): Optional title shown in the widget header. Default is "Swap". Only set if you need to customize the header label.
  • rpcs (object): Custom RPC URLs (all optional)
    • solana (string): Solana RPC URL. Optional. The widget defaults to https://api.mainnet-beta.solana.com; pass this only if you want to override it.
  • initialValues (object): Default values
    • fromChain (number): Default source chain ID
    • toChain (number): Default destination chain ID
    • inputTokens (string[]): Default input token addresses
    • outputTokens (string[]): Default output token addresses
    • amount (string[]): Default amounts
  • supportedTokens (object): Restrict available tokens. See Token Configuration Details.
    • from (object): Tokens by chain ID for source. Structure: { [chainId: string]: Token[] }
    • to (object): Tokens by chain ID for destination. Structure: { [chainId: string]: Token[] }
  • excludedTokens (object): Hide specific tokens from token lists and token search.
    • from (object): Token addresses to hide in the source selector. Structure: { [chainId: number]: string[] }
    • to (object): Token addresses to hide in the destination selector. Structure: { [chainId: number]: string[] }
  • supportedChains (object): Restrict available chains
    • from (number[]): Available source chains
    • to (number[]): Available destination chains
  • eventHandlers (EventHandlers): Event callbacks. See Event Handlers.
  • feeParams (object): Integrator fee configuration
    • feeTakerAddress (string): Wallet address that receives the fee
    • feeBps (number): Fee in basis points (for example 10 = 0.1%)
  • features (object): Feature flags
    • internalToasts (boolean): Show or hide internal toasts (default: true)
    • internalTxHistory (boolean): Show or hide transaction history (default: true)
    • internalInflight (boolean): Show or hide the inflight screen as a non-blocking toast (default: true)
    • internalTokenSelector (boolean): Render the built-in token selector, or delegate token selection to your app via eventHandlers.onOpenTokenSelector (default: true)
    • internalTokenSelectorBounds ("widget" | "viewport"): Constrain the built-in token selector to the widget or viewport (default: "widget")

Base URL and affiliate requirements

The widget uses a single default backend root: https://backend.socket.tech/v3.

  • If you do not pass baseUrl, the widget uses the Socket backend URL above.
  • affiliateId is required in every config.
  • turnstileSiteKey is optional. Pass it only if you want JWT-authenticated requests.
  • You may still override baseUrl explicitly if you need to point the widget at a different compatible backend.

Wallet Adapter

The wallet object is the only host integration point the widget needs. You provide connected accounts and the network-specific wallet hooks you support; the widget handles the rest internally.

| Property | Type | Required | Description | |---|---|---|---| | accounts | AccountInfo[] | Yes | Connected wallet accounts | | getEVMWalletClient | (chainId: number) => Promise<WalletClient \| null> | EVM only | Returns a viem WalletClient for the requested chain | | getSolanaSigner | () => Promise<SolanaSigner \| null> | Solana only | Returns a Solana signer for signing transactions | | getTronWeb | () => TronWebLike \| undefined | Tron only | Returns the wallet-connected TronWeb instance for Tron transactions and deposit flows | | switchChain | (chainId: number, account?) => Promise<boolean> | Recommended for EVM | Switches the wallet's active EVM chain |

What the widget handles internally

When you provide getEVMWalletClient, the widget automatically implements:

  • sendTransaction (including EIP-5792 batched calls)
  • signTypedData
  • writeContract
  • readContract (via viem public clients)
  • getBalance (native + ERC-20)
  • getTransactionReceipt
  • getBytecode
  • getEnsAddress
  • getWalletCapabilities (EIP-5792)
  • getCallsStatus (EIP-5792)

When you provide getSolanaSigner and config.rpcs.solana, the widget additionally handles:

  • Solana transaction building and sending (VersionedTransaction with lookup tables)
  • SOL and SPL token balance fetching (including Token-2022)
  • Solana transaction receipt polling

When you provide getTronWeb, the widget additionally handles:

  • Tron transaction building, signing, and broadcasting (for deposit and direct-deposit flows)
  • TRX and TRC-20 balance and transaction receipt via the host-supplied TronWeb instance

accounts

An array of currently connected wallet accounts:

accounts: Array<{
  address: string;
  chainType: "EVM" | "SVM" | "TRON";
  chainId?: number;
  isConnected: boolean;
  connector?: {
    id?: string;
    name?: string;
    icon?: string;
  };
}>

getEVMWalletClient

Returns a viem WalletClient for the requested chain. The widget uses this to send transactions, sign typed data, write contracts, and query EIP-5792 capabilities.

getEVMWalletClient: (chainId: number) => Promise<WalletClient | null>

The return type is any in the adapter interface so hosts are free to use any viem version; the widget casts internally.

getSolanaSigner

Returns a Solana signer object. The widget builds the transaction internally (instructions, lookup tables, blockhash) and passes it to the signer. If the signer provides signAndSendTransaction, the widget prefers it; otherwise it falls back to signTransaction + sendRawTransaction via its internal Connection.

getSolanaSigner: () => Promise<{
  signAndSendTransaction?: (...args: any[]) => Promise<any>;
  signTransaction?: (...args: any[]) => Promise<any>;
} | null>

getTronWeb

Returns the wallet-connected TronWeb instance from your app. The widget uses it to build, sign, and broadcast Tron transactions for deposit and direct-deposit flows. The instance must implement the minimal TronWebLike interface (see type export). If you do not support Tron, omit this property.

getTronWeb: () => TronWebLike | undefined

switchChain

Switches the wallet's active EVM chain. The optional account parameter targets a specific wallet when multiple are connected.

Treat this as a success-or-throw contract in practice:

  • resolve when the chain switch succeeds
  • reject or throw if the switch is cancelled or fails
switchChain: (
  chainId: number,
  account?: { address?: string; chainType: "EVM" | "SVM" | "TRON" }
) => Promise<boolean>

Token Configuration Details

Token Interface

When using supportedTokens, tokens must follow this structure:

interface Token {
  address: string;
  chainId: number;
  decimals: number;
  logoURI: string;
  name: string;
  symbol: string;
  isVerified?: boolean; // Must be true to avoid warnings
}

Using supportedTokens

Important notes:

  • When supportedTokens are provided, the widget will not automatically set a default token.
  • To show a default source token, you must pass initialValues.fromChain and initialValues.inputTokens.
  • Set isVerified: true for tokens in supportedTokens to avoid warnings.
  • inputTokens addresses must match tokens from your supportedTokens.from[chainId] list.

Using excludedTokens

Use excludedTokens when you want the widget to keep its normal token universe, but hide specific tokens from:

  • the token list
  • built-in search results
  • external token selector payloads

Example:

excludedTokens: {
  from: {
    1: [
      "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
      "0xdac17f958d2ee523a2206206994597c13d831ec7",
    ],
  },
  to: {
    10: ["0x4200000000000000000000000000000000000006"],
  },
}

Notes:

  • Matching is case-insensitive.
  • from and to are applied independently.
  • If you need a strict allowlist instead of a blocklist, use supportedTokens.

Fetching Token Data

When using supportedTokens, you can fetch token data from the Socket swap API endpoints:

  • /swap/tokens/list: Returns a curated list of trending tokens (verified) or the complete token list
  • /swap/tokens/search: Search for tokens by address, name, or symbol

Tokens fetched from these endpoints include the isVerified field. For detailed request and response formats, see the token-list API documentation.

Theme Configuration

Customize the widget appearance with the theme property:

const theme = {
  width: 420, // or "full" for full width
  borderRadius: "base", // "none" | "sm" | "base" | "md" | "lg"
  fonts: {
    primary: "Inter, sans-serif",
    secondary: "Roboto, sans-serif",
  },
  colors: {
    text: {
      primary: "#FFFFFF",
      secondary: "#A0A0A0",
      button: "#000000",
      theme: "#3B82F6",
      accent1: "#10B981",
      accent2: "#F59E0B",
      accent3: "#EF4444",
      accent4: "#8B5CF6",
    },
    bg: {
      layer1: "#1F2937",
      layer2: "#374151",
      layer3: "#4B5563",
      accent1: "#10B981",
      accent3: "#EF4444",
      accent4: "#8B5CF6",
      main: "#111827",
      theme: "#3B82F6",
    },
    border: {
      strong: "#6B7280",
      theme: "#3B82F6",
    },
    icon: {
      primary: "#FFFFFF",
      secondary: "#A0A0A0",
      theme: "#3B82F6",
    },
  },
};

Colors support both hex (#FFFFFF) and RGB (rgb(255, 255, 255)) formats.

Event Handlers

Handle user interactions and widget events:

const eventHandlers = {
  onFromTokenChange: (token: Token) => {
    console.log("Source token changed:", token);
  },
  onToTokenChange: (token: Token) => {
    console.log("Destination token changed:", token);
  },
  onFromChainChange: (chain: Chain) => {
    console.log("Source chain changed:", chain);
  },
  onToChainChange: (chain: Chain) => {
    console.log("Destination chain changed:", chain);
  },
  onEvent: (eventType: "success" | "error" | "warning", eventData: EventData) => {
    console.log("Widget event:", eventType, eventData);
  },
  onOpenWalletConnect: (network: "solana" | "eip155" | "tron") => {
    openWalletModal(network);
  },
  onSwapInitiated: (data: { chainId: number; hash: string; type: OrderFlowType }) => {
    console.log("Swap initiated:", data);
  },
  onTransactionStatusChange: (data: { requestHash: string; statusCode: SwapStatus }) => {
    console.log("Transaction status:", data);
  },
  onOpenTokenSelector: (data: TokenSelectorOpenData) => {
    openExternalTokenSelector(data);
  },
  onTokenSelectorDataChange: (data: TokenSelectorOpenData) => {
    syncExternalTokenSelector(data);
  },
  logEvent: (log: { event: Event; error: unknown; context?: Record<string, unknown> }) => {
    console.log("Analytics event:", log);
  },
  toggleExternalHistorySection: () => {
    toggleHistorySidebar();
  },
  showToast: (title, message, type, duration) => {
    // Display a custom toast notification
  },
};

Imperative API

The imperative API allows parent components to control widget state programmatically.

Use case example: when a user clicks a history item in a sidebar, the parent can navigate the widget to the inflight screen for that transaction.

import { useRef } from "react";
import { SocketWidget, type WidgetImperativeAPIType } from "@socket.tech/widget";

export default function App() {
  const bungeeRef = useRef<WidgetImperativeAPIType>(null);

  const handleSetInflightData = (data: OrderData) => {
    bungeeRef.current?.setInflightData(data);
  };

  return <SocketWidget config={config} ref={bungeeRef} />;
}

Available methods:

  • setInflightData(data: OrderData): Track pending transactions and navigate to inflight screen
  • openQrDeposit(quoteId: string): Open the QR deposit screen for a quote
  • selectToken(token: Token, isSource: boolean): Programmatically select the source or destination token
  • setSourceWalletMode(mode: SourceWalletMode): Update the source wallet mode used by the widget

Type Exports

import type {
  WidgetConfig,
  WidgetImperativeAPIType,
  WalletAdapter,
  TronWebLike,
} from "@socket.tech/widget";

Troubleshooting

  • React Query error or No QueryClient set Mount QueryClientProvider above <SocketWidget />.

  • Clicking connect does nothing Implement eventHandlers.onOpenWalletConnect.

  • Transactions fail because no wallet client is available for the selected chain Make sure getEVMWalletClient(chainId) returns a client for the requested chain, not only the currently active chain.

  • Chain switch handling feels inconsistent Make switchChain reject or throw on cancellation or failure instead of silently resolving unsuccessfully.

  • Solana actions fail immediately Mount Solana wallet-adapter providers higher in the app and pass both getSolanaSigner and rpcs.solana.

  • Tron deposit/direct-deposit fails or is unavailable Pass getTronWeb returning a TronWeb instance that implements TronWebLike, and include TRON accounts in wallet.accounts. If you do not need Tron, you can omit getTronWeb.

  • Widget has no styling Import @socket.tech/widget/styles.css and @socket.tech/widget/fonts.css.

Links