11/* eslint-disable @typescript-eslint/no-explicit-any */
22import * as Crypto from '@cardano-sdk/crypto' ;
33import * as Trezor from '@trezor/connect' ;
4+ import { BIP32Path } from '@cardano-sdk/crypto' ;
45import { Cardano , NotImplementedError , Serialization } from '@cardano-sdk/core' ;
56import {
67 CardanoKeyConst ,
@@ -9,6 +10,7 @@ import {
910 KeyAgentDependencies ,
1011 KeyAgentType ,
1112 KeyPurpose ,
13+ KeyRole ,
1214 SerializableTrezorKeyAgentData ,
1315 SignBlobResult ,
1416 SignTransactionContext ,
@@ -68,6 +70,10 @@ const containsOnlyScriptHashCredentials = (tx: Omit<Trezor.CardanoSignTransactio
6870 return ! tx . withdrawals ?. some ( ( withdrawal ) => ! withdrawal . scriptHash ) ;
6971} ;
7072
73+ const multiSigWitnessPaths : BIP32Path [ ] = [
74+ util . accountKeyDerivationPathToBip32Path ( 0 , { index : 0 , role : KeyRole . External } , KeyPurpose . MULTI_SIG )
75+ ] ;
76+
7177const isMultiSig = ( tx : Omit < Trezor . CardanoSignTransaction , 'signingMode' > ) : boolean => {
7278 const allThirdPartyInputs = ! tx . inputs . some ( ( input ) => input . path ) ;
7379 // 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 {
100106 manifest,
101107 communicationType,
102108 silentMode = false ,
103- lazyLoad = false
109+ lazyLoad = false ,
110+ shouldHandlePassphrase = false
104111 } : TrezorConfig ) : Promise < boolean > {
105112 const trezorConnect = getTrezorConnect ( communicationType ) ;
106113 try {
@@ -116,6 +123,23 @@ export class TrezorKeyAgent extends KeyAgentBase {
116123 // Show Trezor Suite popup. Disabled for node based apps
117124 popup : communicationType !== CommunicationType . Node && ! silentMode
118125 } ) ;
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+
119143 return true ;
120144 } catch ( error : any ) {
121145 if ( error . code === 'Init_AlreadyInitialized' ) return true ;
@@ -215,7 +239,7 @@ export class TrezorKeyAgent extends KeyAgentBase {
215239
216240 async signTransaction (
217241 txBody : Serialization . TransactionBody ,
218- { knownAddresses, txInKeyPathMap } : SignTransactionContext
242+ { knownAddresses, txInKeyPathMap, scripts } : SignTransactionContext
219243 ) : Promise < Cardano . Signatures > {
220244 try {
221245 await this . isTrezorInitialized ;
@@ -235,12 +259,15 @@ export class TrezorKeyAgent extends KeyAgentBase {
235259 const trezorConnect = getTrezorConnect ( this . #communicationType) ;
236260 const result = await trezorConnect . cardanoSignTransaction ( {
237261 ...trezorTxData ,
262+ ...( signingMode === Trezor . PROTO . CardanoTxSigningMode . MULTISIG_TRANSACTION && {
263+ additionalWitnessRequests : multiSigWitnessPaths
264+ } ) ,
238265 signingMode
239266 } ) ;
240267
241268 const expectedPublicKeys = await Promise . all (
242269 util
243- . ownSignatureKeyPaths ( body , knownAddresses , txInKeyPathMap )
270+ . ownSignatureKeyPaths ( body , knownAddresses , txInKeyPathMap , undefined , scripts )
244271 . map ( ( derivationPath ) => this . derivePublicKey ( derivationPath ) )
245272 ) ;
246273
0 commit comments