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)