Class: Sibit::Btc

Inherits:
Object
  • Object
show all
Defined in:
lib/sibit/btc.rb

Overview

Btc.com API.

Instance Method Summary collapse

Constructor Details

#initialize(log: Sibit::Log.new, http: Sibit::Http.new, dry: false) ⇒ Btc

Constructor.



42
43
44
45
46
# File 'lib/sibit/btc.rb', line 42

def initialize(log: Sibit::Log.new, http: Sibit::Http.new, dry: false)
  @http = http
  @log = log
  @dry = dry
end

Instance Method Details

#balance(address) ⇒ Object

Gets the balance of the address, in satoshi.



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/sibit/btc.rb', line 54

def balance(address)
  uri = URI("https://chain.api.btc.com/v3/address/#{address}/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
  txns = json['data']['list']
  balance = txns.map { |tx| tx['value'] }.inject(&:+) || 0
  @log.info("The balance of #{address} is #{balance}, total txns: #{txns.count}")
  balance
end

#block(hash) ⇒ Object

This method should fetch a Blockchain block and return as a hash.

Raises:



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/sibit/btc.rb', line 143

def block(hash)
  head = Sibit::Json.new(http: @http, log: @log).get(
    URI("https://chain.api.btc.com/v3/block/#{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'
  {
    hash: data['hash'],
    orphan: data['is_orphan'],
    next: nxt,
    previous: data['prev_block_hash'],
    txns: txns(hash)
  }
end

#feesObject

Get recommended fees, in satoshi per byte.



94
95
96
# File 'lib/sibit/btc.rb', line 94

def fees
  raise Sibit::NotSupportedError, 'Btc.com doesn\'t provide recommended fees'
end

#height(hash) ⇒ Object

The height of the block.

Raises:



82
83
84
85
86
87
88
89
90
91
# File 'lib/sibit/btc.rb', line 82

def height(hash)
  json = Sibit::Json.new(http: @http, log: @log).get(
    URI("https://chain.api.btc.com/v3/block/#{hash}")
  )
  data = json['data']
  raise Sibit::Error, "The block #{hash} not found" if data.nil?
  h = data['height']
  @log.info("The height of #{hash} is #{h}")
  h
end

#latestObject

Gets the hash of the latest block.

Raises:



99
100
101
102
103
104
105
106
107
# File 'lib/sibit/btc.rb', line 99

def latest
  uri = URI('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) ⇒ Object

Get hash of the block after this one.

Raises:



68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/sibit/btc.rb', line 68

def next_of(hash)
  head = Sibit::Json.new(http: @http, log: @log).get(
    URI("https://chain.api.btc.com/v3/block/#{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("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') ⇒ Object

Current price of BTC in USD (float returned).



49
50
51
# File 'lib/sibit/btc.rb', line 49

def price(_currency = 'USD')
  raise Sibit::NotSupportedError, 'Btc.com API doesn\'t provide prices'
end

#push(_hex) ⇒ Object

Push this transaction (in hex format) to the network.



138
139
140
# File 'lib/sibit/btc.rb', line 138

def push(_hex)
  raise Sibit::NotSupportedError, 'Btc.com doesn\'t provide payment gateway'
end

#utxos(sources) ⇒ Object

Fetch all unspent outputs per address.



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/sibit/btc.rb', line 110

def utxos(sources)
  txns = []
  sources.each do |hash|
    json = Sibit::Json.new(http: @http, log: @log).get(
      URI("https://chain.api.btc.com/v3/address/#{hash}/unspent")
    )
    data = json['data']
    raise Sibit::Error, "The address #{hash} not found" if data.nil?
    data['list'].each do |u|
      outs = Sibit::Json.new(http: @http, log: @log).get(
        URI("https://chain.api.btc.com/v3/tx/#{u['tx_hash']}?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