Skip to content

Commit 06bb598

Browse files
marthendalnunestmm
andauthored
Feat: Add deployContract and useDeployContract (#3816)
* feat: add deployContract action * docs: add viem version badge to deployContract docs * chore: changeset * chore: import order * chore: bump viem to 2.9.25 * chore: tweaks --------- Co-authored-by: Tom Meagher <[email protected]>
1 parent fe08cad commit 06bb598

26 files changed

+1030
-1
lines changed

.changeset/gentle-dryers-cover.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"wagmi": minor
3+
---
4+
5+
Added `useDeployContract` hook.

.changeset/pretty-dogs-doubt.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@wagmi/core": minor
3+
---
4+
5+
Added `deployContract` action.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { abi, bytecode, config } from '@wagmi/test'
2+
import { http } from 'viem'
3+
import { celo, mainnet } from 'viem/chains'
4+
import { expectTypeOf, test } from 'vitest'
5+
6+
import { createConfig } from '../createConfig.js'
7+
import {
8+
type DeployContractParameters,
9+
deployContract,
10+
} from './deployContract.js'
11+
12+
test('default', async () => {
13+
await deployContract(config, {
14+
abi: abi.bayc,
15+
bytecode: bytecode.bayc,
16+
args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n],
17+
chainId: mainnet.id,
18+
})
19+
})
20+
21+
test('chain formatters', () => {
22+
const config = createConfig({
23+
chains: [mainnet, celo],
24+
transports: { [celo.id]: http(), [mainnet.id]: http() },
25+
})
26+
27+
type Result = DeployContractParameters<typeof abi.bayc, typeof config>
28+
expectTypeOf<Result>().toMatchTypeOf<{
29+
chainId?: typeof celo.id | typeof mainnet.id | undefined
30+
feeCurrency?: `0x${string}` | undefined
31+
gatewayFee?: bigint | undefined
32+
gatewayFeeRecipient?: `0x${string}` | undefined
33+
}>()
34+
deployContract(config, {
35+
abi: abi.bayc,
36+
bytecode: bytecode.bayc,
37+
args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n],
38+
feeCurrency: '0x',
39+
gatewayFee: 100n,
40+
gatewayFeeRecipient: '0x',
41+
})
42+
43+
type Result2 = DeployContractParameters<
44+
typeof abi.bayc,
45+
typeof config,
46+
typeof celo.id
47+
>
48+
expectTypeOf<Result2>().toMatchTypeOf<{
49+
feeCurrency?: `0x${string}` | undefined
50+
gatewayFee?: bigint | undefined
51+
gatewayFeeRecipient?: `0x${string}` | undefined
52+
}>()
53+
deployContract(config, {
54+
chainId: celo.id,
55+
abi: abi.bayc,
56+
bytecode: bytecode.bayc,
57+
args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n],
58+
feeCurrency: '0x',
59+
gatewayFee: 100n,
60+
gatewayFeeRecipient: '0x',
61+
})
62+
63+
type Result3 = DeployContractParameters<
64+
typeof abi.bayc,
65+
typeof config,
66+
typeof mainnet.id
67+
>
68+
expectTypeOf<Result3>().not.toMatchTypeOf<{
69+
feeCurrency?: `0x${string}` | undefined
70+
gatewayFee?: bigint | undefined
71+
gatewayFeeRecipient?: `0x${string}` | undefined
72+
}>()
73+
deployContract(config, {
74+
chainId: mainnet.id,
75+
abi: abi.bayc,
76+
bytecode: bytecode.bayc,
77+
args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n],
78+
// @ts-expect-error
79+
feeCurrency: '0x',
80+
gatewayFee: 100n,
81+
gatewayFeeRecipient: '0x',
82+
})
83+
})

packages/core/src/actions/deployContract.test.ts

+67
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import type { Abi, Account, Chain, Client, ContractConstructorArgs } from 'viem'
2+
import {
3+
type DeployContractErrorType as viem_DeployContractErrorType,
4+
type DeployContractParameters as viem_DeployContractParameters,
5+
type DeployContractReturnType as viem_DeployContractReturnType,
6+
deployContract as viem_deployContract,
7+
} from 'viem/actions'
8+
import type { Config } from '../createConfig.js'
9+
import type { BaseErrorType, ErrorType } from '../errors/base.js'
10+
import type { SelectChains } from '../types/chain.js'
11+
import type {
12+
ChainIdParameter,
13+
ConnectorParameter,
14+
} from '../types/properties.js'
15+
import type { Evaluate } from '../types/utils.js'
16+
import { getAction } from '../utils/getAction.js'
17+
import {
18+
type GetConnectorClientErrorType,
19+
getConnectorClient,
20+
} from './getConnectorClient.js'
21+
22+
export type DeployContractParameters<
23+
abi extends Abi | readonly unknown[] = Abi,
24+
config extends Config = Config,
25+
chainId extends
26+
config['chains'][number]['id'] = config['chains'][number]['id'],
27+
///
28+
allArgs = ContractConstructorArgs<abi>,
29+
chains extends readonly Chain[] = SelectChains<config, chainId>,
30+
> = {
31+
[key in keyof chains]: Evaluate<
32+
Omit<
33+
viem_DeployContractParameters<
34+
abi,
35+
chains[key],
36+
Account,
37+
chains[key],
38+
allArgs
39+
>,
40+
'chain'
41+
> &
42+
ChainIdParameter<config, chainId> &
43+
ConnectorParameter
44+
>
45+
}[number]
46+
47+
export type DeployContractReturnType = viem_DeployContractReturnType
48+
49+
export type DeployContractErrorType =
50+
// getConnectorClient()
51+
| GetConnectorClientErrorType
52+
// base
53+
| BaseErrorType
54+
| ErrorType
55+
// viem
56+
| viem_DeployContractErrorType
57+
58+
/** https://wagmi.sh/core/api/actions/deployContract */
59+
export async function deployContract<
60+
config extends Config,
61+
const abi extends Abi | readonly unknown[],
62+
chainId extends config['chains'][number]['id'],
63+
>(
64+
config: config,
65+
parameters: DeployContractParameters<abi, config, chainId>,
66+
): Promise<DeployContractReturnType> {
67+
const { account, chainId, connector, ...rest } = parameters
68+
69+
let client: Client
70+
if (typeof account === 'object' && account.type === 'local')
71+
client = config.getClient({ chainId })
72+
else
73+
client = await getConnectorClient(config, { account, chainId, connector })
74+
75+
const action = getAction(client, viem_deployContract, 'deployContract')
76+
const hash = await action({
77+
...(rest as any),
78+
...(account ? { account } : {}),
79+
chain: chainId ? { id: chainId } : null,
80+
})
81+
82+
return hash
83+
}

packages/core/src/exports/actions.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ test('exports', () => {
77
[
88
"call",
99
"connect",
10+
"deployContract",
1011
"disconnect",
1112
"estimateGas",
1213
"estimateFeesPerGas",

packages/core/src/exports/actions.ts

+7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ export {
1717
connect,
1818
} from '../actions/connect.js'
1919

20+
export {
21+
type DeployContractErrorType,
22+
type DeployContractParameters,
23+
type DeployContractReturnType,
24+
deployContract,
25+
} from '../actions/deployContract.js'
26+
2027
export {
2128
type DisconnectErrorType,
2229
type DisconnectParameters,

packages/core/src/exports/index.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ test('exports', () => {
77
[
88
"call",
99
"connect",
10+
"deployContract",
1011
"disconnect",
1112
"estimateGas",
1213
"estimateFeesPerGas",

packages/core/src/exports/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ export {
1717
connect,
1818
} from '../actions/connect.js'
1919

20+
export {
21+
type DeployContractErrorType,
22+
type DeployContractParameters,
23+
type DeployContractReturnType,
24+
deployContract,
25+
} from '../actions/deployContract.js'
26+
2027
export {
2128
type DisconnectErrorType,
2229
type DisconnectParameters,

packages/core/src/exports/query.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ test('exports', () => {
88
"callQueryKey",
99
"callQueryOptions",
1010
"connectMutationOptions",
11+
"deployContractMutationOptions",
1112
"disconnectMutationOptions",
1213
"estimateFeesPerGasQueryKey",
1314
"estimateFeesPerGasQueryOptions",

packages/core/src/exports/query.ts

+8
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ export {
2020
connectMutationOptions,
2121
} from '../query/connect.js'
2222

23+
export {
24+
type DeployContractData,
25+
type DeployContractVariables,
26+
type DeployContractMutate,
27+
type DeployContractMutateAsync,
28+
deployContractMutationOptions,
29+
} from '../query/deployContract.js'
30+
2331
export {
2432
type DisconnectData,
2533
type DisconnectVariables,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { config } from '@wagmi/test'
2+
import { expect, test } from 'vitest'
3+
4+
import { deployContractMutationOptions } from './deployContract.js'
5+
6+
test('default', () => {
7+
expect(deployContractMutationOptions(config)).toMatchInlineSnapshot(`
8+
{
9+
"mutationFn": [Function],
10+
"mutationKey": [
11+
"deployContract",
12+
],
13+
}
14+
`)
15+
})
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import type { MutateOptions, MutationOptions } from '@tanstack/query-core'
2+
import type { Abi, ContractConstructorArgs } from 'viem'
3+
4+
import {
5+
type DeployContractErrorType,
6+
type DeployContractParameters,
7+
type DeployContractReturnType,
8+
deployContract,
9+
} from '../actions/deployContract.js'
10+
import type { Config } from '../createConfig.js'
11+
import type { Evaluate } from '../types/utils.js'
12+
13+
export function deployContractMutationOptions<config extends Config>(
14+
config: config,
15+
) {
16+
return {
17+
mutationFn(variables) {
18+
return deployContract(config, variables)
19+
},
20+
mutationKey: ['deployContract'],
21+
} as const satisfies MutationOptions<
22+
DeployContractData,
23+
DeployContractErrorType,
24+
DeployContractVariables<Abi, config, config['chains'][number]['id']>
25+
>
26+
}
27+
28+
export type DeployContractData = Evaluate<DeployContractReturnType>
29+
30+
export type DeployContractVariables<
31+
abi extends Abi | readonly unknown[],
32+
config extends Config,
33+
chainId extends config['chains'][number]['id'],
34+
///
35+
allArgs = ContractConstructorArgs<abi>,
36+
> = DeployContractParameters<abi, config, chainId, allArgs>
37+
38+
export type DeployContractMutate<config extends Config, context = unknown> = <
39+
abi extends Abi | readonly unknown[],
40+
chainId extends config['chains'][number]['id'],
41+
>(
42+
variables: DeployContractVariables<abi, config, chainId>,
43+
options?:
44+
| Evaluate<
45+
MutateOptions<
46+
DeployContractData,
47+
DeployContractErrorType,
48+
Evaluate<DeployContractVariables<abi, config, chainId>>,
49+
context
50+
>
51+
>
52+
| undefined,
53+
) => void
54+
55+
export type DeployContractMutateAsync<
56+
config extends Config,
57+
context = unknown,
58+
> = <
59+
abi extends Abi | readonly unknown[],
60+
chainId extends config['chains'][number]['id'],
61+
>(
62+
variables: DeployContractVariables<abi, config, chainId>,
63+
options?:
64+
| Evaluate<
65+
MutateOptions<
66+
DeployContractData,
67+
DeployContractErrorType,
68+
Evaluate<DeployContractVariables<abi, config, chainId>>,
69+
context
70+
>
71+
>
72+
| undefined,
73+
) => Promise<DeployContractData>

packages/react/src/exports/actions.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ test('exports', () => {
77
[
88
"call",
99
"connect",
10+
"deployContract",
1011
"disconnect",
1112
"estimateGas",
1213
"estimateFeesPerGas",

packages/react/src/exports/index.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ test('exports', () => {
2727
"useConnections",
2828
"useConnectors",
2929
"useConnectorClient",
30+
"useDeployContract",
3031
"useDisconnect",
3132
"useEnsAddress",
3233
"useEnsAvatar",

packages/react/src/exports/index.ts

+6
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,12 @@ export {
123123
useConnectorClient,
124124
} from '../hooks/useConnectorClient.js'
125125

126+
export {
127+
type UseDeployContractParameters,
128+
type UseDeployContractReturnType,
129+
useDeployContract,
130+
} from '../hooks/useDeployContract.js'
131+
126132
export {
127133
type UseDisconnectParameters,
128134
type UseDisconnectReturnType,

packages/react/src/exports/query.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ test('exports', () => {
88
"callQueryKey",
99
"callQueryOptions",
1010
"connectMutationOptions",
11+
"deployContractMutationOptions",
1112
"disconnectMutationOptions",
1213
"estimateFeesPerGasQueryKey",
1314
"estimateFeesPerGasQueryOptions",

0 commit comments

Comments
 (0)