Module: CiBlockIo

Defined in:
lib/ci_block_io.rb,
lib/ci_block_io/version.rb

Defined Under Namespace

Modules: Helper Classes: Key

Constant Summary collapse

VERSION =
"1.7.7"

Class Method Summary collapse

Class Method Details

.method_missing(m, *args, &block) ⇒ Object


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/ci_block_io.rb', line 49

def self.method_missing(m, *args, &block)      

  method_name = m.to_s

  if ['withdraw', 'withdraw_from_address', 'withdraw_from_addresses', 'withdraw_from_user', 'withdraw_from_users', 'withdraw_from_label', 'withdraw_from_labels'].include?(m.to_s) then
    # need to withdraw from an address
    self.withdraw(args.first, m.to_s)
  elsif ['sweep_from_address'].include?(m.to_s) then
    # need to sweep from an address
    self.sweep(args.first, m.to_s)
  else
    params = get_params(args.first)
    self.api_call([method_name, params])
  end

end

.mock(method_name, response) ⇒ Object


28
29
30
# File 'lib/ci_block_io.rb', line 28

def self.mock(method_name, response)
  @mock_response[method_name.to_s] = response
end

.set_options(args = {}) ⇒ Object


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/ci_block_io.rb', line 32

def self.set_options(args = {})
  # initialize BlockIo
  @api_key = args[:api_key]
  @pin = args[:pin]

  @encryptionKey = Helper.pinToAesKey(@pin) if !@pin.nil?

  hostname = args[:hostname] || "block.io"
  @base_url = "https://" << hostname << "/api/VERSION/API_CALL/?api_key="

  @client = HTTPClient.new
  @client.tcp_keepalive = true
  @client.ssl_config.ssl_version = :auto

  @version = args[:version] || 2 # default version is 2
end

.sweep(args = {}, method_name = 'sweep_from_address') ⇒ Object

Raises:

  • (Exception)

105
106
107
108
109
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
136
# File 'lib/ci_block_io.rb', line 105

def self.sweep(args = {}, method_name = 'sweep_from_address')
  # sweep coins from a given address + key

  raise Exception.new("No private_key provided.") unless args.has_key?(:private_key)

  key = Key.from_wif(args[:private_key])

  args[:public_key] = key.public_key # so Block.io can match things up
  args.delete(:private_key) # the key must never leave this machine

  params = get_params(args)

  response = self.api_call([method_name, params])

  if response['data'].has_key?('reference_id') then
    # Block.io's asking us to provide some client-side signatures, let's get to it

    # let's sign all the inputs we can
    inputs = response['data']['inputs']
    Helper.signData(inputs, [key])

    # the response object is now signed, let's stringify it and finalize this withdrawal
    response = self.api_call(['sign_and_finalize_sweep',{:signature_data => Oj.dump(response['data'])}])

    # if we provided all the required signatures, this transaction went through
    # otherwise Block.io responded with data asking for more signatures
    # the latter will be the case for dTrust addresses
  end

  return response

end

.withdraw(args = {}, method_name = 'withdraw') ⇒ Object


66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/ci_block_io.rb', line 66

def self.withdraw(args = {}, method_name = 'withdraw')
  # validate arguments for withdrawal of funds TODO

  raise CiBlockIoWithdrawException.new("PIN not set. Use BlockIo.set_options(:api_key=>'API KEY',:pin=>'SECRET PIN',:version=>'API VERSION')") if @pin.nil?

  params = get_params(args)

  params << "&pin=" << @pin if @version == 1 # Block.io handles the Secret PIN in the legacy API (v1)

  response = self.api_call([method_name, params])

  if response['data'].has_key?('reference_id') then
    # Block.io's asking us to provide some client-side signatures, let's get to it

    # extract the passphrase
    encrypted_passphrase = response['data']['encrypted_passphrase']['passphrase']

    # let's get our private key
    key = Helper.extractKey(encrypted_passphrase, @encryptionKey)

    raise CiBlockIoWithdrawException.new('Public key mismatch for requested signer and ourselves. Invalid Secret PIN detected.') if key.public_key != response['data']['encrypted_passphrase']['signer_public_key']

    # let's sign all the inputs we can
    inputs = response['data']['inputs']

    Helper.signData(inputs, [key])

    # the response object is now signed, let's stringify it and finalize this withdrawal
    response = self.api_call(['sign_and_finalize_withdrawal',{:signature_data => Oj.dump(response['data'])}])

    # if we provided all the required signatures, this transaction went through
    # otherwise Block.io responded with data asking for more signatures
    # the latter will be the case for dTrust addresses
  end

  return response

end