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