wagmi 核心 Action 详解:switchConnection 切换当前连接账户
wagmi 核心 Action 详解switchConnection 切换当前连接账户【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmiswitchConnection是wagmi/core提供的一个核心 Action用于在已建立的多个连接connection之间切换当前账户。本文以 switchConnection 官方文档 为骨架结合仓库源码深入讲解它的调用方式、参数与返回类型、底层实现原理、错误处理以及 TanStack Query 与 React Hook 的集成方式帮助你准确掌握多账户场景下的连接切换能力。一、switchConnection 是什么在 wagmi 中一个Config实例可以同时维护多个连接connection每个连接对应一个 Connector如 MetaMask、WalletConnect与一组账户。switchConnection的作用就是改变当前激活的连接从而让后续以当前账户为基准的读取与交易操作切换到另一套账户上。从源码看它的核心逻辑非常精简位于 packages/core/src/actions/switchConnection.tsexport async function switchConnectionconfig extends Config( config: config, parameters: SwitchConnectionParameters, ): PromiseSwitchConnectionReturnTypeconfig { const { connector } parameters const connection config.state.connections.get(connector.uid) if (!connection) throw new ConnectorNotConnectedError() await config.storage?.setItem(recentConnectorId, connector.id) config.setState((x) ({ ...x, current: connector.uid, })) return { accounts: connection.accounts, chainId: connection.chainId, } }它并不负责发起新的钱包连接而是从config.state.connections这个连接池中取出目标 connector 对应的连接将其uid设为state.current从而完成当前账户的切换。二、导入与基本用法1. 导入switchConnection从wagmi/core顶层导出可直接按需引入import { switchConnection } from wagmi/core对应的类型参数、返回、错误同样从wagmi/core导出将在后文逐一说明。2. 标准用法官方文档给出的典型场景是先通过getConnections拿到当前 Config 上已建立的所有连接再把其中一个连接对应的 connector 传给switchConnectionimport { getConnections, switchConnection } from wagmi/core import { config } from ./config const connections getConnections(config) const result await switchConnection(config, { connector: connections[0]?.connector, })这里的config是一个通过createConfig创建的配置实例仓库中对应的示例位于 site/snippets/core/config.tsimport { createConfig, http } from wagmi/core import { mainnet, sepolia } from wagmi/core/chains export const config createConfig({ chains: [mainnet, sepolia], transports: { [mainnet.id]: http(), [sepolia.id]: http(), }, })3. 为什么要配合 getConnectionsswitchConnection的参数是connector而连接是按connector.uid索引的。getConnections会返回当前 Config 上全部已建立的连接packages/core/src/actions/getConnections.tsexport function getConnections(config: Config): GetConnectionsReturnType { const connections [...config.state.connections.values()] if (config.state.status reconnecting) return previousConnections if (deepEqual(previousConnections, connections)) return previousConnections previousConnections connections return connections }因此标准姿势就是先getConnections枚举再switchConnection指定其中一个保证传入的 connector 一定处于已连接状态。三、参数详解SwitchConnectionParametersimport { type SwitchConnectionParameters } from wagmi/core该类型定义在 packages/core/src/actions/switchConnection.tsexport type SwitchConnectionParameters { connector: Connector }connector类型Connector含义要切换到的连接对应的 Connector 实例即 Connector 中描述的对象。一个实际的使用示例文档原样import { getConnections, switchConnection } from wagmi/core import { config } from ./config const connections getConnections(config) const result await switchConnection(config, { connector: connections[0]?.connector, // [!code focus] })需要特别注意的是connector必须是已经建立过连接的 connector。如果传入的连接并不存在于config.state.connections中switchConnection会直接抛出ConnectorNotConnectedError详见下文错误处理小节。如果需要建立全新连接应使用 connect 之类的 Action而不是switchConnection。四、返回类型详解SwitchConnectionReturnTypeimport { type SwitchConnectionReturnType } from wagmi/core类型定义于 packages/core/src/actions/switchConnection.tsexport type SwitchConnectionReturnTypeconfig extends Config Config { accounts: readonly [Address, ...Address[]] chainId: | config[chains][number][id] | (number extends config[chains][number][id] ? number : number {}) }accounts类型readonly [Address, ...Address[]]含义目标 connector 连接上的账户地址列表至少包含一个地址。它与getConnection返回的addresses一致来源于连接建立时获取的账户集合。chainId类型number含义目标 connector 当前所在的链 ID。在类型层面它会尽量收紧为config配置中声明的链 ID 联合类型若 Config 未限定链集合则退化为number。需要说明的是accounts与chainId都是从已有连接中原样返回的对应源码中的connection.accounts与connection.chainIdswitchConnection本身不会发起网络请求去重新查询链与账户。五、错误处理import { type SwitchConnectionErrorType } from wagmi/core该联合类型在 packages/core/src/actions/switchConnection.ts 中定义export type SwitchConnectionErrorType | ConnectorNotConnectedErrorType | BaseError | ErrorTypeConnectorNotConnectedError这是switchConnection最典型的失败场景当传入的 connector 在config.state.connections中找不到对应连接时抛出。其定义位于 packages/core/src/errors/config.tsexport type ConnectorNotConnectedErrorType ConnectorNotConnectedError { name: ConnectorNotConnectedError } export class ConnectorNotConnectedError extends BaseError { override name ConnectorNotConnectedError constructor() { super(Connector not connected.) } }即错误信息为Connector not connected.。因此在调用前建议先用getConnections校验目标 connector 是否已连接避免依赖运行时抛错。其他错误BaseErrorwagmi 内部所有错误的基类涵盖连接过程中的通用异常ErrorType用于承接任意未知错误通常由 connector 内部抛出。实际开发中可结合getConnectionpackages/core/src/actions/getConnection.ts返回的status字段判断当前连接状态再决定是否需要先connect再switchConnection。六、底层实现原理switchConnection虽然只有十几行代码但每一步都有明确的语义值得逐一拆解校验连接存在config.state.connections.get(connector.uid)按 connector 的唯一标识uid在连接池中查找找不到则抛ConnectorNotConnectedError。持久化最近使用的 connectorconfig.storage?.setItem(recentConnectorId, connector.id)会把本次切换的 connector 写入存储。这样在页面刷新或重新连接reconnect时wagmi 可以优先恢复这个最近使用的连接实现记住上次使用的钱包。更新当前连接指针config.setState把state.current更新为目标 connector 的uid同时保留其余 state 字段。此后getConnection(config)会基于新的current返回对应连接与账户getConnection 实现。返回切换结果从已有连接对象中取出accounts与chainId返回供调用方立即使用。由于整个过程只涉及内存状态与一次可选的 storage 写入不经过网络switchConnection是同步语义下非常轻量的操作函数本身为async以便与存储层衔接。七、与 TanStack Query 的集成wagmi/core/query提供了将switchConnection封装为 mutation 的工厂函数位于 packages/core/src/query/switchConnection.tsexport function switchConnectionMutationOptionsconfig extends Config, context( config: config, options: SwitchConnectionOptionsconfig, context {}, ): SwitchConnectionMutationOptionsconfig { return { ...(options.mutation as any), mutationFn(variables) { return switchConnection(config, variables) }, mutationKey: [switchConnection], } }要点如下mutationFn直接调用核心 Action因此语义与手写调用完全一致mutationKey固定为[switchConnection]便于在 TanStack Query DevTools 中定位同时导出了一组类型SwitchConnectionData返回类型、SwitchConnectionVariables参数类型、SwitchConnectionMutate/SwitchConnectionMutateAsync同步/异步触发函数类型、SwitchConnectionErrorType错误类型。官方文档中的标准导入方式如下import { type SwitchConnectionData, type SwitchConnectionVariables, type SwitchConnectionMutate, type SwitchConnectionMutateAsync, SwitchConnectionMutationOptions, } from wagmi/core/query八、React 中的 useSwitchConnection在 React 侧wagmi 提供了现成 Hook useSwitchConnection内部正是基于上面的switchConnectionMutationOptions与 TanStack Query 的useMutation构建export function useSwitchConnection config extends Config ResolvedRegister[config], context unknown, ( parameters: UseSwitchConnectionParametersconfig, context {}, ): UseSwitchConnectionReturnTypeconfig, context { const config useConfig(parameters) const options switchConnectionMutationOptions(config, parameters) const mutation useMutation(options) ... }值得注意的兼容性细节该 Hook 的返回类型中保留了几个标记为deprecated的别名packages/react/src/hooks/useSwitchConnection.ts#L39-L48/** deprecated use useConnections instead */ connectors: readonly Connector[] /** deprecated use mutate instead */ switchAccount: SwitchConnectionMutateconfig, context /** deprecated use mutateAsync instead */ switchAccountAsync: SwitchConnectionMutateAsyncconfig, context /** deprecated use mutate instead */ switchConnection: SwitchConnectionMutateconfig, context /** deprecated use mutateAsync instead */ switchConnectionAsync: SwitchConnectionMutateAsyncconfig, context这说明了三个重要信息当前推荐的用法是直接使用mutate/mutateAsync触发切换使用useConnections读取连接列表旧的switchAccount、switchConnection等字段仅为向后兼容保留新代码不应再依赖触发时只需传入{ connector }变量即可例如const { mutateAsync } useSwitchConnection() await mutateAsync({ connector })九、测试用例验证仓库为switchConnection提供了完整的单元测试见 packages/core/src/actions/switchConnection.test.ts核心场景是在多个已连接账户之间来回切换await connect(config, { connector: connector2 }) await connect(config, { connector: connector1 }) const address1 getConnection(config).address await switchConnection(config, { connector: connector2 }) const address2 getConnection(config).address expect(address2).toBeDefined() expect(address1).not.toBe(address2) await switchConnection(config, { connector: connector1 }) const address3 getConnection(config).address expect(address3).toBeDefined() expect(address1).toBe(address3)测试揭示了三个可以写进实战经验的行为switchConnection只会改变当前账户而不会断开其他连接——两个连接在切换后依然并存切换后getConnection(config).address会立即反映新账户切回原 connector 后账户地址与切换前完全一致address1 address3说明连接状态被完整保留。十、典型应用场景小结结合文档与源码switchConnection最适合以下场景多钱包/多账户 DApp用户在界面上下拉选择使用哪个账户操作切换后所有依赖getConnection/useAccount的组件自动响应记住最近使用通过底层写入recentConnectorId的机制配合连接恢复流程让用户下次进入时自动回到上次使用的连接作为 mutation 接入数据层借助switchConnectionMutationOptions或useSwitchConnection将切换动作纳入 TanStack Query 的加载/错误状态管理。需要再次强调的是switchConnection只负责切换已存在的连接如果目标 connector 尚未连接应当先调用 connect否则会得到ConnectorNotConnectedError。这一约束是使用该 Action 时最容易踩的坑也是文档示例中坚持先getConnections再切换的根本原因。【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考