viem 2.14.1 → 2.15.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +20 -0
- package/_cjs/accounts/hdKeyToAccount.js +2 -2
- package/_cjs/accounts/hdKeyToAccount.js.map +1 -1
- package/_cjs/accounts/index.js +4 -1
- package/_cjs/accounts/index.js.map +1 -1
- package/_cjs/accounts/mnemonicToAccount.js.map +1 -1
- package/_cjs/accounts/privateKeyToAccount.js +3 -1
- package/_cjs/accounts/privateKeyToAccount.js.map +1 -1
- package/_cjs/accounts/toAccount.js +1 -0
- package/_cjs/accounts/toAccount.js.map +1 -1
- package/_cjs/actions/public/getBlock.js +2 -2
- package/_cjs/actions/public/getBlock.js.map +1 -1
- package/_cjs/actions/public/getBlockTransactionCount.js +2 -2
- package/_cjs/actions/public/getBlockTransactionCount.js.map +1 -1
- package/_cjs/actions/public/getChainId.js +1 -1
- package/_cjs/actions/public/getChainId.js.map +1 -1
- package/_cjs/actions/public/getCode.js +1 -1
- package/_cjs/actions/public/getCode.js.map +1 -1
- package/_cjs/actions/public/getFeeHistory.js +1 -1
- package/_cjs/actions/public/getFeeHistory.js.map +1 -1
- package/_cjs/actions/public/getTransaction.js +3 -3
- package/_cjs/actions/public/getTransaction.js.map +1 -1
- package/_cjs/actions/public/getTransactionConfirmations.js +1 -1
- package/_cjs/actions/public/getTransactionCount.js +1 -1
- package/_cjs/actions/public/getTransactionCount.js.map +1 -1
- package/_cjs/actions/public/getTransactionReceipt.js +1 -1
- package/_cjs/actions/public/getTransactionReceipt.js.map +1 -1
- package/_cjs/actions/wallet/addChain.js +1 -1
- package/_cjs/actions/wallet/addChain.js.map +1 -1
- package/_cjs/actions/wallet/getAddresses.js +1 -1
- package/_cjs/actions/wallet/getAddresses.js.map +1 -1
- package/_cjs/actions/wallet/getPermissions.js +1 -1
- package/_cjs/actions/wallet/getPermissions.js.map +1 -1
- package/_cjs/actions/wallet/prepareTransactionRequest.js +30 -13
- package/_cjs/actions/wallet/prepareTransactionRequest.js.map +1 -1
- package/_cjs/actions/wallet/requestAddresses.js +1 -1
- package/_cjs/actions/wallet/requestAddresses.js.map +1 -1
- package/_cjs/chains/definitions/berachainTestnetbArtio.js +24 -0
- package/_cjs/chains/definitions/berachainTestnetbArtio.js.map +1 -0
- package/_cjs/chains/definitions/confluxESpace.js +2 -2
- package/_cjs/chains/definitions/confluxESpaceTestnet.js +2 -2
- package/_cjs/chains/definitions/mode.js +15 -0
- package/_cjs/chains/definitions/mode.js.map +1 -1
- package/_cjs/chains/index.js +8 -6
- package/_cjs/chains/index.js.map +1 -1
- package/_cjs/clients/transports/createTransport.js +12 -2
- package/_cjs/clients/transports/createTransport.js.map +1 -1
- package/_cjs/errors/version.js +1 -1
- package/_cjs/experimental/erc7715/actions/issuePermissions.js +1 -1
- package/_cjs/experimental/erc7715/actions/issuePermissions.js.map +1 -1
- package/_cjs/index.js +4 -1
- package/_cjs/index.js.map +1 -1
- package/_cjs/nonce/index.js +8 -0
- package/_cjs/nonce/index.js.map +1 -0
- package/_cjs/utils/buildRequest.js +10 -3
- package/_cjs/utils/buildRequest.js.map +1 -1
- package/_cjs/utils/index.js +4 -1
- package/_cjs/utils/index.js.map +1 -1
- package/_cjs/utils/nonceManager.js +73 -0
- package/_cjs/utils/nonceManager.js.map +1 -0
- package/_cjs/utils/promise/withDedupe.js +16 -0
- package/_cjs/utils/promise/withDedupe.js.map +1 -0
- package/_esm/accounts/hdKeyToAccount.js +2 -2
- package/_esm/accounts/hdKeyToAccount.js.map +1 -1
- package/_esm/accounts/index.js +1 -0
- package/_esm/accounts/index.js.map +1 -1
- package/_esm/accounts/mnemonicToAccount.js.map +1 -1
- package/_esm/accounts/privateKeyToAccount.js +3 -1
- package/_esm/accounts/privateKeyToAccount.js.map +1 -1
- package/_esm/accounts/toAccount.js +1 -0
- package/_esm/accounts/toAccount.js.map +1 -1
- package/_esm/actions/public/getBlock.js +2 -2
- package/_esm/actions/public/getBlock.js.map +1 -1
- package/_esm/actions/public/getBlockTransactionCount.js +2 -2
- package/_esm/actions/public/getBlockTransactionCount.js.map +1 -1
- package/_esm/actions/public/getChainId.js +1 -1
- package/_esm/actions/public/getChainId.js.map +1 -1
- package/_esm/actions/public/getCode.js +1 -1
- package/_esm/actions/public/getCode.js.map +1 -1
- package/_esm/actions/public/getFeeHistory.js +1 -1
- package/_esm/actions/public/getFeeHistory.js.map +1 -1
- package/_esm/actions/public/getTransaction.js +3 -3
- package/_esm/actions/public/getTransaction.js.map +1 -1
- package/_esm/actions/public/getTransactionConfirmations.js +1 -1
- package/_esm/actions/public/getTransactionCount.js +1 -1
- package/_esm/actions/public/getTransactionCount.js.map +1 -1
- package/_esm/actions/public/getTransactionReceipt.js +1 -1
- package/_esm/actions/public/getTransactionReceipt.js.map +1 -1
- package/_esm/actions/wallet/addChain.js +1 -1
- package/_esm/actions/wallet/addChain.js.map +1 -1
- package/_esm/actions/wallet/getAddresses.js +1 -1
- package/_esm/actions/wallet/getAddresses.js.map +1 -1
- package/_esm/actions/wallet/getPermissions.js +1 -1
- package/_esm/actions/wallet/getPermissions.js.map +1 -1
- package/_esm/actions/wallet/prepareTransactionRequest.js +31 -14
- package/_esm/actions/wallet/prepareTransactionRequest.js.map +1 -1
- package/_esm/actions/wallet/requestAddresses.js +1 -1
- package/_esm/actions/wallet/requestAddresses.js.map +1 -1
- package/_esm/chains/definitions/berachainTestnetbArtio.js +21 -0
- package/_esm/chains/definitions/berachainTestnetbArtio.js.map +1 -0
- package/_esm/chains/definitions/confluxESpace.js +2 -2
- package/_esm/chains/definitions/confluxESpaceTestnet.js +2 -2
- package/_esm/chains/definitions/mode.js +15 -0
- package/_esm/chains/definitions/mode.js.map +1 -1
- package/_esm/chains/index.js +1 -0
- package/_esm/chains/index.js.map +1 -1
- package/_esm/clients/transports/createTransport.js +12 -2
- package/_esm/clients/transports/createTransport.js.map +1 -1
- package/_esm/errors/version.js +1 -1
- package/_esm/experimental/erc7715/actions/issuePermissions.js +1 -1
- package/_esm/experimental/erc7715/actions/issuePermissions.js.map +1 -1
- package/_esm/index.js +1 -0
- package/_esm/index.js.map +1 -1
- package/_esm/nonce/index.js +3 -0
- package/_esm/nonce/index.js.map +1 -0
- package/_esm/utils/buildRequest.js +10 -3
- package/_esm/utils/buildRequest.js.map +1 -1
- package/_esm/utils/index.js +1 -0
- package/_esm/utils/index.js.map +1 -1
- package/_esm/utils/nonceManager.js +84 -0
- package/_esm/utils/nonceManager.js.map +1 -0
- package/_esm/utils/promise/withDedupe.js +14 -0
- package/_esm/utils/promise/withDedupe.js.map +1 -0
- package/_types/accounts/hdKeyToAccount.d.ts +3 -2
- package/_types/accounts/hdKeyToAccount.d.ts.map +1 -1
- package/_types/accounts/index.d.ts +4 -3
- package/_types/accounts/index.d.ts.map +1 -1
- package/_types/accounts/mnemonicToAccount.d.ts +2 -1
- package/_types/accounts/mnemonicToAccount.d.ts.map +1 -1
- package/_types/accounts/privateKeyToAccount.d.ts +5 -1
- package/_types/accounts/privateKeyToAccount.d.ts.map +1 -1
- package/_types/accounts/toAccount.d.ts.map +1 -1
- package/_types/accounts/types.d.ts +2 -0
- package/_types/accounts/types.d.ts.map +1 -1
- package/_types/actions/public/getBlock.d.ts.map +1 -1
- package/_types/actions/public/getBlockTransactionCount.d.ts.map +1 -1
- package/_types/actions/public/getChainId.d.ts.map +1 -1
- package/_types/actions/public/getCode.d.ts.map +1 -1
- package/_types/actions/public/getFeeHistory.d.ts.map +1 -1
- package/_types/actions/public/getTransaction.d.ts.map +1 -1
- package/_types/actions/public/getTransactionCount.d.ts.map +1 -1
- package/_types/actions/public/getTransactionReceipt.d.ts.map +1 -1
- package/_types/actions/wallet/getAddresses.d.ts.map +1 -1
- package/_types/actions/wallet/getPermissions.d.ts.map +1 -1
- package/_types/actions/wallet/prepareTransactionRequest.d.ts.map +1 -1
- package/_types/chains/definitions/berachainTestnetbArtio.d.ts +35 -0
- package/_types/chains/definitions/berachainTestnetbArtio.d.ts.map +1 -0
- package/_types/chains/definitions/confluxESpace.d.ts +2 -2
- package/_types/chains/definitions/confluxESpaceTestnet.d.ts +2 -2
- package/_types/chains/definitions/mode.d.ts +15 -0
- package/_types/chains/definitions/mode.d.ts.map +1 -1
- package/_types/chains/index.d.ts +1 -0
- package/_types/chains/index.d.ts.map +1 -1
- package/_types/clients/transports/createTransport.d.ts.map +1 -1
- package/_types/errors/version.d.ts +1 -1
- package/_types/experimental/erc7715/actions/issuePermissions.d.ts.map +1 -1
- package/_types/index.d.ts +1 -0
- package/_types/index.d.ts.map +1 -1
- package/_types/nonce/index.d.ts +2 -0
- package/_types/nonce/index.d.ts.map +1 -0
- package/_types/types/eip1193.d.ts +3 -0
- package/_types/types/eip1193.d.ts.map +1 -1
- package/_types/utils/buildRequest.d.ts.map +1 -1
- package/_types/utils/index.d.ts +1 -0
- package/_types/utils/index.d.ts.map +1 -1
- package/_types/utils/nonceManager.d.ts +51 -0
- package/_types/utils/nonceManager.d.ts.map +1 -0
- package/_types/utils/promise/withDedupe.d.ts +11 -0
- package/_types/utils/promise/withDedupe.d.ts.map +1 -0
- package/accounts/hdKeyToAccount.ts +11 -2
- package/accounts/index.ts +10 -0
- package/accounts/mnemonicToAccount.ts +3 -0
- package/accounts/privateKeyToAccount.ts +11 -1
- package/accounts/toAccount.ts +1 -0
- package/accounts/types.ts +2 -0
- package/actions/public/getBlock.ts +14 -8
- package/actions/public/getBlockTransactionCount.ts +14 -8
- package/actions/public/getChainId.ts +6 -3
- package/actions/public/getCode.ts +7 -4
- package/actions/public/getFeeHistory.ts +11 -8
- package/actions/public/getTransaction.ts +21 -12
- package/actions/public/getTransactionConfirmations.ts +1 -1
- package/actions/public/getTransactionCount.ts +7 -4
- package/actions/public/getTransactionReceipt.ts +7 -4
- package/actions/wallet/addChain.ts +1 -1
- package/actions/wallet/getAddresses.ts +4 -1
- package/actions/wallet/getPermissions.ts +4 -1
- package/actions/wallet/prepareTransactionRequest.ts +31 -16
- package/actions/wallet/requestAddresses.ts +1 -1
- package/chains/definitions/berachainTestnetbArtio.ts +21 -0
- package/chains/definitions/confluxESpace.ts +2 -2
- package/chains/definitions/confluxESpaceTestnet.ts +2 -2
- package/chains/definitions/mode.ts +15 -0
- package/chains/index.ts +1 -0
- package/clients/transports/createTransport.ts +12 -2
- package/errors/version.ts +1 -1
- package/experimental/erc7715/actions/issuePermissions.ts +7 -4
- package/index.ts +7 -0
- package/nonce/index.ts +9 -0
- package/nonce/package.json +6 -0
- package/package.json +6 -1
- package/types/eip1193.ts +4 -0
- package/utils/buildRequest.ts +104 -88
- package/utils/index.ts +7 -0
- package/utils/nonceManager.ts +132 -0
- package/utils/promise/withDedupe.ts +21 -0
package/utils/buildRequest.ts
CHANGED
@@ -55,9 +55,13 @@ import type {
|
|
55
55
|
EIP1193RequestFn,
|
56
56
|
EIP1193RequestOptions,
|
57
57
|
} from '../types/eip1193.js'
|
58
|
+
import { stringToHex } from './encoding/toHex.js'
|
59
|
+
import { keccak256 } from './hash/keccak256.js'
|
58
60
|
import type { CreateBatchSchedulerErrorType } from './promise/createBatchScheduler.js'
|
61
|
+
import { withDedupe } from './promise/withDedupe.js'
|
59
62
|
import { type WithRetryErrorType, withRetry } from './promise/withRetry.js'
|
60
63
|
import type { GetSocketRpcClientErrorType } from './rpc/socket.js'
|
64
|
+
import { stringify } from './stringify.js'
|
61
65
|
|
62
66
|
export type RequestErrorType =
|
63
67
|
| ChainDisconnectedErrorType
|
@@ -94,98 +98,110 @@ export function buildRequest<request extends (args: any) => Promise<any>>(
|
|
94
98
|
options: EIP1193RequestOptions = {},
|
95
99
|
): EIP1193RequestFn {
|
96
100
|
return async (args, overrideOptions = {}) => {
|
97
|
-
const {
|
101
|
+
const {
|
102
|
+
dedupe = false,
|
103
|
+
retryDelay = 150,
|
104
|
+
retryCount = 3,
|
105
|
+
uid,
|
106
|
+
} = {
|
98
107
|
...options,
|
99
108
|
...overrideOptions,
|
100
109
|
}
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
110
|
+
const requestId = dedupe
|
111
|
+
? keccak256(stringToHex(`${uid}.${stringify(args)}`))
|
112
|
+
: undefined
|
113
|
+
return withDedupe(
|
114
|
+
() =>
|
115
|
+
withRetry(
|
116
|
+
async () => {
|
117
|
+
try {
|
118
|
+
return await request(args)
|
119
|
+
} catch (err_) {
|
120
|
+
const err = err_ as unknown as RpcError<
|
121
|
+
RpcErrorCode | ProviderRpcErrorCode
|
122
|
+
>
|
123
|
+
switch (err.code) {
|
124
|
+
// -32700
|
125
|
+
case ParseRpcError.code:
|
126
|
+
throw new ParseRpcError(err)
|
127
|
+
// -32600
|
128
|
+
case InvalidRequestRpcError.code:
|
129
|
+
throw new InvalidRequestRpcError(err)
|
130
|
+
// -32601
|
131
|
+
case MethodNotFoundRpcError.code:
|
132
|
+
throw new MethodNotFoundRpcError(err)
|
133
|
+
// -32602
|
134
|
+
case InvalidParamsRpcError.code:
|
135
|
+
throw new InvalidParamsRpcError(err)
|
136
|
+
// -32603
|
137
|
+
case InternalRpcError.code:
|
138
|
+
throw new InternalRpcError(err)
|
139
|
+
// -32000
|
140
|
+
case InvalidInputRpcError.code:
|
141
|
+
throw new InvalidInputRpcError(err)
|
142
|
+
// -32001
|
143
|
+
case ResourceNotFoundRpcError.code:
|
144
|
+
throw new ResourceNotFoundRpcError(err)
|
145
|
+
// -32002
|
146
|
+
case ResourceUnavailableRpcError.code:
|
147
|
+
throw new ResourceUnavailableRpcError(err)
|
148
|
+
// -32003
|
149
|
+
case TransactionRejectedRpcError.code:
|
150
|
+
throw new TransactionRejectedRpcError(err)
|
151
|
+
// -32004
|
152
|
+
case MethodNotSupportedRpcError.code:
|
153
|
+
throw new MethodNotSupportedRpcError(err)
|
154
|
+
// -32005
|
155
|
+
case LimitExceededRpcError.code:
|
156
|
+
throw new LimitExceededRpcError(err)
|
157
|
+
// -32006
|
158
|
+
case JsonRpcVersionUnsupportedError.code:
|
159
|
+
throw new JsonRpcVersionUnsupportedError(err)
|
160
|
+
// 4001
|
161
|
+
case UserRejectedRequestError.code:
|
162
|
+
throw new UserRejectedRequestError(err)
|
163
|
+
// 4100
|
164
|
+
case UnauthorizedProviderError.code:
|
165
|
+
throw new UnauthorizedProviderError(err)
|
166
|
+
// 4200
|
167
|
+
case UnsupportedProviderMethodError.code:
|
168
|
+
throw new UnsupportedProviderMethodError(err)
|
169
|
+
// 4900
|
170
|
+
case ProviderDisconnectedError.code:
|
171
|
+
throw new ProviderDisconnectedError(err)
|
172
|
+
// 4901
|
173
|
+
case ChainDisconnectedError.code:
|
174
|
+
throw new ChainDisconnectedError(err)
|
175
|
+
// 4902
|
176
|
+
case SwitchChainError.code:
|
177
|
+
throw new SwitchChainError(err)
|
178
|
+
// CAIP-25: User Rejected Error
|
179
|
+
// https://docs.walletconnect.com/2.0/specs/clients/sign/error-codes#rejected-caip-25
|
180
|
+
case 5000:
|
181
|
+
throw new UserRejectedRequestError(err)
|
182
|
+
default:
|
183
|
+
if (err_ instanceof BaseError) throw err_
|
184
|
+
throw new UnknownRpcError(err as Error)
|
185
|
+
}
|
186
|
+
}
|
187
|
+
},
|
188
|
+
{
|
189
|
+
delay: ({ count, error }) => {
|
190
|
+
// If we find a Retry-After header, let's retry after the given time.
|
191
|
+
if (error && error instanceof HttpRequestError) {
|
192
|
+
const retryAfter = error?.headers?.get('Retry-After')
|
193
|
+
if (retryAfter?.match(/\d/))
|
194
|
+
return Number.parseInt(retryAfter) * 1000
|
195
|
+
}
|
182
196
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
197
|
+
// Otherwise, let's retry with an exponential backoff.
|
198
|
+
return ~~(1 << count) * retryDelay
|
199
|
+
},
|
200
|
+
retryCount,
|
201
|
+
shouldRetry: ({ error }) => shouldRetry(error),
|
202
|
+
},
|
203
|
+
),
|
204
|
+
{ enabled: dedupe, id: requestId },
|
189
205
|
)
|
190
206
|
}
|
191
207
|
}
|
package/utils/index.ts
CHANGED
@@ -491,3 +491,10 @@ export { type FormatUnitsErrorType, formatUnits } from './unit/formatUnits.js'
|
|
491
491
|
export { type ParseUnitsErrorType, parseUnits } from './unit/parseUnits.js'
|
492
492
|
export { type ParseEtherErrorType, parseEther } from './unit/parseEther.js'
|
493
493
|
export { type ParseGweiErrorType, parseGwei } from './unit/parseGwei.js'
|
494
|
+
export {
|
495
|
+
type CreateNonceManagerParameters,
|
496
|
+
type NonceManager,
|
497
|
+
type NonceManagerSource,
|
498
|
+
createNonceManager,
|
499
|
+
nonceManager,
|
500
|
+
} from './nonceManager.js'
|
@@ -0,0 +1,132 @@
|
|
1
|
+
import type { Address } from 'abitype'
|
2
|
+
|
3
|
+
import { getTransactionCount } from '../actions/public/getTransactionCount.js'
|
4
|
+
import type { Client } from '../clients/createClient.js'
|
5
|
+
import type { MaybePromise } from '../types/utils.js'
|
6
|
+
import { LruMap } from './lru.js'
|
7
|
+
|
8
|
+
export type CreateNonceManagerParameters = {
|
9
|
+
source: NonceManagerSource
|
10
|
+
}
|
11
|
+
|
12
|
+
type FunctionParameters = {
|
13
|
+
address: Address
|
14
|
+
chainId: number
|
15
|
+
}
|
16
|
+
|
17
|
+
export type NonceManager = {
|
18
|
+
/** Get and increment a nonce. */
|
19
|
+
consume: (
|
20
|
+
parameters: FunctionParameters & { client: Client },
|
21
|
+
) => Promise<number>
|
22
|
+
/** Increment a nonce. */
|
23
|
+
increment: (chainId: FunctionParameters) => void
|
24
|
+
/** Get a nonce. */
|
25
|
+
get: (chainId: FunctionParameters & { client: Client }) => Promise<number>
|
26
|
+
/** Reset a nonce. */
|
27
|
+
reset: (chainId: FunctionParameters) => void
|
28
|
+
}
|
29
|
+
|
30
|
+
/**
|
31
|
+
* Creates a nonce manager for auto-incrementing transaction nonces.
|
32
|
+
*
|
33
|
+
* - Docs: https://viem.sh/docs/accounts/createNonceManager
|
34
|
+
*
|
35
|
+
* @example
|
36
|
+
* ```ts
|
37
|
+
* const nonceManager = createNonceManager({
|
38
|
+
* source: jsonRpc(),
|
39
|
+
* })
|
40
|
+
* ```
|
41
|
+
*/
|
42
|
+
export function createNonceManager(
|
43
|
+
parameters: CreateNonceManagerParameters,
|
44
|
+
): NonceManager {
|
45
|
+
const { source } = parameters
|
46
|
+
|
47
|
+
const deltaMap = new Map()
|
48
|
+
const nonceMap = new LruMap<number>(8192)
|
49
|
+
const promiseMap = new Map<string, Promise<number>>()
|
50
|
+
|
51
|
+
const getKey = ({ address, chainId }: FunctionParameters) =>
|
52
|
+
`${address}.${chainId}`
|
53
|
+
|
54
|
+
return {
|
55
|
+
async consume({ address, chainId, client }) {
|
56
|
+
const key = getKey({ address, chainId })
|
57
|
+
const promise = this.get({ address, chainId, client })
|
58
|
+
|
59
|
+
this.increment({ address, chainId })
|
60
|
+
const nonce = await promise
|
61
|
+
|
62
|
+
await source.set({ address, chainId }, nonce)
|
63
|
+
nonceMap.set(key, nonce)
|
64
|
+
|
65
|
+
return nonce
|
66
|
+
},
|
67
|
+
async increment({ address, chainId }) {
|
68
|
+
const key = getKey({ address, chainId })
|
69
|
+
const delta = deltaMap.get(key) ?? 0
|
70
|
+
deltaMap.set(key, delta + 1)
|
71
|
+
},
|
72
|
+
async get({ address, chainId, client }) {
|
73
|
+
const key = getKey({ address, chainId })
|
74
|
+
|
75
|
+
let promise = promiseMap.get(key)
|
76
|
+
if (!promise) {
|
77
|
+
promise = (async () => {
|
78
|
+
try {
|
79
|
+
const nonce = await source.get({ address, chainId, client })
|
80
|
+
const previousNonce = nonceMap.get(key) ?? 0
|
81
|
+
if (nonce <= previousNonce) return previousNonce + 1
|
82
|
+
nonceMap.delete(key)
|
83
|
+
return nonce
|
84
|
+
} finally {
|
85
|
+
this.reset({ address, chainId })
|
86
|
+
}
|
87
|
+
})()
|
88
|
+
promiseMap.set(key, promise)
|
89
|
+
}
|
90
|
+
|
91
|
+
const delta = deltaMap.get(key) ?? 0
|
92
|
+
return delta + (await promise)
|
93
|
+
},
|
94
|
+
reset({ address, chainId }) {
|
95
|
+
const key = getKey({ address, chainId })
|
96
|
+
deltaMap.delete(key)
|
97
|
+
promiseMap.delete(key)
|
98
|
+
},
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
////////////////////////////////////////////////////////////////////////////////////////////
|
103
|
+
// Sources
|
104
|
+
|
105
|
+
export type NonceManagerSource = {
|
106
|
+
/** Get a nonce. */
|
107
|
+
get(parameters: FunctionParameters & { client: Client }): MaybePromise<number>
|
108
|
+
/** Set a nonce. */
|
109
|
+
set(parameters: FunctionParameters, nonce: number): MaybePromise<void>
|
110
|
+
}
|
111
|
+
|
112
|
+
/** JSON-RPC source for a nonce manager. */
|
113
|
+
export function jsonRpc(): NonceManagerSource {
|
114
|
+
return {
|
115
|
+
async get(parameters) {
|
116
|
+
const { address, client } = parameters
|
117
|
+
return getTransactionCount(client, {
|
118
|
+
address,
|
119
|
+
blockTag: 'pending',
|
120
|
+
})
|
121
|
+
},
|
122
|
+
set() {},
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
////////////////////////////////////////////////////////////////////////////////////////////
|
127
|
+
// Default
|
128
|
+
|
129
|
+
/** Default Nonce Manager with a JSON-RPC source. */
|
130
|
+
export const nonceManager = /*#__PURE__*/ createNonceManager({
|
131
|
+
source: jsonRpc(),
|
132
|
+
})
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import { LruMap } from '../lru.js'
|
2
|
+
|
3
|
+
/** @internal */
|
4
|
+
export const promiseCache = /*#__PURE__*/ new LruMap<Promise<any>>(8192)
|
5
|
+
|
6
|
+
type WithDedupeOptions = {
|
7
|
+
enabled?: boolean | undefined
|
8
|
+
id?: string | undefined
|
9
|
+
}
|
10
|
+
|
11
|
+
/** Deduplicates in-flight promises. */
|
12
|
+
export function withDedupe<data>(
|
13
|
+
fn: () => Promise<data>,
|
14
|
+
{ enabled = true, id }: WithDedupeOptions,
|
15
|
+
): Promise<data> {
|
16
|
+
if (!enabled || !id) return fn()
|
17
|
+
if (promiseCache.get(id)) return promiseCache.get(id)!
|
18
|
+
const promise = fn().finally(() => promiseCache.delete(id))
|
19
|
+
promiseCache.set(id, promise)
|
20
|
+
return promise
|
21
|
+
}
|