DEV Community

Cover image for Receive Bitcoin from BIP32 in Rails 6
Linuxander
Linuxander

Posted on

Receive Bitcoin from BIP32 in Rails 6

To implement Bitcoin in Rails 6 to receive payment without private keys and full-node, MoneyTree gem is perfect solution. Allow creation of Master Public Key on offline device, and creation of different address for each payment from MPK on production server. Here is a simple implementation of this:

module Bip32

  private

  #   key should be defined as ENV config variable!
  KEY = 'xpub6AvUGrnEpfvJJFCTd6qEYfMaxry******************qV9cfBUbeUEgNYCCP4omxULbNaRr'
  API = BlockCypher::Api.new

  def initialize_wallet_node!
    MoneyTree::Node.from_bip32(KEY)
  end

  def generate_new_pubkey(index)
    wallet = initialize_wallet_node!
    depth  = wallet.depth
    path   = "M/#{depth}/#{index += 1}"
    pubkey = wallet.node_for_path path
    return pubkey if pubkey
  end

  def get_address_data(address)
    balance = API.address_balance(address)
    return balance if balance
  end

  def payment_success?(address, price)
    data = get_address_data(address)
    data ? coins = data[:balance] : coins = 0
    return true unless coins < price
  end

end

#  HOW TO USE
#
#  If you have :transactions table with :index column, you could do something like this:
#
#
#  data  = Transaction.last                  =>  Find last transaction index or use 0
#  data ? index = data.index : index = 0
#  
#  wallet   = generate_new_pubkey(index)     =>  Generate new public-key from MPK
#  @address = wallet.to_address              =>  Generate address from public key
#  @index   = wallet.to_index
#
#  bitcoin    = get_address_data(@address)   =>  Get address data from BlockCypher
#  address    = JSON.parse(bitcoin)
#    balance  = address[:balance]
#    conf_tx  = address[:n_tx]
#    uncon_tx = address[:unconfirmed_n_tx]
#    uncon_bl = address[:unconfirmed_balance]
#
#
#  or to finalize current order:
#
#  Transaction.finalize! if payment_success?(@address, @transaction.price)
Enter fullscreen mode Exit fullscreen mode

In production MPK should be defined as ENV variable.
For checking transaction data I used BlockCypher api, the fastest method :address_balance. It returns JSON data with confirmed and unconfirmed balance and number of transactions. It's enough to check is order ready for shipping or not.

Top comments (0)