@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.
- package/CHANGELOG.md +25 -0
- package/lib/api/index.d.ts +1 -1
- package/lib/api/index.d.ts.map +1 -1
- package/lib/api/index.js +1 -1
- package/lib/api/index.js.map +1 -1
- package/lib/logic/craftRawOperations.js +26 -17
- package/lib/logic/craftRawOperations.js.map +1 -1
- package/lib/logic/estimateFees.js +4 -4
- package/lib/logic/estimateFees.js.map +1 -1
- package/lib/logic/listOperations.d.ts.map +1 -1
- package/lib/logic/listOperations.js +9 -7
- package/lib/logic/listOperations.js.map +1 -1
- package/lib/logic/validateIntent.d.ts.map +1 -1
- package/lib/logic/validateIntent.js +26 -8
- package/lib/logic/validateIntent.js.map +1 -1
- package/lib/network/tzkt.js +1 -1
- package/lib/network/tzkt.js.map +1 -1
- package/lib/test/config.d.ts +2 -22
- package/lib/test/config.d.ts.map +1 -1
- package/lib/test/config.js.map +1 -1
- package/lib/utils.d.ts +0 -3
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +17 -3
- package/lib/utils.js.map +1 -1
- package/lib-es/api/index.d.ts +1 -1
- package/lib-es/api/index.d.ts.map +1 -1
- package/lib-es/api/index.js +1 -1
- package/lib-es/api/index.js.map +1 -1
- package/lib-es/logic/craftRawOperations.js +26 -17
- package/lib-es/logic/craftRawOperations.js.map +1 -1
- package/lib-es/logic/estimateFees.js +4 -4
- package/lib-es/logic/estimateFees.js.map +1 -1
- package/lib-es/logic/listOperations.d.ts.map +1 -1
- package/lib-es/logic/listOperations.js +9 -7
- package/lib-es/logic/listOperations.js.map +1 -1
- package/lib-es/logic/validateIntent.d.ts.map +1 -1
- package/lib-es/logic/validateIntent.js +27 -9
- package/lib-es/logic/validateIntent.js.map +1 -1
- package/lib-es/network/tzkt.js +1 -1
- package/lib-es/network/tzkt.js.map +1 -1
- package/lib-es/test/config.d.ts +2 -22
- package/lib-es/test/config.d.ts.map +1 -1
- package/lib-es/test/config.js.map +1 -1
- package/lib-es/utils.d.ts +0 -3
- package/lib-es/utils.d.ts.map +1 -1
- package/lib-es/utils.js +17 -3
- package/lib-es/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/api/index-mainnet.integ.test.ts +40 -50
- package/src/api/index.integ.test.ts +60 -45
- package/src/api/index.test.ts +229 -180
- package/src/api/index.ts +5 -4
- package/src/logic/broadcast.integ.test.ts +2 -7
- package/src/logic/craftRawOperations.test.ts +11 -10
- package/src/logic/craftRawOperations.ts +35 -19
- package/src/logic/craftTransaction.integ.test.ts +2 -2
- package/src/logic/craftTransaction.test.ts +63 -95
- package/src/logic/estimateFees.integ.test.ts +19 -20
- package/src/logic/estimateFees.test.ts +30 -63
- package/src/logic/estimateFees.ts +4 -4
- package/src/logic/getBalance.test.ts +6 -6
- package/src/logic/getBlock.integ.test.ts +20 -21
- package/src/logic/getBlock.test.ts +44 -51
- package/src/logic/getBlockInfo.integ.test.ts +13 -14
- package/src/logic/getBlockInfo.test.ts +8 -7
- package/src/logic/getStakes.test.ts +17 -17
- package/src/logic/listOperations.integ.test.ts +40 -37
- package/src/logic/listOperations.test.ts +34 -31
- package/src/logic/listOperations.ts +19 -19
- package/src/logic/validateIntent.test.ts +145 -20
- package/src/logic/validateIntent.ts +32 -8
- package/src/network/bakers.integ.test.ts +1 -1
- package/src/network/bakers.test.ts +7 -15
- package/src/network/tzkt.integ.test.ts +13 -14
- package/src/network/tzkt.test.ts +194 -259
- package/src/network/tzkt.ts +1 -1
- package/src/test/config.ts +3 -1
- package/src/utils.ts +18 -3
- package/.oxlintrc.json +0 -20
package/src/network/tzkt.test.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
APITokenTransfer,
|
|
15
15
|
APITransactionType,
|
|
16
16
|
} from './types'
|
|
17
|
+
import type { DeepPartial, DeepPartialReturn } from '@ledgerhq/coin-module-framework/test/utils'
|
|
17
18
|
// tzkt.ts imports `network` from "@ledgerhq/live-network" (the package root, not the /network
|
|
18
19
|
// subpath). We mock the same path so Jest's module registry intercepts those calls.
|
|
19
20
|
import network from '@ledgerhq/live-network'
|
|
@@ -30,7 +31,7 @@ import {
|
|
|
30
31
|
|
|
31
32
|
jest.mock('@ledgerhq/live-network')
|
|
32
33
|
jest.mock('@ledgerhq/logs')
|
|
33
|
-
const mockedNetwork = jest.mocked(network)
|
|
34
|
+
const mockedNetwork = jest.mocked<DeepPartialReturn<typeof network>>(network)
|
|
34
35
|
const mockedLog = jest.mocked(log)
|
|
35
36
|
|
|
36
37
|
// The tzkt module is NOT mocked here. `createTzktApi(config)` returns a plain object whose methods
|
|
@@ -42,7 +43,7 @@ const mockedLog = jest.mocked(log)
|
|
|
42
43
|
// The paginated helpers (`fetchAllTransactions`, `fetchBlock*`) are top-level functions that build
|
|
43
44
|
// their OWN fresh `createTzktApi(config)` instance internally, so spying on `api` cannot intercept
|
|
44
45
|
// them. Those tests therefore drive the mocked `network` directly.
|
|
45
|
-
const config = mockConfig
|
|
46
|
+
const config: TezosCoinConfig = mockConfig
|
|
46
47
|
const api = createTzktApi(config)
|
|
47
48
|
|
|
48
49
|
// ---------------------------------------------------------------------------
|
|
@@ -51,36 +52,30 @@ const api = createTzktApi(config)
|
|
|
51
52
|
|
|
52
53
|
/** Wraps raw data into the shape that @ledgerhq/live-network resolves with. */
|
|
53
54
|
function networkResponse<T>(data: T) {
|
|
54
|
-
return Promise.resolve({
|
|
55
|
-
data,
|
|
56
|
-
status: 200,
|
|
57
|
-
headers: {} as any,
|
|
58
|
-
statusText: '',
|
|
59
|
-
config: { headers: {} as any },
|
|
60
|
-
})
|
|
55
|
+
return Promise.resolve({ data })
|
|
61
56
|
}
|
|
62
57
|
|
|
63
|
-
function makeApiBlock(level = 100): APIBlock {
|
|
64
|
-
return { level, hash: `BLk${level}`, timestamp: '2024-01-01T00:00:00Z' }
|
|
58
|
+
function makeApiBlock(level = 100): Pick<APIBlock, 'level' | 'hash' | 'timestamp'> {
|
|
59
|
+
return { level, hash: `BLk${level}`, timestamp: '2024-01-01T00:00:00Z' }
|
|
65
60
|
}
|
|
66
61
|
|
|
67
|
-
function makeTxItem(id: number): APITransactionType {
|
|
68
|
-
return { id }
|
|
62
|
+
function makeTxItem(id: number): DeepPartial<APITransactionType> {
|
|
63
|
+
return { id }
|
|
69
64
|
}
|
|
70
65
|
|
|
71
|
-
function makeTokenItem(id: number): APITokenTransfer {
|
|
72
|
-
return { id }
|
|
66
|
+
function makeTokenItem(id: number): DeepPartial<APITokenTransfer> {
|
|
67
|
+
return { id }
|
|
73
68
|
}
|
|
74
69
|
|
|
75
|
-
function makeDelegationItem(id: number): APIDelegationType {
|
|
76
|
-
return { id }
|
|
70
|
+
function makeDelegationItem(id: number): DeepPartial<APIDelegationType> {
|
|
71
|
+
return { id }
|
|
77
72
|
}
|
|
78
73
|
|
|
79
|
-
function makeStakingItem(id: number): APIStakingType {
|
|
80
|
-
return { id }
|
|
74
|
+
function makeStakingItem(id: number): DeepPartial<APIStakingType> {
|
|
75
|
+
return { id }
|
|
81
76
|
}
|
|
82
77
|
|
|
83
|
-
function makeOperation(id: number): APIOperation {
|
|
78
|
+
function makeOperation(id: number): DeepPartial<APIOperation> {
|
|
84
79
|
return {
|
|
85
80
|
id,
|
|
86
81
|
type: 'transaction',
|
|
@@ -92,15 +87,15 @@ function makeOperation(id: number): APIOperation {
|
|
|
92
87
|
initiator: null,
|
|
93
88
|
sender: null,
|
|
94
89
|
target: null,
|
|
95
|
-
}
|
|
90
|
+
}
|
|
96
91
|
}
|
|
97
92
|
|
|
98
|
-
function makeTokenWithTxId(id: number, transactionId?: number): APITokenTransfer {
|
|
99
|
-
return { ...makeTokenItem(id), transactionId }
|
|
93
|
+
function makeTokenWithTxId(id: number, transactionId?: number): DeepPartial<APITokenTransfer> {
|
|
94
|
+
return { ...makeTokenItem(id), transactionId }
|
|
100
95
|
}
|
|
101
96
|
|
|
102
|
-
function makeTokenWithOrigId(id: number, originationId?: number): APITokenTransfer {
|
|
103
|
-
return { ...makeTokenItem(id), originationId }
|
|
97
|
+
function makeTokenWithOrigId(id: number, originationId?: number): DeepPartial<APITokenTransfer> {
|
|
98
|
+
return { ...makeTokenItem(id), originationId }
|
|
104
99
|
}
|
|
105
100
|
|
|
106
101
|
const localSpies: jest.SpyInstance[] = []
|
|
@@ -127,7 +122,7 @@ describe('tzkt network API', () => {
|
|
|
127
122
|
|
|
128
123
|
describe('api.getBlockCount', () => {
|
|
129
124
|
it('calls the blocks count endpoint and returns the number', async () => {
|
|
130
|
-
mockedNetwork.mockReturnValue(networkResponse(12_345)
|
|
125
|
+
mockedNetwork.mockReturnValue(networkResponse(12_345))
|
|
131
126
|
|
|
132
127
|
const result = await api.getBlockCount()
|
|
133
128
|
|
|
@@ -147,7 +142,7 @@ describe('tzkt network API', () => {
|
|
|
147
142
|
describe('api.getLastBlock', () => {
|
|
148
143
|
it('returns hash, level and date from the first block in the sorted list', async () => {
|
|
149
144
|
const blocks = [makeApiBlock(9_001)]
|
|
150
|
-
mockedNetwork.mockReturnValue(networkResponse(blocks)
|
|
145
|
+
mockedNetwork.mockReturnValue(networkResponse(blocks))
|
|
151
146
|
|
|
152
147
|
const result = await api.getLastBlock()
|
|
153
148
|
|
|
@@ -171,8 +166,8 @@ describe('tzkt network API', () => {
|
|
|
171
166
|
|
|
172
167
|
describe('api.getAccountByAddress', () => {
|
|
173
168
|
it('calls the account endpoint and returns the account payload', async () => {
|
|
174
|
-
const account = { type: 'empty', address: 'tz1abc', counter: 0 }
|
|
175
|
-
mockedNetwork.mockReturnValue(networkResponse(account)
|
|
169
|
+
const account: DeepPartial<APIAccount> = { type: 'empty', address: 'tz1abc', counter: 0 }
|
|
170
|
+
mockedNetwork.mockReturnValue(networkResponse(account))
|
|
176
171
|
|
|
177
172
|
const result = await api.getAccountByAddress('tz1abc')
|
|
178
173
|
|
|
@@ -185,8 +180,8 @@ describe('tzkt network API', () => {
|
|
|
185
180
|
})
|
|
186
181
|
|
|
187
182
|
it('coalesces concurrent calls for the same address into a single request', async () => {
|
|
188
|
-
const account = { type: 'user', address: 'tz1dup', revealed: true }
|
|
189
|
-
mockedNetwork.mockReturnValue(networkResponse(account)
|
|
183
|
+
const account: DeepPartial<APIAccount> = { type: 'user', address: 'tz1dup', revealed: true }
|
|
184
|
+
mockedNetwork.mockReturnValue(networkResponse(account))
|
|
190
185
|
|
|
191
186
|
const [first, second] = await Promise.all([
|
|
192
187
|
api.getAccountByAddress('tz1dup'),
|
|
@@ -205,8 +200,8 @@ describe('tzkt network API', () => {
|
|
|
205
200
|
|
|
206
201
|
describe('api.getAccountOperations', () => {
|
|
207
202
|
it('requests operations with serialized query', async () => {
|
|
208
|
-
const ops: APIOperation[] = [makeOperation(1)]
|
|
209
|
-
mockedNetwork.mockReturnValue(networkResponse(ops)
|
|
203
|
+
const ops: DeepPartial<APIOperation>[] = [makeOperation(1)]
|
|
204
|
+
mockedNetwork.mockReturnValue(networkResponse(ops))
|
|
210
205
|
|
|
211
206
|
const result = await api.getAccountOperations('tz1addr', {
|
|
212
207
|
lastId: 10,
|
|
@@ -216,7 +211,7 @@ describe('tzkt network API', () => {
|
|
|
216
211
|
})
|
|
217
212
|
|
|
218
213
|
expect(result).toEqual(ops)
|
|
219
|
-
const call = mockedNetwork.mock.calls[0][0]
|
|
214
|
+
const call = mockedNetwork.mock.calls[0][0]
|
|
220
215
|
expect(call.url).toContain('/v1/accounts/tz1addr/operations')
|
|
221
216
|
expect(call.url).toContain('lastId=10')
|
|
222
217
|
expect(call.url).toContain('limit=50')
|
|
@@ -225,10 +220,10 @@ describe('tzkt network API', () => {
|
|
|
225
220
|
})
|
|
226
221
|
|
|
227
222
|
it('omits undefined optional fields from the serialized query', async () => {
|
|
228
|
-
const ops: APIOperation[] = [makeOperation(1)]
|
|
229
|
-
mockedNetwork.mockReturnValue(networkResponse(ops)
|
|
223
|
+
const ops: DeepPartial<APIOperation>[] = [makeOperation(1)]
|
|
224
|
+
mockedNetwork.mockReturnValue(networkResponse(ops))
|
|
230
225
|
const query = {
|
|
231
|
-
lastId: undefined
|
|
226
|
+
lastId: undefined,
|
|
232
227
|
limit: 40,
|
|
233
228
|
sort: 'Ascending' as const,
|
|
234
229
|
'level.ge': 0,
|
|
@@ -236,7 +231,7 @@ describe('tzkt network API', () => {
|
|
|
236
231
|
|
|
237
232
|
await api.getAccountOperations('tz1addr', query)
|
|
238
233
|
|
|
239
|
-
const call = mockedNetwork.mock.calls[0][0]
|
|
234
|
+
const call = mockedNetwork.mock.calls[0][0]
|
|
240
235
|
expect(call.url).not.toMatch(/lastId=/)
|
|
241
236
|
expect(call.url).toContain('limit=40')
|
|
242
237
|
})
|
|
@@ -248,8 +243,8 @@ describe('tzkt network API', () => {
|
|
|
248
243
|
|
|
249
244
|
describe('api.getOperationsTransactions', () => {
|
|
250
245
|
it('fetches without cursor and strips undefined extra args', async () => {
|
|
251
|
-
const txs: APITransactionType[] = [makeTxItem(1)]
|
|
252
|
-
mockedNetwork.mockReturnValue(networkResponse(txs)
|
|
246
|
+
const txs: DeepPartial<APITransactionType>[] = [makeTxItem(1)]
|
|
247
|
+
mockedNetwork.mockReturnValue(networkResponse(txs))
|
|
253
248
|
|
|
254
249
|
const result = await api.getOperationsTransactions(100, undefined, {
|
|
255
250
|
foo: undefined,
|
|
@@ -257,7 +252,7 @@ describe('tzkt network API', () => {
|
|
|
257
252
|
})
|
|
258
253
|
|
|
259
254
|
expect(result).toEqual(txs)
|
|
260
|
-
const params =
|
|
255
|
+
const params = mockedNetwork.mock.calls[0][0].params
|
|
261
256
|
expect(params).toMatchObject({
|
|
262
257
|
'level.gte': 100,
|
|
263
258
|
limit: 1000,
|
|
@@ -274,12 +269,12 @@ describe('tzkt network API', () => {
|
|
|
274
269
|
})
|
|
275
270
|
|
|
276
271
|
it('includes offset.cr when cursor is set', async () => {
|
|
277
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
272
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
278
273
|
|
|
279
274
|
await api.getOperationsTransactions(5, 999)
|
|
280
275
|
|
|
281
|
-
const params =
|
|
282
|
-
expect(params
|
|
276
|
+
const params = mockedNetwork.mock.calls[0][0].params
|
|
277
|
+
expect(params).toMatchObject({ 'offset.cr': 999 })
|
|
283
278
|
})
|
|
284
279
|
})
|
|
285
280
|
|
|
@@ -289,10 +284,10 @@ describe('tzkt network API', () => {
|
|
|
289
284
|
|
|
290
285
|
describe('api.getOperationsOrigination', () => {
|
|
291
286
|
it('fetches without cursor and strips undefined extra args', async () => {
|
|
292
|
-
const originations:
|
|
293
|
-
{ id: 1, hash: 'h1', block: 'b1' }
|
|
287
|
+
const originations: DeepPartial<APITransactionType & { hash: string; block: string }>[] = [
|
|
288
|
+
{ id: 1, hash: 'h1', block: 'b1' },
|
|
294
289
|
]
|
|
295
|
-
mockedNetwork.mockReturnValue(networkResponse(originations)
|
|
290
|
+
mockedNetwork.mockReturnValue(networkResponse(originations))
|
|
296
291
|
|
|
297
292
|
const result = await api.getOperationsOrigination(100, undefined, {
|
|
298
293
|
foo: undefined,
|
|
@@ -300,7 +295,7 @@ describe('tzkt network API', () => {
|
|
|
300
295
|
})
|
|
301
296
|
|
|
302
297
|
expect(result).toEqual(originations)
|
|
303
|
-
const params =
|
|
298
|
+
const params = mockedNetwork.mock.calls[0][0].params
|
|
304
299
|
expect(params).toMatchObject({
|
|
305
300
|
'level.gte': 100,
|
|
306
301
|
limit: 1000,
|
|
@@ -317,12 +312,12 @@ describe('tzkt network API', () => {
|
|
|
317
312
|
})
|
|
318
313
|
|
|
319
314
|
it('includes offset.cr when cursor is set', async () => {
|
|
320
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
315
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
321
316
|
|
|
322
317
|
await api.getOperationsOrigination(5, 999)
|
|
323
318
|
|
|
324
|
-
const params =
|
|
325
|
-
expect(params
|
|
319
|
+
const params = mockedNetwork.mock.calls[0][0].params
|
|
320
|
+
expect(params).toMatchObject({ 'offset.cr': 999 })
|
|
326
321
|
})
|
|
327
322
|
})
|
|
328
323
|
|
|
@@ -332,8 +327,8 @@ describe('tzkt network API', () => {
|
|
|
332
327
|
|
|
333
328
|
describe('api.getTokenTransfers', () => {
|
|
334
329
|
it('passes through params and strips undefined extra args', async () => {
|
|
335
|
-
const transfers: APITokenTransfer[] = [makeTokenItem(1)]
|
|
336
|
-
mockedNetwork.mockReturnValue(networkResponse(transfers)
|
|
330
|
+
const transfers: DeepPartial<APITokenTransfer>[] = [makeTokenItem(1)]
|
|
331
|
+
mockedNetwork.mockReturnValue(networkResponse(transfers))
|
|
337
332
|
|
|
338
333
|
const result = await api.getTokenTransfers({
|
|
339
334
|
'level.gte': 200,
|
|
@@ -342,7 +337,7 @@ describe('tzkt network API', () => {
|
|
|
342
337
|
})
|
|
343
338
|
|
|
344
339
|
expect(result).toEqual(transfers)
|
|
345
|
-
const params =
|
|
340
|
+
const params = mockedNetwork.mock.calls[0][0].params
|
|
346
341
|
expect(params).toMatchObject({
|
|
347
342
|
'level.gte': 200,
|
|
348
343
|
select: 'id',
|
|
@@ -365,12 +360,9 @@ describe('tzkt network API', () => {
|
|
|
365
360
|
const spyTx = spyOnApi('getOperationsTransactions')
|
|
366
361
|
const spyOrig = spyOnApi('getOperationsOrigination')
|
|
367
362
|
|
|
368
|
-
mockedNetwork.mockImplementation(async (config
|
|
369
|
-
if (config.url
|
|
370
|
-
return networkResponse([
|
|
371
|
-
makeTokenWithTxId(1, undefined),
|
|
372
|
-
makeTokenWithTxId(2, undefined),
|
|
373
|
-
]) as ReturnType<typeof network>
|
|
363
|
+
mockedNetwork.mockImplementation(async (config) => {
|
|
364
|
+
if (config.url?.includes('/v1/tokens/transfers')) {
|
|
365
|
+
return networkResponse([makeTokenWithTxId(1, undefined), makeTokenWithTxId(2, undefined)])
|
|
374
366
|
}
|
|
375
367
|
throw new Error(`unexpected url: ${config.url}`)
|
|
376
368
|
})
|
|
@@ -382,10 +374,7 @@ describe('tzkt network API', () => {
|
|
|
382
374
|
expect(spyTx).not.toHaveBeenCalled()
|
|
383
375
|
expect(spyOrig).not.toHaveBeenCalled()
|
|
384
376
|
expect(result).toEqual([])
|
|
385
|
-
const firstCall = mockedNetwork.mock.calls[0]?.[0]
|
|
386
|
-
url: string
|
|
387
|
-
params?: Record<string, unknown>
|
|
388
|
-
}
|
|
377
|
+
const firstCall = mockedNetwork.mock.calls[0]?.[0]
|
|
389
378
|
expect(firstCall.params).toMatchObject({
|
|
390
379
|
'level.ge': 10,
|
|
391
380
|
'sort.asc': 'id',
|
|
@@ -398,20 +387,12 @@ describe('tzkt network API', () => {
|
|
|
398
387
|
it('joins operation hashes and uses empty string when no match', async () => {
|
|
399
388
|
const spyTx = spyOnApi('getOperationsTransactions')
|
|
400
389
|
const spyOrig = spyOnApi('getOperationsOrigination')
|
|
401
|
-
mockedNetwork.mockImplementation(async (config
|
|
402
|
-
if (config.url
|
|
403
|
-
return networkResponse([
|
|
404
|
-
makeTokenWithTxId(1, 100),
|
|
405
|
-
makeTokenWithTxId(2, 200),
|
|
406
|
-
]) as ReturnType<typeof network>
|
|
390
|
+
mockedNetwork.mockImplementation(async (config) => {
|
|
391
|
+
if (config.url?.includes('/v1/tokens/transfers')) {
|
|
392
|
+
return networkResponse([makeTokenWithTxId(1, 100), makeTokenWithTxId(2, 200)])
|
|
407
393
|
}
|
|
408
|
-
if (config.url
|
|
409
|
-
return networkResponse([
|
|
410
|
-
{ id: 100, hash: 'h100', block: 'BLK100' } as APITransactionType & {
|
|
411
|
-
hash: string
|
|
412
|
-
block: string
|
|
413
|
-
},
|
|
414
|
-
]) as ReturnType<typeof network>
|
|
394
|
+
if (config.url?.includes('/v1/operations/transactions')) {
|
|
395
|
+
return networkResponse([{ id: 100, hash: 'h100', block: 'BLK100' }])
|
|
415
396
|
}
|
|
416
397
|
throw new Error(`unexpected url: ${config.url}`)
|
|
417
398
|
})
|
|
@@ -433,24 +414,15 @@ describe('tzkt network API', () => {
|
|
|
433
414
|
it('attaches parent hash and block from originations when only originationIds are present', async () => {
|
|
434
415
|
const spyTx = spyOnApi('getOperationsTransactions')
|
|
435
416
|
const spyOrig = spyOnApi('getOperationsOrigination')
|
|
436
|
-
mockedNetwork.mockImplementation(async (config
|
|
437
|
-
if (config.url
|
|
438
|
-
return networkResponse([
|
|
439
|
-
makeTokenWithOrigId(1, 100),
|
|
440
|
-
makeTokenWithOrigId(2, 200),
|
|
441
|
-
]) as ReturnType<typeof network>
|
|
417
|
+
mockedNetwork.mockImplementation(async (config) => {
|
|
418
|
+
if (config.url?.includes('/v1/tokens/transfers')) {
|
|
419
|
+
return networkResponse([makeTokenWithOrigId(1, 100), makeTokenWithOrigId(2, 200)])
|
|
442
420
|
}
|
|
443
|
-
if (config.url
|
|
421
|
+
if (config.url?.includes('/v1/operations/originations')) {
|
|
444
422
|
return networkResponse([
|
|
445
|
-
{ id: 100, hash: 'h100', block: 'BLK100' }
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
},
|
|
449
|
-
{ id: 200, hash: 'h200', block: 'BLK200' } as APITransactionType & {
|
|
450
|
-
hash: string
|
|
451
|
-
block: string
|
|
452
|
-
},
|
|
453
|
-
]) as ReturnType<typeof network>
|
|
423
|
+
{ id: 100, hash: 'h100', block: 'BLK100' },
|
|
424
|
+
{ id: 200, hash: 'h200', block: 'BLK200' },
|
|
425
|
+
])
|
|
454
426
|
}
|
|
455
427
|
throw new Error(`unexpected url: ${config.url}`)
|
|
456
428
|
})
|
|
@@ -472,28 +444,15 @@ describe('tzkt network API', () => {
|
|
|
472
444
|
it('joins both transactions and originations when both ids are present', async () => {
|
|
473
445
|
const spyTx = spyOnApi('getOperationsTransactions')
|
|
474
446
|
const spyOrig = spyOnApi('getOperationsOrigination')
|
|
475
|
-
mockedNetwork.mockImplementation(async (config
|
|
476
|
-
if (config.url
|
|
477
|
-
return networkResponse([
|
|
478
|
-
makeTokenWithTxId(1, 100),
|
|
479
|
-
makeTokenWithOrigId(2, 500),
|
|
480
|
-
]) as ReturnType<typeof network>
|
|
447
|
+
mockedNetwork.mockImplementation(async (config) => {
|
|
448
|
+
if (config.url?.includes('/v1/tokens/transfers')) {
|
|
449
|
+
return networkResponse([makeTokenWithTxId(1, 100), makeTokenWithOrigId(2, 500)])
|
|
481
450
|
}
|
|
482
|
-
if (config.url
|
|
483
|
-
return networkResponse([
|
|
484
|
-
{ id: 100, hash: 'hTx', block: 'BLK_TX' } as APITransactionType & {
|
|
485
|
-
hash: string
|
|
486
|
-
block: string
|
|
487
|
-
},
|
|
488
|
-
]) as ReturnType<typeof network>
|
|
451
|
+
if (config.url?.includes('/v1/operations/transactions')) {
|
|
452
|
+
return networkResponse([{ id: 100, hash: 'hTx', block: 'BLK_TX' }])
|
|
489
453
|
}
|
|
490
|
-
if (config.url
|
|
491
|
-
return networkResponse([
|
|
492
|
-
{ id: 500, hash: 'hOrig', block: 'BLK_ORIG' } as APITransactionType & {
|
|
493
|
-
hash: string
|
|
494
|
-
block: string
|
|
495
|
-
},
|
|
496
|
-
]) as ReturnType<typeof network>
|
|
454
|
+
if (config.url?.includes('/v1/operations/originations')) {
|
|
455
|
+
return networkResponse([{ id: 500, hash: 'hOrig', block: 'BLK_ORIG' }])
|
|
497
456
|
}
|
|
498
457
|
throw new Error(`unexpected url: ${config.url}`)
|
|
499
458
|
})
|
|
@@ -515,29 +474,20 @@ describe('tzkt network API', () => {
|
|
|
515
474
|
})
|
|
516
475
|
|
|
517
476
|
it('keeps partial hash/block from the parent transaction without dropping transfers', async () => {
|
|
518
|
-
mockedNetwork.mockImplementation(async (config
|
|
519
|
-
if (config.url
|
|
477
|
+
mockedNetwork.mockImplementation(async (config) => {
|
|
478
|
+
if (config.url?.includes('/v1/tokens/transfers')) {
|
|
520
479
|
return networkResponse([
|
|
521
480
|
makeTokenWithTxId(1, 100),
|
|
522
481
|
makeTokenWithTxId(2, 200),
|
|
523
482
|
makeTokenWithTxId(3, 300),
|
|
524
|
-
])
|
|
483
|
+
])
|
|
525
484
|
}
|
|
526
|
-
if (config.url
|
|
485
|
+
if (config.url?.includes('/v1/operations/transactions')) {
|
|
527
486
|
return networkResponse([
|
|
528
|
-
{ id: 100, hash: 'h100', block: '' }
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
{ id: 200, hash: '', block: 'BLK200' } as APITransactionType & {
|
|
533
|
-
hash: string
|
|
534
|
-
block: string
|
|
535
|
-
},
|
|
536
|
-
{ id: 300, hash: 'h300', block: 'BLK300' } as APITransactionType & {
|
|
537
|
-
hash: string
|
|
538
|
-
block: string
|
|
539
|
-
},
|
|
540
|
-
]) as ReturnType<typeof network>
|
|
487
|
+
{ id: 100, hash: 'h100', block: '' },
|
|
488
|
+
{ id: 200, hash: '', block: 'BLK200' },
|
|
489
|
+
{ id: 300, hash: 'h300', block: 'BLK300' },
|
|
490
|
+
])
|
|
541
491
|
}
|
|
542
492
|
throw new Error(`unexpected url: ${config.url}`)
|
|
543
493
|
})
|
|
@@ -556,29 +506,20 @@ describe('tzkt network API', () => {
|
|
|
556
506
|
})
|
|
557
507
|
|
|
558
508
|
it('keeps partial hash/block from the parent origination without dropping transfers', async () => {
|
|
559
|
-
mockedNetwork.mockImplementation(async (config
|
|
560
|
-
if (config.url
|
|
509
|
+
mockedNetwork.mockImplementation(async (config) => {
|
|
510
|
+
if (config.url?.includes('/v1/tokens/transfers')) {
|
|
561
511
|
return networkResponse([
|
|
562
512
|
makeTokenWithOrigId(1, 100),
|
|
563
513
|
makeTokenWithOrigId(2, 200),
|
|
564
514
|
makeTokenWithOrigId(3, 300),
|
|
565
|
-
])
|
|
515
|
+
])
|
|
566
516
|
}
|
|
567
|
-
if (config.url
|
|
517
|
+
if (config.url?.includes('/v1/operations/originations')) {
|
|
568
518
|
return networkResponse([
|
|
569
|
-
{ id: 100, hash: 'h100', block: '' }
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
{ id: 200, hash: '', block: 'BLK200' } as APITransactionType & {
|
|
574
|
-
hash: string
|
|
575
|
-
block: string
|
|
576
|
-
},
|
|
577
|
-
{ id: 300, hash: 'h300', block: 'BLK300' } as APITransactionType & {
|
|
578
|
-
hash: string
|
|
579
|
-
block: string
|
|
580
|
-
},
|
|
581
|
-
]) as ReturnType<typeof network>
|
|
519
|
+
{ id: 100, hash: 'h100', block: '' },
|
|
520
|
+
{ id: 200, hash: '', block: 'BLK200' },
|
|
521
|
+
{ id: 300, hash: 'h300', block: 'BLK300' },
|
|
522
|
+
])
|
|
582
523
|
}
|
|
583
524
|
throw new Error(`unexpected url: ${config.url}`)
|
|
584
525
|
})
|
|
@@ -597,7 +538,7 @@ describe('tzkt network API', () => {
|
|
|
597
538
|
})
|
|
598
539
|
|
|
599
540
|
it('uses sort.desc=id when sort is Descending and forwards level.lt / level.gt', async () => {
|
|
600
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
541
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
601
542
|
|
|
602
543
|
await api.getAccountTokenTransfers('tz1sort', {
|
|
603
544
|
sort: 'Descending',
|
|
@@ -606,7 +547,7 @@ describe('tzkt network API', () => {
|
|
|
606
547
|
limit: 50,
|
|
607
548
|
})
|
|
608
549
|
|
|
609
|
-
const params =
|
|
550
|
+
const params = mockedNetwork.mock.calls[0][0].params
|
|
610
551
|
expect(params).toMatchObject({
|
|
611
552
|
'sort.desc': 'id',
|
|
612
553
|
'level.ge': 1,
|
|
@@ -617,7 +558,7 @@ describe('tzkt network API', () => {
|
|
|
617
558
|
})
|
|
618
559
|
|
|
619
560
|
it('forwards level.gt for ascending continuation windows', async () => {
|
|
620
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
561
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
621
562
|
|
|
622
563
|
await api.getAccountTokenTransfers('tz1asc', {
|
|
623
564
|
sort: 'Ascending',
|
|
@@ -625,7 +566,7 @@ describe('tzkt network API', () => {
|
|
|
625
566
|
'level.gt': 500,
|
|
626
567
|
})
|
|
627
568
|
|
|
628
|
-
const params =
|
|
569
|
+
const params = mockedNetwork.mock.calls[0][0].params
|
|
629
570
|
expect(params).toMatchObject({
|
|
630
571
|
'sort.asc': 'id',
|
|
631
572
|
'level.ge': 100,
|
|
@@ -634,25 +575,28 @@ describe('tzkt network API', () => {
|
|
|
634
575
|
})
|
|
635
576
|
|
|
636
577
|
it('batches transaction id.in lookups in chunks of 100 when more than 100 ids are present', async () => {
|
|
637
|
-
|
|
638
|
-
|
|
578
|
+
spyOnApi('getOperationsTransactions')
|
|
579
|
+
spyOnApi('getOperationsOrigination')
|
|
580
|
+
const spyTx = jest.mocked<DeepPartialReturn<typeof api.getOperationsTransactions>>(
|
|
581
|
+
api.getOperationsTransactions
|
|
582
|
+
)
|
|
583
|
+
const spyOrig = jest.mocked<DeepPartialReturn<typeof api.getOperationsOrigination>>(
|
|
584
|
+
api.getOperationsOrigination
|
|
585
|
+
)
|
|
639
586
|
|
|
640
587
|
const tokens = Array.from({ length: 150 }, (_, i) => makeTokenWithTxId(i + 1, i + 1))
|
|
641
588
|
|
|
642
|
-
mockedNetwork.mockImplementation(async (config
|
|
643
|
-
if (config.url
|
|
644
|
-
return networkResponse(tokens)
|
|
589
|
+
mockedNetwork.mockImplementation(async (config) => {
|
|
590
|
+
if (config.url?.includes('/v1/tokens/transfers')) {
|
|
591
|
+
return networkResponse(tokens)
|
|
645
592
|
}
|
|
646
593
|
throw new Error(`unexpected url: ${config.url}`)
|
|
647
594
|
})
|
|
648
595
|
|
|
649
596
|
spyTx.mockImplementation(async (_level, _cursor, params) => {
|
|
650
|
-
const
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
hash: `h${id}`,
|
|
654
|
-
block: `BLK${id}`,
|
|
655
|
-
})) as (APITransactionType & { hash: string; block: string })[]
|
|
597
|
+
const idIn = params?.['id.in']
|
|
598
|
+
const ids = typeof idIn === 'string' ? idIn.split(',').map(Number) : []
|
|
599
|
+
return ids.map((id) => ({ id, hash: `h${id}`, block: `BLK${id}` }))
|
|
656
600
|
})
|
|
657
601
|
|
|
658
602
|
const result = await api.getAccountTokenTransfers('tz1batch', {
|
|
@@ -675,25 +619,28 @@ describe('tzkt network API', () => {
|
|
|
675
619
|
})
|
|
676
620
|
|
|
677
621
|
it('batches origination id.in lookups in chunks of 100 when more than 100 ids are present', async () => {
|
|
678
|
-
|
|
679
|
-
|
|
622
|
+
spyOnApi('getOperationsTransactions')
|
|
623
|
+
spyOnApi('getOperationsOrigination')
|
|
624
|
+
const spyTx = jest.mocked<DeepPartialReturn<typeof api.getOperationsTransactions>>(
|
|
625
|
+
api.getOperationsTransactions
|
|
626
|
+
)
|
|
627
|
+
const spyOrig = jest.mocked<DeepPartialReturn<typeof api.getOperationsOrigination>>(
|
|
628
|
+
api.getOperationsOrigination
|
|
629
|
+
)
|
|
680
630
|
|
|
681
631
|
const tokens = Array.from({ length: 150 }, (_, i) => makeTokenWithOrigId(i + 1, i + 1))
|
|
682
632
|
|
|
683
|
-
mockedNetwork.mockImplementation(async (config
|
|
684
|
-
if (config.url
|
|
685
|
-
return networkResponse(tokens)
|
|
633
|
+
mockedNetwork.mockImplementation(async (config) => {
|
|
634
|
+
if (config.url?.includes('/v1/tokens/transfers')) {
|
|
635
|
+
return networkResponse(tokens)
|
|
686
636
|
}
|
|
687
637
|
throw new Error(`unexpected url: ${config.url}`)
|
|
688
638
|
})
|
|
689
639
|
|
|
690
640
|
spyOrig.mockImplementation(async (_level, _cursor, params) => {
|
|
691
|
-
const
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
hash: `h${id}`,
|
|
695
|
-
block: `BLK${id}`,
|
|
696
|
-
})) as (APITransactionType & { hash: string; block: string })[]
|
|
641
|
+
const idIn = params?.['id.in']
|
|
642
|
+
const ids = typeof idIn === 'string' ? idIn.split(',').map(Number) : []
|
|
643
|
+
return ids.map((id) => ({ id, hash: `h${id}`, block: `BLK${id}` }))
|
|
697
644
|
})
|
|
698
645
|
|
|
699
646
|
const result = await api.getAccountTokenTransfers('tz1batchOrig', {
|
|
@@ -722,7 +669,7 @@ describe('tzkt network API', () => {
|
|
|
722
669
|
|
|
723
670
|
describe('api.getUnstakeRequestsFinalizable', () => {
|
|
724
671
|
it('queries finalizable unstake requests and sums actualAmount', async () => {
|
|
725
|
-
mockedNetwork.mockReturnValue(networkResponse([100, 250, 7])
|
|
672
|
+
mockedNetwork.mockReturnValue(networkResponse([100, 250, 7]))
|
|
726
673
|
|
|
727
674
|
const result = await api.getUnstakeRequestsFinalizable('tz1abc')
|
|
728
675
|
|
|
@@ -741,7 +688,7 @@ describe('tzkt network API', () => {
|
|
|
741
688
|
})
|
|
742
689
|
|
|
743
690
|
it('returns 0n when no finalizable requests exist', async () => {
|
|
744
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
691
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
745
692
|
|
|
746
693
|
const result = await api.getUnstakeRequestsFinalizable('tz1empty')
|
|
747
694
|
|
|
@@ -775,7 +722,7 @@ describe('tzkt network API', () => {
|
|
|
775
722
|
actualAmount: 40,
|
|
776
723
|
},
|
|
777
724
|
]
|
|
778
|
-
mockedNetwork.mockReturnValue(networkResponse(fixture)
|
|
725
|
+
mockedNetwork.mockReturnValue(networkResponse(fixture))
|
|
779
726
|
|
|
780
727
|
const result = await api.getUnstakeRequests('tz1abc')
|
|
781
728
|
|
|
@@ -794,7 +741,7 @@ describe('tzkt network API', () => {
|
|
|
794
741
|
})
|
|
795
742
|
|
|
796
743
|
it('returns an empty array when no requests match', async () => {
|
|
797
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
744
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
798
745
|
|
|
799
746
|
const result = await api.getUnstakeRequests('tz1empty')
|
|
800
747
|
|
|
@@ -808,8 +755,8 @@ describe('tzkt network API', () => {
|
|
|
808
755
|
|
|
809
756
|
describe('api.getTokensBalances', () => {
|
|
810
757
|
it('requests all FA2 balances for the account when no filter is passed', async () => {
|
|
811
|
-
const balances = [{ id: 1 }
|
|
812
|
-
mockedNetwork.mockReturnValue(networkResponse(balances)
|
|
758
|
+
const balances: DeepPartial<APITokenBalance>[] = [{ id: 1 }]
|
|
759
|
+
mockedNetwork.mockReturnValue(networkResponse(balances))
|
|
813
760
|
|
|
814
761
|
const result = await api.getTokensBalances('tz1bal')
|
|
815
762
|
|
|
@@ -826,8 +773,8 @@ describe('tzkt network API', () => {
|
|
|
826
773
|
})
|
|
827
774
|
|
|
828
775
|
it('requests a specific FA2 contract and token id when a filter is passed', async () => {
|
|
829
|
-
const balances = [{ id: 2 }
|
|
830
|
-
mockedNetwork.mockReturnValue(networkResponse(balances)
|
|
776
|
+
const balances: DeepPartial<APITokenBalance>[] = [{ id: 2 }]
|
|
777
|
+
mockedNetwork.mockReturnValue(networkResponse(balances))
|
|
831
778
|
|
|
832
779
|
const result = await api.getTokensBalances('tz1bal', {
|
|
833
780
|
contractAddress: 'KT1abc',
|
|
@@ -859,7 +806,7 @@ describe('tzkt network API', () => {
|
|
|
859
806
|
// `.data` is the page. The page cursor (`lastId`) is serialized into the request URL.
|
|
860
807
|
describe('fetchAllTransactions', () => {
|
|
861
808
|
it('returns empty when the first page is empty', async () => {
|
|
862
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
809
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
863
810
|
|
|
864
811
|
const result = await fetchAllTransactions(config, 'tz1acc')
|
|
865
812
|
|
|
@@ -868,30 +815,30 @@ describe('tzkt network API', () => {
|
|
|
868
815
|
|
|
869
816
|
it('concatenates pages until an empty response', async () => {
|
|
870
817
|
mockedNetwork
|
|
871
|
-
.mockReturnValueOnce(networkResponse([makeOperation(1)])
|
|
872
|
-
.mockReturnValueOnce(networkResponse([makeOperation(2)])
|
|
873
|
-
.mockReturnValueOnce(networkResponse([])
|
|
818
|
+
.mockReturnValueOnce(networkResponse([makeOperation(1)]))
|
|
819
|
+
.mockReturnValueOnce(networkResponse([makeOperation(2)]))
|
|
820
|
+
.mockReturnValueOnce(networkResponse([]))
|
|
874
821
|
|
|
875
822
|
const result = await fetchAllTransactions(config, 'tz1acc')
|
|
876
823
|
|
|
877
824
|
expect(result).toEqual([makeOperation(1), makeOperation(2)])
|
|
878
825
|
expect(mockedNetwork).toHaveBeenCalledTimes(3)
|
|
879
826
|
// First page: no cursor (lastId undefined is stripped from the query), sort ascending.
|
|
880
|
-
const firstUrl =
|
|
827
|
+
const firstUrl = mockedNetwork.mock.calls[0][0].url
|
|
881
828
|
expect(firstUrl).toContain('/v1/accounts/tz1acc/operations')
|
|
882
829
|
expect(firstUrl).not.toMatch(/lastId=/)
|
|
883
830
|
expect(firstUrl).toContain('sort=Ascending')
|
|
884
831
|
expect(firstUrl).toContain('level.ge=0')
|
|
885
832
|
// Second page: cursor advances to the id of the last op returned by the first page.
|
|
886
|
-
const secondUrl =
|
|
833
|
+
const secondUrl = mockedNetwork.mock.calls[1][0].url
|
|
887
834
|
expect(secondUrl).toContain('lastId=1')
|
|
888
835
|
expect(secondUrl).toContain('sort=Ascending')
|
|
889
836
|
expect(secondUrl).toContain('level.ge=0')
|
|
890
837
|
})
|
|
891
838
|
|
|
892
839
|
it('logs and returns when the last operation has a falsy id', async () => {
|
|
893
|
-
const opMissingId = { ...makeOperation(1), id: 0 }
|
|
894
|
-
mockedNetwork.mockReturnValue(networkResponse([opMissingId])
|
|
840
|
+
const opMissingId: DeepPartial<APIOperation> = { ...makeOperation(1), id: 0 }
|
|
841
|
+
mockedNetwork.mockReturnValue(networkResponse([opMissingId]))
|
|
895
842
|
|
|
896
843
|
const result = await fetchAllTransactions(config, 'tz1acc')
|
|
897
844
|
|
|
@@ -903,9 +850,7 @@ describe('tzkt network API', () => {
|
|
|
903
850
|
// Always return one op with a truthy id so the loop would continue without the cap. The id
|
|
904
851
|
// increases every call so cursors keep advancing (matching the previous spy implementation).
|
|
905
852
|
let nextId = 0
|
|
906
|
-
mockedNetwork.mockImplementation(
|
|
907
|
-
() => networkResponse([makeOperation(++nextId)]) as ReturnType<typeof network>
|
|
908
|
-
)
|
|
853
|
+
mockedNetwork.mockImplementation(() => networkResponse([makeOperation(++nextId)]))
|
|
909
854
|
|
|
910
855
|
const result = await fetchAllTransactions(config, 'tz1acc')
|
|
911
856
|
|
|
@@ -921,7 +866,7 @@ describe('tzkt network API', () => {
|
|
|
921
866
|
describe('api.getBlockByLevel', () => {
|
|
922
867
|
it('calls the correct URL and returns the block', async () => {
|
|
923
868
|
const block = makeApiBlock(999)
|
|
924
|
-
mockedNetwork.mockReturnValue(networkResponse(block)
|
|
869
|
+
mockedNetwork.mockReturnValue(networkResponse(block))
|
|
925
870
|
|
|
926
871
|
const result = await api.getBlockByLevel(999)
|
|
927
872
|
|
|
@@ -952,7 +897,7 @@ describe('tzkt network API', () => {
|
|
|
952
897
|
networkResponse([
|
|
953
898
|
[1234, 'BL-hash-1234'],
|
|
954
899
|
[1235, 'BL-hash-1235'],
|
|
955
|
-
])
|
|
900
|
+
])
|
|
956
901
|
)
|
|
957
902
|
|
|
958
903
|
const result = await api.getBlockHashesByLevels([1234, 1235])
|
|
@@ -973,9 +918,7 @@ describe('tzkt network API', () => {
|
|
|
973
918
|
})
|
|
974
919
|
|
|
975
920
|
it('omits levels that the API did not return', async () => {
|
|
976
|
-
mockedNetwork.mockReturnValue(
|
|
977
|
-
networkResponse([[1234, 'BL-hash-1234']]) as ReturnType<typeof network>
|
|
978
|
-
)
|
|
921
|
+
mockedNetwork.mockReturnValue(networkResponse([[1234, 'BL-hash-1234']]))
|
|
979
922
|
|
|
980
923
|
const result = await api.getBlockHashesByLevels([1234, 9999])
|
|
981
924
|
|
|
@@ -990,24 +933,24 @@ describe('tzkt network API', () => {
|
|
|
990
933
|
|
|
991
934
|
describe('api.getBlockTransactionsPage', () => {
|
|
992
935
|
it('fetches a page without a cursor', async () => {
|
|
993
|
-
const txs: APITransactionType[] = [makeTxItem(1), makeTxItem(2)]
|
|
994
|
-
mockedNetwork.mockReturnValue(networkResponse(txs)
|
|
936
|
+
const txs: DeepPartial<APITransactionType>[] = [makeTxItem(1), makeTxItem(2)]
|
|
937
|
+
mockedNetwork.mockReturnValue(networkResponse(txs))
|
|
995
938
|
|
|
996
939
|
const result = await api.getBlockTransactionsPage(200)
|
|
997
940
|
|
|
998
941
|
expect(result).toEqual(txs)
|
|
999
|
-
const params =
|
|
942
|
+
const params = mockedNetwork.mock.calls[0][0].params
|
|
1000
943
|
expect(params).toMatchObject({ level: 200, limit: 1000, 'sort.asc': 'id' })
|
|
1001
944
|
expect(params).not.toHaveProperty('offset.cr')
|
|
1002
945
|
})
|
|
1003
946
|
|
|
1004
947
|
it('includes offset.cr in params when cursor is provided', async () => {
|
|
1005
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
948
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
1006
949
|
|
|
1007
950
|
await api.getBlockTransactionsPage(200, 42)
|
|
1008
951
|
|
|
1009
|
-
const params =
|
|
1010
|
-
expect(params
|
|
952
|
+
const params = mockedNetwork.mock.calls[0][0].params
|
|
953
|
+
expect(params).toMatchObject({ 'offset.cr': 42 })
|
|
1011
954
|
})
|
|
1012
955
|
})
|
|
1013
956
|
|
|
@@ -1017,24 +960,24 @@ describe('tzkt network API', () => {
|
|
|
1017
960
|
|
|
1018
961
|
describe('api.getBlockTokenTransfersPage', () => {
|
|
1019
962
|
it('fetches a page without a cursor', async () => {
|
|
1020
|
-
const items: APITokenTransfer[] = [makeTokenItem(10)]
|
|
1021
|
-
mockedNetwork.mockReturnValue(networkResponse(items)
|
|
963
|
+
const items: DeepPartial<APITokenTransfer>[] = [makeTokenItem(10)]
|
|
964
|
+
mockedNetwork.mockReturnValue(networkResponse(items))
|
|
1022
965
|
|
|
1023
966
|
const result = await api.getBlockTokenTransfersPage(300)
|
|
1024
967
|
|
|
1025
968
|
expect(result).toEqual(items)
|
|
1026
|
-
const params =
|
|
969
|
+
const params = mockedNetwork.mock.calls[0][0].params
|
|
1027
970
|
expect(params).toMatchObject({ level: 300, limit: 1000, 'sort.asc': 'id' })
|
|
1028
971
|
expect(params).not.toHaveProperty('offset.cr')
|
|
1029
972
|
})
|
|
1030
973
|
|
|
1031
974
|
it('includes offset.cr in params when cursor is provided', async () => {
|
|
1032
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
975
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
1033
976
|
|
|
1034
977
|
await api.getBlockTokenTransfersPage(300, 77)
|
|
1035
978
|
|
|
1036
|
-
const params =
|
|
1037
|
-
expect(params
|
|
979
|
+
const params = mockedNetwork.mock.calls[0][0].params
|
|
980
|
+
expect(params).toMatchObject({ 'offset.cr': 77 })
|
|
1038
981
|
})
|
|
1039
982
|
})
|
|
1040
983
|
|
|
@@ -1047,7 +990,7 @@ describe('tzkt network API', () => {
|
|
|
1047
990
|
// fetch maps to one `network(...)`; the cursor is passed through as the `offset.cr` param.
|
|
1048
991
|
describe('fetchBlockTransactions', () => {
|
|
1049
992
|
it('returns an empty array when the first page is empty', async () => {
|
|
1050
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
993
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
1051
994
|
|
|
1052
995
|
const result = await fetchBlockTransactions(config, 100)
|
|
1053
996
|
|
|
@@ -1056,7 +999,7 @@ describe('tzkt network API', () => {
|
|
|
1056
999
|
|
|
1057
1000
|
it('returns a single page when the page is smaller than the page size', async () => {
|
|
1058
1001
|
const txs = [makeTxItem(1), makeTxItem(2)]
|
|
1059
|
-
mockedNetwork.mockReturnValue(networkResponse(txs)
|
|
1002
|
+
mockedNetwork.mockReturnValue(networkResponse(txs))
|
|
1060
1003
|
|
|
1061
1004
|
const result = await fetchBlockTransactions(config, 100)
|
|
1062
1005
|
|
|
@@ -1068,27 +1011,25 @@ describe('tzkt network API', () => {
|
|
|
1068
1011
|
const lastPage = [makeTxItem(1001), makeTxItem(1002)]
|
|
1069
1012
|
|
|
1070
1013
|
mockedNetwork
|
|
1071
|
-
.mockReturnValueOnce(networkResponse(fullPage)
|
|
1072
|
-
.mockReturnValueOnce(networkResponse(lastPage)
|
|
1014
|
+
.mockReturnValueOnce(networkResponse(fullPage))
|
|
1015
|
+
.mockReturnValueOnce(networkResponse(lastPage))
|
|
1073
1016
|
|
|
1074
1017
|
const result = await fetchBlockTransactions(config, 100)
|
|
1075
1018
|
|
|
1076
1019
|
expect(result).toHaveLength(1002)
|
|
1077
1020
|
expect(mockedNetwork).toHaveBeenCalledTimes(2)
|
|
1078
|
-
const firstParams =
|
|
1079
|
-
.params
|
|
1021
|
+
const firstParams = mockedNetwork.mock.calls[0][0].params
|
|
1080
1022
|
expect(firstParams).toMatchObject({ level: 100 })
|
|
1081
1023
|
expect(firstParams).not.toHaveProperty('offset.cr')
|
|
1082
1024
|
// cursor = last item id of first page = 1000
|
|
1083
|
-
const secondParams =
|
|
1084
|
-
.params
|
|
1025
|
+
const secondParams = mockedNetwork.mock.calls[1][0].params
|
|
1085
1026
|
expect(secondParams).toMatchObject({ level: 100, 'offset.cr': 1000 })
|
|
1086
1027
|
})
|
|
1087
1028
|
|
|
1088
1029
|
it('stops after maxTxQuery iterations regardless of page length', async () => {
|
|
1089
1030
|
// maxTxQuery = 100 (from mockConfig); every call returns a full page to keep the loop going
|
|
1090
1031
|
const fullPage = Array.from({ length: 1000 }, (_, i) => makeTxItem(i + 1))
|
|
1091
|
-
mockedNetwork.mockReturnValue(networkResponse(fullPage)
|
|
1032
|
+
mockedNetwork.mockReturnValue(networkResponse(fullPage))
|
|
1092
1033
|
|
|
1093
1034
|
const result = await fetchBlockTransactions(config, 100)
|
|
1094
1035
|
|
|
@@ -1108,7 +1049,7 @@ describe('tzkt network API', () => {
|
|
|
1108
1049
|
// Driven through the mocked `network` (see the note on `fetchBlockTransactions`).
|
|
1109
1050
|
describe('fetchBlockTokenTransfers', () => {
|
|
1110
1051
|
it('returns an empty array when the first page is empty', async () => {
|
|
1111
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
1052
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
1112
1053
|
|
|
1113
1054
|
const result = await fetchBlockTokenTransfers(config, 100)
|
|
1114
1055
|
|
|
@@ -1117,7 +1058,7 @@ describe('tzkt network API', () => {
|
|
|
1117
1058
|
|
|
1118
1059
|
it('returns a single page when the page is smaller than the page size', async () => {
|
|
1119
1060
|
const items = [makeTokenItem(1), makeTokenItem(2)]
|
|
1120
|
-
mockedNetwork.mockReturnValue(networkResponse(items)
|
|
1061
|
+
mockedNetwork.mockReturnValue(networkResponse(items))
|
|
1121
1062
|
|
|
1122
1063
|
const result = await fetchBlockTokenTransfers(config, 100)
|
|
1123
1064
|
|
|
@@ -1129,25 +1070,23 @@ describe('tzkt network API', () => {
|
|
|
1129
1070
|
const lastPage = [makeTokenItem(1001)]
|
|
1130
1071
|
|
|
1131
1072
|
mockedNetwork
|
|
1132
|
-
.mockReturnValueOnce(networkResponse(fullPage)
|
|
1133
|
-
.mockReturnValueOnce(networkResponse(lastPage)
|
|
1073
|
+
.mockReturnValueOnce(networkResponse(fullPage))
|
|
1074
|
+
.mockReturnValueOnce(networkResponse(lastPage))
|
|
1134
1075
|
|
|
1135
1076
|
const result = await fetchBlockTokenTransfers(config, 100)
|
|
1136
1077
|
|
|
1137
1078
|
expect(result).toHaveLength(1001)
|
|
1138
1079
|
expect(mockedNetwork).toHaveBeenCalledTimes(2)
|
|
1139
|
-
const firstParams =
|
|
1140
|
-
.params
|
|
1080
|
+
const firstParams = mockedNetwork.mock.calls[0][0].params
|
|
1141
1081
|
expect(firstParams).toMatchObject({ level: 100 })
|
|
1142
1082
|
expect(firstParams).not.toHaveProperty('offset.cr')
|
|
1143
|
-
const secondParams =
|
|
1144
|
-
.params
|
|
1083
|
+
const secondParams = mockedNetwork.mock.calls[1][0].params
|
|
1145
1084
|
expect(secondParams).toMatchObject({ level: 100, 'offset.cr': 1000 })
|
|
1146
1085
|
})
|
|
1147
1086
|
|
|
1148
1087
|
it('stops after maxTxQuery iterations regardless of page length', async () => {
|
|
1149
1088
|
const fullPage = Array.from({ length: 1000 }, (_, i) => makeTokenItem(i + 1))
|
|
1150
|
-
mockedNetwork.mockReturnValue(networkResponse(fullPage)
|
|
1089
|
+
mockedNetwork.mockReturnValue(networkResponse(fullPage))
|
|
1151
1090
|
|
|
1152
1091
|
const result = await fetchBlockTokenTransfers(config, 100)
|
|
1153
1092
|
|
|
@@ -1166,28 +1105,28 @@ describe('tzkt network API', () => {
|
|
|
1166
1105
|
|
|
1167
1106
|
describe('api.getBlockDelegationsPage', () => {
|
|
1168
1107
|
it('fetches a page without a cursor', async () => {
|
|
1169
|
-
const items: APIDelegationType[] = [makeDelegationItem(10)]
|
|
1170
|
-
mockedNetwork.mockReturnValue(networkResponse(items)
|
|
1108
|
+
const items: DeepPartial<APIDelegationType>[] = [makeDelegationItem(10)]
|
|
1109
|
+
mockedNetwork.mockReturnValue(networkResponse(items))
|
|
1171
1110
|
|
|
1172
1111
|
const result = await api.getBlockDelegationsPage(400)
|
|
1173
1112
|
|
|
1174
1113
|
expect(result).toEqual(items)
|
|
1175
|
-
const params =
|
|
1114
|
+
const params = mockedNetwork.mock.calls[0][0].params
|
|
1176
1115
|
expect(params).toMatchObject({ level: 400, limit: 1000, 'sort.asc': 'id' })
|
|
1177
1116
|
expect(params).not.toHaveProperty('offset.cr')
|
|
1178
1117
|
})
|
|
1179
1118
|
|
|
1180
1119
|
it('includes offset.cr in params when cursor is provided', async () => {
|
|
1181
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
1120
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
1182
1121
|
|
|
1183
1122
|
await api.getBlockDelegationsPage(400, 88)
|
|
1184
1123
|
|
|
1185
|
-
const params =
|
|
1186
|
-
expect(params
|
|
1124
|
+
const params = mockedNetwork.mock.calls[0][0].params
|
|
1125
|
+
expect(params).toMatchObject({ 'offset.cr': 88 })
|
|
1187
1126
|
})
|
|
1188
1127
|
|
|
1189
1128
|
it('calls the delegations endpoint', async () => {
|
|
1190
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
1129
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
1191
1130
|
|
|
1192
1131
|
await api.getBlockDelegationsPage(500)
|
|
1193
1132
|
|
|
@@ -1206,7 +1145,7 @@ describe('tzkt network API', () => {
|
|
|
1206
1145
|
// Driven through the mocked `network` (see the note on `fetchBlockTransactions`).
|
|
1207
1146
|
describe('fetchBlockDelegations', () => {
|
|
1208
1147
|
it('returns an empty array when the first page is empty', async () => {
|
|
1209
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
1148
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
1210
1149
|
|
|
1211
1150
|
const result = await fetchBlockDelegations(config, 100)
|
|
1212
1151
|
|
|
@@ -1215,7 +1154,7 @@ describe('tzkt network API', () => {
|
|
|
1215
1154
|
|
|
1216
1155
|
it('returns a single page when the page is smaller than the page size', async () => {
|
|
1217
1156
|
const items = [makeDelegationItem(1), makeDelegationItem(2)]
|
|
1218
|
-
mockedNetwork.mockReturnValue(networkResponse(items)
|
|
1157
|
+
mockedNetwork.mockReturnValue(networkResponse(items))
|
|
1219
1158
|
|
|
1220
1159
|
const result = await fetchBlockDelegations(config, 100)
|
|
1221
1160
|
|
|
@@ -1227,25 +1166,23 @@ describe('tzkt network API', () => {
|
|
|
1227
1166
|
const lastPage = [makeDelegationItem(1001)]
|
|
1228
1167
|
|
|
1229
1168
|
mockedNetwork
|
|
1230
|
-
.mockReturnValueOnce(networkResponse(fullPage)
|
|
1231
|
-
.mockReturnValueOnce(networkResponse(lastPage)
|
|
1169
|
+
.mockReturnValueOnce(networkResponse(fullPage))
|
|
1170
|
+
.mockReturnValueOnce(networkResponse(lastPage))
|
|
1232
1171
|
|
|
1233
1172
|
const result = await fetchBlockDelegations(config, 100)
|
|
1234
1173
|
|
|
1235
1174
|
expect(result).toHaveLength(1001)
|
|
1236
1175
|
expect(mockedNetwork).toHaveBeenCalledTimes(2)
|
|
1237
|
-
const firstParams =
|
|
1238
|
-
.params
|
|
1176
|
+
const firstParams = mockedNetwork.mock.calls[0][0].params
|
|
1239
1177
|
expect(firstParams).toMatchObject({ level: 100 })
|
|
1240
1178
|
expect(firstParams).not.toHaveProperty('offset.cr')
|
|
1241
|
-
const secondParams =
|
|
1242
|
-
.params
|
|
1179
|
+
const secondParams = mockedNetwork.mock.calls[1][0].params
|
|
1243
1180
|
expect(secondParams).toMatchObject({ level: 100, 'offset.cr': 1000 })
|
|
1244
1181
|
})
|
|
1245
1182
|
|
|
1246
1183
|
it('stops after maxTxQuery iterations regardless of page length', async () => {
|
|
1247
1184
|
const fullPage = Array.from({ length: 1000 }, (_, i) => makeDelegationItem(i + 1))
|
|
1248
|
-
mockedNetwork.mockReturnValue(networkResponse(fullPage)
|
|
1185
|
+
mockedNetwork.mockReturnValue(networkResponse(fullPage))
|
|
1249
1186
|
|
|
1250
1187
|
const result = await fetchBlockDelegations(config, 100)
|
|
1251
1188
|
|
|
@@ -1264,28 +1201,28 @@ describe('tzkt network API', () => {
|
|
|
1264
1201
|
|
|
1265
1202
|
describe('api.getBlockStakingPage', () => {
|
|
1266
1203
|
it('fetches a page without a cursor', async () => {
|
|
1267
|
-
const items: APIStakingType[] = [makeStakingItem(10)]
|
|
1268
|
-
mockedNetwork.mockReturnValue(networkResponse(items)
|
|
1204
|
+
const items: DeepPartial<APIStakingType>[] = [makeStakingItem(10)]
|
|
1205
|
+
mockedNetwork.mockReturnValue(networkResponse(items))
|
|
1269
1206
|
|
|
1270
1207
|
const result = await api.getBlockStakingPage(400)
|
|
1271
1208
|
|
|
1272
1209
|
expect(result).toEqual(items)
|
|
1273
|
-
const params =
|
|
1210
|
+
const params = mockedNetwork.mock.calls[0][0].params
|
|
1274
1211
|
expect(params).toMatchObject({ level: 400, limit: 1000, 'sort.asc': 'id' })
|
|
1275
1212
|
expect(params).not.toHaveProperty('offset.cr')
|
|
1276
1213
|
})
|
|
1277
1214
|
|
|
1278
1215
|
it('includes offset.cr in params when cursor is provided', async () => {
|
|
1279
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
1216
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
1280
1217
|
|
|
1281
1218
|
await api.getBlockStakingPage(400, 88)
|
|
1282
1219
|
|
|
1283
|
-
const params =
|
|
1284
|
-
expect(params
|
|
1220
|
+
const params = mockedNetwork.mock.calls[0][0].params
|
|
1221
|
+
expect(params).toMatchObject({ 'offset.cr': 88 })
|
|
1285
1222
|
})
|
|
1286
1223
|
|
|
1287
1224
|
it('calls the staking endpoint', async () => {
|
|
1288
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
1225
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
1289
1226
|
|
|
1290
1227
|
await api.getBlockStakingPage(500)
|
|
1291
1228
|
|
|
@@ -1304,7 +1241,7 @@ describe('tzkt network API', () => {
|
|
|
1304
1241
|
// Driven through the mocked `network` (see the note on `fetchBlockTransactions`).
|
|
1305
1242
|
describe('fetchBlockStaking', () => {
|
|
1306
1243
|
it('returns an empty array when the first page is empty', async () => {
|
|
1307
|
-
mockedNetwork.mockReturnValue(networkResponse([])
|
|
1244
|
+
mockedNetwork.mockReturnValue(networkResponse([]))
|
|
1308
1245
|
|
|
1309
1246
|
const result = await fetchBlockStaking(config, 100)
|
|
1310
1247
|
|
|
@@ -1313,7 +1250,7 @@ describe('tzkt network API', () => {
|
|
|
1313
1250
|
|
|
1314
1251
|
it('returns a single page when the page is smaller than the page size', async () => {
|
|
1315
1252
|
const items = [makeStakingItem(1), makeStakingItem(2)]
|
|
1316
|
-
mockedNetwork.mockReturnValue(networkResponse(items)
|
|
1253
|
+
mockedNetwork.mockReturnValue(networkResponse(items))
|
|
1317
1254
|
|
|
1318
1255
|
const result = await fetchBlockStaking(config, 100)
|
|
1319
1256
|
|
|
@@ -1325,25 +1262,23 @@ describe('tzkt network API', () => {
|
|
|
1325
1262
|
const lastPage = [makeStakingItem(1001)]
|
|
1326
1263
|
|
|
1327
1264
|
mockedNetwork
|
|
1328
|
-
.mockReturnValueOnce(networkResponse(fullPage)
|
|
1329
|
-
.mockReturnValueOnce(networkResponse(lastPage)
|
|
1265
|
+
.mockReturnValueOnce(networkResponse(fullPage))
|
|
1266
|
+
.mockReturnValueOnce(networkResponse(lastPage))
|
|
1330
1267
|
|
|
1331
1268
|
const result = await fetchBlockStaking(config, 100)
|
|
1332
1269
|
|
|
1333
1270
|
expect(result).toHaveLength(1001)
|
|
1334
1271
|
expect(mockedNetwork).toHaveBeenCalledTimes(2)
|
|
1335
|
-
const firstParams =
|
|
1336
|
-
.params
|
|
1272
|
+
const firstParams = mockedNetwork.mock.calls[0][0].params
|
|
1337
1273
|
expect(firstParams).toMatchObject({ level: 100 })
|
|
1338
1274
|
expect(firstParams).not.toHaveProperty('offset.cr')
|
|
1339
|
-
const secondParams =
|
|
1340
|
-
.params
|
|
1275
|
+
const secondParams = mockedNetwork.mock.calls[1][0].params
|
|
1341
1276
|
expect(secondParams).toMatchObject({ level: 100, 'offset.cr': 1000 })
|
|
1342
1277
|
})
|
|
1343
1278
|
|
|
1344
1279
|
it('stops after maxTxQuery iterations regardless of page length', async () => {
|
|
1345
1280
|
const fullPage = Array.from({ length: 1000 }, (_, i) => makeStakingItem(i + 1))
|
|
1346
|
-
mockedNetwork.mockReturnValue(networkResponse(fullPage)
|
|
1281
|
+
mockedNetwork.mockReturnValue(networkResponse(fullPage))
|
|
1347
1282
|
|
|
1348
1283
|
const result = await fetchBlockStaking(config, 100)
|
|
1349
1284
|
|