Skip to content

Commit

Permalink
feat(BCH - Split): Add coinDust separately from io selection
Browse files Browse the repository at this point in the history
  • Loading branch information
plondon committed Nov 21, 2018
1 parent 97c5b28 commit c00a27e
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 31 deletions.
42 changes: 20 additions & 22 deletions packages/blockchain-wallet-v4/src/redux/payment/bch/sagas.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import * as CoinSelection from '../../../coinSelection'
import * as Coin from '../../../coinSelection/coin'
import settingsSagaFactory from '../../../redux/settings/sagas'
import {
scriptToAddress,
privateKeyStringToKey,
detectPrivateKeyFormat
} from '../../../utils/btc'
Expand Down Expand Up @@ -237,7 +236,9 @@ export default ({ api }) => {
scrambleKey,
fromType,
selection,
changeIndex
changeIndex,
lockSecret,
coinDust
) {
if (!selection) {
throw new Error('missing_selection')
Expand All @@ -246,7 +247,9 @@ export default ({ api }) => {
switch (fromType) {
case ADDRESS_TYPES.ACCOUNT:
return yield call(() =>
taskToPromise(bch.signHDWallet(network, password, wrapper, selection))
taskToPromise(
bch.signHDWallet(network, password, wrapper, selection, coinDust)
)
)
case ADDRESS_TYPES.LEGACY:
return yield call(() =>
Expand Down Expand Up @@ -277,19 +280,6 @@ export default ({ api }) => {
return yield call(() => taskToPromise(pushBitcoinTx(txHex, lockSecret)))
}

// ///////////////////////////////////////////////////////////////////////////
const splitCoins = function*(selection) {
const dust = yield call(api.getBchDust)
const lockSecret = prop('lock_secret', dust)
const address = scriptToAddress(prop('output_script', dust))
const coinDust = Coin.fromJS({ address, value: 546 })

selection.inputs.push(coinDust)
selection.outputs.push(coinDust)

return { selection, lockSecret }
}

// ///////////////////////////////////////////////////////////////////////////
function create ({ network, payment } = { network: undefined, payment: {} }) {
const makePayment = p => ({
Expand Down Expand Up @@ -347,7 +337,17 @@ export default ({ api }) => {
return makePayment(merge(p, { selection }))
},

*getCoinDust () {
const dust = yield call(api.getBchDust)
const script = prop('output_script', dust)
const lockSecret = prop('lock_secret', dust)
const coinDust = Coin.fromJS({ ...dust, script })

return { coinDust, lockSecret }
},

*sign (password, transport, scrambleKey) {
const { coinDust, lockSecret } = yield call(this.getCoinDust)
let signed = yield call(
calculateSignature,
network,
Expand All @@ -356,13 +356,11 @@ export default ({ api }) => {
scrambleKey,
prop('fromType', p),
prop('selection', p),
prop('changeIndex', p)
)
let { selection, lockSecret } = yield call(
splitCoins,
prop('selection', p)
prop('changeIndex', p),
lockSecret,
coinDust
)
return makePayment(merge(p, { ...signed, selection, lockSecret }))
return makePayment(merge(p, { ...signed, lockSecret }))
},

*publish () {
Expand Down
24 changes: 15 additions & 9 deletions packages/blockchain-wallet-v4/src/signer/bch.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { addHDWalletWIFS, addLegacyWIFS } from './wifs.js'
import Btc from '@ledgerhq/hw-app-btc'
import * as crypto from '../walletCrypto'

export const signSelection = curry((network, selection) => {
export const signSelection = curry((network, coinDust, selection) => {
const hashType =
BitcoinCash.Transaction.SIGHASH_ALL |
BitcoinCash.Transaction.SIGHASH_SINGLE |
BitcoinCash.Transaction.SIGHASH_BITCOINCASHBIP143
const tx = new BitcoinCash.TransactionBuilder(network)
tx.enableBitcoinCash(true)
Expand All @@ -25,10 +25,16 @@ export const signSelection = curry((network, selection) => {
coin.value
)
const sign = (coin, i) => tx.sign(i, coin.priv, null, hashType, coin.value)
tx.addInput(
coinDust.txHash,
coinDust.index,
BitcoinCash.Transaction.DEFAULT_SEQUENCE
)
tx.addOutput(coinDust.address, coinDust.value)
forEach(addInput, selection.inputs)
forEach(addOutput, selection.outputs)
addIndex(forEach)(sign, selection.inputs)
const signedTx = tx.build()
const signedTx = tx.buildIncomplete()
return { txHex: signedTx.toHex(), txId: signedTx.getId() }
})

Expand All @@ -40,9 +46,9 @@ export const sortSelection = selection => ({

// signHDWallet :: network -> password -> wrapper -> selection -> Task selection
export const signHDWallet = curry(
(network, secondPassword, wrapper, selection) =>
(network, secondPassword, wrapper, selection, coinDust) =>
addHDWalletWIFS(network, secondPassword, wrapper, selection).map(
signWithWIF(network)
signWithWIF(network, coinDust)
)
)

Expand All @@ -66,13 +72,13 @@ export const wifToKeys = curry((network, selection) =>
)

// signWithWIF :: network -> selection -> selection
export const signWithWIF = curry((network, selection) =>
compose(
signSelection(network),
export const signWithWIF = curry((network, coinDust, selection) => {
return compose(
signSelection(network, coinDust),
sortSelection,
wifToKeys(network)
)(selection)
)
})

export const signWithLockbox = function*(
selection,
Expand Down

0 comments on commit c00a27e

Please sign in to comment.