viem 2.37.12 → 2.38.0
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.
- package/CHANGELOG.md +20 -0
- package/_cjs/actions/index.js +10 -2
- package/_cjs/actions/index.js.map +1 -1
- package/_cjs/actions/wallet/sendCallsSync.js +17 -0
- package/_cjs/actions/wallet/sendCallsSync.js.map +1 -0
- package/_cjs/actions/wallet/sendRawTransactionSync.js +17 -0
- package/_cjs/actions/wallet/sendRawTransactionSync.js.map +1 -0
- package/_cjs/actions/wallet/sendTransactionSync.js +172 -0
- package/_cjs/actions/wallet/sendTransactionSync.js.map +1 -0
- package/_cjs/actions/wallet/writeContract.js +31 -25
- package/_cjs/actions/wallet/writeContract.js.map +1 -1
- package/_cjs/actions/wallet/writeContractSync.js +9 -0
- package/_cjs/actions/wallet/writeContractSync.js.map +1 -0
- package/_cjs/chains/definitions/domaTestnet.js +24 -0
- package/_cjs/chains/definitions/domaTestnet.js.map +1 -0
- package/_cjs/chains/definitions/nitrographTestnet.js +26 -0
- package/_cjs/chains/definitions/nitrographTestnet.js.map +1 -0
- package/_cjs/chains/definitions/tronNile.js +22 -0
- package/_cjs/chains/definitions/tronNile.js.map +1 -0
- package/_cjs/chains/index.js +17 -11
- package/_cjs/chains/index.js.map +1 -1
- package/_cjs/clients/decorators/public.js +2 -0
- package/_cjs/clients/decorators/public.js.map +1 -1
- package/_cjs/clients/decorators/wallet.js +8 -0
- package/_cjs/clients/decorators/wallet.js.map +1 -1
- package/_cjs/errors/version.js +1 -1
- package/_cjs/errors/version.js.map +1 -1
- package/_cjs/index.js.map +1 -1
- package/_esm/actions/index.js +4 -0
- package/_esm/actions/index.js.map +1 -1
- package/_esm/actions/wallet/sendCallsSync.js +46 -0
- package/_esm/actions/wallet/sendCallsSync.js.map +1 -0
- package/_esm/actions/wallet/sendRawTransactionSync.js +39 -0
- package/_esm/actions/wallet/sendRawTransactionSync.js.map +1 -0
- package/_esm/actions/wallet/sendTransactionSync.js +218 -0
- package/_esm/actions/wallet/sendTransactionSync.js.map +1 -0
- package/_esm/actions/wallet/writeContract.js +31 -25
- package/_esm/actions/wallet/writeContract.js.map +1 -1
- package/_esm/actions/wallet/writeContractSync.js +38 -0
- package/_esm/actions/wallet/writeContractSync.js.map +1 -0
- package/_esm/chains/definitions/domaTestnet.js +21 -0
- package/_esm/chains/definitions/domaTestnet.js.map +1 -0
- package/_esm/chains/definitions/nitrographTestnet.js +23 -0
- package/_esm/chains/definitions/nitrographTestnet.js.map +1 -0
- package/_esm/chains/definitions/tronNile.js +19 -0
- package/_esm/chains/definitions/tronNile.js.map +1 -0
- package/_esm/chains/index.js +4 -0
- package/_esm/chains/index.js.map +1 -1
- package/_esm/clients/decorators/public.js +2 -0
- package/_esm/clients/decorators/public.js.map +1 -1
- package/_esm/clients/decorators/wallet.js +8 -0
- package/_esm/clients/decorators/wallet.js.map +1 -1
- package/_esm/errors/version.js +1 -1
- package/_esm/errors/version.js.map +1 -1
- package/_esm/index.js.map +1 -1
- package/_types/accounts/types.d.ts +3 -4
- package/_types/accounts/types.d.ts.map +1 -1
- package/_types/actions/index.d.ts +4 -0
- package/_types/actions/index.d.ts.map +1 -1
- package/_types/actions/wallet/sendCallsSync.d.ts +47 -0
- package/_types/actions/wallet/sendCallsSync.d.ts.map +1 -0
- package/_types/actions/wallet/sendRawTransactionSync.d.ts +42 -0
- package/_types/actions/wallet/sendRawTransactionSync.d.ts.map +1 -0
- package/_types/actions/wallet/sendTransactionSync.d.ts +73 -0
- package/_types/actions/wallet/sendTransactionSync.d.ts.map +1 -0
- package/_types/actions/wallet/writeContract.d.ts +5 -1
- package/_types/actions/wallet/writeContract.d.ts.map +1 -1
- package/_types/actions/wallet/writeContractSync.d.ts +45 -0
- package/_types/actions/wallet/writeContractSync.d.ts.map +1 -0
- package/_types/chains/definitions/domaTestnet.d.ts +39 -0
- package/_types/chains/definitions/domaTestnet.d.ts.map +1 -0
- package/_types/chains/definitions/nitrographTestnet.d.ts +39 -0
- package/_types/chains/definitions/nitrographTestnet.d.ts.map +1 -0
- package/_types/chains/definitions/tronNile.d.ts +39 -0
- package/_types/chains/definitions/tronNile.d.ts.map +1 -0
- package/_types/chains/index.d.ts +4 -0
- package/_types/chains/index.d.ts.map +1 -1
- package/_types/clients/decorators/public.d.ts +26 -0
- package/_types/clients/decorators/public.d.ts.map +1 -1
- package/_types/clients/decorators/wallet.d.ts +138 -0
- package/_types/clients/decorators/wallet.d.ts.map +1 -1
- package/_types/errors/version.d.ts +1 -1
- package/_types/errors/version.d.ts.map +1 -1
- package/_types/index.d.ts +4 -0
- package/_types/index.d.ts.map +1 -1
- package/_types/types/eip1193.d.ts +24 -0
- package/_types/types/eip1193.d.ts.map +1 -1
- package/accounts/types.ts +3 -14
- package/actions/index.ts +24 -0
- package/actions/wallet/sendCallsSync.ts +85 -0
- package/actions/wallet/sendRawTransactionSync.ts +68 -0
- package/actions/wallet/sendTransactionSync.ts +390 -0
- package/actions/wallet/writeContract.ts +71 -36
- package/actions/wallet/writeContractSync.ts +108 -0
- package/chains/definitions/domaTestnet.ts +21 -0
- package/chains/definitions/nitrographTestnet.ts +23 -0
- package/chains/definitions/tronNile.ts +19 -0
- package/chains/index.ts +4 -0
- package/clients/decorators/public.ts +33 -0
- package/clients/decorators/wallet.ts +189 -0
- package/errors/version.ts +1 -1
- package/index.ts +21 -0
- package/package.json +1 -1
- package/types/eip1193.ts +28 -0
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
import type { Address } from 'abitype'
|
|
2
|
+
|
|
3
|
+
import type { Account } from '../../accounts/types.js'
|
|
4
|
+
import {
|
|
5
|
+
type ParseAccountErrorType,
|
|
6
|
+
parseAccount,
|
|
7
|
+
} from '../../accounts/utils/parseAccount.js'
|
|
8
|
+
import type { SignTransactionErrorType } from '../../accounts/utils/signTransaction.js'
|
|
9
|
+
import type { Client } from '../../clients/createClient.js'
|
|
10
|
+
import type { Transport } from '../../clients/transports/createTransport.js'
|
|
11
|
+
import {
|
|
12
|
+
AccountNotFoundError,
|
|
13
|
+
type AccountNotFoundErrorType,
|
|
14
|
+
AccountTypeNotSupportedError,
|
|
15
|
+
type AccountTypeNotSupportedErrorType,
|
|
16
|
+
} from '../../errors/account.js'
|
|
17
|
+
import { BaseError } from '../../errors/base.js'
|
|
18
|
+
import type { ErrorType } from '../../errors/utils.js'
|
|
19
|
+
import type { GetAccountParameter } from '../../types/account.js'
|
|
20
|
+
import type {
|
|
21
|
+
Chain,
|
|
22
|
+
DeriveChain,
|
|
23
|
+
GetChainParameter,
|
|
24
|
+
} from '../../types/chain.js'
|
|
25
|
+
import type { GetTransactionRequestKzgParameter } from '../../types/kzg.js'
|
|
26
|
+
import type { Hash } from '../../types/misc.js'
|
|
27
|
+
import type { TransactionRequest } from '../../types/transaction.js'
|
|
28
|
+
import type { UnionOmit } from '../../types/utils.js'
|
|
29
|
+
import {
|
|
30
|
+
type RecoverAuthorizationAddressErrorType,
|
|
31
|
+
recoverAuthorizationAddress,
|
|
32
|
+
} from '../../utils/authorization/recoverAuthorizationAddress.js'
|
|
33
|
+
import type { RequestErrorType } from '../../utils/buildRequest.js'
|
|
34
|
+
import {
|
|
35
|
+
type AssertCurrentChainErrorType,
|
|
36
|
+
assertCurrentChain,
|
|
37
|
+
} from '../../utils/chain/assertCurrentChain.js'
|
|
38
|
+
import {
|
|
39
|
+
type GetTransactionErrorReturnType,
|
|
40
|
+
getTransactionError,
|
|
41
|
+
} from '../../utils/errors/getTransactionError.js'
|
|
42
|
+
import { extract } from '../../utils/formatters/extract.js'
|
|
43
|
+
import {
|
|
44
|
+
type FormattedTransactionRequest,
|
|
45
|
+
formatTransactionRequest,
|
|
46
|
+
} from '../../utils/formatters/transactionRequest.js'
|
|
47
|
+
import { getAction } from '../../utils/getAction.js'
|
|
48
|
+
import { LruMap } from '../../utils/lru.js'
|
|
49
|
+
import {
|
|
50
|
+
type AssertRequestErrorType,
|
|
51
|
+
type AssertRequestParameters,
|
|
52
|
+
assertRequest,
|
|
53
|
+
} from '../../utils/transaction/assertRequest.js'
|
|
54
|
+
import { type GetChainIdErrorType, getChainId } from '../public/getChainId.js'
|
|
55
|
+
import {
|
|
56
|
+
type WaitForTransactionReceiptErrorType,
|
|
57
|
+
waitForTransactionReceipt,
|
|
58
|
+
} from '../public/waitForTransactionReceipt.js'
|
|
59
|
+
import {
|
|
60
|
+
defaultParameters,
|
|
61
|
+
type PrepareTransactionRequestErrorType,
|
|
62
|
+
prepareTransactionRequest,
|
|
63
|
+
} from './prepareTransactionRequest.js'
|
|
64
|
+
import {
|
|
65
|
+
type SendRawTransactionSyncErrorType,
|
|
66
|
+
type SendRawTransactionSyncReturnType,
|
|
67
|
+
sendRawTransactionSync,
|
|
68
|
+
} from './sendRawTransactionSync.js'
|
|
69
|
+
|
|
70
|
+
const supportsWalletNamespace = new LruMap<boolean>(128)
|
|
71
|
+
|
|
72
|
+
export type SendTransactionSyncRequest<
|
|
73
|
+
chain extends Chain | undefined = Chain | undefined,
|
|
74
|
+
chainOverride extends Chain | undefined = Chain | undefined,
|
|
75
|
+
///
|
|
76
|
+
_derivedChain extends Chain | undefined = DeriveChain<chain, chainOverride>,
|
|
77
|
+
> = UnionOmit<FormattedTransactionRequest<_derivedChain>, 'from'> &
|
|
78
|
+
GetTransactionRequestKzgParameter
|
|
79
|
+
|
|
80
|
+
export type SendTransactionSyncParameters<
|
|
81
|
+
chain extends Chain | undefined = Chain | undefined,
|
|
82
|
+
account extends Account | undefined = Account | undefined,
|
|
83
|
+
chainOverride extends Chain | undefined = Chain | undefined,
|
|
84
|
+
request extends SendTransactionSyncRequest<
|
|
85
|
+
chain,
|
|
86
|
+
chainOverride
|
|
87
|
+
> = SendTransactionSyncRequest<chain, chainOverride>,
|
|
88
|
+
> = request &
|
|
89
|
+
GetAccountParameter<account, Account | Address, true, true> &
|
|
90
|
+
GetChainParameter<chain, chainOverride> &
|
|
91
|
+
GetTransactionRequestKzgParameter<request> & {
|
|
92
|
+
/** Polling interval (ms) to poll for the transaction receipt. @default client.pollingInterval */
|
|
93
|
+
pollingInterval?: number | undefined
|
|
94
|
+
/** Timeout (ms) to wait for a response. @default Math.max(chain.blockTime * 3, 5_000) */
|
|
95
|
+
timeout?: number | undefined
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export type SendTransactionSyncReturnType<
|
|
99
|
+
chain extends Chain | undefined = Chain | undefined,
|
|
100
|
+
> = SendRawTransactionSyncReturnType<chain>
|
|
101
|
+
|
|
102
|
+
export type SendTransactionSyncErrorType =
|
|
103
|
+
| ParseAccountErrorType
|
|
104
|
+
| GetTransactionErrorReturnType<
|
|
105
|
+
| AccountNotFoundErrorType
|
|
106
|
+
| AccountTypeNotSupportedErrorType
|
|
107
|
+
| AssertCurrentChainErrorType
|
|
108
|
+
| AssertRequestErrorType
|
|
109
|
+
| GetChainIdErrorType
|
|
110
|
+
| PrepareTransactionRequestErrorType
|
|
111
|
+
| SendRawTransactionSyncErrorType
|
|
112
|
+
| RecoverAuthorizationAddressErrorType
|
|
113
|
+
| SignTransactionErrorType
|
|
114
|
+
| RequestErrorType
|
|
115
|
+
>
|
|
116
|
+
| WaitForTransactionReceiptErrorType
|
|
117
|
+
| ErrorType
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Creates, signs, and sends a new transaction to the network synchronously.
|
|
121
|
+
* Returns the transaction receipt.
|
|
122
|
+
*
|
|
123
|
+
* @param client - Client to use
|
|
124
|
+
* @param parameters - {@link SendTransactionSyncParameters}
|
|
125
|
+
* @returns The transaction receipt. {@link SendTransactionSyncReturnType}
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* import { createWalletClient, custom } from 'viem'
|
|
129
|
+
* import { mainnet } from 'viem/chains'
|
|
130
|
+
* import { sendTransactionSync } from 'viem/wallet'
|
|
131
|
+
*
|
|
132
|
+
* const client = createWalletClient({
|
|
133
|
+
* chain: mainnet,
|
|
134
|
+
* transport: custom(window.ethereum),
|
|
135
|
+
* })
|
|
136
|
+
* const receipt = await sendTransactionSync(client, {
|
|
137
|
+
* account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
|
|
138
|
+
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
|
|
139
|
+
* value: 1000000000000000000n,
|
|
140
|
+
* })
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* // Account Hoisting
|
|
144
|
+
* import { createWalletClient, http } from 'viem'
|
|
145
|
+
* import { privateKeyToAccount } from 'viem/accounts'
|
|
146
|
+
* import { mainnet } from 'viem/chains'
|
|
147
|
+
* import { sendTransactionSync } from 'viem/wallet'
|
|
148
|
+
*
|
|
149
|
+
* const client = createWalletClient({
|
|
150
|
+
* account: privateKeyToAccount('0x…'),
|
|
151
|
+
* chain: mainnet,
|
|
152
|
+
* transport: http(),
|
|
153
|
+
* })
|
|
154
|
+
* const receipt = await sendTransactionSync(client, {
|
|
155
|
+
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
|
|
156
|
+
* value: 1000000000000000000n,
|
|
157
|
+
* })
|
|
158
|
+
*/
|
|
159
|
+
export async function sendTransactionSync<
|
|
160
|
+
chain extends Chain | undefined,
|
|
161
|
+
account extends Account | undefined,
|
|
162
|
+
const request extends SendTransactionSyncRequest<chain, chainOverride>,
|
|
163
|
+
chainOverride extends Chain | undefined = undefined,
|
|
164
|
+
>(
|
|
165
|
+
client: Client<Transport, chain, account>,
|
|
166
|
+
parameters: SendTransactionSyncParameters<
|
|
167
|
+
chain,
|
|
168
|
+
account,
|
|
169
|
+
chainOverride,
|
|
170
|
+
request
|
|
171
|
+
>,
|
|
172
|
+
): Promise<SendTransactionSyncReturnType<chain>> {
|
|
173
|
+
const {
|
|
174
|
+
account: account_ = client.account,
|
|
175
|
+
chain = client.chain,
|
|
176
|
+
accessList,
|
|
177
|
+
authorizationList,
|
|
178
|
+
blobs,
|
|
179
|
+
data,
|
|
180
|
+
gas,
|
|
181
|
+
gasPrice,
|
|
182
|
+
maxFeePerBlobGas,
|
|
183
|
+
maxFeePerGas,
|
|
184
|
+
maxPriorityFeePerGas,
|
|
185
|
+
nonce,
|
|
186
|
+
pollingInterval,
|
|
187
|
+
type,
|
|
188
|
+
value,
|
|
189
|
+
...rest
|
|
190
|
+
} = parameters
|
|
191
|
+
const timeout =
|
|
192
|
+
parameters.timeout ?? Math.max((chain?.blockTime ?? 0) * 3, 5_000)
|
|
193
|
+
|
|
194
|
+
if (typeof account_ === 'undefined')
|
|
195
|
+
throw new AccountNotFoundError({
|
|
196
|
+
docsPath: '/docs/actions/wallet/sendTransactionSync',
|
|
197
|
+
})
|
|
198
|
+
const account = account_ ? parseAccount(account_) : null
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
assertRequest(parameters as AssertRequestParameters)
|
|
202
|
+
|
|
203
|
+
const to = await (async () => {
|
|
204
|
+
// If `to` exists on the parameters, use that.
|
|
205
|
+
if (parameters.to) return parameters.to
|
|
206
|
+
|
|
207
|
+
// If `to` is null, we are sending a deployment transaction.
|
|
208
|
+
if (parameters.to === null) return undefined
|
|
209
|
+
|
|
210
|
+
// If no `to` exists, and we are sending a EIP-7702 transaction, use the
|
|
211
|
+
// address of the first authorization in the list.
|
|
212
|
+
if (authorizationList && authorizationList.length > 0)
|
|
213
|
+
return await recoverAuthorizationAddress({
|
|
214
|
+
authorization: authorizationList[0],
|
|
215
|
+
}).catch(() => {
|
|
216
|
+
throw new BaseError(
|
|
217
|
+
'`to` is required. Could not infer from `authorizationList`.',
|
|
218
|
+
)
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
// Otherwise, we are sending a deployment transaction.
|
|
222
|
+
return undefined
|
|
223
|
+
})()
|
|
224
|
+
|
|
225
|
+
if (account?.type === 'json-rpc' || account === null) {
|
|
226
|
+
let chainId: number | undefined
|
|
227
|
+
if (chain !== null) {
|
|
228
|
+
chainId = await getAction(client, getChainId, 'getChainId')({})
|
|
229
|
+
assertCurrentChain({
|
|
230
|
+
currentChainId: chainId,
|
|
231
|
+
chain,
|
|
232
|
+
})
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const chainFormat = client.chain?.formatters?.transactionRequest?.format
|
|
236
|
+
const format = chainFormat || formatTransactionRequest
|
|
237
|
+
|
|
238
|
+
const request = format(
|
|
239
|
+
{
|
|
240
|
+
// Pick out extra data that might exist on the chain's transaction request type.
|
|
241
|
+
...extract(rest, { format: chainFormat }),
|
|
242
|
+
accessList,
|
|
243
|
+
authorizationList,
|
|
244
|
+
blobs,
|
|
245
|
+
chainId,
|
|
246
|
+
data,
|
|
247
|
+
from: account?.address,
|
|
248
|
+
gas,
|
|
249
|
+
gasPrice,
|
|
250
|
+
maxFeePerBlobGas,
|
|
251
|
+
maxFeePerGas,
|
|
252
|
+
maxPriorityFeePerGas,
|
|
253
|
+
nonce,
|
|
254
|
+
to,
|
|
255
|
+
type,
|
|
256
|
+
value,
|
|
257
|
+
} as TransactionRequest,
|
|
258
|
+
'sendTransaction',
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
const isWalletNamespaceSupported = supportsWalletNamespace.get(client.uid)
|
|
262
|
+
const method = isWalletNamespaceSupported
|
|
263
|
+
? 'wallet_sendTransaction'
|
|
264
|
+
: 'eth_sendTransaction'
|
|
265
|
+
|
|
266
|
+
const hash = await (async () => {
|
|
267
|
+
try {
|
|
268
|
+
return await client.request(
|
|
269
|
+
{
|
|
270
|
+
method,
|
|
271
|
+
params: [request],
|
|
272
|
+
},
|
|
273
|
+
{ retryCount: 0 },
|
|
274
|
+
)
|
|
275
|
+
} catch (e) {
|
|
276
|
+
if (isWalletNamespaceSupported === false) throw e
|
|
277
|
+
|
|
278
|
+
const error = e as BaseError
|
|
279
|
+
// If the transport does not support the method or input, attempt to use the
|
|
280
|
+
// `wallet_sendTransaction` method.
|
|
281
|
+
if (
|
|
282
|
+
error.name === 'InvalidInputRpcError' ||
|
|
283
|
+
error.name === 'InvalidParamsRpcError' ||
|
|
284
|
+
error.name === 'MethodNotFoundRpcError' ||
|
|
285
|
+
error.name === 'MethodNotSupportedRpcError'
|
|
286
|
+
) {
|
|
287
|
+
return (await client
|
|
288
|
+
.request(
|
|
289
|
+
{
|
|
290
|
+
method: 'wallet_sendTransaction',
|
|
291
|
+
params: [request],
|
|
292
|
+
},
|
|
293
|
+
{ retryCount: 0 },
|
|
294
|
+
)
|
|
295
|
+
.then((hash) => {
|
|
296
|
+
supportsWalletNamespace.set(client.uid, true)
|
|
297
|
+
return hash
|
|
298
|
+
})
|
|
299
|
+
.catch((e) => {
|
|
300
|
+
const walletNamespaceError = e as BaseError
|
|
301
|
+
if (
|
|
302
|
+
walletNamespaceError.name === 'MethodNotFoundRpcError' ||
|
|
303
|
+
walletNamespaceError.name === 'MethodNotSupportedRpcError'
|
|
304
|
+
) {
|
|
305
|
+
supportsWalletNamespace.set(client.uid, false)
|
|
306
|
+
throw error
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
throw walletNamespaceError
|
|
310
|
+
})) as never
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
throw error
|
|
314
|
+
}
|
|
315
|
+
})()
|
|
316
|
+
|
|
317
|
+
return getAction(
|
|
318
|
+
client,
|
|
319
|
+
waitForTransactionReceipt,
|
|
320
|
+
'waitForTransactionReceipt',
|
|
321
|
+
)({
|
|
322
|
+
checkReplacement: false,
|
|
323
|
+
hash,
|
|
324
|
+
pollingInterval,
|
|
325
|
+
timeout,
|
|
326
|
+
})
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (account?.type === 'local') {
|
|
330
|
+
// Prepare the request for signing (assign appropriate fees, etc.)
|
|
331
|
+
const request = await getAction(
|
|
332
|
+
client,
|
|
333
|
+
prepareTransactionRequest,
|
|
334
|
+
'prepareTransactionRequest',
|
|
335
|
+
)({
|
|
336
|
+
account,
|
|
337
|
+
accessList,
|
|
338
|
+
authorizationList,
|
|
339
|
+
blobs,
|
|
340
|
+
chain,
|
|
341
|
+
data,
|
|
342
|
+
gas,
|
|
343
|
+
gasPrice,
|
|
344
|
+
maxFeePerBlobGas,
|
|
345
|
+
maxFeePerGas,
|
|
346
|
+
maxPriorityFeePerGas,
|
|
347
|
+
nonce,
|
|
348
|
+
nonceManager: account.nonceManager,
|
|
349
|
+
parameters: [...defaultParameters, 'sidecars'],
|
|
350
|
+
type,
|
|
351
|
+
value,
|
|
352
|
+
...rest,
|
|
353
|
+
to,
|
|
354
|
+
} as any)
|
|
355
|
+
|
|
356
|
+
const serializer = chain?.serializers?.transaction
|
|
357
|
+
const serializedTransaction = (await account.signTransaction(request, {
|
|
358
|
+
serializer,
|
|
359
|
+
})) as Hash
|
|
360
|
+
return (await getAction(
|
|
361
|
+
client,
|
|
362
|
+
sendRawTransactionSync,
|
|
363
|
+
'sendRawTransactionSync',
|
|
364
|
+
)({
|
|
365
|
+
serializedTransaction,
|
|
366
|
+
})) as never
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (account?.type === 'smart')
|
|
370
|
+
throw new AccountTypeNotSupportedError({
|
|
371
|
+
metaMessages: [
|
|
372
|
+
'Consider using the `sendUserOperation` Action instead.',
|
|
373
|
+
],
|
|
374
|
+
docsPath: '/docs/actions/bundler/sendUserOperation',
|
|
375
|
+
type: 'smart',
|
|
376
|
+
})
|
|
377
|
+
|
|
378
|
+
throw new AccountTypeNotSupportedError({
|
|
379
|
+
docsPath: '/docs/actions/wallet/sendTransactionSync',
|
|
380
|
+
type: (account as any)?.type,
|
|
381
|
+
})
|
|
382
|
+
} catch (err) {
|
|
383
|
+
if (err instanceof AccountTypeNotSupportedError) throw err
|
|
384
|
+
throw getTransactionError(err as BaseError, {
|
|
385
|
+
...parameters,
|
|
386
|
+
account,
|
|
387
|
+
chain: parameters.chain || undefined,
|
|
388
|
+
})
|
|
389
|
+
}
|
|
390
|
+
}
|
|
@@ -43,6 +43,7 @@ import {
|
|
|
43
43
|
type SendTransactionReturnType,
|
|
44
44
|
sendTransaction,
|
|
45
45
|
} from './sendTransaction.js'
|
|
46
|
+
import type { sendTransactionSync } from './sendTransactionSync.js'
|
|
46
47
|
|
|
47
48
|
export type WriteContractParameters<
|
|
48
49
|
abi extends Abi | readonly unknown[] = Abi,
|
|
@@ -171,47 +172,81 @@ export async function writeContract<
|
|
|
171
172
|
chainOverride
|
|
172
173
|
>,
|
|
173
174
|
): Promise<WriteContractReturnType> {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
...request
|
|
182
|
-
} = parameters as WriteContractParameters
|
|
183
|
-
|
|
184
|
-
if (typeof account_ === 'undefined')
|
|
185
|
-
throw new AccountNotFoundError({
|
|
186
|
-
docsPath: '/docs/contract/writeContract',
|
|
187
|
-
})
|
|
188
|
-
const account = account_ ? parseAccount(account_) : null
|
|
189
|
-
|
|
190
|
-
const data = encodeFunctionData({
|
|
191
|
-
abi,
|
|
192
|
-
args,
|
|
193
|
-
functionName,
|
|
194
|
-
} as EncodeFunctionDataParameters)
|
|
175
|
+
return writeContract.internal(
|
|
176
|
+
client,
|
|
177
|
+
sendTransaction,
|
|
178
|
+
'sendTransaction',
|
|
179
|
+
parameters,
|
|
180
|
+
) as never
|
|
181
|
+
}
|
|
195
182
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
183
|
+
export namespace writeContract {
|
|
184
|
+
export async function internal<
|
|
185
|
+
chain extends Chain | undefined,
|
|
186
|
+
account extends Account | undefined,
|
|
187
|
+
const abi extends Abi | readonly unknown[],
|
|
188
|
+
functionName extends ContractFunctionName<abi, 'nonpayable' | 'payable'>,
|
|
189
|
+
args extends ContractFunctionArgs<
|
|
190
|
+
abi,
|
|
191
|
+
'nonpayable' | 'payable',
|
|
192
|
+
functionName
|
|
193
|
+
>,
|
|
194
|
+
chainOverride extends Chain | undefined,
|
|
195
|
+
>(
|
|
196
|
+
client: Client<Transport, chain, account>,
|
|
197
|
+
actionFn: typeof sendTransaction | typeof sendTransactionSync,
|
|
198
|
+
name: 'sendTransaction' | 'sendTransactionSync',
|
|
199
|
+
parameters: WriteContractParameters<
|
|
200
|
+
abi,
|
|
201
|
+
functionName,
|
|
202
|
+
args,
|
|
203
|
+
chain,
|
|
204
204
|
account,
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
205
|
+
chainOverride
|
|
206
|
+
>,
|
|
207
|
+
) {
|
|
208
|
+
const {
|
|
209
209
|
abi,
|
|
210
|
+
account: account_ = client.account,
|
|
210
211
|
address,
|
|
211
212
|
args,
|
|
212
|
-
|
|
213
|
+
dataSuffix,
|
|
214
|
+
functionName,
|
|
215
|
+
...request
|
|
216
|
+
} = parameters as WriteContractParameters
|
|
217
|
+
|
|
218
|
+
if (typeof account_ === 'undefined')
|
|
219
|
+
throw new AccountNotFoundError({
|
|
220
|
+
docsPath: '/docs/contract/writeContract',
|
|
221
|
+
})
|
|
222
|
+
const account = account_ ? parseAccount(account_) : null
|
|
223
|
+
|
|
224
|
+
const data = encodeFunctionData({
|
|
225
|
+
abi,
|
|
226
|
+
args,
|
|
213
227
|
functionName,
|
|
214
|
-
|
|
215
|
-
|
|
228
|
+
} as EncodeFunctionDataParameters)
|
|
229
|
+
|
|
230
|
+
try {
|
|
231
|
+
return await getAction(
|
|
232
|
+
client,
|
|
233
|
+
actionFn as never,
|
|
234
|
+
name,
|
|
235
|
+
)({
|
|
236
|
+
data: `${data}${dataSuffix ? dataSuffix.replace('0x', '') : ''}`,
|
|
237
|
+
to: address,
|
|
238
|
+
account,
|
|
239
|
+
...request,
|
|
240
|
+
})
|
|
241
|
+
} catch (error) {
|
|
242
|
+
throw getContractError(error as BaseError, {
|
|
243
|
+
abi,
|
|
244
|
+
address,
|
|
245
|
+
args,
|
|
246
|
+
docsPath: '/docs/contract/writeContract',
|
|
247
|
+
functionName,
|
|
248
|
+
sender: account?.address,
|
|
249
|
+
})
|
|
250
|
+
}
|
|
216
251
|
}
|
|
217
252
|
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { Abi } from 'abitype'
|
|
2
|
+
|
|
3
|
+
import type { Account } from '../../accounts/types.js'
|
|
4
|
+
import type { Client } from '../../clients/createClient.js'
|
|
5
|
+
import type { Transport } from '../../clients/transports/createTransport.js'
|
|
6
|
+
import type { Chain } from '../../types/chain.js'
|
|
7
|
+
import type {
|
|
8
|
+
ContractFunctionArgs,
|
|
9
|
+
ContractFunctionName,
|
|
10
|
+
} from '../../types/contract.js'
|
|
11
|
+
import {
|
|
12
|
+
type SendTransactionSyncParameters,
|
|
13
|
+
type SendTransactionSyncReturnType,
|
|
14
|
+
sendTransactionSync,
|
|
15
|
+
} from './sendTransactionSync.js'
|
|
16
|
+
import { type WriteContractParameters, writeContract } from './writeContract.js'
|
|
17
|
+
|
|
18
|
+
export type { WriteContractErrorType as WriteContractSyncErrorType } from './writeContract.js'
|
|
19
|
+
|
|
20
|
+
export type WriteContractSyncParameters<
|
|
21
|
+
abi extends Abi | readonly unknown[] = Abi,
|
|
22
|
+
functionName extends ContractFunctionName<
|
|
23
|
+
abi,
|
|
24
|
+
'nonpayable' | 'payable'
|
|
25
|
+
> = ContractFunctionName<abi, 'nonpayable' | 'payable'>,
|
|
26
|
+
args extends ContractFunctionArgs<
|
|
27
|
+
abi,
|
|
28
|
+
'nonpayable' | 'payable',
|
|
29
|
+
functionName
|
|
30
|
+
> = ContractFunctionArgs<abi, 'nonpayable' | 'payable', functionName>,
|
|
31
|
+
chain extends Chain | undefined = Chain | undefined,
|
|
32
|
+
account extends Account | undefined = Account | undefined,
|
|
33
|
+
chainOverride extends Chain | undefined = Chain | undefined,
|
|
34
|
+
> = WriteContractParameters<
|
|
35
|
+
abi,
|
|
36
|
+
functionName,
|
|
37
|
+
args,
|
|
38
|
+
chain,
|
|
39
|
+
account,
|
|
40
|
+
chainOverride
|
|
41
|
+
> &
|
|
42
|
+
Pick<SendTransactionSyncParameters<chain>, 'pollingInterval' | 'timeout'>
|
|
43
|
+
|
|
44
|
+
export type WriteContractSyncReturnType<
|
|
45
|
+
chain extends Chain | undefined = Chain | undefined,
|
|
46
|
+
> = SendTransactionSyncReturnType<chain>
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Executes a write function on a contract synchronously.
|
|
50
|
+
* Returns the transaction receipt.
|
|
51
|
+
*
|
|
52
|
+
* - Docs: https://viem.sh/docs/contract/writeContractSync
|
|
53
|
+
*
|
|
54
|
+
* A "write" function on a Solidity contract modifies the state of the blockchain. These types of functions require gas to be executed, and hence a [Transaction](https://viem.sh/docs/glossary/terms) is needed to be broadcast in order to change the state.
|
|
55
|
+
*
|
|
56
|
+
* Internally, uses a [Wallet Client](https://viem.sh/docs/clients/wallet) to call the [`sendTransaction` action](https://viem.sh/docs/actions/wallet/sendTransaction) with [ABI-encoded `data`](https://viem.sh/docs/contract/encodeFunctionData).
|
|
57
|
+
*
|
|
58
|
+
* __Warning: The `write` internally sends a transaction – it does not validate if the contract write will succeed (the contract may throw an error). It is highly recommended to [simulate the contract write with `contract.simulate`](https://viem.sh/docs/contract/writeContract#usage) before you execute it.__
|
|
59
|
+
*
|
|
60
|
+
* @param client - Client to use
|
|
61
|
+
* @param parameters - {@link WriteContractParameters}
|
|
62
|
+
* @returns A [Transaction Hash](https://viem.sh/docs/glossary/terms#hash). {@link WriteContractReturnType}
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* import { createWalletClient, custom, parseAbi } from 'viem'
|
|
66
|
+
* import { mainnet } from 'viem/chains'
|
|
67
|
+
* import { writeContract } from 'viem/contract'
|
|
68
|
+
*
|
|
69
|
+
* const client = createWalletClient({
|
|
70
|
+
* chain: mainnet,
|
|
71
|
+
* transport: custom(window.ethereum),
|
|
72
|
+
* })
|
|
73
|
+
* const receipt = await writeContractSync(client, {
|
|
74
|
+
* address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
|
|
75
|
+
* abi: parseAbi(['function mint(uint32 tokenId) nonpayable']),
|
|
76
|
+
* functionName: 'mint',
|
|
77
|
+
* args: [69420],
|
|
78
|
+
* })
|
|
79
|
+
*/
|
|
80
|
+
export async function writeContractSync<
|
|
81
|
+
chain extends Chain | undefined,
|
|
82
|
+
account extends Account | undefined,
|
|
83
|
+
const abi extends Abi | readonly unknown[],
|
|
84
|
+
functionName extends ContractFunctionName<abi, 'nonpayable' | 'payable'>,
|
|
85
|
+
args extends ContractFunctionArgs<
|
|
86
|
+
abi,
|
|
87
|
+
'nonpayable' | 'payable',
|
|
88
|
+
functionName
|
|
89
|
+
>,
|
|
90
|
+
chainOverride extends Chain | undefined,
|
|
91
|
+
>(
|
|
92
|
+
client: Client<Transport, chain, account>,
|
|
93
|
+
parameters: WriteContractSyncParameters<
|
|
94
|
+
abi,
|
|
95
|
+
functionName,
|
|
96
|
+
args,
|
|
97
|
+
chain,
|
|
98
|
+
account,
|
|
99
|
+
chainOverride
|
|
100
|
+
>,
|
|
101
|
+
): Promise<WriteContractSyncReturnType<chain>> {
|
|
102
|
+
return writeContract.internal(
|
|
103
|
+
client,
|
|
104
|
+
sendTransactionSync,
|
|
105
|
+
'sendTransactionSync',
|
|
106
|
+
parameters as never,
|
|
107
|
+
) as never
|
|
108
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineChain } from '../../utils/chain/defineChain.js'
|
|
2
|
+
|
|
3
|
+
export const domaTestnet = /*#__PURE__*/ defineChain({
|
|
4
|
+
id: 97_476,
|
|
5
|
+
name: 'Doma Testnet',
|
|
6
|
+
nativeCurrency: {
|
|
7
|
+
decimals: 18,
|
|
8
|
+
name: 'Ether',
|
|
9
|
+
symbol: 'ETH',
|
|
10
|
+
},
|
|
11
|
+
rpcUrls: {
|
|
12
|
+
default: { http: ['https://rpc-testnet.doma.xyz'] },
|
|
13
|
+
},
|
|
14
|
+
blockExplorers: {
|
|
15
|
+
default: {
|
|
16
|
+
name: 'Doma Testnet Explorer',
|
|
17
|
+
url: 'https://explorer-testnet.doma.xyz',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
testnet: true,
|
|
21
|
+
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { defineChain } from '../../utils/chain/defineChain.js'
|
|
2
|
+
|
|
3
|
+
export const nitrographTestnet = /*#__PURE__*/ defineChain({
|
|
4
|
+
id: 200024,
|
|
5
|
+
name: 'Nitrograph Testnet',
|
|
6
|
+
testnet: true,
|
|
7
|
+
rpcUrls: {
|
|
8
|
+
default: {
|
|
9
|
+
http: ['https://rpc-testnet.nitrograph.foundation'],
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
nativeCurrency: {
|
|
13
|
+
name: 'Nitro',
|
|
14
|
+
symbol: 'NOS',
|
|
15
|
+
decimals: 18,
|
|
16
|
+
},
|
|
17
|
+
blockExplorers: {
|
|
18
|
+
default: {
|
|
19
|
+
url: 'https://explorer-testnet.nitrograph.foundation',
|
|
20
|
+
name: 'Nitrograph Explorer',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
})
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { defineChain } from '../../utils/chain/defineChain.js'
|
|
2
|
+
|
|
3
|
+
export const tronNile = /*#__PURE__*/ defineChain({
|
|
4
|
+
id: 3448148188,
|
|
5
|
+
name: 'Tron Nile',
|
|
6
|
+
nativeCurrency: { name: 'TRON', symbol: 'TRX', decimals: 6 },
|
|
7
|
+
rpcUrls: {
|
|
8
|
+
default: {
|
|
9
|
+
http: ['https://nile.trongrid.io/jsonrpc'],
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
blockExplorers: {
|
|
13
|
+
default: {
|
|
14
|
+
name: 'Tronscan',
|
|
15
|
+
url: 'https://nile.tronscan.org',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
testnet: true,
|
|
19
|
+
})
|