bitcoind_rpc 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f74740329efd56a839d8fd49beb9b8afd03ac12c
4
- data.tar.gz: 1193a537f6b3486f5acb53fcf3385866932ba1c9
3
+ metadata.gz: 79c3c0305faaac12a984279bb387c5dbea898dd5
4
+ data.tar.gz: 6551d3485a5fd61b3e17f796d7a0d5622f6fc527
5
5
  SHA512:
6
- metadata.gz: 3706284e82201f575dc003ce85eede6176ebcda1c4709f67be722d33e4fb4e846522be3686438deb232b571cd71b5024c54ffbb9a03e06e677cb7b6e9b167650
7
- data.tar.gz: f52e87dce9121b3e1be4e277f042b41876aa8c630de92117bdb79f29ef9dbfd1e422718e71c42cdb1ae551ea8cb0eec2e9ca0766863ab6ce5831385b78180b25
6
+ metadata.gz: a48811ef87ee14964e6164fd4bb13bcf17a4896b4cee6c3b4e4d977ff5b9b2e5e3fea6e709d951509d28304e38b4526312df720f8852a30af88687f82cad2272
7
+ data.tar.gz: 65bda6c214c0e9e3239bd821be130df68761caa9d557d1a1b4a4c4f272ecedef5ea3054db7275cc151334b0d9bab2780e20cbbe3a3ac2fef92937f586d14e60e
data/README.md CHANGED
@@ -1,6 +1,12 @@
1
- # BitcoindRPC
1
+ # Bitcoind RPC
2
2
 
3
- A Ruby client for the bitcoind JSON-RPC.
3
+ A Ruby client for the *bitcoind* ([Bitcoin Core](https://github.com/bitcoin/bitcoin) compatible) JSON-RPC.
4
+
5
+ Features:
6
+
7
+ * Parses floats as BigDecimal
8
+ * Lists methods supported by the connected bitcoind
9
+ * Allows access to RPC methods as plain Ruby methods of Connection object
4
10
 
5
11
  ## Installation
6
12
 
@@ -20,7 +26,19 @@ Or install it yourself as:
20
26
 
21
27
  ## Usage
22
28
 
23
- TODO: Write usage instructions here
29
+ ```ruby
30
+
31
+ require 'bitcoind_rpc'
32
+
33
+ bitcoind = BitcoindRPC::Connection.new(uri: 'http://{username}:{password}@{host}:{port}')
34
+
35
+ bitcoind.supported_methods # => [ :getbestblockhash, :getblock, ... ]
36
+ bitcoind.getbalance # => #<BigDecimal:...>
37
+ bitcoind.blablabla # => NoMethodError
38
+
39
+ bitcoind.getblock "3d587773d2cbaf64f208f165f5f7717d7324350612d189063b4d1d2f14711380" # => { :hash => "3d58..." ...}
40
+
41
+ ```
24
42
 
25
43
 
26
44
  ## Contributing
@@ -27,6 +27,8 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ['lib']
29
29
 
30
+ spec.add_dependency 'oj', '~> 2.15'
31
+
30
32
  spec.add_development_dependency 'bundler', '~> 1.11'
31
33
  spec.add_development_dependency 'rake', '~> 10.0'
32
34
  spec.add_development_dependency 'rspec', '~> 3.0'
@@ -1,5 +1,28 @@
1
- require 'bitcoind_rpc/version'
1
+ require 'logger'
2
+ require_relative 'bitcoind_rpc/version'
3
+ require_relative 'bitcoind_rpc/connection'
2
4
 
3
5
  module BitcoindRPC
4
- # Your code goes here...
5
- end
6
+ DEFAULT_OPTIONS = {
7
+ logger: Logger.new(STDOUT).tap { |l| l.level = ::Logger::WARN }
8
+ }.freeze
9
+
10
+ def self.configure(opts = {})
11
+ opts = DEFAULT_OPTIONS.dup.merge(opts.dup)
12
+ @connection = BitcoindRPC::Connection.new(opts)
13
+ @logger = opts[:logger] if opts[:logger]
14
+ @connection
15
+ end
16
+
17
+ def self.connection
18
+ @connection
19
+ end
20
+
21
+ def self.logger
22
+ @logger ||= DEFAULT_OPTIONS[:logger]
23
+ end
24
+
25
+ def self.logger=(new_logger)
26
+ @logger = new_logger
27
+ end
28
+ end # module BitcoindRPC
@@ -0,0 +1,85 @@
1
+ require 'oj'
2
+ require 'net/http'
3
+
4
+ module BitcoindRPC
5
+ class Connection
6
+ attr_reader :options, :uri
7
+
8
+ DEFAULT_OPTIONS = {
9
+ host: 'localhost',
10
+ port: 18332 # Default for testnet: 18332, for mainnet: 8332
11
+ }.freeze
12
+
13
+ CONTENT_TYPE = 'application/json'.freeze
14
+
15
+ # Creates a new connection to a bitcoind
16
+ #
17
+ # @param [Hash] opts Connection parameters
18
+ # @option opts [String] :host
19
+ # @option opts [String] :port
20
+ # @option opts [String] :username
21
+ # @option opts [String] :password
22
+ # @option opts [String,URI] :uri Specify a complete URI instead of separate host, port etc
23
+ #
24
+ def initialize(opts)
25
+ @options = DEFAULT_OPTIONS.dup.merge(opts.dup)
26
+ @uri = @options[:uri] ? URI(@options[:uri]) : URI(uri_to_s)
27
+ end
28
+
29
+ def respond_to_missing?(name, _include_all = false)
30
+ supported_methods.include?(name.to_sym) || super
31
+ end
32
+
33
+ def method_missing(name, *args)
34
+ return request(name, *args) if supported_methods.include?(name.to_sym)
35
+ super
36
+ end
37
+
38
+ def request(name, *args)
39
+ BitcoindRPC.logger.debug "> #{name}: #{args.join(',')}"
40
+ response = request_http_post(name, args)
41
+ BitcoindRPC.logger.debug "< #{response.code} #{response.message}"
42
+ raise Error, response.message unless (200...300).cover?(response.code.to_i)
43
+ begin
44
+ response = Oj.load(response.body, symbol_keys: true, bigdecimal_load: true)
45
+ rescue StandardError => e
46
+ BitcoindRPC.logger.warn "Failed to parse JSON response: #{e}"
47
+ raise
48
+ end
49
+ raise Error, response[:error] if response[:error]
50
+ response[:result]
51
+ end
52
+
53
+ # Makes a request to a bitcoind instance once and returns the list of supported RPC methods
54
+ #
55
+ def supported_methods
56
+ return @supported_methods if @supported_methods
57
+ help_response = request(:help)
58
+ mm = help_response.split("\n").select { |l| l =~ /^\w+(\s|$)/ }
59
+ @supported_methods = mm.map { |l| l.split(' ').first }.map(&:to_sym)
60
+ end
61
+
62
+ private
63
+
64
+ def uri_to_s
65
+ "http://#{options[:username]}:#{options[:password]}@#{options[:host]}:#{options[:port]}"
66
+ end
67
+
68
+ def request_http_post(name, params)
69
+ username = uri.user
70
+ password = uri.password
71
+ http = Net::HTTP.new(uri.host, uri.port)
72
+ request = Net::HTTP::Post.new(uri.request_uri)
73
+ request.basic_auth(username, password)
74
+ request.body = request_body(name, params)
75
+ request['Content-Type'] = CONTENT_TYPE
76
+ http.request(request)
77
+ end
78
+
79
+ def request_body(name, params)
80
+ Oj.dump({ method: name, params: params, id: 'jsonrpc' }, mode: :compat)
81
+ end
82
+
83
+ class Error < RuntimeError; end
84
+ end # class Connection
85
+ end # module BitcoindRPC
@@ -1,3 +1,3 @@
1
1
  module BitcoindRPC
2
- VERSION = '0.0.1'.freeze
2
+ VERSION = '0.0.2'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitcoind_rpc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Kukushkin
@@ -10,6 +10,20 @@ bindir: exe
10
10
  cert_chain: []
11
11
  date: 2016-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: oj
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.15'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.15'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -85,6 +99,7 @@ files:
85
99
  - bin/setup
86
100
  - bitcoind_rpc.gemspec
87
101
  - lib/bitcoind_rpc.rb
102
+ - lib/bitcoind_rpc/connection.rb
88
103
  - lib/bitcoind_rpc/version.rb
89
104
  homepage: https://github.com/kukushkin/bitcoind_rpc
90
105
  licenses: