Web3Modal Solana 适配器全解析:@reown/appkit-adapter-solana 架构、连接器与交易工具链
区块链前端认证鉴权【免费下载链接】web3modalThe full stack toolkit to build onchain app UX项目地址https://gitcode.com/gh_mirrors/we/web3modal点击查看免费下载导读本文以 packages/adapters/solana/README.md 为骨架深入讲解 Web3ModalAppKit生态中面向 Solana 的官方适配器reown/appkit-adapter-solana。你将了解到该适配器在 AppKit 全栈工具链中的定位、它支持的网络与钱包接入方式WalletConnect、Wallet Standard、Coinbase Wallet、邮箱/社交登录、SolanaAdapter的配置参数与核心 API以及底层基于solana/web3.js与solana/kit两套 API 的 SOL / SPL Token 交易构建与发送机制。阅读本文后你可以直接在自己的 React、Vue、Next.js 或纯 HTML 项目中接入 Solana 钱包与链上交易能力。一、适配器在 AppKit 中的定位AppKit 的自我定位是 The full stack toolkit to build onchain app UX——一站式构建链上应用体验的全栈工具包。其能力清单覆盖了 Swap代币兑换、On-Ramp法币入金、多链Multi Chain、多钱包Multi Wallets、智能账户Smart Accounts、Telegram Mini Apps、Sponsored Transactions赞助交易等而网络支持则横跨 EVM Chains、Solana 与 Bitcoin见 packages/adapters/solana/README.md。reown/appkit-adapter-solana正是该体系中连接 Solana 网络的桥梁。从 package.json 可以看出它是一等公民name为reown/appkit-adapter-solana版本1.8.24以 ESM 方式发布并同时提供react与vue两个子入口exports字段中的./react、./vue。其依赖与 Solana 官方生态深度绑定solana/web3.js1.98.4—— 传统Connection/Transaction/PublicKeyAPIsolana/kit8.3.0与solana/compat—— 新一代 Solana Kit APIsolana/wallet-adapter-base、solana/wallet-standard-features、wallet-standard/app—— 钱包标准协议walletconnect/universal-provider与reown/appkit-wallet—— WalletConnect 会话与 W3mFrame邮箱/社交登录能力solana/spl-token、solana-program/token、solana-program/compute-budget—— SPL Token 转账与计算预算指令二、快速上手安装与基础配置2.1 安装以 React 项目为例在 README 提供的 SDK 列表中 React 位于首位。安装命令为npm install reown/appkit reown/appkit-adapter-solana reown/appkit/networks # 或使用 pnpm pnpm add reown/appkit reown/appkit-adapter-solana reown/appkit/networks注意reown/appkit/networks子路径提供了solana、solanaDevnet、solanaTestnet三个预置网络常量定义于 packages/appkit/src/networks/solana/ 目录下。例如 solana.ts 中export const solana defineChain({ id: 5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp, name: Solana, network: solana-mainnet, nativeCurrency: { name: Solana, symbol: SOL, decimals: 9 }, rpcUrls: { default: { http: [https://rpc.walletconnect.org/v1] } }, blockExplorers: { default: { name: Solscan, url: https://solscan.io } }, testnet: false, chainNamespace: solana, caipNetworkId: solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp, deprecatedCaipNetworkId: solana:4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ })三个网络对应的 CAIP-2 网络 ID 可以在 packages/appkit-utils/src/solana/SolanaConstantsUtil.ts 的CHAIN_IDS中查到主网solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp、Devnetsolana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1、Testnetsolana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z。2.2 最小配置React 示例仓库的 examples/react-solana/src/config.ts 给出了完整的 React 接入范例import { SolanaAdapter } from reown/appkit-adapter-solana/react import { solana, solanaDevnet, solanaTestnet } from reown/appkit/networks import { createAppKit, useAppKit, useAppKitAccount, useAppKitNetwork } from reown/appkit/react // 请在 https://cloud.reown.com 申请自己的 projectId仓库示例中给出的 // b56e18d47c72ab683b10814fe9495694 仅用于 localhost 本地调试 export const projectId import.meta.env.VITE_PROJECT_ID || b56e18d47c72ab683b10814fe9495694 const networks [solana, solanaTestnet, solanaDevnet] // 创建 Solana 适配器 const solanaAdapter new SolanaAdapter() // 创建 Modal const modal createAppKit({ adapters: [solanaAdapter], networks, metadata: { name: AppKit React Example, description: AppKit React Solana Example, url: https://reown.com/appkit, icons: [https://avatars.githubusercontent.com/u/179229932?s200v4] }, projectId, themeMode: light, features: { analytics: true } })要点通过reown/appkit-adapter-solana/react子入口导入SolanaAdapterVue 项目则从reown/appkit-adapter-solana/vue导入。将适配器放入createAppKit的adapters数组networks支持同时传入 EVM、Solana、Bitcoin 网络实现多链共存。该示例还展示了useAppKitAccount、useAppKitNetwork等 hooks 的导出方式App.tsx中则通过appkit-button /、appkit-network-button /两个 Web Component 渲染接入按钮。纯 HTML/JS 场景可参考 examples/html-solana/src/main.js其使用createAppKit后通过modal.subscribeAccount、modal.subscribeNetwork、modal.subscribeProviders等订阅方法获取状态与 Solana provider。三、SolanaAdapter 配置项与内部结构3.1 AdapterOptions适配器构造函数位于 packages/adapters/solana/src/client.ts接受一个可选的AdapterOptionsexport interface AdapterOptions { connectionSettings?: Commitment | ConnectionConfig /** * deprecated 钱包现在会自动从浏览器中识别 */ wallets?: BaseWalletAdapter[] /** * 是否将 WalletConnect 注册为一个 Wallet Standard 钱包 * default false */ registerWalletStandard?: boolean }connectionSettings传给solana/web3.jsConnection的配置可以是Commitment字符串默认confirmed或完整ConnectionConfig对象。它决定了区块确认级别与 RPC 行为。wallets已废弃——旧版本手动传入钱包适配器列表现在钱包会自动从浏览器环境识别。registerWalletStandard默认false。开启后适配器会把 WalletConnect 会话注册为一个标准的 Wallet Standard 钱包见下文setUniversalProvider。3.2 继承体系SolanaAdapter继承自AdapterBlueprintSolanaProvider构造时声明了adapterType: SOLANA、namespace: solana。这是 AppKit 的AdapterBlueprint抽象要求实现connect、disconnect、switchNetwork、sendTransaction、signMessage、getBalance、getAccounts等统一接口从而让上层 Modal 以统一方式操作不同链。3.3 全局连接状态SolStoreUtil适配器把当前 RPC 连接集中存放在 packages/adapters/solana/src/utils/SolanaStoreUtil.ts 的SolStoreUtil中基于valtio的proxy实现响应式状态export interface SolStoreUtilState { connection: Connection | null rpc: Rpc | null } const state proxySolStoreUtilState({ connection: null, rpc: null }) export const SolStoreUtil { state, setConnection(connection: Connection, rpc: Rpc) { state.connection ref(connection) state.rpc ref(rpc) } // 另有 subscribe / subscribeKey 供外部订阅 }connection是solana/web3.js的Connection用于getBalance、getLatestBlockhash、sendRawTransaction等rpc是solana/kit的Rpc用于新的 Kit API。两者都基于同一 RPC URL 创建new SolanaConnection(rpcUrl, this.connectionSettings)与createSolanaRpc(rpcUrl)。RPC URL 的优先级为连接时传入的params.rpcUrl 当前 CAIP 网络的rpcUrls.default.http[0]。四、四大 Provider钱包接入的完整矩阵适配器通过addConnector注册多种连接器Connector每种连接器都实现统一的SolanaProvider接口publicKey、address、signMessage、signTransaction、signAndSendTransaction、sendTransaction等。四个 Provider 位于 packages/adapters/solana/src/providers/4.1 AuthProvider —— 邮箱 / 社交登录AuthProvider.ts 基于W3mFrameProviderAppKit 托管的嵌入式钱包框架通过SIWXUtil.authConnectorAuthenticate完成认证支持邮箱登录、社交登录Google、X 等与 One-Click Auth并配合 SIWXSign In with X能力。连接时使用withSolanaNamespace(chainId)把链 ID 规范为solana:${chainId}形式见 withSolanaNamespace.ts。签名走solana_signMessage/solana_signTransaction方法返回 base58 编码签名。4.2 SolanaWalletConnectProvider —— WalletConnect 钱包SolanaWalletConnectProvider.ts 继承自WalletConnectConnectorsolana把UniversalProvider包装成 Solana Provider。它实现了四个 WalletConnect Solana RPC 方法方法参数返回solana_signMessage{ message, pubkey }{ signature }solana_signTransaction{ transaction, pubkey }{ signature }或{ transaction }solana_signAndSendTransaction{ transaction, pubkey, sendOptions }{ signature }solana_signAllTransactions{ transactions }{ transactions }实现细节值得注意交易序列化统一使用base64Buffer.from(bytes).toString(base64)这是 Reown 多链 RPC 规范的要求。对已废弃网络 ID做了兼容部分钱包只接受旧的solana:4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZDeprecated Mainnet等 IDProvider 在发送请求前会自动在标准 ID 与废弃 ID 之间切换见chainsgetter 与internalRequest。兼容solana/web3.js的Transaction/VersionedTransaction与solana/kit的Transaction两类对象通过 SolanaKitTransaction.ts 中的encode/decode做双向转换。4.3 WalletStandardProvider —— Wallet Standard 钱包WalletStandardProvider.ts 实现了SolanaProvider接口对接浏览器中通过wallet-standard/app注册的钱包Phantom、Solflare 等。它只调用钱包features中真实存在的能力standard:connect、standard:disconnect、solana:signMessage、solana:signTransaction、solana:signAndSendTransaction、standard:events缺失能力时抛出WalletStandardFeatureNotSupportedError。钱包的自动发现由 watchStandard.ts 完成监听register/unregister事件把兼容的钱包包装成WalletStandardProvider并过滤掉WalletConnect避免重复。syncConnectors中调用它同时若浏览器存在window.coinbaseSolana还会注册CoinbaseWalletProvider见 client.ts 与 CoinbaseWalletProvider.ts。这一行为在 client.test.ts 中有明确测试覆盖window.coinbaseSolana存在时addConnector被调用一次且连接器 ID 为 Coinbase 的 explorer ID、type: ANNOUNCED。五、核心 API连接、余额、签名与交易SolanaAdapter暴露给上层的关键方法全部定义于 client.ts5.1 connect 与 switchNetworkconnect(params)按连接器 ID 找到对应 connector 并调用其connect随后通过SolStoreUtil.setConnection建立 RPC 连接广播accountChanged事件并调用listenSolanaProviderEvents订阅disconnect/accountsChanged/connect事件以同步账户状态。switchNetwork则根据目标 CAIP 网络的 RPC URL 重建连接。连接的同步重连由syncConnections负责它会读取本地存储中已连接过且未断开的连接器并逐一重连WalletConnect 连接则直接复用universalProvider的既有账户。5.2 getBalance 与缓存getBalance使用connection.getBalance(new PublicKey(address))获取 lamports再除以SolConstantsUtil.LAMPORTS_PER_SOL1_000_000_000见 SolanaConstantsUtil.ts得到以 SOL 为单位的字符串。适配器做了两层缓存进行中的请求按caipAddress缓存 Promise 去重已完成的结果写入StorageUtil的原生资产缓存命中后直接返回。5.3 signMessage调用provider.signMessage(new TextEncoder().encode(params.message))返回的签名经bs58.encode编码为 base58 字符串。5.4 sendTransactionSOL 与 SPL Token 双路径sendTransaction是交易的统一入口client.tsconst transaction params.tokenMint ? await createSPLTokenTransaction({ provider, connection, to: params.to, amount: Number(params.value), tokenMint: params.tokenMint }) : await createSendTransaction({ provider, connection, to: params.to, value: Number.isNaN(Number(params.value)) ? 0 : Number(params.value) }) const result await provider.sendTransaction(transaction, connection) // 钱包签名并广播 // 随后每 1 秒轮询 getSignatureStatus直到状态可用SOL 转账由 createSendTransaction.ts 构建lamports Math.floor(value * LAMPORTS_PER_SOL)并自动附加两条 Compute Budget 指令——setComputeUnitPrice({ microLamports: 20000000 })20,000,000 微 lamports 的优先费单价与setComputeUnitLimit({ units: 500 })最后使用最新 blockhash 组装SystemProgram.transfer交易。这保证转账在拥堵时仍能被优先打包。SPL Token 转账由 createSPLTokenTransaction.ts 构建流程更复杂通过getMintOwnerProgramId自动识别 mint 归属TOKEN_PROGRAM_IDSPL Token还是TOKEN_2022_PROGRAM_IDToken-2022读取 mint 的decimals计算最小精度单位金额通过getAssociatedTokenAddressSync计算收发双方的 ATA 地址并检查余额是否充足若接收方没有 ATA则自动加入createAssociatedTokenAccountInstructionATA 创建指令调用resolveComputeBudgetInstructions估算计算单元再附加createTransferCheckedInstruction完成转账。5.5 计算单元估算模拟驱动的优先费resolveComputeBudgetInstructions.ts 是 SPL 转账的智能计价器它先用connection.simulateTransaction对交易做一次模拟sigVerify: false、replaceRecentBlockhash: true即无需真实签名拿到unitsConsumed实际消耗值再乘以1.3的裕量系数并封顶在1_400_000模拟失败时回退到固定值仅转账150_000含 ATA 创建200_000。这些常量统一定义在 SolanaConstantsUtil.ts 的SPL_COMPUTE_BUDGET_CONSTANTS中。注释指出这样做的原因Solana 按请求的计算单元上限而非实际消耗收费因此用真实模拟结果而非静态上限来定价。5.6 交易错误友好化sendTransaction与writeSolanaTransaction都会捕获SendTransactionError把其transactionError.message与logs拼接后与正则表匹配翻译成人类可读的错误client.ts匹配模式友好提示Attempt to debit an account but found no record of a prior creditNot enough SOL to cover fees or rentInsufficient funds for feeNot enough SOL to cover fees or rentTransfer: insufficient lamportsNot enough SOL to cover this transfer该行为在 sendTransaction.test.ts 中有专门测试当模拟错误消息包含Transfer: insufficient lamports时断言抛出自定义错误。5.7 Solana Kit 工具函数针对solana/kit新一代 API适配器在 SolanaKitConnectionUtil.ts 中提供了三个可直接导出的工具函数从包入口reown/appkit-adapter-solana导出getBalanceKit(rpc, address)—— 通过rpc.getBalance(address).send()获取 lamports 余额getLatestBlockhashKit(rpc)—— 获取{ blockhash, lastValidBlockHeight }waitForSignatureConfirmationKit(rpc, signature)—— 每 1 秒轮询getSignatureStatuses直到确认。六、Solana Kit 集成createSPLTokenTransactionKit 与 useAppKitConnection6.1 纯 Kit 实现的 SPL 转账createSPLTokenTransactionKit.ts 是不依赖solana/web3.js的替代实现完全基于solana/kit与solana-program/token用fetchMaybeMint读取 mint目前仅支持 SPL Token 标准 mintToken-2022 会明确报错用toTokenBaseUnits做十进制金额到最小单位的转换——它采用字符串数学而非浮点乘法规避了0.29 * 100 28.999999999999996这类 IEEE-754 精度问题使用estimateComputeUnitLimitFactory({ rpc })对无 lifetime 的交易消息做真实模拟估算值乘以1.3裕量、封顶1_400_000失败回退50_000blockhash 刻意放在编译前最后一次 RPC 调用才获取setTransactionMessageLifetimeUsingBlockhash以最小化签名前 blockhash 过期的窗口。6.2 React / Vue 的 useAppKitConnection hookReact 与 Vue 子入口exports/react.ts、exports/vue.ts都导出了useAppKitConnection()它读取SolStoreUtil.state并返回{ connection, rpc }让 dApp 侧可以直接拿到当前 RPC 连接做链上查询。仓库的 examples/react-solana-kit/src/components/SolanaKitDemo.tsx 完整演示了这套组合拳通过useAppKitProviderProvider(solana)拿到walletProvideruseAppKitConnection()拿到connection然后const kitTransaction await createSPLTokenTransactionKit({ provider: walletProvider, connection, to: walletProvider.address, amount: 0.01, tokenMint: DEVNET_USDC_MINT // Circle Devnet USDC: 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU }) const signature await walletProvider.signAndSendTransaction(kitTransaction)示例同时说明Provider 类型是加法式的——publicKey旧 web3.js与addresssolana-kit Address永远指向同一个已连接账户。七、多链共存与网络适配7.1 与其他链适配器共存AppKit 支持 EVM、Solana、Bitcoin 同时接入。examples/next-wagmi-solana-bitcoin-app-router/src/config/index.ts 展示了三链适配器并存的配置export const networks [mainnet, polygon, arbitrum, optimism, solana, solanaDevnet, solanaTestnet, bitcoin, bitcoinTestnet] export const wagmiAdapter new WagmiAdapter({ networks, projectId }) export const solanaAdapter new SolanaAdapter({}) export const bitcoinAdapter new BitcoinAdapter() const modal createAppKit({ adapters: [wagmiAdapter, solanaAdapter, bitcoinAdapter], networks, metadata: { name: AppKit Next.js Wagmi Solana, ... }, projectId })7.2 Solana 网络 ID 的归一化chains.ts 定义了solanaChains映射solana:mainnet、solana:testnet、solana:devnetgetStandardChain用于在 CAIP-2 ID 与 Wallet Standard 的链名之间转换getStandardChainName等辅助则被WalletStandardProvider用于把活动链映射为钱包要求的链名。配合前文提到的废弃网络 ID兼容逻辑适配器能够在标准网络与旧钱包兼容网络间自动协商。八、包导出结构与测试保障8.1 导出矩阵包入口 exports/index.ts 导出SolanaAdapter、三个 Kit 工具函数、createSPLTokenTransactionKit以及AdapterOptions等类型./react、./vue子入口额外导出useAppKitConnection与 Solana 相关类型。另外index.ts第一行会导入reown/appkit-polyfills以补齐运行时兼容。8.2 测试覆盖适配器测试位于 packages/adapters/solana/src/tests/覆盖client.test.ts—— 适配器构造、syncConnectorsCoinbase 条件注册、连接初始化断言SolStoreUtil.setConnection使用网络默认 RPCsendTransaction.test.ts、createSendTransaction.test.ts—— 交易构建与错误映射createSPLTokenTransaction.test.ts、createSPLTokenTransactionKit.test.ts、resolveComputeBudgetInstructions.test.ts—— SPL 转账与模拟估算AuthProvider.test.ts、WalletConnectProvider.test.ts、WalletStandardProvider.test.ts、GenericProvider.test.ts—— 各 Provider 的签名与事件SolanaKitConnectionUtil.test.ts、SolanaStoreUtil.test.ts、withSolanaNamespace.test.ts—— 工具函数。运行测试见 package.json 的 scriptspnpm --filter reown/appkit-adapter-solana test内部使用 Vitest 并开启覆盖率统计。九、从 Web3Modal v1–v5 迁移README 特别提示如果你正在使用 Web3Modal v1–v5请使用官方迁移指南升级到 Reown AppKit。迁移的核心变化包括包名从web3modal/*改为reown/appkit*、createWeb3Modal改为createAppKit、adapter 概念取代旧的 modal 直连方式等。具体到 Solana旧版通过web3modal/solana提供的SolanaAdapter配置方式已迁移为reown/appkit-adapter-solana的新接口如connectionSettings、自动钱包发现迁移后请移除手动传入的wallets数组。十、小结reown/appkit-adapter-solana是 Web3Modal/AppKit 多链体系中功能最完整的 Solana 接入层之一其设计要点可概括为统一抽象通过AdapterBlueprint接口与四大 ProviderAuth、WalletConnect、Wallet Standard、Coinbase屏蔽了不同钱包接入协议W3mFrame、WalletConnect RPC、Wallet Standard features的差异双 API 兼容同时支持solana/web3.js与solana/kit两代 API交易可在两者间无缝序列化/反序列化智能计价基于真实模拟的计算单元估算与优先费指令兼顾交易成功率与费用开箱即用SOL/SPL 转账、余额缓存、错误翻译、多链共存、网络 ID 兼容等细节全部内置dApp 侧只需几行配置即可完成接入。如需继续深入推荐阅读 client.ts 的完整实现、SolanaKitDemo.tsx 的 Kit 集成范例以及 tests 目录下的测试用例。赞分享区块链前端认证鉴权【免费下载链接】web3modalThe full stack toolkit to build onchain app UX项目地址https://gitcode.com/gh_mirrors/we/web3modal点击查看免费下载相关推荐FlashAttention 稀疏 MLA 训练精度dpsum 精度修复O 残差补偿技术解析FlashAttention 稀疏 MLA 训练精度dpsum 精度修复O 残差补偿技术解析 稀疏 MLADSA / top k gathered KV区块链前端认证鉴权创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考