Skip to content

Commit 1723cb0

Browse files
fix(hardware-trezor): transaction outputs format are now computed independently
1 parent 5fbe606 commit 1723cb0

File tree

7 files changed

+150
-78
lines changed

7 files changed

+150
-78
lines changed

packages/hardware-trezor/src/TrezorKeyAgent.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -246,13 +246,25 @@ export class TrezorKeyAgent extends KeyAgentBase {
246246
const body = txBody.toCore();
247247
const hash = txBody.hash() as unknown as HexBlob;
248248

249+
const outputsFormat = txBody
250+
.outputs()
251+
.map((out) =>
252+
out.isBabbageOutput()
253+
? Trezor.PROTO.CardanoTxOutputSerializationFormat.MAP_BABBAGE
254+
: Trezor.PROTO.CardanoTxOutputSerializationFormat.ARRAY_LEGACY
255+
);
256+
const collateralReturnFormat = txBody.collateralReturn()?.isBabbageOutput()
257+
? Trezor.PROTO.CardanoTxOutputSerializationFormat.MAP_BABBAGE
258+
: Trezor.PROTO.CardanoTxOutputSerializationFormat.ARRAY_LEGACY;
259+
249260
const trezorTxData = await txToTrezor(body, {
250261
accountIndex: this.accountIndex,
251262
chainId: this.chainId,
263+
collateralReturnFormat,
252264
knownAddresses,
265+
outputsFormat,
253266
tagCborSets: txBody.hasTaggedSets(),
254-
txInKeyPathMap,
255-
useBabbageOutputs: txBody.hasBabbageOutput()
267+
txInKeyPathMap
256268
});
257269

258270
const signingMode = TrezorKeyAgent.matchSigningMode(trezorTxData);

packages/hardware-trezor/src/transformers/tx.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const trezorTxTransformer: Transformer<
1919
certificates: ({ certificates }, context) => (certificates ? mapCerts(certificates, context!) : undefined),
2020
collateralInputs: ({ collaterals }, context) => (collaterals ? mapTxIns(collaterals, context!) : undefined),
2121
collateralReturn: ({ collateralReturn }, context) =>
22-
collateralReturn ? toTxOut(collateralReturn, context!) : undefined,
22+
collateralReturn ? toTxOut({ index: 0, isCollateral: true, txOut: collateralReturn }, context!) : undefined,
2323
fee: ({ fee }) => fee.toString(),
2424
inputs: ({ inputs }, context) => mapTxIns(inputs, context!),
2525
mint: ({ mint }) => mapTokenMap(mint, true),

packages/hardware-trezor/src/transformers/txOut.ts

+18-22
Original file line numberDiff line numberDiff line change
@@ -42,31 +42,27 @@ const getScriptHex = (output: Serialization.TransactionOutput): HexBlob | undefi
4242

4343
const getInlineDatum = (datum: Cardano.PlutusData): string => Serialization.PlutusData.fromCore(datum).toCbor();
4444

45-
export const toTxOut: Transform<Cardano.TxOut, Trezor.CardanoOutput, TrezorTxTransformerContext> = (txOut, context) => {
46-
const destination = toDestination(txOut, context);
45+
export const toTxOut: Transform<
46+
{ txOut: Cardano.TxOut; index: number; isCollateral: boolean },
47+
Trezor.CardanoOutput,
48+
TrezorTxTransformerContext
49+
> = (elem, context) => {
50+
const { txOut, index, isCollateral } = elem;
4751
const output = Serialization.TransactionOutput.fromCore(txOut);
4852
const scriptHex = getScriptHex(output);
53+
const format = isCollateral ? context?.collateralReturnFormat : context?.outputsFormat[index];
54+
const isBabbage = format === Trezor.PROTO.CardanoTxOutputSerializationFormat.MAP_BABBAGE;
4955

50-
return context?.useBabbageOutputs
51-
? {
52-
...destination,
53-
amount: txOut.value.coins.toString(),
54-
datumHash: txOut.datumHash?.toString(),
55-
format: Trezor.PROTO.CardanoTxOutputSerializationFormat.MAP_BABBAGE,
56-
inlineDatum: txOut.datum ? getInlineDatum(txOut.datum) : undefined,
57-
referenceScript: scriptHex,
58-
tokenBundle: mapTokenMap(txOut.value.assets)
59-
}
60-
: {
61-
...destination,
62-
amount: txOut.value.coins.toString(),
63-
datumHash: txOut.datumHash?.toString(),
64-
format: Trezor.PROTO.CardanoTxOutputSerializationFormat.ARRAY_LEGACY,
65-
inlineDatum: undefined,
66-
referenceScript: undefined,
67-
tokenBundle: mapTokenMap(txOut.value.assets)
68-
};
56+
return {
57+
...toDestination(txOut, context),
58+
amount: txOut.value.coins.toString(),
59+
datumHash: txOut.datumHash?.toString(),
60+
format,
61+
inlineDatum: isBabbage ? (txOut.datum ? getInlineDatum(txOut.datum) : undefined) : undefined,
62+
referenceScript: isBabbage ? scriptHex : undefined,
63+
tokenBundle: mapTokenMap(txOut.value.assets)
64+
};
6965
};
7066

7167
export const mapTxOuts = (txOuts: Cardano.TxOut[], context: TrezorTxTransformerContext): Trezor.CardanoOutput[] =>
72-
txOuts.map((txOut) => toTxOut(txOut, context));
68+
txOuts.map((txOut, index) => toTxOut({ index, isCollateral: false, txOut }, context));

packages/hardware-trezor/src/types.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ export type TrezorTxTransformerContext = {
1313
accountIndex: number;
1414
/** Whether sets should be encoded as tagged set in CBOR */
1515
tagCborSets: boolean;
16-
/** Whether to use Babbage output format or not. */
17-
useBabbageOutputs: boolean;
16+
/** The outputs format in the same order as they appear in the transaction. */
17+
outputsFormat: Array<Trezor.PROTO.CardanoTxOutputSerializationFormat>;
18+
/** The collateral return output format. */
19+
collateralReturnFormat: Trezor.PROTO.CardanoTxOutputSerializationFormat | undefined;
1820
} & SignTransactionContext;
1921

2022
export type TrezorTxOutputDestination =

packages/hardware-trezor/test/testData.ts

+20-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as Crypto from '@cardano-sdk/crypto';
2+
import * as Trezor from '@trezor/connect';
23
import { AddressType, GroupedAddress, KeyRole } from '@cardano-sdk/key-management';
34
import { Cardano } from '@cardano-sdk/core';
45
import { HexBlob } from '@cardano-sdk/util';
@@ -169,10 +170,15 @@ export const contextWithKnownAddresses: TrezorTxTransformerContext = {
169170
networkId: Cardano.NetworkId.Testnet,
170171
networkMagic: 999
171172
},
173+
collateralReturnFormat: Trezor.PROTO.CardanoTxOutputSerializationFormat.MAP_BABBAGE,
172174
knownAddresses: [knownAddress],
175+
outputsFormat: [
176+
Trezor.PROTO.CardanoTxOutputSerializationFormat.ARRAY_LEGACY,
177+
Trezor.PROTO.CardanoTxOutputSerializationFormat.MAP_BABBAGE,
178+
Trezor.PROTO.CardanoTxOutputSerializationFormat.ARRAY_LEGACY
179+
],
173180
tagCborSets: false,
174-
txInKeyPathMap: {},
175-
useBabbageOutputs: false
181+
txInKeyPathMap: {}
176182
};
177183

178184
export const contextWithKnownAddressesWithoutStakingCredentials: TrezorTxTransformerContext = {
@@ -181,10 +187,14 @@ export const contextWithKnownAddressesWithoutStakingCredentials: TrezorTxTransfo
181187
networkId: Cardano.NetworkId.Testnet,
182188
networkMagic: 999
183189
},
190+
collateralReturnFormat: Trezor.PROTO.CardanoTxOutputSerializationFormat.MAP_BABBAGE,
184191
knownAddresses: [knownAddressWithoutStakingPath],
192+
outputsFormat: [
193+
Trezor.PROTO.CardanoTxOutputSerializationFormat.ARRAY_LEGACY,
194+
Trezor.PROTO.CardanoTxOutputSerializationFormat.MAP_BABBAGE
195+
],
185196
tagCborSets: false,
186-
txInKeyPathMap: {},
187-
useBabbageOutputs: false
197+
txInKeyPathMap: {}
188198
};
189199

190200
export const contextWithoutKnownAddresses: TrezorTxTransformerContext = {
@@ -193,10 +203,14 @@ export const contextWithoutKnownAddresses: TrezorTxTransformerContext = {
193203
networkId: Cardano.NetworkId.Testnet,
194204
networkMagic: 999
195205
},
206+
collateralReturnFormat: Trezor.PROTO.CardanoTxOutputSerializationFormat.MAP_BABBAGE,
196207
knownAddresses: [],
208+
outputsFormat: [
209+
Trezor.PROTO.CardanoTxOutputSerializationFormat.ARRAY_LEGACY,
210+
Trezor.PROTO.CardanoTxOutputSerializationFormat.MAP_BABBAGE
211+
],
197212
tagCborSets: false,
198-
txInKeyPathMap: {},
199-
useBabbageOutputs: false
213+
txInKeyPathMap: {}
200214
};
201215

202216
export const coreWithdrawalWithKeyHashCredential = {

packages/hardware-trezor/test/transformers/tx.test.ts

+24-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
babbageTxBodyWithScripts,
55
contextWithKnownAddresses,
66
contextWithoutKnownAddresses,
7+
knownAddress,
78
knownAddressKeyPath,
89
knownAddressPaymentKeyPath,
910
knownAddressStakeKeyPath,
@@ -45,6 +46,11 @@ describe('tx', () => {
4546
expect(
4647
await txToTrezor(txBody, {
4748
...contextWithKnownAddresses,
49+
outputsFormat: [
50+
Trezor.PROTO.CardanoTxOutputSerializationFormat.ARRAY_LEGACY,
51+
Trezor.PROTO.CardanoTxOutputSerializationFormat.ARRAY_LEGACY,
52+
Trezor.PROTO.CardanoTxOutputSerializationFormat.ARRAY_LEGACY
53+
],
4854
txInKeyPathMap: { [TxInId(txBody.inputs[0])]: knownAddressPaymentKeyPath }
4955
})
5056
).toEqual({
@@ -202,10 +208,13 @@ describe('tx', () => {
202208
expect(
203209
await txToTrezor(babbageTxBodyWithScripts, {
204210
...contextWithKnownAddresses,
211+
outputsFormat: [
212+
Trezor.PROTO.CardanoTxOutputSerializationFormat.MAP_BABBAGE,
213+
Trezor.PROTO.CardanoTxOutputSerializationFormat.MAP_BABBAGE
214+
],
205215
txInKeyPathMap: {
206216
[TxInId(babbageTxBodyWithScripts.inputs[0])]: knownAddressPaymentKeyPath
207-
},
208-
useBabbageOutputs: true
217+
}
209218
})
210219
).toEqual({
211220
additionalWitnessRequests: [
@@ -286,7 +295,12 @@ describe('tx', () => {
286295
});
287296

288297
test('can map transaction with collaterals', async () => {
289-
expect(await txToTrezor(txBodyWithCollaterals, contextWithoutKnownAddresses)).toEqual({
298+
expect(
299+
await txToTrezor(txBodyWithCollaterals, {
300+
...contextWithoutKnownAddresses,
301+
collateralReturnFormat: Trezor.PROTO.CardanoTxOutputSerializationFormat.ARRAY_LEGACY
302+
})
303+
).toEqual({
290304
additionalWitnessRequests: [],
291305
collateralInputs: [
292306
{
@@ -325,11 +339,16 @@ describe('tx', () => {
325339
expect(
326340
await txToTrezor(plutusTxWithBabbage, {
327341
...contextWithKnownAddresses,
342+
collateralReturnFormat: Trezor.PROTO.CardanoTxOutputSerializationFormat.MAP_BABBAGE,
343+
knownAddresses: [knownAddress],
344+
outputsFormat: [
345+
Trezor.PROTO.CardanoTxOutputSerializationFormat.MAP_BABBAGE,
346+
Trezor.PROTO.CardanoTxOutputSerializationFormat.MAP_BABBAGE
347+
],
328348
txInKeyPathMap: {
329349
[TxInId(plutusTxWithBabbage.inputs[0])]: knownAddressPaymentKeyPath,
330350
[TxInId(plutusTxWithBabbage.collaterals[0])]: knownAddressPaymentKeyPath
331-
},
332-
useBabbageOutputs: true
351+
}
333352
})
334353
).toEqual({
335354
additionalWitnessRequests: [

0 commit comments

Comments
 (0)