@@ -441,42 +441,64 @@ To sign a tx with a hardware or external wallet use `tx.getMessageToSign()` to r
441
441
442
442
A legacy transaction will return a Buffer list of the values, and a Typed Transaction ([ EIP-2718] ( https://eips.ethereum.org/EIPS/eip-2718 ) ) will return the serialized output.
443
443
444
- Here is an example of signing txs with ` @ledgerhq/hw-app-eth ` as of ` v6.5.0 ` :
445
-
444
+ Here is an example of signing txs with ` @ledgerhq/hw-app-eth ` with ` v6.45.4 ` and ` @ledgerhq/hw-transport-node-hid ` with ` v6.29.5 ` :
446
445
``` ts
447
- import { Chain , Common } from ' @ethereumjs/common'
448
- import { LegacyTransaction , FeeMarketEIP1559Transaction } from ' @ethereumjs/tx'
446
+ // examples/ledgerSigner.mts
447
+
448
+ import { Chain , Common , Sepolia } from ' @ethereumjs/common'
449
+ import { createLegacyTx , createFeeMarket1559Tx , type LegacyTx , type FeeMarket1559Tx , type LegacyTxData , type FeeMarketEIP1559TxData } from ' @ethereumjs/tx'
449
450
import { bytesToHex } from ' @ethereumjs/util'
450
451
import { RLP } from ' @ethereumjs/rlp'
451
452
import Eth from ' @ledgerhq/hw-app-eth'
453
+ import TransportNodeHid from ' @ledgerhq/hw-transport-node-hid'
452
454
453
- const eth = new Eth (transport )
454
- const common = new Common ({ chain: Chain .Sepolia })
455
+ const transport = await TransportNodeHid .default .open ()
456
+ const eth = new Eth .default (transport )
457
+ const common = new Common ({ chain: Sepolia })
455
458
456
- let txData: any = { value: 1 }
457
- let tx: LegacyTransaction | FeeMarketEIP1559Transaction
458
- let unsignedTx: Uint8Array [] | Uint8Array
459
- let signedTx: typeof tx
459
+ // Signing with the first key of the derivation path
460
460
const bip32Path = " 44'/60'/0'/0/0"
461
461
462
+ const legacyTxData: LegacyTxData = {
463
+ nonce: ' 0x0' ,
464
+ gasPrice: ' 0x09184e72a000' ,
465
+ gasLimit: ' 0x2710' ,
466
+ to: ' 0x0000000000000000000000000000000000000000' ,
467
+ value: ' 0x00' ,
468
+ data: ' 0x7f7465737432000000000000000000000000000000000000000000000000000000600057' ,
469
+ }
470
+
471
+ const eip1559TxData: FeeMarketEIP1559TxData = {
472
+ data: ' 0x1a8451e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' ,
473
+ gasLimit: ' 0x02625a00' ,
474
+ maxPriorityFeePerGas: ' 0x01' ,
475
+ maxFeePerGas: ' 0xff' ,
476
+ nonce: ' 0x00' ,
477
+ to: ' 0xcccccccccccccccccccccccccccccccccccccccc' ,
478
+ value: ' 0x0186a0' ,
479
+ accessList: [],
480
+ type: ' 0x02' ,
481
+ }
482
+
462
483
const run = async () => {
463
- // Signing a legacy tx
464
- tx = LegacyTransaction .fromTxData (txData , { common })
465
- tx = tx .getMessageToSign ()
466
- // ledger signTransaction API expects it to be serialized
467
- let { v, r, s } = await eth .signTransaction (bip32Path , RLP .encode (tx ))
468
- tx .addSignature (v , r , s , true )
469
- let from = tx .getSenderAddress ().toString ()
470
- console .log (` signedTx: ${bytesToHex (tx .serialize ())}\n from: ${from } ` )
471
-
472
- // Signing a 1559 tx
473
- txData = { value: 1 }
474
- tx = FeeMarketEIP1559Transaction .fromTxData (txData , { common })
475
- tx = tx .getMessageToSign ()
476
- ;({ v , r , s } = await eth .signTransaction (bip32Path , unsignedTx )) // this syntax is: object destructuring - assignment without declaration
477
- tx .addSignature (v , r , s )
478
- from = tx .getSenderAddress ().toString ()
479
- console .log (` signedTx: ${bytesToHex (tx .serialize ())}\n from: ${from } ` )
484
+ // Signing a legacy tx
485
+ const tx1 = createLegacyTx (legacyTxData , { common })
486
+ const unsignedTx1 = tx1 .getMessageToSign ()
487
+ // Ledger signTransaction API expects it to be serialized
488
+ // Ledger returns unprefixed hex strings without 0x for v, r, s values
489
+ const { v, r, s } = await eth .signTransaction (bip32Path , bytesToHex (RLP .encode (unsignedTx1 )).slice (2 ), null )
490
+ const signedTx1 = tx1 .addSignature (BigInt (` 0x${v } ` ), BigInt (` 0x${r } ` ), BigInt (` 0x${s } ` ))
491
+ const from = signedTx1 .getSenderAddress ().toString ()
492
+ console .log (` signedTx: ${bytesToHex (tx1 .serialize ())}\n from: ${from } ` )
493
+
494
+ // Signing a 1559 tx
495
+ const tx2 = createFeeMarket1559Tx (eip1559TxData , { common })
496
+ // Ledger returns unprefixed hex strings without 0x for v, r, s values
497
+ const unsignedTx2 = tx2 .getMessageToSign ()
498
+ const { v2, r2, s2 } = await eth .signTransaction (bip32Path , bytesToHex (unsignedTx2 ).slice (2 ), null )
499
+ const signedTx2 = tx2 .addSignature (BigInt (` 0x${v2 } ` ), BigInt (` 0x${r2 } ` ), BigInt (` 0x${s2 } ` ))
500
+ const from2 = signedTx2 .getSenderAddress ().toString ()
501
+ console .log (` signedTx: ${bytesToHex (tx2 .serialize ())}\n from: ${from2 } ` )
480
502
}
481
503
482
504
run ()
0 commit comments