class Sibit::Btc
Btc.com API.
Public Class Methods
new(log: Sibit::Log.new, http: Sibit::Http.new, dry: false)
click to toggle source
Constructor.
# File lib/sibit/btc.rb, line 43 def initialize(log: Sibit::Log.new, http: Sibit::Http.new, dry: false) @http = http @log = log @dry = dry end
Public Instance Methods
balance(address)
click to toggle source
Gets the balance of the address, in satoshi.
# File lib/sibit/btc.rb, line 55 def balance(address) uri = Iri.new('https://chain.api.btc.com/v3/address').append(address).append('unspent') json = Sibit::Json.new(http: @http, log: @log).get(uri) if json['err_no'] == 1 @log.info("The balance of #{address} is zero (not found)") return 0 end data = json['data'] if data.nil? @log.info("The balance of #{address} is probably zero (not found)") return 0 end txns = data['list'] if txns.nil? @log.info("The balance of #{address} is probably zero (not found)") return 0 end balance = txns.map { |tx| tx['value'] }.inject(&:+) || 0 @log.info("The balance of #{address} is #{balance}, total txns: #{txns.count}") balance end
block(hash)
click to toggle source
This method should fetch a Blockchain
block and return as a hash.
# File lib/sibit/btc.rb, line 156 def block(hash) head = Sibit::Json.new(http: @http, log: @log).get( Iri.new('https://chain.api.btc.com/v3/block').append(hash) ) data = head['data'] raise Sibit::Error, "The block #{hash} not found" if data.nil? nxt = data['next_block_hash'] nxt = nil if nxt == '0000000000000000000000000000000000000000000000000000000000000000' { provider: self.class.name, hash: data['hash'], orphan: data['is_orphan'], next: nxt, previous: data['prev_block_hash'], txns: txns(hash) } end
fees()
click to toggle source
Get recommended fees, in satoshi per byte.
# File lib/sibit/btc.rb, line 105 def fees raise Sibit::NotSupportedError, 'Btc.com doesn\'t provide recommended fees' end
height(hash)
click to toggle source
The height of the block.
# File lib/sibit/btc.rb, line 92 def height(hash) json = Sibit::Json.new(http: @http, log: @log).get( Iri.new('https://chain.api.btc.com/v3/block').append(hash) ) data = json['data'] raise Sibit::Error, "The block #{hash} not found" if data.nil? h = data['height'] raise Sibit::Error, "The block #{hash} found but the height is absent" if h.nil? @log.info("The height of #{hash} is #{h}") h end
latest()
click to toggle source
Gets the hash of the latest block.
# File lib/sibit/btc.rb, line 110 def latest uri = Iri.new('https://chain.api.btc.com/v3/block/latest') json = Sibit::Json.new(http: @http, log: @log).get(uri) data = json['data'] raise Sibit::Error, 'The latest block not found' if data.nil? hash = data['hash'] @log.info("The hash of the latest block is #{hash}") hash end
next_of(hash)
click to toggle source
Get hash of the block after this one, or NIL if it's the last one in Blockchain
.
# File lib/sibit/btc.rb, line 78 def next_of(hash) head = Sibit::Json.new(http: @http, log: @log).get( Iri.new('https://chain.api.btc.com/v3/block').append(hash) ) data = head['data'] raise Sibit::Error, "The block #{hash} not found" if data.nil? nxt = data['next_block_hash'] nxt = nil if nxt == '0000000000000000000000000000000000000000000000000000000000000000' @log.info("In BTC.com the block #{hash} is the latest, there is no next block") if nxt.nil? @log.info("The next block of #{hash} is #{nxt}") unless nxt.nil? nxt end
price(_currency = 'USD')
click to toggle source
Current price of BTC in USD (float returned).
# File lib/sibit/btc.rb, line 50 def price(_currency = 'USD') raise Sibit::NotSupportedError, 'Btc.com API doesn\'t provide prices' end
push(_hex)
click to toggle source
Push this transaction (in hex format) to the network.
# File lib/sibit/btc.rb, line 151 def push(_hex) raise Sibit::NotSupportedError, 'Btc.com doesn\'t provide payment gateway' end
utxos(sources)
click to toggle source
Fetch all unspent outputs per address.
# File lib/sibit/btc.rb, line 121 def utxos(sources) txns = [] sources.each do |hash| json = Sibit::Json.new(http: @http, log: @log).get( Iri.new('https://chain.api.btc.com/v3/address').append(hash).append('unspent') ) data = json['data'] raise Sibit::Error, "The address #{hash} not found" if data.nil? txns = data['list'] next if txns.nil? txns.each do |u| outs = Sibit::Json.new(http: @http, log: @log).get( Iri.new('https://chain.api.btc.com/v3/tx').append(u['tx_hash']).add(verbose: 3) )['data']['outputs'] outs.each_with_index do |o, i| next unless o['addresses'].include?(hash) txns << { value: o['value'], hash: u['tx_hash'], index: i, confirmations: u['confirmations'], script: [o['script_hex']].pack('H*') } end end end txns end
Private Instance Methods
txns(hash)
click to toggle source
# File lib/sibit/btc.rb, line 176 def txns(hash) page = 1 psize = 50 all = [] loop do data = Sibit::Json.new(http: @http, log: @log).get( Iri.new('https://chain.api.btc.com/v3/block') .append(hash).append('tx').add(page: page, pagesize: psize) )['data'] raise Sibit::Error, "The block #{hash} has no data at page #{page}" if data.nil? list = data['list'] raise Sibit::Error, "The list is empty for block #{hash} at page #{page}" if list.nil? txns = list.map do |t| { hash: t['hash'], outputs: t['outputs'].reject { |o| o['spent_by_tx'] }.map do |o| { address: o['addresses'][0], value: o['value'] } end } end all += txns page += 1 break if txns.length < psize end all end