Class: Pochette::Backends::BlockchainInfo

Inherits:
Object
  • Object
show all
Defined in:
lib/pochette/backends/blockchain_info.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key = nil) ⇒ BlockchainInfo

Returns a new instance of BlockchainInfo.



10
11
12
# File 'lib/pochette/backends/blockchain_info.rb', line 10

def initialize(key = nil)
  self.api_key = key
end

Instance Attribute Details

#api_keyObject

Returns the value of attribute api_key.



8
9
10
# File 'lib/pochette/backends/blockchain_info.rb', line 8

def api_key
  @api_key
end

Instance Method Details

#balances_for(addresses, confirmations) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/pochette/backends/blockchain_info.rb', line 22

def balances_for(addresses, confirmations)
  json = get_json("multiaddr", {active: addresses.join('|'), format: 'json'})
  result = {}
  json['addresses'].collect do |a|
    address = a['address']
    sent = get_json("q/getsentbyaddress/#{address}",
      {confirmations: confirmations, format: 'json'})
    received = get_json("q/getreceivedbyaddress/#{address}",
      {confirmations: confirmations, format: 'json'})
    result[address] = [
      sat(received), sat(sent), sat(received - sent),
      sat(a['total_received']), sat(a['total_sent']), sat(a['final_balance'])]
  end
  result
end

#block_heightObject



84
85
86
# File 'lib/pochette/backends/blockchain_info.rb', line 84

def block_height
  get_json("latestblock", {format: 'json'})['height'].to_i
end

#get_json(path, params = {}) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/pochette/backends/blockchain_info.rb', line 97

def get_json(path, params={})
  params['api_code'] = api_key if api_key
  query = params.empty? ? '' : "?#{params.to_query}"
  retries = 30
  begin
    raw_response = open("https://blockchain.info/#{path}#{query}").read
    sleep cooldown
    Oj.load(raw_response)
  rescue OpenURI::HTTPError => e
    raise if retries < 0 || e.message.to_i != 429
    retries -= 1
    sleep (cooldown * 5)
    retry
  end
end

#incoming_for(addresses, min_date) ⇒ Object



42
43
44
45
46
47
# File 'lib/pochette/backends/blockchain_info.rb', line 42

def incoming_for(addresses, min_date)
  return unless latest_block = block_height
  addresses.in_groups_of(50, false).collect do |group|
    incoming_for_helper(group, latest_block)
  end.flatten(1)
end

#incoming_for_helper(addresses, latest_block) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/pochette/backends/blockchain_info.rb', line 49

def incoming_for_helper(addresses, latest_block)
  json = get_json("multiaddr", {active: addresses.join('|'), format: 'json'})

  json['txs'].collect do |transaction|
    transaction['out'].collect do |out|
      next unless addresses.include? out['addr']
      confirmations = latest_block - transaction['block_height'].to_i
      senders = transaction['inputs'].collect{ |i| i['prev_out']['addr'] }.join(',')
      [ out['value'].to_d, out['addr'], transaction['hash'], confirmations, out['n'], senders ]
    end.compact
  end.flatten(1)
end

#list_transactions(txids) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/pochette/backends/blockchain_info.rb', line 62

def list_transactions(txids)
  return nil if txids.empty?
  txids.collect do |txid|
    tx = get_json("rawtx/#{txid}", {format: 'json'})
    inputs = tx['inputs'].collect do |i|
      prevhash = get_json("rawtx/#{i['prev_out']['tx_index']}", {format: 'json'})['hash']
      { prev_hash: prevhash,
        prev_index: i['prev_out']['n'],
        sequence: i['sequence'],
        script_sig: i['script']
      }
    end

    outputs = tx['out'].collect do |o|
      { amount: o['value'].to_i, script_pubkey: o['script'] }
    end

    { hash: tx['hash'], version: tx['ver'], lock_time: tx['lock_time'],
      inputs: inputs, bin_outputs: outputs}
  end
end

#list_unspent(addresses) ⇒ Object



14
15
16
17
18
19
20
# File 'lib/pochette/backends/blockchain_info.rb', line 14

def list_unspent(addresses)
  json = get_json("unspent", {active: addresses.join('|'), format: 'json'})
  json['unspent_outputs'].collect do |utxo|
    address = Bitcoin::Script.new(utxo['script'].htb).get_address
    [address, utxo['tx_hash_big_endian'], utxo['tx_output_n'].to_i, utxo['value'], utxo['script']]
  end
end

#pushtx(hex) ⇒ Object

Raises:

  • (StandardError)


88
89
90
91
92
93
94
95
# File 'lib/pochette/backends/blockchain_info.rb', line 88

def pushtx(hex)
  uri = URI.parse("https://blockchain.info/pushtx")
  params = { "tx" => hex }
  params['api_code'] = api_key if api_key
  response = Net::HTTP.post_form(uri, params)
  raise StandardError.new(response) if response.code.to_i != 200
  Bitcoin::Protocol::Tx.new(hex.htb).hash
end

#sat(x) ⇒ Object



38
39
40
# File 'lib/pochette/backends/blockchain_info.rb', line 38

def sat(x)
  x.to_d / 1_0000_0000
end