@@ -2,6 +2,7 @@ import { Common, Chain, Hardfork } from '@ethereumjs/common';
22import { RLP } from '@ethereumjs/rlp' ;
33import { TransactionFactory } from '@ethereumjs/tx' ;
44import * as ethUtil from '@ethereumjs/util' ;
5+ import { TransportStatusError } from '@ledgerhq/hw-transport' ;
56import * as sigUtil from '@metamask/eth-sig-util' ;
67import { bytesToHex , Hex , remove0x } from '@metamask/utils' ;
78import EthereumTx from 'ethereumjs-tx' ;
@@ -784,6 +785,60 @@ describe('LedgerKeyring', function () {
784785 keyring . signTransaction ( fakeAccounts [ 0 ] , fakeTx ) ,
785786 ) . rejects . toThrow ( 'Ledger: The transaction signature is not valid' ) ;
786787 } ) ;
788+
789+ it ( 'throws user rejection error when TransportStatusError with code 27013 is thrown' , async function ( ) {
790+ await basicSetupToUnlockOneAccount ( ) ;
791+ const transportError = {
792+ statusCode : 27013 ,
793+ message : 'Ledger device: (denied by the user?) (0x6985)' ,
794+ name : 'TransportStatusError' ,
795+ } ;
796+
797+ Object . setPrototypeOf ( transportError , TransportStatusError . prototype ) ;
798+ jest
799+ . spyOn ( keyring . bridge , 'deviceSignTransaction' )
800+ . mockRejectedValue ( transportError ) ;
801+
802+ await expect (
803+ keyring . signTransaction ( fakeAccounts [ 0 ] , fakeTx ) ,
804+ ) . rejects . toThrow ( 'Ledger: User rejected the transaction' ) ;
805+ } ) ;
806+
807+ it ( 'throws blind signing error when TransportStatusError with code 27264 is thrown' , async function ( ) {
808+ await basicSetupToUnlockOneAccount ( ) ;
809+ const transportError = {
810+ statusCode : 27264 ,
811+ message : 'Ledger device: Invalid data received (0x6a80)' ,
812+ name : 'TransportStatusError' ,
813+ } ;
814+
815+ Object . setPrototypeOf ( transportError , TransportStatusError . prototype ) ;
816+ jest
817+ . spyOn ( keyring . bridge , 'deviceSignTransaction' )
818+ . mockRejectedValue ( transportError ) ;
819+
820+ await expect (
821+ keyring . signTransaction ( fakeAccounts [ 0 ] , fakeTx ) ,
822+ ) . rejects . toThrow ( 'Ledger: Blind signing must be enabled' ) ;
823+ } ) ;
824+
825+ it ( 're-throws TransportStatusError with unknown status code' , async function ( ) {
826+ await basicSetupToUnlockOneAccount ( ) ;
827+ const transportError = {
828+ statusCode : 12345 ,
829+ message : 'Some other transport error' ,
830+ name : 'TransportStatusError' ,
831+ } ;
832+
833+ Object . setPrototypeOf ( transportError , TransportStatusError . prototype ) ;
834+ jest
835+ . spyOn ( keyring . bridge , 'deviceSignTransaction' )
836+ . mockRejectedValue ( transportError ) ;
837+
838+ await expect (
839+ keyring . signTransaction ( fakeAccounts [ 0 ] , fakeTx ) ,
840+ ) . rejects . toThrow ( transportError ) ;
841+ } ) ;
787842 } ) ;
788843
789844 describe ( 'signPersonalMessage' , function ( ) {
@@ -858,6 +913,40 @@ describe('LedgerKeyring', function () {
858913 'Ledger: The signature doesnt match the right address' ,
859914 ) ;
860915 } ) ;
916+
917+ it ( 'throws user rejection error when TransportStatusError with code 27013 is thrown in signPersonalMessage' , async function ( ) {
918+ await basicSetupToUnlockOneAccount ( ) ;
919+ const transportError = {
920+ statusCode : 27013 ,
921+ message : 'Ledger device: (denied by the user?) (0x6985)' ,
922+ name : 'TransportStatusError' ,
923+ } ;
924+ Object . setPrototypeOf ( transportError , TransportStatusError . prototype ) ;
925+ jest
926+ . spyOn ( keyring . bridge , 'deviceSignMessage' )
927+ . mockRejectedValue ( transportError ) ;
928+
929+ await expect (
930+ keyring . signPersonalMessage ( fakeAccounts [ 0 ] , 'some message' ) ,
931+ ) . rejects . toThrow ( 'Ledger: User rejected the transaction' ) ;
932+ } ) ;
933+
934+ it ( 're-throws TransportStatusError with unknown status code in signPersonalMessage' , async function ( ) {
935+ await basicSetupToUnlockOneAccount ( ) ;
936+ const transportError = {
937+ statusCode : 12345 ,
938+ message : 'Some other transport error' ,
939+ name : 'TransportStatusError' ,
940+ } ;
941+ Object . setPrototypeOf ( transportError , TransportStatusError . prototype ) ;
942+ jest
943+ . spyOn ( keyring . bridge , 'deviceSignMessage' )
944+ . mockRejectedValue ( transportError ) ;
945+
946+ await expect (
947+ keyring . signPersonalMessage ( fakeAccounts [ 0 ] , 'some message' ) ,
948+ ) . rejects . toThrow ( transportError ) ;
949+ } ) ;
861950 } ) ;
862951
863952 describe ( 'signMessage' , function ( ) {
@@ -1207,6 +1296,60 @@ describe('LedgerKeyring', function () {
12071296 '0x72d4e38a0e582e09a620fd38e236fe687a1ec782206b56d576f579c026a7e5b946759735981cd0c3efb02d36df28bb2feedfec3d90e408efc93f45b894946e3200' ,
12081297 ) ;
12091298 } ) ;
1299+
1300+ it ( 'throws user rejection error when TransportStatusError with code 27013 is thrown in signTypedData' , async function ( ) {
1301+ const transportError = {
1302+ statusCode : 27013 ,
1303+ message : 'Ledger device: (denied by the user?) (0x6985)' ,
1304+ name : 'TransportStatusError' ,
1305+ } ;
1306+ Object . setPrototypeOf ( transportError , TransportStatusError . prototype ) ;
1307+ jest
1308+ . spyOn ( keyring . bridge , 'deviceSignTypedData' )
1309+ . mockRejectedValue ( transportError ) ;
1310+
1311+ await expect (
1312+ keyring . signTypedData ( fakeAccounts [ 15 ] , fixtureData , {
1313+ version : sigUtil . SignTypedDataVersion . V4 ,
1314+ } ) ,
1315+ ) . rejects . toThrow ( 'Ledger: User rejected the transaction' ) ;
1316+ } ) ;
1317+
1318+ it ( 'throws blind signing error when TransportStatusError with code 27264 is thrown in signTypedData' , async function ( ) {
1319+ const transportError = {
1320+ statusCode : 27264 ,
1321+ message : 'Ledger device: Invalid data received (0x6a80)' ,
1322+ name : 'TransportStatusError' ,
1323+ } ;
1324+ Object . setPrototypeOf ( transportError , TransportStatusError . prototype ) ;
1325+ jest
1326+ . spyOn ( keyring . bridge , 'deviceSignTypedData' )
1327+ . mockRejectedValue ( transportError ) ;
1328+
1329+ await expect (
1330+ keyring . signTypedData ( fakeAccounts [ 15 ] , fixtureData , {
1331+ version : sigUtil . SignTypedDataVersion . V4 ,
1332+ } ) ,
1333+ ) . rejects . toThrow ( 'Ledger: Blind signing must be enabled' ) ;
1334+ } ) ;
1335+
1336+ it ( 're-throws TransportStatusError with unknown status code in signTypedData' , async function ( ) {
1337+ const transportError = {
1338+ statusCode : 12345 ,
1339+ message : 'Some other transport error' ,
1340+ name : 'TransportStatusError' ,
1341+ } ;
1342+ Object . setPrototypeOf ( transportError , TransportStatusError . prototype ) ;
1343+ jest
1344+ . spyOn ( keyring . bridge , 'deviceSignTypedData' )
1345+ . mockRejectedValue ( transportError ) ;
1346+
1347+ await expect (
1348+ keyring . signTypedData ( fakeAccounts [ 15 ] , fixtureData , {
1349+ version : sigUtil . SignTypedDataVersion . V4 ,
1350+ } ) ,
1351+ ) . rejects . toThrow ( transportError ) ;
1352+ } ) ;
12101353 } ) ;
12111354
12121355 describe ( 'destroy' , function ( ) {
0 commit comments