@ledgerhq/coin-tezos 7.12.0 → 9.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.
- package/CHANGELOG.md +39 -0
- package/lib/api/index.d.ts +1 -2
- package/lib/api/index.d.ts.map +1 -1
- package/lib/api/index.js +45 -44
- package/lib/api/index.js.map +1 -1
- package/lib/api/types.d.ts +3 -2
- package/lib/api/types.d.ts.map +1 -1
- package/lib/config.d.ts +3 -1
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js.map +1 -1
- package/lib/logic/broadcast.d.ts +2 -1
- package/lib/logic/broadcast.d.ts.map +1 -1
- package/lib/logic/broadcast.js +3 -2
- package/lib/logic/broadcast.js.map +1 -1
- package/lib/logic/combine.d.ts +1 -1
- package/lib/logic/combine.d.ts.map +1 -1
- package/lib/logic/combine.js +4 -1
- package/lib/logic/combine.js.map +1 -1
- package/lib/logic/craftRawOperations.d.ts +2 -1
- package/lib/logic/craftRawOperations.d.ts.map +1 -1
- package/lib/logic/craftRawOperations.js +5 -8
- package/lib/logic/craftRawOperations.js.map +1 -1
- package/lib/logic/craftTransaction.d.ts +3 -2
- package/lib/logic/craftTransaction.d.ts.map +1 -1
- package/lib/logic/craftTransaction.js +6 -9
- package/lib/logic/craftTransaction.js.map +1 -1
- package/lib/logic/estimateFees.d.ts +2 -1
- package/lib/logic/estimateFees.d.ts.map +1 -1
- package/lib/logic/estimateFees.js +24 -19
- package/lib/logic/estimateFees.js.map +1 -1
- package/lib/logic/getBalance.d.ts +2 -1
- package/lib/logic/getBalance.d.ts.map +1 -1
- package/lib/logic/getBalance.js +7 -8
- package/lib/logic/getBalance.js.map +1 -1
- package/lib/logic/getBlock.d.ts +2 -1
- package/lib/logic/getBlock.d.ts.map +1 -1
- package/lib/logic/getBlock.js +12 -10
- package/lib/logic/getBlock.js.map +1 -1
- package/lib/logic/getBlockInfo.d.ts +2 -1
- package/lib/logic/getBlockInfo.d.ts.map +1 -1
- package/lib/logic/getBlockInfo.js +5 -3
- package/lib/logic/getBlockInfo.js.map +1 -1
- package/lib/logic/getStakes.d.ts +3 -2
- package/lib/logic/getStakes.d.ts.map +1 -1
- package/lib/logic/getStakes.js +9 -9
- package/lib/logic/getStakes.js.map +1 -1
- package/lib/logic/lastBlock.d.ts +2 -1
- package/lib/logic/lastBlock.d.ts.map +1 -1
- package/lib/logic/lastBlock.js +4 -6
- package/lib/logic/lastBlock.js.map +1 -1
- package/lib/logic/listOperations.d.ts +2 -1
- package/lib/logic/listOperations.d.ts.map +1 -1
- package/lib/logic/listOperations.js +8 -6
- package/lib/logic/listOperations.js.map +1 -1
- package/lib/logic/tezosToolkit.d.ts +2 -1
- package/lib/logic/tezosToolkit.d.ts.map +1 -1
- package/lib/logic/tezosToolkit.js +2 -6
- package/lib/logic/tezosToolkit.js.map +1 -1
- package/lib/logic/validateIntent.d.ts +2 -1
- package/lib/logic/validateIntent.d.ts.map +1 -1
- package/lib/logic/validateIntent.js +12 -13
- package/lib/logic/validateIntent.js.map +1 -1
- package/lib/network/bakers.d.ts +5 -4
- package/lib/network/bakers.d.ts.map +1 -1
- package/lib/network/bakers.js +9 -10
- package/lib/network/bakers.js.map +1 -1
- package/lib/network/index.d.ts +1 -1
- package/lib/network/index.d.ts.map +1 -1
- package/lib/network/index.js +2 -5
- package/lib/network/index.js.map +1 -1
- package/lib/network/tzkt.d.ts +16 -9
- package/lib/network/tzkt.d.ts.map +1 -1
- package/lib/network/tzkt.js +341 -333
- package/lib/network/tzkt.js.map +1 -1
- package/lib/utils.d.ts +2 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +1 -6
- package/lib/utils.js.map +1 -1
- package/lib-es/api/index.d.ts +1 -2
- package/lib-es/api/index.d.ts.map +1 -1
- package/lib-es/api/index.js +40 -36
- package/lib-es/api/index.js.map +1 -1
- package/lib-es/api/types.d.ts +3 -2
- package/lib-es/api/types.d.ts.map +1 -1
- package/lib-es/config.d.ts +3 -1
- package/lib-es/config.d.ts.map +1 -1
- package/lib-es/config.js.map +1 -1
- package/lib-es/logic/broadcast.d.ts +2 -1
- package/lib-es/logic/broadcast.d.ts.map +1 -1
- package/lib-es/logic/broadcast.js +3 -2
- package/lib-es/logic/broadcast.js.map +1 -1
- package/lib-es/logic/combine.d.ts +1 -1
- package/lib-es/logic/combine.d.ts.map +1 -1
- package/lib-es/logic/combine.js +4 -1
- package/lib-es/logic/combine.js.map +1 -1
- package/lib-es/logic/craftRawOperations.d.ts +2 -1
- package/lib-es/logic/craftRawOperations.d.ts.map +1 -1
- package/lib-es/logic/craftRawOperations.js +5 -5
- package/lib-es/logic/craftRawOperations.js.map +1 -1
- package/lib-es/logic/craftTransaction.d.ts +3 -2
- package/lib-es/logic/craftTransaction.d.ts.map +1 -1
- package/lib-es/logic/craftTransaction.js +6 -6
- package/lib-es/logic/craftTransaction.js.map +1 -1
- package/lib-es/logic/estimateFees.d.ts +2 -1
- package/lib-es/logic/estimateFees.d.ts.map +1 -1
- package/lib-es/logic/estimateFees.js +24 -16
- package/lib-es/logic/estimateFees.js.map +1 -1
- package/lib-es/logic/getBalance.d.ts +2 -1
- package/lib-es/logic/getBalance.d.ts.map +1 -1
- package/lib-es/logic/getBalance.js +5 -3
- package/lib-es/logic/getBalance.js.map +1 -1
- package/lib-es/logic/getBlock.d.ts +2 -1
- package/lib-es/logic/getBlock.d.ts.map +1 -1
- package/lib-es/logic/getBlock.js +10 -8
- package/lib-es/logic/getBlock.js.map +1 -1
- package/lib-es/logic/getBlockInfo.d.ts +2 -1
- package/lib-es/logic/getBlockInfo.d.ts.map +1 -1
- package/lib-es/logic/getBlockInfo.js +4 -2
- package/lib-es/logic/getBlockInfo.js.map +1 -1
- package/lib-es/logic/getStakes.d.ts +3 -2
- package/lib-es/logic/getStakes.d.ts.map +1 -1
- package/lib-es/logic/getStakes.js +9 -6
- package/lib-es/logic/getStakes.js.map +1 -1
- package/lib-es/logic/lastBlock.d.ts +2 -1
- package/lib-es/logic/lastBlock.d.ts.map +1 -1
- package/lib-es/logic/lastBlock.js +4 -3
- package/lib-es/logic/lastBlock.js.map +1 -1
- package/lib-es/logic/listOperations.d.ts +2 -1
- package/lib-es/logic/listOperations.d.ts.map +1 -1
- package/lib-es/logic/listOperations.js +7 -5
- package/lib-es/logic/listOperations.js.map +1 -1
- package/lib-es/logic/tezosToolkit.d.ts +2 -1
- package/lib-es/logic/tezosToolkit.d.ts.map +1 -1
- package/lib-es/logic/tezosToolkit.js +2 -3
- package/lib-es/logic/tezosToolkit.js.map +1 -1
- package/lib-es/logic/validateIntent.d.ts +2 -1
- package/lib-es/logic/validateIntent.d.ts.map +1 -1
- package/lib-es/logic/validateIntent.js +10 -8
- package/lib-es/logic/validateIntent.js.map +1 -1
- package/lib-es/network/bakers.d.ts +5 -4
- package/lib-es/network/bakers.d.ts.map +1 -1
- package/lib-es/network/bakers.js +9 -10
- package/lib-es/network/bakers.js.map +1 -1
- package/lib-es/network/index.d.ts +1 -1
- package/lib-es/network/index.d.ts.map +1 -1
- package/lib-es/network/index.js +1 -1
- package/lib-es/network/index.js.map +1 -1
- package/lib-es/network/tzkt.d.ts +16 -9
- package/lib-es/network/tzkt.d.ts.map +1 -1
- package/lib-es/network/tzkt.js +340 -333
- package/lib-es/network/tzkt.js.map +1 -1
- package/lib-es/utils.d.ts +2 -1
- package/lib-es/utils.d.ts.map +1 -1
- package/lib-es/utils.js +1 -3
- package/lib-es/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/api/index-mainnet.integ.test.ts +34 -30
- package/src/api/index.integ.test.ts +69 -53
- package/src/api/index.test.ts +99 -60
- package/src/api/index.ts +52 -36
- package/src/api/types.ts +3 -2
- package/src/config.ts +4 -1
- package/src/logic/broadcast.integ.test.ts +12 -13
- package/src/logic/broadcast.ts +4 -2
- package/src/logic/combine.test.ts +17 -0
- package/src/logic/combine.ts +5 -2
- package/src/logic/craftRawOperations.test.ts +47 -33
- package/src/logic/craftRawOperations.ts +6 -4
- package/src/logic/craftTransaction.integ.test.ts +12 -5
- package/src/logic/craftTransaction.test.ts +39 -31
- package/src/logic/craftTransaction.ts +10 -5
- package/src/logic/estimateFees.integ.test.ts +7 -7
- package/src/logic/estimateFees.test.ts +52 -49
- package/src/logic/estimateFees.ts +34 -22
- package/src/logic/getBalance.test.ts +19 -17
- package/src/logic/getBalance.ts +6 -3
- package/src/logic/getBlock.integ.test.ts +8 -30
- package/src/logic/getBlock.test.ts +91 -81
- package/src/logic/getBlock.ts +11 -8
- package/src/logic/getBlockInfo.integ.test.ts +9 -18
- package/src/logic/getBlockInfo.test.ts +19 -9
- package/src/logic/getBlockInfo.ts +5 -2
- package/src/logic/getStakes.test.ts +46 -49
- package/src/logic/getStakes.ts +14 -5
- package/src/logic/lastBlock.ts +5 -3
- package/src/logic/listOperations.integ.test.ts +40 -67
- package/src/logic/listOperations.test.ts +65 -59
- package/src/logic/listOperations.ts +8 -3
- package/src/logic/tezosToolkit.ts +3 -3
- package/src/logic/validateIntent.test.ts +78 -74
- package/src/logic/validateIntent.ts +17 -7
- package/src/network/bakers.integ.test.ts +2 -5
- package/src/network/bakers.test.ts +5 -6
- package/src/network/bakers.ts +13 -10
- package/src/network/index.ts +2 -1
- package/src/network/tzkt.integ.test.ts +3 -14
- package/src/network/tzkt.test.ts +128 -96
- package/src/network/tzkt.ts +426 -393
- package/src/utils.ts +2 -3
package/src/api/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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 { CoreAccountInfo, CoreTransactionInfo, EstimatedFees } from '../logic/estimateFees'
|
|
6
6
|
import type { TezosOperationMode } from '../types/model'
|
|
7
7
|
import type { TezosAccountInfo, TezosApi, TezosFeeEstimation } from './types'
|
|
@@ -24,7 +24,6 @@ import { craftTransactionData } from '@ledgerhq/coin-module-framework/logic/craf
|
|
|
24
24
|
import { log } from '@ledgerhq/logs'
|
|
25
25
|
import { getRevealFee } from '@taquito/taquito'
|
|
26
26
|
import { getPkhfromPk, validatePublicKey, ValidationResult } from '@taquito/utils'
|
|
27
|
-
import coinConfig from '../config'
|
|
28
27
|
import {
|
|
29
28
|
broadcast,
|
|
30
29
|
combine,
|
|
@@ -43,7 +42,7 @@ import {
|
|
|
43
42
|
import { getTezosToolkit } from '../logic/tezosToolkit'
|
|
44
43
|
import { validateAddress } from '../logic/validateAddress'
|
|
45
44
|
import { hasManagerKey } from '../network/types'
|
|
46
|
-
import
|
|
45
|
+
import { createTzktApi } from '../network/tzkt'
|
|
47
46
|
import {
|
|
48
47
|
DUST_MARGIN_MUTEZ,
|
|
49
48
|
hasEmptyBalance,
|
|
@@ -52,53 +51,56 @@ import {
|
|
|
52
51
|
resolveTezosOperationMode,
|
|
53
52
|
} from '../utils'
|
|
54
53
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
// The caller builds the {@link TezosContext} (config + logger) and passes it to each method (ADR-019).
|
|
55
|
+
export function createApi(): TezosApi {
|
|
58
56
|
return {
|
|
59
|
-
broadcast,
|
|
57
|
+
broadcast: (context, tx) => broadcast(context, tx),
|
|
60
58
|
async call() {
|
|
61
59
|
throw new Error('call is not supported')
|
|
62
60
|
},
|
|
63
|
-
combine,
|
|
64
|
-
craftTransaction:
|
|
61
|
+
combine: (_context, tx, signature) => combine(tx, signature),
|
|
62
|
+
craftTransaction: (context, transactionIntent, options) =>
|
|
63
|
+
craft(context, transactionIntent, options?.customFees),
|
|
65
64
|
craftRawTransaction: async (
|
|
65
|
+
context,
|
|
66
66
|
transaction: string,
|
|
67
67
|
sender: string,
|
|
68
68
|
publicKey: string,
|
|
69
69
|
sequence: bigint
|
|
70
70
|
): Promise<CraftedTransaction> => {
|
|
71
|
-
const tx = await craftRawOperations(transaction, sender, publicKey, sequence)
|
|
71
|
+
const tx = await craftRawOperations(context, transaction, sender, publicKey, sequence)
|
|
72
72
|
return { transaction: tx }
|
|
73
73
|
},
|
|
74
|
-
estimateFees: estimate,
|
|
75
|
-
getBalance: (address: string, options?: BalanceOptions) =>
|
|
76
|
-
rejectBalanceOptions(() => getBalance(address), options),
|
|
77
|
-
lastBlock,
|
|
78
|
-
listOperations: operations,
|
|
79
|
-
getStakes,
|
|
80
|
-
validateIntent,
|
|
81
|
-
getNextSequence: async (address: string) => {
|
|
82
|
-
const
|
|
74
|
+
estimateFees: (context, transactionIntent) => estimate(context, transactionIntent),
|
|
75
|
+
getBalance: (context, address: string, options?: BalanceOptions) =>
|
|
76
|
+
rejectBalanceOptions(() => getBalance(context, address), options),
|
|
77
|
+
lastBlock: (context) => lastBlock(context),
|
|
78
|
+
listOperations: (context, address, options) => operations(context, address, options),
|
|
79
|
+
getStakes: (context, address, options) => getStakes(context, address, options?.cursor),
|
|
80
|
+
validateIntent: (context, transactionIntent) => validateIntent(context, transactionIntent),
|
|
81
|
+
getNextSequence: async (context, address: string) => {
|
|
82
|
+
const config = await context.config()
|
|
83
|
+
const accountInfo = await createTzktApi(config).getAccountByAddress(address)
|
|
83
84
|
return hasManagerKey(accountInfo) ? BigInt(accountInfo.counter + 1) : 0n
|
|
84
85
|
},
|
|
85
|
-
getAccountInfo: async (address: string): Promise<TezosAccountInfo> => {
|
|
86
|
-
const
|
|
86
|
+
getAccountInfo: async (context, address: string): Promise<TezosAccountInfo> => {
|
|
87
|
+
const config = await context.config()
|
|
88
|
+
const account = await createTzktApi(config).getAccountByAddress(address)
|
|
87
89
|
// Manager-key accounts (plain wallets "user" and registered bakers "delegate") carry a
|
|
88
90
|
// reveal state; empty / non-existent accounts are treated as unrevealed (no public key
|
|
89
91
|
// published on-chain yet).
|
|
90
92
|
return { type: 'tezos', revealed: hasManagerKey(account) ? account.revealed : false }
|
|
91
93
|
},
|
|
92
|
-
getBlock,
|
|
93
|
-
getBlockInfo,
|
|
94
|
-
getRewards(_address: string,
|
|
94
|
+
getBlock: (context, height) => getBlock(context, height),
|
|
95
|
+
getBlockInfo: (context, height) => getBlockInfo(context, height),
|
|
96
|
+
getRewards(_context, _address: string, _options?: { cursor?: Cursor }): Promise<Page<Reward>> {
|
|
95
97
|
throw new Error('getRewards is not supported')
|
|
96
98
|
},
|
|
97
|
-
getValidators(
|
|
99
|
+
getValidators(_context, _options?: { cursor?: Cursor }): Promise<Page<Validator>> {
|
|
98
100
|
throw new Error('getValidators is not supported')
|
|
99
101
|
},
|
|
100
|
-
validateAddress,
|
|
101
|
-
craftTransactionData,
|
|
102
|
+
validateAddress: (_context, address, parameters) => validateAddress(address, parameters),
|
|
103
|
+
craftTransactionData: (_context, intent) => craftTransactionData(intent),
|
|
102
104
|
}
|
|
103
105
|
}
|
|
104
106
|
|
|
@@ -108,6 +110,7 @@ function isTezosTransactionType(
|
|
|
108
110
|
return ['send', 'delegate', 'undelegate', 'stake', 'unstake', 'finalize_unstake'].includes(type)
|
|
109
111
|
}
|
|
110
112
|
async function craft(
|
|
113
|
+
context: TezosContext,
|
|
111
114
|
transactionIntent: TransactionIntent,
|
|
112
115
|
customFees?: FeeEstimation
|
|
113
116
|
): Promise<CraftedTransaction> {
|
|
@@ -115,8 +118,11 @@ async function craft(
|
|
|
115
118
|
throw new IncorrectTypeError(transactionIntent.type)
|
|
116
119
|
}
|
|
117
120
|
|
|
121
|
+
const config = await context.config()
|
|
122
|
+
const api = createTzktApi(config)
|
|
123
|
+
|
|
118
124
|
// Always estimate to get gasLimit/storageLimit
|
|
119
|
-
const estimation = await estimate(transactionIntent)
|
|
125
|
+
const estimation = await estimate(context, transactionIntent)
|
|
120
126
|
const fee = {
|
|
121
127
|
fees: (customFees?.value ?? estimation.value).toString(),
|
|
122
128
|
gasLimit: estimation.parameters?.gasLimit?.toString(),
|
|
@@ -156,7 +162,7 @@ async function craft(
|
|
|
156
162
|
const needsReveal = hasManagerKey(senderApiAcc) && !senderApiAcc.revealed
|
|
157
163
|
const totalFee = Number(fee.fees || '0')
|
|
158
164
|
|
|
159
|
-
const feesConfig =
|
|
165
|
+
const feesConfig = config.fees
|
|
160
166
|
const revealFeeForSplit = needsReveal
|
|
161
167
|
? Math.max(feesConfig.minFees ?? 0, getRevealFee(transactionIntent.sender))
|
|
162
168
|
: 0
|
|
@@ -207,14 +213,23 @@ async function craft(
|
|
|
207
213
|
return { publicKey: pk, publicKeyHash: transactionIntent.sender }
|
|
208
214
|
})()
|
|
209
215
|
: undefined
|
|
210
|
-
const { contents } = await craftTransaction(
|
|
211
|
-
|
|
216
|
+
const { contents } = await craftTransaction(
|
|
217
|
+
context,
|
|
218
|
+
accountForCraft,
|
|
219
|
+
txForCraft,
|
|
220
|
+
publicKeyForCraft
|
|
221
|
+
)
|
|
222
|
+
const tx = await rawEncode(config, contents)
|
|
212
223
|
return { transaction: tx }
|
|
213
224
|
}
|
|
214
225
|
|
|
215
|
-
async function estimate(
|
|
226
|
+
async function estimate(
|
|
227
|
+
context: TezosContext,
|
|
228
|
+
transactionIntent: TransactionIntent
|
|
229
|
+
): Promise<TezosFeeEstimation> {
|
|
216
230
|
// avoid taquito error when estimating a 0-amount transfer during input
|
|
217
|
-
const config =
|
|
231
|
+
const config = await context.config()
|
|
232
|
+
const api = createTzktApi(config)
|
|
218
233
|
const tezosModeForEstimate = resolveTezosOperationMode(
|
|
219
234
|
transactionIntent.type,
|
|
220
235
|
transactionIntent.asset
|
|
@@ -276,7 +291,7 @@ async function estimate(transactionIntent: TransactionIntent): Promise<TezosFeeE
|
|
|
276
291
|
// needed by the compiler (it can assume it's a manager-key account with respective fields)
|
|
277
292
|
if (!hasManagerKey(senderAccountInfo)) throw new Error('unexpected account type')
|
|
278
293
|
const account = xpub ? { ...accountBase, xpub } : accountBase
|
|
279
|
-
return await estimateFees({ account, transaction })
|
|
294
|
+
return await estimateFees(context, { account, transaction })
|
|
280
295
|
}
|
|
281
296
|
const xpub = transactionIntent.senderPublicKey ?? senderAccountInfo.publicKey
|
|
282
297
|
|
|
@@ -332,7 +347,7 @@ async function estimate(transactionIntent: TransactionIntent): Promise<TezosFeeE
|
|
|
332
347
|
let txGasLimit: bigint
|
|
333
348
|
|
|
334
349
|
try {
|
|
335
|
-
const toolkit = getTezosToolkit()
|
|
350
|
+
const toolkit = getTezosToolkit(config)
|
|
336
351
|
const simpleEstimate = await toolkit.estimate.transfer({
|
|
337
352
|
to: transactionIntent.recipient,
|
|
338
353
|
amount: Number(transactionIntent.amount),
|
|
@@ -382,13 +397,14 @@ async function estimate(transactionIntent: TransactionIntent): Promise<TezosFeeE
|
|
|
382
397
|
}
|
|
383
398
|
|
|
384
399
|
async function operations(
|
|
400
|
+
context: TezosContext,
|
|
385
401
|
address: string,
|
|
386
402
|
{ minHeight = 0, cursor, order = 'asc' }: ListOperationsOptions
|
|
387
403
|
): Promise<Page<Operation>> {
|
|
388
404
|
// FIXME This wrapper hard-codes limit: 1000 and ignores any caller-provided limit from ListOperationsOptions. Either
|
|
389
405
|
// forward options.limit (as a soft/capped limit) or throw a "not supported" error when limit is set to match the
|
|
390
406
|
// ListOperationsOptions contract.
|
|
391
|
-
const [items, newNextCursor] = await listOperations(address, {
|
|
407
|
+
const [items, newNextCursor] = await listOperations(context, address, {
|
|
392
408
|
limit: 1000, // Increased limit to 1000 to ensure delegation information is available when displaying account details (temporary fix until proper pagination is implemented).
|
|
393
409
|
token: cursor,
|
|
394
410
|
sort: order === 'asc' ? 'Ascending' : 'Descending',
|
package/src/api/types.ts
CHANGED
|
@@ -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, TezosContext } from '../config'
|
|
4
5
|
import type { CoinModuleApi, FeeEstimation } from '@ledgerhq/coin-module-framework/api/types'
|
|
5
6
|
|
|
6
7
|
export type TezosFeeParameters = {
|
|
@@ -32,6 +33,6 @@ export type TezosAccountInfo = { type: 'tezos'; revealed: boolean }
|
|
|
32
33
|
* signatures would otherwise intersect into an incompatible-return-type collision) and letting the
|
|
33
34
|
* implementation satisfy the generic method directly.
|
|
34
35
|
*/
|
|
35
|
-
export type TezosApi = CoinModuleApi & {
|
|
36
|
-
getAccountInfo: (address: string) => Promise<TezosAccountInfo>
|
|
36
|
+
export type TezosApi = CoinModuleApi<TezosCoinConfig> & {
|
|
37
|
+
getAccountInfo: (context: TezosContext, address: string) => Promise<TezosAccountInfo>
|
|
37
38
|
}
|
package/src/config.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: © 2026 LEDGER SAS
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import type { CoinConfig, CurrencyConfig } from '@ledgerhq/coin-module-framework/config'
|
|
4
|
+
import type { CoinConfig, Context, CurrencyConfig } from '@ledgerhq/coin-module-framework/config'
|
|
5
5
|
import buildCoinConfig from '@ledgerhq/coin-module-framework/config'
|
|
6
6
|
|
|
7
7
|
export type TezosConfig = {
|
|
@@ -26,6 +26,9 @@ export type TezosConfig = {
|
|
|
26
26
|
|
|
27
27
|
export type TezosCoinConfig = CurrencyConfig & TezosConfig
|
|
28
28
|
|
|
29
|
+
/** The {@link Context} threaded through the coin-tezos low layers (ADR-019). */
|
|
30
|
+
export type TezosContext = Context<TezosCoinConfig>
|
|
31
|
+
|
|
29
32
|
const coinConfig: {
|
|
30
33
|
setCoinConfig: (config: CoinConfig<TezosCoinConfig>) => void
|
|
31
34
|
getCoinConfig: (currencyId?: string) => TezosCoinConfig
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: © 2026 LEDGER SAS
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import type { TezosContext } from '../config'
|
|
4
5
|
import { InMemorySigner } from '@taquito/signer'
|
|
5
6
|
import { OpKind, TezosToolkit } from '@taquito/taquito'
|
|
6
|
-
import coinConfig from '../config'
|
|
7
7
|
import { broadcast } from './broadcast'
|
|
8
8
|
|
|
9
9
|
describe('Broadcast', () => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
})
|
|
10
|
+
const context: TezosContext = {
|
|
11
|
+
config: async () =>
|
|
12
|
+
({
|
|
13
|
+
status: { type: 'active' },
|
|
14
|
+
node: {
|
|
15
|
+
url: 'https://xtz-node.api.live.ledger.com',
|
|
16
|
+
},
|
|
17
|
+
}) as any,
|
|
18
|
+
logger: () => undefined,
|
|
19
|
+
}
|
|
21
20
|
|
|
22
21
|
it('throws on insufficient funds', async () => {
|
|
23
22
|
const tezos = new TezosToolkit('https://xtz-node.api.live.ledger.com')
|
|
@@ -47,6 +46,6 @@ describe('Broadcast', () => {
|
|
|
47
46
|
})
|
|
48
47
|
const { sbytes } = await signer.sign(prepared, new Uint8Array([3]))
|
|
49
48
|
|
|
50
|
-
await expect(broadcast(sbytes)).rejects.toThrow(/Empty implicit contract/)
|
|
49
|
+
await expect(broadcast(context, sbytes)).rejects.toThrow(/Empty implicit contract/)
|
|
51
50
|
})
|
|
52
51
|
})
|
package/src/logic/broadcast.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: © 2026 LEDGER SAS
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import type { TezosContext } from '../config'
|
|
4
5
|
import { getTezosToolkit } from './tezosToolkit'
|
|
5
6
|
|
|
6
|
-
export async function broadcast(signature: string): Promise<string> {
|
|
7
|
-
const
|
|
7
|
+
export async function broadcast(context: TezosContext, signature: string): Promise<string> {
|
|
8
|
+
const config = await context.config()
|
|
9
|
+
const { rpc } = getTezosToolkit(config)
|
|
8
10
|
return await rpc.injectOperation(signature)
|
|
9
11
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: © 2026 LEDGER SAS
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { combine } from './combine'
|
|
5
|
+
|
|
6
|
+
describe('combine', () => {
|
|
7
|
+
it('concatenates transaction and signature and strips the leading 2 chars', () => {
|
|
8
|
+
// slice(2) removes the first byte (magic byte) from the concatenated hex string
|
|
9
|
+
expect(combine('03aabbcc', ['ddeeff'])).toBe('aabbccddeeff')
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
it('throws when more than one signature is provided', () => {
|
|
13
|
+
expect(() => combine('0xdeadbeef', ['0xsig0', '0xsig1'])).toThrow(
|
|
14
|
+
'Tezos combine expects exactly one signature, got 2'
|
|
15
|
+
)
|
|
16
|
+
})
|
|
17
|
+
})
|
package/src/logic/combine.ts
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
// Source: https://github.com/ecadlabs/taquito/blob/97832fc088eccb93c152659367618ce1782a8b51/packages/taquito-ledger-signer/src/taquito-ledger-signer.ts#L187C23-L187C32
|
|
5
|
-
export function combine(transaction: string, signature: string): string {
|
|
6
|
-
|
|
5
|
+
export function combine(transaction: string, signature: string[]): string {
|
|
6
|
+
if (signature.length !== 1) {
|
|
7
|
+
throw new Error(`Tezos combine expects exactly one signature, got ${signature.length}`)
|
|
8
|
+
}
|
|
9
|
+
return `${transaction}${signature[0]}`.slice(2)
|
|
7
10
|
}
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: © 2026 LEDGER SAS
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import type { TezosCoinConfig, TezosContext } from '../config'
|
|
4
5
|
import { OpKind } from '@taquito/rpc'
|
|
5
6
|
import { getPkhfromPk } from '@taquito/utils'
|
|
6
|
-
import coinConfig from '../config'
|
|
7
7
|
import { UnsupportedOperationKind } from '../types/errors'
|
|
8
8
|
import { craftRawOperations } from './craftRawOperations'
|
|
9
9
|
import { getTezosToolkit } from './tezosToolkit'
|
|
10
10
|
|
|
11
11
|
jest.mock('./tezosToolkit')
|
|
12
|
-
jest.mock('../config', () => ({
|
|
13
|
-
getCoinConfig: jest.fn(),
|
|
14
|
-
}))
|
|
15
12
|
// Keep real validatePublicKey/normalize, override only the pkh derivation so we can
|
|
16
13
|
// pair an arbitrary valid edpk with our test sender in the reveal path.
|
|
17
14
|
jest.mock('@taquito/utils', () => ({
|
|
@@ -47,6 +44,14 @@ describe('craftRawOperations', () => {
|
|
|
47
44
|
return mockTezosToolkit.rpc.forgeOperations.mock.calls[0][0].contents
|
|
48
45
|
}
|
|
49
46
|
|
|
47
|
+
const context: TezosContext = {
|
|
48
|
+
config: async () =>
|
|
49
|
+
({
|
|
50
|
+
fees: { minFees: 100, minRevealGasLimit: 0, minStorageLimit: 0 },
|
|
51
|
+
}) as unknown as TezosCoinConfig,
|
|
52
|
+
logger: () => undefined,
|
|
53
|
+
}
|
|
54
|
+
|
|
50
55
|
beforeEach(() => {
|
|
51
56
|
jest.clearAllMocks()
|
|
52
57
|
;(getTezosToolkit as jest.Mock).mockReturnValue(mockTezosToolkit)
|
|
@@ -58,15 +63,12 @@ describe('craftRawOperations', () => {
|
|
|
58
63
|
mockTezosToolkit.estimate.batch.mockResolvedValue([
|
|
59
64
|
{ suggestedFeeMutez: 500, gasLimit: 1400, storageLimit: 0 },
|
|
60
65
|
])
|
|
61
|
-
;(coinConfig.getCoinConfig as jest.Mock).mockReturnValue({
|
|
62
|
-
fees: { minFees: 100, minRevealGasLimit: 0, minStorageLimit: 0 },
|
|
63
|
-
})
|
|
64
66
|
})
|
|
65
67
|
|
|
66
68
|
it('forges a plain transfer, estimating the missing limits', async () => {
|
|
67
69
|
const ops = [{ kind: 'transaction', destination: RECIPIENT, amount: '1000' }]
|
|
68
70
|
|
|
69
|
-
const result = await craftRawOperations(JSON.stringify(ops), SENDER, PUBLIC_KEY, 5n)
|
|
71
|
+
const result = await craftRawOperations(context, JSON.stringify(ops), SENDER, PUBLIC_KEY, 5n)
|
|
70
72
|
|
|
71
73
|
expect(result).toBe('03deadbeef') // 0x03 watermark + forged bytes
|
|
72
74
|
expect(mockTezosToolkit.estimate.batch).toHaveBeenCalledWith([
|
|
@@ -90,7 +92,7 @@ describe('craftRawOperations', () => {
|
|
|
90
92
|
const parameters = { entrypoint: 'transfer', value: { prim: 'Unit' } }
|
|
91
93
|
const ops = [{ kind: 'transaction', destination: CONTRACT, amount: '0', parameters }]
|
|
92
94
|
|
|
93
|
-
await craftRawOperations(JSON.stringify(ops), SENDER, PUBLIC_KEY, 7n)
|
|
95
|
+
await craftRawOperations(context, JSON.stringify(ops), SENDER, PUBLIC_KEY, 7n)
|
|
94
96
|
|
|
95
97
|
expect(mockTezosToolkit.estimate.batch).toHaveBeenCalledWith([
|
|
96
98
|
{
|
|
@@ -116,7 +118,7 @@ describe('craftRawOperations', () => {
|
|
|
116
118
|
])
|
|
117
119
|
const ops = [{ kind: 'delegation', delegate: BAKER }]
|
|
118
120
|
|
|
119
|
-
await craftRawOperations(JSON.stringify(ops), SENDER, PUBLIC_KEY, 3n)
|
|
121
|
+
await craftRawOperations(context, JSON.stringify(ops), SENDER, PUBLIC_KEY, 3n)
|
|
120
122
|
|
|
121
123
|
expect(mockTezosToolkit.estimate.batch).toHaveBeenCalledWith([
|
|
122
124
|
{ kind: OpKind.DELEGATION, source: SENDER, delegate: BAKER },
|
|
@@ -149,7 +151,7 @@ describe('craftRawOperations', () => {
|
|
|
149
151
|
},
|
|
150
152
|
]
|
|
151
153
|
|
|
152
|
-
await craftRawOperations(JSON.stringify(ops), SENDER, PUBLIC_KEY, 9n)
|
|
154
|
+
await craftRawOperations(context, JSON.stringify(ops), SENDER, PUBLIC_KEY, 9n)
|
|
153
155
|
|
|
154
156
|
expect(mockTezosToolkit.estimate.batch).toHaveBeenCalledTimes(1)
|
|
155
157
|
const contents = forgedContents()
|
|
@@ -173,7 +175,7 @@ describe('craftRawOperations', () => {
|
|
|
173
175
|
])
|
|
174
176
|
const ops = [{ kind: 'transaction', destination: RECIPIENT, amount: '1000' }]
|
|
175
177
|
|
|
176
|
-
await craftRawOperations(JSON.stringify(ops), SENDER, PUBLIC_KEY, 5n)
|
|
178
|
+
await craftRawOperations(context, JSON.stringify(ops), SENDER, PUBLIC_KEY, 5n)
|
|
177
179
|
|
|
178
180
|
const contents = forgedContents()
|
|
179
181
|
expect(contents[0].kind).toBe(OpKind.REVEAL)
|
|
@@ -193,9 +195,9 @@ describe('craftRawOperations', () => {
|
|
|
193
195
|
])
|
|
194
196
|
const ops = [{ kind: 'transaction', destination: RECIPIENT, amount: '1000' }]
|
|
195
197
|
|
|
196
|
-
await expect(
|
|
197
|
-
|
|
198
|
-
)
|
|
198
|
+
await expect(
|
|
199
|
+
craftRawOperations(context, JSON.stringify(ops), SENDER, PUBLIC_KEY, 5n)
|
|
200
|
+
).rejects.toThrow('expected 1 estimate(s)')
|
|
199
201
|
})
|
|
200
202
|
|
|
201
203
|
it('honours caller-provided fee/gas/storage without estimating', async () => {
|
|
@@ -210,7 +212,7 @@ describe('craftRawOperations', () => {
|
|
|
210
212
|
},
|
|
211
213
|
]
|
|
212
214
|
|
|
213
|
-
await craftRawOperations(JSON.stringify(ops), SENDER, PUBLIC_KEY, 5n)
|
|
215
|
+
await craftRawOperations(context, JSON.stringify(ops), SENDER, PUBLIC_KEY, 5n)
|
|
214
216
|
|
|
215
217
|
expect(mockTezosToolkit.estimate.batch).not.toHaveBeenCalled()
|
|
216
218
|
expect(forgedContents()[0]).toMatchObject({
|
|
@@ -231,7 +233,7 @@ describe('craftRawOperations', () => {
|
|
|
231
233
|
|
|
232
234
|
const ops = [{ kind: 'transaction', destination: RECIPIENT, amount: '1000' }]
|
|
233
235
|
|
|
234
|
-
await craftRawOperations(JSON.stringify(ops), SENDER, PUBLIC_KEY, 5n)
|
|
236
|
+
await craftRawOperations(context, JSON.stringify(ops), SENDER, PUBLIC_KEY, 5n)
|
|
235
237
|
|
|
236
238
|
const contents = forgedContents()
|
|
237
239
|
expect(contents).toHaveLength(2)
|
|
@@ -251,7 +253,7 @@ describe('craftRawOperations', () => {
|
|
|
251
253
|
|
|
252
254
|
const ops = [{ kind: 'transaction', destination: RECIPIENT, amount: '1000' }]
|
|
253
255
|
|
|
254
|
-
await craftRawOperations(JSON.stringify(ops), SENDER, PUBLIC_KEY, 5n)
|
|
256
|
+
await craftRawOperations(context, JSON.stringify(ops), SENDER, PUBLIC_KEY, 5n)
|
|
255
257
|
|
|
256
258
|
const reveal = forgedContents()[0]
|
|
257
259
|
expect(reveal.kind).toBe(OpKind.REVEAL)
|
|
@@ -266,39 +268,40 @@ describe('craftRawOperations', () => {
|
|
|
266
268
|
|
|
267
269
|
const ops = [{ kind: 'transaction', destination: RECIPIENT, amount: '1000' }]
|
|
268
270
|
|
|
269
|
-
await expect(
|
|
270
|
-
|
|
271
|
-
)
|
|
271
|
+
await expect(
|
|
272
|
+
craftRawOperations(context, JSON.stringify(ops), SENDER, PUBLIC_KEY, 5n)
|
|
273
|
+
).rejects.toThrow('does not match the sender')
|
|
272
274
|
})
|
|
273
275
|
|
|
274
276
|
it('throws on an unsupported operation kind', async () => {
|
|
275
277
|
const ops = [{ kind: 'origination', balance: '0' }]
|
|
276
278
|
|
|
277
279
|
await expect(
|
|
278
|
-
craftRawOperations(JSON.stringify(ops), SENDER, PUBLIC_KEY, 5n)
|
|
280
|
+
craftRawOperations(context, JSON.stringify(ops), SENDER, PUBLIC_KEY, 5n)
|
|
279
281
|
).rejects.toBeInstanceOf(UnsupportedOperationKind)
|
|
280
282
|
})
|
|
281
283
|
|
|
282
284
|
describe('input validation', () => {
|
|
283
285
|
it('throws on malformed JSON or an empty array', async () => {
|
|
284
|
-
await expect(craftRawOperations('not-json', SENDER, PUBLIC_KEY, 5n)).rejects.toThrow(
|
|
286
|
+
await expect(craftRawOperations(context, 'not-json', SENDER, PUBLIC_KEY, 5n)).rejects.toThrow(
|
|
285
287
|
'must be a JSON array'
|
|
286
288
|
)
|
|
287
|
-
await expect(craftRawOperations('[]', SENDER, PUBLIC_KEY, 5n)).rejects.toThrow(
|
|
289
|
+
await expect(craftRawOperations(context, '[]', SENDER, PUBLIC_KEY, 5n)).rejects.toThrow(
|
|
288
290
|
'non-empty array'
|
|
289
291
|
)
|
|
290
292
|
})
|
|
291
293
|
|
|
292
294
|
it('throws on a non-integer amount', async () => {
|
|
293
295
|
const ops = [{ kind: 'transaction', destination: RECIPIENT, amount: '1.5' }]
|
|
294
|
-
await expect(
|
|
295
|
-
|
|
296
|
-
)
|
|
296
|
+
await expect(
|
|
297
|
+
craftRawOperations(context, JSON.stringify(ops), SENDER, PUBLIC_KEY, 5n)
|
|
298
|
+
).rejects.toThrow('`amount` must be a non-negative integer string')
|
|
297
299
|
})
|
|
298
300
|
|
|
299
301
|
it('throws on a missing or invalid destination', async () => {
|
|
300
302
|
await expect(
|
|
301
303
|
craftRawOperations(
|
|
304
|
+
context,
|
|
302
305
|
JSON.stringify([{ kind: 'transaction', amount: '1000' }]),
|
|
303
306
|
SENDER,
|
|
304
307
|
PUBLIC_KEY,
|
|
@@ -307,6 +310,7 @@ describe('craftRawOperations', () => {
|
|
|
307
310
|
).rejects.toThrow('valid `destination`')
|
|
308
311
|
await expect(
|
|
309
312
|
craftRawOperations(
|
|
313
|
+
context,
|
|
310
314
|
JSON.stringify([{ kind: 'transaction', destination: 'not-an-address', amount: '1000' }]),
|
|
311
315
|
SENDER,
|
|
312
316
|
PUBLIC_KEY,
|
|
@@ -317,14 +321,15 @@ describe('craftRawOperations', () => {
|
|
|
317
321
|
|
|
318
322
|
it('throws on a non-numeric fee', async () => {
|
|
319
323
|
const ops = [{ kind: 'transaction', destination: RECIPIENT, amount: '1000', fee: 'abc' }]
|
|
320
|
-
await expect(
|
|
321
|
-
|
|
322
|
-
)
|
|
324
|
+
await expect(
|
|
325
|
+
craftRawOperations(context, JSON.stringify(ops), SENDER, PUBLIC_KEY, 5n)
|
|
326
|
+
).rejects.toThrow('`fee` must be a non-negative integer string')
|
|
323
327
|
})
|
|
324
328
|
|
|
325
329
|
it('rejects an empty or invalid delegate (must not be treated as undelegation)', async () => {
|
|
326
330
|
await expect(
|
|
327
331
|
craftRawOperations(
|
|
332
|
+
context,
|
|
328
333
|
JSON.stringify([{ kind: 'delegation', delegate: '' }]),
|
|
329
334
|
SENDER,
|
|
330
335
|
PUBLIC_KEY,
|
|
@@ -333,6 +338,7 @@ describe('craftRawOperations', () => {
|
|
|
333
338
|
).rejects.toThrow('`delegate` must be a valid implicit account address')
|
|
334
339
|
await expect(
|
|
335
340
|
craftRawOperations(
|
|
341
|
+
context,
|
|
336
342
|
JSON.stringify([{ kind: 'delegation', delegate: 123 }]),
|
|
337
343
|
SENDER,
|
|
338
344
|
PUBLIC_KEY,
|
|
@@ -344,6 +350,7 @@ describe('craftRawOperations', () => {
|
|
|
344
350
|
it('rejects a contract (KT1) delegate (delegates must be implicit accounts)', async () => {
|
|
345
351
|
await expect(
|
|
346
352
|
craftRawOperations(
|
|
353
|
+
context,
|
|
347
354
|
JSON.stringify([{ kind: 'delegation', delegate: CONTRACT }]),
|
|
348
355
|
SENDER,
|
|
349
356
|
PUBLIC_KEY,
|
|
@@ -356,7 +363,13 @@ describe('craftRawOperations', () => {
|
|
|
356
363
|
mockTezosToolkit.estimate.batch.mockResolvedValue([
|
|
357
364
|
{ suggestedFeeMutez: 400, gasLimit: 1000, storageLimit: 0 },
|
|
358
365
|
])
|
|
359
|
-
await craftRawOperations(
|
|
366
|
+
await craftRawOperations(
|
|
367
|
+
context,
|
|
368
|
+
JSON.stringify([{ kind: 'delegation' }]),
|
|
369
|
+
SENDER,
|
|
370
|
+
PUBLIC_KEY,
|
|
371
|
+
5n
|
|
372
|
+
)
|
|
360
373
|
|
|
361
374
|
const content = forgedContents()[0]
|
|
362
375
|
expect(content.kind).toBe(OpKind.DELEGATION)
|
|
@@ -367,6 +380,7 @@ describe('craftRawOperations', () => {
|
|
|
367
380
|
const ops = [{ kind: 'transaction', destination: RECIPIENT, amount: '1000' }]
|
|
368
381
|
await expect(
|
|
369
382
|
craftRawOperations(
|
|
383
|
+
context,
|
|
370
384
|
JSON.stringify(ops),
|
|
371
385
|
SENDER,
|
|
372
386
|
PUBLIC_KEY,
|
|
@@ -378,10 +392,10 @@ describe('craftRawOperations', () => {
|
|
|
378
392
|
it('throws on an invalid or contract (KT1) sender address', async () => {
|
|
379
393
|
const ops = [{ kind: 'transaction', destination: RECIPIENT, amount: '1000' }]
|
|
380
394
|
await expect(
|
|
381
|
-
craftRawOperations(JSON.stringify(ops), 'not-an-address', PUBLIC_KEY, 5n)
|
|
395
|
+
craftRawOperations(context, JSON.stringify(ops), 'not-an-address', PUBLIC_KEY, 5n)
|
|
382
396
|
).rejects.toThrow('`sender` must be a valid implicit account address')
|
|
383
397
|
await expect(
|
|
384
|
-
craftRawOperations(JSON.stringify(ops), CONTRACT, PUBLIC_KEY, 5n)
|
|
398
|
+
craftRawOperations(context, JSON.stringify(ops), CONTRACT, PUBLIC_KEY, 5n)
|
|
385
399
|
).rejects.toThrow('`sender` must be a valid implicit account address')
|
|
386
400
|
})
|
|
387
401
|
})
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: © 2026 LEDGER SAS
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import type { TezosContext } from '../config'
|
|
4
5
|
import type { MichelsonV1Expression, OperationContents } from '@taquito/rpc'
|
|
5
6
|
import type { Estimate, ParamsWithKind } from '@taquito/taquito'
|
|
6
7
|
import { OpKind } from '@taquito/rpc'
|
|
@@ -11,7 +12,6 @@ import {
|
|
|
11
12
|
validatePublicKey,
|
|
12
13
|
ValidationResult,
|
|
13
14
|
} from '@taquito/utils'
|
|
14
|
-
import coinConfig from '../config'
|
|
15
15
|
import { UnsupportedOperationKind } from '../types/errors'
|
|
16
16
|
import { createMockSigner, normalizePublicKeyForAddress } from '../utils'
|
|
17
17
|
import { rawEncode } from './craftTransaction'
|
|
@@ -61,11 +61,13 @@ type ResolvedLimits = { fee: string; gasLimit: string; storageLimit: string }
|
|
|
61
61
|
* `signer.signTransaction` + `combine` + broadcast path applies to it unchanged.
|
|
62
62
|
*/
|
|
63
63
|
export async function craftRawOperations(
|
|
64
|
+
context: TezosContext,
|
|
64
65
|
rawTransaction: string,
|
|
65
66
|
sender: string,
|
|
66
67
|
publicKey: string,
|
|
67
68
|
sequence: bigint
|
|
68
69
|
): Promise<string> {
|
|
70
|
+
const config = await context.config()
|
|
69
71
|
if (sequence < 0n || sequence > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
70
72
|
throw new Error('craftRawOperations: sequence is out of the safe integer range')
|
|
71
73
|
}
|
|
@@ -74,12 +76,12 @@ export async function craftRawOperations(
|
|
|
74
76
|
}
|
|
75
77
|
const operations = parseOperations(rawTransaction)
|
|
76
78
|
|
|
77
|
-
const tezosToolkit = getTezosToolkit()
|
|
79
|
+
const tezosToolkit = getTezosToolkit(config)
|
|
78
80
|
const normalizedPk = normalizePublicKeyForAddress(publicKey, sender)
|
|
79
81
|
// Mock signer lets Taquito estimate without a connected device.
|
|
80
82
|
tezosToolkit.setProvider({ signer: createMockSigner(sender, normalizedPk ?? '') })
|
|
81
83
|
|
|
82
|
-
const feesConfig =
|
|
84
|
+
const feesConfig = config.fees
|
|
83
85
|
const minFees = feesConfig.minFees
|
|
84
86
|
|
|
85
87
|
let counter = Number(sequence)
|
|
@@ -115,7 +117,7 @@ export async function craftRawOperations(
|
|
|
115
117
|
counter += 1
|
|
116
118
|
})
|
|
117
119
|
|
|
118
|
-
return rawEncode(contents)
|
|
120
|
+
return rawEncode(config, contents)
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
function parseOperations(rawTransaction: string): PartialTezosOperation[] {
|