wagmi-development
Creates Wagmi features across all layers - core actions, query options, framework bindings. Use when adding new actions, hooks, or working across packages/core, packages/react, packages/vue.
Install
mkdir -p .claude/skills/wagmi-development && curl -L -o skill.zip "https://mcp.directory/api/skills/download/4453" && unzip -o skill.zip -d .claude/skills/wagmi-development && rm skill.zipInstalls to .claude/skills/wagmi-development
About this skill
Wagmi Development
Full-stack patterns for adding Wagmi features. This skill covers Viem-based actions only (not Wagmi config actions).
Layer Overview
- Core Action (
packages/core/src/actions/) - Base functionality wrapping Viem - Query Options (
packages/core/src/query/) - TanStack Query integration - Framework Bindings - React (
packages/react/src/hooks/), Vue (packages/vue/src/composables/)
1. Core Action
Structure
import {
type MyActionErrorType as viem_MyActionErrorType,
type MyActionParameters as viem_MyActionParameters,
type MyActionReturnType as viem_MyActionReturnType,
myAction as viem_myAction,
} from 'viem/actions'
import type { Config } from '../createConfig.js'
import type { ChainIdParameter, ConnectorParameter } from '../types/properties.js'
import type { Compute } from '../types/utils.js'
import { getAction } from '../utils/getAction.js'
export type MyActionParameters<config extends Config = Config> = Compute<
ChainIdParameter<config> & viem_MyActionParameters
>
export type MyActionReturnType = viem_MyActionReturnType
export type MyActionErrorType = viem_MyActionErrorType
/** https://wagmi.sh/core/api/actions/myAction */
export async function myAction<config extends Config>(
config: config,
parameters: MyActionParameters<config>,
): Promise<MyActionReturnType> {
const { chainId, ...rest } = parameters
const client = config.getClient({ chainId })
const action = getAction(client, viem_myAction, 'myAction')
return action(rest)
}
Key Rules
- Viem imports: Prefix with
viem_(e.g.,viem_getBalance) - Client access:
- Read-only:
config.getClient({ chainId }) - Wallet:
await getConnectorClient(config, { chainId, connector, account }) - Mixed: Use
getConnectorClientfor account,getClientfor action (seeestimateGas.ts)
- Read-only:
- Parameters: Add
ChainIdParameter<config>always. AddConnectorParameterfor wallet actions. - Type params: Mirror Viem's type params for inference. Use
constmodifier for literal inference (abi, args). - Spread: Omit wagmi-specific props (
chainId,connector) when calling Viem action.
Testing
Runtime tests (action.test.ts):
import { abi, address, config } from '@wagmi/test'
import { expect, test } from 'vitest'
import { myAction } from './myAction.js'
test('default', async () => {
await expect(myAction(config, { /* required params */ })).resolves.toMatchInlineSnapshot(`...`)
})
test('parameters: chainId', async () => { /* test chainId param */ })
test('behavior: error case', async () => { /* test error handling */ })
Type tests (action.test-d.ts) - only if action has type inference:
import { config } from '@wagmi/test'
import { expectTypeOf, test } from 'vitest'
import { myAction } from './myAction.js'
test('default', async () => {
const result = await myAction(config, { /* params */ })
expectTypeOf(result).toEqualTypeOf<ExpectedType>()
})
Type benchmarks (action.bench-d.ts) - only if action has type inference:
import { attest } from '@ark/attest'
import { test } from 'vitest'
import type { MyActionParameters } from './myAction.js'
test('default', () => {
type Result = MyActionParameters<typeof abi.erc20, 'balanceOf'>
const res = {} as Result
attest.instantiations([12345, 'instantiations'])
attest(res.args).type.toString.snap(`readonly [account: \`0x\${string}\`]`)
})
Wallet action tests: Connect before, disconnect after:
test('default', async () => {
await connect(config, { connector })
await expect(myAction(config, { /* params */ })).resolves.toMatchInlineSnapshot(`...`)
await disconnect(config, { connector })
})
2. Query Options
Query (read-only) or Mutation (wallet) options for TanStack Query.
Query Structure
import {
type MyActionErrorType,
type MyActionParameters,
type MyActionReturnType,
myAction,
} from '../actions/myAction.js'
import type { Config } from '../createConfig.js'
import type { ScopeKeyParameter } from '../types/properties.js'
import type { QueryOptions, QueryParameter } from '../types/query.js'
import type { Compute, ExactPartial } from '../types/utils.js'
import { filterQueryOptions, structuralSharing } from './utils.js'
export type MyActionOptions<
config extends Config,
selectData = MyActionData,
> = Compute<ExactPartial<MyActionParameters<config>> & ScopeKeyParameter> &
QueryParameter<MyActionQueryFnData, MyActionErrorType, selectData, MyActionQueryKey<config>>
export function myActionQueryOptions<
config extends Config,
selectData = MyActionData,
>(
config: config,
options: MyActionOptions<config, selectData> = {},
): MyActionQueryOptions<config, selectData> {
return {
...options.query,
enabled: Boolean(options.requiredParam && (options.query?.enabled ?? true)),
queryFn: async (context) => {
const [, { scopeKey: _, ...parameters }] = context.queryKey
if (!parameters.requiredParam) throw new Error('requiredParam is required')
const result = await myAction(config, {
...(parameters as MyActionParameters),
requiredParam: parameters.requiredParam,
})
return result ?? null
},
queryKey: myActionQueryKey(options),
structuralSharing, // include when returning complex objects/arrays
}
}
export type MyActionQueryFnData = Compute<MyActionReturnType>
export type MyActionData = MyActionQueryFnData
export function myActionQueryKey<config extends Config>(
options: Compute<ExactPartial<MyActionParameters<config>> & ScopeKeyParameter> = {},
) {
return ['myAction', filterQueryOptions(options)] as const
}
export type MyActionQueryKey<config extends Config> = ReturnType<typeof myActionQueryKey<config>>
export type MyActionQueryOptions<
config extends Config,
selectData = MyActionData,
> = QueryOptions<MyActionQueryFnData, MyActionErrorType, selectData, MyActionQueryKey<config>>
Mutation Structure
import type { MutationOptions, MutationParameter } from '../types/query.js'
export type MyActionOptions<config extends Config, context = unknown> = MutationParameter<
MyActionData,
MyActionErrorType,
MyActionVariables<config>,
context
>
export function myActionMutationOptions<config extends Config, context>(
config: config,
options: MyActionOptions<config, context> = {},
): MyActionMutationOptions<config> {
return {
...options.mutation,
mutationFn: async (variables) => {
return myAction(config, variables)
},
mutationKey: ['myAction'],
}
}
export type MyActionMutationOptions<config extends Config> = MutationOptions<
MyActionData,
MyActionErrorType,
MyActionVariables<config>
>
Key Rules
- ExactPartial vs UnionExactPartial: Use
ExactPartialfor simple types,UnionExactPartialfor complex unions (contract actions) - enabled: Based on required params being truthy
- structuralSharing: Include when action returns objects/arrays
- filterQueryOptions: Filters common non-serializable props. Skip props like
onReplacedmanually in query key. - Query key: Always
['actionName', filterQueryOptions(options)]
Testing
import { config } from '@wagmi/test'
import { expect, test } from 'vitest'
import { myActionQueryOptions } from './myAction.js'
test('default', () => {
expect(myActionQueryOptions(config, {})).toMatchInlineSnapshot(`
{
"enabled": false,
"queryFn": [Function],
"queryKey": ["myAction", {}],
}
`)
})
test('enabled', () => {
expect(myActionQueryOptions(config, { requiredParam: 'value' }).enabled).toBe(true)
})
test('queryFn: calls query fn', async () => {
const options = myActionQueryOptions(config, { requiredParam: 'value' })
const result = await options.queryFn({ queryKey: options.queryKey } as any)
expect(result).toMatchInlineSnapshot(`...`)
})
3. Framework Bindings
React Query Hook
'use client'
import type { Config, MyActionErrorType, ResolvedRegister } from '@wagmi/core'
import type { Compute } from '@wagmi/core/internal'
import {
type MyActionData,
type MyActionOptions,
myActionQueryOptions,
} from '@wagmi/core/query'
import type { ConfigParameter } from '../types/properties.js'
import { type UseQueryReturnType, useQuery } from '../utils/query.js'
import { useChainId } from './useChainId.js'
import { useConfig } from './useConfig.js'
export type UseMyActionParameters<
config extends Config = Config,
selectData = MyActionData,
> = Compute<MyActionOptions<config, selectData> & ConfigParameter<config>>
export type UseMyActionReturnType<selectData = MyActionData> =
UseQueryReturnType<selectData, MyActionErrorType>
/** https://wagmi.sh/react/api/hooks/useMyAction */
export function useMyAction<
config extends Config = ResolvedRegister['config'],
selectData = MyActionData,
>(
parameters: UseMyActionParameters<config, selectData> = {},
): UseMyActionReturnType<selectData> {
const config = useConfig(parameters)
const chainId = useChainId({ config })
const options = myActionQueryOptions(config, {
...parameters,
chainId: parameters.chainId ?? chainId,
query: parameters.query,
})
return useQuery(options)
}
React Mutation Hook
'use client'
import { useMutation } from '@tanstack/react-query'
import type { Config, ResolvedRegister, MyActionErrorType } from '@wagmi/core'
import {
type MyActionData,
type MyActionMutate,
type MyActionMutateAsync,
type MyActionOptions,
type MyActionVariables,
myActionMutationOptions,
} from '@wagmi/core/query'
import type { ConfigParameter } from '../types/properties.js'
import type { UseMutationReturnType } from '../utils/query.js'
import { useConfig } from './useConfig.js'
export type UseMyActionParameters<config extends Config = Config, context = unknown> =
MyActionOptions<config, context> & ConfigParameter<config>
export type UseMyActionReturnType<config extends Con
---
*Content truncated.*
More by wevm
View all skills by wevm →You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
fastapi-templates
wshobson
Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.
Related MCP Servers
Browse all serversUnlock AI-ready web data with Firecrawl: scrape any website, handle dynamic content, and automate web scraping for resea
Supercharge your AI code assistant with JetBrains IDE Index. Unlock advanced code intelligence, navigation & refactoring
Generate stunning AI images with ImageGen, a unified AI image generator supporting DALL-E, Gemini & more, with smart par
AI Consultant (OpenRouter) delivers intelligent consultations, multi-model support, and reliable conversation management
Persistent AI memory server for contextual storage and artifacts - full-text search, version history, and automatic cont
Build persistent semantic networks for enterprise & engineering data management. Enable data persistence and memory acro
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.