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)
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)