@@ -441,42 +441,64 @@ To sign a tx with a hardware or external wallet use `tx.getMessageToSign()` to r
441441
442442A 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.
443443
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 ` :
446445``` 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'
449450import { bytesToHex } from ' @ethereumjs/util'
450451import { RLP } from ' @ethereumjs/rlp'
451452import Eth from ' @ledgerhq/hw-app-eth'
453+ import TransportNodeHid from ' @ledgerhq/hw-transport-node-hid'
452454
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 })
455458
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
460460const bip32Path = " 44'/60'/0'/0/0"
461461
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+
462483const 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 } ` )
480502}
481503
482504run ()
0 commit comments