bcoin-client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "bcoin-server",
3
+ "version": "1.0.0",
4
+ "description": "Bcoin installation for development.",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "author": "Dan Knox <dknox@threedotloft.com> (http://danknox.github.io/)",
10
+ "license": "MIT",
11
+ "dependencies": {
12
+ "bcoin": "^1.0.0-beta.14"
13
+ }
14
+ }
@@ -0,0 +1,18 @@
1
+ FROM ruby:2.2.5
2
+ MAINTAINER Daniel Knox <dk@bitfs.us>
3
+ ENV REFRESHED_AT 2017-08-09
4
+
5
+ RUN apt-get update -qq && apt-get install -y build-essential
6
+
7
+ # cleanup
8
+ RUN rm -rf /var/lib/apt/lists/*
9
+
10
+ RUN mkdir -p /bcoin-client
11
+
12
+ ADD . /bcoin-client
13
+ WORKDIR /bcoin-client
14
+
15
+ RUN gem install bundler
16
+ RUN bundle install
17
+
18
+ CMD ['bundle', 'exec', 'rspec']
@@ -0,0 +1,19 @@
1
+ version: '2'
2
+ services:
3
+ bcoin-client:
4
+ build:
5
+ context: .
6
+ dockerfile: ./config/containers/ruby/Dockerfile
7
+ links:
8
+ - bcoin
9
+ env_file: .env
10
+ command: bundle exec rspec
11
+ bcoin:
12
+ build: ./config/containers/bcoin
13
+ environment:
14
+ PATH: ./node_modules/.bin:$PATH
15
+ env_file: .env
16
+ expose:
17
+ - 8332
18
+ command:
19
+ - /bcoin/node_modules/.bin/bcoin --config=/bcoin/bcoin.conf
@@ -0,0 +1,81 @@
1
+ require "bcoin/client/version"
2
+ require "bcoin/client/http_methods"
3
+ require "bcoin/client/base"
4
+ require "bcoin/client/wallet"
5
+ require "bcoin/client/account"
6
+ require "bcoin/client/balance"
7
+ require "bcoin/client/master"
8
+ require "bcoin/client/collection"
9
+ require "bcoin/client/wallets"
10
+ require "bcoin/client/accounts"
11
+ require "httparty"
12
+
13
+ module Bcoin
14
+ class Client
15
+ include HTTParty
16
+
17
+ attr_reader :options
18
+
19
+ format :json
20
+
21
+ def initialize(options = {})
22
+ @options = options
23
+ end
24
+
25
+ def port
26
+ @options[:port] || 8332
27
+ end
28
+
29
+ def host
30
+ @options[:host] || "localhost"
31
+ end
32
+
33
+ def username
34
+ @options[:username]
35
+ end
36
+
37
+ def password
38
+ @options[:password]
39
+ end
40
+
41
+ def base_uri
42
+ [host, port].join(':')
43
+ end
44
+
45
+ def basic_auth
46
+ password.nil? ? nil : {username: username, password: password}
47
+ end
48
+
49
+ def default_options
50
+ {
51
+ base_uri: base_uri,
52
+ basic_auth: basic_auth
53
+ }
54
+ end
55
+
56
+ def request method, path, options = {}
57
+ options.merge! default_options
58
+ self.class.send(method, path, options).parsed_response
59
+ end
60
+
61
+ def get path, options = {}
62
+ request :get, path, query: options
63
+ end
64
+
65
+ def post path, options = {}
66
+ request :post, path, body: options.to_json
67
+ end
68
+
69
+ def put path, options = {}
70
+ request :put, path, body: options.to_json
71
+ end
72
+
73
+ def delete path, options = {}
74
+ request :delete, path, body: options.to_json
75
+ end
76
+
77
+ def wallets
78
+ @wallets ||= Wallets.new(self)
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,21 @@
1
+ module Bcoin
2
+ class Client
3
+ class Account < Base
4
+
5
+ # Contains an instance of Bcoin::Client::Wallet
6
+ # which adheres to the HTTP client interface
7
+ # but builds the URL correctly for the specific
8
+ # wallet which this account belongs to.
9
+ attr_reader :client
10
+
11
+ def name
12
+ @attributes[:name]
13
+ end
14
+
15
+ def base_path
16
+ '/account/' + name.to_s
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ require "bcoin/client/collection"
2
+ require "bcoin/client/account"
3
+
4
+ module Bcoin
5
+ class Client
6
+ class Accounts < Collection
7
+
8
+ # Contains an instance of Bcoin::Client::Wallet
9
+ # which adheres to the HTTP client interface
10
+ # but builds the URL correctly for the specific
11
+ # wallet which this account belongs to.
12
+ attr_reader :client
13
+
14
+ def base_path
15
+ '/account'
16
+ end
17
+
18
+ def refresh!
19
+ @collection = super.collect { |w|
20
+ Account.new(client, name: w).refresh!
21
+ }
22
+ self
23
+ end
24
+
25
+ def find attr
26
+ Account.new(client, attr).refresh!
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,17 @@
1
+ module Bcoin
2
+ class Client
3
+ class Balance < Base
4
+
5
+ # Contains an instance of Bcoin::Client::Wallet
6
+ # which adheres to the HTTP client interface
7
+ # but builds the URL correctly for the specific
8
+ # wallet which this account belongs to.
9
+ attr_reader :client
10
+
11
+ def base_path
12
+ '/balance/'
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,69 @@
1
+ module Bcoin
2
+ class Client
3
+ class Base
4
+
5
+ include HttpMethods
6
+
7
+ attr_reader :client, :attributes
8
+
9
+ def initialize client, attr = {}
10
+ @client = client
11
+ self.attributes = attr
12
+ end
13
+
14
+ def inspect
15
+ printf "#<%s @attributes=%p>", self.class.name, @attributes
16
+ end
17
+
18
+ # Override this in sub class
19
+ def id
20
+ 'base'
21
+ end
22
+
23
+ # Override this in sub class
24
+ def base_path
25
+ '/base'
26
+ end
27
+
28
+ def refresh!
29
+ self.attributes = get '/'
30
+ self
31
+ end
32
+
33
+ def wallet_token
34
+ @attributes[:token] if @attributes
35
+ end
36
+
37
+ def token= _token
38
+ @attributes[:token] = _token
39
+ end
40
+
41
+ def attributes= attr
42
+ @attributes = symbolize attr
43
+ end
44
+
45
+ def error= _error
46
+ @attributes[:error] = _error
47
+ end
48
+
49
+ private
50
+
51
+ def symbolize attr
52
+ symbolized = {}
53
+ attr.each do |k,v|
54
+ symbolized[k.to_sym] = v
55
+ end
56
+ symbolized
57
+ end
58
+
59
+ def method_missing method, *args
60
+ if @attributes[method].nil?
61
+ raise NoMethodError
62
+ else
63
+ @attributes[method]
64
+ end
65
+ end
66
+
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,47 @@
1
+ require "bcoin/client/http_methods"
2
+
3
+ module Bcoin
4
+ class Client
5
+ class Collection
6
+
7
+ include Enumerable
8
+ include HttpMethods
9
+
10
+ attr_reader :client, :collection, :error
11
+
12
+ def initialize client, collection = []
13
+ @client = client
14
+ @collection = collection
15
+ end
16
+
17
+ def inspect
18
+ printf "#<%s @collection=%p>", self.class.name, @collection
19
+ end
20
+
21
+ # Redefine in sub class
22
+ def base_path
23
+ '/collection'
24
+ end
25
+
26
+ def each &block
27
+ @collection.each {|w| block.call(w) }
28
+ end
29
+
30
+ # Allow for overriding of the path for situations
31
+ # like the wallet list retrieval. See the comment
32
+ # for Wallets#base_path for details.
33
+ def refresh! path = ''
34
+ get path + '/'
35
+ end
36
+
37
+ def error?
38
+ @error ? true : false
39
+ end
40
+
41
+ def error=(_error)
42
+ @error = _error
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,53 @@
1
+ module Bcoin
2
+ class Client
3
+ module HttpMethods
4
+
5
+ # Override this in sub class
6
+ def base_path
7
+ '/base'
8
+ end
9
+
10
+ def get path, options = {}
11
+ options[:token] = wallet_token if wallet_token
12
+ response = @client.get base_path + path, options
13
+ set_error_from response
14
+ response
15
+ end
16
+
17
+ def post path, options = {}
18
+ options[:token] = wallet_token if wallet_token
19
+ response = @client.post base_path + path, options
20
+ set_error_from response
21
+ response
22
+ end
23
+
24
+ def put path, options = {}
25
+ options[:token] = wallet_token if wallet_token
26
+ response = @client.put base_path + path, options
27
+ set_error_from response
28
+ response
29
+ end
30
+
31
+ def delete path, options = {}
32
+ options[:token] = wallet_token if wallet_token
33
+ response = @client.delete base_path + path, options
34
+ set_error_from response
35
+ response
36
+ end
37
+
38
+ # Override this is sub class
39
+ def wallet_token
40
+ nil
41
+ end
42
+
43
+ private
44
+
45
+ def set_error_from response = {}
46
+ if response.is_a?(Hash) && response['error']
47
+ self.error = response['error']
48
+ end
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,21 @@
1
+ module Bcoin
2
+ class Client
3
+ # Contains a copy of the HD Master Key. Depending
4
+ # on the lock state of the wallet (see Wallet#unlock),
5
+ # the master key will either be encrypted or in
6
+ # plain text.
7
+ class Master < Base
8
+
9
+ # Contains an instance of Bcoin::Client::Wallet
10
+ # which adheres to the HTTP client interface
11
+ # but builds the URL correctly for the specific
12
+ # wallet which this account belongs to.
13
+ attr_reader :client
14
+
15
+ def base_path
16
+ '/master/'
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ module Bcoin
2
+ class Client
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,109 @@
1
+ require "bcoin/client/accounts"
2
+ require "bcoin/client/balance"
3
+ require "bcoin/client/master"
4
+
5
+ module Bcoin
6
+ class Client
7
+ # The primary bcoin.io Wallet object.
8
+ class Wallet < Base
9
+
10
+ def id
11
+ @attributes[:id]
12
+ end
13
+
14
+ def base_path
15
+ '/wallet/' + id.to_s
16
+ end
17
+
18
+ # Retrieve a list of acounts with details.
19
+ # @return [Bcoin::Client::Accounts]
20
+ def accounts
21
+ @accounts ||= Accounts.new(self).refresh!
22
+ end
23
+
24
+ # Access the default account without making another
25
+ # network request.
26
+ # @return [Bcoin::Client::Account]
27
+ def account
28
+ @account ||= Account.new(self, @attributes[:account])
29
+ end
30
+
31
+ # Retrieve balance information for this wallet.
32
+ # @return [Bcoin::Client::Balance]
33
+ def balance
34
+ @balance ||= Balance.new(self).refresh!
35
+ end
36
+
37
+ # Reset the wallet passphrase. Useful for locking
38
+ # and unlocking the the master key and wallet coins.
39
+ # @param [Hash] opts The options for resetting
40
+ # the wallet passphrase.
41
+ # @option opts [String] :old The old password.
42
+ # @option opts [String] :new The new password.
43
+ # @return [true, false] True if successful.
44
+ def passphrase options = {}
45
+ post '/passphrase', options
46
+ !error?
47
+ end
48
+
49
+ # Unlock the wallet master key for retrieval of
50
+ # the wallet mnemonic, and key in plain text for
51
+ # 'timeout' number of seconds.
52
+ # @params [Hash] opts The options for unlocking
53
+ # the wallet master key.
54
+ # @option opts [String] :passphrase The wallet passphrase.
55
+ # @option opts [Integer] :timeout Seconds to unlock the wallet for.
56
+ # @return [true, false] True if succesful.
57
+ def unlock options = {}
58
+ post '/unlock', options
59
+ !error?
60
+ end
61
+
62
+ # Locks the wallet master key.
63
+ # @return [true, false] True if succesful.
64
+ def lock
65
+ post '/lock'
66
+ !error?
67
+ end
68
+
69
+ # Retrieves the wallet HD Master Key.
70
+ # @return [Bcoin::Client::Master] The wallet master key object.
71
+ def master
72
+ @master ||= begin
73
+ response = get '/master'
74
+ Master.new self, response
75
+ end
76
+ end
77
+
78
+ # Retrieves a new wallet API token.
79
+ # @return [Hash] opts
80
+ # @option opts :token The new wallet API token.
81
+ def retoken
82
+ response = post '/retoken'
83
+
84
+ if error?
85
+ false
86
+ else
87
+ @attributes[:token] = response['token']
88
+ true
89
+ end
90
+ end
91
+
92
+ # Create, sign, and send a new transaction.
93
+ # @params [Hash] opts Options for the new transaction.
94
+ # @option opts :rate Rate for the bitcoin network.
95
+ # @option opts :outputs => [{:value => '', :address => ''}]
96
+ def send options = {}
97
+ response = post '/send', options
98
+ error? ? false : response
99
+ end
100
+
101
+ # Checks for an error returned during a request.
102
+ # @return [true, false]
103
+ def error?
104
+ @attributes[:error] ? true : false
105
+ end
106
+
107
+ end
108
+ end
109
+ end