Class: Sibit::Blockchain

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

Overview

Blockchain.info API.

Instance Method Summary collapse

Constructor Details

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

Constructor.



44
45
46
47
48
# File 'lib/sibit/blockchain.rb', line 44

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.



87
88
89
90
91
92
93
94
95
# File 'lib/sibit/blockchain.rb', line 87

def balance(address)
  json = Sibit::Json.new(http: @http, log: @log).get(
    Iri.new('https://blockchain.info/rawaddr').append(address).add(limit: 0),
    accept: [200, 500]
  )
  b = json['final_balance']
  @log.info("The balance of #{address} is #{b} satoshi (#{json['n_tx']} txns)")
  b
end

#block(hash) ⇒ Object

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



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/sibit/blockchain.rb', line 147

def block(hash)
  json = Sibit::Json.new(http: @http, log: @log).get(
    Iri.new('https://blockchain.info/rawblock').append(hash)
  )
  {
    provider: self.class.name,
    hash: json['hash'],
    orphan: !json['main_chain'],
    next: json['next_block'][0],
    previous: json['prev_block'],
    txns: json['tx'].map do |t|
      {
        hash: t['hash'],
        outputs: t['out'].map do |o|
          {
            address: o['addr'],
            value: o['value']
          }
        end
      }
    end
  }
end

#feesObject

Get recommended fees.



98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/sibit/blockchain.rb', line 98

def fees
  json = Sibit::Json.new(http: @http, log: @log).get(
    Iri.new('https://api.blockchain.info/mempool/fees')
  )
  @log.info("Current recommended Bitcoin fees: \
  #{json['regular']}/#{json['priority']}/#{json['limits']['max']} sat/byte")
  {
    S: json['regular'] / 3,
    M: json['regular'],
    L: json['priority'],
    XL: json['limits']['max']
  }
end

#height(hash) ⇒ Object

The height of the block.



77
78
79
80
81
82
83
84
# File 'lib/sibit/blockchain.rb', line 77

def height(hash)
  json = Sibit::Json.new(http: @http, log: @log).get(
    Iri.new('https://blockchain.info/rawblock').append(hash)
  )
  h = json['height']
  @log.info("The height of #{hash} is #{h}")
  h
end

#latestObject

Gets the hash of the latest block.



138
139
140
141
142
143
144
# File 'lib/sibit/blockchain.rb', line 138

def latest
  hash = Sibit::Json.new(http: @http, log: @log).get(
    Iri.new('https://blockchain.info/latestblock')
  )['hash']
  @log.info("The latest block hash is #{hash}")
  hash
end

#next_of(_hash) ⇒ Object

Get hash of the block after this one.



62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/sibit/blockchain.rb', line 62

def next_of(_hash)
  raise Sibit::NotSupportedError, 'next_of() in Blockchain API is broken, always returns NULL'
  # json = Sibit::Json.new(http: @http, log: @log).get(
  #   Iri.new('https://blockchain.info/rawblock').append(hash)
  # )
  # nxt = json['next_block'][0]
  # if nxt.nil?
  #   @log.info("There is no block after #{hash}")
  # else
  #   @log.info("The next block of #{hash} is #{nxt}")
  # end
  # nxt
end

#price(currency = 'USD') ⇒ Object

Current price of BTC in USD (float returned).

Raises:



51
52
53
54
55
56
57
58
59
# File 'lib/sibit/blockchain.rb', line 51

def price(currency = 'USD')
  h = Sibit::Json.new(http: @http, log: @log).get(
    Iri.new('https://blockchain.info/ticker')
  )[currency]
  raise Error, "Unrecognized currency #{currency}" if h.nil?
  price = h['15m']
  @log.info("The price of BTC is #{price} USD")
  price
end

#push(hex) ⇒ Object

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



129
130
131
132
133
134
135
# File 'lib/sibit/blockchain.rb', line 129

def push(hex)
  return if @dry
  Sibit::Json.new(http: @http, log: @log).post(
    Iri.new('https://blockchain.info/pushtx'),
    hex
  )
end

#utxos(sources) ⇒ Object

Fetch all unspent outputs per address. The argument is an array of Bitcoin addresses.



114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/sibit/blockchain.rb', line 114

def utxos(sources)
  Sibit::Json.new(http: @http, log: @log).get(
    Iri.new('https://blockchain.info/unspent').add(active: sources.join('|'), limit: 1000)
  )['unspent_outputs'].map do |u|
    {
      value: u['value'],
      hash: u['tx_hash_big_endian'],
      index: u['tx_output_n'],
      confirmations: u['confirmations'],
      script: [u['script']].pack('H*')
    }
  end
end