module CiBlockIo
Constants
- VERSION
Public Class Methods
method_missing(m, *args, &block)
click to toggle source
# 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)
click to toggle source
# 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 = {})
click to toggle source
# 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')
click to toggle source
# 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')
click to toggle source
# 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
Private Class Methods
api_call(endpoint)
click to toggle source
# File lib/ci_block_io.rb, line 141 def self.api_call(endpoint) return @mock_response[endpoint[0]] if @mock_response.keys.include?(endpoint[0]) body = nil base_url = @base_url.gsub('API_CALL',endpoint[0]).gsub('VERSION', 'v'+@version.to_s) return nil if base_url.nil? || @api_key.nil? response = @client.post(base_url + @api_key, endpoint[1]) body = Oj.load(response.body) if endpoint[0] == 'withdraw' raise CiBlockIoWithdrawException.new(body['data']['error_message']) if !body['status'].eql?('success') else raise CiBlockIoNetworkException.new(body['data']['error_message']) if !body['status'].eql?('success') end body end
get_params(args = {})
click to toggle source
# File lib/ci_block_io.rb, line 161 def self.get_params(args = {}) # construct the parameter string params = "" args = {} if args.nil? args.each do |k,v| params += '&' if params.length > 0 params += "#{k.to_s}=#{v.to_s}" end return params end