kucoin-api 0.2.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.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +24 -0
  3. data/.rspec +2 -0
  4. data/.simplecov +7 -0
  5. data/.travis.yml +7 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +6 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +551 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/kucoin-api.gemspec +42 -0
  14. data/lib/kucoin/api.rb +34 -0
  15. data/lib/kucoin/api/endpoints.rb +117 -0
  16. data/lib/kucoin/api/endpoints/base.rb +58 -0
  17. data/lib/kucoin/api/endpoints/markets.rb +17 -0
  18. data/lib/kucoin/api/endpoints/markets/currencies.rb +24 -0
  19. data/lib/kucoin/api/endpoints/markets/histories.rb +18 -0
  20. data/lib/kucoin/api/endpoints/markets/order_book.rb +30 -0
  21. data/lib/kucoin/api/endpoints/markets/symbols.rb +15 -0
  22. data/lib/kucoin/api/endpoints/markets/tickers.rb +19 -0
  23. data/lib/kucoin/api/endpoints/other.rb +12 -0
  24. data/lib/kucoin/api/endpoints/trade.rb +8 -0
  25. data/lib/kucoin/api/endpoints/trade/fills.rb +20 -0
  26. data/lib/kucoin/api/endpoints/trade/orders.rb +44 -0
  27. data/lib/kucoin/api/endpoints/user.rb +8 -0
  28. data/lib/kucoin/api/endpoints/user/accounts.rb +40 -0
  29. data/lib/kucoin/api/endpoints/user/deposits.rb +26 -0
  30. data/lib/kucoin/api/endpoints/user/withdrawals.rb +30 -0
  31. data/lib/kucoin/api/endpoints/websocket.rb +27 -0
  32. data/lib/kucoin/api/error.rb +11 -0
  33. data/lib/kucoin/api/middleware/auth_request.rb +45 -0
  34. data/lib/kucoin/api/middleware/nonce_request.rb +13 -0
  35. data/lib/kucoin/api/rest.rb +46 -0
  36. data/lib/kucoin/api/rest/connection.rb +50 -0
  37. data/lib/kucoin/api/version.rb +5 -0
  38. data/lib/kucoin/api/websocket.rb +150 -0
  39. data/log/.keep +0 -0
  40. metadata +193 -0
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "kucoin/api"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,42 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "kucoin/api/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "kucoin-api"
8
+ spec.version = Kucoin::Api::VERSION
9
+ spec.authors = ["Michael Lang"]
10
+ spec.email = ["mwlang@cybrains.net"]
11
+
12
+ spec.summary = "Implements Kucoin 2.0 API and Websocket"
13
+ spec.description = spec.summary
14
+ spec.homepage = "https://github.com/mwlang/kucoin-api"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ # if spec.respond_to?(:metadata)
20
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
21
+ # else
22
+ # raise "RubyGems 2.0 or newer is required to protect against " \
23
+ # "public gem pushes."
24
+ # end
25
+
26
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
27
+ f.match(%r{^(test|spec|features)/})
28
+ end
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+
33
+ spec.add_runtime_dependency 'faraday', '~> 0.15'
34
+ spec.add_runtime_dependency 'faraday_middleware', '~> 0.12'
35
+ spec.add_runtime_dependency 'faye-websocket', '~> 0.10'
36
+
37
+ spec.add_development_dependency 'bundler', '~> 1.17'
38
+ spec.add_development_dependency 'rake', '~> 10.0'
39
+ spec.add_development_dependency 'rspec', '~> 3.0'
40
+ spec.add_development_dependency 'webmock', '~> 3.5'
41
+ spec.add_development_dependency 'simplecov'
42
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+ require 'json'
3
+ require 'faraday'
4
+ require 'faraday_middleware'
5
+ require 'faye/websocket'
6
+
7
+ require 'kucoin/api/version'
8
+ require 'kucoin/api/error'
9
+
10
+ require 'kucoin/api/middleware/auth_request'
11
+ require 'kucoin/api/middleware/nonce_request'
12
+
13
+ require 'kucoin/api/websocket'
14
+
15
+ require 'kucoin/api/endpoints'
16
+
17
+ require 'kucoin/api/rest'
18
+ require 'kucoin/api/rest/connection'
19
+
20
+ module Kucoin
21
+ module Api
22
+ def self.default_key
23
+ ENV['KUCOIN_API_KEY'].to_s
24
+ end
25
+
26
+ def self.default_secret
27
+ ENV['KUCOIN_API_SECRET'].to_s
28
+ end
29
+
30
+ def self.default_passphrase
31
+ ENV['KUCOIN_API_PASSPHRASE'].to_s
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir[File.expand_path('endpoints/*.rb', File.dirname(__FILE__))].each {|file| require file }
4
+ Dir[File.expand_path('endpoints/*/*.rb', File.dirname(__FILE__))].each {|file| require file }
5
+
6
+ module Kucoin
7
+ module Api
8
+ ENDPOINTS = {
9
+ user: {
10
+ accounts: {
11
+ index: '/api/v1/accounts',
12
+ inner_transfer: '/api/v1/accounts/inner-transfer',
13
+ # member
14
+ show: '/api/v1/accounts/:account_id',
15
+ ledgers: '/api/v1/accounts/:account_id/ledgers',
16
+ holds: '/api/v1/accounts/:account_id/holds',
17
+ },
18
+ deposits: {
19
+ create: '/api/v1/deposit-addresses',
20
+ index: '/api/v1/deposits',
21
+ # member
22
+ show: '/api/v1/deposit-addresses?currency=:currency',
23
+ },
24
+ withdrawals: {
25
+ index: '/api/v1/withdrawals',
26
+ quotas: '/api/v1/withdrawals/quotas',
27
+ # member
28
+ delete: '/api/v1/withdrawals/:withdrawal_id',
29
+ }
30
+ },
31
+ trade: {
32
+ orders: {
33
+ index: '/api/v1/orders',
34
+ recent: '/api/v1/limit/orders',
35
+ # member
36
+ show: '/api/v1/orders/:order_id',
37
+ },
38
+ fills: {
39
+ index: '/api/v1/fills',
40
+ recent: '/api/v1/limit/fills',
41
+ }
42
+ },
43
+ markets: {
44
+ index: '/api/v1/markets',
45
+ # member
46
+ stats: '/api/v1/market/stats?symbol=:symbol',
47
+ symbols: {
48
+ index: '/api/v1/symbols',
49
+ },
50
+ tickers: {
51
+ # member
52
+ index: '/api/v1/market/allTickers',
53
+ inside: '/api/v1/market/orderbook/level1?symbol=:symbol',
54
+ },
55
+ order_book: {
56
+ part_aggregated: '/api/v1/market/orderbook/level2_:depth?symbol=:symbol',
57
+ full_aggregated: '/api/v2/market/orderbook/level2?symbol=:symbol',
58
+ full_atomic: '/api/v1/market/orderbook/level3?symbol=:symbol',
59
+ },
60
+ histories: {
61
+ trade: '/api/v1/market/histories?symbol=:symbol',
62
+ klines: '/api/v1/market/candles?symbol=:symbol'
63
+ },
64
+ currencies: {
65
+ index: '/api/v1/currencies',
66
+ fiat: '/api/v1/prices',
67
+ # member
68
+ show: '/api/v1/currencies/:currency',
69
+ }
70
+ },
71
+ other: {
72
+ timestamp: '/api/v1/timestamp'
73
+ },
74
+
75
+ websocket: {
76
+ public: '/api/v1/bullet-public',
77
+ private: '/api/v1/bullet-private'
78
+ }
79
+ }
80
+
81
+ module Endpoints
82
+ def self.get_klass name, parent=nil
83
+ Object.const_get("#{parent || 'Kucoin::Api::Endpoints'}::#{name.to_s.split('_').map(&:capitalize).join}")
84
+ end
85
+
86
+ def self.endpoint_method client_klass, name, result, parent_var = nil
87
+ child_endpoint_klass = Endpoints.get_klass(name, (parent_var && parent_var.class))
88
+
89
+ if parent_var
90
+ parent_var.define_singleton_method name do
91
+ endpoint_var = "@#{name}"
92
+ var = instance_variable_get(endpoint_var) || instance_variable_set(endpoint_var, child_endpoint_klass.new(parent_var.client))
93
+ client_klass.generate_endpoint_methods result: result, parent_var: var
94
+ var
95
+ end
96
+ else
97
+ client_klass.class_exec do
98
+ define_method name do
99
+ endpoint_var = "@#{name}"
100
+ var = instance_variable_get(endpoint_var) || instance_variable_set(endpoint_var, child_endpoint_klass.new(self))
101
+ client_klass.generate_endpoint_methods result: result, parent_var: var
102
+ var
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ def generate_endpoint_methods result: ENDPOINTS, parent_var: nil
109
+ result.each do |endpoint_name, _result|
110
+ if _result.is_a?(Hash)
111
+ Kucoin::Api::Endpoints.endpoint_method(self, endpoint_name, _result, parent_var)
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+ module Kucoin
3
+ module Api
4
+ module Endpoints
5
+ class Base
6
+ attr_reader :client
7
+ def initialize client
8
+ @client = client
9
+ end
10
+
11
+ def open
12
+ client.open(self)
13
+ end
14
+
15
+ def auth
16
+ client.auth(self)
17
+ end
18
+
19
+ def path
20
+ self.class.name
21
+ .gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
22
+ .gsub(/([a-z\d])([A-Z])/,'\1_\2')
23
+ .tr('-', '_')
24
+ .downcase.split('::')[3..-1].join('::')
25
+ end
26
+
27
+ def url action
28
+ path_array = path.split('::').map(&:to_sym)
29
+ path_array.reduce(Kucoin::Api::ENDPOINTS) { |m, k| m.fetch(k, {}) }[action]
30
+ end
31
+
32
+ def assert_required_param options, param, valid_values=nil
33
+ raise Kucoin::Api::MissingParamError.new("#{param} is required") unless options.has_key?(param)
34
+ assert_param_is_one_of options, param, valid_values if valid_values
35
+ end
36
+
37
+ def assert_param_is_one_of options, param, valid_values
38
+ return if valid_values.include? options[param].to_s
39
+ raise Kucoin::Api::InvalidParamError.new("#{param} must be one of #{valid_values.inspect}")
40
+ end
41
+
42
+ private
43
+
44
+ def side_types
45
+ %w(buy sell)
46
+ end
47
+
48
+ def order_types
49
+ %w(limit market)
50
+ end
51
+
52
+ def account_types
53
+ %w(main trade)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ module Kucoin
3
+ module Api
4
+ module Endpoints
5
+ class Markets < Base
6
+ def index
7
+ open.ku_request :get, :index
8
+ end
9
+ alias all index
10
+
11
+ def stats symbol
12
+ open.ku_request :get, :stats, symbol: symbol
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+ module Kucoin
3
+ module Api
4
+ module Endpoints
5
+ class Markets
6
+ class Currencies < Markets
7
+ def index options={}
8
+ open.ku_request :get, :index, options
9
+ end
10
+ alias all index
11
+
12
+ def fiat options= {}
13
+ open.ku_request :get, :fiat, options
14
+ end
15
+
16
+ def show currency
17
+ open.ku_request :get, :show, currency: currency
18
+ end
19
+ alias detail show
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ module Kucoin
3
+ module Api
4
+ module Endpoints
5
+ class Markets
6
+ class Histories < Markets
7
+ def trade symbol
8
+ open.ku_request :get, :trade, symbol: symbol
9
+ end
10
+
11
+ def klines symbol, type, options={}
12
+ open.ku_request :get, :klines, symbol: symbol, type: type, **options
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+ module Kucoin
3
+ module Api
4
+ module Endpoints
5
+ class Markets
6
+ class OrderBook < Markets
7
+ def part symbol, depth
8
+ options = { symbol: symbol, depth: depth }
9
+ assert_required_param options, :depth, depth_types
10
+ open.ku_request :get, :part_aggregated, **options
11
+ end
12
+
13
+ def full_aggregated symbol
14
+ open.ku_request :get, :full_aggregated, symbol: symbol
15
+ end
16
+
17
+ def full_atomic symbol
18
+ open.ku_request :get, :full_atomic, symbol: symbol
19
+ end
20
+
21
+ private
22
+
23
+ def depth_types
24
+ %w(20 100)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+ module Kucoin
3
+ module Api
4
+ module Endpoints
5
+ class Markets
6
+ class Symbols < Markets
7
+ def index options={}
8
+ open.ku_request :get, :index, **options
9
+ end
10
+ alias all index
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ module Kucoin
3
+ module Api
4
+ module Endpoints
5
+ class Markets
6
+ class Tickers < Markets
7
+ def index
8
+ open.ku_request :get, :index
9
+ end
10
+ alias all index
11
+
12
+ def inside symbol
13
+ open.ku_request :get, :inside, symbol: symbol
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ module Kucoin
3
+ module Api
4
+ module Endpoints
5
+ class Other < Base
6
+ def timestamp
7
+ auth.ku_request :get, :timestamp
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ module Kucoin
3
+ module Api
4
+ module Endpoints
5
+ class Trade < Base; end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ module Kucoin
3
+ module Api
4
+ module Endpoints
5
+ class Trade
6
+ class Fills < Trade
7
+ def index options={}
8
+ auth.ku_request :get, :index, **options
9
+ end
10
+ alias all index
11
+ alias list index
12
+
13
+ def recent
14
+ auth.ku_request :get, :recent
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end