Skip to content

Commit

Permalink
Fix Ledger integration (#1324)
Browse files Browse the repository at this point in the history
* Fix ledger integration

* Changelog
  • Loading branch information
hippocampus-web3 authored Dec 20, 2024
1 parent 98eec32 commit af49c34
Show file tree
Hide file tree
Showing 14 changed files with 48 additions and 32 deletions.
10 changes: 10 additions & 0 deletions .changeset/weak-ducks-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@xchainjs/xchain-bitcoincash': patch
'@xchainjs/xchain-litecoin': patch
'@xchainjs/xchain-bitcoin': patch
'@xchainjs/xchain-dash': patch
'@xchainjs/xchain-doge': patch
'@xchainjs/xchain-utxo': patch
---

Fix Ledger integration
4 changes: 2 additions & 2 deletions packages/xchain-bitcoin/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ abstract class Client extends UTXOClient {
spendPendingUTXO?: boolean
}): Promise<PreparedTx> {
// Build the transaction using the provided parameters.
const { psbt, utxos } = await this.buildTx({
const { psbt, utxos, inputs } = await this.buildTx({
sender,
recipient,
amount,
Expand All @@ -258,7 +258,7 @@ abstract class Client extends UTXOClient {
spendPendingUTXO,
})
// Return the raw unsigned transaction (PSBT) and associated UTXOs.
return { rawUnsignedTx: psbt.toBase64(), utxos }
return { rawUnsignedTx: psbt.toBase64(), utxos, inputs }
}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/xchain-bitcoin/src/clientLedger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ class ClientLedger extends Client {
// Get sender address
const sender = await this.getAddressAsync(fromAddressIndex)
// Prepare transaction
const { rawUnsignedTx, utxos } = await this.prepareTx({ ...params, sender, feeRate })
const { rawUnsignedTx, inputs } = await this.prepareTx({ ...params, sender, feeRate })
const psbt = Bitcoin.Psbt.fromBase64(rawUnsignedTx)
// Prepare Ledger inputs
const ledgerInputs: [Transaction, number, string | null, number | null][] = (utxos as UTXO[]).map(
const ledgerInputs: [Transaction, number, string | null, number | null][] = (inputs as UTXO[]).map(
({ txHex, hash, index }) => {
if (!txHex) {
throw Error(`Missing 'txHex' for UTXO (txHash ${hash})`)
Expand Down
4 changes: 2 additions & 2 deletions packages/xchain-bitcoincash/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,15 +175,15 @@ abstract class Client extends UTXOClient {
feeRate: FeeRate
}): Promise<BchPreparedTx> {
// Build the transaction using provided options
const { builder, utxos } = await this.buildTx({
const { builder, utxos, inputs } = await this.buildTx({
sender,
recipient,
amount,
memo,
feeRate,
})
// Return the raw unsigned transaction and UTXOs
return { rawUnsignedTx: builder.buildIncomplete().toHex(), utxos }
return { rawUnsignedTx: builder.buildIncomplete().toHex(), utxos, inputs }
}
/**
* Compile a memo.
Expand Down
7 changes: 4 additions & 3 deletions packages/xchain-bitcoincash/src/clientLedger.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import AppBtc from '@ledgerhq/hw-app-btc'
import { Transaction } from '@ledgerhq/hw-app-btc/lib/types'
import * as bitcash from '@psf/bitcoincashjs-lib'
import { FeeOption, FeeRate, TxHash } from '@xchainjs/xchain-client'
import { FeeOption, FeeRate, TxHash, checkFeeBounds } from '@xchainjs/xchain-client'
import { Address } from '@xchainjs/xchain-util'
import { TxParams, UtxoClientParams } from '@xchainjs/xchain-utxo'

Expand Down Expand Up @@ -53,12 +53,13 @@ class ClientLedger extends Client {
const fromAddressIndex = params?.walletIndex || 0
// Get fee rate
const feeRate = params.feeRate || (await this.getFeeRates())[FeeOption.Fast]
checkFeeBounds(this.feeBounds, feeRate)
// Get sender address
const sender = await this.getAddressAsync(fromAddressIndex)
// Prepare transaction
const { rawUnsignedTx, utxos: txInputs } = await this.prepareTx({ ...params, sender, feeRate })
const { rawUnsignedTx, inputs } = await this.prepareTx({ ...params, sender, feeRate })

const ledgerInputs: Array<[Transaction, number, string | null, number | null]> = txInputs.map(
const ledgerInputs: Array<[Transaction, number, string | null, number | null]> = inputs.map(
({ txHex, hash, index }) => {
if (!txHex) {
throw Error(`Missing 'txHex' for UTXO (txHash ${hash})`)
Expand Down
1 change: 1 addition & 0 deletions packages/xchain-bitcoincash/src/types/client-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ export type GetChangeParams = {

export type BchPreparedTx = {
utxos: BaseUTXO[]
inputs: BaseUTXO[]
} & PreparedTx
4 changes: 2 additions & 2 deletions packages/xchain-dash/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ abstract class Client extends UTXOClient {
feeRate: FeeRate
}): Promise<DashPreparedTx> {
// Build the transaction using provided parameters
const { tx, utxos } = await Utils.buildTx({
const { tx, utxos, inputs } = await Utils.buildTx({
sender,
recipient,
memo,
Expand All @@ -221,7 +221,7 @@ abstract class Client extends UTXOClient {
network: this.network,
})
// Return the raw unsigned transaction and UTXOs
return { rawUnsignedTx: tx.toString(), utxos }
return { rawUnsignedTx: tx.toString(), utxos, inputs }
}
/**
* Compiles a memo into a buffer.
Expand Down
7 changes: 4 additions & 3 deletions packages/xchain-dash/src/clientLedger.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as dashcore from '@dashevo/dashcore-lib'
import AppBtc from '@ledgerhq/hw-app-btc'
import { Transaction as LedgerTransaction } from '@ledgerhq/hw-app-btc/lib/types'
import { FeeOption, FeeRate, TxHash } from '@xchainjs/xchain-client'
import { FeeOption, FeeRate, TxHash, checkFeeBounds } from '@xchainjs/xchain-client'
import { Address } from '@xchainjs/xchain-util'
import { TxParams, UtxoClientParams } from '@xchainjs/xchain-utxo'

Expand Down Expand Up @@ -56,10 +56,11 @@ class ClientLedger extends Client {
const fromAddressIndex = params?.walletIndex || 0
// Get fee rate
const feeRate = params.feeRate || (await this.getFeeRates())[FeeOption.Fast]
checkFeeBounds(this.feeBounds, feeRate)
// Get sender address
const sender = await this.getAddressAsync(fromAddressIndex)
// Prepare transaction
const { rawUnsignedTx, utxos } = await this.prepareTx({ ...params, sender, feeRate })
const { rawUnsignedTx, inputs } = await this.prepareTx({ ...params, sender, feeRate })

const tx = new dashcore.Transaction(rawUnsignedTx)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand All @@ -68,7 +69,7 @@ class ClientLedger extends Client {

for (const input of tx.inputs) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const insightUtxo = utxos.find((utxo) => {
const insightUtxo = inputs.find((utxo) => {
return utxo.hash === input.prevTxId.toString('hex') && utxo.index == input.outputIndex
})
if (!insightUtxo) {
Expand Down
4 changes: 2 additions & 2 deletions packages/xchain-dash/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const buildTx = async ({
sender: Address
network: Network
withTxHex?: boolean
}): Promise<{ tx: Transaction; utxos: UTXO[] }> => {
}): Promise<{ tx: Transaction; utxos: UTXO[]; inputs: UTXO[] }> => {
// Validate recipient address
if (!validateAddress(recipient, network)) throw new Error('Invalid address')

Expand Down Expand Up @@ -152,7 +152,7 @@ export const buildTx = async ({
tx.addData(memo)
}

return { tx, utxos } // Return the built transaction and its UTXOs
return { tx, utxos, inputs } // Return the built transaction and its UTXOs
}

/**
Expand Down
10 changes: 5 additions & 5 deletions packages/xchain-doge/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ abstract class Client extends UTXOClient {
}: TxParams & {
feeRate: FeeRate
sender: Address
}): Promise<{ psbt: Dogecoin.Psbt; utxos: UTXO[] }> => {
}): Promise<{ psbt: Dogecoin.Psbt; utxos: UTXO[]; inputs: UTXO[] }> => {
// Validate the recipient address
if (!this.validateAddress(recipient)) throw new Error('Invalid address')

Expand Down Expand Up @@ -159,7 +159,7 @@ abstract class Client extends UTXOClient {
}
})

return { psbt, utxos }
return { psbt, utxos, inputs }
}

/**
Expand Down Expand Up @@ -198,9 +198,9 @@ abstract class Client extends UTXOClient {
sender: Address
feeRate: FeeRate
spendPendingUTXO?: boolean
}): Promise<PreparedTx & { utxos: UTXO[] }> {
}): Promise<PreparedTx & { utxos: UTXO[]; inputs: UTXO[] }> {
// Build the transaction (PSBT) with the specified transfer options
const { psbt, utxos } = await this.buildTx({
const { psbt, utxos, inputs } = await this.buildTx({
sender,
recipient,
amount,
Expand All @@ -209,7 +209,7 @@ abstract class Client extends UTXOClient {
})

// Return the raw unsigned transaction (PSBT)
return { rawUnsignedTx: psbt.toBase64(), utxos }
return { rawUnsignedTx: psbt.toBase64(), utxos, inputs }
}

/**
Expand Down
7 changes: 4 additions & 3 deletions packages/xchain-doge/src/clientLedger.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import AppBtc from '@ledgerhq/hw-app-btc'
import { Transaction } from '@ledgerhq/hw-app-btc/lib/types'
import { FeeOption, FeeRate, TxHash } from '@xchainjs/xchain-client'
import { FeeOption, FeeRate, TxHash, checkFeeBounds } from '@xchainjs/xchain-client'
import { Address } from '@xchainjs/xchain-util'
import { TxParams, UtxoClientParams } from '@xchainjs/xchain-utxo'
import * as Dogecoin from 'bitcoinjs-lib'
Expand Down Expand Up @@ -52,13 +52,14 @@ class ClientLedger extends Client {
const fromAddressIndex = params?.walletIndex || 0
// Get fee rate
const feeRate = params.feeRate || (await this.getFeeRates())[FeeOption.Fast]
checkFeeBounds(this.feeBounds, feeRate)
// Get sender address
const sender = await this.getAddressAsync(fromAddressIndex)
// Prepare transaction
const { rawUnsignedTx, utxos } = await this.prepareTx({ ...params, sender, feeRate })
const { rawUnsignedTx, inputs } = await this.prepareTx({ ...params, sender, feeRate })
const psbt = Dogecoin.Psbt.fromBase64(rawUnsignedTx)
// Prepare Ledger inputs
const ledgerInputs: Array<[Transaction, number, string | null, number | null]> = utxos.map(
const ledgerInputs: Array<[Transaction, number, string | null, number | null]> = inputs.map(
({ txHex, hash, index }) => {
if (!txHex) {
throw Error(`Missing 'txHex' for UTXO (txHash ${hash})`)
Expand Down
7 changes: 4 additions & 3 deletions packages/xchain-litecoin/src/ClientLedger.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import AppBtc from '@ledgerhq/hw-app-btc'
import { Transaction } from '@ledgerhq/hw-app-btc/lib/types'
import { FeeOption, FeeRate, TxHash } from '@xchainjs/xchain-client'
import { FeeOption, FeeRate, TxHash, checkFeeBounds } from '@xchainjs/xchain-client'
import { Address } from '@xchainjs/xchain-util'
import { TxParams, UtxoClientParams } from '@xchainjs/xchain-utxo'
import * as Litecoin from 'bitcoinjs-lib'
Expand Down Expand Up @@ -54,13 +54,14 @@ class ClientLedger extends Client {
const fromAddressIndex = params?.walletIndex || 0
// Get fee rate
const feeRate = params.feeRate || (await this.getFeeRates())[FeeOption.Fast]
checkFeeBounds(this.feeBounds, feeRate)
// Get sender address
const sender = await this.getAddressAsync(fromAddressIndex)
// Prepare transaction
const { rawUnsignedTx, utxos } = await this.prepareTx({ ...params, sender, feeRate })
const { rawUnsignedTx, inputs } = await this.prepareTx({ ...params, sender, feeRate })
const psbt = Litecoin.Psbt.fromBase64(rawUnsignedTx)
// Prepare Ledger inputs
const ledgerInputs: [Transaction, number, string | null, number | null][] = utxos.map(({ txHex, hash, index }) => {
const ledgerInputs: [Transaction, number, string | null, number | null][] = inputs.map(({ txHex, hash, index }) => {
if (!txHex) {
throw Error(`Missing 'txHex' for UTXO (txHash ${hash})`)
}
Expand Down
10 changes: 5 additions & 5 deletions packages/xchain-litecoin/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ abstract class Client extends UTXOClient {
}: TxParams & {
feeRate: FeeRate
sender: Address
}): Promise<{ psbt: Litecoin.Psbt; utxos: UTXO[] }> {
}): Promise<{ psbt: Litecoin.Psbt; utxos: UTXO[]; inputs: UTXO[] }> {
if (!this.validateAddress(recipient)) throw new Error('Invalid address')

const utxos = await this.scanUTXOs(sender, false)
Expand Down Expand Up @@ -163,7 +163,7 @@ abstract class Client extends UTXOClient {
}
})

return { psbt, utxos }
return { psbt, utxos, inputs }
}

/**
Expand All @@ -182,16 +182,16 @@ abstract class Client extends UTXOClient {
sender: Address
feeRate: FeeRate
spendPendingUTXO?: boolean
}): Promise<PreparedTx & { utxos: UTXO[] }> {
const { psbt, utxos } = await this.buildTx({
}): Promise<PreparedTx & { utxos: UTXO[]; inputs: UTXO[] }> {
const { psbt, utxos, inputs } = await this.buildTx({
sender,
recipient,
amount,
feeRate,
memo,
})

return { rawUnsignedTx: psbt.toBase64(), utxos }
return { rawUnsignedTx: psbt.toBase64(), utxos, inputs }
}
/**
* Compile memo.
Expand Down
1 change: 1 addition & 0 deletions packages/xchain-utxo/src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export type UtxoClientParams = XChainClientParams & {

export type PreparedTx = BasePreparedTx & {
utxos: UTXO[]
inputs: UTXO[]
}

export type TxParams = BaseTxParams & {
Expand Down

0 comments on commit af49c34

Please sign in to comment.