@ledgerhq/coin-tezos 7.12.0 → 8.0.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.
Files changed (189) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/lib/api/index.d.ts +1 -2
  3. package/lib/api/index.d.ts.map +1 -1
  4. package/lib/api/index.js +45 -44
  5. package/lib/api/index.js.map +1 -1
  6. package/lib/api/types.d.ts +3 -2
  7. package/lib/api/types.d.ts.map +1 -1
  8. package/lib/config.d.ts +3 -1
  9. package/lib/config.d.ts.map +1 -1
  10. package/lib/config.js.map +1 -1
  11. package/lib/logic/broadcast.d.ts +2 -1
  12. package/lib/logic/broadcast.d.ts.map +1 -1
  13. package/lib/logic/broadcast.js +3 -2
  14. package/lib/logic/broadcast.js.map +1 -1
  15. package/lib/logic/craftRawOperations.d.ts +2 -1
  16. package/lib/logic/craftRawOperations.d.ts.map +1 -1
  17. package/lib/logic/craftRawOperations.js +5 -8
  18. package/lib/logic/craftRawOperations.js.map +1 -1
  19. package/lib/logic/craftTransaction.d.ts +3 -2
  20. package/lib/logic/craftTransaction.d.ts.map +1 -1
  21. package/lib/logic/craftTransaction.js +6 -9
  22. package/lib/logic/craftTransaction.js.map +1 -1
  23. package/lib/logic/estimateFees.d.ts +2 -1
  24. package/lib/logic/estimateFees.d.ts.map +1 -1
  25. package/lib/logic/estimateFees.js +24 -19
  26. package/lib/logic/estimateFees.js.map +1 -1
  27. package/lib/logic/getBalance.d.ts +2 -1
  28. package/lib/logic/getBalance.d.ts.map +1 -1
  29. package/lib/logic/getBalance.js +7 -8
  30. package/lib/logic/getBalance.js.map +1 -1
  31. package/lib/logic/getBlock.d.ts +2 -1
  32. package/lib/logic/getBlock.d.ts.map +1 -1
  33. package/lib/logic/getBlock.js +12 -10
  34. package/lib/logic/getBlock.js.map +1 -1
  35. package/lib/logic/getBlockInfo.d.ts +2 -1
  36. package/lib/logic/getBlockInfo.d.ts.map +1 -1
  37. package/lib/logic/getBlockInfo.js +5 -3
  38. package/lib/logic/getBlockInfo.js.map +1 -1
  39. package/lib/logic/getStakes.d.ts +3 -2
  40. package/lib/logic/getStakes.d.ts.map +1 -1
  41. package/lib/logic/getStakes.js +9 -9
  42. package/lib/logic/getStakes.js.map +1 -1
  43. package/lib/logic/lastBlock.d.ts +2 -1
  44. package/lib/logic/lastBlock.d.ts.map +1 -1
  45. package/lib/logic/lastBlock.js +4 -6
  46. package/lib/logic/lastBlock.js.map +1 -1
  47. package/lib/logic/listOperations.d.ts +2 -1
  48. package/lib/logic/listOperations.d.ts.map +1 -1
  49. package/lib/logic/listOperations.js +8 -6
  50. package/lib/logic/listOperations.js.map +1 -1
  51. package/lib/logic/tezosToolkit.d.ts +2 -1
  52. package/lib/logic/tezosToolkit.d.ts.map +1 -1
  53. package/lib/logic/tezosToolkit.js +2 -6
  54. package/lib/logic/tezosToolkit.js.map +1 -1
  55. package/lib/logic/validateIntent.d.ts +2 -1
  56. package/lib/logic/validateIntent.d.ts.map +1 -1
  57. package/lib/logic/validateIntent.js +12 -13
  58. package/lib/logic/validateIntent.js.map +1 -1
  59. package/lib/network/bakers.d.ts +5 -4
  60. package/lib/network/bakers.d.ts.map +1 -1
  61. package/lib/network/bakers.js +9 -10
  62. package/lib/network/bakers.js.map +1 -1
  63. package/lib/network/index.d.ts +1 -1
  64. package/lib/network/index.d.ts.map +1 -1
  65. package/lib/network/index.js +2 -5
  66. package/lib/network/index.js.map +1 -1
  67. package/lib/network/tzkt.d.ts +16 -9
  68. package/lib/network/tzkt.d.ts.map +1 -1
  69. package/lib/network/tzkt.js +341 -333
  70. package/lib/network/tzkt.js.map +1 -1
  71. package/lib/utils.d.ts +2 -1
  72. package/lib/utils.d.ts.map +1 -1
  73. package/lib/utils.js +1 -6
  74. package/lib/utils.js.map +1 -1
  75. package/lib-es/api/index.d.ts +1 -2
  76. package/lib-es/api/index.d.ts.map +1 -1
  77. package/lib-es/api/index.js +40 -36
  78. package/lib-es/api/index.js.map +1 -1
  79. package/lib-es/api/types.d.ts +3 -2
  80. package/lib-es/api/types.d.ts.map +1 -1
  81. package/lib-es/config.d.ts +3 -1
  82. package/lib-es/config.d.ts.map +1 -1
  83. package/lib-es/config.js.map +1 -1
  84. package/lib-es/logic/broadcast.d.ts +2 -1
  85. package/lib-es/logic/broadcast.d.ts.map +1 -1
  86. package/lib-es/logic/broadcast.js +3 -2
  87. package/lib-es/logic/broadcast.js.map +1 -1
  88. package/lib-es/logic/craftRawOperations.d.ts +2 -1
  89. package/lib-es/logic/craftRawOperations.d.ts.map +1 -1
  90. package/lib-es/logic/craftRawOperations.js +5 -5
  91. package/lib-es/logic/craftRawOperations.js.map +1 -1
  92. package/lib-es/logic/craftTransaction.d.ts +3 -2
  93. package/lib-es/logic/craftTransaction.d.ts.map +1 -1
  94. package/lib-es/logic/craftTransaction.js +6 -6
  95. package/lib-es/logic/craftTransaction.js.map +1 -1
  96. package/lib-es/logic/estimateFees.d.ts +2 -1
  97. package/lib-es/logic/estimateFees.d.ts.map +1 -1
  98. package/lib-es/logic/estimateFees.js +24 -16
  99. package/lib-es/logic/estimateFees.js.map +1 -1
  100. package/lib-es/logic/getBalance.d.ts +2 -1
  101. package/lib-es/logic/getBalance.d.ts.map +1 -1
  102. package/lib-es/logic/getBalance.js +5 -3
  103. package/lib-es/logic/getBalance.js.map +1 -1
  104. package/lib-es/logic/getBlock.d.ts +2 -1
  105. package/lib-es/logic/getBlock.d.ts.map +1 -1
  106. package/lib-es/logic/getBlock.js +10 -8
  107. package/lib-es/logic/getBlock.js.map +1 -1
  108. package/lib-es/logic/getBlockInfo.d.ts +2 -1
  109. package/lib-es/logic/getBlockInfo.d.ts.map +1 -1
  110. package/lib-es/logic/getBlockInfo.js +4 -2
  111. package/lib-es/logic/getBlockInfo.js.map +1 -1
  112. package/lib-es/logic/getStakes.d.ts +3 -2
  113. package/lib-es/logic/getStakes.d.ts.map +1 -1
  114. package/lib-es/logic/getStakes.js +9 -6
  115. package/lib-es/logic/getStakes.js.map +1 -1
  116. package/lib-es/logic/lastBlock.d.ts +2 -1
  117. package/lib-es/logic/lastBlock.d.ts.map +1 -1
  118. package/lib-es/logic/lastBlock.js +4 -3
  119. package/lib-es/logic/lastBlock.js.map +1 -1
  120. package/lib-es/logic/listOperations.d.ts +2 -1
  121. package/lib-es/logic/listOperations.d.ts.map +1 -1
  122. package/lib-es/logic/listOperations.js +7 -5
  123. package/lib-es/logic/listOperations.js.map +1 -1
  124. package/lib-es/logic/tezosToolkit.d.ts +2 -1
  125. package/lib-es/logic/tezosToolkit.d.ts.map +1 -1
  126. package/lib-es/logic/tezosToolkit.js +2 -3
  127. package/lib-es/logic/tezosToolkit.js.map +1 -1
  128. package/lib-es/logic/validateIntent.d.ts +2 -1
  129. package/lib-es/logic/validateIntent.d.ts.map +1 -1
  130. package/lib-es/logic/validateIntent.js +10 -8
  131. package/lib-es/logic/validateIntent.js.map +1 -1
  132. package/lib-es/network/bakers.d.ts +5 -4
  133. package/lib-es/network/bakers.d.ts.map +1 -1
  134. package/lib-es/network/bakers.js +9 -10
  135. package/lib-es/network/bakers.js.map +1 -1
  136. package/lib-es/network/index.d.ts +1 -1
  137. package/lib-es/network/index.d.ts.map +1 -1
  138. package/lib-es/network/index.js +1 -1
  139. package/lib-es/network/index.js.map +1 -1
  140. package/lib-es/network/tzkt.d.ts +16 -9
  141. package/lib-es/network/tzkt.d.ts.map +1 -1
  142. package/lib-es/network/tzkt.js +340 -333
  143. package/lib-es/network/tzkt.js.map +1 -1
  144. package/lib-es/utils.d.ts +2 -1
  145. package/lib-es/utils.d.ts.map +1 -1
  146. package/lib-es/utils.js +1 -3
  147. package/lib-es/utils.js.map +1 -1
  148. package/package.json +2 -2
  149. package/src/api/index-mainnet.integ.test.ts +34 -30
  150. package/src/api/index.integ.test.ts +69 -53
  151. package/src/api/index.test.ts +99 -60
  152. package/src/api/index.ts +52 -36
  153. package/src/api/types.ts +3 -2
  154. package/src/config.ts +4 -1
  155. package/src/logic/broadcast.integ.test.ts +12 -13
  156. package/src/logic/broadcast.ts +4 -2
  157. package/src/logic/craftRawOperations.test.ts +47 -33
  158. package/src/logic/craftRawOperations.ts +6 -4
  159. package/src/logic/craftTransaction.integ.test.ts +12 -5
  160. package/src/logic/craftTransaction.test.ts +39 -31
  161. package/src/logic/craftTransaction.ts +10 -5
  162. package/src/logic/estimateFees.integ.test.ts +7 -7
  163. package/src/logic/estimateFees.test.ts +52 -49
  164. package/src/logic/estimateFees.ts +34 -22
  165. package/src/logic/getBalance.test.ts +19 -17
  166. package/src/logic/getBalance.ts +6 -3
  167. package/src/logic/getBlock.integ.test.ts +8 -30
  168. package/src/logic/getBlock.test.ts +91 -81
  169. package/src/logic/getBlock.ts +11 -8
  170. package/src/logic/getBlockInfo.integ.test.ts +9 -18
  171. package/src/logic/getBlockInfo.test.ts +19 -9
  172. package/src/logic/getBlockInfo.ts +5 -2
  173. package/src/logic/getStakes.test.ts +46 -49
  174. package/src/logic/getStakes.ts +14 -5
  175. package/src/logic/lastBlock.ts +5 -3
  176. package/src/logic/listOperations.integ.test.ts +40 -67
  177. package/src/logic/listOperations.test.ts +65 -59
  178. package/src/logic/listOperations.ts +8 -3
  179. package/src/logic/tezosToolkit.ts +3 -3
  180. package/src/logic/validateIntent.test.ts +78 -74
  181. package/src/logic/validateIntent.ts +17 -7
  182. package/src/network/bakers.integ.test.ts +2 -5
  183. package/src/network/bakers.test.ts +5 -6
  184. package/src/network/bakers.ts +13 -10
  185. package/src/network/index.ts +2 -1
  186. package/src/network/tzkt.integ.test.ts +3 -14
  187. package/src/network/tzkt.test.ts +128 -96
  188. package/src/network/tzkt.ts +426 -393
  189. package/src/utils.ts +2 -3
@@ -1,6 +1,7 @@
1
1
  // SPDX-FileCopyrightText: © 2026 LEDGER SAS
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import type { TezosContext } from '../config'
4
5
  import type {
5
6
  APIBlock,
6
7
  APIDelegationType,
@@ -19,13 +20,13 @@ import type {
19
20
  } from '@ledgerhq/coin-module-framework/api/index'
20
21
  import { STAKING_ACTION_TO_OP_TYPE } from '../constants'
21
22
  import {
23
+ createTzktApi,
22
24
  fetchBlockDelegations,
23
25
  fetchBlockOriginations,
24
26
  fetchBlockReveals,
25
27
  fetchBlockStaking,
26
28
  fetchBlockTokenTransfers,
27
29
  fetchBlockTransactions,
28
- tzkt,
29
30
  } from '../network'
30
31
 
31
32
  const NATIVE_ASSET: AssetInfo = { type: 'native', name: 'XTZ' }
@@ -514,11 +515,13 @@ function groupAndMapTransactions(
514
515
  * - Appends FA token transfer operations to the owning BlockTransaction when a
515
516
  * matching `transactionId` can be resolved; otherwise creates a standalone entry.
516
517
  */
517
- export async function getBlock(height: number): Promise<Block> {
518
+ export async function getBlock(context: TezosContext, height: number): Promise<Block> {
518
519
  if (!Number.isSafeInteger(height) || height <= 0) {
519
520
  throw new Error(`getBlock: height must be a positive integer, got ${height}`)
520
521
  }
521
522
 
523
+ const config = await context.config()
524
+ const tzkt = createTzktApi(config)
522
525
  const [
523
526
  block,
524
527
  parentBlock,
@@ -531,12 +534,12 @@ export async function getBlock(height: number): Promise<Block> {
531
534
  ] = await Promise.all([
532
535
  tzkt.getBlockByLevel(height),
533
536
  tzkt.getBlockByLevel(height - 1),
534
- fetchBlockTransactions(height),
535
- fetchBlockTokenTransfers(height),
536
- fetchBlockDelegations(height),
537
- fetchBlockStaking(height),
538
- fetchBlockOriginations(height),
539
- fetchBlockReveals(height),
537
+ fetchBlockTransactions(config, height),
538
+ fetchBlockTokenTransfers(config, height),
539
+ fetchBlockDelegations(config, height),
540
+ fetchBlockStaking(config, height),
541
+ fetchBlockOriginations(config, height),
542
+ fetchBlockReveals(config, height),
540
543
  ])
541
544
 
542
545
  // Token transfers triggered by originations from other blocks carry an
@@ -1,8 +1,7 @@
1
1
  // SPDX-FileCopyrightText: © 2026 LEDGER SAS
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import type { TezosCoinConfig } from '../config'
5
- import coinConfig from '../config'
4
+ import type { TezosCoinConfig, TezosContext } from '../config'
6
5
  import { getBlock } from './getBlock'
7
6
  import { getBlockInfo } from './getBlockInfo'
8
7
 
@@ -15,8 +14,6 @@ import { getBlockInfo } from './getBlockInfo'
15
14
  * consistent, independently verifiable data.
16
15
  */
17
16
 
18
- let originalGetCoinConfig: () => TezosCoinConfig
19
-
20
17
  const shadownetConfig = (): TezosCoinConfig =>
21
18
  ({
22
19
  status: { type: 'active' },
@@ -32,20 +29,14 @@ const shadownetConfig = (): TezosCoinConfig =>
32
29
  },
33
30
  }) as TezosCoinConfig
34
31
 
35
- describe('getBlockInfo', () => {
36
- beforeAll(() => {
37
- originalGetCoinConfig = coinConfig.getCoinConfig
38
- coinConfig.setCoinConfig(shadownetConfig)
39
- })
40
-
41
- afterAll(() => {
42
- if (originalGetCoinConfig) {
43
- coinConfig.setCoinConfig(originalGetCoinConfig)
44
- }
45
- })
32
+ const context: TezosContext = {
33
+ config: async () => shadownetConfig(),
34
+ logger: () => undefined,
35
+ }
46
36
 
37
+ describe('getBlockInfo', () => {
47
38
  it('should fetch and parse block info for block 3113219 correctly', async () => {
48
- const blockInfo = await getBlockInfo(3113219)
39
+ const blockInfo = await getBlockInfo(context, 3113219)
49
40
 
50
41
  expect(blockInfo).toMatchObject({
51
42
  height: 3113219,
@@ -59,8 +50,8 @@ describe('getBlockInfo', () => {
59
50
  })
60
51
 
61
52
  it('should return consistent data with getBlock for the same block', async () => {
62
- const blockInfo = await getBlockInfo(3113219)
63
- const block = await getBlock(3113219)
53
+ const blockInfo = await getBlockInfo(context, 3113219)
54
+ const block = await getBlock(context, 3113219)
64
55
 
65
56
  expect(blockInfo).toMatchObject({
66
57
  height: block.info.height,
@@ -1,10 +1,20 @@
1
1
  // SPDX-FileCopyrightText: © 2026 LEDGER SAS
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import tzktApi from '../network/tzkt'
4
+ import type { TezosCoinConfig, TezosContext } from '../config'
5
5
  import { getBlockInfo } from './getBlockInfo'
6
6
 
7
- const mockGetBlockByLevel = jest.spyOn(tzktApi, 'getBlockByLevel')
7
+ const mockGetBlockByLevel = jest.fn()
8
+ jest.mock('../network', () => ({
9
+ createTzktApi: () => ({
10
+ getBlockByLevel: (...args: unknown[]) => mockGetBlockByLevel(...args),
11
+ }),
12
+ }))
13
+
14
+ const context: TezosContext = {
15
+ config: async () => ({}) as unknown as TezosCoinConfig,
16
+ logger: () => undefined,
17
+ }
8
18
 
9
19
  describe('getBlockInfo', () => {
10
20
  beforeEach(() => {
@@ -26,7 +36,7 @@ describe('getBlockInfo', () => {
26
36
  } as any)
27
37
 
28
38
  // When
29
- const result = await getBlockInfo(level)
39
+ const result = await getBlockInfo(context, level)
30
40
 
31
41
  // Then
32
42
  expect(mockGetBlockByLevel).toHaveBeenCalledTimes(2)
@@ -50,7 +60,7 @@ describe('getBlockInfo', () => {
50
60
  } as any)
51
61
 
52
62
  // When
53
- const result = await getBlockInfo(8_000_000)
63
+ const result = await getBlockInfo(context, 8_000_000)
54
64
 
55
65
  // Then
56
66
  expect(result.time).toBeInstanceOf(Date)
@@ -59,7 +69,7 @@ describe('getBlockInfo', () => {
59
69
 
60
70
  it('throws for height = 0 without calling the API', async () => {
61
71
  // When / Then
62
- await expect(getBlockInfo(0)).rejects.toThrow(
72
+ await expect(getBlockInfo(context, 0)).rejects.toThrow(
63
73
  'getBlockInfo: height must be a positive integer, got 0'
64
74
  )
65
75
  expect(mockGetBlockByLevel).not.toHaveBeenCalled()
@@ -67,7 +77,7 @@ describe('getBlockInfo', () => {
67
77
 
68
78
  it('throws for negative height without calling the API', async () => {
69
79
  // When / Then
70
- await expect(getBlockInfo(-5)).rejects.toThrow(
80
+ await expect(getBlockInfo(context, -5)).rejects.toThrow(
71
81
  'getBlockInfo: height must be a positive integer, got -5'
72
82
  )
73
83
  expect(mockGetBlockByLevel).not.toHaveBeenCalled()
@@ -76,7 +86,7 @@ describe('getBlockInfo', () => {
76
86
  it.each([NaN, 1.5, Infinity, -Infinity])(
77
87
  'throws for non-safe-integer height (%s) without calling the API',
78
88
  async (height) => {
79
- await expect(getBlockInfo(height)).rejects.toThrow(
89
+ await expect(getBlockInfo(context, height)).rejects.toThrow(
80
90
  'getBlockInfo: height must be a positive integer'
81
91
  )
82
92
  expect(mockGetBlockByLevel).not.toHaveBeenCalled()
@@ -97,7 +107,7 @@ describe('getBlockInfo', () => {
97
107
  } as any)
98
108
 
99
109
  // When
100
- const result = await getBlockInfo(1)
110
+ const result = await getBlockInfo(context, 1)
101
111
 
102
112
  // Then
103
113
  expect(result.parent).toEqual({ height: 0, hash: 'BLGenesis' })
@@ -108,6 +118,6 @@ describe('getBlockInfo', () => {
108
118
  mockGetBlockByLevel.mockRejectedValue(new Error('TzKT unreachable'))
109
119
 
110
120
  // When / Then
111
- await expect(getBlockInfo(999_999)).rejects.toThrow('TzKT unreachable')
121
+ await expect(getBlockInfo(context, 999_999)).rejects.toThrow('TzKT unreachable')
112
122
  })
113
123
  })
@@ -1,8 +1,9 @@
1
1
  // SPDX-FileCopyrightText: © 2026 LEDGER SAS
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import type { TezosContext } from '../config'
4
5
  import type { BlockInfo } from '@ledgerhq/coin-module-framework/api/index'
5
- import { tzkt } from '../network'
6
+ import { createTzktApi } from '../network'
6
7
 
7
8
  /**
8
9
  * Returns lightweight metadata for a Tezos block at the given level.
@@ -10,11 +11,13 @@ import { tzkt } from '../network'
10
11
  * Fetches the block and its predecessor in parallel so that `BlockInfo.parent`
11
12
  * is always populated without adding serial latency.
12
13
  */
13
- export async function getBlockInfo(height: number): Promise<BlockInfo> {
14
+ export async function getBlockInfo(context: TezosContext, height: number): Promise<BlockInfo> {
14
15
  if (!Number.isSafeInteger(height) || height <= 0) {
15
16
  throw new Error(`getBlockInfo: height must be a positive integer, got ${height}`)
16
17
  }
17
18
 
19
+ const config = await context.config()
20
+ const tzkt = createTzktApi(config)
18
21
  const [block, parentBlock] = await Promise.all([
19
22
  tzkt.getBlockByLevel(height),
20
23
  tzkt.getBlockByLevel(height - 1),
@@ -1,26 +1,37 @@
1
1
  // SPDX-FileCopyrightText: © 2026 LEDGER SAS
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { createApi } from '../api/index'
5
- import coinConfig from '../config'
6
- import tzktApi from '../network/tzkt'
4
+ import type { TezosCoinConfig, TezosContext } from '../config'
5
+ import { getStakes } from './getStakes'
6
+
7
+ const mockGetAccountByAddress = jest.fn()
8
+ const mockGetUnstakeRequests = jest.fn()
9
+ jest.mock('../network/tzkt', () => ({
10
+ __esModule: true,
11
+ createTzktApi: () => ({
12
+ getAccountByAddress: (...args: unknown[]) => mockGetAccountByAddress(...args),
13
+ getUnstakeRequests: (...args: unknown[]) => mockGetUnstakeRequests(...args),
14
+ }),
15
+ }))
7
16
 
8
17
  describe('getStakes', () => {
9
- const api = createApi({
10
- baker: { url: 'http://baker.example.com' },
11
- explorer: { url: 'http://tezos.explorer.com', maxTxQuery: 100 },
12
- node: { url: 'http://tezos.node.com' },
13
- fees: {
14
- minGasLimit: 600,
15
- minRevealGasLimit: 300,
16
- minStorageLimit: 0,
17
- minFees: 500,
18
- minEstimatedFees: 500,
19
- },
20
- })
21
-
22
- const mockGetAccountByAddress = jest.spyOn(tzktApi, 'getAccountByAddress')
23
- const mockGetUnstakeRequests = jest.spyOn(tzktApi, 'getUnstakeRequests')
18
+ 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,
33
+ logger: () => undefined,
34
+ }
24
35
 
25
36
  const makeRequest = (
26
37
  overrides: Partial<{
@@ -45,20 +56,6 @@ describe('getStakes', () => {
45
56
  beforeEach(() => {
46
57
  jest.clearAllMocks()
47
58
  mockGetUnstakeRequests.mockResolvedValue([])
48
-
49
- coinConfig.setCoinConfig(() => ({
50
- status: { type: 'active' },
51
- baker: { url: 'http://baker.example.com' },
52
- explorer: { url: 'http://tezos.explorer.com', maxTxQuery: 100 },
53
- node: { url: 'http://tezos.node.com' },
54
- fees: {
55
- minGasLimit: 600,
56
- minRevealGasLimit: 300,
57
- minStorageLimit: 0,
58
- minFees: 500,
59
- minEstimatedFees: 500,
60
- },
61
- }))
62
59
  })
63
60
 
64
61
  describe('account types', () => {
@@ -76,7 +73,7 @@ describe('getStakes', () => {
76
73
  firstActivityTime: '2021-01-01T00:00:00Z',
77
74
  })
78
75
 
79
- const result = await api.getStakes('tz1WvvbEGpBXGeTVbLiR6DYBe1izmgiYuZbq')
76
+ const result = await getStakes(context, 'tz1WvvbEGpBXGeTVbLiR6DYBe1izmgiYuZbq')
80
77
 
81
78
  expect(result.items).toEqual([])
82
79
  })
@@ -88,7 +85,7 @@ describe('getStakes', () => {
88
85
  counter: 0,
89
86
  })
90
87
 
91
- const result = await api.getStakes('tz1EmptyAccount')
88
+ const result = await getStakes(context, 'tz1EmptyAccount')
92
89
 
93
90
  expect(result.items).toEqual([])
94
91
  })
@@ -109,7 +106,7 @@ describe('getStakes', () => {
109
106
  firstActivityTime: '2021-01-01T00:00:00Z',
110
107
  })
111
108
 
112
- const result = await api.getStakes(address)
109
+ const result = await getStakes(context, address)
113
110
 
114
111
  expect(result.items).toEqual([
115
112
  {
@@ -143,7 +140,7 @@ describe('getStakes', () => {
143
140
  makeRequest({ id: 42, bakerAddress, actualAmount: 10, firstTime: '2026-05-01T00:00:00Z' }),
144
141
  ])
145
142
 
146
- const result = await api.getStakes(address)
143
+ const result = await getStakes(context, address)
147
144
 
148
145
  expect(result.items).toEqual([
149
146
  {
@@ -184,7 +181,7 @@ describe('getStakes', () => {
184
181
  it('should return delegation stake for delegated account with no staking', async () => {
185
182
  mockGetAccountByAddress.mockResolvedValue(makeAccount())
186
183
 
187
- const result = await api.getStakes(address)
184
+ const result = await getStakes(context, address)
188
185
 
189
186
  expect(result.items).toEqual([
190
187
  {
@@ -202,7 +199,7 @@ describe('getStakes', () => {
202
199
  it('should handle account with zero balance but delegation', async () => {
203
200
  mockGetAccountByAddress.mockResolvedValue(makeAccount({ balance: 0 }))
204
201
 
205
- const result = await api.getStakes(address)
202
+ const result = await getStakes(context, address)
206
203
 
207
204
  expect(result.items).toEqual([
208
205
  {
@@ -220,7 +217,7 @@ describe('getStakes', () => {
220
217
  it('should return delegation + stake when stakedBalance > 0', async () => {
221
218
  mockGetAccountByAddress.mockResolvedValue(makeAccount({ balance: 100, stakedBalance: 30 }))
222
219
 
223
- const result = await api.getStakes(address)
220
+ const result = await getStakes(context, address)
224
221
 
225
222
  expect(result.items).toEqual([
226
223
  {
@@ -255,7 +252,7 @@ describe('getStakes', () => {
255
252
  }),
256
253
  ])
257
254
 
258
- const result = await api.getStakes(address)
255
+ const result = await getStakes(context, address)
259
256
 
260
257
  expect(result.items).toEqual([
261
258
  {
@@ -293,7 +290,7 @@ describe('getStakes', () => {
293
290
  }),
294
291
  ])
295
292
 
296
- const result = await api.getStakes(address)
293
+ const result = await getStakes(context, address)
297
294
 
298
295
  expect(result.items).toEqual([
299
296
  {
@@ -376,7 +373,7 @@ describe('getStakes', () => {
376
373
  }),
377
374
  ])
378
375
 
379
- const result = await api.getStakes(address)
376
+ const result = await getStakes(context, address)
380
377
 
381
378
  expect(result.items).toEqual([
382
379
  {
@@ -423,7 +420,7 @@ describe('getStakes', () => {
423
420
  }),
424
421
  ])
425
422
 
426
- const result = await api.getStakes(address)
423
+ const result = await getStakes(context, address)
427
424
 
428
425
  const unstaking = result.items.find((i) => i.uid === 'unstaking-99')
429
426
  expect(unstaking?.delegate).toBe(previousBaker)
@@ -436,7 +433,7 @@ describe('getStakes', () => {
436
433
  makeRequest({ id: 4, actualAmount: 10, firstTime: '2026-05-04T00:00:00Z' }),
437
434
  ])
438
435
 
439
- const result = await api.getStakes(address)
436
+ const result = await getStakes(context, address)
440
437
 
441
438
  expect(result.items.filter((i) => i.uid.startsWith('unstaking-'))).toHaveLength(1)
442
439
  expect(result.items.find((i) => i.uid === 'unstaking-4')?.amount).toBe(10n)
@@ -445,7 +442,7 @@ describe('getStakes', () => {
445
442
  it('skips the unstake-requests endpoint entirely when unstakedBalance is 0', async () => {
446
443
  mockGetAccountByAddress.mockResolvedValue(makeAccount({ balance: 1000, unstakedBalance: 0 }))
447
444
 
448
- const result = await api.getStakes(address)
445
+ const result = await getStakes(context, address)
449
446
 
450
447
  expect(result.items).toEqual([])
451
448
  expect(mockGetUnstakeRequests).not.toHaveBeenCalled()
@@ -458,7 +455,7 @@ describe('getStakes', () => {
458
455
  makeRequest({ id: 2, actualAmount: 20, firstTime: '2026-05-04T00:00:00Z' }),
459
456
  ])
460
457
 
461
- const result = await api.getStakes(address)
458
+ const result = await getStakes(context, address)
462
459
 
463
460
  expect(result.items.map((i) => i.uid)).toEqual(['unstaking-2'])
464
461
  })
@@ -470,7 +467,7 @@ describe('getStakes', () => {
470
467
  makeRequest({ id: 2, actualAmount: 30, firstTime: '2026-05-04T00:00:00Z' }),
471
468
  ])
472
469
 
473
- const result = await api.getStakes(address)
470
+ const result = await getStakes(context, address)
474
471
 
475
472
  expect(result.items.map((i) => i.uid)).toEqual(['unstaking-2'])
476
473
  expect(result.items.find((i) => i.uid === 'unstaking-2')?.amount).toBe(30n)
@@ -480,7 +477,7 @@ describe('getStakes', () => {
480
477
  mockGetAccountByAddress.mockResolvedValue(makeAccount({ balance: 100, unstakedBalance: 10 }))
481
478
  mockGetUnstakeRequests.mockRejectedValueOnce(new Error('tzkt 500'))
482
479
 
483
- await expect(api.getStakes(address)).rejects.toThrow('tzkt 500')
480
+ await expect(getStakes(context, address)).rejects.toThrow('tzkt 500')
484
481
  })
485
482
  })
486
483
 
@@ -504,7 +501,7 @@ describe('getStakes', () => {
504
501
  firstActivityTime: '2026-01-01T00:00:00Z',
505
502
  })
506
503
 
507
- const result = await api.getStakes(address)
504
+ const result = await getStakes(context, address)
508
505
 
509
506
  const delegation = result.items.find((i) => i.uid === `delegation-${address}`)
510
507
  expect(delegation?.amount).toBe(0n)
@@ -1,11 +1,12 @@
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
5
  import type { APIAccount, APIManagerAccount, APIUnstakeRequest } from '../network/types'
5
6
  import type { Cursor, Page, Stake } from '@ledgerhq/coin-module-framework/api/types'
6
7
  import { log } from '@ledgerhq/logs'
7
8
  import { hasManagerKey } from '../network/types'
8
- import api from '../network/tzkt'
9
+ import { createTzktApi } from '../network/tzkt'
9
10
  import { partitionNativeBalance } from '../utils'
10
11
  import { STAKING_UID_PREFIX } from './positionUid'
11
12
 
@@ -17,11 +18,14 @@ export {
17
18
  } from './positionUid'
18
19
 
19
20
  export function fetchUnstakeRequests(
21
+ config: TezosCoinConfig,
20
22
  address: string,
21
23
  account: APIAccount
22
24
  ): Promise<APIUnstakeRequest[]> {
23
25
  if (!hasManagerKey(account)) return Promise.resolve([])
24
- return (account.unstakedBalance ?? 0) > 0 ? api.getUnstakeRequests(address) : Promise.resolve([])
26
+ return (account.unstakedBalance ?? 0) > 0
27
+ ? createTzktApi(config).getUnstakeRequests(address)
28
+ : Promise.resolve([])
25
29
  }
26
30
 
27
31
  function unstakeRequestToStake(address: string, req: APIUnstakeRequest): Stake | null {
@@ -124,9 +128,14 @@ export function buildStakesForAccount(
124
128
  return stakes
125
129
  }
126
130
 
127
- export async function getStakes(address: string, _cursor?: Cursor): Promise<Page<Stake>> {
128
- const accountInfo = await api.getAccountByAddress(address)
131
+ export async function getStakes(
132
+ context: TezosContext,
133
+ address: string,
134
+ _cursor?: Cursor
135
+ ): Promise<Page<Stake>> {
136
+ const config = await context.config()
137
+ const accountInfo = await createTzktApi(config).getAccountByAddress(address)
129
138
  if (!hasManagerKey(accountInfo)) return { items: [] }
130
- const unstakeRequests = await fetchUnstakeRequests(address, accountInfo)
139
+ const unstakeRequests = await fetchUnstakeRequests(config, address, accountInfo)
131
140
  return { items: buildStakesForAccount(address, accountInfo, unstakeRequests) }
132
141
  }
@@ -1,11 +1,13 @@
1
1
  // SPDX-FileCopyrightText: © 2026 LEDGER SAS
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import type { TezosContext } from '../config'
4
5
  import type { BlockInfo } from '@ledgerhq/coin-module-framework/api/index'
5
- import api from '../network/tzkt'
6
+ import { createTzktApi } from '../network/tzkt'
6
7
 
7
- export async function lastBlock(): Promise<BlockInfo> {
8
- const result = await api.getLastBlock()
8
+ export async function lastBlock(context: TezosContext): Promise<BlockInfo> {
9
+ const config = await context.config()
10
+ const result = await createTzktApi(config).getLastBlock()
9
11
 
10
12
  return {
11
13
  height: result.level,