I'm trying to add a signature using a Ledger Nano HW wallet but I could not find a question about it. I'm going to research the topic and post a working solution for that.
I managed to do it with the following TypeScript code:
import { Transaction, Keypair, xdr, Network } from 'stellar-sdk'
// import Transport from "@ledgerhq/hw-transport-node-hid"
import Transport from '@ledgerhq/hw-transport-u2f'
import Str from '@ledgerhq/hw-app-str'
export class StellarUtils {
constructor() {
Network.use(new Network(environment.stellar.stellarPassphrase))
}
async getStrPublicKey(): Promise<string> {
const isSupported = await this.isSupported()
if (isSupported) {
const transport = await Transport.create()
const str = new Str(transport)
const result = await str.getPublicKey('44\'/148\'/0\'')
transport.close()
return result.publicKey
} else { throw new Error('Not supported') }
}
async signTransaction(transactionXDR: string) {
const isSupported = await this.isSupported()
if (isSupported) {
const transport = await Transport.create()
const str = new Str(transport)
const tx = new Transaction(transactionXDR)
const result = await str.signTransaction('44\'/148\'/0\'', tx.signatureBase())
const keyPair = Keypair.fromPublicKey(await this.getStrPublicKey())
const hint = (keyPair as any).signatureHint()
const decorated = new (xdr as any).DecoratedSignature({ hint: hint, signature: result.signature });
(tx as any).signatures.push(decorated)
return tx
} else { throw new Error('Not supported') }
}
}