@exodus/ethereum-api 8.72.0 → 8.73.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 CHANGED
@@ -3,6 +3,16 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [8.73.0](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-api@8.72.0...@exodus/ethereum-api@8.73.0) (2026-05-01)
7
+
8
+
9
+ ### Features
10
+
11
+
12
+ * feat: Faster Security Hydration Across Monitor (#7824)
13
+
14
+
15
+
6
16
  ## [8.72.0](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-api@8.71.3...@exodus/ethereum-api@8.72.0) (2026-04-30)
7
17
 
8
18
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/ethereum-api",
3
- "version": "8.72.0",
3
+ "version": "8.73.0",
4
4
  "description": "Transaction monitors, fee monitors, RPC with the blockchain node, and other networking code for Ethereum and EVM-based blockchains",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -68,5 +68,5 @@
68
68
  "type": "git",
69
69
  "url": "git+https://github.com/ExodusMovement/assets.git"
70
70
  },
71
- "gitHead": "87bf2c314792d465c10789267316e74d7a19301a"
71
+ "gitHead": "d17ee07f3f8bf4cc67518f8a8395522578e8dae1"
72
72
  }
@@ -163,6 +163,23 @@ export class ClarityMonitorV2 extends BaseMonitor {
163
163
  return { txsToRemove }
164
164
  }
165
165
 
166
+ async persistSecurityState({ walletAccount, accountState, isBlacklisted, eip7702Delegation }) {
167
+ const securityStatePatch = {
168
+ ...(isBlacklisted !== undefined && { isBlacklisted }),
169
+ ...(eip7702Delegation !== undefined && { eip7702Delegation }),
170
+ }
171
+
172
+ if (isEmpty(securityStatePatch)) {
173
+ return
174
+ }
175
+
176
+ await this.updateAccountState({
177
+ walletAccount,
178
+ accountState,
179
+ newData: securityStatePatch,
180
+ })
181
+ }
182
+
166
183
  async tick({ walletAccount, refresh }) {
167
184
  await this.subscribeWalletAddresses(walletAccount)
168
185
 
@@ -173,17 +190,26 @@ export class ClarityMonitorV2 extends BaseMonitor {
173
190
  }
174
191
 
175
192
  const { derivedData, tokensByAddress, assets, tokens, assetName } = walletAccountInfo
176
- const { accountState, eip7702Delegation, isBlacklisted } = await this.getStateUpdate({
193
+ const { eip7702Delegation, isBlacklisted } = await this.getSecurityAccountState({
177
194
  derivedData,
178
- tokens,
179
195
  walletAccount,
180
196
  })
197
+
198
+ await this.persistSecurityState({
199
+ walletAccount,
200
+ accountState: derivedData.currentAccountState,
201
+ isBlacklisted,
202
+ eip7702Delegation,
203
+ })
204
+
205
+ const accountState = await this.getNewAccountState({
206
+ tokens,
207
+ currentTokenBalances: derivedData.currentAccountState?.tokenBalances,
208
+ ourWalletAddress: derivedData.ourWalletAddress,
209
+ })
210
+
181
211
  const batch = this.aci.createOperationsBatch()
182
- const newData = {
183
- ...accountState,
184
- ...(isBlacklisted !== undefined && { isBlacklisted }),
185
- ...(eip7702Delegation !== undefined && { eip7702Delegation }),
186
- }
212
+ const newData = { ...accountState }
187
213
  let allTxs = []
188
214
  let hasNewTxs = false
189
215
  let historyError
@@ -285,6 +311,24 @@ export class ClarityMonitorV2 extends BaseMonitor {
285
311
  }) {
286
312
  const hasNewTxs = allTxs.length > 0
287
313
 
314
+ const { eip7702Delegation, isBlacklisted } = await this.getSecurityAccountState({
315
+ derivedData,
316
+ walletAccount,
317
+ })
318
+
319
+ await this.persistSecurityState({
320
+ walletAccount,
321
+ accountState: derivedData.currentAccountState,
322
+ isBlacklisted,
323
+ eip7702Delegation,
324
+ })
325
+
326
+ const accountState = await this.getNewAccountState({
327
+ tokens,
328
+ currentTokenBalances: derivedData.currentAccountState?.tokenBalances,
329
+ ourWalletAddress: derivedData.ourWalletAddress,
330
+ })
331
+
288
332
  const logItemsByAsset = this.getAllLogItemsByAsset({
289
333
  getLogItemsFromServerTx,
290
334
  ourWalletAddress: derivedData.ourWalletAddress,
@@ -303,12 +347,6 @@ export class ClarityMonitorV2 extends BaseMonitor {
303
347
  ...derivedData,
304
348
  })
305
349
 
306
- const { accountState, eip7702Delegation, isBlacklisted } = await this.getStateUpdate({
307
- derivedData,
308
- tokens,
309
- walletAccount,
310
- })
311
-
312
350
  const batch = this.aci.createOperationsBatch()
313
351
 
314
352
  this.aci.removeTxLogBatch({
@@ -329,11 +367,7 @@ export class ClarityMonitorV2 extends BaseMonitor {
329
367
  }
330
368
 
331
369
  // All updates must go through newData (accountState param is only used for mem merging)
332
- const newData = {
333
- ...accountState,
334
- ...(isBlacklisted !== undefined && { isBlacklisted }),
335
- ...(eip7702Delegation !== undefined && { eip7702Delegation }),
336
- }
370
+ const newData = { ...accountState }
337
371
 
338
372
  if (cursor) {
339
373
  newData.clarityCursor = cursor
@@ -360,14 +394,8 @@ export class ClarityMonitorV2 extends BaseMonitor {
360
394
  }
361
395
  }
362
396
 
363
- async getStateUpdate({ derivedData, tokens, walletAccount }) {
397
+ async getSecurityAccountState({ derivedData, walletAccount }) {
364
398
  const shouldCheckBlacklist = this.tickCount[walletAccount] === 0
365
- const accountState = await this.getNewAccountState({
366
- tokens,
367
- currentTokenBalances: derivedData.currentAccountState?.tokenBalances,
368
- ourWalletAddress: derivedData.ourWalletAddress,
369
- })
370
-
371
399
  const eip7702Delegation = await getCurrentEIP7702Delegation({
372
400
  server: this.server,
373
401
  address: derivedData.ourWalletAddress,
@@ -384,7 +412,7 @@ export class ClarityMonitorV2 extends BaseMonitor {
384
412
  })
385
413
  : undefined
386
414
 
387
- return { accountState, eip7702Delegation, isBlacklisted }
415
+ return { eip7702Delegation, isBlacklisted }
388
416
  }
389
417
 
390
418
  async addSingleTx({ tx, address, cursor }) {
@@ -151,6 +151,23 @@ export class ClarityMonitor extends BaseMonitor {
151
151
  return { txsToRemove }
152
152
  }
153
153
 
154
+ async persistSecurityState({ walletAccount, accountState, isBlacklisted, eip7702Delegation }) {
155
+ const securityStatePatch = {
156
+ ...(isBlacklisted !== undefined && { isBlacklisted }),
157
+ ...(eip7702Delegation !== undefined && { eip7702Delegation }),
158
+ }
159
+
160
+ if (isEmpty(securityStatePatch)) {
161
+ return
162
+ }
163
+
164
+ await this.updateAccountState({
165
+ walletAccount,
166
+ accountState,
167
+ newData: securityStatePatch,
168
+ })
169
+ }
170
+
154
171
  async tick({ walletAccount, refresh }) {
155
172
  await this.subscribeWalletAddresses()
156
173
  const tickCount = this.tickCount[walletAccount]
@@ -165,18 +182,26 @@ export class ClarityMonitor extends BaseMonitor {
165
182
  }, new Map())
166
183
  const assetName = this.asset.name
167
184
  const derivedData = await this.deriveData({ assetName, walletAccount, tokens })
168
- const { accountState, eip7702Delegation, isBlacklisted } = await this.getStateUpdate({
185
+ const { eip7702Delegation, isBlacklisted } = await this.getSecurityAccountState({
169
186
  derivedData,
170
- tokens,
171
187
  shouldCheckBlacklist,
172
188
  })
173
189
 
190
+ await this.persistSecurityState({
191
+ walletAccount,
192
+ accountState: derivedData.currentAccountState,
193
+ isBlacklisted,
194
+ eip7702Delegation,
195
+ })
196
+
197
+ const accountState = await this.getNewAccountState({
198
+ tokens,
199
+ currentTokenBalances: derivedData.currentAccountState?.tokenBalances,
200
+ ourWalletAddress: derivedData.ourWalletAddress,
201
+ })
202
+
174
203
  const batch = this.aci.createOperationsBatch()
175
- const newData = {
176
- ...accountState,
177
- ...(isBlacklisted !== undefined && { isBlacklisted }),
178
- ...(eip7702Delegation !== undefined && { eip7702Delegation }),
179
- }
204
+ const newData = { ...accountState }
180
205
  let allTxs = []
181
206
  let hasNewTxs = false
182
207
  let historyError
@@ -265,13 +290,7 @@ export class ClarityMonitor extends BaseMonitor {
265
290
  }
266
291
  }
267
292
 
268
- async getStateUpdate({ derivedData, tokens, shouldCheckBlacklist }) {
269
- const accountState = await this.getNewAccountState({
270
- tokens,
271
- currentTokenBalances: derivedData.currentAccountState?.tokenBalances,
272
- ourWalletAddress: derivedData.ourWalletAddress,
273
- })
274
-
293
+ async getSecurityAccountState({ derivedData, shouldCheckBlacklist }) {
275
294
  const eip7702Delegation = await getCurrentEIP7702Delegation({
276
295
  server: this.server,
277
296
  address: derivedData.ourWalletAddress,
@@ -289,7 +308,7 @@ export class ClarityMonitor extends BaseMonitor {
289
308
  })
290
309
  : undefined
291
310
 
292
- return { accountState, eip7702Delegation, isBlacklisted }
311
+ return { eip7702Delegation, isBlacklisted }
293
312
  }
294
313
 
295
314
  async getNewAccountState({ tokens, currentTokenBalances, ourWalletAddress }) {