cryptum 0.0.380 → 0.0.381

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,177 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rest-client'
4
+ require 'json'
5
+
6
+ module Cryptum
7
+ # This module is used to Interact with the APIs
8
+ module API
9
+ # Module specifically related to orders history retrieval.
10
+ module Rest
11
+ # Actually Make a REST API call
12
+ public_class_method def self.call(opts = {})
13
+ env = opts[:env]
14
+ option_choice = opts[:option_choice]
15
+ order_type = opts[:order_type]
16
+ event_notes = opts[:event_notes]
17
+ api_endpoint = opts[:api_endpoint]
18
+ base_increment = opts[:base_increment].to_f
19
+
20
+ api_key = env[:api_key]
21
+ api_secret = env[:api_secret]
22
+ api_passphrase = env[:api_passphrase]
23
+ api_endpoint = 'https://api.exchange.coinbase.com'
24
+ api_endpoint = 'https://api-public.sandbox.exchange.coinbase.com' if env[:env] == :sandbox
25
+ api_endpoint = opts[:api_endpoint] if opts[:api_endpoint]
26
+
27
+ http_method = if opts[:http_method].nil?
28
+ :GET
29
+ else
30
+ opts[:http_method].to_s.upcase.scrub.strip.chomp.to_sym
31
+ end
32
+ api_call = opts[:api_call].to_s.scrub
33
+ params = opts[:params]
34
+ http_body = opts[:http_body].to_s.scrub.strip.chomp
35
+
36
+ max_conn_attempts = 30
37
+ conn_attempt = 0
38
+
39
+ begin
40
+ conn_attempt += 1
41
+ if option_choice.proxy
42
+ rest_client = RestClient
43
+ rest_client.proxy = option_choice.proxy
44
+ rest_client_request = rest_client::Request
45
+ else
46
+ rest_client_request = RestClient::Request
47
+ end
48
+
49
+ api_signature_response = Cryptum::API::Signature.generate(
50
+ api_secret: api_secret,
51
+ http_method: http_method,
52
+ api_call: api_call,
53
+ params: params,
54
+ http_body: http_body
55
+ )
56
+ api_signature = api_signature_response[:api_signature]
57
+ api_timestamp = api_signature_response[:api_timestamp]
58
+
59
+ case http_method
60
+ when :GET
61
+ headers = {
62
+ content_type: 'application/json; charset=UTF-8',
63
+ CB_ACCESS_TIMESTAMP: api_timestamp,
64
+ CB_ACCESS_PASSPHRASE: api_passphrase,
65
+ CB_ACCESS_KEY: api_key,
66
+ CB_ACCESS_SIGN: api_signature
67
+ }
68
+
69
+ headers[:params] = params if params
70
+ headers[:ORDER_TYPE] = order_type if order_type
71
+ headers[:EVENT_NOTES] = event_notes if event_notes
72
+
73
+ response = rest_client_request.execute(
74
+ method: :GET,
75
+ url: "#{api_endpoint}#{api_call}",
76
+ headers: headers,
77
+ verify_ssl: false
78
+ )
79
+
80
+ when :DELETE
81
+ headers = {
82
+ content_type: 'application/json; charset=UTF-8',
83
+ CB_ACCESS_TIMESTAMP: api_timestamp,
84
+ CB_ACCESS_PASSPHRASE: api_passphrase,
85
+ CB_ACCESS_KEY: api_key,
86
+ CB_ACCESS_SIGN: api_signature
87
+ }
88
+
89
+ headers[:params] = params if params
90
+ headers[:ORDER_TYPE] = order_type if order_type
91
+ headers[:EVENT_NOTES] = event_notes if event_notes
92
+
93
+ response = rest_client_request.execute(
94
+ method: :DELETE,
95
+ url: "#{api_endpoint}#{api_call}",
96
+ headers: headers,
97
+ verify_ssl: false
98
+ )
99
+
100
+ when :POST
101
+ headers = {
102
+ content_type: 'application/json; charset=UTF-8',
103
+ CB_ACCESS_TIMESTAMP: api_timestamp,
104
+ CB_ACCESS_PASSPHRASE: api_passphrase,
105
+ CB_ACCESS_KEY: api_key,
106
+ CB_ACCESS_SIGN: api_signature
107
+ }
108
+
109
+ headers[:params] = params if params
110
+ headers[:ORDER_TYPE] = order_type if order_type
111
+ headers[:EVENT_NOTES] = event_notes if event_notes
112
+
113
+ response = rest_client_request.execute(
114
+ method: :POST,
115
+ url: "#{api_endpoint}#{api_call}",
116
+ headers: headers,
117
+ payload: http_body,
118
+ verify_ssl: false
119
+ )
120
+
121
+ else
122
+ raise @@logger.error("Unsupported HTTP Method #{http_method} for #{self} Plugin")
123
+ end
124
+
125
+ resp = JSON.parse(response, symbolize_names: true)
126
+ resp ||= []
127
+ rescue RestClient::Unauthorized => e
128
+ File.open('/tmp/cryptum-errors.txt', 'a') do |f|
129
+ f.puts Time.now.strftime('%Y-%m-%d %H:%M:%S.%N %z')
130
+ f.puts "#{self}\n#{e}\n\n\n"
131
+ end
132
+
133
+ raise e if conn_attempt > max_conn_attempts
134
+
135
+ sleep 60
136
+ retry
137
+ end
138
+ rescue RestClient::ExceptionWithResponse => e
139
+ File.open('/tmp/cryptum-errors.txt', 'a') do |f|
140
+ f.puts Time.now.strftime('%Y-%m-%d %H:%M:%S.%N %z')
141
+ f.puts "Module: #{self}"
142
+ f.puts "URL: #{api_endpoint}#{api_call}"
143
+ f.puts "PARAMS: #{params.inspect}"
144
+ f.puts "HTTP POST BODY: #{http_body.inspect}" if http_body != ''
145
+ f.puts "#{e}\n#{e.response}\n\n\n"
146
+ end
147
+
148
+ insufficient_funds = '{"message":"Insufficient funds"}'
149
+ size -= base_increment if e.response == insufficient_funds
150
+
151
+ sleep 0.3
152
+ retry
153
+ rescue RestClient::TooManyRequests => e
154
+ File.open('/tmp/cryptum-errors.txt', 'a') do |f|
155
+ f.puts Time.now.strftime('%Y-%m-%d %H:%M:%S.%N %z')
156
+ f.puts "Module: #{self}"
157
+ f.puts "URL: #{api_endpoint}#{api_call}"
158
+ f.puts "PARAMS: #{params.inspect}"
159
+ f.puts "HTTP POST BODY: #{http_body.inspect}" if http_body != ''
160
+ f.puts "#{e}\n#{e.response}\n\n\n"
161
+ end
162
+
163
+ sleep 1
164
+ retry
165
+ end
166
+
167
+ # Display Usage for this Module
168
+ public_class_method def self.help
169
+ puts "USAGE:
170
+ rest_response = #{self}.call(
171
+ env: 'required - Coinbase::Option::Environment.get Object'
172
+ )
173
+ "
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'addressable'
4
+ require 'base64'
5
+ require 'openssl'
6
+
7
+ module Cryptum
8
+ # This module is used to Interact with the APIs
9
+ module API
10
+ # Module specifically related to orders history retrieval.
11
+ module Signature
12
+ # Obtain latest order history
13
+ public_class_method def self.generate(opts = {})
14
+ api_secret = opts[:api_secret]
15
+
16
+ http_method = if opts[:http_method].nil?
17
+ :GET
18
+ else
19
+ opts[:http_method].to_s.upcase.scrub.strip.chomp.to_sym
20
+ end
21
+
22
+ api_call = opts[:api_call].to_s.scrub.strip.chomp
23
+ api_call = '/users/self/verify' if opts[:api_call].nil?
24
+
25
+ if opts[:params].nil?
26
+ path = api_call
27
+ else
28
+ uri = Addressable::URI.new
29
+ uri.query_values = opts[:params]
30
+ params = uri.query
31
+ path = "#{api_call}?#{params}"
32
+ end
33
+
34
+ http_body = opts[:http_body].to_s.scrub.strip.chomp
35
+
36
+ api_timestamp = Time.now.utc.to_i.to_s
37
+
38
+ api_signature = Base64.strict_encode64(
39
+ OpenSSL::HMAC.digest(
40
+ 'sha256',
41
+ Base64.strict_decode64(api_secret),
42
+ "#{api_timestamp}#{http_method}#{path}#{http_body}"
43
+ )
44
+ )
45
+
46
+ if http_body == ''
47
+ api_signature = Base64.strict_encode64(
48
+ OpenSSL::HMAC.digest(
49
+ 'sha256',
50
+ Base64.strict_decode64(api_secret),
51
+ "#{api_timestamp}#{http_method}#{path}"
52
+ )
53
+ )
54
+ end
55
+
56
+ api_signature_response = {}
57
+ api_signature_response[:api_timestamp] = api_timestamp
58
+ api_signature_response[:api_signature] = api_signature
59
+
60
+ api_signature_response
61
+ rescue StandardError => e
62
+ raise e
63
+ end
64
+
65
+ # Display Usage for this Module
66
+ public_class_method def self.help
67
+ puts "USAGE:
68
+ signature = #{self}.generate_signature(
69
+ api_secret: 'required - Coinbase Pro API Secret',
70
+ http_method: 'optional - Defaults to :GET',
71
+ api_call: 'optional - Defaults to /users/self/verify',
72
+ params: 'optional - HTTP GET Parameters',
73
+ http_body: 'optional HTTP POST Body'
74
+ )
75
+ "
76
+ end
77
+ end
78
+ end
79
+ end