class Pochette::BaseTrezorTransactionBuilder

Same as TransactionBuilder but outputs a transaction hash with all the required data to create and sign a transaction using a BitcoinTrezor.

Attributes

bip32_address_lookup[RW]
transactions[RW]
trezor_inputs[RW]
trezor_outputs[RW]

Public Class Methods

new(options) click to toggle source
Calls superclass method Pochette::BaseTransactionBuilder::new
# File lib/pochette/base_trezor_transaction_builder.rb, line 16
def initialize(options)
  options = options.dup
  initialize_bip32_addresses(options)
  super(options)
  return unless valid?
  build_trezor_inputs
  build_trezor_outputs
  build_transactions
end

Public Instance Methods

as_hash() click to toggle source
# File lib/pochette/base_trezor_transaction_builder.rb, line 47
def as_hash
  return nil unless valid?
  super.merge(
    trezor_inputs: trezor_inputs,
    trezor_outputs: trezor_outputs,
    transactions: transactions)
end

Protected Instance Methods

address_from_bip32(array) click to toggle source

Bip32 addresses may look like an address with a bip32 path, or an array of xpubs, bip32 path and M (as in M of N) for multisig p2sh addresses.

# File lib/pochette/base_trezor_transaction_builder.rb, line 75
def address_from_bip32(array)
  if array.first.is_a?(String)
    array.first
  else
    public_keys = array.first.collect do |x|
      MoneyTree::Node.from_bip32(x).node_for_path(array[1].join('/')).public_key.key
    end
    address, _ = Bitcoin.pubkeys_to_p2sh_multisig_address(array.last, *public_keys)
    address
  end
end
build_transactions() click to toggle source
# File lib/pochette/base_trezor_transaction_builder.rb, line 124
def build_transactions
  txids = inputs.collect{|i| i[1] }
  self.transactions = backend.list_transactions(txids)
end
build_trezor_inputs() click to toggle source
# File lib/pochette/base_trezor_transaction_builder.rb, line 87
def build_trezor_inputs
  self.trezor_inputs = inputs.collect do |input|
    address = bip32_address_lookup[input[0]]
    hash = { address_n: address[1],
      prev_hash: input[1], prev_index: input[2] }
    if address.size == 3
      xpubs = address.first
      m = address.last
      hash[:script_type] = 'SPENDMULTISIG'
      hash[:multisig] = {
        signatures: [''] * xpubs.size,
        m: m,
        pubkeys: xpubs.collect do |xpub|
          node = MoneyTree::Node.from_bip32(xpub)
          { address_n: address[1],
            node: {
              chain_code: node.chain_code.to_s(16),
              depth: 0, 
              child_num: 0, 
              fingerprint: 0,
              public_key: node.public_key.key,
            }
          }
        end
      }
    end
    hash
  end
end
build_trezor_outputs() click to toggle source
# File lib/pochette/base_trezor_transaction_builder.rb, line 117
def build_trezor_outputs
  self.trezor_outputs = outputs.collect do |address, amount|
    type = Bitcoin.address_type(address) == :hash160 ? 'PAYTOADDRESS' : 'PAYTOSCRIPTHASH'
    { script_type: type, address: address, amount: amount.to_i }
  end
end
initialize_bip32_addresses(options) click to toggle source
# File lib/pochette/base_trezor_transaction_builder.rb, line 61
def initialize_bip32_addresses(options)
  if options[:bip32_addresses].blank?
    self.errors = [:no_bip32_addresses_given]
    return
  end
  options[:addresses] = options[:bip32_addresses].collect{|a| address_from_bip32(a) }
  self.bip32_address_lookup = options[:bip32_addresses].reduce({}) do |accum, addr|
    accum[address_from_bip32(addr)] = addr
    accum
  end
end