@ledgerhq/coin-tezos 10.2.2 → 10.2.4

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 (116) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/lib/api/index.d.ts +1 -3
  3. package/lib/api/index.d.ts.map +1 -1
  4. package/lib/api/index.js +4 -9
  5. package/lib/api/index.js.map +1 -1
  6. package/lib/logic/craftRawOperations.js +1 -1
  7. package/lib/logic/craftRawOperations.js.map +1 -1
  8. package/lib/logic/craftTransaction.d.ts.map +1 -1
  9. package/lib/logic/craftTransaction.js +1 -2
  10. package/lib/logic/craftTransaction.js.map +1 -1
  11. package/lib/logic/estimateFees.d.ts.map +1 -1
  12. package/lib/logic/estimateFees.js +51 -6
  13. package/lib/logic/estimateFees.js.map +1 -1
  14. package/lib/logic/estimateRevealLimits.d.ts +2 -2
  15. package/lib/logic/estimateRevealLimits.d.ts.map +1 -1
  16. package/lib/logic/estimateRevealLimits.js +3 -3
  17. package/lib/logic/estimateRevealLimits.js.map +1 -1
  18. package/lib/logic/getBalance.d.ts.map +1 -1
  19. package/lib/logic/getBalance.js +2 -3
  20. package/lib/logic/getBalance.js.map +1 -1
  21. package/lib/logic/getBlock.js +6 -6
  22. package/lib/logic/getBlock.js.map +1 -1
  23. package/lib/logic/getStakes.d.ts +2 -1
  24. package/lib/logic/getStakes.d.ts.map +1 -1
  25. package/lib/logic/getStakes.js +8 -9
  26. package/lib/logic/getStakes.js.map +1 -1
  27. package/lib/logic/listOperations.d.ts.map +1 -1
  28. package/lib/logic/listOperations.js +16 -16
  29. package/lib/logic/listOperations.js.map +1 -1
  30. package/lib/logic/validateIntent.d.ts.map +1 -1
  31. package/lib/logic/validateIntent.js +14 -2
  32. package/lib/logic/validateIntent.js.map +1 -1
  33. package/lib/network/bakers.d.ts +6 -5
  34. package/lib/network/bakers.d.ts.map +1 -1
  35. package/lib/network/bakers.js +13 -12
  36. package/lib/network/bakers.js.map +1 -1
  37. package/lib/network/tzkt.d.ts +8 -8
  38. package/lib/network/tzkt.d.ts.map +1 -1
  39. package/lib/network/tzkt.js +13 -11
  40. package/lib/network/tzkt.js.map +1 -1
  41. package/lib/types/errors.d.ts +3 -0
  42. package/lib/types/errors.d.ts.map +1 -1
  43. package/lib/types/errors.js +8 -1
  44. package/lib/types/errors.js.map +1 -1
  45. package/lib/utils.d.ts +17 -0
  46. package/lib/utils.d.ts.map +1 -1
  47. package/lib/utils.js +31 -1
  48. package/lib/utils.js.map +1 -1
  49. package/lib-es/api/index.d.ts +1 -3
  50. package/lib-es/api/index.d.ts.map +1 -1
  51. package/lib-es/api/index.js +5 -10
  52. package/lib-es/api/index.js.map +1 -1
  53. package/lib-es/logic/craftRawOperations.js +1 -1
  54. package/lib-es/logic/craftRawOperations.js.map +1 -1
  55. package/lib-es/logic/craftTransaction.d.ts.map +1 -1
  56. package/lib-es/logic/craftTransaction.js +1 -2
  57. package/lib-es/logic/craftTransaction.js.map +1 -1
  58. package/lib-es/logic/estimateFees.d.ts.map +1 -1
  59. package/lib-es/logic/estimateFees.js +52 -7
  60. package/lib-es/logic/estimateFees.js.map +1 -1
  61. package/lib-es/logic/estimateRevealLimits.d.ts +2 -2
  62. package/lib-es/logic/estimateRevealLimits.d.ts.map +1 -1
  63. package/lib-es/logic/estimateRevealLimits.js +3 -3
  64. package/lib-es/logic/estimateRevealLimits.js.map +1 -1
  65. package/lib-es/logic/getBalance.d.ts.map +1 -1
  66. package/lib-es/logic/getBalance.js +2 -3
  67. package/lib-es/logic/getBalance.js.map +1 -1
  68. package/lib-es/logic/getBlock.js +6 -6
  69. package/lib-es/logic/getBlock.js.map +1 -1
  70. package/lib-es/logic/getStakes.d.ts +2 -1
  71. package/lib-es/logic/getStakes.d.ts.map +1 -1
  72. package/lib-es/logic/getStakes.js +8 -9
  73. package/lib-es/logic/getStakes.js.map +1 -1
  74. package/lib-es/logic/listOperations.d.ts.map +1 -1
  75. package/lib-es/logic/listOperations.js +16 -16
  76. package/lib-es/logic/listOperations.js.map +1 -1
  77. package/lib-es/logic/validateIntent.d.ts.map +1 -1
  78. package/lib-es/logic/validateIntent.js +16 -4
  79. package/lib-es/logic/validateIntent.js.map +1 -1
  80. package/lib-es/network/bakers.d.ts +6 -5
  81. package/lib-es/network/bakers.d.ts.map +1 -1
  82. package/lib-es/network/bakers.js +13 -12
  83. package/lib-es/network/bakers.js.map +1 -1
  84. package/lib-es/network/tzkt.d.ts +8 -8
  85. package/lib-es/network/tzkt.d.ts.map +1 -1
  86. package/lib-es/network/tzkt.js +13 -11
  87. package/lib-es/network/tzkt.js.map +1 -1
  88. package/lib-es/types/errors.d.ts +3 -0
  89. package/lib-es/types/errors.d.ts.map +1 -1
  90. package/lib-es/types/errors.js +6 -0
  91. package/lib-es/types/errors.js.map +1 -1
  92. package/lib-es/utils.d.ts +17 -0
  93. package/lib-es/utils.d.ts.map +1 -1
  94. package/lib-es/utils.js +29 -0
  95. package/lib-es/utils.js.map +1 -1
  96. package/package.json +3 -4
  97. package/src/api/index.test.ts +32 -0
  98. package/src/api/index.ts +5 -13
  99. package/src/logic/craftRawOperations.ts +1 -1
  100. package/src/logic/craftTransaction.ts +1 -2
  101. package/src/logic/estimateFees.test.ts +124 -2
  102. package/src/logic/estimateFees.ts +59 -6
  103. package/src/logic/estimateRevealLimits.ts +11 -7
  104. package/src/logic/getBalance.ts +9 -6
  105. package/src/logic/getBlock.ts +6 -6
  106. package/src/logic/getStakes.ts +13 -8
  107. package/src/logic/listOperations.ts +23 -13
  108. package/src/logic/validateIntent.test.ts +90 -1
  109. package/src/logic/validateIntent.ts +18 -2
  110. package/src/network/bakers.integ.test.ts +3 -2
  111. package/src/network/bakers.test.ts +2 -1
  112. package/src/network/bakers.ts +15 -13
  113. package/src/network/tzkt.test.ts +29 -30
  114. package/src/network/tzkt.ts +38 -23
  115. package/src/types/errors.ts +7 -0
  116. package/src/utils.ts +32 -0
@@ -1,7 +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
+ import type { TezosCoinConfig, TezosContext } from '../config'
5
5
  import type {
6
6
  APIAccount,
7
7
  APIBlock,
@@ -19,7 +19,6 @@ import type {
19
19
  } from './types'
20
20
  import URL from 'url'
21
21
  import network from '@ledgerhq/live-network'
22
- import { log } from '@ledgerhq/logs'
23
22
 
24
23
  /** TzKT hard-caps `limit` at 10 000; we use a safer page size to stay well under that. */
25
24
  const BLOCK_PAGE_SIZE = 1000
@@ -466,10 +465,11 @@ export type TzktApi = ReturnType<typeof createTzktApi>
466
465
 
467
466
  // TODO this has same purpose as api/listOperations
468
467
  export const fetchAllTransactions = async (
469
- config: TezosCoinConfig,
468
+ context: TezosContext,
470
469
  address: string,
471
470
  lastId?: number
472
471
  ): Promise<APIOperation[]> => {
472
+ const config = await context.config()
473
473
  const api = createTzktApi(config)
474
474
  let ops: APIOperation[] = []
475
475
  let maxIteration = config.explorer.maxTxQuery
@@ -485,7 +485,7 @@ export const fetchAllTransactions = async (
485
485
  if (!last) return ops
486
486
  lastId = last.id
487
487
  if (!lastId) {
488
- log('tezos', 'id missing!')
488
+ context.logger('tezos', 'id missing!')
489
489
  return ops
490
490
  }
491
491
  } while (--maxIteration)
@@ -500,11 +500,13 @@ export const fetchAllTransactions = async (
500
500
  * A safety cap (`maxTxQuery`) prevents infinite loops on pathological responses.
501
501
  */
502
502
  async function fetchBlockPaginated<T extends { id: number }>(
503
- config: TezosCoinConfig,
504
- pageFn: (level: number, cursor?: number) => Promise<T[]>,
503
+ context: TezosContext,
504
+ pageFnFactory: (config: TezosCoinConfig) => (level: number, cursor?: number) => Promise<T[]>,
505
505
  level: number,
506
506
  label: string
507
507
  ): Promise<T[]> {
508
+ const config = await context.config()
509
+ const pageFn = pageFnFactory(config)
508
510
  const items: T[] = []
509
511
  let cursor: number | undefined
510
512
  let maxIteration = config.explorer.maxTxQuery
@@ -516,45 +518,58 @@ async function fetchBlockPaginated<T extends { id: number }>(
516
518
  cursor = page.at(-1)!.id
517
519
  } while (--maxIteration > 0)
518
520
  if (maxIteration === 0) {
519
- log('tezos', `${label}: maxTxQuery limit reached at level ${level}, result may be incomplete`)
521
+ context.logger(
522
+ 'tezos',
523
+ `${label}: maxTxQuery limit reached at level ${level}, result may be incomplete`
524
+ )
520
525
  }
521
526
  return items
522
527
  }
523
528
 
524
- export const fetchBlockTransactions = (config: TezosCoinConfig, level: number) =>
529
+ export const fetchBlockTransactions = (context: TezosContext, level: number) =>
525
530
  fetchBlockPaginated(
526
- config,
527
- createTzktApi(config).getBlockTransactionsPage,
531
+ context,
532
+ (config) => createTzktApi(config).getBlockTransactionsPage,
528
533
  level,
529
534
  'fetchBlockTransactions'
530
535
  )
531
536
 
532
- export const fetchBlockTokenTransfers = (config: TezosCoinConfig, level: number) =>
537
+ export const fetchBlockTokenTransfers = (context: TezosContext, level: number) =>
533
538
  fetchBlockPaginated(
534
- config,
535
- createTzktApi(config).getBlockTokenTransfersPage,
539
+ context,
540
+ (config) => createTzktApi(config).getBlockTokenTransfersPage,
536
541
  level,
537
542
  'fetchBlockTokenTransfers'
538
543
  )
539
544
 
540
- export const fetchBlockDelegations = (config: TezosCoinConfig, level: number) =>
545
+ export const fetchBlockDelegations = (context: TezosContext, level: number) =>
541
546
  fetchBlockPaginated(
542
- config,
543
- createTzktApi(config).getBlockDelegationsPage,
547
+ context,
548
+ (config) => createTzktApi(config).getBlockDelegationsPage,
544
549
  level,
545
550
  'fetchBlockDelegations'
546
551
  )
547
552
 
548
- export const fetchBlockStaking = (config: TezosCoinConfig, level: number) =>
549
- fetchBlockPaginated(config, createTzktApi(config).getBlockStakingPage, level, 'fetchBlockStaking')
553
+ export const fetchBlockStaking = (context: TezosContext, level: number) =>
554
+ fetchBlockPaginated(
555
+ context,
556
+ (config) => createTzktApi(config).getBlockStakingPage,
557
+ level,
558
+ 'fetchBlockStaking'
559
+ )
550
560
 
551
- export const fetchBlockOriginations = (config: TezosCoinConfig, level: number) =>
561
+ export const fetchBlockOriginations = (context: TezosContext, level: number) =>
552
562
  fetchBlockPaginated(
553
- config,
554
- createTzktApi(config).getBlockOriginationsPage,
563
+ context,
564
+ (config) => createTzktApi(config).getBlockOriginationsPage,
555
565
  level,
556
566
  'fetchBlockOriginations'
557
567
  )
558
568
 
559
- export const fetchBlockReveals = (config: TezosCoinConfig, level: number) =>
560
- fetchBlockPaginated(config, createTzktApi(config).getBlockRevealsPage, level, 'fetchBlockReveals')
569
+ export const fetchBlockReveals = (context: TezosContext, level: number) =>
570
+ fetchBlockPaginated(
571
+ context,
572
+ (config) => createTzktApi(config).getBlockRevealsPage,
573
+ level,
574
+ 'fetchBlockReveals'
575
+ )
@@ -59,3 +59,10 @@ export class TezosStakeBlockedByPendingUnstake extends Error {
59
59
  this.name = 'TezosStakeBlockedByPendingUnstake'
60
60
  }
61
61
  }
62
+
63
+ export class TezosStakeAmountTooSmall extends Error {
64
+ constructor() {
65
+ super('Stake amount too small to mint any staking pseudotoken')
66
+ this.name = 'TezosStakeAmountTooSmall'
67
+ }
68
+ }
package/src/utils.ts CHANGED
@@ -20,6 +20,38 @@ export const DUST_MARGIN_MUTEZ = 500
20
20
  // Tezos rejects `empty_implicit_delegated_contract`; stake-max leaves this buffer.
21
21
  export const STAKE_USE_ALL_RESERVE_MUTEZ = 10_000n
22
22
 
23
+ /**
24
+ * Amount pre-estimated for a stake whose real amount isn't known yet (stake-max), and the floor
25
+ * a resolved stake-max must clear: only the probe is simulated, never the resolved amount.
26
+ *
27
+ * Octez rejects a stake that mints no pseudotoken (`stake_amount_too_small`): issued
28
+ * pseudotokens are `floor(amount * pseudotokens / staked_tez)`, so 1 mutez fails for any
29
+ * delegate whose stakers accrued rewards — a 2 mutez floor across delegates in 2026-09.
30
+ * https://gitlab.com/tezos/tezos/-/commit/b8339f8893e1da45e73ea5c4b1b82a0dfefb503c
31
+ */
32
+ export const STAKE_ESTIMATION_PROBE_MUTEZ = 1_000n
33
+
34
+ /**
35
+ * Suffixes of the protocol error ids `validateIntent` turns into field errors. Estimation reports
36
+ * these as `taquitoError` and the api returns them, so the mapping gets its turn instead of the
37
+ * raw id reaching the user. Any other protocol error keeps propagating — callers retry on it.
38
+ */
39
+ export const MAPPED_TAQUITO_ERRORS = [
40
+ 'balance_too_low',
41
+ 'cannot_stake_with_unfinalizable_unstake_requests_to_another_delegate',
42
+ 'contract.must_be_delegated_to_stake',
43
+ 'delegate.unchanged',
44
+ 'empty_implicit_contract',
45
+ 'script_rejected',
46
+ 'stake_amount_too_small',
47
+ 'staking.too_much_unstaked',
48
+ 'subtraction_underflow',
49
+ ]
50
+
51
+ export function isMappedTaquitoError(id: string): boolean {
52
+ return MAPPED_TAQUITO_ERRORS.some((mapped) => id.endsWith(mapped))
53
+ }
54
+
23
55
  /** Stake "Use Max": staked and unstaked-frozen funds count toward `balance` but aren't (re-)stakeable until finalized, so subtract both. */
24
56
  export function computeMaxStakeAmount(
25
57
  balance: bigint,