nano_rpc 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +13 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +137 -0
- data/Rakefile +6 -0
- data/bin/console +4 -0
- data/bin/setup +8 -0
- data/lib/nano/client.rb +59 -0
- data/lib/nano/errors.rb +11 -0
- data/lib/nano/helpers/account_proxy_helper.rb +70 -0
- data/lib/nano/helpers/accounts_proxy_helper.rb +48 -0
- data/lib/nano/helpers/node_proxy_helper.rb +42 -0
- data/lib/nano/helpers/wallet_proxy_helper.rb +105 -0
- data/lib/nano/proxies/account.rb +44 -0
- data/lib/nano/proxies/accounts.rb +25 -0
- data/lib/nano/proxies/node.rb +55 -0
- data/lib/nano/proxies/wallet.rb +47 -0
- data/lib/nano/proxy.rb +100 -0
- data/lib/nano/proxy_context.rb +80 -0
- data/lib/nano/response.rb +25 -0
- data/lib/nano/version.rb +4 -0
- data/lib/nano_rpc.rb +15 -0
- data/nano_rpc.gemspec +36 -0
- metadata +195 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: da3e826d03d97a0b481735d2c930a9f2dfd098167ae263c6a91b2b7da55dd607
|
4
|
+
data.tar.gz: a22e93555b44d86f5b53cb07ca13d6bc16a38f6f1d9025051655604d146b16a3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4ebe96119c1db5db4e4ac8d1a75a0dab74717d0fa718062fda33651820113b2021d5da2994fa7508cd67281c19e673d1b26229504720cef3fc77b46905686302
|
7
|
+
data.tar.gz: 461f6bdd4eb3db88ca94c2781519616e58bb412e44ab407f6abc76a381b4faa55f0741e054f7604829b3958753f7592e5d2d6f82dc6c716854bf5355dc8a864e
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.5.0
|
3
|
+
Exclude:
|
4
|
+
- 'bin/*'
|
5
|
+
DisplayCopNames: true
|
6
|
+
Style/ClassAndModuleChildren:
|
7
|
+
EnforcedStyle: compact
|
8
|
+
Style/EmptyMethod:
|
9
|
+
EnforcedStyle: expanded
|
10
|
+
Layout/EmptyLineAfterMagicComment:
|
11
|
+
Enabled: false
|
12
|
+
Documentation:
|
13
|
+
Enabled: false
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 Justin Craig-Kuhn
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
# Nano RPC
|
2
|
+
|
3
|
+
An RPC wrapper for Nano (the digital currency) written in Ruby. It connects to an individual Nano node that you control. There's a client object you can use to make explicit RPC calls as well as proxy objects with logically grouped helper methods ([Wiki](https://github.com/jcraigk/ruby_nano_rpc/wiki/Proxy-Object-Reference)).
|
4
|
+
|
5
|
+
To run a Nano node locally, see [Nano Docker Docs](https://github.com/clemahieu/raiblocks/wiki/Docker-node).
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'nano_rpc'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install nano_rpc
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
There are two ways to use this gem. You can make direct calls to the RPC client using Ruby hashes or you can use proxy objects for terser code.
|
26
|
+
|
27
|
+
### Raw RPC Calls
|
28
|
+
|
29
|
+
The RCP client exposes raw Remote Procedure Call methods according to the [Nano RPC Docs](https://github.com/clemahieu/raiblocks/wiki/RPC-protocol).
|
30
|
+
|
31
|
+
Every method requires an `action`, which is passed as the first argument to `call`. Depending on the action, there may be additional required or optional parameters that are passed as an options hash.
|
32
|
+
|
33
|
+
First setup the client:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
# Connect to localhost:7076
|
37
|
+
client = Nano.client
|
38
|
+
|
39
|
+
# Connect to custom host
|
40
|
+
client = Nano::Client.new(host: 'mynanonode', port: 1234)
|
41
|
+
```
|
42
|
+
|
43
|
+
Then make a `call`, passing the action and data:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
client.call(:account_balance, account: 'xrb_someaddress1234')
|
47
|
+
# => {"balance"=>100, "pending"=>0}
|
48
|
+
````
|
49
|
+
|
50
|
+
Response data are provided as [Hashie](https://github.com/intridea/hashie) objects with integer coercion, indifferent access, and method access.
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
data = client.call(:account_balance, account: 'xrb_someaddress1234')
|
54
|
+
# => {"balance"=>100, "pending"=>0}
|
55
|
+
data.balance
|
56
|
+
# => 100
|
57
|
+
data[:balance]
|
58
|
+
# => 100
|
59
|
+
data['balance']
|
60
|
+
# => 100
|
61
|
+
````
|
62
|
+
|
63
|
+
### Proxy Objects
|
64
|
+
|
65
|
+
Proxy objects are provided to ease interaction with the API by providing logically grouped helper methods. Here we do not strictly follow the grouping as expressed in the [Nano RPC Docs](https://github.com/clemahieu/raiblocks/wiki/RPC-protocol). Instead, the following objects are provided:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
Nano::Account # { account: 'xrb_address12345' }
|
69
|
+
Nano::Accounts # { accounts: %w[xrb_address12345 xrb_address67890] }
|
70
|
+
Nano::Node
|
71
|
+
Nano::Wallet # { wallet: 'F3093AB' }
|
72
|
+
```
|
73
|
+
|
74
|
+
`Account`, `Accounts`, and `Wallet` each require a single parameter to be passed during initialization. This parameter is persisted for subsequent calls. All RPC methods are provided directly as methods.
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
account = Nano::Account.new('xrb_someaddress1234')
|
78
|
+
|
79
|
+
account.account_balance
|
80
|
+
# => {"balance"=>100, "pending"=>0}
|
81
|
+
account.account_balance.balance
|
82
|
+
# 100
|
83
|
+
```
|
84
|
+
|
85
|
+
You can ask an object what raw RPC methods it provides using `proxy_methods`:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
account.proxy_methods
|
89
|
+
# => [:account_balance, :account_block_count, :account_create, ...]
|
90
|
+
```
|
91
|
+
|
92
|
+
There are also helper methods for terser code:
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
account = Nano::Account.new('xrb_someaddress1234')
|
96
|
+
account.balance
|
97
|
+
# 100
|
98
|
+
account.pending_balance
|
99
|
+
# 0
|
100
|
+
```
|
101
|
+
|
102
|
+
You can ask an object what helper methods it provides using `helper_methods` (coming soon):
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
account.helper_methods
|
106
|
+
# => [:balance, :pending_balance, ...]
|
107
|
+
```
|
108
|
+
|
109
|
+
`Node` methods are provided at both the instance and class levels:
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
Nano::Node.version
|
113
|
+
# => {"rpc_version"=>1, "store_version"=>10, "node_vendor"=>"RaiBlocks 9.0"}
|
114
|
+
|
115
|
+
node = Nano::Node.new
|
116
|
+
version.rpc_version
|
117
|
+
# => 1
|
118
|
+
node.peers
|
119
|
+
# => {"peers"=>{"[::ffff:2.80.5.202]:64317"=>"5", "[::ffff:2.249.74.58]:7075"=>"5", "[::ffff:5.9.31.82]:7077"=>"4", ... }
|
120
|
+
node.available_supply
|
121
|
+
# => {"available"=>132596127030666124778600855847014518457}
|
122
|
+
node.block_count.unchecked
|
123
|
+
# => 4868605
|
124
|
+
```
|
125
|
+
|
126
|
+
To connect to a custom node, instantiate a client and pass it into the proxy object as `client`:
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
client = Nano::Client.new(host: 'mynanonode', port: 1234)
|
130
|
+
account = Nano::Account.new('xrb_someaddress1234', client: client)
|
131
|
+
```
|
132
|
+
|
133
|
+
For a more comprehensive guide, see the [Wiki](https://github.com/jcraigk/ruby_nano_rpc/wiki/Proxy-Object-Reference).
|
134
|
+
|
135
|
+
## License
|
136
|
+
|
137
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
data/bin/setup
ADDED
data/lib/nano/client.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'rest-client'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Nano
|
6
|
+
def self.client
|
7
|
+
@client ||= Client.new
|
8
|
+
end
|
9
|
+
|
10
|
+
class Client
|
11
|
+
attr_accessor :host, :port
|
12
|
+
|
13
|
+
def initialize(host: 'localhost', port: 7076)
|
14
|
+
@host = host
|
15
|
+
@port = port
|
16
|
+
end
|
17
|
+
|
18
|
+
def call(action, params = {})
|
19
|
+
args = { action: action }
|
20
|
+
args.merge!(params) if params.is_a?(Hash)
|
21
|
+
post(args)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def post(params)
|
27
|
+
response = rest_client_post(url, params)
|
28
|
+
ensure_status_success!(response)
|
29
|
+
|
30
|
+
data = Nano::Response.new(JSON[response.body])
|
31
|
+
ensure_valid_response!(data)
|
32
|
+
|
33
|
+
data
|
34
|
+
end
|
35
|
+
|
36
|
+
def rest_client_post(url, params)
|
37
|
+
RestClient.post(url, params.to_json)
|
38
|
+
rescue Errno::ECONNREFUSED
|
39
|
+
raise Nano::NodeConnectionFailure,
|
40
|
+
"Node connection failure at #{url}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def url
|
44
|
+
"http://#{host}:#{port}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def ensure_status_success!(response)
|
48
|
+
return if response.code == 200
|
49
|
+
raise Nano::BadRequest,
|
50
|
+
"Error response from node: #{JSON[response.body]}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def ensure_valid_response!(data)
|
54
|
+
return unless data['error']
|
55
|
+
raise Nano::InvalidRequest,
|
56
|
+
"Invalid request: #{data['error']}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/nano/errors.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Nano
|
3
|
+
class Error < StandardError; end
|
4
|
+
|
5
|
+
class NodeConnectionFailure < Error; end
|
6
|
+
class BadRequest < Error; end
|
7
|
+
class InvalidRequest < Error; end
|
8
|
+
class InvalidParameterType < Error; end
|
9
|
+
class ForbiddenParameter < Error; end
|
10
|
+
class MissingParameters < Error; end
|
11
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Nano::AccountProxyHelper
|
3
|
+
def balance
|
4
|
+
account_balance.balance
|
5
|
+
end
|
6
|
+
|
7
|
+
def block_count
|
8
|
+
account_block_count.block_count
|
9
|
+
end
|
10
|
+
|
11
|
+
def create(wallet:, work:)
|
12
|
+
account_create(wallet: wallet, work: work).account
|
13
|
+
end
|
14
|
+
|
15
|
+
def history(count:)
|
16
|
+
account_history(count: count).history
|
17
|
+
end
|
18
|
+
|
19
|
+
def info
|
20
|
+
account_info
|
21
|
+
end
|
22
|
+
|
23
|
+
def key
|
24
|
+
account_key.key
|
25
|
+
end
|
26
|
+
|
27
|
+
def list
|
28
|
+
account_list.accounts
|
29
|
+
end
|
30
|
+
|
31
|
+
def move(wallet:, source:, accounts:)
|
32
|
+
account_move(wallet: wallet, source: source, accounts: accounts).moved == 1
|
33
|
+
end
|
34
|
+
|
35
|
+
def wallet_work(wallet:)
|
36
|
+
work_get(wallet: wallet).work
|
37
|
+
end
|
38
|
+
|
39
|
+
def wallet_work_set(wallet:, work:)
|
40
|
+
work_set(wallet: wallet, work: work).work[:success] == ''
|
41
|
+
end
|
42
|
+
|
43
|
+
def pending_balance
|
44
|
+
account_balance.pending
|
45
|
+
end
|
46
|
+
alias balance_pending pending_balance
|
47
|
+
|
48
|
+
def pending_blocks(count:, threshold: nil, exists: nil)
|
49
|
+
pending(count: count, threshold: threshold, exists: exists).locks
|
50
|
+
end
|
51
|
+
alias blocks_pending pending_blocks
|
52
|
+
|
53
|
+
def remove(wallet:)
|
54
|
+
account_remove(wallet: wallet).removed == 1
|
55
|
+
end
|
56
|
+
|
57
|
+
def representative
|
58
|
+
account_representative.representative
|
59
|
+
end
|
60
|
+
|
61
|
+
def representative_set(wallet:, representative:)
|
62
|
+
account_representative_set(
|
63
|
+
wallet: wallet, representative: representative
|
64
|
+
).set == 1
|
65
|
+
end
|
66
|
+
|
67
|
+
def weight
|
68
|
+
account_weight.weight
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Nano::AccountsProxyHelper
|
3
|
+
def balances
|
4
|
+
accounts_balances.balances
|
5
|
+
end
|
6
|
+
|
7
|
+
def create(wallet:, count:, work: nil)
|
8
|
+
accounts_create(wallet: wallet, count: count, work: work).accounts
|
9
|
+
end
|
10
|
+
|
11
|
+
def frontiers
|
12
|
+
accounts_frontiers.frontiers
|
13
|
+
end
|
14
|
+
|
15
|
+
def pending(count:, threshold: nil, source: nil)
|
16
|
+
accounts_pending(count: count, threshold: threshold, source: source).blocks
|
17
|
+
end
|
18
|
+
alias pending_blocks pending
|
19
|
+
|
20
|
+
# Array-like access for Nano::Account
|
21
|
+
def [](idx)
|
22
|
+
return unless @addresses[idx]
|
23
|
+
@account_objects ||= []
|
24
|
+
@account_objects[idx] ||= Nano::Account.new(@addresses[idx])
|
25
|
+
end
|
26
|
+
|
27
|
+
def <<(val)
|
28
|
+
@addresses << val
|
29
|
+
end
|
30
|
+
|
31
|
+
def each(&_block)
|
32
|
+
@addresses.each do |address|
|
33
|
+
yield Nano::Account.new(address)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def first
|
38
|
+
self[0]
|
39
|
+
end
|
40
|
+
|
41
|
+
def second
|
42
|
+
self[1]
|
43
|
+
end
|
44
|
+
|
45
|
+
def third
|
46
|
+
self[2]
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Nano::NodeProxyHelper
|
3
|
+
def account_containing_block(hash)
|
4
|
+
block_account(hash: hash).account
|
5
|
+
end
|
6
|
+
|
7
|
+
def available
|
8
|
+
available_supply.available
|
9
|
+
end
|
10
|
+
|
11
|
+
def krai_from(amount:)
|
12
|
+
krai_from_raw(amount: amount).amount
|
13
|
+
end
|
14
|
+
|
15
|
+
def krai_to(amount:)
|
16
|
+
krai_to_raw(amount: amount).amount
|
17
|
+
end
|
18
|
+
|
19
|
+
def mrai_from(amount:)
|
20
|
+
mrai_from_raw(amount: amount).amount
|
21
|
+
end
|
22
|
+
|
23
|
+
def mrai_to(amount:)
|
24
|
+
mrai_to_raw(amount: amount).amount
|
25
|
+
end
|
26
|
+
|
27
|
+
def pending_exists?(hash:)
|
28
|
+
pending_exists(hash: hash).exists == 1
|
29
|
+
end
|
30
|
+
|
31
|
+
def rai_from(amount:)
|
32
|
+
rai_from_raw(amount: amount).amount
|
33
|
+
end
|
34
|
+
|
35
|
+
def rai_to(amount:)
|
36
|
+
rai_to_raw(amount: amount).amount
|
37
|
+
end
|
38
|
+
|
39
|
+
def work_valid?(work:, hash:)
|
40
|
+
work_validate(work: work, hash: hash).valid == 1
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Nano::WalletProxyHelper
|
3
|
+
def account_work(account:)
|
4
|
+
work_get.work(account: account).work
|
5
|
+
end
|
6
|
+
|
7
|
+
def add(key:, work: nil)
|
8
|
+
wallet_add(key: key, work: work).account
|
9
|
+
end
|
10
|
+
|
11
|
+
def balance
|
12
|
+
wallet_balance_total.balance
|
13
|
+
end
|
14
|
+
|
15
|
+
def balances(threshold: nil)
|
16
|
+
wallet_balances(threshold: threshold).balances
|
17
|
+
end
|
18
|
+
|
19
|
+
def begin_payment
|
20
|
+
payment_begin.account
|
21
|
+
end
|
22
|
+
|
23
|
+
def change_password(new_password:)
|
24
|
+
password_change(password: new_password).changed == 1
|
25
|
+
end
|
26
|
+
|
27
|
+
def change_seed(new_seed:)
|
28
|
+
wallet_change_seed(seed: new_seed)[:success] == ''
|
29
|
+
end
|
30
|
+
|
31
|
+
def contains?(account:)
|
32
|
+
wallet_contains(account: account).exists == 1
|
33
|
+
end
|
34
|
+
|
35
|
+
def create
|
36
|
+
wallet_create.wallet
|
37
|
+
end
|
38
|
+
|
39
|
+
def destroy
|
40
|
+
wallet_destroy
|
41
|
+
end
|
42
|
+
|
43
|
+
def enter_password(password)
|
44
|
+
password_enter(password: password).valid == 1
|
45
|
+
end
|
46
|
+
|
47
|
+
def export
|
48
|
+
JSON[wallet_export.json]
|
49
|
+
end
|
50
|
+
|
51
|
+
def frontiers
|
52
|
+
wallet_frontiers.frontiers
|
53
|
+
end
|
54
|
+
|
55
|
+
def init_payment
|
56
|
+
payment_init.status == 'Ready'
|
57
|
+
end
|
58
|
+
|
59
|
+
def locked?
|
60
|
+
wallet_locked.locked == 1
|
61
|
+
end
|
62
|
+
|
63
|
+
def password_valid?(password:)
|
64
|
+
password_valid(password: password).valid == 1
|
65
|
+
end
|
66
|
+
|
67
|
+
def pending_balance
|
68
|
+
wallet_balance_total.pending
|
69
|
+
end
|
70
|
+
|
71
|
+
def pending_blocks(count:, threshold: nil, source: nil)
|
72
|
+
wallet_pending(count: count, threshold: threshold, source: source).blocks
|
73
|
+
end
|
74
|
+
|
75
|
+
def receive_block(account:, block:)
|
76
|
+
receive.block(account: account, block: block).block
|
77
|
+
end
|
78
|
+
|
79
|
+
def representative
|
80
|
+
wallet_representative.representative
|
81
|
+
end
|
82
|
+
|
83
|
+
def republish(count:)
|
84
|
+
wallet_republish(count: count).blocks
|
85
|
+
end
|
86
|
+
|
87
|
+
def account_work_set(account:, work:)
|
88
|
+
work_set(account: account, work: work).work[:success] == ''
|
89
|
+
end
|
90
|
+
alias set_account_work account_work_set
|
91
|
+
|
92
|
+
def representative_set(representative:)
|
93
|
+
wallet_representative_set(representative: representative).set == 1
|
94
|
+
end
|
95
|
+
alias set_representative representative_set
|
96
|
+
|
97
|
+
def send_tx(source:, destination:, amount:)
|
98
|
+
rai_send(source: source, destination: destination, amount: amount).block
|
99
|
+
end
|
100
|
+
alias send_transaction send_tx
|
101
|
+
|
102
|
+
def work
|
103
|
+
wallet_work_get.works
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
class Nano::Account
|
3
|
+
include Nano::Proxy
|
4
|
+
include Nano::AccountProxyHelper
|
5
|
+
|
6
|
+
attr_accessor :address
|
7
|
+
|
8
|
+
def initialize(address = nil, opts = {})
|
9
|
+
unless address.is_a?(String)
|
10
|
+
raise Nano::MissingParameters,
|
11
|
+
'Missing argument: address (str)'
|
12
|
+
end
|
13
|
+
|
14
|
+
@address = address
|
15
|
+
@client = opts[:client] || Nano.client
|
16
|
+
end
|
17
|
+
|
18
|
+
proxy_params account: :address
|
19
|
+
|
20
|
+
proxy_method :account_balance
|
21
|
+
proxy_method :account_block_count
|
22
|
+
proxy_method :account_info
|
23
|
+
proxy_method :account_create, required: %i[wallet], optional: %i[work]
|
24
|
+
proxy_method :account_history, required: %i[count]
|
25
|
+
proxy_method :account_list
|
26
|
+
proxy_method :account_move, required: %i[wallet source accounts]
|
27
|
+
proxy_method :account_key
|
28
|
+
proxy_method :account_remove, required: %i[wallet]
|
29
|
+
proxy_method :account_representative
|
30
|
+
proxy_method :account_representative_set, required: %i[wallet representative]
|
31
|
+
proxy_method :account_weight
|
32
|
+
proxy_method :delegators
|
33
|
+
proxy_method :delegators_count
|
34
|
+
proxy_method :frontiers, required: %i[count]
|
35
|
+
proxy_method :frontier_count
|
36
|
+
proxy_method :ledger,
|
37
|
+
required: %i[count],
|
38
|
+
optional: %i[representative weight pending sorting]
|
39
|
+
proxy_method :validate_account_number
|
40
|
+
proxy_method :pending, required: %i[count], optional: %i[threshold exists]
|
41
|
+
proxy_method :payment_wait, required: %i[amount timeout]
|
42
|
+
proxy_method :work_get
|
43
|
+
proxy_method :work_set
|
44
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
class Nano::Accounts
|
3
|
+
include Nano::Proxy
|
4
|
+
include Nano::AccountsProxyHelper
|
5
|
+
|
6
|
+
attr_accessor :addresses
|
7
|
+
|
8
|
+
def initialize(addresses = nil, client = nil)
|
9
|
+
unless addresses.is_a?(Array)
|
10
|
+
raise Nano::MissingParameters,
|
11
|
+
'Missing argument: addresses (str[])'
|
12
|
+
end
|
13
|
+
|
14
|
+
@addresses = addresses
|
15
|
+
@client = client || Nano.client
|
16
|
+
end
|
17
|
+
|
18
|
+
proxy_params accounts: :addresses
|
19
|
+
|
20
|
+
proxy_method :accounts_balances
|
21
|
+
proxy_method :accounts_create, required: %i[wallet count], optional: %i[work]
|
22
|
+
proxy_method :accounts_frontiers
|
23
|
+
proxy_method :accounts_pending,
|
24
|
+
required: %i[count], optional: %i[threshold source]
|
25
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
class Nano::Node
|
3
|
+
include Nano::Proxy
|
4
|
+
include Nano::NodeProxyHelper
|
5
|
+
|
6
|
+
proxy_method :available_supply
|
7
|
+
proxy_method :block, required: %i[hash]
|
8
|
+
proxy_method :block_account, required: %i[hash]
|
9
|
+
proxy_method :block_count
|
10
|
+
proxy_method :block_count_type
|
11
|
+
proxy_method :block_create,
|
12
|
+
required: %i[type key representative source], optional: %i[work]
|
13
|
+
proxy_method :blocks, required: %i[hashes]
|
14
|
+
proxy_method :blocks_info,
|
15
|
+
required: %i[hashes], optional: %i[pending source]
|
16
|
+
proxy_method :bootstrap, required: %i[address port]
|
17
|
+
proxy_method :bootstrap_any
|
18
|
+
proxy_method :chain, required: %i[block count]
|
19
|
+
proxy_method :deterministic_key, required: %i[seed index]
|
20
|
+
proxy_method :history, required: %i[hash count]
|
21
|
+
proxy_method :keepalive, required: %i[address port]
|
22
|
+
proxy_method :key_create
|
23
|
+
proxy_method :key_expand, required: %i[key]
|
24
|
+
proxy_method :krai_from_raw, required: %i[amount]
|
25
|
+
proxy_method :krai_to_raw, required: %i[amount]
|
26
|
+
proxy_method :mrai_from_raw, required: %i[amount]
|
27
|
+
proxy_method :mrai_to_raw, required: %i[amount]
|
28
|
+
proxy_method :payment_wait, required: %i[account amount timeout]
|
29
|
+
proxy_method :peers
|
30
|
+
proxy_method :pending_exists, required: %i[hash]
|
31
|
+
proxy_method :process, required: %i[block]
|
32
|
+
proxy_method :rai_from_raw, required: %i[amount]
|
33
|
+
proxy_method :rai_to_raw, required: %i[amount]
|
34
|
+
proxy_method :receive_minimum
|
35
|
+
proxy_method :receive_minimum_set, required: %i[amount]
|
36
|
+
proxy_method :representatives
|
37
|
+
proxy_method :republish,
|
38
|
+
required: %i[hash],
|
39
|
+
optional: %i[count sources destinations]
|
40
|
+
proxy_method :search_pending, required: %i[wallet]
|
41
|
+
proxy_method :search_pending_all
|
42
|
+
proxy_method :stop
|
43
|
+
proxy_method :successors, required: %i[block count]
|
44
|
+
proxy_method :unchecked, required: %i[count]
|
45
|
+
proxy_method :unchecked_clear
|
46
|
+
proxy_method :unchecked_get, required: %i[hash]
|
47
|
+
proxy_method :unchecked_keys, required: %i[key count]
|
48
|
+
proxy_method :version
|
49
|
+
proxy_method :work_cancel, required: %i[hash]
|
50
|
+
proxy_method :work_generate, required: %i[hash]
|
51
|
+
proxy_method :work_peer_add, required: %i[address port]
|
52
|
+
proxy_method :work_peers
|
53
|
+
proxy_method :work_peers_clear
|
54
|
+
proxy_method :work_validate, required: %i[work hash]
|
55
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
class Nano::Wallet
|
3
|
+
include Nano::Proxy
|
4
|
+
include Nano::WalletProxyHelper
|
5
|
+
|
6
|
+
attr_accessor :seed
|
7
|
+
|
8
|
+
def initialize(wallet_seed = nil, opts = {})
|
9
|
+
unless wallet_seed.is_a?(String)
|
10
|
+
raise Nano::MissingParameters,
|
11
|
+
'Missing argument: address (str)'
|
12
|
+
end
|
13
|
+
|
14
|
+
@seed = wallet_seed
|
15
|
+
@client = opts[:client] || Nano.client
|
16
|
+
end
|
17
|
+
|
18
|
+
proxy_params wallet: :seed
|
19
|
+
|
20
|
+
proxy_method :password_change, required: %i[password]
|
21
|
+
proxy_method :password_enter, required: %i[password]
|
22
|
+
proxy_method :password_valid
|
23
|
+
proxy_method :payment_begin
|
24
|
+
proxy_method :payment_init
|
25
|
+
proxy_method :payment_end, required: %i[account]
|
26
|
+
proxy_method :receive, required: %i[account block]
|
27
|
+
proxy_method :send, required: %i[wallet source destination amount]
|
28
|
+
proxy_method :search_pending
|
29
|
+
proxy_method :wallet_add, required: %i[key], optional: %i[work]
|
30
|
+
proxy_method :wallet_balance_total
|
31
|
+
proxy_method :wallet_balances, optional: %i[threshold]
|
32
|
+
proxy_method :wallet_change_seed, required: %i[seed]
|
33
|
+
proxy_method :wallet_contains, required: %i[account]
|
34
|
+
proxy_method :wallet_create
|
35
|
+
proxy_method :wallet_destroy
|
36
|
+
proxy_method :wallet_export
|
37
|
+
proxy_method :wallet_frontiers
|
38
|
+
proxy_method :wallet_locked
|
39
|
+
proxy_method :wallet_pending,
|
40
|
+
required: %i[count], optional: %i[threshold source]
|
41
|
+
proxy_method :wallet_representative
|
42
|
+
proxy_method :wallet_representative_set, required: %i[representative]
|
43
|
+
proxy_method :wallet_republish, required: %i[count]
|
44
|
+
proxy_method :wallet_work_get
|
45
|
+
proxy_method :work_get
|
46
|
+
proxy_method :work_set
|
47
|
+
end
|
data/lib/nano/proxy.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Nano::Proxy
|
3
|
+
attr_accessor :client
|
4
|
+
|
5
|
+
def initialize(opts = {})
|
6
|
+
@client = opts[:client] || Nano.client
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.extend(ClassMethods)
|
11
|
+
end
|
12
|
+
module ClassMethods
|
13
|
+
attr_reader :proxy_method_def, :proxy_param_def
|
14
|
+
|
15
|
+
def proxy_params(param_def = nil)
|
16
|
+
@proxy_param_def = param_def
|
17
|
+
end
|
18
|
+
|
19
|
+
def proxy_method(name, signature = nil)
|
20
|
+
@proxy_method_def ||= {}
|
21
|
+
@proxy_method_def[name] = signature
|
22
|
+
end
|
23
|
+
|
24
|
+
def proxy_methods
|
25
|
+
proxy_method_def.keys.sort
|
26
|
+
end
|
27
|
+
|
28
|
+
def methods
|
29
|
+
(super + proxy_methods).sort
|
30
|
+
end
|
31
|
+
|
32
|
+
def define_proxy_method(m, singleton = false)
|
33
|
+
send(
|
34
|
+
singleton ? :define_singleton_method : :define_method,
|
35
|
+
method_alias(m)
|
36
|
+
) do |opts = {}|
|
37
|
+
params = Nano::ProxyContext.new(
|
38
|
+
singleton ? self : self.class, m, opts
|
39
|
+
).populate_params(singleton ? nil : base_params)
|
40
|
+
data = Nano.client.call(m, params)
|
41
|
+
data.is_a?(Hash) && data.keys.map(&:to_s) == [m.to_s] ? data[m] : data
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
# Nano `send` action is also the method caller in Ruby ;)
|
48
|
+
def method_alias(m)
|
49
|
+
m == :send ? :tx_send : m
|
50
|
+
end
|
51
|
+
|
52
|
+
def method_missing(m, *args, &_block)
|
53
|
+
return super unless valid_method?(m)
|
54
|
+
define_proxy_method(m, true)
|
55
|
+
send(m, args.first)
|
56
|
+
end
|
57
|
+
|
58
|
+
def respond_to_missing?(m, include_private = false)
|
59
|
+
valid_method?(m) || super
|
60
|
+
end
|
61
|
+
|
62
|
+
def valid_method?(m)
|
63
|
+
proxy_param_def.nil? && methods.include?(m)
|
64
|
+
end
|
65
|
+
|
66
|
+
def proxy_context(m)
|
67
|
+
@proxy_context ||= {}
|
68
|
+
@proxy_context[m] ||= Nano::ProxyContext.new(self, m)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def proxy_methods
|
73
|
+
self.class.proxy_methods
|
74
|
+
end
|
75
|
+
|
76
|
+
def methods
|
77
|
+
(super + proxy_methods).sort
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def base_params
|
83
|
+
return if self.class.proxy_param_def.nil?
|
84
|
+
self.class
|
85
|
+
.proxy_param_def
|
86
|
+
.each_with_object({}) do |(k, v), params|
|
87
|
+
params[k] ||= send(v)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def method_missing(m, *args, &_block)
|
92
|
+
return super unless methods.include?(m)
|
93
|
+
self.class.define_proxy_method(m)
|
94
|
+
send(m, args.first)
|
95
|
+
end
|
96
|
+
|
97
|
+
def respond_to_missing?(m, include_private = false)
|
98
|
+
methods.include?(m) || super
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
class Nano::ProxyContext
|
3
|
+
def initialize(klass, m, opts = {})
|
4
|
+
@klass = klass
|
5
|
+
@method_def = klass.proxy_method_def
|
6
|
+
@param_def = klass.proxy_param_def
|
7
|
+
@m = m
|
8
|
+
@opts = opts
|
9
|
+
end
|
10
|
+
|
11
|
+
def valid_proxy_method?
|
12
|
+
rpc_action?
|
13
|
+
end
|
14
|
+
|
15
|
+
def populate_params(params)
|
16
|
+
opts = validate_opts!
|
17
|
+
opts.merge!(params) if params
|
18
|
+
validate_params!
|
19
|
+
opts.delete_if { |_k, v| v.nil? }
|
20
|
+
opts
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate_opts!
|
24
|
+
return @opts if @opts.is_a?(Hash)
|
25
|
+
return {} if @opts.nil?
|
26
|
+
raise Nano::InvalidParameterType,
|
27
|
+
'You must pass a hash to an action method'
|
28
|
+
end
|
29
|
+
|
30
|
+
def validate_params!
|
31
|
+
ensure_required_params!
|
32
|
+
ensure_no_forbidden_params!
|
33
|
+
end
|
34
|
+
|
35
|
+
def ensure_required_params!
|
36
|
+
missing_params = required_params - opts_keys
|
37
|
+
return unless missing_params.any?
|
38
|
+
raise Nano::MissingParameters,
|
39
|
+
"Missing required parameter(s): #{missing_params.join(', ')}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def ensure_no_forbidden_params!
|
43
|
+
forbidden_params = base_param_keys + opts_keys - allowed_params
|
44
|
+
return unless forbidden_params.any?
|
45
|
+
raise Nano::ForbiddenParameter,
|
46
|
+
"Forbidden parameter(s) passed: #{forbidden_params.join(', ')}"
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def opts_keys
|
52
|
+
@opts.nil? ? [] : @opts.keys
|
53
|
+
end
|
54
|
+
|
55
|
+
def allowed_params
|
56
|
+
base_param_keys + required_params + optional_params
|
57
|
+
end
|
58
|
+
|
59
|
+
def required_params
|
60
|
+
return [] unless @method_def && @method_def[@m]
|
61
|
+
@method_def[@m][:required]
|
62
|
+
end
|
63
|
+
|
64
|
+
def optional_params
|
65
|
+
return [] unless @method_def && @method_def[@m]
|
66
|
+
@method_def[@m][:optional]
|
67
|
+
end
|
68
|
+
|
69
|
+
def base_param_keys
|
70
|
+
@param_def.is_a?(Hash) ? @param_def.keys : []
|
71
|
+
end
|
72
|
+
|
73
|
+
def method_expansion
|
74
|
+
"#{action_prefix}#{@m}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def action_prefix
|
78
|
+
@klass.name.split('::').last.downcase + '_'
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'hashie'
|
3
|
+
|
4
|
+
class Nano::Response < Hash
|
5
|
+
include ::Hashie::Extensions::MergeInitializer
|
6
|
+
include ::Hashie::Extensions::IndifferentAccess
|
7
|
+
include ::Hashie::Extensions::MethodAccess
|
8
|
+
|
9
|
+
def initialize(hash = {})
|
10
|
+
super
|
11
|
+
coerce_values
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def coerce_values
|
17
|
+
merge!(self) { |_k, v| to_f_or_i_or_s(v) }
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_f_or_i_or_s(v)
|
21
|
+
(float = Float(v)) && (float % 1.0).zero? ? float.to_i : float
|
22
|
+
rescue ArgumentError, TypeErrror
|
23
|
+
v
|
24
|
+
end
|
25
|
+
end
|
data/lib/nano/version.rb
ADDED
data/lib/nano_rpc.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'nano/version'
|
3
|
+
require 'nano/client'
|
4
|
+
require 'nano/errors'
|
5
|
+
require 'nano/proxy'
|
6
|
+
require 'nano/proxy_context'
|
7
|
+
require 'nano/response'
|
8
|
+
require 'nano/helpers/account_proxy_helper'
|
9
|
+
require 'nano/helpers/accounts_proxy_helper'
|
10
|
+
require 'nano/helpers/node_proxy_helper'
|
11
|
+
require 'nano/helpers/wallet_proxy_helper'
|
12
|
+
require 'nano/proxies/account'
|
13
|
+
require 'nano/proxies/accounts'
|
14
|
+
require 'nano/proxies/node'
|
15
|
+
require 'nano/proxies/wallet'
|
data/nano_rpc.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'nano/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'nano_rpc'
|
8
|
+
spec.version = Nano::VERSION
|
9
|
+
spec.authors = ['Justin Craig-Kuhn (JCK)']
|
10
|
+
spec.email = ['jcraigk@gmail.com']
|
11
|
+
|
12
|
+
spec.summary = 'RPC wrapper for Nano digital nodes written in Ruby'
|
13
|
+
spec.description = 'An RPC wrapper for Nano nodes written in Ruby.' \
|
14
|
+
'It connects to an individual node that you control. ' \
|
15
|
+
'A client object provides arbitrary RPC access and ' \
|
16
|
+
'proxy objects provide logically grouped helper methods.'
|
17
|
+
spec.homepage = 'https://github.com/jcraigk/ruby_nano_rpc'
|
18
|
+
spec.license = 'MIT'
|
19
|
+
|
20
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
21
|
+
f.match(%r{^(test|spec|features)/})
|
22
|
+
end
|
23
|
+
spec.bindir = 'exe'
|
24
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
|
+
spec.require_paths = %w[lib]
|
26
|
+
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
28
|
+
spec.add_development_dependency 'pry', '~> 0.11.3'
|
29
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
30
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
31
|
+
spec.add_development_dependency 'rubocop', '~> 0.52.1'
|
32
|
+
spec.add_development_dependency 'simplecov', '~> 0.15.1'
|
33
|
+
|
34
|
+
spec.add_runtime_dependency 'hashie', '~> 3.5', '>= 3.5.7'
|
35
|
+
spec.add_runtime_dependency 'rest-client', '~> 2.0', '>= 2.0.2'
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,195 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nano_rpc
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Justin Craig-Kuhn (JCK)
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-01-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.16'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.16'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.11.3
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.11.3
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.52.1
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.52.1
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.15.1
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.15.1
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: hashie
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.5'
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 3.5.7
|
107
|
+
type: :runtime
|
108
|
+
prerelease: false
|
109
|
+
version_requirements: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - "~>"
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '3.5'
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 3.5.7
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: rest-client
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - "~>"
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '2.0'
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: 2.0.2
|
127
|
+
type: :runtime
|
128
|
+
prerelease: false
|
129
|
+
version_requirements: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - "~>"
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '2.0'
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: 2.0.2
|
137
|
+
description: An RPC wrapper for Nano nodes written in Ruby.It connects to an individual
|
138
|
+
node that you control. A client object provides arbitrary RPC access and proxy objects
|
139
|
+
provide logically grouped helper methods.
|
140
|
+
email:
|
141
|
+
- jcraigk@gmail.com
|
142
|
+
executables: []
|
143
|
+
extensions: []
|
144
|
+
extra_rdoc_files: []
|
145
|
+
files:
|
146
|
+
- ".gitignore"
|
147
|
+
- ".rspec"
|
148
|
+
- ".rubocop.yml"
|
149
|
+
- Gemfile
|
150
|
+
- LICENSE.txt
|
151
|
+
- README.md
|
152
|
+
- Rakefile
|
153
|
+
- bin/console
|
154
|
+
- bin/setup
|
155
|
+
- lib/nano/client.rb
|
156
|
+
- lib/nano/errors.rb
|
157
|
+
- lib/nano/helpers/account_proxy_helper.rb
|
158
|
+
- lib/nano/helpers/accounts_proxy_helper.rb
|
159
|
+
- lib/nano/helpers/node_proxy_helper.rb
|
160
|
+
- lib/nano/helpers/wallet_proxy_helper.rb
|
161
|
+
- lib/nano/proxies/account.rb
|
162
|
+
- lib/nano/proxies/accounts.rb
|
163
|
+
- lib/nano/proxies/node.rb
|
164
|
+
- lib/nano/proxies/wallet.rb
|
165
|
+
- lib/nano/proxy.rb
|
166
|
+
- lib/nano/proxy_context.rb
|
167
|
+
- lib/nano/response.rb
|
168
|
+
- lib/nano/version.rb
|
169
|
+
- lib/nano_rpc.rb
|
170
|
+
- nano_rpc.gemspec
|
171
|
+
homepage: https://github.com/jcraigk/ruby_nano_rpc
|
172
|
+
licenses:
|
173
|
+
- MIT
|
174
|
+
metadata: {}
|
175
|
+
post_install_message:
|
176
|
+
rdoc_options: []
|
177
|
+
require_paths:
|
178
|
+
- lib
|
179
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
180
|
+
requirements:
|
181
|
+
- - ">="
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: '0'
|
184
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
|
+
requirements:
|
186
|
+
- - ">="
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
version: '0'
|
189
|
+
requirements: []
|
190
|
+
rubyforge_project:
|
191
|
+
rubygems_version: 2.7.3
|
192
|
+
signing_key:
|
193
|
+
specification_version: 4
|
194
|
+
summary: RPC wrapper for Nano digital nodes written in Ruby
|
195
|
+
test_files: []
|