@ledgerhq/coin-tezos 10.2.0 → 10.2.2

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 (79) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/lib/api/index.d.ts +1 -1
  3. package/lib/api/index.d.ts.map +1 -1
  4. package/lib/api/index.js +1 -1
  5. package/lib/api/index.js.map +1 -1
  6. package/lib/logic/craftRawOperations.js +26 -17
  7. package/lib/logic/craftRawOperations.js.map +1 -1
  8. package/lib/logic/estimateFees.js +4 -4
  9. package/lib/logic/estimateFees.js.map +1 -1
  10. package/lib/logic/listOperations.d.ts.map +1 -1
  11. package/lib/logic/listOperations.js +9 -7
  12. package/lib/logic/listOperations.js.map +1 -1
  13. package/lib/logic/validateIntent.d.ts.map +1 -1
  14. package/lib/logic/validateIntent.js +26 -8
  15. package/lib/logic/validateIntent.js.map +1 -1
  16. package/lib/network/tzkt.js +1 -1
  17. package/lib/network/tzkt.js.map +1 -1
  18. package/lib/test/config.d.ts +2 -22
  19. package/lib/test/config.d.ts.map +1 -1
  20. package/lib/test/config.js.map +1 -1
  21. package/lib/utils.d.ts +0 -3
  22. package/lib/utils.d.ts.map +1 -1
  23. package/lib/utils.js +17 -3
  24. package/lib/utils.js.map +1 -1
  25. package/lib-es/api/index.d.ts +1 -1
  26. package/lib-es/api/index.d.ts.map +1 -1
  27. package/lib-es/api/index.js +1 -1
  28. package/lib-es/api/index.js.map +1 -1
  29. package/lib-es/logic/craftRawOperations.js +26 -17
  30. package/lib-es/logic/craftRawOperations.js.map +1 -1
  31. package/lib-es/logic/estimateFees.js +4 -4
  32. package/lib-es/logic/estimateFees.js.map +1 -1
  33. package/lib-es/logic/listOperations.d.ts.map +1 -1
  34. package/lib-es/logic/listOperations.js +9 -7
  35. package/lib-es/logic/listOperations.js.map +1 -1
  36. package/lib-es/logic/validateIntent.d.ts.map +1 -1
  37. package/lib-es/logic/validateIntent.js +27 -9
  38. package/lib-es/logic/validateIntent.js.map +1 -1
  39. package/lib-es/network/tzkt.js +1 -1
  40. package/lib-es/network/tzkt.js.map +1 -1
  41. package/lib-es/test/config.d.ts +2 -22
  42. package/lib-es/test/config.d.ts.map +1 -1
  43. package/lib-es/test/config.js.map +1 -1
  44. package/lib-es/utils.d.ts +0 -3
  45. package/lib-es/utils.d.ts.map +1 -1
  46. package/lib-es/utils.js +17 -3
  47. package/lib-es/utils.js.map +1 -1
  48. package/package.json +2 -2
  49. package/src/api/index-mainnet.integ.test.ts +40 -50
  50. package/src/api/index.integ.test.ts +60 -45
  51. package/src/api/index.test.ts +229 -180
  52. package/src/api/index.ts +5 -4
  53. package/src/logic/broadcast.integ.test.ts +2 -7
  54. package/src/logic/craftRawOperations.test.ts +11 -10
  55. package/src/logic/craftRawOperations.ts +35 -19
  56. package/src/logic/craftTransaction.integ.test.ts +2 -2
  57. package/src/logic/craftTransaction.test.ts +63 -95
  58. package/src/logic/estimateFees.integ.test.ts +19 -20
  59. package/src/logic/estimateFees.test.ts +30 -63
  60. package/src/logic/estimateFees.ts +4 -4
  61. package/src/logic/getBalance.test.ts +6 -6
  62. package/src/logic/getBlock.integ.test.ts +20 -21
  63. package/src/logic/getBlock.test.ts +44 -51
  64. package/src/logic/getBlockInfo.integ.test.ts +13 -14
  65. package/src/logic/getBlockInfo.test.ts +8 -7
  66. package/src/logic/getStakes.test.ts +17 -17
  67. package/src/logic/listOperations.integ.test.ts +40 -37
  68. package/src/logic/listOperations.test.ts +34 -31
  69. package/src/logic/listOperations.ts +19 -19
  70. package/src/logic/validateIntent.test.ts +145 -20
  71. package/src/logic/validateIntent.ts +32 -8
  72. package/src/network/bakers.integ.test.ts +1 -1
  73. package/src/network/bakers.test.ts +7 -15
  74. package/src/network/tzkt.integ.test.ts +13 -14
  75. package/src/network/tzkt.test.ts +194 -259
  76. package/src/network/tzkt.ts +1 -1
  77. package/src/test/config.ts +3 -1
  78. package/src/utils.ts +18 -3
  79. package/.oxlintrc.json +0 -20
@@ -1,7 +1,8 @@
1
1
  // SPDX-FileCopyrightText: © 2026 LEDGER SAS
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import type { TezosCoinConfig, TezosContext } from '../config'
4
+ import type { TezosContext } from '../config'
5
+ import { mockConfig } from '../test/config'
5
6
  import { getBlockInfo } from './getBlockInfo'
6
7
 
7
8
  const mockGetBlockByLevel = jest.fn()
@@ -12,7 +13,7 @@ jest.mock('../network', () => ({
12
13
  }))
13
14
 
14
15
  const context: TezosContext = {
15
- config: async () => ({}) as unknown as TezosCoinConfig,
16
+ config: async () => mockConfig,
16
17
  logger: () => undefined,
17
18
  }
18
19
 
@@ -28,12 +29,12 @@ describe('getBlockInfo', () => {
28
29
  level,
29
30
  hash: 'BLockHashABC123',
30
31
  timestamp: '2024-06-15T10:30:00Z',
31
- } as any)
32
+ })
32
33
  mockGetBlockByLevel.mockResolvedValueOnce({
33
34
  level: level - 1,
34
35
  hash: 'BLockHashParent',
35
36
  timestamp: '2024-06-15T10:29:52Z',
36
- } as any)
37
+ })
37
38
 
38
39
  // When
39
40
  const result = await getBlockInfo(context, level)
@@ -57,7 +58,7 @@ describe('getBlockInfo', () => {
57
58
  level: 8_000_000,
58
59
  hash: 'BLockHashXYZ',
59
60
  timestamp: isoDate,
60
- } as any)
61
+ })
61
62
 
62
63
  // When
63
64
  const result = await getBlockInfo(context, 8_000_000)
@@ -99,12 +100,12 @@ describe('getBlockInfo', () => {
99
100
  level: 1,
100
101
  hash: 'BLBlock1',
101
102
  timestamp: '2018-06-30T16:07:40Z',
102
- } as any)
103
+ })
103
104
  mockGetBlockByLevel.mockResolvedValueOnce({
104
105
  level: 0,
105
106
  hash: 'BLGenesis',
106
107
  timestamp: '2018-06-30T16:07:32Z',
107
- } as any)
108
+ })
108
109
 
109
110
  // When
110
111
  const result = await getBlockInfo(context, 1)
@@ -1,7 +1,8 @@
1
1
  // SPDX-FileCopyrightText: © 2026 LEDGER SAS
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import type { TezosCoinConfig, TezosContext } from '../config'
4
+ import type { TezosContext } from '../config'
5
+ import type { APIUnstakeRequest } from '../network/types'
5
6
  import { getStakes } from './getStakes'
6
7
 
7
8
  const mockGetAccountByAddress = jest.fn()
@@ -16,20 +17,19 @@ jest.mock('../network/tzkt', () => ({
16
17
 
17
18
  describe('getStakes', () => {
18
19
  const context: TezosContext = {
19
- config: async () =>
20
- ({
21
- status: { type: 'active' },
22
- baker: { url: 'http://baker.example.com' },
23
- explorer: { url: 'http://tezos.explorer.com', maxTxQuery: 100 },
24
- node: { url: 'http://tezos.node.com' },
25
- fees: {
26
- minGasLimit: 600,
27
- minRevealGasLimit: 300,
28
- minStorageLimit: 0,
29
- minFees: 500,
30
- minEstimatedFees: 500,
31
- },
32
- }) as unknown as TezosCoinConfig,
20
+ config: async () => ({
21
+ status: { type: 'active' },
22
+ baker: { url: 'http://baker.example.com' },
23
+ explorer: { url: 'http://tezos.explorer.com', maxTxQuery: 100 },
24
+ node: { url: 'http://tezos.node.com' },
25
+ fees: {
26
+ minGasLimit: 600,
27
+ minRevealGasLimit: 300,
28
+ minStorageLimit: 0,
29
+ minFees: 500,
30
+ minEstimatedFees: 500,
31
+ },
32
+ }),
33
33
  logger: () => undefined,
34
34
  }
35
35
 
@@ -43,13 +43,13 @@ describe('getStakes', () => {
43
43
  status: 'pending' | 'finalizable' | 'finalized'
44
44
  actualAmount: number
45
45
  }>
46
- ) => ({
46
+ ): APIUnstakeRequest => ({
47
47
  id: overrides.id ?? 1,
48
48
  cycle: overrides.cycle ?? 100,
49
49
  baker: { address: overrides.bakerAddress ?? 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx' },
50
50
  staker: { address: overrides.stakerAddress ?? 'tz1TzrmTBSuiVHV2VfMnGRMYvTEPCP42oSM8' },
51
51
  firstTime: overrides.firstTime ?? '2026-05-01T00:00:00Z',
52
- status: overrides.status ?? ('pending' as const),
52
+ status: overrides.status ?? 'pending',
53
53
  actualAmount: overrides.actualAmount ?? 10,
54
54
  })
55
55
 
@@ -18,20 +18,19 @@ const USDT_FA2_CONTRACT = 'KT1XnTn74bUtxHfDtBmm2bGZAQfhPbvKWR8o'
18
18
  const USDT_FA2_ASSET_REF = `${USDT_FA2_CONTRACT}:0`
19
19
  const KT1_ASSET_REF_PATTERN = /^KT1[1-9A-HJ-NP-Za-km-z]+:\d+$/
20
20
 
21
- const mainnetConfig = (): TezosCoinConfig =>
22
- ({
23
- status: { type: 'active' },
24
- baker: { url: 'https://tezos-bakers.api.live.ledger.com' },
25
- explorer: { url: 'https://xtz-tzkt-explorer.api.vault.ledger.com', maxTxQuery: 100 },
26
- node: { url: 'https://xtz-node.api.live.ledger.com' },
27
- fees: {
28
- minGasLimit: 0,
29
- minRevealGasLimit: 0,
30
- minStorageLimit: 0,
31
- minFees: 0,
32
- minEstimatedFees: 0,
33
- },
34
- }) as TezosCoinConfig
21
+ const mainnetConfig = (): TezosCoinConfig => ({
22
+ status: { type: 'active' },
23
+ baker: { url: 'https://tezos-bakers.api.live.ledger.com' },
24
+ explorer: { url: 'https://xtz-tzkt-explorer.api.vault.ledger.com', maxTxQuery: 100 },
25
+ node: { url: 'https://xtz-node.api.live.ledger.com' },
26
+ fees: {
27
+ minGasLimit: 0,
28
+ minRevealGasLimit: 0,
29
+ minStorageLimit: 0,
30
+ minFees: 0,
31
+ minEstimatedFees: 0,
32
+ },
33
+ })
35
34
 
36
35
  const baseOpts = { sort: 'Descending' as const, minHeight: 0 }
37
36
 
@@ -212,20 +211,19 @@ describe('listOperations — mainnet FA2 / convertTokenOperation', () => {
212
211
  const SHADOWNET_STAKER = 'tz1dKrT1h6d7wP8fEzMPptG6er7mLLeQjBBY'
213
212
  const SHADOWNET_BAKER = 'tz3Q67aMz7gSMiQRcW729sXSfuMtkyAHYfqc'
214
213
 
215
- const shadownetConfig = (): TezosCoinConfig =>
216
- ({
217
- status: { type: 'active' },
218
- baker: { url: 'https://tezos-bakers.api.live.ledger.com' },
219
- explorer: { url: 'https://api.shadownet.tzkt.io', maxTxQuery: 100 },
220
- node: { url: 'https://rpc.shadownet.teztnets.com' },
221
- fees: {
222
- minGasLimit: 0,
223
- minRevealGasLimit: 0,
224
- minStorageLimit: 0,
225
- minFees: 0,
226
- minEstimatedFees: 0,
227
- },
228
- }) as TezosCoinConfig
214
+ const shadownetConfig = (): TezosCoinConfig => ({
215
+ status: { type: 'active' },
216
+ baker: { url: 'https://tezos-bakers.api.live.ledger.com' },
217
+ explorer: { url: 'https://api.shadownet.tzkt.io', maxTxQuery: 100 },
218
+ node: { url: 'https://rpc.shadownet.teztnets.com' },
219
+ fees: {
220
+ minGasLimit: 0,
221
+ minRevealGasLimit: 0,
222
+ minStorageLimit: 0,
223
+ minFees: 0,
224
+ minEstimatedFees: 0,
225
+ },
226
+ })
229
227
 
230
228
  // To refresh: TzKT `/v1/operations/staking?sender=…` + `/v1/blocks/{level}`.
231
229
  const EXPECTED_STAKE = {
@@ -405,10 +403,15 @@ describe('listOperations — mainnet origination ops', () => {
405
403
 
406
404
  /**
407
405
  * Multi-asset FA2 integration tests (LIVE-29210).
408
- * Uses tz1ZB8hpQJZdQeEPc3uG2cL1NXwLTPkqeAD6 which holds multiple tokens
409
- * on the Wrapped Tokens Contract (KT18fp5rcTW7mbWDmzFwjLDUhs5MeJmagDSZ).
406
+ * Uses tz1d1cPC6pmpM95xB2kcmKvscrsRkuWfKhpH, a dormant account (last activity
407
+ * 2025-04-20, ~150 native ops total) that received multiple tokens on the
408
+ * Wrapped Tokens Contract (KT18fp5rcTW7mbWDmzFwjLDUhs5MeJmagDSZ). Because the
409
+ * account is inactive, its full history always fits within a single `limit`
410
+ * page, so the fixture won't drift out of range as mainnet moves forward
411
+ * (unlike the previous fixture, an actively-trading address whose older
412
+ * transfers eventually fell outside the fetch window).
410
413
  */
411
- const MULTI_ASSET_ADDRESS = 'tz1ZB8hpQJZdQeEPc3uG2cL1NXwLTPkqeAD6'
414
+ const MULTI_ASSET_ADDRESS = 'tz1d1cPC6pmpM95xB2kcmKvscrsRkuWfKhpH'
412
415
  const WRAPPED_CONTRACT = 'KT18fp5rcTW7mbWDmzFwjLDUhs5MeJmagDSZ'
413
416
 
414
417
  describe('listOperations — mainnet multi-asset FA2 (LIVE-29210)', () => {
@@ -423,18 +426,18 @@ describe('listOperations — mainnet multi-asset FA2 (LIVE-29210)', () => {
423
426
  limit: 200,
424
427
  })
425
428
 
426
- // Known on-chain transfer: tokenId=11 (wMATIC), OUT to KT1V5X...
429
+ // Known on-chain transfer: tokenId=11 (wMATIC), IN from 3Route v4 (KT1V5X...)
427
430
  const op = operations.find(
428
431
  (op) =>
429
432
  'assetReference' in op.asset &&
430
433
  op.asset.assetReference === `${WRAPPED_CONTRACT}:11` &&
431
- op.tx.hash === 'ooMtaw5H7dtrgAyW5ky4jFzhQjayWn6La2h3BadHvZd56p6jm9g'
434
+ op.tx.hash === 'ooxJAJuEmPsJBS4DWBWAku3NLfqk6JJJAjdWHPC9Po8M9nF9CVz'
432
435
  )!
433
436
 
434
- expect(op.type).toBe('OUT')
437
+ expect(op.type).toBe('IN')
435
438
  expect(op.asset.type).toBe('fa2')
436
- expect(op.value).toBe(18423705864886566n)
437
- expect(op.senders).toEqual([MULTI_ASSET_ADDRESS])
438
- expect(op.recipients).toEqual(['KT1V5XKmeypanMS9pR65REpqmVejWBZURuuT'])
439
+ expect(op.value).toBe(150017147151179206n)
440
+ expect(op.senders).toEqual(['KT1V5XKmeypanMS9pR65REpqmVejWBZURuuT'])
441
+ expect(op.recipients).toEqual([MULTI_ASSET_ADDRESS])
439
442
  })
440
443
  })
@@ -1,15 +1,15 @@
1
1
  // SPDX-FileCopyrightText: © 2026 LEDGER SAS
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import type { TezosCoinConfig, TezosContext } from '../config'
4
+ import type { TezosContext } from '../config'
5
5
  import type {
6
- APIBlock,
7
6
  APIDelegationType,
8
7
  APIRevealType,
9
8
  APIStakingType,
10
9
  APITokenTransfer,
11
10
  APITransactionType,
12
11
  } from '../network/types'
12
+ import { mockConfig } from '../test/config'
13
13
  import { listOperations } from './listOperations'
14
14
 
15
15
  const mockGetAccountOperations = jest.fn()
@@ -27,7 +27,7 @@ jest.mock('../network', () => ({
27
27
  }))
28
28
 
29
29
  const context: TezosContext = {
30
- config: async () => ({}) as unknown as TezosCoinConfig,
30
+ config: async () => mockConfig,
31
31
  logger: () => undefined,
32
32
  }
33
33
 
@@ -496,7 +496,7 @@ describe('listOperations', () => {
496
496
  transactionId: transfer.id,
497
497
  hash: someHash,
498
498
  }
499
- const appliedTransfer = { ...transfer, status: 'applied' as const, level: 100 }
499
+ const appliedTransfer: APITransactionType = { ...transfer, status: 'applied', level: 100 }
500
500
  mockGetAccountOperations.mockResolvedValue([appliedTransfer])
501
501
  mockGetAccountTokenTransfers.mockResolvedValue([fa2])
502
502
  const [results, next] = await listOperations(context, someDestinationAddress, {
@@ -561,9 +561,9 @@ describe('listOperations', () => {
561
561
  hash: someHash,
562
562
  block: 'BLK_FROM_TRANSFER',
563
563
  }
564
- const appliedTransfer = {
564
+ const appliedTransfer: APITransactionType = {
565
565
  ...transfer,
566
- status: 'applied' as const,
566
+ status: 'applied',
567
567
  block: 'BLK_FROM_PARENT',
568
568
  }
569
569
  mockGetAccountOperations.mockResolvedValue([appliedTransfer])
@@ -680,7 +680,8 @@ describe('listOperations', () => {
680
680
  transactionId: transfer.id,
681
681
  hash: 'ooTokenOutHash',
682
682
  }
683
- mockGetAccountOperations.mockResolvedValue([{ ...transfer, status: 'applied' as const }])
683
+ const appliedTransfer: APITransactionType = { ...transfer, status: 'applied' }
684
+ mockGetAccountOperations.mockResolvedValue([appliedTransfer])
684
685
  mockGetAccountTokenTransfers.mockResolvedValue([fa2Out])
685
686
  const [results] = await listOperations(context, someSenderAddress, options)
686
687
  const tokenOut = results.find((o) => o.asset.type === 'fa2')
@@ -767,13 +768,13 @@ describe('listOperations', () => {
767
768
  ...transfer,
768
769
  id: 80010,
769
770
  level: 2000,
770
- status: 'applied' as const,
771
+ status: 'applied',
771
772
  }
772
773
  const opLow: APITransactionType = {
773
774
  ...transfer,
774
775
  id: 80011,
775
776
  level: 1999,
776
- status: 'applied' as const,
777
+ status: 'applied',
777
778
  }
778
779
  mockGetAccountOperations.mockResolvedValue([opHigh, opLow])
779
780
  mockGetAccountTokenTransfers.mockResolvedValue([])
@@ -787,8 +788,8 @@ describe('listOperations', () => {
787
788
  })
788
789
 
789
790
  it('emits nativeLastId on full single-level native page and forwards lastId on next request', async () => {
790
- const op1 = { ...transfer, id: 900_001, level: 5000, status: 'applied' as const }
791
- const op2 = { ...transfer, id: 900_002, level: 5000, status: 'applied' as const }
791
+ const op1: APITransactionType = { ...transfer, id: 900_001, level: 5000, status: 'applied' }
792
+ const op2: APITransactionType = { ...transfer, id: 900_002, level: 5000, status: 'applied' }
792
793
  mockGetAccountOperations.mockResolvedValueOnce([op1, op2]).mockResolvedValueOnce([])
793
794
  mockGetAccountTokenTransfers.mockResolvedValue([])
794
795
 
@@ -885,13 +886,13 @@ describe('listOperations', () => {
885
886
  ...transfer,
886
887
  id: 80020,
887
888
  level: 1000,
888
- status: 'applied' as const,
889
+ status: 'applied',
889
890
  }
890
891
  const opOlder: APITransactionType = {
891
892
  ...transfer,
892
893
  id: 80021,
893
894
  level: 500,
894
- status: 'applied' as const,
895
+ status: 'applied',
895
896
  }
896
897
  const fa2At1000: APITokenTransfer & { hash: string } = {
897
898
  id: 80030,
@@ -934,13 +935,13 @@ describe('listOperations', () => {
934
935
  ...transfer,
935
936
  id: 70_001,
936
937
  level: 500,
937
- status: 'applied' as const,
938
+ status: 'applied',
938
939
  }
939
940
  const nativeOp2: APITransactionType = {
940
941
  ...transfer,
941
942
  id: 70_002,
942
943
  level: 600,
943
- status: 'applied' as const,
944
+ status: 'applied',
944
945
  }
945
946
  const tokenAtLowLevel: APITokenTransfer & { hash: string } = {
946
947
  id: 71_001,
@@ -1030,7 +1031,7 @@ describe('listOperations', () => {
1030
1031
  ...transfer,
1031
1032
  id: 73_001,
1032
1033
  level: 2000,
1033
- status: 'applied' as const,
1034
+ status: 'applied',
1034
1035
  }
1035
1036
  const fa2Low: APITokenTransfer & { hash: string } = {
1036
1037
  id: 73_002,
@@ -1189,13 +1190,14 @@ describe('listOperations', () => {
1189
1190
  })
1190
1191
 
1191
1192
  it('falls back to requestedAmount when amount is missing on a failed staking op', async () => {
1192
- const op = {
1193
- ...makeStaking('stake', 0),
1194
- status: 'failed',
1195
- amount: undefined,
1196
- requestedAmount: 500_000_000,
1197
- } as unknown as APIStakingType
1198
- mockGetAccountOperations.mockResolvedValue([op])
1193
+ mockGetAccountOperations.mockResolvedValue([
1194
+ {
1195
+ ...makeStaking('stake', 0),
1196
+ status: 'failed',
1197
+ amount: undefined,
1198
+ requestedAmount: 500_000_000,
1199
+ },
1200
+ ])
1199
1201
 
1200
1202
  const [results] = await listOperations(context, stakerAddress, options)
1201
1203
 
@@ -1204,13 +1206,14 @@ describe('listOperations', () => {
1204
1206
  })
1205
1207
 
1206
1208
  it('returns 0 when both amount and requestedAmount are missing on a staking op', async () => {
1207
- const op = {
1208
- ...makeStaking('stake', 0),
1209
- status: 'failed',
1210
- amount: undefined,
1211
- requestedAmount: undefined,
1212
- } as unknown as APIStakingType
1213
- mockGetAccountOperations.mockResolvedValue([op])
1209
+ mockGetAccountOperations.mockResolvedValue([
1210
+ {
1211
+ ...makeStaking('stake', 0),
1212
+ status: 'failed',
1213
+ amount: undefined,
1214
+ requestedAmount: undefined,
1215
+ },
1216
+ ])
1214
1217
 
1215
1218
  const [results] = await listOperations(context, stakerAddress, options)
1216
1219
 
@@ -1263,7 +1266,7 @@ describe('listOperations', () => {
1263
1266
  level: 3106307,
1264
1267
  hash: 'BLMaHTGtBfh7ZM2wk5rpFHQhNtx5LC7YMdYrnokzBcosrpgqNAe',
1265
1268
  timestamp: '2026-04-28T20:54:09Z',
1266
- } as unknown as APIBlock
1269
+ }
1267
1270
  const stakeWithObjectBlock = {
1268
1271
  ...makeStaking('stake', 100),
1269
1272
  block: inlineBlock,
@@ -3,24 +3,26 @@
3
3
 
4
4
  import type { TezosCoinConfig, TezosContext } from '../config'
5
5
  import type { AccountsGetOperationsOptions } from '../network/types'
6
+ import type {
7
+ APIDelegationType,
8
+ APIOperation,
9
+ APIOriginationType,
10
+ APIRevealType,
11
+ APIStakingType,
12
+ APITokenTransfer,
13
+ APITransactionType,
14
+ TokenTransfersGetOptions,
15
+ } from '../network/types'
6
16
  import type { Operation } from '@ledgerhq/coin-module-framework/api/types'
7
17
  import { log } from '@ledgerhq/logs'
8
18
  import { STAKING_ACTION_TO_OP_TYPE } from '../constants'
9
19
  import { createTzktApi } from '../network'
10
20
  import {
11
- type APIDelegationType,
12
- type APIOperation,
13
- type APIOriginationType,
14
- type APIRevealType,
15
- type APIStakingType,
16
- type APITokenTransfer,
17
- type APITransactionType,
18
21
  isAPIDelegationType,
19
22
  isAPIOriginationType,
20
23
  isAPIRevealType,
21
24
  isAPIStakingType,
22
25
  isAPITransactionType,
23
- type TokenTransfersGetOptions,
24
26
  } from '../network/types'
25
27
 
26
28
  /** Block-level boundary + optional per-stream id cursors for intra-level continuation. */
@@ -35,18 +37,16 @@ function parseCursor(token?: string): ListOperationsCursor | undefined {
35
37
  try {
36
38
  const parsed: unknown = JSON.parse(token)
37
39
  if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
38
- const o = parsed as {
39
- lastLevel?: unknown
40
- nativeLastId?: unknown
41
- tokenLastId?: unknown
42
- }
43
- if (typeof o.lastLevel === 'number' && Number.isFinite(o.lastLevel)) {
44
- const cursor: ListOperationsCursor = { lastLevel: o.lastLevel }
45
- if (typeof o.nativeLastId === 'number' && Number.isFinite(o.nativeLastId)) {
46
- cursor.nativeLastId = o.nativeLastId
40
+ const lastLevel = 'lastLevel' in parsed ? parsed.lastLevel : undefined
41
+ const nativeLastId = 'nativeLastId' in parsed ? parsed.nativeLastId : undefined
42
+ const tokenLastId = 'tokenLastId' in parsed ? parsed.tokenLastId : undefined
43
+ if (typeof lastLevel === 'number' && Number.isFinite(lastLevel)) {
44
+ const cursor: ListOperationsCursor = { lastLevel }
45
+ if (typeof nativeLastId === 'number' && Number.isFinite(nativeLastId)) {
46
+ cursor.nativeLastId = nativeLastId
47
47
  }
48
- if (typeof o.tokenLastId === 'number' && Number.isFinite(o.tokenLastId)) {
49
- cursor.tokenLastId = o.tokenLastId
48
+ if (typeof tokenLastId === 'number' && Number.isFinite(tokenLastId)) {
49
+ cursor.tokenLastId = tokenLastId
50
50
  }
51
51
  return cursor
52
52
  }