bitcoind_rpc 0.0.1 → 0.0.2
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 +4 -4
- data/README.md +21 -3
- data/bitcoind_rpc.gemspec +2 -0
- data/lib/bitcoind_rpc.rb +26 -3
- data/lib/bitcoind_rpc/connection.rb +85 -0
- data/lib/bitcoind_rpc/version.rb +1 -1
- metadata +16 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79c3c0305faaac12a984279bb387c5dbea898dd5
|
4
|
+
data.tar.gz: 6551d3485a5fd61b3e17f796d7a0d5622f6fc527
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a48811ef87ee14964e6164fd4bb13bcf17a4896b4cee6c3b4e4d977ff5b9b2e5e3fea6e709d951509d28304e38b4526312df720f8852a30af88687f82cad2272
|
7
|
+
data.tar.gz: 65bda6c214c0e9e3239bd821be130df68761caa9d557d1a1b4a4c4f272ecedef5ea3054db7275cc151334b0d9bab2780e20cbbe3a3ac2fef92937f586d14e60e
|
data/README.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
|
-
#
|
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
|
-
|
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
|
data/bitcoind_rpc.gemspec
CHANGED
@@ -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'
|
data/lib/bitcoind_rpc.rb
CHANGED
@@ -1,5 +1,28 @@
|
|
1
|
-
require '
|
1
|
+
require 'logger'
|
2
|
+
require_relative 'bitcoind_rpc/version'
|
3
|
+
require_relative 'bitcoind_rpc/connection'
|
2
4
|
|
3
5
|
module BitcoindRPC
|
4
|
-
|
5
|
-
|
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
|
data/lib/bitcoind_rpc/version.rb
CHANGED
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.
|
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:
|