Class: Sibit::Btc

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

Overview

Btc.com API.

Here: https://btc.com/api-doc

Author

Yegor Bugayenko (yegor256@gmail.com)

Copyright

Copyright (c) 2019-2026 Yegor Bugayenko

License

MIT

Instance Method Summary collapse

Constructor Details

#initialize(log: Loog::NULL, http: Sibit::Http.new) ⇒ Btc

Constructor.



24
25
26
27
# File 'lib/sibit/btc.rb', line 24

def initialize(log: Loog::NULL, http: Sibit::Http.new)
  @http = http
  @log = log
end

Instance Method Details

#balance(address) ⇒ Object

Gets the balance of the address, in satoshi.

Raises:



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/sibit/btc.rb', line 35

def balance(address)
  json = Sibit::Json.new(http: @http, log: @log).get(Iri.new('https://chain.api.btc.com/v3/address').append(address).append('unspent'))
  if json['err_no'] == 1
    @log.debug("The balance of #{address} is zero (not found)")
    return 0
  end
  data = json['data']
  raise(Sibit::Error, "The address #{address} not found") if data.nil?
  txns = data['list']
  if txns.nil?
    @log.debug("The balance of #{address} is probably zero (not found)")
    return 0
  end
  balance = txns.sum { |tx| tx['value'] } || 0
  @log.debug("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:



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/sibit/btc.rb', line 127

def block(hash)
  data = Sibit::Json.new(http: @http, log: @log).get(
    Iri.new('https://chain.api.btc.com/v3/block').append(hash)
  )['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.



79
80
81
# File 'lib/sibit/btc.rb', line 79

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

#height(hash) ⇒ Object

The height of the block.

Raises:



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

def height(hash)
  data = Sibit::Json.new(http: @http, log: @log).get(
    Iri.new('https://chain.api.btc.com/v3/block').append(hash)
  )['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.debug("The height of #{hash} is #{h}")
  h
end

#latestObject

Gets the hash of the latest block.

Raises:



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

def latest
  data = Sibit::Json.new(http: @http, log: @log).get(Iri.new('https://chain.api.btc.com/v3/block/latest'))['data']
  raise(Sibit::Error, 'The latest block not found') if data.nil?
  hash = data['hash']
  @log.debug("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:



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

def next_of(hash)
  data = Sibit::Json.new(http: @http, log: @log).get(
    Iri.new('https://chain.api.btc.com/v3/block').append(hash)
  )['data']
  raise(Sibit::Error, "The block #{hash} not found") if data.nil?
  nxt = data['next_block_hash']
  nxt = nil if nxt == '0000000000000000000000000000000000000000000000000000000000000000'
  @log.debug("In BTC.com the block #{hash} is the latest, there is no next block") if nxt.nil?
  @log.debug("The next block of #{hash} is #{nxt}") unless nxt.nil?
  nxt
end

#price(_currency = 'USD') ⇒ Object

Current price of BTC in USD (float returned).



30
31
32
# File 'lib/sibit/btc.rb', line 30

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.



122
123
124
# File 'lib/sibit/btc.rb', line 122

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

#utxos(sources) ⇒ Object

Fetch all unspent outputs per address.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/sibit/btc.rb', line 93

def utxos(sources)
  results = []
  sources.each do |hash|
    data = Sibit::Json.new(http: @http, log: @log).get(
      Iri.new('https://chain.api.btc.com/v3/address').append(hash).append('unspent')
    )['data']
    raise(Sibit::Error, "The address #{hash} not found") if data.nil?
    list = data['list']
    next if list.nil?
    list.each do |u|
      index = u['tx_output_n']
      raise(Sibit::Error, "The unspent output of #{hash} has no tx_output_n") if index.nil?
      out = 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'][index]
      raise(Sibit::Error, "The output #{index} of #{u['tx_hash']} is absent") if out.nil?
      results << {
        value: u['value'],
        hash: u['tx_hash'],
        index: index,
        confirmations: u['confirmations'],
        script: [out['script_hex']].pack('H*')
      }
    end
  end
  results
end