@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 { TezosCoinConfig } from '../config'
4
5
  import type {
5
6
  APIAccount,
6
7
  APIBlock,
@@ -19,7 +20,6 @@ import type {
19
20
  import URL from 'url'
20
21
  import network from '@ledgerhq/live-network'
21
22
  import { log } from '@ledgerhq/logs'
22
- import coinConfig from '../config'
23
23
 
24
24
  /** TzKT hard-caps `limit` at 10 000; we use a safer page size to stay well under that. */
25
25
  const BLOCK_PAGE_SIZE = 1000
@@ -27,8 +27,6 @@ const BLOCK_PAGE_SIZE = 1000
27
27
  /** Maximum number of IDs per `id.in` request to keep URLs under the Cloudflare proxy limit (~16 KB). */
28
28
  const ID_IN_CHUNK_SIZE = 100
29
29
 
30
- const getExplorerUrl = () => coinConfig.getCoinConfig().explorer.url
31
-
32
30
  /**
33
31
  * Coalesces concurrent `getAccountByAddress` calls for the same explorer+address into a
34
32
  * single request. During a sync both `getBalance` and the readiness hook hit this endpoint
@@ -53,412 +51,428 @@ function chunk<T>(arr: T[], size: number): T[][] {
53
51
  }
54
52
 
55
53
  /**
56
- * Internal helper shared by `getOperationsTransactions` and `getOperationsOrigination`.
57
- * Both endpoints accept the same query shape; only the URL path differs.
54
+ * Builds the TzKT explorer client bound to the given coin config (ADR-019). The caller resolves the
55
+ * config from its {@link Context} and passes it in, rather than the client reading a module-level
56
+ * singleton.
58
57
  */
59
- async function getOperationsByType(
60
- type: 'transactions' | 'originations',
61
- level: number,
62
- cursor?: number,
63
- apiQueryParams: Record<string, unknown> = {}
64
- ): Promise<(APITransactionType & { block: string; hash: string })[]> {
65
- // "sort.asc": "id" guarantees forward progress for cursor-based paging (offset.cr).
66
- // Without an explicit sort the API default may be descending, which would cause the
67
- // cursor to go backwards and produce duplicates or an infinite loop.
68
- const params: Record<string, unknown> = {
69
- 'level.gte': level,
70
- limit: BLOCK_PAGE_SIZE,
71
- 'sort.asc': 'id',
72
- ...clearUndefined(apiQueryParams),
73
- }
74
- if (cursor !== undefined) params['offset.cr'] = cursor
75
- const { data } = await network<(APITransactionType & { block: string; hash: string })[]>({
76
- url: `${getExplorerUrl()}/v1/operations/${type}`,
77
- params,
78
- })
79
- return data
80
- }
81
-
82
- const api = {
83
- async getBlockCount(): Promise<number> {
84
- const { data } = await network<number>({
85
- url: `${getExplorerUrl()}/v1/blocks/count`,
86
- })
87
- return data
88
- },
89
- async getLastBlock(): Promise<{ hash: string; level: number; date: Date }> {
90
- const { data } = await network<APIBlock[]>({
91
- url: `${getExplorerUrl()}/v1/blocks`,
92
- params: {
93
- 'sort.desc': 'level',
94
- },
95
- })
96
-
97
- return {
98
- hash: data[0].hash,
99
- level: data[0].level,
100
- date: new Date(data[0].timestamp),
101
- }
102
- },
103
- async getAccountByAddress(address: string): Promise<APIAccount> {
104
- const key = `${getExplorerUrl()}|${address}`
105
- const existing = accountByAddressInflight.get(key)
106
- if (existing) return existing
107
- const request = network<APIAccount>({
108
- url: `${getExplorerUrl()}/v1/accounts/${address}`,
109
- })
110
- .then(({ data }) => data)
111
- .finally(() => accountByAddressInflight.delete(key))
112
- accountByAddressInflight.set(key, request)
113
- return request
114
- },
115
-
116
- /**
117
- * Returns the total `actualAmount` (mutez) summed over the account's `finalizable`
118
- * unstake requests — the portion of `unstakedBalance` whose unlock cycle has been
119
- * reached and that can be reclaimed via `finalize_unstake`. The complementary
120
- * `unstakedBalance - finalizable` portion is still in the deactivation delay window.
121
- *
122
- * TzKT's account endpoint does not expose this split, so we sum from
123
- * `/v1/staking/unstake_requests`. https://api.tzkt.io/#operation/Staking_GetUnstakeRequests
124
- *
125
- * `limit=1000` covers any realistic number of concurrent finalizable requests for
126
- * a single staker — we do not paginate.
127
- */
128
- async getUnstakeRequestsFinalizable(address: string): Promise<bigint> {
129
- const { data } = await network<number[]>({
130
- url: `${getExplorerUrl()}/v1/staking/unstake_requests`,
131
- params: {
132
- 'staker.eq': address,
133
- status: 'finalizable',
134
- 'select.values': 'actualAmount',
135
- limit: 1000,
136
- },
137
- })
138
- return data.reduce<bigint>((sum, n) => sum + BigInt(n), 0n)
139
- },
58
+ export function createTzktApi(config: TezosCoinConfig) {
59
+ const explorerUrl = config.explorer.url
140
60
 
141
61
  /**
142
- * Pending + finalizable unstake requests, by id ascending. Uses `status.ne=finalized` because
143
- * TzKT ignores `status.in=pending,finalizable` on this endpoint and returns finalized requests.
144
- * https://api.tzkt.io/#operation/Staking_GetUnstakeRequests
62
+ * Internal helper shared by `getOperationsTransactions` and `getOperationsOrigination`.
63
+ * Both endpoints accept the same query shape; only the URL path differs.
145
64
  */
146
- async getUnstakeRequests(address: string): Promise<APIUnstakeRequest[]> {
147
- const { data } = await network<APIUnstakeRequest[]>({
148
- url: `${getExplorerUrl()}/v1/staking/unstake_requests`,
149
- params: {
150
- 'staker.eq': address,
151
- 'status.ne': 'finalized',
152
- 'sort.asc': 'id',
153
- limit: 1000,
154
- },
155
- })
156
- return data
157
- },
158
- // https://api.tzkt.io/#operation/Accounts_GetOperations
159
- async getAccountOperations(
160
- address: string,
161
- query: AccountsGetOperationsOptions
162
- ): Promise<APIOperation[]> {
163
- // Remove undefined from query
164
- Object.entries(query).forEach(
165
- ([key, value]) => value === undefined && delete query[key as keyof typeof query]
166
- )
167
- const { data } = await network<APIOperation[]>({
168
- url: URL.format({
169
- pathname: `${getExplorerUrl()}/v1/accounts/${address}/operations`,
170
- query,
171
- }),
172
- })
173
- return data
174
- },
175
-
176
- // https://api.tzkt.io/#operation/Blocks_GetByLevel
177
- async getBlockByLevel(level: number): Promise<APIBlock> {
178
- const { data } = await network<APIBlock>({
179
- url: `${getExplorerUrl()}/v1/blocks/${level}`,
180
- })
181
- return data
182
- },
183
-
184
- /**
185
- * Resolves block hashes for the given levels in a single request.
186
- * Uses `/v1/blocks?level.in=...&select.values=level,hash`, which TzKT honours
187
- * (unlike `/v1/blocks/{level}?select=...`, where `select` is ignored). Used
188
- * for cheap backfill of `block.hash` on operations whose level is known but
189
- * whose response omits the block field (e.g. `/accounts/{addr}/operations`
190
- * for staking ops). Levels that don't resolve are absent from the result map.
191
- */
192
- async getBlockHashesByLevels(levels: readonly number[]): Promise<Map<number, string>> {
193
- if (levels.length === 0) return new Map()
194
- const { data } = await network<[number, string][]>({
195
- url: `${getExplorerUrl()}/v1/blocks`,
196
- params: {
197
- 'level.in': levels.join(','),
198
- 'select.values': 'level,hash',
199
- limit: levels.length,
200
- },
201
- })
202
- return new Map(data)
203
- },
204
-
205
- /**
206
- * Fetches a single page of `transaction` operations at the given block level.
207
- * Internal — used by `fetchBlockTransactions` which handles pagination.
208
- * https://api.tzkt.io/#operation/Operations_GetTransactions
209
- */
210
- async getBlockTransactionsPage(level: number, cursor?: number): Promise<APITransactionType[]> {
211
- // "sort.asc": "id" guarantees forward progress for cursor-based paging (offset.cr).
212
- // Without an explicit sort the API default may be descending, which would cause the
213
- // cursor to go backwards and produce duplicates or an infinite loop.
214
- const params: Record<string, unknown> = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' }
215
- if (cursor !== undefined) params['offset.cr'] = cursor
216
- const { data } = await network<APITransactionType[]>({
217
- url: `${getExplorerUrl()}/v1/operations/transactions`,
218
- params,
219
- })
220
- return data
221
- },
222
-
223
- /**
224
- * Fetches a list of `transaction` operations after the given level.
225
- * https://api.tzkt.io/#operation/Operations_GetTransactions
226
- */
227
- async getOperationsTransactions(
228
- level: number,
229
- cursor?: number,
230
- apiQueryParams: Record<string, unknown> = {}
231
- ): Promise<(APITransactionType & { block: string; hash: string })[]> {
232
- return getOperationsByType('transactions', level, cursor, apiQueryParams)
233
- },
234
-
235
- /**
236
- * Fetches a list of `originations` operations after the given level.
237
- * https://api.tzkt.io/#operation/Operations_GetOriginations
238
- */
239
- async getOperationsOrigination(
65
+ async function getOperationsByType(
66
+ type: 'transactions' | 'originations',
240
67
  level: number,
241
68
  cursor?: number,
242
69
  apiQueryParams: Record<string, unknown> = {}
243
70
  ): Promise<(APITransactionType & { block: string; hash: string })[]> {
244
- return getOperationsByType('originations', level, cursor, apiQueryParams)
245
- },
246
-
247
- /**
248
- * Fetches a single page of FA token transfers at the given block level.
249
- * Internal — used by `fetchBlockTokenTransfers` which handles pagination.
250
- * https://api.tzkt.io/#operation/Tokens_GetTokenTransfers
251
- */
252
- async getBlockTokenTransfersPage(level: number, cursor?: number): Promise<APITokenTransfer[]> {
253
- // Same rationale as getBlockTransactionsPage: explicit ascending sort keeps the
254
- // offset.cr cursor advancing forward regardless of the API's default ordering.
71
+ // "sort.asc": "id" guarantees forward progress for cursor-based paging (offset.cr).
72
+ // Without an explicit sort the API default may be descending, which would cause the
73
+ // cursor to go backwards and produce duplicates or an infinite loop.
255
74
  const params: Record<string, unknown> = {
256
- level,
75
+ 'level.gte': level,
257
76
  limit: BLOCK_PAGE_SIZE,
258
77
  'sort.asc': 'id',
259
- 'token.standard': 'fa2',
260
- }
261
- if (cursor !== undefined) params['offset.cr'] = cursor
262
- const { data } = await network<APITokenTransfer[]>({
263
- url: `${getExplorerUrl()}/v1/tokens/transfers`,
264
- params,
265
- })
266
- return data
267
- },
268
-
269
- /**
270
- * Fetches the latest FA token transfers since the given level.
271
- * https://api.tzkt.io/#operation/Tokens_GetTokenTransfers
272
- */
273
- async getTokenTransfers(
274
- apiQueryParams: Record<string, unknown> = {}
275
- ): Promise<APITokenTransfer[]> {
276
- const params = {
277
78
  ...clearUndefined(apiQueryParams),
278
79
  }
279
- const { data } = await network<APITokenTransfer[]>({
280
- url: `${getExplorerUrl()}/v1/tokens/transfers`,
281
- params,
282
- })
283
- return data
284
- },
285
-
286
- /**
287
- * Fetches a single page of `origination` operations at the given block level.
288
- * Internal — used by `fetchBlockOriginations` which handles pagination.
289
- * https://api.tzkt.io/#operation/Operations_GetOriginations
290
- */
291
- async getBlockOriginationsPage(level: number, cursor?: number): Promise<APIOriginationType[]> {
292
- const params: Record<string, unknown> = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' }
293
- if (cursor !== undefined) params['offset.cr'] = cursor
294
- const { data } = await network<APIOriginationType[]>({
295
- url: `${getExplorerUrl()}/v1/operations/originations`,
296
- params,
297
- })
298
- return data
299
- },
300
-
301
- /**
302
- * Fetches a single page of `reveal` operations at the given block level.
303
- * Internal — used by `fetchBlockReveals` which handles pagination.
304
- * https://api.tzkt.io/#operation/Operations_GetReveals
305
- */
306
- async getBlockRevealsPage(level: number, cursor?: number): Promise<APIRevealType[]> {
307
- const params: Record<string, unknown> = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' }
308
- if (cursor !== undefined) params['offset.cr'] = cursor
309
- const { data } = await network<APIRevealType[]>({
310
- url: `${getExplorerUrl()}/v1/operations/reveals`,
311
- params,
312
- })
313
- return data
314
- },
315
-
316
- /**
317
- * Fetches a single page of `delegation` operations at the given block level.
318
- * Internal — used by `fetchBlockDelegations` which handles pagination.
319
- * https://api.tzkt.io/#operation/Operations_GetDelegations
320
- */
321
- async getBlockDelegationsPage(level: number, cursor?: number): Promise<APIDelegationType[]> {
322
- const params: Record<string, unknown> = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' }
323
80
  if (cursor !== undefined) params['offset.cr'] = cursor
324
- const { data } = await network<APIDelegationType[]>({
325
- url: `${getExplorerUrl()}/v1/operations/delegations`,
81
+ const { data } = await network<(APITransactionType & { block: string; hash: string })[]>({
82
+ url: `${explorerUrl}/v1/operations/${type}`,
326
83
  params,
327
84
  })
328
85
  return data
329
- },
86
+ }
330
87
 
331
- /**
332
- * Fetches a single page of `staking` operations at the given block level.
333
- * Internal used by `fetchBlockStaking` which handles pagination.
334
- * https://api.tzkt.io/#operation/Operations_GetStaking
335
- */
336
- async getBlockStakingPage(level: number, cursor?: number): Promise<APIStakingType[]> {
337
- const params: Record<string, unknown> = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' }
338
- if (cursor !== undefined) params['offset.cr'] = cursor
339
- const { data } = await network<APIStakingType[]>({
340
- url: `${getExplorerUrl()}/v1/operations/staking`,
341
- params,
342
- })
343
- return data
344
- },
88
+ const api = {
89
+ async getBlockCount(): Promise<number> {
90
+ const { data } = await network<number>({
91
+ url: `${explorerUrl}/v1/blocks/count`,
92
+ })
93
+ return data
94
+ },
95
+ async getLastBlock(): Promise<{ hash: string; level: number; date: Date }> {
96
+ const { data } = await network<APIBlock[]>({
97
+ url: `${explorerUrl}/v1/blocks`,
98
+ params: {
99
+ 'sort.desc': 'level',
100
+ },
101
+ })
345
102
 
346
- /**
347
- * Fetches FA2 token transfers for a given account.
348
- * Translates `query.sort` to TzKT's `sort.asc=id` / `sort.desc=id`.
349
- * The lower-level `getTokenTransfers` helper is a generic pass-through and does not pin the sort.
350
- * https://api.tzkt.io/#operation/Tokens_GetTokenTransfers
351
- */
352
- async getAccountTokenTransfers(
353
- address: string,
354
- query: TokenTransfersGetOptions
355
- ): Promise<(APITokenTransfer & { hash: string; block: string })[]> {
356
- const sortKey = query.sort === 'Descending' ? 'sort.desc' : 'sort.asc'
357
- const params: Record<string, unknown> = {
358
- 'anyof.from.to': address,
359
- 'token.standard': 'fa2',
360
- [sortKey]: 'id',
361
- limit: query.limit,
362
- 'level.ge': query['level.ge'],
363
- 'level.lt': query['level.lt'],
364
- 'level.gt': query['level.gt'],
365
- 'id.lt': query['id.lt'],
366
- 'id.gt': query['id.gt'],
367
- }
103
+ return {
104
+ hash: data[0].hash,
105
+ level: data[0].level,
106
+ date: new Date(data[0].timestamp),
107
+ }
108
+ },
109
+ async getAccountByAddress(address: string): Promise<APIAccount> {
110
+ const key = `${explorerUrl}|${address}`
111
+ const existing = accountByAddressInflight.get(key)
112
+ if (existing) return existing
113
+ const request = network<APIAccount>({
114
+ url: `${explorerUrl}/v1/accounts/${address}`,
115
+ })
116
+ .then(({ data }) => data)
117
+ .finally(() => accountByAddressInflight.delete(key))
118
+ accountByAddressInflight.set(key, request)
119
+ return request
120
+ },
121
+
122
+ /**
123
+ * Returns the total `actualAmount` (mutez) summed over the account's `finalizable`
124
+ * unstake requests — the portion of `unstakedBalance` whose unlock cycle has been
125
+ * reached and that can be reclaimed via `finalize_unstake`. The complementary
126
+ * `unstakedBalance - finalizable` portion is still in the deactivation delay window.
127
+ *
128
+ * TzKT's account endpoint does not expose this split, so we sum from
129
+ * `/v1/staking/unstake_requests`. https://api.tzkt.io/#operation/Staking_GetUnstakeRequests
130
+ *
131
+ * `limit=1000` covers any realistic number of concurrent finalizable requests for
132
+ * a single staker — we do not paginate.
133
+ */
134
+ async getUnstakeRequestsFinalizable(address: string): Promise<bigint> {
135
+ const { data } = await network<number[]>({
136
+ url: `${explorerUrl}/v1/staking/unstake_requests`,
137
+ params: {
138
+ 'staker.eq': address,
139
+ status: 'finalizable',
140
+ 'select.values': 'actualAmount',
141
+ limit: 1000,
142
+ },
143
+ })
144
+ return data.reduce<bigint>((sum, n) => sum + BigInt(n), 0n)
145
+ },
146
+
147
+ /**
148
+ * Pending + finalizable unstake requests, by id ascending. Uses `status.ne=finalized` because
149
+ * TzKT ignores `status.in=pending,finalizable` on this endpoint and returns finalized requests.
150
+ * https://api.tzkt.io/#operation/Staking_GetUnstakeRequests
151
+ */
152
+ async getUnstakeRequests(address: string): Promise<APIUnstakeRequest[]> {
153
+ const { data } = await network<APIUnstakeRequest[]>({
154
+ url: `${explorerUrl}/v1/staking/unstake_requests`,
155
+ params: {
156
+ 'staker.eq': address,
157
+ 'status.ne': 'finalized',
158
+ 'sort.asc': 'id',
159
+ limit: 1000,
160
+ },
161
+ })
162
+ return data
163
+ },
164
+ // https://api.tzkt.io/#operation/Accounts_GetOperations
165
+ async getAccountOperations(
166
+ address: string,
167
+ query: AccountsGetOperationsOptions
168
+ ): Promise<APIOperation[]> {
169
+ // Remove undefined from query
170
+ Object.entries(query).forEach(
171
+ ([key, value]) => value === undefined && delete query[key as keyof typeof query]
172
+ )
173
+ const { data } = await network<APIOperation[]>({
174
+ url: URL.format({
175
+ pathname: `${explorerUrl}/v1/accounts/${address}/operations`,
176
+ query,
177
+ }),
178
+ })
179
+ return data
180
+ },
181
+
182
+ // https://api.tzkt.io/#operation/Blocks_GetByLevel
183
+ async getBlockByLevel(level: number): Promise<APIBlock> {
184
+ const { data } = await network<APIBlock>({
185
+ url: `${explorerUrl}/v1/blocks/${level}`,
186
+ })
187
+ return data
188
+ },
189
+
190
+ /**
191
+ * Resolves block hashes for the given levels in a single request.
192
+ * Uses `/v1/blocks?level.in=...&select.values=level,hash`, which TzKT honours
193
+ * (unlike `/v1/blocks/{level}?select=...`, where `select` is ignored). Used
194
+ * for cheap backfill of `block.hash` on operations whose level is known but
195
+ * whose response omits the block field (e.g. `/accounts/{addr}/operations`
196
+ * for staking ops). Levels that don't resolve are absent from the result map.
197
+ */
198
+ async getBlockHashesByLevels(levels: readonly number[]): Promise<Map<number, string>> {
199
+ if (levels.length === 0) return new Map()
200
+ const { data } = await network<[number, string][]>({
201
+ url: `${explorerUrl}/v1/blocks`,
202
+ params: {
203
+ 'level.in': levels.join(','),
204
+ 'select.values': 'level,hash',
205
+ limit: levels.length,
206
+ },
207
+ })
208
+ return new Map(data)
209
+ },
210
+
211
+ /**
212
+ * Fetches a single page of `transaction` operations at the given block level.
213
+ * Internal — used by `fetchBlockTransactions` which handles pagination.
214
+ * https://api.tzkt.io/#operation/Operations_GetTransactions
215
+ */
216
+ async getBlockTransactionsPage(level: number, cursor?: number): Promise<APITransactionType[]> {
217
+ // "sort.asc": "id" guarantees forward progress for cursor-based paging (offset.cr).
218
+ // Without an explicit sort the API default may be descending, which would cause the
219
+ // cursor to go backwards and produce duplicates or an infinite loop.
220
+ const params: Record<string, unknown> = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' }
221
+ if (cursor !== undefined) params['offset.cr'] = cursor
222
+ const { data } = await network<APITransactionType[]>({
223
+ url: `${explorerUrl}/v1/operations/transactions`,
224
+ params,
225
+ })
226
+ return data
227
+ },
228
+
229
+ /**
230
+ * Fetches a list of `transaction` operations after the given level.
231
+ * https://api.tzkt.io/#operation/Operations_GetTransactions
232
+ */
233
+ async getOperationsTransactions(
234
+ level: number,
235
+ cursor?: number,
236
+ apiQueryParams: Record<string, unknown> = {}
237
+ ): Promise<(APITransactionType & { block: string; hash: string })[]> {
238
+ return getOperationsByType('transactions', level, cursor, apiQueryParams)
239
+ },
240
+
241
+ /**
242
+ * Fetches a list of `originations` operations after the given level.
243
+ * https://api.tzkt.io/#operation/Operations_GetOriginations
244
+ */
245
+ async getOperationsOrigination(
246
+ level: number,
247
+ cursor?: number,
248
+ apiQueryParams: Record<string, unknown> = {}
249
+ ): Promise<(APITransactionType & { block: string; hash: string })[]> {
250
+ return getOperationsByType('originations', level, cursor, apiQueryParams)
251
+ },
252
+
253
+ /**
254
+ * Fetches a single page of FA token transfers at the given block level.
255
+ * Internal — used by `fetchBlockTokenTransfers` which handles pagination.
256
+ * https://api.tzkt.io/#operation/Tokens_GetTokenTransfers
257
+ */
258
+ async getBlockTokenTransfersPage(level: number, cursor?: number): Promise<APITokenTransfer[]> {
259
+ // Same rationale as getBlockTransactionsPage: explicit ascending sort keeps the
260
+ // offset.cr cursor advancing forward regardless of the API's default ordering.
261
+ const params: Record<string, unknown> = {
262
+ level,
263
+ limit: BLOCK_PAGE_SIZE,
264
+ 'sort.asc': 'id',
265
+ 'token.standard': 'fa2',
266
+ }
267
+ if (cursor !== undefined) params['offset.cr'] = cursor
268
+ const { data } = await network<APITokenTransfer[]>({
269
+ url: `${explorerUrl}/v1/tokens/transfers`,
270
+ params,
271
+ })
272
+ return data
273
+ },
274
+
275
+ /**
276
+ * Fetches the latest FA token transfers since the given level.
277
+ * https://api.tzkt.io/#operation/Tokens_GetTokenTransfers
278
+ */
279
+ async getTokenTransfers(
280
+ apiQueryParams: Record<string, unknown> = {}
281
+ ): Promise<APITokenTransfer[]> {
282
+ const params = {
283
+ ...clearUndefined(apiQueryParams),
284
+ }
285
+ const { data } = await network<APITokenTransfer[]>({
286
+ url: `${explorerUrl}/v1/tokens/transfers`,
287
+ params,
288
+ })
289
+ return data
290
+ },
291
+
292
+ /**
293
+ * Fetches a single page of `origination` operations at the given block level.
294
+ * Internal — used by `fetchBlockOriginations` which handles pagination.
295
+ * https://api.tzkt.io/#operation/Operations_GetOriginations
296
+ */
297
+ async getBlockOriginationsPage(level: number, cursor?: number): Promise<APIOriginationType[]> {
298
+ const params: Record<string, unknown> = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' }
299
+ if (cursor !== undefined) params['offset.cr'] = cursor
300
+ const { data } = await network<APIOriginationType[]>({
301
+ url: `${explorerUrl}/v1/operations/originations`,
302
+ params,
303
+ })
304
+ return data
305
+ },
306
+
307
+ /**
308
+ * Fetches a single page of `reveal` operations at the given block level.
309
+ * Internal — used by `fetchBlockReveals` which handles pagination.
310
+ * https://api.tzkt.io/#operation/Operations_GetReveals
311
+ */
312
+ async getBlockRevealsPage(level: number, cursor?: number): Promise<APIRevealType[]> {
313
+ const params: Record<string, unknown> = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' }
314
+ if (cursor !== undefined) params['offset.cr'] = cursor
315
+ const { data } = await network<APIRevealType[]>({
316
+ url: `${explorerUrl}/v1/operations/reveals`,
317
+ params,
318
+ })
319
+ return data
320
+ },
321
+
322
+ /**
323
+ * Fetches a single page of `delegation` operations at the given block level.
324
+ * Internal — used by `fetchBlockDelegations` which handles pagination.
325
+ * https://api.tzkt.io/#operation/Operations_GetDelegations
326
+ */
327
+ async getBlockDelegationsPage(level: number, cursor?: number): Promise<APIDelegationType[]> {
328
+ const params: Record<string, unknown> = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' }
329
+ if (cursor !== undefined) params['offset.cr'] = cursor
330
+ const { data } = await network<APIDelegationType[]>({
331
+ url: `${explorerUrl}/v1/operations/delegations`,
332
+ params,
333
+ })
334
+ return data
335
+ },
336
+
337
+ /**
338
+ * Fetches a single page of `staking` operations at the given block level.
339
+ * Internal — used by `fetchBlockStaking` which handles pagination.
340
+ * https://api.tzkt.io/#operation/Operations_GetStaking
341
+ */
342
+ async getBlockStakingPage(level: number, cursor?: number): Promise<APIStakingType[]> {
343
+ const params: Record<string, unknown> = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' }
344
+ if (cursor !== undefined) params['offset.cr'] = cursor
345
+ const { data } = await network<APIStakingType[]>({
346
+ url: `${explorerUrl}/v1/operations/staking`,
347
+ params,
348
+ })
349
+ return data
350
+ },
351
+
352
+ /**
353
+ * Fetches FA2 token transfers for a given account.
354
+ * Translates `query.sort` to TzKT's `sort.asc=id` / `sort.desc=id`.
355
+ * The lower-level `getTokenTransfers` helper is a generic pass-through and does not pin the sort.
356
+ * https://api.tzkt.io/#operation/Tokens_GetTokenTransfers
357
+ */
358
+ async getAccountTokenTransfers(
359
+ address: string,
360
+ query: TokenTransfersGetOptions
361
+ ): Promise<(APITokenTransfer & { hash: string; block: string })[]> {
362
+ const sortKey = query.sort === 'Descending' ? 'sort.desc' : 'sort.asc'
363
+ const params: Record<string, unknown> = {
364
+ 'anyof.from.to': address,
365
+ 'token.standard': 'fa2',
366
+ [sortKey]: 'id',
367
+ limit: query.limit,
368
+ 'level.ge': query['level.ge'],
369
+ 'level.lt': query['level.lt'],
370
+ 'level.gt': query['level.gt'],
371
+ 'id.lt': query['id.lt'],
372
+ 'id.gt': query['id.gt'],
373
+ }
368
374
 
369
- const data = await api.getTokenTransfers(clearUndefined(params))
375
+ const data = await api.getTokenTransfers(clearUndefined(params))
370
376
 
371
- const transactionIds = data
372
- .map((t) => t.transactionId)
373
- .filter((id): id is number => typeof id === 'number')
377
+ const transactionIds = data
378
+ .map((t) => t.transactionId)
379
+ .filter((id): id is number => typeof id === 'number')
374
380
 
375
- const originationIds = data
376
- .map((t) => t.originationId)
377
- .filter((id): id is number => typeof id === 'number')
381
+ const originationIds = data
382
+ .map((t) => t.originationId)
383
+ .filter((id): id is number => typeof id === 'number')
378
384
 
379
- if (transactionIds.length === 0 && originationIds.length === 0) {
380
- return []
381
- }
385
+ if (transactionIds.length === 0 && originationIds.length === 0) {
386
+ return []
387
+ }
382
388
 
383
- const transactions = transactionIds.length
384
- ? (
385
- await Promise.all(
386
- chunk(transactionIds, ID_IN_CHUNK_SIZE).map((ids) =>
387
- api.getOperationsTransactions(query['level.ge'] || 0, undefined, {
388
- 'id.in': ids.join(','),
389
- })
389
+ const transactions = transactionIds.length
390
+ ? (
391
+ await Promise.all(
392
+ chunk(transactionIds, ID_IN_CHUNK_SIZE).map((ids) =>
393
+ api.getOperationsTransactions(query['level.ge'] || 0, undefined, {
394
+ 'id.in': ids.join(','),
395
+ })
396
+ )
390
397
  )
391
- )
392
- ).flat()
393
- : []
394
-
395
- const originations = originationIds.length
396
- ? (
397
- await Promise.all(
398
- chunk(originationIds, ID_IN_CHUNK_SIZE).map((ids) =>
399
- api.getOperationsOrigination(query['level.ge'] || 0, undefined, {
400
- 'id.in': ids.join(','),
401
- })
398
+ ).flat()
399
+ : []
400
+
401
+ const originations = originationIds.length
402
+ ? (
403
+ await Promise.all(
404
+ chunk(originationIds, ID_IN_CHUNK_SIZE).map((ids) =>
405
+ api.getOperationsOrigination(query['level.ge'] || 0, undefined, {
406
+ 'id.in': ids.join(','),
407
+ })
408
+ )
402
409
  )
403
- )
404
- ).flat()
405
- : []
406
-
407
- // Build id -> operation maps once so per-transfer lookups are O(1) instead of O(n).
408
- // Keys are widened to `number | undefined` so lookups with a missing id naturally
409
- // return `undefined` (no entry is ever stored under the `undefined` key).
410
- const transactionsById = new Map<number | undefined, (typeof transactions)[number]>(
411
- transactions.map((t) => [t.id, t])
412
- )
413
- const originationsById = new Map<number | undefined, (typeof originations)[number]>(
414
- originations.map((o) => [o.id, o])
415
- )
416
-
417
- return data.map((token) => {
418
- const transaction = transactionsById.get(token.transactionId)
419
- const origination = originationsById.get(token.originationId)
420
-
421
- return {
422
- ...token,
423
- hash: transaction?.hash ?? origination?.hash ?? '',
424
- block: transaction?.block ?? origination?.block ?? '',
410
+ ).flat()
411
+ : []
412
+
413
+ // Build id -> operation maps once so per-transfer lookups are O(1) instead of O(n).
414
+ // Keys are widened to `number | undefined` so lookups with a missing id naturally
415
+ // return `undefined` (no entry is ever stored under the `undefined` key).
416
+ const transactionsById = new Map<number | undefined, (typeof transactions)[number]>(
417
+ transactions.map((t) => [t.id, t])
418
+ )
419
+ const originationsById = new Map<number | undefined, (typeof originations)[number]>(
420
+ originations.map((o) => [o.id, o])
421
+ )
422
+
423
+ return data.map((token) => {
424
+ const transaction = transactionsById.get(token.transactionId)
425
+ const origination = originationsById.get(token.originationId)
426
+
427
+ return {
428
+ ...token,
429
+ hash: transaction?.hash ?? origination?.hash ?? '',
430
+ block: transaction?.block ?? origination?.block ?? '',
431
+ }
432
+ })
433
+ },
434
+
435
+ /**
436
+ * Fetches FA2 token balances for a given account.
437
+ * When `tokenFilter` is omitted, all FA2 token balances are returned.
438
+ * Pass `tokenFilter` to query a specific FA2 contract + token id (e.g. send-max for FA2).
439
+ * https://api.tzkt.io/#operation/Tokens_GetTokenBalances
440
+ */
441
+ async getTokensBalances(
442
+ address: string,
443
+ tokenFilter?: { contractAddress: string; tokenId: number }
444
+ ): Promise<APITokenBalance[]> {
445
+ const params: Record<string, unknown> = {
446
+ account: address,
447
+ 'token.standard': 'fa2',
425
448
  }
426
- })
427
- },
449
+ if (tokenFilter) {
450
+ params['token.contract'] = tokenFilter.contractAddress
451
+ params['token.tokenId'] = String(tokenFilter.tokenId)
452
+ }
453
+ const { data } = await network<APITokenBalance[]>({
454
+ url: `${explorerUrl}/v1/tokens/balances`,
455
+ params,
456
+ })
457
+ return data
458
+ },
459
+ }
428
460
 
429
- /**
430
- * Fetches FA2 token balances for a given account.
431
- * When `tokenFilter` is omitted, all FA2 token balances are returned.
432
- * Pass `tokenFilter` to query a specific FA2 contract + token id (e.g. send-max for FA2).
433
- * https://api.tzkt.io/#operation/Tokens_GetTokenBalances
434
- */
435
- async getTokensBalances(
436
- address: string,
437
- tokenFilter?: { contractAddress: string; tokenId: number }
438
- ): Promise<APITokenBalance[]> {
439
- const params: Record<string, unknown> = {
440
- account: address,
441
- 'token.standard': 'fa2',
442
- }
443
- if (tokenFilter) {
444
- params['token.contract'] = tokenFilter.contractAddress
445
- params['token.tokenId'] = String(tokenFilter.tokenId)
446
- }
447
- const { data } = await network<APITokenBalance[]>({
448
- url: `${getExplorerUrl()}/v1/tokens/balances`,
449
- params,
450
- })
451
- return data
452
- },
461
+ return api
453
462
  }
454
463
 
464
+ /** The TzKT explorer client bound to a coin config, as returned by {@link createTzktApi}. */
465
+ export type TzktApi = ReturnType<typeof createTzktApi>
466
+
455
467
  // TODO this has same purpose as api/listOperations
456
468
  export const fetchAllTransactions = async (
469
+ config: TezosCoinConfig,
457
470
  address: string,
458
471
  lastId?: number
459
472
  ): Promise<APIOperation[]> => {
473
+ const api = createTzktApi(config)
460
474
  let ops: APIOperation[] = []
461
- let maxIteration = coinConfig.getCoinConfig().explorer.maxTxQuery
475
+ let maxIteration = config.explorer.maxTxQuery
462
476
  do {
463
477
  const newOps = await api.getAccountOperations(address, {
464
478
  lastId,
@@ -486,13 +500,14 @@ export const fetchAllTransactions = async (
486
500
  * A safety cap (`maxTxQuery`) prevents infinite loops on pathological responses.
487
501
  */
488
502
  async function fetchBlockPaginated<T extends { id: number }>(
503
+ config: TezosCoinConfig,
489
504
  pageFn: (level: number, cursor?: number) => Promise<T[]>,
490
505
  level: number,
491
506
  label: string
492
507
  ): Promise<T[]> {
493
508
  const items: T[] = []
494
509
  let cursor: number | undefined
495
- let maxIteration = coinConfig.getCoinConfig().explorer.maxTxQuery
510
+ let maxIteration = config.explorer.maxTxQuery
496
511
  do {
497
512
  const page = await pageFn(level, cursor)
498
513
  if (page.length === 0) break
@@ -506,22 +521,40 @@ async function fetchBlockPaginated<T extends { id: number }>(
506
521
  return items
507
522
  }
508
523
 
509
- export const fetchBlockTransactions = (level: number) =>
510
- fetchBlockPaginated(api.getBlockTransactionsPage, level, 'fetchBlockTransactions')
511
-
512
- export const fetchBlockTokenTransfers = (level: number) =>
513
- fetchBlockPaginated(api.getBlockTokenTransfersPage, level, 'fetchBlockTokenTransfers')
514
-
515
- export const fetchBlockDelegations = (level: number) =>
516
- fetchBlockPaginated(api.getBlockDelegationsPage, level, 'fetchBlockDelegations')
517
-
518
- export const fetchBlockStaking = (level: number) =>
519
- fetchBlockPaginated(api.getBlockStakingPage, level, 'fetchBlockStaking')
520
-
521
- export const fetchBlockOriginations = (level: number) =>
522
- fetchBlockPaginated(api.getBlockOriginationsPage, level, 'fetchBlockOriginations')
523
-
524
- export const fetchBlockReveals = (level: number) =>
525
- fetchBlockPaginated(api.getBlockRevealsPage, level, 'fetchBlockReveals')
526
-
527
- export default api
524
+ export const fetchBlockTransactions = (config: TezosCoinConfig, level: number) =>
525
+ fetchBlockPaginated(
526
+ config,
527
+ createTzktApi(config).getBlockTransactionsPage,
528
+ level,
529
+ 'fetchBlockTransactions'
530
+ )
531
+
532
+ export const fetchBlockTokenTransfers = (config: TezosCoinConfig, level: number) =>
533
+ fetchBlockPaginated(
534
+ config,
535
+ createTzktApi(config).getBlockTokenTransfersPage,
536
+ level,
537
+ 'fetchBlockTokenTransfers'
538
+ )
539
+
540
+ export const fetchBlockDelegations = (config: TezosCoinConfig, level: number) =>
541
+ fetchBlockPaginated(
542
+ config,
543
+ createTzktApi(config).getBlockDelegationsPage,
544
+ level,
545
+ 'fetchBlockDelegations'
546
+ )
547
+
548
+ export const fetchBlockStaking = (config: TezosCoinConfig, level: number) =>
549
+ fetchBlockPaginated(config, createTzktApi(config).getBlockStakingPage, level, 'fetchBlockStaking')
550
+
551
+ export const fetchBlockOriginations = (config: TezosCoinConfig, level: number) =>
552
+ fetchBlockPaginated(
553
+ config,
554
+ createTzktApi(config).getBlockOriginationsPage,
555
+ level,
556
+ 'fetchBlockOriginations'
557
+ )
558
+
559
+ export const fetchBlockReveals = (config: TezosCoinConfig, level: number) =>
560
+ fetchBlockPaginated(config, createTzktApi(config).getBlockRevealsPage, level, 'fetchBlockReveals')