> ## Documentation Index
> Fetch the complete documentation index at: https://docs.li.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# Widget Light 钱包管理

> @lifi/widget-light 的生态系统处理器和钱包集成

在 Widget Light 中，主机应用拥有所有钱包连接。运行在 iframe 内的 widget 从不直接接触浏览器扩展或私钥。取而代之的是，生态系统处理器将来自 iframe 的 RPC 请求桥接到你的钱包 provider。

## 钱包桥接的工作原理

当 iframe 内的 widget 需要执行钱包操作（发送交易、签名消息、切换链）时，它会通过 `postMessage` 发送一条 `RPC_REQUEST` 消息。主机端的处理器使用你的钱包 provider 处理该请求，并将结果作为 `RPC_RESPONSE` 发送回来。

```
Widget (iframe)                         Host (your app)
     |                                       |
     |-- RPC_REQUEST (eth_sendTransaction) ->|
     |                                       |-- wagmi sends tx
     |                                       |<- tx hash
     |<- RPC_RESPONSE (tx hash) ------------|
```

钱包状态变化（账户切换、链更改、连接/断开连接）也会通过 `EVENT` 消息自动从主机推送到 iframe。

## IframeEcosystemHandler 接口

每个生态系统处理器都实现 `IframeEcosystemHandler` 接口：

```tsx theme={"system"}
interface IframeEcosystemHandler {
  /** Chain type identifier: 'EVM' | 'SVM' | 'UTXO' | 'MVM' | 'TVM' */
  chainType: WidgetLightChainType

  /** Returns initial wallet state sent with the INIT handshake */
  getInitState(): EcosystemInitState | null

  /** Handles an RPC request forwarded from the iframe */
  handleRequest(id: string, method: string, params?: unknown): Promise<unknown>

  /** Subscribes to wallet state changes; returns an unsubscribe function */
  subscribe(emit: (event: string, data: unknown) => void): () => void
}
```

## 生态系统处理器

### EVM -- `useEthereumIframeHandler()`

```tsx theme={"system"}
import { useEthereumIframeHandler } from '@lifi/widget-light/ethereum'
```

EVM 处理器会自动从你的 wagmi 上下文中读取钱包状态。无需任何参数。

```tsx theme={"system"}
const ethHandler = useEthereumIframeHandler()
```

| 细节       | 值                                                                               |
| -------- | ------------------------------------------------------------------------------- |
| **链类型**  | `EVM`                                                                           |
| **读取来源** | wagmi 上下文（`useConnection`、`useWalletClient`、`usePublicClient`、`useSwitchChain`） |
| **对等依赖** | `wagmi`、`viem`、`@wagmi/core`                                                    |
| **参数**   | 无                                                                               |

**支持的 RPC 方法：**

| 方法                           | 说明                             |
| ---------------------------- | ------------------------------ |
| `eth_accounts`               | 返回已连接的账户                       |
| `eth_requestAccounts`        | 请求账户访问权限                       |
| `eth_chainId`                | 返回当前链 ID（十六进制）                 |
| `net_version`                | 返回当前网络版本                       |
| `eth_sendTransaction`        | 发送交易（支持 EIP-1559 和 legacy gas） |
| `personal_sign`              | 签名任意消息                         |
| `eth_sign`                   | 签名数据                           |
| `eth_signTypedData_v4`       | 签名 EIP-712 类型化数据               |
| `wallet_switchEthereumChain` | 切换到另一条链                        |
| `wallet_addEthereumChain`    | 向钱包添加新链                        |
| `wallet_sendCalls`           | 发送批处理调用（EIP-5792）              |
| `wallet_getCallsStatus`      | 获取批处理调用的状态（EIP-5792）           |
| `wallet_showCallsStatus`     | 显示批处理调用状态 UI（EIP-5792）         |
| `wallet_getCapabilities`     | 查询钱包能力（EIP-5792）               |

任何无法识别的方法都会被转发到公共客户端（例如 `eth_getBalance`、`eth_call`）。

**发出的钱包事件：** `accountsChanged`、`chainChanged`、`connect`

### Solana -- `useSolanaIframeHandler(params)`

```tsx theme={"system"}
import { useSolanaIframeHandler } from '@lifi/widget-light/solana'
```

Solana 处理器与具体库无关。你需要显式传入钱包状态，因此它可以与任何提供 wallet-standard `Wallet` 实例的 Solana 钱包库配合使用。

```tsx theme={"system"}
const solHandler = useSolanaIframeHandler({
  address: solanaAddress,     // string | null
  connected: solanaConnected, // boolean
  wallet: solanaWallet,       // Wallet from @wallet-standard/base | null
})
```

| 细节       | 值                       |
| -------- | ----------------------- |
| **链类型**  | `SVM`                   |
| **对等依赖** | `@wallet-standard/base` |

**参数：**

| 参数          | 类型               | 说明                            |
| ----------- | ---------------- | ----------------------------- |
| `address`   | `string \| null` | 已连接的钱包地址                      |
| `connected` | `boolean`        | 是否已连接钱包                       |
| `wallet`    | `Wallet \| null` | wallet-standard 的 `Wallet` 实例 |

**支持的 RPC 方法：**

| 方法                       | 说明               |
| ------------------------ | ---------------- |
| `getAccount`             | 返回当前账户地址         |
| `signTransaction`        | 签名序列化的交易（base64） |
| `signMessage`            | 签名任意消息（base64）   |
| `signAndSendTransaction` | 签名并发送交易（base64）  |

**发出的钱包事件：** `accountsChanged`、`connect`、`disconnect`

### Bitcoin -- `useBitcoinIframeHandler()`

```tsx theme={"system"}
import { useBitcoinIframeHandler } from '@lifi/widget-light/bitcoin'
```

Bitcoin 处理器会自动从 `@bigmi/react` 上下文中读取钱包状态。无需任何参数。

```tsx theme={"system"}
const btcHandler = useBitcoinIframeHandler()
```

| 细节       | 值                                            |
| -------- | -------------------------------------------- |
| **链类型**  | `UTXO`                                       |
| **读取来源** | `@bigmi/react` 上下文（`useAccount`、`useConfig`） |
| **对等依赖** | `@bigmi/client`、`@bigmi/react`               |
| **参数**   | 无                                            |

**支持的 RPC 方法：**

| 方法           | 说明                             |
| ------------ | ------------------------------ |
| `getAccount` | 返回当前账户地址和公钥                    |
| 其他方法         | 通过 `client.request()` 转发到钱包客户端 |

**发出的钱包事件：** `accountsChanged`、`connect`、`disconnect`

### Sui -- `useSuiIframeHandler()`

```tsx theme={"system"}
import { useSuiIframeHandler } from '@lifi/widget-light/sui'
```

Sui 处理器会自动从 `@mysten/dapp-kit-react` 钩子中读取钱包状态。无需任何参数。

```tsx theme={"system"}
const suiHandler = useSuiIframeHandler()
```

| 细节       | 值                                                                                  |
| -------- | ---------------------------------------------------------------------------------- |
| **链类型**  | `MVM`                                                                              |
| **读取来源** | `@mysten/dapp-kit-react` 钩子（`useCurrentWallet`、`useDAppKit`、`useWalletConnection`） |
| **对等依赖** | `@mysten/dapp-kit-react`                                                           |
| **参数**   | 无                                                                                  |

**支持的 RPC 方法：**

| 方法                          | 说明             |
| --------------------------- | -------------- |
| `getAccount`                | 返回当前账户地址       |
| `signTransaction`           | 签名交易块（base64）  |
| `signPersonalMessage`       | 签名任意消息（base64） |
| `signAndExecuteTransaction` | 签名并执行交易块       |

**发出的钱包事件：** `accountsChanged`、`connect`、`disconnect`

### Tron -- `useTronIframeHandler(params)`

```tsx theme={"system"}
import { useTronIframeHandler } from '@lifi/widget-light/tron'
```

Tron 处理器与具体库无关。你需要显式传入钱包状态，因此它可以与任何提供兼容适配器的 Tron 钱包库配合使用。

```tsx theme={"system"}
const tronHandler = useTronIframeHandler({
  address: tronAddress,     // string | null
  connected: tronConnected, // boolean
  adapter: tronAdapter,     // TronAdapter | null
})
```

| 细节       | 值             |
| -------- | ------------- |
| **链类型**  | `TVM`         |
| **对等依赖** | 无（适配器状态需显式传入） |

**参数：**

| 参数          | 类型                    | 说明                                            |
| ----------- | --------------------- | --------------------------------------------- |
| `address`   | `string \| null`      | 已连接的钱包地址                                      |
| `connected` | `boolean`             | 是否已连接钱包                                       |
| `adapter`   | `TronAdapter \| null` | 带有 `signTransaction` 和 `signMessage` 方法的钱包适配器 |

**支持的 RPC 方法：**

| 方法                | 说明                    |
| ----------------- | --------------------- |
| `getAccount`      | 返回当前账户地址              |
| `signTransaction` | 签名 TronWeb 交易对象（JSON） |
| `signMessage`     | 签名任意消息字符串             |

**发出的钱包事件：** `accountsChanged`、`connect`、`disconnect`

## 子路径导入

每个生态系统处理器都通过子路径导入暴露，以支持 tree-shaking。如果你只使用 EVM，则 Solana、Bitcoin、Sui 和 Tron 处理器（及其对等依赖）永远不会包含在你的 bundle 中：

```tsx theme={"system"}
// Only includes EVM handler code
import { useEthereumIframeHandler } from '@lifi/widget-light/ethereum'

// Only includes Solana handler code
import { useSolanaIframeHandler } from '@lifi/widget-light/solana'

// Only includes Bitcoin handler code
import { useBitcoinIframeHandler } from '@lifi/widget-light/bitcoin'

// Only includes Sui handler code
import { useSuiIframeHandler } from '@lifi/widget-light/sui'

// Only includes Tron handler code
import { useTronIframeHandler } from '@lifi/widget-light/tron'
```

## 组合多个处理器

将你的所有处理器作为数组传入。widget 会将每个 RPC 请求路由到与该请求 `chainType` 匹配的处理器：

```tsx theme={"system"}
import { LiFiWidgetLight } from '@lifi/widget-light'
import { useEthereumIframeHandler } from '@lifi/widget-light/ethereum'
import { useSolanaIframeHandler } from '@lifi/widget-light/solana'
import { useMemo } from 'react'

function App() {
  const ethHandler = useEthereumIframeHandler()
  const solHandler = useSolanaIframeHandler({
    address: solanaAddress,
    connected: solanaConnected,
    wallet: solanaWallet,
  })

  const handlers = useMemo(
    () => [ethHandler, solHandler],
    [ethHandler, solHandler]
  )

  return (
    <LiFiWidgetLight
      config={{ integrator: 'my-app' }}
      handlers={handlers}
    />
  )
}
```

## 外部钱包管理

如果你的应用有自己的钱包连接 UI（连接按钮、弹窗等），请使用 `onConnect` prop 来拦截来自 widget 的钱包连接请求。当提供了 `onConnect` 时，widget 会向主机发送 `CONNECT_WALLET_REQUEST`，而不是打开其内置的钱包菜单。

```tsx theme={"system"}
import { LiFiWidgetLight } from '@lifi/widget-light'
import type { ConnectWalletArgs } from '@lifi/widget-light'
import { useCallback } from 'react'

function App() {
  const handleConnect = useCallback((args?: ConnectWalletArgs) => {
    // args.chainId - the chain the widget wants to connect to (optional)
    // args.chainType - the chain type ('EVM', 'SVM', 'UTXO', 'MVM', 'TVM') (optional)
    openYourWalletModal(args)
  }, [])

  return (
    <LiFiWidgetLight
      config={{ integrator: 'my-app' }}
      handlers={handlers}
      onConnect={handleConnect}
    />
  )
}
```

`ConnectWalletArgs` 类型包含：

| 字段          | 类型                             | 说明                                            |
| ----------- | ------------------------------ | --------------------------------------------- |
| `chainId`   | `number \| undefined`          | widget 想要连接到的链 ID                             |
| `chainType` | `WidgetChainType \| undefined` | 链类型（`'EVM'`、`'SVM'`、`'UTXO'`、`'MVM'`、`'TVM'`） |

<Note>
  当提供了 `onConnect` 时，主机会在发送到 iframe 的配置中自动设置 `walletConfig.useExternalWalletManagement: true`。你无需手动设置它。
</Note>
