wanglu_client 0.0.8

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 47f4874beebb55803c2984ced904db0a247e9fb3
4
+ data.tar.gz: d833a41c5343dda1fcc453b4fa6384f4a00ec952
5
+ SHA512:
6
+ metadata.gz: 4b203549fc229f2c67828c4db80c78a426b01088949b6f4b5dd50beeeadb1ffad3db01d78e6543af4d487ccfb098eb995df6f26fb8966354f11f44272d7b64a7
7
+ data.tar.gz: a0b407f4392e1153d354907fab68ffb7be100a91c5b169bed89ee5e435990ed4d773eff3f77ef2deb4de1915ce26545fa4245bb8128b64724023f8371035d455
data/README.markdown ADDED
@@ -0,0 +1,76 @@
1
+ Ruby client for Wanglu API
2
+ ==========================
3
+
4
+ [![Build Status](https://travis-ci.org/wanglu/wanglu-client-ruby.png?branch=master)](https://travis-ci.org/wanglu/wanglu-client-ruby)
5
+
6
+ `wanglu-client-ruby` is a client for Wanglu API, support all Wanglu API functions like submit order, get tickers, etc. It's also a reference client implementation, where you can find how to authenticate private Wanglu API.
7
+
8
+ ### Requirements ###
9
+
10
+ * ruby 2.0.0 or higher (if you want to run 'rake test' in this gem you'll need ruby 2.1.0 or higher)
11
+ * openssl
12
+
13
+ ### Install ###
14
+
15
+ gem install wanglu_client
16
+
17
+ ### Usage ###
18
+
19
+ #### Command line tool ####
20
+
21
+ TBD
22
+
23
+ #### REST API client ####
24
+
25
+ Use `#get` or `#post` to access API after you created a `WangluAPI::Client`:
26
+
27
+ ```ruby
28
+ require 'wanglu_client'
29
+
30
+ # Client can be initialized not providing key and sercet, but this client can only access public APIs
31
+ client_public = WangluAPI::Client.new endpoint: 'https://exchange.wanglutech.com'
32
+
33
+ # GET public api /api/v2/markets
34
+ client_public.get_public '/api/v2/markets'
35
+
36
+ # To build a full functional client which can access both public/private api, access_key/secret_key
37
+ # are required.
38
+ #
39
+ # `endpoint` can be ignored or set to any Wanglu powered exchange.
40
+ #
41
+ # If there's no data received in `timeout` seconds, Net::OpenTimeout will be raised. Default to 60.
42
+ #
43
+ client = WangluAPI::Client.new access_key: 'your_access_key', secret_key: 'your_secret_key', endpoint: 'https://exchange.wanglutech.com', timeout: 60
44
+
45
+ # GET private api /api/v2/orders with 'market=btccny'
46
+ client.get '/api/v2/orders', market: 'btccny'
47
+
48
+ # POST to create an order
49
+ client.post '/api/v2/orders', market: 'btccny', side: 'sell', volume: '0.11', price: '2955.0'
50
+
51
+ # POST to create multiple orders at once
52
+ client.post '/api/v2/orders/multi', market: 'btccny', orders: [{side: 'buy', volume: '0.15', price: '2955.0'}, {side: 'sell', volume: '0.16', price: '2956'}]
53
+ ```
54
+
55
+ Check [Wanglu API v2 Documents](https://exchange.wanglutech.com/documents/api_v2) for details on Wanglu API.
56
+
57
+ ### Streaming API client ###
58
+
59
+ Streaming API client is built upon eventmachine, it will start an endless loop to accept updates from server side, you only need to provide a callback block:
60
+
61
+ ```ruby
62
+ require 'wanglu_client'
63
+
64
+ client = WangluAPI::StreamingClient.new access_key: 'your_access_key', secret_key: 'your_secret_key', endpoint: 'wss://exchange.wanglutech.com:8080'
65
+ client.run do |message|
66
+ # do whatever you want with message
67
+ end
68
+ ```
69
+
70
+ ### License ###
71
+
72
+ `wanglu-client-ruby` is released under MIT license. See [http://wanglu.mit-license.org](http://wanglu.mit-license.org) for more information.
73
+
74
+ ### How To Contribute ###
75
+
76
+ Just create an issue or open a pull request :)
@@ -0,0 +1,36 @@
1
+ module WangluAPI
2
+ class Auth
3
+
4
+ def initialize(access_key, secret_key)
5
+ @access_key = access_key
6
+ @secret_key = secret_key
7
+ end
8
+
9
+ def signed_challenge(challenge)
10
+ signature = OpenSSL::HMAC.hexdigest 'SHA256', @secret_key, "#{@access_key}#{challenge}"
11
+ {auth: {access_key: @access_key, answer: signature}}
12
+ end
13
+
14
+ def signed_params(verb, path, params={})
15
+ params = format_params params
16
+ signature = sign verb, path, URI.unescape(params.to_query)
17
+ params.merge(signature: signature)
18
+ end
19
+
20
+ def sign(verb, path, params)
21
+ OpenSSL::HMAC.hexdigest 'SHA256', @secret_key, payload(verb, path, params)
22
+ end
23
+
24
+ def payload(verb, path, params)
25
+ "#{verb.upcase}|#{path}|#{params}"
26
+ end
27
+
28
+ def format_params(params)
29
+ params = params.symbolize_keys
30
+ params[:access_key] ||= @access_key
31
+ params[:tonce] ||= (Time.now.to_f*1000).to_i
32
+ params
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,80 @@
1
+ require 'json'
2
+ require 'net/http'
3
+ require_relative 'client/version'
4
+
5
+ module WangluAPI
6
+ class Client
7
+
8
+ attr :auth
9
+
10
+ def initialize(options={})
11
+ options = options.symbolize_keys
12
+ setup_auth_keys options
13
+ @endpoint = options[:endpoint] || 'https://exchange.wanglutech.com'
14
+ @timeout = options[:timeout] || 60
15
+ end
16
+
17
+ def get_public(path, params={})
18
+ uri = URI("#{@endpoint}#{path}")
19
+ uri.query = URI.encode_www_form params
20
+
21
+ request(:get, path, nil, params) do |http, _|
22
+ http.request_get(uri.request_uri)
23
+ end
24
+ end
25
+
26
+ def get(path, params={})
27
+ check_auth!
28
+
29
+ uri = URI("#{@endpoint}#{path}")
30
+
31
+ request(:get, path, @auth, params) do |http, signed_params|
32
+ uri.query = URI.encode_www_form signed_params
33
+ http.request_get(uri.request_uri)
34
+ end
35
+ end
36
+
37
+ def post(path, params={})
38
+ check_auth!
39
+
40
+ request(:post, path, @auth, params) do |http, signed_params|
41
+ http.request_post(path, signed_params.to_query)
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def request(action, path, auth, params={})
48
+ uri = URI("#{@endpoint}#{path}")
49
+ params = auth.signed_params action.to_s.upcase, path, params if auth
50
+
51
+ http = Net::HTTP.new(uri.hostname, uri.port)
52
+ http.open_timeout = @timeout
53
+ http.use_ssl = true if @endpoint.start_with?('https://')
54
+
55
+ http.start do |http|
56
+ parse yield(http, params)
57
+ end
58
+ end
59
+
60
+ def parse(response)
61
+ JSON.parse response.body
62
+ rescue JSON::ParserError
63
+ {http_error: {code: response.code, body: response.body}}
64
+ end
65
+
66
+ def setup_auth_keys(options)
67
+ if options[:access_key] && options[:secret_key]
68
+ @access_key = options[:access_key]
69
+ @secret_key = options[:secret_key]
70
+ @auth = Auth.new @access_key, @secret_key
71
+ else
72
+ #raise ArgumentError, 'Missing access key and/or secret key'
73
+ end
74
+ end
75
+
76
+ def check_auth!
77
+ raise ArgumentError, 'Missing access key and/or secret key' if @auth.nil?
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,5 @@
1
+ module WangluAPI
2
+ class Client
3
+ VERSION = '0.0.8'
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ module WangluAPI
2
+ class Config
3
+
4
+ def self.get_wanglurc(path)
5
+ if File.exist? path
6
+ lines = File.readlines path
7
+ [ lines[0].strip, lines[1].strip ]
8
+ end
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ require 'wanglu_api/core_ext/keys'
2
+ require 'wanglu_api/core_ext/to_query'
3
+
@@ -0,0 +1,16 @@
1
+ unless {}.respond_to? :symbolize_keys
2
+ class Hash
3
+ def transform_keys
4
+ return enum_for(:transform_keys) unless block_given?
5
+ result = self.class.new
6
+ each_key do |key|
7
+ result[yield(key)] = self[key]
8
+ end
9
+ result
10
+ end
11
+
12
+ def symbolize_keys
13
+ transform_keys{ |key| key.to_sym rescue key }
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,60 @@
1
+ unless Object.new.respond_to? :to_query and Object.new.respond_to? :to_param
2
+
3
+ require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
4
+
5
+ class Object
6
+ def to_param
7
+ to_s
8
+ end
9
+
10
+ def to_query(key)
11
+ "#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
12
+ end
13
+ end
14
+
15
+ class NilClass
16
+ def to_param
17
+ self
18
+ end
19
+ end
20
+
21
+ class TrueClass
22
+ def to_param
23
+ self
24
+ end
25
+ end
26
+
27
+ class FalseClass
28
+ def to_param
29
+ self
30
+ end
31
+ end
32
+
33
+ class Array
34
+ def to_param
35
+ collect(&:to_param).join '/'
36
+ end
37
+
38
+ def to_query(key)
39
+ prefix = "#{key}[]"
40
+
41
+ if empty?
42
+ nil.to_query(prefix)
43
+ else
44
+ collect { |value| value.to_query(prefix) }.join '&'
45
+ end
46
+ end
47
+ end
48
+
49
+ class Hash
50
+ def to_query(namespace = nil)
51
+ collect do |key, value|
52
+ unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
53
+ value.to_query(namespace ? "#{namespace}[#{key}]" : key)
54
+ end
55
+ end.compact.sort! * '&'
56
+ end
57
+
58
+ alias_method :to_param, :to_query
59
+ end
60
+ end
@@ -0,0 +1,52 @@
1
+ require 'logger'
2
+ require 'json'
3
+ require 'eventmachine'
4
+ require 'faye/websocket'
5
+
6
+ module WangluAPI
7
+ class StreamingClient < Client
8
+
9
+ def initialize(options={})
10
+ super
11
+ @endpoint = options[:endpoint] || 'wss://wanglutech.com:8080'
12
+ @logger = options[:logger] || Logger.new(STDOUT)
13
+ end
14
+
15
+ def run(&callback)
16
+ EM.run do
17
+ ws = Faye::WebSocket::Client.new(@endpoint)
18
+
19
+ ws.on(:open) do |event|
20
+ @logger.info "Connected."
21
+ end
22
+
23
+ ws.on(:message) do |event|
24
+ msg = JSON.parse(event.data)
25
+
26
+ key = msg.keys.first
27
+ data = msg[key]
28
+ case key
29
+ when 'challenge'
30
+ ws.send JSON.dump(@auth.signed_challenge(data))
31
+ else
32
+ begin
33
+ callback.call msg
34
+ rescue
35
+ @logger.error "Failed to process message: #{payload}"
36
+ @logger.error $!
37
+ end
38
+ end
39
+ end
40
+
41
+ ws.on(:close) do |event|
42
+ @logger.info "Closed. Code: #{event.code}, Reason: #{event.reason || 'none'}"
43
+ ws = nil
44
+ EM.stop
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,5 @@
1
+ require_relative 'wanglu_api/core_ext'
2
+ require_relative 'wanglu_api/config'
3
+ require_relative 'wanglu_api/auth'
4
+ require_relative 'wanglu_api/client'
5
+ require_relative 'wanglu_api/streaming_client'
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wanglu_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.8
5
+ platform: ruby
6
+ authors:
7
+ - Wanglu Opensource
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-02-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faye-websocket
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.9.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.9.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 5.5.1
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 5.5.1
41
+ description: A ruby client which can access all Wanglu's API.
42
+ email:
43
+ - mutouji1@163.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - README.markdown
49
+ - lib/wanglu_api/auth.rb
50
+ - lib/wanglu_api/client.rb
51
+ - lib/wanglu_api/client/version.rb
52
+ - lib/wanglu_api/config.rb
53
+ - lib/wanglu_api/core_ext.rb
54
+ - lib/wanglu_api/core_ext/keys.rb
55
+ - lib/wanglu_api/core_ext/to_query.rb
56
+ - lib/wanglu_api/streaming_client.rb
57
+ - lib/wanglu_client.rb
58
+ homepage: https://github.com/wanglu/wanglu-client-ruby
59
+ licenses:
60
+ - MIT
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 2.4.5
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: A ruby client to access Wanglu's API.
82
+ test_files: []