> ## 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.

# 多虚拟机支持

> 无缝连接满足您需求的每个生态系统

## SDK 生态系统提供程序简介

LI.FI SDK 支持不同的区块链生态系统，允许您与 EVM 和 Solana 网络集成，还有更多生态系统即将推出。在内部，提供程序充当每个生态系统的抽象，在路由/报价执行期间处理关键任务，例如地址解析、余额检查和交易处理。

这些生态系统提供程序在设计时考虑了模块化，并且完全可以进行 tree-shake，确保如果不使用它们，它们不会给您的捆绑包增加不必要的重量。

SDK 提供四个提供程序，`EVM`、`Solana`、`UTXO` 和 `Sui`，每个提供程序都有各自生态系统的类似配置选项。

```typescript theme={"system"}
import { EVM, Solana, Sui, UTXO } from '@lifi/sdk'
```

所有提供程序的设置都侧重于利用钱包客户端、钱包适配器或类似的钱包接口概念，具体取决于特定于生态系统的库和标准。这种统一的方法简化了跨 EVM 兼容、Solana 和 Sui 链管理钱包和交易的过程。

### 不同类型的钱包/账户

要通过特定提供程序执行报价/路由，该提供程序必须能够签署交易。SDK 提供程序支持通过以下类型的钱包/账户签署交易：

* **本地账户（例如私钥/助记词钱包）。**

本地账户是使用私钥或助记词管理的钱包。此设置通常用于后端服务或需要自动签名和交易管理的场景。

* **JSON-RPC 账户（例如浏览器扩展钱包、WalletConnect 等）。**

使用 JSON-RPC 账户涉及通过 Web3 提供程序（例如 `window.ethereum`）进行连接，并在浏览器或移动环境中管理用户的账户。此设置在 dApp UI 中很受欢迎，通常与 `Wagmi`、`@solana/web3.js` 或 `@mysten/dapp-kit` 等库一起使用。

这些账户类型和交互方法允许开发人员选择最适合将 SDK 与其应用程序集成的方法。

## 设置 EVM 提供程序

EVM 提供程序执行逻辑是基于 `Viem` 库构建的，使用其一些类型和术语。

**配置 EVM 提供程序的可用选项：**

* `getWalletClient`: 返回 `WalletClient` 实例的函数。

* `switchChain`: 用于在不同网络之间切换的钩子。

### 本地账户

使用本地账户时，开发人员需要一个预定义的链列表，他们计划在交易执行期间与之交互以切换链。这些链可以来自 `viem/chains` 包，也可以从 LI.FI API 获取并采用 viem 的 `Chain` 类型。

这是一个使用 `viem/chains` 中的链的基本示例：

```typescript theme={"system"}
import { createConfig, EVM } from '@lifi/sdk'
import type { Chain } from 'viem'
import { createWalletClient, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { arbitrum, mainnet, optimism, polygon, scroll } from 'viem/chains'

const account = privateKeyToAccount('PRIVATE_KEY')

const chains = [arbitrum, mainnet, optimism, polygon, scroll]

const client = createWalletClient({
  account,
  chain: mainnet,
  transport: http(),
})

createConfig({
  integrator: 'Your dApp/company name',
  providers: [
    EVM({
      getWalletClient: async () => client,
      switchChain: async (chainId) =>
        // 通过创建新的钱包客户端切换链
        createWalletClient({
          account,
          chain: chains.find((chain) => chain.id == chainId) as Chain,
          transport: http(),
        }),
    }),
  ],
})
```

### JSON-RPC 账户

与 JSON-RPC 账户交互并将 `WalletClient` 传递给 `EVM` 提供程序的最佳方法是使用 [Wagmi](https://wagmi.sh/) 库。开发人员可以通过使用 `viem/chains` 包中的链或从 LI.FI API 获取链并将其适配到 Viem 的 `Chain` 类型来配置 Wagmi 链。

以下是如何使用 LI.FI API 的链与 Wagmi 和 React 结合设置 EVM 提供程序的简化示例。

我们提供了一个 `useSyncWagmiConfig` 钩子，它将获取的链与 Wagmi 配置同步并更新连接器。请注意，我们不使用连接器初始化 Wagmi 配置。此外，我们将 `reconnectOnMount` 设置为 `false`，因为在链与配置和连接器同步后，将在 `useSyncWagmiConfig` 钩子中调用 `reconnect` 操作。

```typescript theme={"system"}
import { ChainType, EVM, config, createConfig, getChains } from '@lifi/sdk';
import { useSyncWagmiConfig } from '@lifi/wallet-management';
import { useQuery } from '@tanstack/react-query';
import { getWalletClient, switchChain } from '@wagmi/core';
import { type FC, type PropsWithChildren } from 'react';
import { createClient, http } from 'viem';
import { mainnet } from 'viem/chains';
import type { Config, CreateConnectorFn } from 'wagmi';
import { WagmiProvider, createConfig as createWagmiConfig } from 'wagmi';
import { injected } from 'wagmi/connectors';

// Wagmi 连接器列表
const connectors: CreateConnectorFn[] = [injected()];

// 使用默认链创建 Wagmi 配置，不使用连接器
const wagmiConfig: Config = createWagmiConfig({
  chains: [mainnet],
  client({ chain }) {
    return createClient({ chain, transport: http() });
  },
});

// 使用 Wagmi 操作和配置创建 SDK 配置
const config = createConfig({
  integrator: 'Your dApp/company name',
  providers: [
    EVM({
      getWalletClient: () => getWalletClient(wagmiConfig),
      switchChain: async (chainId) => {
        const chain = await switchChain(wagmiConfig, { chainId });
        return getWalletClient(wagmiConfig, { chainId: chain.id });
      },
    }),
  ],
  // 我们禁用链预加载，并将在运行时更新链配置
  preloadChains: false,
});

export const CustomWagmiProvider: FC<PropsWithChildren> = ({ children }) => {
  // 使用 LI.FI SDK 的 getChains 操作从 LI.FI API 加载 EVM 链
  const { data: chains } = useQuery({
    queryKey: ['chains'] as const,
    queryFn: async () => {
      const chains = await getChains({
        chainTypes: [ChainType.EVM],
      });
      // 更新 LI.FI SDK 的链配置
      config.setChains(chains);
      return chains;
    },
  });

  // 将获取的链与 Wagmi 配置同步并更新连接器
  useSyncWagmiConfig(wagmiConfig, connectors, chains);

  return (
    <WagmiProvider config={wagmiConfig} reconnectOnMount={false}>
      {children}
    </WagmiProvider>
  );
};

```

### 更新提供程序配置

此外，提供程序允许通过 `setOptions` 函数动态更新其初始配置。

这是如何修改 `EVM` 提供程序的初始配置的示例：

```typescript theme={"system"}
import { createConfig, EVM } from '@lifi/sdk'
import { createWalletClient, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { arbitrum, mainnet } from 'viem/chains'

const account = privateKeyToAccount('PRIVATE_KEY')

const mainnetClient = createWalletClient({
  account,
  chain: mainnet,
  transport: http(),
})

const evmProvider = EVM({
  getWalletClient: async () => mainnetClient,
})

createConfig({
  integrator: 'Your dApp/company name',
  providers: [evmProvider],
})

const optimismClient = createWalletClient({
  account,
  chain: arbitrum,
  transport: http(),
})

evmProvider.setOptions({
  getWalletClient: async () => optimismClient,
})
```

### 支持 Ethers.js 和其他替代方案

开发人员仍然可以在其项目中使用 Ethers.js 或任何其他替代 Web3 库，并在将 `Signer`/`Provider` 对象传递给 EVM 提供程序配置之前[转换](https://viem.sh/docs/ethers-migration)为 Viem 的 `WalletClient`。

## 设置 Solana 提供程序

Solana 提供程序执行逻辑是基于 [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) 和 [@solana/wallet-adapter-base](https://github.com/anza-xyz/wallet-adapter) 库构建的，使用其一些类型和术语。

**配置 EVM 提供程序的可用选项：**

* `getWalletAdapter`: 返回 WalletAdapter 实例的函数。

### 本地钱包适配器

标准 Solana 库不提供直接从私钥创建钱包适配器的内置方法。为了解决此限制，我们提供了 `KeypairWalletAdapter`。此自定义适配器使用户能够从私钥创建钱包适配器。

值得注意的是，`KeypairWalletAdapter` 专为后端或测试目的而设计，不应在面向用户的代码中使用，以防止暴露您的私钥的风险。

```typescript theme={"system"}
import { createConfig, KeypairWalletAdapter, Solana } from '@lifi/sdk'

const walletAdapter = new KeypairWalletAdapter('PRIVATE_KEY')

createConfig({
  integrator: 'Your dApp/company name',
  providers: [
    Solana({
      getWalletAdapter: async () => walletAdapter,
    }),
  ],
})
```

### JSON-RPC 钱包适配器

要与 JSON-RPC 账户交互并将 `WalletAdapter` 传递给 Solana 提供程序，我们建议使用 [@solana/wallet-adapter-base](https://github.com/anza-xyz/wallet-adapter) 和 [@solana/wallet-adapter-react](https://github.com/anza-xyz/wallet-adapter) 库。与 Wagmi 不同，React 的 Solana 配置没有全局配置。因此，我们需要使用 React 钩子在运行时更新 SDK 配置。

以下是如何设置 Solana 提供程序的简化示例。

<CodeGroup>
  ```typescript SDKProviders.tsx theme={"system"}
  import { Solana, config, createConfig } from '@lifi/sdk';
  import type { SignerWalletAdapter } from '@solana/wallet-adapter-base';
  import { useWallet } from '@solana/wallet-adapter-react';
  import { useEffect } from 'react';

  createConfig({
    integrator: 'Your dApp/company name',
  });

  export const SDKProviders = () => {
    const { wallet } = useWallet();

    useEffect(() => {
      // 配置 SDK 提供程序
      config.setProviders([
        Solana({
          async getWalletAdapter() {
            return wallet?.adapter as SignerWalletAdapter;
          },
        }),
      ]);
    }, [wallet?.adapter]);

    return null;
  };
  ```

  ```typescript SolanaProvider.tsx theme={"system"}
  import type { Adapter } from '@solana/wallet-adapter-base';
  import { WalletAdapterNetwork } from '@solana/wallet-adapter-base';
  import {
    ConnectionProvider,
    WalletProvider,
  } from '@solana/wallet-adapter-react';
  import { clusterApiUrl } from '@solana/web3.js';
  import { type FC, type PropsWithChildren } from 'react';
  import { SDKProviders } from './SDKProviders.js';

  const endpoint = clusterApiUrl(WalletAdapterNetwork.Mainnet);
  /**
   * 实现这些标准之一的钱包将自动可用。
   *
   *   - Solana Mobile Stack Mobile Wallet Adapter Protocol
   *     (https://github.com/solana-mobile/mobile-wallet-adapter)
   *   - Solana Wallet Standard
   *     (https://github.com/solana-labs/wallet-standard)
   *
   * 如果您希望支持不支持这些标准的钱包，
   * 请在此处实例化其旧版钱包适配器。常见的旧版适配器可以在
   * npm 包 `@solana/wallet-adapter-wallets` 中找到。
   */
  const wallets: Adapter[] = [];

  export const SVMBaseProvider: FC<PropsWithChildren> = ({ children }) => {
    return (
      <ConnectionProvider endpoint={endpoint}>
        <WalletProvider wallets={wallets} autoConnect>
          {/* 配置 Solana SDK 提供程序 */}
          <SDKProviders />
          {children}
        </WalletProvider>
      </ConnectionProvider>
    );
  };
  ```
</CodeGroup>

## 设置 Sui 提供程序

Sui 提供程序执行逻辑是基于 [@mysten/dapp-kit](https://sdk.mystenlabs.com/dapp-kit) 和 [@mysten/sui](https://sdk.mystenlabs.com/typescript) 库构建的，使用其一些类型和术语。

**配置 Sui 提供程序的可用选项：**

* `getWallet`: 返回 `WalletWithRequiredFeatures` 实例（由 `@mysten/wallet-standard` 定义）的函数。

### JSON-RPC 钱包

要与用户钱包（如 Sui Wallet、Ethos 等）交互并将 `WalletWithRequiredFeatures` 传递给 Sui 提供程序，我们建议使用 [@mysten/dapp-kit](https://sdk.mystenlabs.com/dapp-kit) 库。

以下是如何使用用户钱包设置 Sui 提供程序的简化示例。

<CodeGroup>
  ```typescript SDKProviders.tsx theme={"system"}
  import { Sui, config, createConfig } from '@lifi/sdk';
  import { useCurrentWallet } from '@mysten/dapp-kit';
  import { useEffect } from 'react';

  createConfig({
    integrator: 'Your dApp/company name',
  });

  export const SDKProviders = () => {
    const { currentWallet } = useCurrentWallet();

    useEffect(() => {
      // 配置 Sui SDK 提供程序
      config.setProviders([
        Sui({
          async getWallet() {
            return currentWallet!;
          },
        }),
      ]);
    }, [currentWallet]);

    return null;
  };
  ```

  ```typescript SuiProvider.tsx theme={"system"}
  import { SuiClientProvider, WalletProvider } from '@mysten/dapp-kit';
  import { getFullnodeUrl } from '@mysten/sui/client';
  import { type FC, type PropsWithChildren } from 'react';
  import { SDKProviders } from './SDKProviders.js';

  const { networkConfig } = createNetworkConfig({
  	mainnet: { url: getFullnodeUrl('mainnet') },
  });

  export const SuiBaseProvider: FC<PropsWithChildren> = ({ children }) => {
    return (
      <SuiClientProvider networks={networkConfig} defaultNetwork="mainnet">
        <WalletProvider autoConnect>
          {/* 配置 Sui SDK 提供程序 */}
          <SDKProviders />
          {children}
        </WalletProvider>
      </SuiClientProvider>
    );
  };
  ```
</CodeGroup>

## 设置 UTXO（比特币）提供程序

比特币提供程序执行逻辑是基于 [Bigmi](https://github.com/lifinance/bigmi) 库构建的，使用其一些类型和术语。

**配置 UTXO 提供程序的可用选项：**

* `getWalletClient`: 返回 `Client` 实例的函数

### JSON-RPC 钱包

要与用户钱包（如 Phantom、Xverse）交互，请使用 `getConnectorClient` 操作返回 SDK 所需的 Bigmi Client 对象。

<CodeGroup>
  ```typescript SDKProvider.tsx theme={"system"}
  import { createConfig, UTXO } from '@lifi/sdk'
  import { getConnectorClient } from '@bigmi/client' 
  import { useConfig } from '@bigmi/react'


  const config = createConfig({
    integrator: 'Your dApp/company name',
  })

  export const SDKProviders = () => {
    const bigmiConfig = useConfig();

    useEffect(() => {
      // 配置 SDK 提供程序
      config.setProviders([
        UTXO({
          async getWalletClient() {
            return getConnectorClient(bigmiConfig)
          },
        }),
      ]);
    }, [bigmiConfig]);

    return null;
  };

  ```

  ```typescript UTXOProvider.tsx theme={"system"}
  import { bitcoin, createClient, http } from '@bigmi/core'
  import { createConfig, phantom, getConnectorClient, type CreateConnectorFn, type Config } from '@bigmi/client' 
  import { BigmiProvider } from '@bigmi/react'
  import { SDKProvider } from './SDKProvider.js'

    const connectors: CreateConnectorFn[] = [phantom()]

    const bigmiConfig = createConfig({
      chains: [bitcoin],
      connectors,
      client({ chain }) {
        return createClient({ chain, transport: http() })
      }
    }) as Config

  export const UTXOProvider: FC<PropsWithChildren> = ({ children }) => {
    return (
      <BigmiProvider config={bigmiConfig} reconnectOnMount>
      <SDKProvider />
        { children }
      </BigmiProvider>
    )
  }

  ```
</CodeGroup>
