1
1
/* eslint-disable @typescript-eslint/no-explicit-any */
2
2
import * as Crypto from '@cardano-sdk/crypto' ;
3
3
import * as Trezor from '@trezor/connect' ;
4
+ import { BIP32Path } from '@cardano-sdk/crypto' ;
4
5
import { Cardano , NotImplementedError , Serialization } from '@cardano-sdk/core' ;
5
6
import {
6
7
CardanoKeyConst ,
@@ -9,6 +10,7 @@ import {
9
10
KeyAgentDependencies ,
10
11
KeyAgentType ,
11
12
KeyPurpose ,
13
+ KeyRole ,
12
14
SerializableTrezorKeyAgentData ,
13
15
SignBlobResult ,
14
16
SignTransactionContext ,
@@ -68,6 +70,10 @@ const containsOnlyScriptHashCredentials = (tx: Omit<Trezor.CardanoSignTransactio
68
70
return ! tx . withdrawals ?. some ( ( withdrawal ) => ! withdrawal . scriptHash ) ;
69
71
} ;
70
72
73
+ const multiSigWitnessPaths : BIP32Path [ ] = [
74
+ util . accountKeyDerivationPathToBip32Path ( 0 , { index : 0 , role : KeyRole . External } , KeyPurpose . MULTI_SIG )
75
+ ] ;
76
+
71
77
const isMultiSig = ( tx : Omit < Trezor . CardanoSignTransaction , 'signingMode' > ) : boolean => {
72
78
const allThirdPartyInputs = ! tx . inputs . some ( ( input ) => input . path ) ;
73
79
// Trezor doesn't allow change outputs to address controlled by your keys and instead you have to use script address for change out
@@ -100,7 +106,8 @@ export class TrezorKeyAgent extends KeyAgentBase {
100
106
manifest,
101
107
communicationType,
102
108
silentMode = false ,
103
- lazyLoad = false
109
+ lazyLoad = false ,
110
+ shouldHandlePassphrase = false
104
111
} : TrezorConfig ) : Promise < boolean > {
105
112
const trezorConnect = getTrezorConnect ( communicationType ) ;
106
113
try {
@@ -116,6 +123,23 @@ export class TrezorKeyAgent extends KeyAgentBase {
116
123
// Show Trezor Suite popup. Disabled for node based apps
117
124
popup : communicationType !== CommunicationType . Node && ! silentMode
118
125
} ) ;
126
+
127
+ if ( shouldHandlePassphrase ) {
128
+ trezorConnect . on ( Trezor . UI_EVENT , ( event ) => {
129
+ // React on ui-request_passphrase event
130
+ if ( event . type === Trezor . UI . REQUEST_PASSPHRASE && event . payload . device ) {
131
+ trezorConnect . uiResponse ( {
132
+ payload : {
133
+ passphraseOnDevice : true ,
134
+ save : true ,
135
+ value : ''
136
+ } ,
137
+ type : Trezor . UI . RECEIVE_PASSPHRASE
138
+ } ) ;
139
+ }
140
+ } ) ;
141
+ }
142
+
119
143
return true ;
120
144
} catch ( error : any ) {
121
145
if ( error . code === 'Init_AlreadyInitialized' ) return true ;
@@ -215,7 +239,7 @@ export class TrezorKeyAgent extends KeyAgentBase {
215
239
216
240
async signTransaction (
217
241
txBody : Serialization . TransactionBody ,
218
- { knownAddresses, txInKeyPathMap } : SignTransactionContext
242
+ { knownAddresses, txInKeyPathMap, scripts } : SignTransactionContext
219
243
) : Promise < Cardano . Signatures > {
220
244
try {
221
245
await this . isTrezorInitialized ;
@@ -235,12 +259,15 @@ export class TrezorKeyAgent extends KeyAgentBase {
235
259
const trezorConnect = getTrezorConnect ( this . #communicationType) ;
236
260
const result = await trezorConnect . cardanoSignTransaction ( {
237
261
...trezorTxData ,
262
+ ...( signingMode === Trezor . PROTO . CardanoTxSigningMode . MULTISIG_TRANSACTION && {
263
+ additionalWitnessRequests : multiSigWitnessPaths
264
+ } ) ,
238
265
signingMode
239
266
} ) ;
240
267
241
268
const expectedPublicKeys = await Promise . all (
242
269
util
243
- . ownSignatureKeyPaths ( body , knownAddresses , txInKeyPathMap )
270
+ . ownSignatureKeyPaths ( body , knownAddresses , txInKeyPathMap , undefined , scripts )
244
271
. map ( ( derivationPath ) => this . derivePublicKey ( derivationPath ) )
245
272
) ;
246
273
0 commit comments