@@ -86,8 +86,10 @@ async function ledgerProvider(options: LedgerProviderOptions) {
86
86
const { generateAddresses, isValidPath } = await import ( './hd-wallet' )
87
87
const { default : Eth } = await import ( '@ledgerhq/hw-app-eth' )
88
88
89
- const { Transaction } = await import ( '@ethereumjs/tx' )
90
- const { default : Common } = await import ( '@ethereumjs/common' )
89
+ const { TransactionFactory : Transaction , Capability } = await import (
90
+ '@ethereumjs/tx'
91
+ )
92
+ const { default : Common , Hardfork } = await import ( '@ethereumjs/common' )
91
93
const ethUtil = await import ( 'ethereumjs-util' )
92
94
const { TypedDataUtils } = await import ( 'eth-sig-util' )
93
95
@@ -403,38 +405,47 @@ async function ledgerProvider(options: LedgerProviderOptions) {
403
405
404
406
async function signTransaction ( transactionData : any ) {
405
407
const path = [ ...addressToPath . values ( ) ] [ 0 ]
406
- const { BN , toBuffer } = ethUtil
408
+ const { rlp } = ethUtil
407
409
const common = new Common ( {
408
- chain : customNetwork || networkName ( networkId )
410
+ chain : customNetwork || networkName ( networkId ) ,
411
+ // Berlin is the minimum hardfork that will allow for EIP1559
412
+ hardfork : Hardfork . Berlin ,
413
+ // List of supported EIPS
414
+ eips : [ 1559 ]
409
415
} )
410
416
try {
417
+ // The below implemenation is adapted from:
418
+ // https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/tx#signing-with-a-hardware-or-external-wallet
419
+ transactionData . gasLimit = transactionData . gas ?? transactionData . gasLimit
411
420
const transaction = Transaction . fromTxData (
412
421
{
413
- ...transactionData ,
414
- gasLimit : transactionData . gas ?? transactionData . gasLimit
422
+ ...transactionData
415
423
} ,
416
- { common, freeze : false }
424
+ { common }
417
425
)
418
- transaction . v = new BN ( toBuffer ( networkId ) )
419
- transaction . r = transaction . s = new BN ( toBuffer ( 0 ) )
420
426
421
- const ledgerResult = await eth . signTransaction (
422
- path ,
423
- transaction . serialize ( ) . toString ( 'hex' )
424
- )
425
- let v = ledgerResult . v . toString ( 16 )
426
- // EIP155 support. check/recalc signature v value.
427
- const rv = parseInt ( v , 16 )
428
- let cv = networkId * 2 + 35
429
- if ( rv !== cv && ( rv & cv ) !== rv ) {
430
- cv += 1 // add signature v bit.
427
+ let unsignedTx = transaction . getMessageToSign ( false )
428
+
429
+ // If this is not an EIP1559 transaction then it is legacy and it needs to be
430
+ // rlp encoded before being passed to ledger
431
+ if ( ! transaction . supports ( Capability . EIP1559FeeMarket ) ) {
432
+ unsignedTx = rlp . encode ( unsignedTx )
431
433
}
432
- v = cv . toString ( 16 )
433
- transaction . v = new BN ( toBuffer ( `0x${ v } ` ) )
434
- transaction . r = new BN ( toBuffer ( `0x${ ledgerResult . r } ` ) )
435
- transaction . s = new BN ( toBuffer ( `0x${ ledgerResult . s } ` ) )
436
434
437
- return `0x${ transaction . serialize ( ) . toString ( 'hex' ) } `
435
+ const { v, r, s } = await eth . signTransaction ( path , unsignedTx )
436
+
437
+ // Reconstruct the signed transaction
438
+ const signedTx = Transaction . fromTxData (
439
+ {
440
+ ...transactionData ,
441
+ v : `0x${ v } ` ,
442
+ r : `0x${ r } ` ,
443
+ s : `0x${ s } `
444
+ } ,
445
+ { common }
446
+ )
447
+
448
+ return `0x${ signedTx . serialize ( ) . toString ( 'hex' ) } `
438
449
} catch ( error ) {
439
450
throw error
440
451
}
0 commit comments