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

@de1/widget

v1.0.3

Published

De¹ Exchange Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.

Readme

De¹ Widget

De¹ Exchange 跨链兑换与桥接组件。把 Swap / Bridge 能力嵌入任意 Web 应用,支持 EVM、Solana、Bitcoin、NEAR 等多链钱包。


能力概览

  • 同链兑换(Swap)跨链桥接(Bridge),路由聚合报价
  • 开箱即用 UI:代币选择、钱包连接、交易进度、历史记录
  • 多链钱包:MetaMask、WalletConnect、Coinbase、Solana、UTXO、NEAR
  • 可定制:主题、布局、语言、链/代币白名单、手续费与推荐码
  • 可观测:交易生命周期事件,便于埋点与风控
  • 多框架示例:React、Next.js、Vue、Nuxt、Svelte、Remix,以及 RainbowKit / Privy / Dynamic 等钱包栈

包说明

本仓库是 pnpm monorepo,对外主要使用以下 npm 包:

| 包名 | 说明 | | --- | --- | | @de1/widget | React Widget 组件,接入首选 | | @de1/widget-sdk | 报价、余额、路由执行等无头 SDK | | @de1/wallet-management | 钱包连接与账户管理 | | @de1/widget-types | 共享 TypeScript 类型 |

当前 Widget 版本:@de1/[email protected]


快速接入

1. 安装

npm install @de1/widget
# 或
pnpm add @de1/widget

Peer 依赖(宿主项目需要提供):

npm install react react-dom @tanstack/react-query wagmi viem @bigmi/react @solana/wallet-adapter-react

| 依赖 | 版本要求 | | --- | --- | | react / react-dom | >= 18 | | wagmi | ^2.14.0 | | @tanstack/react-query | ^5.62.0 | | viem | ^2 | | @bigmi/react | >= 0.1.0 | | @solana/wallet-adapter-react | ^0.15.35 |

Vite 项目还需 Node polyfill:

npm install -D vite-plugin-node-polyfills
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { nodePolyfills } from 'vite-plugin-node-polyfills'

export default defineConfig({
  plugins: [
    react(),
    nodePolyfills({ include: ['buffer', 'process'] }),
  ],
})

2. 渲染 Widget

integrator 必填,用于标识接入方。请使用稳定的英文标识,例如产品名或域名。

import { De1Widget } from '@de1/widget'

export function App() {
  return (
    <De1Widget
      integrator="your-app-name"
      config={{
        variant: 'compact',
        appearance: 'auto',
        theme: {
          container: {
            border: '1px solid rgb(234, 234, 234)',
            borderRadius: '16px',
          },
        },
      }}
    />
  )
}

Next.js App Router 必须在客户端渲染,可用 WidgetSkeleton 作为 SSR 占位:

'use client'

import { De1Widget, WidgetSkeleton } from '@de1/widget'
import { useEffect, useState } from 'react'

export function Widget() {
  const [mounted, setMounted] = useState(false)
  useEffect(() => setMounted(true), [])

  const config = {
    appearance: 'light' as const,
    theme: { container: { borderRadius: '16px' } },
  }

  if (!mounted) {
    return <WidgetSkeleton config={config} />
  }

  return <De1Widget integrator="your-app-name" config={config} />
}

next.config.js 中加入:

module.exports = {
  transpilePackages: ['@de1/widget'],
}

常用配置

De1Widget 同时接受顶层 props 和 config 对象,二者会合并。完整类型见 WidgetConfig

布局与模式

| 字段 | 取值 | 说明 | | --- | --- | --- | | variant | 'compact' | 'wide' | 'drawer' | 卡片 / 宽屏 / 抽屉 | | subvariant | 'default' | 'swap' | 'bridge' | 'split' | 'custom' | 'refuel' | 业务模式 | | appearance | 'light' | 'dark' | 'auto' | 明暗主题 | | buildUrl | boolean | 是否把表单状态同步到 URL |

只做兑换或只做跨链:

<De1Widget integrator="your-app-name" config={{ subvariant: 'swap' }} />
<De1Widget integrator="your-app-name" config={{ subvariant: 'bridge' }} />

抽屉模式可通过 ref 控制开关:

import { useRef } from 'react'
import { De1Widget, type WidgetDrawer } from '@de1/widget'

export function SwapDrawer() {
  const drawerRef = useRef<WidgetDrawer>(null)
  return (
    <>
      <button onClick={() => drawerRef.current?.openDrawer()}>Open</button>
      <De1Widget
        ref={drawerRef}
        integrator="your-app-name"
        variant="drawer"
      />
    </>
  )
}

默认交易对

<De1Widget
  integrator="your-app-name"
  config={{
    fromChain: 1,
    fromToken: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
    toChain: 56,
    toToken: '0x0000000000000000000000000000000000000000', // BNB
    fromAmount: '100',
  }}
/>

链与代币过滤

import { ChainType } from '@de1/widget'

<De1Widget
  integrator="your-app-name"
  config={{
    chains: {
      allow: [1, 56, 137, 42161],
      types: { allow: [ChainType.EVM] },
    },
    tokens: {
      deny: [{ chainId: 1, address: '0x...' }],
    },
  }}
/>

隐藏 / 禁用 UI

import { DisabledUI, HiddenUI, RequiredUI } from '@de1/widget'

<De1Widget
  integrator="your-app-name"
  config={{
    hiddenUI: [HiddenUI.Language, HiddenUI.Appearance, HiddenUI.PoweredBy],
    disabledUI: [DisabledUI.ToAddress],
    requiredUI: [RequiredUI.ToAddress],
  }}
/>

主题

可直接使用内置 de1Theme,或按品牌覆盖色板:

import { De1Widget, de1Theme } from '@de1/widget'

<De1Widget
  integrator="your-app-name"
  config={{
    appearance: 'dark',
    theme: {
      ...de1Theme,
      palette: {
        ...de1Theme.palette,
        primary: { main: '#fb534f' },
      },
      container: {
        borderRadius: '16px',
        boxShadow: '0px 8px 32px rgba(0, 0, 0, 0.08)',
      },
    },
  }}
/>

语言

内置:enzhjakoesfrdeptvithidtritukbn

<De1Widget
  integrator="your-app-name"
  config={{
    languages: { default: 'zh' },
  }}
/>

可用 languageResources 覆盖指定文案。

手续费与推荐码

<De1Widget
  integrator="your-app-name"
  config={{
    fee: 0.003, // 0.3%
    evmReferrer: {
      address: '0xYourFeeReceiver',
      fee: '0.003',
    },
    solanaReferrer: {
      address: 'YourSolanaAddress',
      fee: '0.003',
    },
  }}
/>

动态费率使用 feeConfig.calculateFee


事件

useWidgetEvents 订阅交易与表单事件,适合埋点和客服跳转。

import { useEffect } from 'react'
import { useWidgetEvents, WidgetEvent } from '@de1/widget'

export function WidgetAnalytics() {
  const events = useWidgetEvents()

  useEffect(() => {
    const onStarted = (route) => console.log('started', route.id)
    const onCompleted = (route) => console.log('completed', route.id)
    const onFailed = ({ route, process }) =>
      console.error('failed', route.id, process)

    events.on(WidgetEvent.RouteExecutionStarted, onStarted)
    events.on(WidgetEvent.RouteExecutionCompleted, onCompleted)
    events.on(WidgetEvent.RouteExecutionFailed, onFailed)

    return () => {
      events.off(WidgetEvent.RouteExecutionStarted, onStarted)
      events.off(WidgetEvent.RouteExecutionCompleted, onCompleted)
      events.off(WidgetEvent.RouteExecutionFailed, onFailed)
    }
  }, [events])

  return null
}

常用事件:

| 事件 | 时机 | | --- | --- | | RouteExecutionStarted | 用户确认并开始执行 | | RouteExecutionUpdated | 步骤状态更新 | | RouteExecutionCompleted | 成功 | | RouteExecutionFailed | 失败 | | RouteSelected | 用户选择某条路由 | | AvailableRoutes | 报价列表就绪 | | WalletConnected | 钱包已连接 | | SourceChainTokenSelected / DestinationChainTokenSelected | 代币变更 | | ContactSupport | 用户点击联系支持 | | PageEntered | 页面切换 |


钱包接入

Widget 自带钱包菜单。若站点已有 RainbowKit、Privy、Dynamic、Reown 等方案,通过 walletConfig.onConnect 把「连接钱包」交给宿主:

<De1Widget
  integrator="your-app-name"
  config={{
    walletConfig: {
      onConnect() {
        openConnectModal?.()
      },
    },
  }}
/>

需要 Widget 与外部钱包菜单并存时,开启 usePartialWalletManagement

WalletConnect / MetaMask / Coinbase 可在 walletConfig 中传入各自参数(例如 WalletConnect projectId)。

更完整的钱包栈示例见 examples/


无头 SDK

不需要 UI、只做报价或执行路由时使用 @de1/widget-sdk

import { createConfig, getRoutes, executeRoute } from '@de1/widget-sdk'

createConfig({ integrator: 'your-app-name' })

const { routes } = await getRoutes({
  fromChainId: 1,
  toChainId: 56,
  fromTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  toTokenAddress: '0x0000000000000000000000000000000000000000',
  fromAmount: '100000000',
})

if (routes?.[0]) {
  await executeRoute(routes[0])
}

常用方法:getRoutesgetQuotegetStatusgetTokensgetChainsgetTokenBalancesexecuteRouteresumeRoutestopRouteExecution


框架示例

逐步说明在 examples/README.md。目录对照:

| 目录 | 场景 | | --- | --- | | examples/vite | Vite + React | | examples/nextjs | Next.js App Router | | examples/nextjs-page-router | Next.js Pages Router | | examples/vue / examples/nuxt | Vue 3 / Nuxt 3(veaury) | | examples/svelte | Svelte | | examples/remix | Remix | | examples/rainbowkit | RainbowKit | | examples/privy | Privy | | examples/dynamic | Dynamic | | examples/reown | Reown (WalletConnect) | | examples/deposit-flow | 自定义充值 / 合约调用 |


本地开发

pnpm install
pnpm dev          # Widget Playground(Vite)
pnpm build        # 构建全部 packages
pnpm check        # Biome
pnpm check:types  # TypeScript

要求:Node.js 18+,包管理器 pnpm@10

仓库结构:

packages/
  widget/                 # @de1/widget
  widget-sdk/             # @de1/widget-sdk
  wallet-management/      # @de1/wallet-management
  widget-types/           # @de1/widget-types
  widget-playground-vite/ # 本地调试台
examples/                 # 各框架接入示例

接入注意

  1. integrator 必填。未设置时 SDK 会拒绝初始化。
  2. Widget 依赖浏览器钱包与 Web3 API,SSR 框架请包一层 Client-only。
  3. Vite / 部分打包器需要 bufferprocess polyfill。
  4. 合约 ABI、Permit2 类型名等链上字段请勿改写,以免破坏签名与执行。
  5. 生产环境请自行配置 WalletConnect Project ID,以及所需的 RPC。

支持

License

Apache-2.0,见 LICENSE.md