viem 0.0.0-w-20230630153145 → 0.0.0-w-20230711200108

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 (143) hide show
  1. package/dist/cjs/accounts/utils/signTransaction.js.map +1 -1
  2. package/dist/cjs/actions/public/simulateContract.js +1 -0
  3. package/dist/cjs/actions/public/simulateContract.js.map +1 -1
  4. package/dist/cjs/actions/public/waitForTransactionReceipt.js +3 -4
  5. package/dist/cjs/actions/public/waitForTransactionReceipt.js.map +1 -1
  6. package/dist/cjs/chains/formatters/celo.js +2 -2
  7. package/dist/cjs/chains/formatters/celo.js.map +1 -1
  8. package/dist/cjs/chains/formatters/optimism.js +2 -2
  9. package/dist/cjs/chains/formatters/optimism.js.map +1 -1
  10. package/dist/cjs/chains/index.js +9 -5
  11. package/dist/cjs/chains/index.js.map +1 -1
  12. package/dist/cjs/chains/serializers/celo.js +84 -0
  13. package/dist/cjs/chains/serializers/celo.js.map +1 -0
  14. package/dist/cjs/clients/createClient.js +19 -12
  15. package/dist/cjs/clients/createClient.js.map +1 -1
  16. package/dist/cjs/clients/createPublicClient.js +6 -7
  17. package/dist/cjs/clients/createPublicClient.js.map +1 -1
  18. package/dist/cjs/clients/createTestClient.js +9 -9
  19. package/dist/cjs/clients/createTestClient.js.map +1 -1
  20. package/dist/cjs/clients/createWalletClient.js +6 -6
  21. package/dist/cjs/clients/createWalletClient.js.map +1 -1
  22. package/dist/cjs/clients/decorators/public.js +44 -42
  23. package/dist/cjs/clients/decorators/public.js.map +1 -1
  24. package/dist/cjs/clients/decorators/wallet.js +17 -15
  25. package/dist/cjs/clients/decorators/wallet.js.map +1 -1
  26. package/dist/cjs/errors/base.js +2 -2
  27. package/dist/cjs/errors/base.js.map +1 -1
  28. package/dist/cjs/errors/version.js +1 -1
  29. package/dist/cjs/errors/version.js.map +1 -1
  30. package/dist/cjs/utils/abi/encodePacked.js.map +1 -1
  31. package/dist/cjs/utils/ens/avatar/utils.js +2 -1
  32. package/dist/cjs/utils/ens/avatar/utils.js.map +1 -1
  33. package/dist/cjs/utils/errors/getContractError.js +1 -1
  34. package/dist/cjs/utils/errors/getContractError.js.map +1 -1
  35. package/dist/cjs/utils/formatters/extract.js +0 -1
  36. package/dist/cjs/utils/formatters/extract.js.map +1 -1
  37. package/dist/cjs/utils/transaction/prepareRequest.js +1 -1
  38. package/dist/cjs/utils/transaction/prepareRequest.js.map +1 -1
  39. package/dist/esm/accounts/utils/signTransaction.js.map +1 -1
  40. package/dist/esm/actions/public/simulateContract.js +1 -0
  41. package/dist/esm/actions/public/simulateContract.js.map +1 -1
  42. package/dist/esm/actions/public/waitForTransactionReceipt.js +3 -4
  43. package/dist/esm/actions/public/waitForTransactionReceipt.js.map +1 -1
  44. package/dist/esm/chains/formatters/celo.js +1 -1
  45. package/dist/esm/chains/formatters/celo.js.map +1 -1
  46. package/dist/esm/chains/formatters/optimism.js +1 -1
  47. package/dist/esm/chains/formatters/optimism.js.map +1 -1
  48. package/dist/esm/chains/index.js +11 -7
  49. package/dist/esm/chains/index.js.map +1 -1
  50. package/dist/esm/chains/serializers/celo.js +92 -0
  51. package/dist/esm/chains/serializers/celo.js.map +1 -0
  52. package/dist/esm/clients/createClient.js +19 -15
  53. package/dist/esm/clients/createClient.js.map +1 -1
  54. package/dist/esm/clients/createPublicClient.js +6 -26
  55. package/dist/esm/clients/createPublicClient.js.map +1 -1
  56. package/dist/esm/clients/createTestClient.js +9 -32
  57. package/dist/esm/clients/createTestClient.js.map +1 -1
  58. package/dist/esm/clients/createWalletClient.js +6 -42
  59. package/dist/esm/clients/createWalletClient.js.map +1 -1
  60. package/dist/esm/clients/decorators/public.js +44 -42
  61. package/dist/esm/clients/decorators/public.js.map +1 -1
  62. package/dist/esm/clients/decorators/wallet.js +17 -15
  63. package/dist/esm/clients/decorators/wallet.js.map +1 -1
  64. package/dist/esm/errors/base.js +2 -2
  65. package/dist/esm/errors/base.js.map +1 -1
  66. package/dist/esm/errors/version.js +1 -1
  67. package/dist/esm/errors/version.js.map +1 -1
  68. package/dist/esm/utils/abi/encodePacked.js.map +1 -1
  69. package/dist/esm/utils/ens/avatar/utils.js +3 -1
  70. package/dist/esm/utils/ens/avatar/utils.js.map +1 -1
  71. package/dist/esm/utils/errors/getContractError.js +1 -1
  72. package/dist/esm/utils/errors/getContractError.js.map +1 -1
  73. package/dist/esm/utils/formatters/extract.js +1 -1
  74. package/dist/esm/utils/formatters/extract.js.map +1 -1
  75. package/dist/esm/utils/transaction/prepareRequest.js +1 -1
  76. package/dist/esm/utils/transaction/prepareRequest.js.map +1 -1
  77. package/dist/types/accounts/utils/signTransaction.d.ts +1 -1
  78. package/dist/types/accounts/utils/signTransaction.d.ts.map +1 -1
  79. package/dist/types/actions/public/simulateContract.d.ts.map +1 -1
  80. package/dist/types/actions/public/waitForTransactionReceipt.d.ts.map +1 -1
  81. package/dist/types/actions/wallet/deployContract.d.ts +1 -1
  82. package/dist/types/actions/wallet/deployContract.d.ts.map +1 -1
  83. package/dist/types/chains/formatters/celo.d.ts +2 -2
  84. package/dist/types/chains/formatters/celo.d.ts.map +1 -1
  85. package/dist/types/chains/formatters/optimism.d.ts +9 -9
  86. package/dist/types/chains/formatters/optimism.d.ts.map +1 -1
  87. package/dist/types/chains/index.d.ts.map +1 -1
  88. package/dist/types/chains/serializers/celo.d.ts +20 -0
  89. package/dist/types/chains/serializers/celo.d.ts.map +1 -0
  90. package/dist/types/clients/createClient.d.ts +32 -34
  91. package/dist/types/clients/createClient.d.ts.map +1 -1
  92. package/dist/types/clients/createPublicClient.d.ts +3 -3
  93. package/dist/types/clients/createPublicClient.d.ts.map +1 -1
  94. package/dist/types/clients/createTestClient.d.ts +9 -7
  95. package/dist/types/clients/createTestClient.d.ts.map +1 -1
  96. package/dist/types/clients/createWalletClient.d.ts +3 -3
  97. package/dist/types/clients/createWalletClient.d.ts.map +1 -1
  98. package/dist/types/clients/decorators/public.d.ts +1 -519
  99. package/dist/types/clients/decorators/public.d.ts.map +1 -1
  100. package/dist/types/clients/decorators/wallet.d.ts +1 -519
  101. package/dist/types/clients/decorators/wallet.d.ts.map +1 -1
  102. package/dist/types/errors/base.d.ts +2 -1
  103. package/dist/types/errors/base.d.ts.map +1 -1
  104. package/dist/types/errors/version.d.ts +1 -1
  105. package/dist/types/errors/version.d.ts.map +1 -1
  106. package/dist/types/types/chain.d.ts +3 -4
  107. package/dist/types/types/chain.d.ts.map +1 -1
  108. package/dist/types/types/eip1193.d.ts +9 -10
  109. package/dist/types/types/eip1193.d.ts.map +1 -1
  110. package/dist/types/types/transaction.d.ts +1 -1
  111. package/dist/types/types/transaction.d.ts.map +1 -1
  112. package/dist/types/types/typedData.d.ts +6 -6
  113. package/dist/types/types/typedData.d.ts.map +1 -1
  114. package/dist/types/utils/ens/avatar/utils.d.ts +1 -1
  115. package/dist/types/utils/ens/avatar/utils.d.ts.map +1 -1
  116. package/dist/types/utils/formatters/extract.d.ts +1 -1
  117. package/dist/types/utils/formatters/extract.d.ts.map +1 -1
  118. package/package.json +6 -1
  119. package/src/accounts/utils/signTransaction.ts +7 -2
  120. package/src/actions/public/simulateContract.ts +1 -0
  121. package/src/actions/public/waitForTransactionReceipt.ts +3 -4
  122. package/src/actions/wallet/deployContract.ts +1 -1
  123. package/src/chains/formatters/celo.ts +8 -7
  124. package/src/chains/formatters/optimism.ts +14 -14
  125. package/src/chains/index.ts +11 -7
  126. package/src/chains/serializers/celo.ts +190 -0
  127. package/src/clients/createClient.ts +116 -88
  128. package/src/clients/createPublicClient.ts +26 -26
  129. package/src/clients/createTestClient.ts +41 -47
  130. package/src/clients/createWalletClient.ts +30 -33
  131. package/src/clients/decorators/public.ts +49 -44
  132. package/src/clients/decorators/wallet.ts +18 -16
  133. package/src/errors/base.ts +6 -3
  134. package/src/errors/version.ts +1 -1
  135. package/src/types/chain.ts +6 -7
  136. package/src/types/eip1193.ts +14 -27
  137. package/src/types/transaction.ts +1 -1
  138. package/src/types/typedData.ts +6 -6
  139. package/src/utils/abi/encodePacked.ts +1 -1
  140. package/src/utils/ens/avatar/utils.ts +3 -1
  141. package/src/utils/errors/getContractError.ts +1 -1
  142. package/src/utils/formatters/extract.ts +3 -2
  143. package/src/utils/transaction/prepareRequest.ts +1 -1
@@ -0,0 +1,190 @@
1
+ import type { Address } from 'abitype'
2
+
3
+ import { InvalidAddressError } from '../../errors/address.js'
4
+ import { BaseError } from '../../errors/base.js'
5
+ import { InvalidChainIdError } from '../../errors/chain.js'
6
+ import { FeeCapTooHighError, TipAboveFeeCapError } from '../../errors/node.js'
7
+ import type { FeeValuesEIP1559 } from '../../types/fee.js'
8
+ import type { Signature } from '../../types/misc.js'
9
+ import type { Serializers } from '../../types/serializer.js'
10
+ import type {
11
+ AccessList,
12
+ TransactionSerializable,
13
+ TransactionSerializableBase,
14
+ } from '../../types/transaction.js'
15
+ import { isAddress } from '../../utils/address/isAddress.js'
16
+ import { concatHex } from '../../utils/data/concat.js'
17
+ import { trim } from '../../utils/data/trim.js'
18
+ import { toHex } from '../../utils/encoding/toHex.js'
19
+ import { toRlp } from '../../utils/encoding/toRlp.js'
20
+ import { serializeAccessList } from '../../utils/transaction/serializeAccessList.js'
21
+ import {
22
+ type SerializeTransactionFn,
23
+ serializeTransaction,
24
+ } from '../../utils/transaction/serializeTransaction.js'
25
+
26
+ export const serializeTransactionCelo: SerializeTransactionFn<
27
+ TransactionSerializableCelo
28
+ > = (tx, signature) => {
29
+ // Handle CIP-42 transactions
30
+ if (isCIP42(tx))
31
+ return serializeTransactionCIP42(
32
+ tx as TransactionSerializableCIP42,
33
+ signature,
34
+ )
35
+
36
+ // Handle other transaction types
37
+ return serializeTransaction(tx as TransactionSerializable, signature)
38
+ }
39
+
40
+ export const serializersCelo = {
41
+ transaction: serializeTransactionCelo,
42
+ } as const satisfies Serializers
43
+
44
+ //////////////////////////////////////////////////////////////////////////////
45
+ // Types
46
+
47
+ export type TransactionSerializableCIP42<
48
+ TQuantity = bigint,
49
+ TIndex = number,
50
+ > = TransactionSerializableBase<TQuantity, TIndex> &
51
+ FeeValuesEIP1559<TQuantity> & {
52
+ accessList?: AccessList
53
+ gasPrice?: never
54
+ feeCurrency?: Address
55
+ gatewayFeeRecipient?: Address
56
+ gatewayFee?: TQuantity
57
+ chainId: number
58
+ type?: 'cip42'
59
+ }
60
+
61
+ export type TransactionSerializableCelo =
62
+ | TransactionSerializableCIP42
63
+ | TransactionSerializable
64
+
65
+ export type SerializedCIP42TransactionReturnType = `0x7c${string}`
66
+
67
+ //////////////////////////////////////////////////////////////////////////////
68
+ // Serializers
69
+
70
+ // There shall be a typed transaction with the code 0x7c that has the following format:
71
+ // 0x7c || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, feecurrency, gatewayFeeRecipient, gatewayfee, destination, amount, data, access_list, signature_y_parity, signature_r, signature_s]).
72
+ // This will be in addition to the type 0x02 transaction as specified in EIP-1559.
73
+ function serializeTransactionCIP42(
74
+ transaction: TransactionSerializableCIP42,
75
+ signature?: Signature,
76
+ ): SerializedCIP42TransactionReturnType {
77
+ assertTransactionCIP42(transaction)
78
+ const {
79
+ chainId,
80
+ gas,
81
+ nonce,
82
+ to,
83
+ value,
84
+ maxFeePerGas,
85
+ maxPriorityFeePerGas,
86
+ accessList,
87
+ feeCurrency,
88
+ gatewayFeeRecipient,
89
+ gatewayFee,
90
+ data,
91
+ } = transaction
92
+
93
+ const serializedTransaction = [
94
+ toHex(chainId),
95
+ nonce ? toHex(nonce) : '0x',
96
+ maxPriorityFeePerGas ? toHex(maxPriorityFeePerGas) : '0x',
97
+ maxFeePerGas ? toHex(maxFeePerGas) : '0x',
98
+ gas ? toHex(gas) : '0x',
99
+ feeCurrency ?? '0x',
100
+ gatewayFeeRecipient ?? '0x',
101
+ gatewayFee ? toHex(gatewayFee) : '0x',
102
+ to ?? '0x',
103
+ value ? toHex(value) : '0x',
104
+ data ?? '0x',
105
+ serializeAccessList(accessList),
106
+ ]
107
+
108
+ if (signature) {
109
+ serializedTransaction.push(
110
+ signature.v === 27n ? '0x' : toHex(1), // yParity
111
+ trim(signature.r),
112
+ trim(signature.s),
113
+ )
114
+ }
115
+
116
+ return concatHex([
117
+ '0x7c',
118
+ toRlp(serializedTransaction),
119
+ ]) as SerializedCIP42TransactionReturnType
120
+ }
121
+
122
+ //////////////////////////////////////////////////////////////////////////////
123
+ // Utilities
124
+
125
+ // process as CIP42 if any of these fields are present. realistically gatewayfee is not used but is part of spec
126
+ function isCIP42(transaction: TransactionSerializableCelo) {
127
+ if (
128
+ 'maxFeePerGas' in transaction &&
129
+ 'maxPriorityFeePerGas' in transaction &&
130
+ ('feeCurrency' in transaction ||
131
+ 'gatewayFee' in transaction ||
132
+ 'gatewayFeeRecipient' in transaction)
133
+ )
134
+ return true
135
+ return false
136
+ }
137
+
138
+ // maxFeePerGas must be less than 2^256 - 1: however writing like that caused exceptions to be raised
139
+ const MAX_MAX_FEE_PER_GAS =
140
+ 115792089237316195423570985008687907853269984665640564039457584007913129639935n
141
+
142
+ function assertTransactionCIP42(transaction: TransactionSerializableCIP42) {
143
+ const {
144
+ chainId,
145
+ maxPriorityFeePerGas,
146
+ gasPrice,
147
+ maxFeePerGas,
148
+ to,
149
+ feeCurrency,
150
+ gatewayFee,
151
+ gatewayFeeRecipient,
152
+ } = transaction
153
+ if (chainId <= 0) throw new InvalidChainIdError({ chainId })
154
+ if (to && !isAddress(to)) throw new InvalidAddressError({ address: to })
155
+ if (gasPrice)
156
+ throw new BaseError(
157
+ '`gasPrice` is not a valid CIP-42 Transaction attribute.',
158
+ )
159
+
160
+ if (maxFeePerGas && maxFeePerGas > MAX_MAX_FEE_PER_GAS)
161
+ throw new FeeCapTooHighError({ maxFeePerGas })
162
+
163
+ if (
164
+ maxPriorityFeePerGas &&
165
+ maxFeePerGas &&
166
+ maxPriorityFeePerGas > maxFeePerGas
167
+ )
168
+ throw new TipAboveFeeCapError({ maxFeePerGas, maxPriorityFeePerGas })
169
+
170
+ if (
171
+ (gatewayFee && !gatewayFeeRecipient) ||
172
+ (gatewayFeeRecipient && !gatewayFee)
173
+ ) {
174
+ throw new BaseError(
175
+ '`gatewayFee` and `gatewayFeeRecipient` must be provided together.',
176
+ )
177
+ }
178
+
179
+ if (feeCurrency && !feeCurrency?.startsWith('0x')) {
180
+ throw new BaseError(
181
+ '`feeCurrency` MUST be a token address for CIP-42 transactions.',
182
+ )
183
+ }
184
+
185
+ if (!feeCurrency && !gatewayFeeRecipient) {
186
+ throw new BaseError(
187
+ 'Either `feeCurrency` or `gatewayFeeRecipient` must be provided for CIP-42 transactions.',
188
+ )
189
+ }
190
+ }
@@ -1,7 +1,6 @@
1
- import type { Address, Narrow } from 'abitype'
1
+ import type { Address } from 'abitype'
2
2
 
3
3
  import type { Account, JsonRpcAccount } from '../accounts/types.js'
4
- import type { ParseAccount } from '../types/account.js'
5
4
  import type { Chain } from '../types/chain.js'
6
5
  import type {
7
6
  EIP1193RequestFn,
@@ -13,60 +12,64 @@ import { parseAccount } from '../utils/accounts.js'
13
12
  import { uid } from '../utils/uid.js'
14
13
  import type { Transport } from './transports/createTransport.js'
15
14
 
16
- export type MulticallBatchOptions = {
17
- /** The maximum size (in bytes) for each calldata chunk. @default 1_024 */
18
- batchSize?: number
19
- /** The maximum number of milliseconds to wait before sending a batch. @default 0 */
20
- wait?: number
21
- }
22
-
23
15
  export type ClientConfig<
24
- TTransport extends Transport = Transport,
25
- TChain extends Chain | undefined = Chain | undefined,
26
- TAccountOrAddress extends Account | Address | undefined =
16
+ transport extends Transport = Transport,
17
+ chain extends Chain | undefined = Chain | undefined,
18
+ accountOrAddress extends Account | Address | undefined =
27
19
  | Account
28
20
  | Address
29
21
  | undefined,
30
22
  > = {
31
23
  /** The Account to use for the Client. This will be used for Actions that require an account as an argument. */
32
- account?: TAccountOrAddress
24
+ account?: accountOrAddress | Account | Address | undefined
33
25
  /** Flags for batch settings. */
34
- batch?: {
35
- /** Toggle to enable `eth_call` multicall aggregation. */
36
- multicall?: boolean | MulticallBatchOptions
37
- }
26
+ batch?:
27
+ | {
28
+ /** Toggle to enable `eth_call` multicall aggregation. */
29
+ multicall?: boolean | Prettify<MulticallBatchOptions> | undefined
30
+ }
31
+ | undefined
38
32
  /** Chain for the client. */
39
- chain?: TChain
33
+ chain?: Chain | undefined | chain
40
34
  /** A key for the client. */
41
- key?: string
35
+ key?: string | undefined
42
36
  /** A name for the client. */
43
- name?: string
37
+ name?: string | undefined
44
38
  /**
45
39
  * Frequency (in ms) for polling enabled actions & events.
46
40
  * @default 4_000
47
41
  */
48
- pollingInterval?: number
42
+ pollingInterval?: number | undefined
49
43
  /** The RPC transport */
50
- transport: TTransport
44
+ transport: transport
51
45
  /** The type of client. */
52
- type?: string
46
+ type?: string | undefined
53
47
  }
54
48
 
49
+ // TODO: Move `transport` to slot index 2 since `chain` and `account` used more frequently.
50
+ // Otherwise, we end up with a lot of `Client<Transport, chain, account>` in actions.
51
+ export type Client<
52
+ transport extends Transport = Transport,
53
+ chain extends Chain | undefined = Chain | undefined,
54
+ account extends Account | undefined = Account | undefined,
55
+ rpcSchema extends RpcSchema | undefined = undefined,
56
+ extended extends Extended | undefined = Extended | undefined,
57
+ > = Client_Base<transport, chain, account, rpcSchema> &
58
+ (extended extends Extended ? extended : unknown) &
59
+ ExtendFn<transport, chain, account, rpcSchema, extended>
60
+
55
61
  type Client_Base<
56
- TTransport extends Transport = Transport,
57
- TChain extends Chain | undefined = Chain | undefined,
58
- TAccount extends Account | undefined = Account | undefined,
59
- TRpcSchema extends RpcSchema | undefined = undefined,
62
+ transport extends Transport = Transport,
63
+ chain extends Chain | undefined = Chain | undefined,
64
+ account extends Account | undefined = Account | undefined,
65
+ rpcSchema extends RpcSchema | undefined = undefined,
60
66
  > = {
61
67
  /** The Account of the Client. */
62
- account: TAccount
68
+ account: account
63
69
  /** Flags for batch settings. */
64
- batch?: {
65
- /** Toggle to enable `eth_call` multicall aggregation. */
66
- multicall?: boolean | MulticallBatchOptions
67
- }
70
+ batch?: ClientConfig['batch']
68
71
  /** Chain for the client. */
69
- chain: TChain
72
+ chain: chain
70
73
  /** A key for the client. */
71
74
  key: string
72
75
  /** A name for the client. */
@@ -74,86 +77,111 @@ type Client_Base<
74
77
  /** Frequency (in ms) for polling enabled actions & events. Defaults to 4_000 milliseconds. */
75
78
  pollingInterval: number
76
79
  /** Request function wrapped with friendly error handling */
77
- request: TRpcSchema extends undefined
78
- ? EIP1193RequestFn<EIP1474Methods>
79
- : EIP1193RequestFn<TRpcSchema>
80
+ request: EIP1193RequestFn<
81
+ rpcSchema extends undefined ? EIP1474Methods : rpcSchema
82
+ >
80
83
  /** The RPC transport */
81
- transport: ReturnType<TTransport>['config'] & ReturnType<TTransport>['value']
84
+ transport: ReturnType<transport>['config'] & ReturnType<transport>['value']
82
85
  /** The type of client. */
83
86
  type: string
84
87
  /** A unique ID for the client. */
85
88
  uid: string
86
89
  }
87
90
 
88
- type Extended = { [K in keyof Client_Base]?: undefined } & {
89
- [key: string]: unknown
90
- }
91
-
92
- export type Client<
93
- TTransport extends Transport = Transport,
94
- TChain extends Chain | undefined = Chain | undefined,
95
- TAccount extends Account | undefined = Account | undefined,
96
- TRpcSchema extends RpcSchema | undefined = undefined,
97
- TExtended extends Extended | undefined = Extended | undefined,
98
- > = Client_Base<TTransport, TChain, TAccount, TRpcSchema> & {
99
- extend: <TNextExtended extends Extended = Extended>(
91
+ type ExtendFn<
92
+ transport extends Transport = Transport,
93
+ chain extends Chain | undefined = Chain | undefined,
94
+ account extends Account | undefined = Account | undefined,
95
+ rpcSchema extends RpcSchema | undefined = undefined,
96
+ extended extends Extended | undefined = Extended | undefined,
97
+ > = {
98
+ extend: <const client extends Extended>(
100
99
  fn: (
101
- client: Client<TTransport, TChain, TAccount, TRpcSchema, TExtended>,
102
- ) => Narrow<TNextExtended>,
100
+ client: Client<transport, chain, account, rpcSchema, extended>,
101
+ ) => client,
103
102
  ) => Client<
104
- TTransport,
105
- TChain,
106
- TAccount,
107
- TRpcSchema,
108
- (TExtended extends Extended ? TExtended : {}) & TNextExtended
103
+ transport,
104
+ chain,
105
+ account,
106
+ rpcSchema,
107
+ Prettify<client> & (extended extends Extended ? extended : unknown)
109
108
  >
110
- } & (TExtended extends Extended ? TExtended : {})
109
+ }
110
+
111
+ type Extended = Prettify<
112
+ { [key: string]: unknown } & {
113
+ // disallow redefining base properties
114
+ [K in keyof Client_Base]?: undefined
115
+ }
116
+ >
117
+
118
+ export type MulticallBatchOptions = {
119
+ /** The maximum size (in bytes) for each calldata chunk. @default 1_024 */
120
+ batchSize?: number | undefined
121
+ /** The maximum number of milliseconds to wait before sending a batch. @default 0 */
122
+ wait?: number | undefined
123
+ }
111
124
 
112
125
  /**
113
- * @description Creates a base client with the given transport.
126
+ * Creates a base client with the given transport.
114
127
  */
115
128
  export function createClient<
116
- TTransport extends Transport,
117
- TChain extends Chain | undefined = undefined,
118
- TAccountOrAddress extends Account | Address | undefined = undefined,
119
- >({
120
- account,
121
- batch,
122
- chain,
123
- key = 'base',
124
- name = 'Base Client',
125
- pollingInterval = 4_000,
126
- transport,
127
- type = 'base',
128
- }: ClientConfig<TTransport, TChain, TAccountOrAddress>): Client<
129
- TTransport,
130
- TChain,
131
- TAccountOrAddress extends Address
132
- ? Prettify<JsonRpcAccount<TAccountOrAddress>>
133
- : TAccountOrAddress
134
- > {
135
- const { config, request, value } = transport({ chain, pollingInterval })
129
+ transport extends Transport,
130
+ chain extends Chain | undefined = undefined,
131
+ accountOrAddress extends Account | Address | undefined = undefined,
132
+ >(
133
+ parameters: ClientConfig<transport, chain, accountOrAddress>,
134
+ ): Prettify<
135
+ Client<
136
+ transport,
137
+ chain,
138
+ accountOrAddress extends Address
139
+ ? Prettify<JsonRpcAccount<accountOrAddress>>
140
+ : accountOrAddress
141
+ >
142
+ >
143
+
144
+ export function createClient(parameters: ClientConfig): Client {
145
+ const {
146
+ batch,
147
+ key = 'base',
148
+ name = 'Base Client',
149
+ pollingInterval = 4_000,
150
+ type = 'base',
151
+ } = parameters
152
+
153
+ const chain = parameters.chain
154
+ const account = parameters.account
155
+ ? parseAccount(parameters.account)
156
+ : undefined
157
+ const { config, request, value } = parameters.transport({
158
+ chain,
159
+ pollingInterval,
160
+ })
161
+ const transport = { ...config, ...value }
162
+
136
163
  const client = {
137
- account: (account
138
- ? parseAccount(account)
139
- : undefined) as ParseAccount<TAccountOrAddress>,
164
+ account,
140
165
  batch,
141
- chain: chain as TChain,
166
+ chain,
142
167
  key,
143
168
  name,
144
169
  pollingInterval,
145
170
  request,
146
- transport: { ...config, ...value },
171
+ transport,
147
172
  type,
148
173
  uid: uid(),
149
174
  }
150
- function extend(client_: typeof client) {
151
- return (fn: (_: typeof client) => unknown) => {
152
- const extended = fn(client_) as Extended
175
+
176
+ function extend(base: typeof client) {
177
+ type ExtendFn = (base: typeof client) => unknown
178
+ return (extendFn: ExtendFn) => {
179
+ const extended = extendFn(base) as Extended
153
180
  for (const key in client) delete extended[key]
154
- const nextClient = { ...client_, ...extended }
155
- return Object.assign(nextClient, { extend: extend(nextClient) })
181
+ const combined = { ...base, ...extended }
182
+ return Object.assign(combined, { extend: extend(combined) })
156
183
  }
157
184
  }
185
+
158
186
  return Object.assign(client, { extend: extend(client) as any })
159
187
  }
@@ -6,23 +6,25 @@ import { type PublicActions, publicActions } from './decorators/public.js'
6
6
  import type { Transport } from './transports/createTransport.js'
7
7
 
8
8
  export type PublicClientConfig<
9
- TTransport extends Transport = Transport,
10
- TChain extends Chain | undefined = Chain | undefined,
11
- > = Pick<
12
- ClientConfig<TTransport, TChain>,
13
- 'batch' | 'chain' | 'key' | 'name' | 'pollingInterval' | 'transport'
9
+ transport extends Transport = Transport,
10
+ chain extends Chain | undefined = Chain | undefined,
11
+ > = Prettify<
12
+ Pick<
13
+ ClientConfig<transport, chain>,
14
+ 'batch' | 'chain' | 'key' | 'name' | 'pollingInterval' | 'transport'
15
+ >
14
16
  >
15
17
 
16
18
  export type PublicClient<
17
- TTransport extends Transport = Transport,
18
- TChain extends Chain | undefined = Chain | undefined,
19
+ transport extends Transport = Transport,
20
+ chain extends Chain | undefined = Chain | undefined,
19
21
  > = Prettify<
20
22
  Client<
21
- TTransport,
22
- TChain,
23
+ transport,
24
+ chain,
23
25
  undefined,
24
26
  PublicRpcSchema,
25
- PublicActions<TTransport, TChain>
27
+ PublicActions<transport, chain>
26
28
  >
27
29
  >
28
30
 
@@ -46,23 +48,21 @@ export type PublicClient<
46
48
  * })
47
49
  */
48
50
  export function createPublicClient<
49
- TTransport extends Transport,
50
- TChain extends Chain | undefined = undefined,
51
- >({
52
- batch,
53
- chain,
54
- key = 'public',
55
- name = 'Public Client',
56
- transport,
57
- pollingInterval,
58
- }: PublicClientConfig<TTransport, TChain>): PublicClient<TTransport, TChain> {
59
- return createClient({
60
- batch,
61
- chain,
51
+ transport extends Transport,
52
+ chain extends Chain | undefined = undefined,
53
+ >(
54
+ parameters: PublicClientConfig<transport, chain>,
55
+ ): PublicClient<transport, chain>
56
+
57
+ export function createPublicClient(
58
+ parameters: PublicClientConfig,
59
+ ): PublicClient {
60
+ const { key = 'public', name = 'Public Client' } = parameters
61
+ const client = createClient({
62
+ ...parameters,
62
63
  key,
63
64
  name,
64
- pollingInterval,
65
- transport,
66
65
  type: 'publicClient',
67
- }).extend(publicActions)
66
+ })
67
+ return client.extend(publicActions)
68
68
  }
@@ -2,6 +2,7 @@ import type { Account } from '../accounts/types.js'
2
2
  import type { ParseAccount } from '../types/account.js'
3
3
  import type { Chain } from '../types/chain.js'
4
4
  import type { TestRpcSchema } from '../types/eip1193.js'
5
+ import type { Prettify } from '../types/utils.js'
5
6
  import { type Client, type ClientConfig, createClient } from './createClient.js'
6
7
  import { type TestActions, testActions } from './decorators/test.js'
7
8
  import type { Transport } from './transports/createTransport.js'
@@ -10,36 +11,38 @@ import type { Address } from 'abitype'
10
11
  export type TestClientMode = 'anvil' | 'hardhat' | 'ganache'
11
12
 
12
13
  export type TestClientConfig<
13
- TMode extends TestClientMode = TestClientMode,
14
- TTransport extends Transport = Transport,
15
- TChain extends Chain | undefined = Chain | undefined,
16
- TAccountOrAddress extends Account | Address | undefined =
14
+ mode extends TestClientMode = TestClientMode,
15
+ transport extends Transport = Transport,
16
+ chain extends Chain | undefined = Chain | undefined,
17
+ accountOrAddress extends Account | Address | undefined =
17
18
  | Account
18
19
  | Address
19
20
  | undefined,
20
- > = Pick<
21
- ClientConfig<TTransport, TChain, TAccountOrAddress>,
22
- 'account' | 'chain' | 'key' | 'name' | 'pollingInterval' | 'transport'
23
- > & {
24
- /** Mode of the test client. Available: "anvil" | "hardhat" | "ganache" */
25
- mode: TMode
26
- }
21
+ > = Prettify<
22
+ Pick<
23
+ ClientConfig<transport, chain, accountOrAddress>,
24
+ 'account' | 'chain' | 'key' | 'name' | 'pollingInterval' | 'transport'
25
+ > & {
26
+ /** Mode of the test client. */
27
+ mode: mode | ('anvil' | 'hardhat' | 'ganache') // TODO: Type utility that expands `TestClientMode`
28
+ }
29
+ >
27
30
 
28
31
  export type TestClient<
29
32
  TMode extends TestClientMode = TestClientMode,
30
- TTransport extends Transport = Transport,
31
- TChain extends Chain | undefined = Chain | undefined,
33
+ transport extends Transport = Transport,
34
+ chain extends Chain | undefined = Chain | undefined,
32
35
  TAccount extends Account | undefined = Account | undefined,
33
36
  TIncludeActions extends boolean = true,
34
- > = Client<
35
- TTransport,
36
- TChain,
37
- TAccount,
38
- TestRpcSchema<TMode>,
39
- TIncludeActions extends true ? TestActions : Record<string, unknown>
40
- > & {
41
- mode: TMode
42
- }
37
+ > = Prettify<
38
+ { mode: TMode } & Client<
39
+ transport,
40
+ chain,
41
+ TAccount,
42
+ TestRpcSchema<TMode>,
43
+ TIncludeActions extends true ? TestActions : Record<string, unknown>
44
+ >
45
+ >
43
46
 
44
47
  /**
45
48
  * @description Creates a test client with a given transport.
@@ -65,33 +68,24 @@ export type TestClient<
65
68
  * })
66
69
  */
67
70
  export function createTestClient<
68
- TMode extends TestClientMode,
69
- TTransport extends Transport,
70
- TChain extends Chain | undefined = undefined,
71
- TAccountOrAddress extends Account | Address | undefined = undefined,
72
- >({
73
- account,
74
- chain,
75
- key = 'test',
76
- name = 'Test Client',
77
- mode,
78
- pollingInterval,
79
- transport,
80
- }: TestClientConfig<TMode, TTransport, TChain, TAccountOrAddress>): TestClient<
81
- TMode,
82
- TTransport,
83
- TChain,
84
- ParseAccount<TAccountOrAddress>
85
- > {
86
- return createClient({
87
- account,
88
- chain,
71
+ mode extends 'anvil' | 'hardhat' | 'ganache', // TODO: Type utility that expands `TestClientMode`
72
+ transport extends Transport,
73
+ chain extends Chain | undefined = undefined,
74
+ accountOrAddress extends Account | Address | undefined = undefined,
75
+ >(
76
+ parameters: TestClientConfig<mode, transport, chain, accountOrAddress>,
77
+ ): TestClient<mode, transport, chain, ParseAccount<accountOrAddress>>
78
+
79
+ export function createTestClient(parameters: TestClientConfig): TestClient {
80
+ const { key = 'test', name = 'Test Client', mode } = parameters
81
+ const client = createClient({
82
+ ...parameters,
89
83
  key,
90
84
  name,
91
- pollingInterval,
92
- transport,
93
85
  type: 'testClient',
94
86
  })
95
- .extend(() => ({ mode }))
96
- .extend(testActions({ mode }))
87
+ return client.extend((config) => ({
88
+ mode,
89
+ ...testActions({ mode })(config),
90
+ }))
97
91
  }