vaultoro 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +4 -0
- data/LICENSE.md +20 -0
- data/README.md +583 -0
- data/lib/vaultoro.rb +57 -0
- data/lib/vaultoro/base.rb +32 -0
- data/lib/vaultoro/basic_api/bid_ask.rb +38 -0
- data/lib/vaultoro/basic_api/buy_orders.rb +37 -0
- data/lib/vaultoro/basic_api/client.rb +47 -0
- data/lib/vaultoro/basic_api/latest_price.rb +25 -0
- data/lib/vaultoro/basic_api/latest_trades.rb +44 -0
- data/lib/vaultoro/basic_api/market_data.rb +56 -0
- data/lib/vaultoro/basic_api/order.rb +10 -0
- data/lib/vaultoro/basic_api/order_book.rb +46 -0
- data/lib/vaultoro/basic_api/price_volume.rb +11 -0
- data/lib/vaultoro/basic_api/sell_orders.rb +37 -0
- data/lib/vaultoro/basic_api/trade.rb +12 -0
- data/lib/vaultoro/basic_api/transaction.rb +11 -0
- data/lib/vaultoro/basic_api/transactions.rb +45 -0
- data/lib/vaultoro/configuration.rb +72 -0
- data/lib/vaultoro/trading_api/balance.rb +11 -0
- data/lib/vaultoro/trading_api/balances.rb +39 -0
- data/lib/vaultoro/trading_api/buy.rb +51 -0
- data/lib/vaultoro/trading_api/cancel.rb +33 -0
- data/lib/vaultoro/trading_api/client.rb +59 -0
- data/lib/vaultoro/trading_api/order.rb +13 -0
- data/lib/vaultoro/trading_api/orders.rb +53 -0
- data/lib/vaultoro/trading_api/sell.rb +48 -0
- data/lib/vaultoro/trading_api/trade.rb +16 -0
- data/lib/vaultoro/trading_api/trades.rb +65 -0
- data/lib/vaultoro/trading_api/withdraw.rb +36 -0
- data/lib/vaultoro/version.rb +11 -0
- metadata +105 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
module Vaultoro
|
2
|
+
module BasicAPI
|
3
|
+
class Transactions < Base
|
4
|
+
attribute :time, String # Allowed values: "hour", "day", "month"
|
5
|
+
attribute :list, Array[Transaction]
|
6
|
+
|
7
|
+
def fetch
|
8
|
+
@errors.clear
|
9
|
+
|
10
|
+
ensure_attribute_has_value :time
|
11
|
+
|
12
|
+
@errors << ":time argument must be either 'hour', 'day' or 'month'" unless ["hour", "day", "month"].include?(@time)
|
13
|
+
|
14
|
+
return false if @errors.any?
|
15
|
+
|
16
|
+
response = Client.get("/transactions/#{@time}", {})
|
17
|
+
code = response.code rescue ""
|
18
|
+
|
19
|
+
case code
|
20
|
+
when '200'
|
21
|
+
hash = JSON.parse(response.body)
|
22
|
+
@status = hash['status'].upcase
|
23
|
+
|
24
|
+
if @status == 'SUCCESS'
|
25
|
+
hash['data'].each do |transaction|
|
26
|
+
@list << Transaction.new(
|
27
|
+
time: DateTime.strptime(transaction['Time'], '%Y-%m-%dT%H:%M:%S.%L%z').to_time.utc,
|
28
|
+
gold_price: transaction['Gold_Price'].to_f,
|
29
|
+
gold_amount: transaction['Gold_Amount'].to_f
|
30
|
+
)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
set_errors(response)
|
34
|
+
return false
|
35
|
+
end
|
36
|
+
|
37
|
+
return true
|
38
|
+
else
|
39
|
+
set_errors(response)
|
40
|
+
return false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Vaultoro
|
2
|
+
class Configuration
|
3
|
+
attr_writer :credentials
|
4
|
+
|
5
|
+
def api_key
|
6
|
+
Vaultoro.credentials[Vaultoro.environment][:api_key]
|
7
|
+
end
|
8
|
+
|
9
|
+
def api_key=(value)
|
10
|
+
Vaultoro.credentials[Vaultoro.environment][:api_key] = value
|
11
|
+
end
|
12
|
+
|
13
|
+
def api_secret
|
14
|
+
Vaultoro.credentials[Vaultoro.environment][:api_secret]
|
15
|
+
end
|
16
|
+
|
17
|
+
def api_secret=(value)
|
18
|
+
Vaultoro.credentials[Vaultoro.environment][:api_secret] = value
|
19
|
+
end
|
20
|
+
|
21
|
+
def api_uri
|
22
|
+
Vaultoro.credentials[Vaultoro.environment][:api_uri]
|
23
|
+
end
|
24
|
+
|
25
|
+
def api_uri=(value)
|
26
|
+
Vaultoro.credentials[Vaultoro.environment][:api_uri] = value
|
27
|
+
end
|
28
|
+
|
29
|
+
def api_version
|
30
|
+
Vaultoro.credentials[Vaultoro.environment][:api_version]
|
31
|
+
end
|
32
|
+
|
33
|
+
def api_version=(value)
|
34
|
+
Vaultoro.credentials[Vaultoro.environment][:api_version] = value
|
35
|
+
end
|
36
|
+
|
37
|
+
def credentials
|
38
|
+
@credentials ||= {
|
39
|
+
:production => {
|
40
|
+
:api_key => ENV['VAULTORO_API_KEY'],
|
41
|
+
:api_secret => ENV['VAULTORO_API_SECRET'],
|
42
|
+
:api_uri => "https://api.vaultoro.com",
|
43
|
+
:api_version => 1
|
44
|
+
},
|
45
|
+
:test => {
|
46
|
+
:api_key => "testapi",
|
47
|
+
:api_secret => "testpass",
|
48
|
+
:api_uri => "https://api.vaultoro.com",
|
49
|
+
:api_version => 1
|
50
|
+
},
|
51
|
+
:development => {
|
52
|
+
:api_key => "testapi",
|
53
|
+
:api_secret => "testpass",
|
54
|
+
:api_uri => "https://api.vaultoro.com",
|
55
|
+
:api_version => 1
|
56
|
+
}
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def environment
|
61
|
+
@environment ||= :production
|
62
|
+
end
|
63
|
+
|
64
|
+
def environment=(value)
|
65
|
+
@environment = value.is_a?(String) ? value.to_sym : value
|
66
|
+
end
|
67
|
+
|
68
|
+
def environments
|
69
|
+
Vaultoro.credentials.keys
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Vaultoro
|
2
|
+
module TradingAPI
|
3
|
+
class Balances < Base
|
4
|
+
attribute :list, Array[Balance]
|
5
|
+
|
6
|
+
def fetch
|
7
|
+
@errors.clear
|
8
|
+
|
9
|
+
response = Client.get("/balance", {})
|
10
|
+
code = response.code rescue ""
|
11
|
+
|
12
|
+
case code
|
13
|
+
when '200'
|
14
|
+
hash = JSON.parse(response.body)
|
15
|
+
|
16
|
+
@status = hash['status'].upcase
|
17
|
+
|
18
|
+
if @status == 'SUCCESS'
|
19
|
+
hash['data'].each do |balance|
|
20
|
+
@list << Balance.new(
|
21
|
+
:currency => balance['currency_code'],
|
22
|
+
:cash => balance['cash'].to_f,
|
23
|
+
:reserved => balance['reserved'].to_f
|
24
|
+
)
|
25
|
+
end
|
26
|
+
else
|
27
|
+
set_errors(response)
|
28
|
+
return false
|
29
|
+
end
|
30
|
+
|
31
|
+
return true
|
32
|
+
else
|
33
|
+
set_errors(response)
|
34
|
+
return false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Vaultoro
|
2
|
+
module TradingAPI
|
3
|
+
class Buy < Base
|
4
|
+
attribute :symbol, String, default: "gld" # Allowed value: "gld"
|
5
|
+
attribute :type, String, default: "market" # Allowed values: "limit", "market"
|
6
|
+
attribute :bitcoin, Float # Size range: 0.0002-100000 (expressed in bitcoin)
|
7
|
+
attribute :gold, Float # Size range: 0.001-100000 (expressed in grams)
|
8
|
+
attribute :price, Float # Size range: 0.00002-100000 (expressed in bitcoin, ignored for market orders)
|
9
|
+
attribute :order_id, String
|
10
|
+
attribute :order_time, Time # UTC
|
11
|
+
|
12
|
+
def execute!
|
13
|
+
ensure_attribute_has_value :symbol, :type
|
14
|
+
|
15
|
+
@errors << ":bitcoin or :gold argument is required" unless @bitcoin || @gold
|
16
|
+
@errors << ":symbol argument must be 'gold'" unless @symbol == 'gold'
|
17
|
+
@errors << ":type argument must be 'limit' or 'market'" unless ['limit', 'market'].include?(@type)
|
18
|
+
|
19
|
+
return false if @errors.any?
|
20
|
+
|
21
|
+
params = {}
|
22
|
+
params.merge!(btc: @bitcoin) if @bitcoin
|
23
|
+
params.merge!(gld: @gold) if @gold
|
24
|
+
params.merge!(price: @price) if @price && @type == 'market'
|
25
|
+
|
26
|
+
response = Client.post("/buy/#{@symbol}/#{@type}", params)
|
27
|
+
code = response.code rescue ""
|
28
|
+
|
29
|
+
case code
|
30
|
+
when '200'
|
31
|
+
hash = JSON.parse(response.body)
|
32
|
+
|
33
|
+
@status = hash['status'].upcase
|
34
|
+
|
35
|
+
if @status == 'SUCCESS'
|
36
|
+
@order_id = hash['data']['Order_ID']
|
37
|
+
@order_time = DateTime.strptime(hash['data']['time'], '%Y-%m-%dT%H:%M:%S.%L%z').to_time.utc
|
38
|
+
else
|
39
|
+
set_errors(response)
|
40
|
+
return false
|
41
|
+
end
|
42
|
+
|
43
|
+
return true
|
44
|
+
else
|
45
|
+
set_errors(response)
|
46
|
+
return false
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Vaultoro
|
2
|
+
module TradingAPI
|
3
|
+
class Cancel < Base
|
4
|
+
attribute :order_id, String
|
5
|
+
|
6
|
+
def execute!
|
7
|
+
ensure_attribute_has_value :order_id
|
8
|
+
return false if @errors.any?
|
9
|
+
|
10
|
+
response = Client.post("/cancel/#{@order_id}", {})
|
11
|
+
code = response.code rescue ""
|
12
|
+
|
13
|
+
case code
|
14
|
+
when '200'
|
15
|
+
hash = JSON.parse(response.body)
|
16
|
+
|
17
|
+
@status = hash['status'].upcase
|
18
|
+
@order_id = hash['data']['Order_ID']
|
19
|
+
|
20
|
+
unless @status == 'SUCCESS'
|
21
|
+
set_errors(response)
|
22
|
+
return false
|
23
|
+
end
|
24
|
+
|
25
|
+
return true
|
26
|
+
else
|
27
|
+
set_errors(response)
|
28
|
+
return false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'net/http'
|
3
|
+
require 'net/https'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Vaultoro
|
7
|
+
module TradingAPI
|
8
|
+
class Client
|
9
|
+
def self.get(endpoint, params = {})
|
10
|
+
begin
|
11
|
+
uri = URI.parse([Vaultoro.api_uri, "/#{Vaultoro.api_version.to_s}", endpoint].join)
|
12
|
+
params.merge!(nonce: nonce, apikey: Vaultoro.api_key)
|
13
|
+
uri.query = URI.encode_www_form(params)
|
14
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
15
|
+
http.use_ssl = uri.scheme == 'https'
|
16
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
17
|
+
headers.merge!("X-Signature" => signature)
|
18
|
+
request = Net::HTTP::Get.new(uri, headers)
|
19
|
+
response = http.request(request)
|
20
|
+
rescue StandardError => error
|
21
|
+
puts "Request failed (#{error.message})"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.post(endpoint, params = {})
|
26
|
+
begin
|
27
|
+
uri = URI.parse([Vaultoro.api_uri, endpoint].join)
|
28
|
+
params.merge!(nonce: nonce, apikey: Vaultoro.api_key)
|
29
|
+
uri.query = URI.encode_www_form(params)
|
30
|
+
# body = URI.encode_www_form(params)
|
31
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
32
|
+
http.use_ssl = uri.scheme == 'https'
|
33
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
34
|
+
headers.merge!("X-Signature" => signature)
|
35
|
+
request = Net::HTTP::Post.new(uri, headers)
|
36
|
+
request.add_field "Content-Type", "application/x-www-form-urlencoded"
|
37
|
+
# request.body = body
|
38
|
+
response = http.request(request)
|
39
|
+
rescue StandardError => error
|
40
|
+
puts "Request failed (#{error.message})"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def headers
|
47
|
+
{ 'User-Agent' => Vaultoro::VERSION::SUMMARY, 'Accept' => 'application/json' }
|
48
|
+
end
|
49
|
+
|
50
|
+
def signature(uri)
|
51
|
+
OpenSSL::HMAC.hexdigest('sha256', Vaultoro.api_secret, uri.to_s)
|
52
|
+
end
|
53
|
+
|
54
|
+
def nonce
|
55
|
+
Time.to_i
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Vaultoro
|
2
|
+
module TradingAPI
|
3
|
+
class Orders < Base
|
4
|
+
attribute :list, Array[Order]
|
5
|
+
|
6
|
+
def fetch
|
7
|
+
@errors.clear
|
8
|
+
|
9
|
+
response = Client.get("/orders", {})
|
10
|
+
code = response.code rescue ""
|
11
|
+
|
12
|
+
case code
|
13
|
+
when '200'
|
14
|
+
hash = JSON.parse(response.body)
|
15
|
+
|
16
|
+
@status = hash['status'].upcase
|
17
|
+
|
18
|
+
if @status == 'SUCCESS'
|
19
|
+
hash['data'].each do |orders|
|
20
|
+
orders['b'] do |buy|
|
21
|
+
@list << Order.new(
|
22
|
+
order_id: buy['Order_ID']
|
23
|
+
side: 'BUY',
|
24
|
+
bitcoin_amount: buy['BTC_Amount'].to_f,
|
25
|
+
gold_amount: buy['Gold_Amount'].to_f,
|
26
|
+
gold_price: buy['Gold_Price'].to_f
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
orders['s'] do |sell|
|
31
|
+
@list << Order.new(
|
32
|
+
order_id: buy['Order_ID']
|
33
|
+
side: 'SELL',
|
34
|
+
bitcoin_amount: buy['BTC_Amount'].to_f,
|
35
|
+
gold_amount: buy['Gold_Amount'].to_f,
|
36
|
+
gold_price: buy['Gold_Price'].to_f
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
else
|
41
|
+
set_errors(response)
|
42
|
+
return false
|
43
|
+
end
|
44
|
+
|
45
|
+
return true
|
46
|
+
else
|
47
|
+
set_errors(response)
|
48
|
+
return false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Vaultoro
|
2
|
+
module TradingAPI
|
3
|
+
class Sell < Base
|
4
|
+
attribute :symbol, String, default: "gld" # Allowed value: "gld"
|
5
|
+
attribute :type, String, default: "market" # Allowed values: "limit", "market"
|
6
|
+
attribute :gold, Float # Size range: 0.001-100000 (expressed in grams)
|
7
|
+
attribute :price, Float # Size range: 0.00002-100000 (expressed in bitcoin, ignored for market orders)
|
8
|
+
attribute :order_id, String
|
9
|
+
attribute :order_time, Time # UTC
|
10
|
+
|
11
|
+
def execute!
|
12
|
+
ensure_attribute_has_value :gld, :symbol, :type
|
13
|
+
|
14
|
+
@errors << ":symbol argument must be 'gld'" unless @symbol == 'gld'
|
15
|
+
@errors << ":type argument must be 'limit' or 'market'" unless ['limit', 'market'].include?(@type)
|
16
|
+
|
17
|
+
return false if @errors.any?
|
18
|
+
|
19
|
+
params = {}
|
20
|
+
params.merge!(gld: @gold) if @gold
|
21
|
+
params.merge!(price: @price) if @price && @type == 'market'
|
22
|
+
|
23
|
+
response = Client.post("/sell/#{@symbol}/#{@type}", params)
|
24
|
+
code = response.code rescue ""
|
25
|
+
|
26
|
+
case code
|
27
|
+
when '200'
|
28
|
+
hash = JSON.parse(response.body)
|
29
|
+
|
30
|
+
@status = hash['status'].upcase
|
31
|
+
|
32
|
+
if @status == 'SUCCESS'
|
33
|
+
@order_id = hash['data']['Order_ID']
|
34
|
+
@order_time = DateTime.strptime(hash['data']['time'], '%Y-%m-%dT%H:%M:%S.%L%z').to_time.utc
|
35
|
+
else
|
36
|
+
set_errors(response)
|
37
|
+
return false
|
38
|
+
end
|
39
|
+
|
40
|
+
return true
|
41
|
+
else
|
42
|
+
set_errors(response)
|
43
|
+
return false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|