ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

wagmi Solid 中的 useConnectorClient:如何从活跃 Connector 获取 Viem Wallet Client

wagmi Solid 中的 useConnectorClient:如何从活跃 Connector 获取 Viem Wallet Client wagmi Solid 中的 useConnectorClient如何从活跃 Connector 获取 Viem Wallet Client【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi本文围绕 wagmi 的 Solid 适配器原语useConnectorClient定义于 packages/solid/src/primitives/useConnectorClient.ts展开讲解它如何在 SolidJS 应用中以响应式方式获取活跃 Connector 对应的 Viem Wallet Client包括参数account/chainId/config/connector的含义与默认行为、查询选项、返回结构以及缓存失效断连时清除、换地址时失效等生命周期机制。读完你应能在 Solid 项目中安全地拿到可调用writeContract、write等方法的 Wallet Client并理解其背后的getConnectorClientaction 与 TanStack Query 集成细节。用途与导入useConnectorClient是一个用于从当前活跃 Connector获取 [Viem Wallet Client] 的原语primitive。典型场景是用户已连接钱包如 MetaMask、Coinbase Wallet你需要一个绑定该钱包账号与链的 Client 来发送交易或调用合约写方法。导入方式import { useConnectorClient } from wagmi/solid基本用法import { useConnectorClient } from wagmi/solid function App() { const client useConnectorClient() // client() 在已连接时返回 Wallet Client }配套的配置示例摘自 site/snippets/solid/config.tsimport { createConfig, http } from wagmi/solid import { mainnet, sepolia } from wagmi/solid/chains export const config createConfig({ chains: [mainnet, sepolia], transports: { [mainnet.id]: http(), [sepolia.id]: http(), }, })注意一个与 React 版本的显著差异Solid 中参数必须作为 getter 函数Accessor传入以维持响应性详见 site/solid/api/primitives.mduseConnectorClient(() ({ chainId: 1, connector: myConnector, }))从源码看useConnectorClient.ts参数的类型正是AccessorSolidParameters...默认值为() ({})因此不传参数时取的是最近WagmiProvider中的 config 与当前连接状态。参数详解accountAddress | undefined指定 Wallet Client 使用的账号。底层 action 的完整签名见 getConnectorClient.ts实际接受Address | Account | null | undefined传入地址/账号时该账号必须存在于 Connector 上否则会抛出ConnectorAccountNotFoundError传入null表示账号可能不存在适用于可从 Connector 推断账号的场景如未连接时发起调用由钱包内弹窗选择账号不传时默认使用连接中的第一个账号connection.accounts[0]。chainIdconfig[chains][number][id] | undefinedClient 要使用的链 ID。不传时默认取当前连接的链Solid 实现中通过useChainId原语响应式获取useConnectorClient.tsconst config useConfig(parameters) const chainId useChainId(() ({ config: config() })) const connection useConnection(() ({ config: config() })) const options createMemo(() getConnectorClientQueryOptionsconfig, chainId(config(), { ...(parameters() as any), chainId: parameters().chainId ?? chainId(), connector: parameters().connector ?? connection().connector, }), )也就是说chainId与connector都支持显式传入 当前连接状态的回退链且由于包在createMemo中切换链useSwitchChain会触发查询选项的重新计算。类型测试useConnectorClient.test-d.ts验证了这一推导指定config后client.data?.chain?.id被推导为1 | 456 | 10再显式传chainId: 1则收窄为1。configConfig | undefined覆盖从最近WagmiProvider获取的Config。用于多 Provider 嵌套或测试场景中注入自定义 config。connectorConnector | undefined指定要获取 Client 的 Connector默认是活跃 Connector即config.state.current对应的连接。connector还决定了查询是否启用。核心查询选项构建函数getConnectorClientQueryOptionspackages/core/src/query/getConnectorClient.ts中有这样的逻辑enabled: Boolean(options.connector?.getProvider (options.query?.enabled ?? true)),即仅当 connector 实现了getProvider时查询才默认启用同时该函数强制了gcTime: 0与staleTime: Number.POSITIVE_INFINITYClient 一旦被获取便视为长时有效缓存交由原语自行清理。queryTanStack Query 选项query参数接受一组 TanStack Query 选项但 wagmi 并不支持全部参数——queryFn、queryKey等由内部使用、不可覆盖。支持的常用项包括enabled设为false可禁用自动查询实现依赖查询、initialData/initialDataUpdatedAt、meta、networkMode、notifyOnChangeProps、placeholderData、queryClient、refetchInterval、refetchIntervalInBackground、refetchOnMount、refetchOnReconnect、refetchOnWindowFocus、retry、retryDelay、retryOnMount、select、structuralSharing完整说明见 site/shared/query-options.md。注意gcTime与staleTime在本原语中由内部固定不在可传之列对应类型中Omit..., gcTime | staleTime。返回类型useConnectorClient.ReturnType // UseQueryReturnTypeGetConnectorClientDataconfig, chainId, GetConnectorClientErrorType它本质上是一个createQuery的结果经 packages/solid/src/utils/query.ts 中的useQuery封装因此包含 TanStack Query 的标准状态与访问器状态statuspending/success/error、fetchStatus、isPending、isLoading、isSuccess、isError、isFetching、isStale等数据data成功时为 Viem Client含account与chain、dataUpdatedAt错误error类型为GetConnectorClientErrorType、errorUpdateCount、failureCount等操作refetch、queryKey。queryKey的结构为[connectorClient, { chainId, ... }]由getConnectorClientQueryKey生成见 getConnectorClient.ts默认状态下测试快照可直观看到queryKey: [connectorClient, { chainId: 1 }]可能的错误类型GetConnectorClientErrorType包括ConnectorAccountNotFoundError、ConnectorChainMismatchError、ConnectorNotConnectedError、ConnectorUnavailableReconnectingError以及 Viem 的BaseError。生命周期缓存清理与失效useConnectorClient除了查询本身还通过createEffect管理了连接状态变化时的缓存useConnectorClient.tsconst queryClient useQueryClient() createEffect( on( () connection().address, (currentAddress, previousAddress) { if (!currentAddress previousAddress) { // 账号断开时移除缓存 queryClient.removeQueries({ queryKey: options().queryKey }) } else if (currentAddress ! previousAddress) { // 地址变化时使缓存失效 queryClient.invalidateQueries({ queryKey: options().queryKey }) } }, { defer: true }, ), )这意味着断连后旧 Client 缓存会被移除避免残留指向已失效账号的 Client地址切换时旧缓存被标记失效并重新获取。测试用例useConnectorClient.test.ts对这套行为做了完整验证behavior: connect and disconnect连接前data为undefineduseConnect().mutate(...)后data就绪useDisconnect().mutate()后data重新变为undefinedbehavior: switch chainsuseSwitchChain切换到链 456 后data.chain.id变为456切回 1 后恢复behavior: disabled when connectingconfig 状态为connecting时查询不进入 loading等待连接完成。底层 actiongetConnectorClient原语底层复用了 core 包的getConnectorClientactionpackages/core/src/actions/getConnectorClient.ts其执行链路值得了解定位连接显式传connector时并行调用connector.getAccounts()与connector.getChainId()构造连接否则读取config.state.connections.get(config.state.current)。无连接则抛ConnectorNotConnectedError。若 config 处于reconnecting且 connector 无法离线读取账号/链则抛ConnectorUnavailableReconnectingError链一致性断言默认assertChainId true当connection.connector.getChainId()与目标chainId不一致时抛ConnectorChainMismatchError防止 Client 指向与钱包实际链不符的环境优先使用 connector 自定义 Client若 connector 实现了getClient直接返回其结果见 getConnectorClient.ts默认路径取账号默认connection.accounts[0]并做地址校验和通过connector.getProvider({ chainId })获取 Provider然后用 Viem 的createClient以customtransportretryCount: 0即不做 RPC 重试创建 Clientreturn createClient({ account, chain, name: Connector Client, transport: (opts) custom(provider)({ ...opts, retryCount: 0 }), })这也解释了为何返回的 Client 是直连钱包 Provider的写能力载体而不是走 config 中配置的httptransport。与其他原语的组合useConnectorClient是写操作链路的一环可自然与仓库中的其他 Solid 原语组合useConnect / useDisconnect驱动连接状态useConnectorClient的data随之出现/消失useSwitchChain切链后 Client 的chain自动更新见上文测试useWriteContract拿到 Client 后发送交易。小结useConnectorClient是 Solid 端获取活跃 Connector 对应 Viem Wallet Client 的响应式原语参数需以 getter 函数传入四个核心参数account/chainId/config/connector均有合理的回退默认值连接账号、连接链、Provider 的 config、活跃 connector不传参即可在大多数场景直接使用查询在 connector 未就绪如connecting状态、无getProvider时保持pending底层固定staleTime: Infinity、gcTime: 0由原语在断连时removeQueries、换地址时invalidateQueries管理缓存失败时会以ConnectorNotConnectedError、ConnectorChainMismatchError、ConnectorAccountNotFoundError等类型化错误暴露问题便于在error分支中精确处理。【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表