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.



43
44
45
46
47
# 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

Instance Method Details

#balance(address) ⇒ Object

Gets the balance of the address, in satoshi.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# 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) ⇒ Object

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

Raises:



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# 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

#feesObject

Get recommended fees, in satoshi per byte.



105
106
107
# File 'lib/sibit/btc.rb', line 105

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

#height(hash) ⇒ Object

The height of the block.

Raises:



92
93
94
95
96
97
98
99
100
101
102
# 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

#latestObject

Gets the hash of the latest block.

Raises:



110
111
112
113
114
115
116
117
118
# 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) ⇒ Object

Get hash of the block after this one, or NIL if it’s the last one in Blockchain.

Raises:



78
79
80
81
82
83
84
85
86
87
88
89
# 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') ⇒ Object

Current price of BTC in USD (float returned).



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

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.



151
152
153
# File 'lib/sibit/btc.rb', line 151

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

#utxos(sources) ⇒ Object

Fetch all unspent outputs per address.



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# 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