viem 2.21.58 → 2.21.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/_cjs/account-abstraction/actions/bundler/estimateUserOperationGas.js.map +1 -1
  3. package/_cjs/account-abstraction/actions/bundler/prepareUserOperation.js +1 -1
  4. package/_cjs/account-abstraction/actions/bundler/prepareUserOperation.js.map +1 -1
  5. package/_cjs/account-abstraction/actions/bundler/sendUserOperation.js.map +1 -1
  6. package/_cjs/account-abstraction/index.js.map +1 -1
  7. package/_cjs/account-abstraction/utils/errors/getUserOperationError.js.map +1 -1
  8. package/_cjs/errors/version.js +1 -1
  9. package/_cjs/experimental/erc7821/actions/execute.js +78 -0
  10. package/_cjs/experimental/erc7821/actions/execute.js.map +1 -0
  11. package/_cjs/experimental/erc7821/actions/supportsExecutionMode.js +21 -0
  12. package/_cjs/experimental/erc7821/actions/supportsExecutionMode.js.map +1 -0
  13. package/_cjs/experimental/erc7821/constants.js +65 -0
  14. package/_cjs/experimental/erc7821/constants.js.map +1 -0
  15. package/_cjs/experimental/erc7821/decorators/erc7821.js +14 -0
  16. package/_cjs/experimental/erc7821/decorators/erc7821.js.map +1 -0
  17. package/_cjs/experimental/erc7821/errors.js +26 -0
  18. package/_cjs/experimental/erc7821/errors.js.map +1 -0
  19. package/_cjs/experimental/erc7821/index.js +13 -0
  20. package/_cjs/experimental/erc7821/index.js.map +1 -0
  21. package/_cjs/experimental/index.js +3 -1
  22. package/_cjs/experimental/index.js.map +1 -1
  23. package/_cjs/types/calls.js +3 -0
  24. package/_cjs/types/calls.js.map +1 -0
  25. package/_cjs/zksync/actions/deployContract.js +3 -1
  26. package/_cjs/zksync/actions/deployContract.js.map +1 -1
  27. package/_cjs/zksync/actions/getL1TokenAddress.js +21 -0
  28. package/_cjs/zksync/actions/getL1TokenAddress.js.map +1 -0
  29. package/_cjs/zksync/actions/getL2TokenAddress.js +25 -0
  30. package/_cjs/zksync/actions/getL2TokenAddress.js.map +1 -0
  31. package/_cjs/zksync/actions/sendEip712Transaction.js +3 -3
  32. package/_cjs/zksync/actions/sendEip712Transaction.js.map +1 -1
  33. package/_cjs/zksync/actions/signEip712Transaction.js +2 -2
  34. package/_cjs/zksync/actions/signEip712Transaction.js.map +1 -1
  35. package/_cjs/zksync/constants/abis.js +185 -1
  36. package/_cjs/zksync/constants/abis.js.map +1 -1
  37. package/_cjs/zksync/constants/address.js +2 -1
  38. package/_cjs/zksync/constants/address.js.map +1 -1
  39. package/_cjs/zksync/decorators/publicL2.js +4 -0
  40. package/_cjs/zksync/decorators/publicL2.js.map +1 -1
  41. package/_cjs/zksync/index.js +5 -1
  42. package/_cjs/zksync/index.js.map +1 -1
  43. package/_esm/account-abstraction/actions/bundler/estimateUserOperationGas.js.map +1 -1
  44. package/_esm/account-abstraction/actions/bundler/prepareUserOperation.js +1 -1
  45. package/_esm/account-abstraction/actions/bundler/prepareUserOperation.js.map +1 -1
  46. package/_esm/account-abstraction/actions/bundler/sendUserOperation.js.map +1 -1
  47. package/_esm/account-abstraction/index.js.map +1 -1
  48. package/_esm/account-abstraction/utils/errors/getUserOperationError.js.map +1 -1
  49. package/_esm/errors/version.js +1 -1
  50. package/_esm/experimental/erc7821/actions/execute.js +143 -0
  51. package/_esm/experimental/erc7821/actions/execute.js.map +1 -0
  52. package/_esm/experimental/erc7821/actions/supportsExecutionMode.js +41 -0
  53. package/_esm/experimental/erc7821/actions/supportsExecutionMode.js.map +1 -0
  54. package/_esm/experimental/erc7821/constants.js +62 -0
  55. package/_esm/experimental/erc7821/constants.js.map +1 -0
  56. package/_esm/experimental/erc7821/decorators/erc7821.js +24 -0
  57. package/_esm/experimental/erc7821/decorators/erc7821.js.map +1 -0
  58. package/_esm/experimental/erc7821/errors.js +21 -0
  59. package/_esm/experimental/erc7821/errors.js.map +1 -0
  60. package/_esm/experimental/erc7821/index.js +7 -0
  61. package/_esm/experimental/erc7821/index.js.map +1 -0
  62. package/_esm/experimental/index.js +1 -0
  63. package/_esm/experimental/index.js.map +1 -1
  64. package/_esm/types/calls.js +2 -0
  65. package/_esm/types/calls.js.map +1 -0
  66. package/_esm/zksync/actions/deployContract.js +5 -3
  67. package/_esm/zksync/actions/deployContract.js.map +1 -1
  68. package/_esm/zksync/actions/getL1TokenAddress.js +40 -0
  69. package/_esm/zksync/actions/getL1TokenAddress.js.map +1 -0
  70. package/_esm/zksync/actions/getL2TokenAddress.js +45 -0
  71. package/_esm/zksync/actions/getL2TokenAddress.js.map +1 -0
  72. package/_esm/zksync/actions/sendEip712Transaction.js +3 -3
  73. package/_esm/zksync/actions/sendEip712Transaction.js.map +1 -1
  74. package/_esm/zksync/actions/signEip712Transaction.js +4 -2
  75. package/_esm/zksync/actions/signEip712Transaction.js.map +1 -1
  76. package/_esm/zksync/constants/abis.js +184 -0
  77. package/_esm/zksync/constants/abis.js.map +1 -1
  78. package/_esm/zksync/constants/address.js +1 -0
  79. package/_esm/zksync/constants/address.js.map +1 -1
  80. package/_esm/zksync/decorators/publicL2.js +4 -0
  81. package/_esm/zksync/decorators/publicL2.js.map +1 -1
  82. package/_esm/zksync/index.js +2 -0
  83. package/_esm/zksync/index.js.map +1 -1
  84. package/_types/account-abstraction/actions/bundler/estimateUserOperationGas.d.ts +3 -2
  85. package/_types/account-abstraction/actions/bundler/estimateUserOperationGas.d.ts.map +1 -1
  86. package/_types/account-abstraction/actions/bundler/prepareUserOperation.d.ts +3 -2
  87. package/_types/account-abstraction/actions/bundler/prepareUserOperation.d.ts.map +1 -1
  88. package/_types/account-abstraction/actions/bundler/sendUserOperation.d.ts +3 -2
  89. package/_types/account-abstraction/actions/bundler/sendUserOperation.d.ts.map +1 -1
  90. package/_types/account-abstraction/index.d.ts +1 -1
  91. package/_types/account-abstraction/index.d.ts.map +1 -1
  92. package/_types/account-abstraction/types/userOperation.d.ts +2 -30
  93. package/_types/account-abstraction/types/userOperation.d.ts.map +1 -1
  94. package/_types/account-abstraction/utils/errors/getUserOperationError.d.ts.map +1 -1
  95. package/_types/errors/version.d.ts +1 -1
  96. package/_types/experimental/erc7821/actions/execute.d.ts +94 -0
  97. package/_types/experimental/erc7821/actions/execute.d.ts.map +1 -0
  98. package/_types/experimental/erc7821/actions/supportsExecutionMode.d.ts +37 -0
  99. package/_types/experimental/erc7821/actions/supportsExecutionMode.d.ts.map +1 -0
  100. package/_types/experimental/erc7821/constants.d.ts +48 -0
  101. package/_types/experimental/erc7821/constants.d.ts.map +1 -0
  102. package/_types/experimental/erc7821/decorators/erc7821.d.ts +116 -0
  103. package/_types/experimental/erc7821/decorators/erc7821.d.ts.map +1 -0
  104. package/_types/experimental/erc7821/errors.d.ts +14 -0
  105. package/_types/experimental/erc7821/errors.d.ts.map +1 -0
  106. package/_types/experimental/erc7821/index.d.ts +6 -0
  107. package/_types/experimental/erc7821/index.d.ts.map +1 -0
  108. package/_types/experimental/index.d.ts +1 -0
  109. package/_types/experimental/index.d.ts.map +1 -1
  110. package/_types/types/calls.d.ts +14 -0
  111. package/_types/types/calls.d.ts.map +1 -0
  112. package/_types/zksync/actions/deployContract.d.ts +1 -1
  113. package/_types/zksync/actions/deployContract.d.ts.map +1 -1
  114. package/_types/zksync/actions/getL1TokenAddress.d.ts +34 -0
  115. package/_types/zksync/actions/getL1TokenAddress.d.ts.map +1 -0
  116. package/_types/zksync/actions/getL2TokenAddress.d.ts +37 -0
  117. package/_types/zksync/actions/getL2TokenAddress.d.ts.map +1 -0
  118. package/_types/zksync/actions/sendEip712Transaction.d.ts.map +1 -1
  119. package/_types/zksync/actions/signEip712Transaction.d.ts +2 -0
  120. package/_types/zksync/actions/signEip712Transaction.d.ts.map +1 -1
  121. package/_types/zksync/constants/abis.d.ts +143 -0
  122. package/_types/zksync/constants/abis.d.ts.map +1 -1
  123. package/_types/zksync/constants/address.d.ts +1 -0
  124. package/_types/zksync/constants/address.d.ts.map +1 -1
  125. package/_types/zksync/decorators/publicL2.d.ts +46 -0
  126. package/_types/zksync/decorators/publicL2.d.ts.map +1 -1
  127. package/_types/zksync/index.d.ts +2 -0
  128. package/_types/zksync/index.d.ts.map +1 -1
  129. package/account-abstraction/actions/bundler/estimateUserOperationGas.ts +2 -4
  130. package/account-abstraction/actions/bundler/prepareUserOperation.ts +6 -10
  131. package/account-abstraction/actions/bundler/sendUserOperation.ts +2 -4
  132. package/account-abstraction/index.ts +0 -2
  133. package/account-abstraction/types/userOperation.ts +2 -72
  134. package/account-abstraction/utils/errors/getUserOperationError.ts +10 -16
  135. package/errors/version.ts +1 -1
  136. package/experimental/erc7821/actions/execute.ts +232 -0
  137. package/experimental/erc7821/actions/supportsExecutionMode.ts +60 -0
  138. package/experimental/erc7821/constants.ts +62 -0
  139. package/experimental/erc7821/decorators/erc7821.ts +149 -0
  140. package/experimental/erc7821/errors.ts +29 -0
  141. package/experimental/erc7821/index.ts +23 -0
  142. package/experimental/index.ts +5 -0
  143. package/package.json +6 -1
  144. package/types/calls.ts +38 -0
  145. package/zksync/actions/deployContract.ts +9 -3
  146. package/zksync/actions/getL1TokenAddress.ts +59 -0
  147. package/zksync/actions/getL2TokenAddress.ts +70 -0
  148. package/zksync/actions/sendEip712Transaction.ts +5 -3
  149. package/zksync/actions/signEip712Transaction.ts +5 -2
  150. package/zksync/constants/abis.ts +185 -0
  151. package/zksync/constants/address.ts +3 -0
  152. package/zksync/decorators/publicL2.ts +62 -0
  153. package/zksync/index.ts +10 -0
@@ -1,10 +1,8 @@
1
- import type { AbiStateMutability, Address } from 'abitype'
2
- import type { ContractFunctionParameters } from '../../types/contract.js'
1
+ import type { Address } from 'abitype'
3
2
  import type { Log } from '../../types/log.js'
4
3
  import type { Hash, Hex } from '../../types/misc.js'
5
- import type { GetMulticallContractParameters } from '../../types/multicall.js'
6
4
  import type { TransactionReceipt } from '../../types/transaction.js'
7
- import type { OneOf, Prettify, UnionPartialBy } from '../../types/utils.js'
5
+ import type { OneOf, UnionPartialBy } from '../../types/utils.js'
8
6
  import type { EntryPointVersion } from './entryPointVersion.js'
9
7
 
10
8
  /** @link https://eips.ethereum.org/EIPS/eip-4337#-eth_estimateuseroperationgas */
@@ -192,71 +190,3 @@ export type UserOperationReceipt<
192
190
  /** Hash of the user operation. */
193
191
  userOpHash: Hash
194
192
  }
195
-
196
- export type UserOperationCall = {
197
- to: Hex
198
- data?: Hex | undefined
199
- value?: bigint | undefined
200
- }
201
-
202
- export type UserOperationCalls<
203
- calls extends readonly unknown[],
204
- ///
205
- result extends readonly any[] = [],
206
- > = calls extends readonly [] // no calls, return empty
207
- ? readonly []
208
- : calls extends readonly [infer call] // one call left before returning `result`
209
- ? readonly [
210
- ...result,
211
- Prettify<
212
- OneOf<
213
- | (Omit<
214
- GetMulticallContractParameters<call, AbiStateMutability>,
215
- 'address'
216
- > & {
217
- to: Address
218
- value?: bigint | undefined
219
- })
220
- | UserOperationCall
221
- >
222
- >,
223
- ]
224
- : calls extends readonly [infer call, ...infer rest] // grab first call and recurse through `rest`
225
- ? UserOperationCalls<
226
- [...rest],
227
- [
228
- ...result,
229
- Prettify<
230
- OneOf<
231
- | (Omit<
232
- GetMulticallContractParameters<call, AbiStateMutability>,
233
- 'address'
234
- > & {
235
- to: Address
236
- value?: bigint | undefined
237
- })
238
- | UserOperationCall
239
- >
240
- >,
241
- ]
242
- >
243
- : readonly unknown[] extends calls
244
- ? calls
245
- : // If `calls` is *some* array but we couldn't assign `unknown[]` to it, then it must hold some known/homogenous type!
246
- // use this to infer the param types in the case of Array.map() argument
247
- calls extends readonly (infer call extends OneOf<
248
- | (Omit<ContractFunctionParameters, 'address'> & {
249
- to: Address
250
- value?: bigint | undefined
251
- })
252
- | UserOperationCall
253
- >)[]
254
- ? readonly Prettify<call>[]
255
- : // Fallback
256
- readonly OneOf<
257
- | (Omit<ContractFunctionParameters, 'address'> & {
258
- to: Address
259
- value?: bigint | undefined
260
- })
261
- | UserOperationCall
262
- >[]
@@ -1,4 +1,4 @@
1
- import type { Address } from 'abitype'
1
+ import type { Abi, Address } from 'abitype'
2
2
  import { BaseError } from '../../../errors/base.js'
3
3
  import {
4
4
  ContractFunctionExecutionError,
@@ -6,9 +6,8 @@ import {
6
6
  ContractFunctionZeroDataError,
7
7
  } from '../../../errors/contract.js'
8
8
  import type { ErrorType } from '../../../errors/utils.js'
9
- import type { ContractFunctionParameters } from '../../../types/contract.js'
9
+ import type { Call } from '../../../types/calls.js'
10
10
  import type { Hex } from '../../../types/misc.js'
11
- import type { OneOf } from '../../../types/utils.js'
12
11
  import { decodeErrorResult } from '../../../utils/abi/decodeErrorResult.js'
13
12
  import type { GetContractErrorReturnType } from '../../../utils/errors/getContractError.js'
14
13
  import { ExecutionRevertedError } from '../../errors/bundler.js'
@@ -16,22 +15,12 @@ import {
16
15
  UserOperationExecutionError,
17
16
  type UserOperationExecutionErrorType,
18
17
  } from '../../errors/userOperation.js'
19
- import type {
20
- UserOperation,
21
- UserOperationCall,
22
- } from '../../types/userOperation.js'
18
+ import type { UserOperation } from '../../types/userOperation.js'
23
19
  import {
24
20
  type GetBundlerErrorParameters,
25
21
  getBundlerError,
26
22
  } from './getBundlerError.js'
27
23
 
28
- type Call = OneOf<
29
- | UserOperationCall
30
- | (ContractFunctionParameters & {
31
- to: Address
32
- })
33
- >
34
-
35
24
  type GetNodeErrorReturnType = ErrorType
36
25
 
37
26
  export type GetUserOperationErrorParameters = UserOperation & {
@@ -106,7 +95,7 @@ function getContractError(parameters: {
106
95
  const { abi, functionName, args, to } = (() => {
107
96
  const contractCalls = calls?.filter((call) =>
108
97
  Boolean(call.abi),
109
- ) as readonly (ContractFunctionParameters & { to: Address })[]
98
+ ) as readonly Call[]
110
99
 
111
100
  if (contractCalls.length === 1) return contractCalls[0]
112
101
 
@@ -133,7 +122,12 @@ function getContractError(parameters: {
133
122
  args: undefined,
134
123
  to: undefined,
135
124
  }
136
- })()
125
+ })() as {
126
+ abi: Abi
127
+ functionName: string
128
+ args: unknown[]
129
+ to: Address
130
+ }
137
131
 
138
132
  const cause = (() => {
139
133
  if (revertData === '0x')
package/errors/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '2.21.58'
1
+ export const version = '2.21.59'
@@ -0,0 +1,232 @@
1
+ import type { Abi, Address, Narrow } from 'abitype'
2
+ import * as AbiError from 'ox/AbiError'
3
+ import * as AbiParameters from 'ox/AbiParameters'
4
+
5
+ import {
6
+ type SendTransactionErrorType,
7
+ sendTransaction,
8
+ } from '../../../actions/wallet/sendTransaction.js'
9
+ import type { Client } from '../../../clients/createClient.js'
10
+ import type { Transport } from '../../../clients/transports/createTransport.js'
11
+ import type { BaseError } from '../../../errors/base.js'
12
+ import type { ErrorType } from '../../../errors/utils.js'
13
+ import type { Account, GetAccountParameter } from '../../../types/account.js'
14
+ import type { Call, Calls } from '../../../types/calls.js'
15
+ import type {
16
+ Chain,
17
+ DeriveChain,
18
+ GetChainParameter,
19
+ } from '../../../types/chain.js'
20
+ import type { Hex } from '../../../types/misc.js'
21
+ import type { UnionEvaluate, UnionPick } from '../../../types/utils.js'
22
+ import {
23
+ type DecodeErrorResultErrorType,
24
+ decodeErrorResult,
25
+ } from '../../../utils/abi/decodeErrorResult.js'
26
+ import {
27
+ type EncodeFunctionDataErrorType,
28
+ encodeFunctionData,
29
+ } from '../../../utils/abi/encodeFunctionData.js'
30
+ import {
31
+ type GetContractErrorReturnType,
32
+ getContractError,
33
+ } from '../../../utils/errors/getContractError.js'
34
+ import type { FormattedTransactionRequest } from '../../../utils/formatters/transactionRequest.js'
35
+ import { abi, executionMode } from '../constants.js'
36
+ import {
37
+ ExecuteUnsupportedError,
38
+ FunctionSelectorNotRecognizedError,
39
+ } from '../errors.js'
40
+ import { supportsExecutionMode } from './supportsExecutionMode.js'
41
+
42
+ export type ExecuteParameters<
43
+ chain extends Chain | undefined = Chain | undefined,
44
+ account extends Account | undefined = Account | undefined,
45
+ chainOverride extends Chain | undefined = Chain | undefined,
46
+ calls extends readonly unknown[] = readonly unknown[],
47
+ _derivedChain extends Chain | undefined = DeriveChain<chain, chainOverride>,
48
+ > = UnionEvaluate<
49
+ UnionPick<
50
+ FormattedTransactionRequest<_derivedChain>,
51
+ | 'authorizationList'
52
+ | 'gas'
53
+ | 'gasPrice'
54
+ | 'maxFeePerGas'
55
+ | 'maxPriorityFeePerGas'
56
+ >
57
+ > &
58
+ GetAccountParameter<account, Account | Address, true, true> &
59
+ GetChainParameter<chain, chainOverride> & {
60
+ /** Address that will execute the calls. */
61
+ address: Address
62
+ /** Calls to execute. */
63
+ calls: Calls<Narrow<calls>>
64
+ /** Additional data to include for execution. */
65
+ opData?: Hex | undefined
66
+ }
67
+
68
+ export type ExecuteReturnType = Hex
69
+
70
+ export type ExecuteErrorType =
71
+ | DecodeErrorResultErrorType
72
+ | GetContractErrorReturnType
73
+ | EncodeFunctionDataErrorType
74
+ | SendTransactionErrorType
75
+ | ErrorType
76
+
77
+ /**
78
+ * Executes call(s) using the `execute` function on an [ERC-7821-compatible contract](https://eips.ethereum.org/EIPS/eip-7821).
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * import { createClient, http } from 'viem'
83
+ * import { privateKeyToAccount } from 'viem/accounts'
84
+ * import { mainnet } from 'viem/chains'
85
+ * import { execute } from 'viem/experimental/erc7821'
86
+ *
87
+ * const account = privateKeyToAccount('0x...')
88
+ *
89
+ * const client = createClient({
90
+ * chain: mainnet,
91
+ * transport: http(),
92
+ * })
93
+ *
94
+ * const hash = await execute(client, {
95
+ * account,
96
+ * calls: [{
97
+ * {
98
+ * data: '0xdeadbeef',
99
+ * to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
100
+ * },
101
+ * {
102
+ * to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
103
+ * value: 69420n,
104
+ * },
105
+ * }],
106
+ * to: account.address,
107
+ * })
108
+ * ```
109
+ *
110
+ * @example
111
+ * ```ts
112
+ * // Account Hoisting
113
+ * import { createClient, http } from 'viem'
114
+ * import { privateKeyToAccount } from 'viem/accounts'
115
+ * import { mainnet } from 'viem/chains'
116
+ * import { execute } from 'viem/experimental/erc7821'
117
+ *
118
+ * const account = privateKeyToAccount('0x...')
119
+ *
120
+ * const client = createClient({
121
+ * account,
122
+ * chain: mainnet,
123
+ * transport: http(),
124
+ * })
125
+ *
126
+ * const hash = await execute(client, {
127
+ * calls: [{
128
+ * {
129
+ * data: '0xdeadbeef',
130
+ * to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
131
+ * },
132
+ * {
133
+ * to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
134
+ * value: 69420n,
135
+ * },
136
+ * }],
137
+ * to: account.address,
138
+ * })
139
+ * ```
140
+ *
141
+ * @param client - Client to use.
142
+ * @param parameters - {@link ExecuteParameters}
143
+ * @returns Transaction hash. {@link ExecuteReturnType}
144
+ */
145
+ export async function execute<
146
+ const calls extends readonly unknown[],
147
+ chain extends Chain | undefined,
148
+ account extends Account | undefined,
149
+ chainOverride extends Chain | undefined = undefined,
150
+ >(
151
+ client: Client<Transport, chain, account>,
152
+ parameters: ExecuteParameters<chain, account, chainOverride, calls>,
153
+ ): Promise<ExecuteReturnType> {
154
+ const { address, authorizationList, opData } = parameters
155
+
156
+ const calls = parameters.calls.map((call_) => {
157
+ const call = call_ as Call
158
+ return {
159
+ data: call.abi ? encodeFunctionData(call) : (call.data ?? '0x'),
160
+ value: call.value ?? 0n,
161
+ target: call.to,
162
+ }
163
+ })
164
+ const mode = opData ? executionMode.opData : executionMode.default
165
+
166
+ const encodedCalls = AbiParameters.encode(
167
+ AbiParameters.from([
168
+ 'struct Call { address target; uint256 value; bytes data; }',
169
+ 'Call[] calls',
170
+ ...(opData ? ['bytes opData'] : []),
171
+ ]),
172
+ [calls, ...(opData ? [opData] : [])] as any,
173
+ )
174
+
175
+ const supported = await supportsExecutionMode(client, {
176
+ address: authorizationList?.[0]?.contractAddress ?? address,
177
+ opData,
178
+ })
179
+ if (!supported) throw new ExecuteUnsupportedError()
180
+
181
+ try {
182
+ return await sendTransaction(client, {
183
+ ...parameters,
184
+ to: address,
185
+ data: encodeFunctionData({
186
+ abi,
187
+ functionName: 'execute',
188
+ args: [mode, encodedCalls],
189
+ }),
190
+ } as any)
191
+ } catch (e) {
192
+ const error = (e as BaseError).walk((e) => 'data' in (e as Error)) as
193
+ | (BaseError & { data?: Hex | undefined })
194
+ | undefined
195
+
196
+ if (!error?.data) throw e
197
+ if (
198
+ error.data ===
199
+ AbiError.getSelector(AbiError.from('error FnSelectorNotRecognized()'))
200
+ )
201
+ throw new FunctionSelectorNotRecognizedError()
202
+
203
+ const matched = parameters.calls.find((call_) => {
204
+ const call = call_ as Call
205
+ if (!call.abi) return false
206
+ try {
207
+ return Boolean(
208
+ decodeErrorResult({
209
+ abi: call.abi,
210
+ data: error.data!,
211
+ }),
212
+ )
213
+ } catch {
214
+ return false
215
+ }
216
+ }) as {
217
+ abi: Abi
218
+ functionName: string
219
+ args: unknown[]
220
+ to: Address
221
+ } | null
222
+ if (!matched) throw e
223
+
224
+ throw getContractError(error as BaseError, {
225
+ abi: matched.abi,
226
+ address: matched.to,
227
+ args: matched.args,
228
+ docsPath: '/experimental/erc7821/execute',
229
+ functionName: matched.functionName,
230
+ })
231
+ }
232
+ }
@@ -0,0 +1,60 @@
1
+ import type { Address } from '../../../accounts/index.js'
2
+ import { readContract } from '../../../actions/public/readContract.js'
3
+ import type { Client } from '../../../clients/createClient.js'
4
+ import type { Transport } from '../../../clients/transports/createTransport.js'
5
+ import type { ErrorType } from '../../../errors/utils.js'
6
+ import type { Chain } from '../../../types/chain.js'
7
+ import type { Hex } from '../../../types/misc.js'
8
+ import { abi, executionMode } from '../constants.js'
9
+
10
+ export type SupportsExecutionModeParameters = {
11
+ address: Address
12
+ opData?: Hex | undefined
13
+ }
14
+
15
+ export type SupportsExecutionModeReturnType = boolean
16
+
17
+ export type SupportsExecutionModeErrorType = ErrorType
18
+
19
+ /**
20
+ * Checks if the contract supports the ERC-7821 execution mode.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * import { createClient, http } from 'viem'
25
+ * import { mainnet } from 'viem/chains'
26
+ * import { supportsExecutionMode } from 'viem/experimental/erc7821'
27
+ *
28
+ * const client = createClient({
29
+ * chain: mainnet,
30
+ * transport: http(),
31
+ * })
32
+ *
33
+ * const supported = await supportsExecutionMode(client, {
34
+ * to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
35
+ * })
36
+ * ```
37
+ *
38
+ * @param client - Client to use.
39
+ * @param parameters - {@link SupportsExecutionModeParameters}
40
+ * @returns If the execution mode is supported. {@link SupportsExecutionModeReturnType}
41
+ */
42
+ export async function supportsExecutionMode<
43
+ chain extends Chain | undefined = Chain | undefined,
44
+ >(
45
+ client: Client<Transport, chain>,
46
+ parameters: SupportsExecutionModeParameters,
47
+ ): Promise<SupportsExecutionModeReturnType> {
48
+ const { address, opData } = parameters
49
+ const mode = opData ? executionMode.opData : executionMode.default
50
+ try {
51
+ return await readContract(client, {
52
+ abi,
53
+ address,
54
+ functionName: 'supportsExecutionMode',
55
+ args: [mode],
56
+ })
57
+ } catch {
58
+ return false
59
+ }
60
+ }
@@ -0,0 +1,62 @@
1
+ export const abi = [
2
+ {
3
+ type: 'fallback',
4
+ stateMutability: 'payable',
5
+ },
6
+ {
7
+ type: 'receive',
8
+ stateMutability: 'payable',
9
+ },
10
+ {
11
+ type: 'function',
12
+ name: 'execute',
13
+ inputs: [
14
+ {
15
+ name: 'mode',
16
+ type: 'bytes32',
17
+ internalType: 'bytes32',
18
+ },
19
+ {
20
+ name: 'executionData',
21
+ type: 'bytes',
22
+ internalType: 'bytes',
23
+ },
24
+ ],
25
+ outputs: [],
26
+ stateMutability: 'payable',
27
+ },
28
+ {
29
+ type: 'function',
30
+ name: 'supportsExecutionMode',
31
+ inputs: [
32
+ {
33
+ name: 'mode',
34
+ type: 'bytes32',
35
+ internalType: 'bytes32',
36
+ },
37
+ ],
38
+ outputs: [
39
+ {
40
+ name: 'result',
41
+ type: 'bool',
42
+ internalType: 'bool',
43
+ },
44
+ ],
45
+ stateMutability: 'view',
46
+ },
47
+ {
48
+ type: 'error',
49
+ name: 'FnSelectorNotRecognized',
50
+ inputs: [],
51
+ },
52
+ {
53
+ type: 'error',
54
+ name: 'UnsupportedExecutionMode',
55
+ inputs: [],
56
+ },
57
+ ] as const
58
+
59
+ export const executionMode = {
60
+ default: '0x0100000000000000000000000000000000000000000000000000000000000000',
61
+ opData: '0x0100000000007821000100000000000000000000000000000000000000000000',
62
+ } as const
@@ -0,0 +1,149 @@
1
+ import type { Client } from '../../../clients/createClient.js'
2
+ import type { Transport } from '../../../clients/transports/createTransport.js'
3
+ import type { Account } from '../../../types/account.js'
4
+ import type { Chain } from '../../../types/chain.js'
5
+ import {
6
+ type ExecuteParameters,
7
+ type ExecuteReturnType,
8
+ execute,
9
+ } from '../actions/execute.js'
10
+ import {
11
+ type SupportsExecutionModeParameters,
12
+ type SupportsExecutionModeReturnType,
13
+ supportsExecutionMode,
14
+ } from '../actions/supportsExecutionMode.js'
15
+
16
+ export type Erc7821Actions<
17
+ chain extends Chain | undefined = Chain | undefined,
18
+ account extends Account | undefined = Account | undefined,
19
+ > = {
20
+ /**
21
+ * Executes call(s) using the `execute` function on an [ERC-7821-compatible contract](https://eips.ethereum.org/EIPS/eip-7821).
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * import { createClient, http } from 'viem'
26
+ * import { privateKeyToAccount } from 'viem/accounts'
27
+ * import { mainnet } from 'viem/chains'
28
+ * import { erc7821Actions } from 'viem/experimental'
29
+ *
30
+ * const account = privateKeyToAccount('0x...')
31
+ *
32
+ * const client = createClient({
33
+ * chain: mainnet,
34
+ * transport: http(),
35
+ * }).extend(erc7821Actions())
36
+ *
37
+ * const hash = await client.execute({
38
+ * account,
39
+ * calls: [{
40
+ * {
41
+ * data: '0xdeadbeef',
42
+ * to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
43
+ * },
44
+ * {
45
+ * to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
46
+ * value: 69420n,
47
+ * },
48
+ * }],
49
+ * to: account.address,
50
+ * })
51
+ * ```
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * // Account Hoisting
56
+ * import { createClient, http } from 'viem'
57
+ * import { privateKeyToAccount } from 'viem/accounts'
58
+ * import { mainnet } from 'viem/chains'
59
+ * import { erc7821Actions } from 'viem/experimental'
60
+ *
61
+ * const account = privateKeyToAccount('0x...')
62
+ *
63
+ * const client = createClient({
64
+ * account,
65
+ * chain: mainnet,
66
+ * transport: http(),
67
+ * }).extend(erc7821Actions())
68
+ *
69
+ * const hash = await client.execute({
70
+ * calls: [{
71
+ * {
72
+ * data: '0xdeadbeef',
73
+ * to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
74
+ * },
75
+ * {
76
+ * to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
77
+ * value: 69420n,
78
+ * },
79
+ * }],
80
+ * to: account.address,
81
+ * })
82
+ * ```
83
+ *
84
+ * @param client - Client to use.
85
+ * @param parameters - {@link ExecuteParameters}
86
+ * @returns Transaction hash. {@link ExecuteReturnType}
87
+ */
88
+ execute: <
89
+ const calls extends readonly unknown[],
90
+ chainOverride extends Chain | undefined = undefined,
91
+ >(
92
+ parameters: ExecuteParameters<chain, account, chainOverride, calls>,
93
+ ) => Promise<ExecuteReturnType>
94
+ /**
95
+ * Checks if the contract supports the ERC-7821 execution mode.
96
+ *
97
+ * @example
98
+ * ```ts
99
+ * import { createClient, http } from 'viem'
100
+ * import { mainnet } from 'viem/chains'
101
+ * import { erc7821Actions } from 'viem/experimental'
102
+ *
103
+ * const client = createClient({
104
+ * chain: mainnet,
105
+ * transport: http(),
106
+ * }).extend(erc7821Actions())
107
+ *
108
+ * const supported = await supportsExecutionMode(client, {
109
+ * to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
110
+ * })
111
+ * ```
112
+ *
113
+ * @param client - Client to use.
114
+ * @param parameters - {@link SupportsExecutionModeParameters}
115
+ * @returns If the execution mode is supported. {@link SupportsExecutionModeReturnType}
116
+ */
117
+ supportsExecutionMode: (
118
+ parameters: SupportsExecutionModeParameters,
119
+ ) => Promise<SupportsExecutionModeReturnType>
120
+ }
121
+
122
+ /**
123
+ * A suite of Actions for [ERC-7821](https://eips.ethereum.org/EIPS/eip-7821).
124
+ *
125
+ * @example
126
+ * import { createClient, http } from 'viem'
127
+ * import { mainnet } from 'viem/chains'
128
+ * import { erc7821Actions } from 'viem/experimental'
129
+ *
130
+ * const client = createClient({
131
+ * chain: mainnet,
132
+ * transport: http(),
133
+ * }).extend(erc7821Actions())
134
+ */
135
+ export function erc7821Actions() {
136
+ return <
137
+ transport extends Transport,
138
+ chain extends Chain | undefined = Chain | undefined,
139
+ account extends Account | undefined = Account | undefined,
140
+ >(
141
+ client: Client<transport, chain, account>,
142
+ ): Erc7821Actions<chain, account> => {
143
+ return {
144
+ execute: (parameters) => execute(client, parameters),
145
+ supportsExecutionMode: (parameters) =>
146
+ supportsExecutionMode(client, parameters),
147
+ }
148
+ }
149
+ }
@@ -0,0 +1,29 @@
1
+ import { BaseError } from '../../errors/base.js'
2
+
3
+ export type ExecuteUnsupportedErrorType = ExecuteUnsupportedError & {
4
+ name: 'ExecuteUnsupportedError'
5
+ }
6
+ export class ExecuteUnsupportedError extends BaseError {
7
+ constructor() {
8
+ super('ERC-7821 execution is not supported.', {
9
+ name: 'ExecuteUnsupportedError',
10
+ })
11
+ }
12
+ }
13
+
14
+ export type FunctionSelectorNotRecognizedErrorType =
15
+ FunctionSelectorNotRecognizedError & {
16
+ name: 'FunctionSelectorNotRecognizedError'
17
+ }
18
+ export class FunctionSelectorNotRecognizedError extends BaseError {
19
+ constructor() {
20
+ super('Function is not recognized.', {
21
+ metaMessages: [
22
+ 'This could be due to any of the following:',
23
+ ' - The contract does not have the function,',
24
+ ' - The address is not a contract.',
25
+ ],
26
+ name: 'FunctionSelectorNotRecognizedError',
27
+ })
28
+ }
29
+ }