nanook 1.0.2 → 2.0.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 +4 -4
- data/CHANGELOG.md +37 -3
- data/README.md +40 -10
- data/lib/nanook.rb +70 -16
- data/lib/nanook/account.rb +183 -129
- data/lib/nanook/block.rb +61 -50
- data/lib/nanook/key.rb +1 -1
- data/lib/nanook/node.rb +14 -5
- data/lib/nanook/rpc.rb +6 -6
- data/lib/nanook/util.rb +2 -2
- data/lib/nanook/version.rb +1 -1
- data/lib/nanook/wallet.rb +147 -41
- data/lib/nanook/wallet_account.rb +74 -52
- data/lib/nanook/work_peer.rb +1 -1
- metadata +14 -21
- data/.circleci/config.yml +0 -56
- data/.gitignore +0 -9
- data/.rspec +0 -1
- data/Gemfile +0 -6
- data/Gemfile.lock +0 -65
- data/Rakefile +0 -20
- data/img/qr.png +0 -0
- data/nanook.gemspec +0 -34
data/lib/nanook/block.rb
CHANGED
@@ -10,7 +10,7 @@ class Nanook
|
|
10
10
|
# Initialize this class through the convenient Nanook#block method:
|
11
11
|
#
|
12
12
|
# nanook = Nanook.new
|
13
|
-
#
|
13
|
+
# block = nanook.block("FBF8B0E...")
|
14
14
|
#
|
15
15
|
# Or compose the longhand way like this:
|
16
16
|
#
|
@@ -24,22 +24,23 @@ class Nanook
|
|
24
24
|
block_required! # All methods expect a block
|
25
25
|
end
|
26
26
|
|
27
|
-
# Returns
|
27
|
+
# Returns the {Nanook::Account} of the block.
|
28
28
|
#
|
29
|
-
# ==== Example
|
29
|
+
# ==== Example:
|
30
|
+
# block.account # => Nanook::Account
|
30
31
|
#
|
31
|
-
#
|
32
|
+
# @return [Nanook::Account] the account of the block
|
32
33
|
def account
|
33
|
-
rpc(:block_account, :hash)[:account]
|
34
|
+
Nanook::Account.new(@rpc, rpc(:block_account, :hash)[:account])
|
34
35
|
end
|
35
36
|
|
36
37
|
# Stop generating work for a block.
|
37
38
|
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
# ==== Example
|
39
|
+
# ==== Example:
|
41
40
|
#
|
42
41
|
# block.cancel_work # => true
|
42
|
+
#
|
43
|
+
# @return [Boolean] signalling if the action was successful
|
43
44
|
def cancel_work
|
44
45
|
rpc(:work_cancel, :hash).empty?
|
45
46
|
end
|
@@ -49,20 +50,17 @@ class Nanook
|
|
49
50
|
#
|
50
51
|
# See also #successors.
|
51
52
|
#
|
52
|
-
# ====
|
53
|
-
#
|
54
|
-
# [+limit:+] Maximum number of block hashes to return (default is 1000)
|
55
|
-
#
|
56
|
-
# ==== Example
|
53
|
+
# ==== Example:
|
57
54
|
#
|
58
55
|
# block.chain(limit: 2)
|
59
56
|
#
|
60
|
-
# ==== Example reponse
|
57
|
+
# ==== Example reponse:
|
61
58
|
#
|
62
59
|
# [
|
63
60
|
# "36A0FB717368BA8CF8D255B63DC207771EABC6C6FFC22A7F455EC2209464897E",
|
64
61
|
# "FBF8B0E6623A31AB528EBD839EEAA91CAFD25C12294C46754E45FD017F7939EB"
|
65
62
|
# ]
|
63
|
+
# @param limit [Integer] maximum number of block hashes to return (default is 1000)
|
66
64
|
def chain(limit: 1000)
|
67
65
|
response = rpc(:chain, :block, count: limit)[:blocks]
|
68
66
|
Nanook::Util.coerce_empty_string_to_type(response, Array)
|
@@ -70,9 +68,10 @@ class Nanook
|
|
70
68
|
|
71
69
|
# Generate work for a block.
|
72
70
|
#
|
73
|
-
#
|
74
|
-
#
|
71
|
+
# ==== Example:
|
75
72
|
# block.generate_work # => "2bf29ef00786a6bc"
|
73
|
+
#
|
74
|
+
# @return [String] the work id of the work completed.
|
76
75
|
def generate_work
|
77
76
|
rpc(:work_generate, :hash)[:work]
|
78
77
|
end
|
@@ -80,16 +79,11 @@ class Nanook
|
|
80
79
|
# Returns Array of Hashes containing information about a chain of
|
81
80
|
# send/receive blocks, starting from this block.
|
82
81
|
#
|
83
|
-
# ====
|
84
|
-
#
|
85
|
-
# [+limit:+] Maximum number of send/receive block hashes to return
|
86
|
-
# in the chain (default is 1000)
|
87
|
-
#
|
88
|
-
# ==== Example
|
82
|
+
# ==== Example:
|
89
83
|
#
|
90
84
|
# block.history(limit: 1)
|
91
85
|
#
|
92
|
-
# ==== Example response
|
86
|
+
# ==== Example response:
|
93
87
|
#
|
94
88
|
# [
|
95
89
|
# {
|
@@ -99,27 +93,35 @@ class Nanook
|
|
99
93
|
# :type=>"send"
|
100
94
|
# }
|
101
95
|
# ]
|
96
|
+
#
|
97
|
+
# @param limit [Integer] maximum number of send/receive block hashes
|
98
|
+
# to return in the chain (default is 1000)
|
102
99
|
def history(limit: 1000)
|
103
100
|
rpc(:history, :hash, count: limit)[:history]
|
104
101
|
end
|
105
102
|
|
106
|
-
# Returns the block hash
|
103
|
+
# Returns the block hash id.
|
104
|
+
#
|
105
|
+
# ==== Example:
|
107
106
|
#
|
108
107
|
# block.id #=> "FBF8B0E..."
|
108
|
+
#
|
109
|
+
# @return [String] the block hash id
|
109
110
|
def id
|
110
111
|
@block
|
111
112
|
end
|
112
113
|
|
113
114
|
# Returns a Hash of information about the block.
|
114
115
|
#
|
115
|
-
# ====
|
116
|
+
# ==== Examples:
|
117
|
+
#
|
118
|
+
# block.info
|
119
|
+
# block.info(allow_unchecked: true)
|
116
120
|
#
|
117
|
-
#
|
118
|
-
# information can be returned about blocks that
|
119
|
-
# are unchecked (unverified).
|
120
|
-
# ==== Example response
|
121
|
+
# ==== Example response:
|
121
122
|
#
|
122
123
|
# {
|
124
|
+
# :id=>"36A0FB717368BA8CF8D255B63DC207771EABC6C6FFC22A7F455EC2209464897E",
|
123
125
|
# :type=>"send",
|
124
126
|
# :previous=>"FBF8B0E6623A31AB528EBD839EEAA91CAFD25C12294C46754E45FD017F7939EB",
|
125
127
|
# :destination=>"xrb_3x7cjioqahgs5ppheys6prpqtb4rdknked83chf97bot1unrbdkaux37t31b",
|
@@ -127,23 +129,28 @@ class Nanook
|
|
127
129
|
# :work=>"44cc24b60705083a",
|
128
130
|
# :signature=>"42ADFEFE7C3FFF188AE92A202F8A5734DE91779C454613E446EEC93D001D6C953E9FD16730AF32C891791BA8EDAECEB059A213E2FE1EEB7ADF9D5D0815464D06"
|
129
131
|
# }
|
132
|
+
#
|
133
|
+
# @param allow_unchecked [Boolean] (default is +false+). If +true+,
|
134
|
+
# information can be returned about blocks that are unchecked (unverified).
|
130
135
|
def info(allow_unchecked: false)
|
131
136
|
if allow_unchecked
|
132
|
-
# TODO not actually sure what this response looks like when it's not an unchecked block, assuming its blank
|
133
137
|
response = rpc(:unchecked_get, :hash)
|
134
|
-
|
135
|
-
return _parse_info_response(response
|
138
|
+
unless response.has_key?(:error)
|
139
|
+
return _parse_info_response(response)
|
136
140
|
end
|
137
|
-
#
|
141
|
+
# If unchecked not found, continue to checked block
|
138
142
|
end
|
139
143
|
|
140
144
|
response = rpc(:block, :hash)
|
141
145
|
_parse_info_response(response)
|
142
146
|
end
|
143
147
|
|
144
|
-
#
|
148
|
+
# ==== Example:
|
145
149
|
#
|
146
150
|
# block.is_valid_work?("2bf29ef00786a6bc") # => true
|
151
|
+
#
|
152
|
+
# @param work [String] the work id to check is valid
|
153
|
+
# @return [Boolean] signalling if work is valid for the block
|
147
154
|
def is_valid_work?(work)
|
148
155
|
response = rpc(:work_validate, :hash, work: work)
|
149
156
|
!response.empty? && response[:valid] == 1
|
@@ -152,13 +159,14 @@ class Nanook
|
|
152
159
|
# Republish blocks starting at this block up the account chain
|
153
160
|
# back to the nano network.
|
154
161
|
#
|
155
|
-
#
|
162
|
+
# @return [Array<String>] block hashes that were republished
|
156
163
|
#
|
157
|
-
# ==== Example
|
164
|
+
# ==== Example:
|
158
165
|
#
|
159
166
|
# block.republish
|
160
167
|
#
|
161
|
-
# ==== Example response
|
168
|
+
# ==== Example response:
|
169
|
+
#
|
162
170
|
# ["36A0FB717368BA8CF8D255B63DC207771EABC6C6FFC22A7F455EC2209464897E"]
|
163
171
|
def republish(destinations:nil, sources:nil)
|
164
172
|
if !destinations.nil? && !sources.nil?
|
@@ -174,9 +182,11 @@ class Nanook
|
|
174
182
|
rpc(:republish, :hash, params)[:blocks]
|
175
183
|
end
|
176
184
|
|
177
|
-
#
|
185
|
+
# ==== Example:
|
178
186
|
#
|
179
187
|
# block.pending? #=> false
|
188
|
+
#
|
189
|
+
# @return [Boolean] signalling if the block is a pending block.
|
180
190
|
def pending?
|
181
191
|
response = rpc(:pending_exists, :hash)
|
182
192
|
!response.empty? && response[:exists] == 1
|
@@ -186,12 +196,13 @@ class Nanook
|
|
186
196
|
#
|
187
197
|
# Note, if block has previously been published, use #republish instead.
|
188
198
|
#
|
189
|
-
#
|
199
|
+
# ==== Examples:
|
190
200
|
#
|
191
201
|
# block.publish # => "FBF8B0E..."
|
202
|
+
#
|
203
|
+
# @return [String] the block hash, or false.
|
192
204
|
def publish
|
193
|
-
|
194
|
-
rpc(:process, :block)[:hash]
|
205
|
+
rpc(:process, :block)[:hash] || false
|
195
206
|
end
|
196
207
|
alias_method :process, :publish
|
197
208
|
|
@@ -200,24 +211,23 @@ class Nanook
|
|
200
211
|
#
|
201
212
|
# See also #chain.
|
202
213
|
#
|
203
|
-
# ====
|
204
|
-
#
|
205
|
-
# [+limit:+] Maximum number of send/receive block hashes to return
|
206
|
-
# in the chain (default is 1000)
|
207
|
-
#
|
208
|
-
# ==== Example
|
214
|
+
# ==== Example:
|
209
215
|
#
|
210
216
|
# block.successors
|
211
217
|
#
|
212
|
-
# ==== Example response
|
218
|
+
# ==== Example response:
|
213
219
|
#
|
214
220
|
# ["36A0FB717368BA8CF8D255B63DC207771EABC6C6FFC22A7F455EC2209464897E"]
|
221
|
+
#
|
222
|
+
# @param limit [Integer] maximum number of send/receive block hashes
|
223
|
+
# to return in the chain (default is 1000)
|
224
|
+
# @return [Array<String>] block hashes in the account chain ending at this block
|
215
225
|
def successors(limit: 1000)
|
216
226
|
response = rpc(:successors, :block, count: limit)[:blocks]
|
217
227
|
Nanook::Util.coerce_empty_string_to_type(response, Array)
|
218
228
|
end
|
219
229
|
|
220
|
-
def inspect
|
230
|
+
def inspect
|
221
231
|
"#{self.class.name}(id: \"#{id}\", object_id: \"#{"0x00%x" % (object_id << 1)}\")"
|
222
232
|
end
|
223
233
|
|
@@ -240,7 +250,8 @@ class Nanook
|
|
240
250
|
def _parse_info_response(response)
|
241
251
|
# The contents is a stringified JSON
|
242
252
|
if response[:contents]
|
243
|
-
|
253
|
+
r = JSON.parse(response[:contents]).to_symbolized_hash
|
254
|
+
return r.merge(id: id)
|
244
255
|
end
|
245
256
|
|
246
257
|
response
|
data/lib/nanook/key.rb
CHANGED
data/lib/nanook/node.rb
CHANGED
@@ -5,6 +5,11 @@ class Nanook
|
|
5
5
|
@rpc = rpc
|
6
6
|
end
|
7
7
|
|
8
|
+
def account_count
|
9
|
+
rpc(:frontier_count)[:count]
|
10
|
+
end
|
11
|
+
alias_method :frontier_count, :account_count
|
12
|
+
|
8
13
|
def block_count
|
9
14
|
rpc(:block_count)
|
10
15
|
end
|
@@ -21,11 +26,7 @@ class Nanook
|
|
21
26
|
rpc(:bootstrap_any).has_key?(:success)
|
22
27
|
end
|
23
28
|
|
24
|
-
def
|
25
|
-
rpc(:frontier_count)[:count]
|
26
|
-
end
|
27
|
-
|
28
|
-
def inspect # :nodoc:
|
29
|
+
def inspect
|
29
30
|
"#{self.class.name}(object_id: \"#{"0x00%x" % (object_id << 1)}\")"
|
30
31
|
end
|
31
32
|
|
@@ -41,6 +42,14 @@ class Nanook
|
|
41
42
|
rpc(:stop).has_key?(:success)
|
42
43
|
end
|
43
44
|
|
45
|
+
def synchronizing_blocks(limit: 1000)
|
46
|
+
response = rpc(:unchecked, count: limit)[:blocks]
|
47
|
+
response = response.map do |block, info|
|
48
|
+
[block, JSON.parse(info).to_symbolized_hash]
|
49
|
+
end
|
50
|
+
Hash[response.sort].to_symbolized_hash
|
51
|
+
end
|
52
|
+
|
44
53
|
def sync_progress
|
45
54
|
response = rpc(:block_count)
|
46
55
|
|
data/lib/nanook/rpc.rb
CHANGED
@@ -8,15 +8,15 @@ class Nanook
|
|
8
8
|
DEFAULT_TIMEOUT = 500 # seconds
|
9
9
|
|
10
10
|
def initialize(uri=DEFAULT_URI, timeout:DEFAULT_TIMEOUT)
|
11
|
-
rpc_server = URI(uri)
|
11
|
+
@rpc_server = URI(uri)
|
12
12
|
|
13
|
-
unless ['http', 'https'].include?(rpc_server.scheme)
|
13
|
+
unless ['http', 'https'].include?(@rpc_server.scheme)
|
14
14
|
raise ArgumentError.new("URI must have http or https in it. Was given: #{uri}")
|
15
15
|
end
|
16
16
|
|
17
|
-
@http = Net::HTTP.new(rpc_server.host, rpc_server.port)
|
17
|
+
@http = Net::HTTP.new(@rpc_server.host, @rpc_server.port)
|
18
18
|
@http.read_timeout = timeout
|
19
|
-
@request = Net::HTTP::Post.new(rpc_server.request_uri, {"user-agent" => "Ruby nanook gem"})
|
19
|
+
@request = Net::HTTP::Post.new(@rpc_server.request_uri, {"user-agent" => "Ruby nanook gem"})
|
20
20
|
@request.content_type = "application/json"
|
21
21
|
end
|
22
22
|
|
@@ -36,8 +36,8 @@ class Nanook
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
def inspect
|
40
|
-
"#{self.class.name}(host: #{@
|
39
|
+
def inspect
|
40
|
+
"#{self.class.name}(host: \"#{@rpc_server}\", timeout: #{@http.read_timeout} object_id: \"#{"0x00%x" % (object_id << 1)}\")"
|
41
41
|
end
|
42
42
|
|
43
43
|
private
|
data/lib/nanook/util.rb
CHANGED
@@ -10,11 +10,11 @@ class Nanook
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.raw_to_NANO(raw)
|
13
|
-
raw.to_f / STEP
|
13
|
+
(raw.to_f / STEP).to_f
|
14
14
|
end
|
15
15
|
|
16
16
|
def self.coerce_empty_string_to_type(response, type)
|
17
|
-
if response == ""
|
17
|
+
if response == "" || response.nil?
|
18
18
|
return type.new
|
19
19
|
end
|
20
20
|
|
data/lib/nanook/version.rb
CHANGED
data/lib/nanook/wallet.rb
CHANGED
@@ -20,12 +20,12 @@ class Nanook
|
|
20
20
|
# Initialize this class through the convenient Nanook#wallet method:
|
21
21
|
#
|
22
22
|
# nanook = Nanook.new
|
23
|
-
# wallet = nanook.wallet(
|
23
|
+
# wallet = nanook.wallet(wallet_id)
|
24
24
|
#
|
25
25
|
# Or compose the longhand way like this:
|
26
26
|
#
|
27
27
|
# rpc_conn = Nanook::Rpc.new
|
28
|
-
# wallet = Nanook::Wallet.new(rpc_conn,
|
28
|
+
# wallet = Nanook::Wallet.new(rpc_conn, wallet_id)
|
29
29
|
class Wallet
|
30
30
|
|
31
31
|
def initialize(rpc, wallet)
|
@@ -58,18 +58,17 @@ class Nanook
|
|
58
58
|
Nanook::WalletAccount.new(@rpc, @wallet, account)
|
59
59
|
end
|
60
60
|
|
61
|
-
#
|
61
|
+
# ==== Example:
|
62
62
|
#
|
63
|
-
#
|
63
|
+
# wallet.accounts # => [Nanook::WalletAccount, Nanook::WalletAccount...]
|
64
64
|
#
|
65
|
-
#
|
66
|
-
# "xrb_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000",
|
67
|
-
# "xrb_1e5aqegc1jb7qe964u4adzmcezyo6o146zb8hm6dft8tkp79za3sxwjym5rx"
|
68
|
-
# ]
|
65
|
+
# @return [Array<Nanook::WalletAccount>] all accounts in the wallet
|
69
66
|
def accounts
|
70
67
|
wallet_required!
|
71
68
|
response = rpc(:account_list)[:accounts]
|
72
|
-
Nanook::Util.coerce_empty_string_to_type(response, Array)
|
69
|
+
Nanook::Util.coerce_empty_string_to_type(response, Array).map do |account|
|
70
|
+
Nanook::WalletAccount.new(@rpc, @wallet, account)
|
71
|
+
end
|
73
72
|
end
|
74
73
|
|
75
74
|
# Returns a Hash containing the balance of all accounts in the
|
@@ -123,10 +122,10 @@ class Nanook
|
|
123
122
|
# "pending"=>0
|
124
123
|
# },
|
125
124
|
# }
|
126
|
-
def balance(account_break_down: false, unit: Nanook
|
125
|
+
def balance(account_break_down: false, unit: Nanook.default_unit)
|
127
126
|
wallet_required!
|
128
127
|
|
129
|
-
unless Nanook::
|
128
|
+
unless Nanook::UNITS.include?(unit)
|
130
129
|
raise ArgumentError.new("Unsupported unit: #{unit}")
|
131
130
|
end
|
132
131
|
|
@@ -149,31 +148,28 @@ class Nanook
|
|
149
148
|
end
|
150
149
|
end
|
151
150
|
|
152
|
-
#
|
153
|
-
#
|
154
|
-
# Nanook.new.wallet.create
|
151
|
+
# Changes a wallet's seed.
|
155
152
|
#
|
156
|
-
#
|
157
|
-
#
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
# wallet
|
153
|
+
# @param seed [String] the seed to change to.
|
154
|
+
# @return [Boolean] indicating whether the change was successful.
|
155
|
+
def change_seed(seed)
|
156
|
+
wallet_required!
|
157
|
+
rpc(:wallet_change_seed, seed: seed).has_key?(:success)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Creates a new wallet.
|
164
161
|
#
|
165
|
-
#
|
166
|
-
# you
|
167
|
-
#
|
168
|
-
# the seed over secure (SSH or SSL) networks and do not store it where
|
169
|
-
# it is able to be easily comprised by a hacker, which includes your
|
170
|
-
# personal computer.
|
162
|
+
# The wallet will be created only on this node. It's important that
|
163
|
+
# if you intend to add funds to accounts in this wallet that you
|
164
|
+
# backup the wallet *seed* in order to restore the wallet in future.
|
171
165
|
#
|
172
|
-
# ==== Example
|
166
|
+
# ==== Example:
|
167
|
+
# Nanook.new.wallet.create # => Nanook::Wallet
|
173
168
|
#
|
174
|
-
#
|
169
|
+
# @return [Nanook::Wallet]
|
175
170
|
def create
|
176
|
-
rpc(:wallet_create)[:wallet]
|
171
|
+
@wallet = rpc(:wallet_create)[:wallet]
|
172
|
+
self
|
177
173
|
end
|
178
174
|
|
179
175
|
# Destroy the wallet. Returns a boolean indicating whether the action
|
@@ -214,8 +210,9 @@ class Nanook
|
|
214
210
|
def id
|
215
211
|
@wallet
|
216
212
|
end
|
213
|
+
alias_method :seed, :id
|
217
214
|
|
218
|
-
def inspect
|
215
|
+
def inspect
|
219
216
|
"#{self.class.name}(id: \"#{id}\", object_id: \"#{"0x00%x" % (object_id << 1)}\")"
|
220
217
|
end
|
221
218
|
|
@@ -252,12 +249,94 @@ class Nanook
|
|
252
249
|
# Or:
|
253
250
|
#
|
254
251
|
# "Account not found"
|
255
|
-
def pay(from:, to:, amount:, unit: Nanook
|
252
|
+
def pay(from:, to:, amount:, unit: Nanook.default_unit, id:)
|
256
253
|
wallet_required!
|
257
254
|
validate_wallet_contains_account!(from)
|
258
255
|
account(from).pay(to: to, amount: amount, unit: unit, id: id)
|
259
256
|
end
|
260
257
|
|
258
|
+
# Returns information about pending blocks (payments) that are waiting
|
259
|
+
# to be received by accounts in this wallet.
|
260
|
+
#
|
261
|
+
# See also the #receive method of this class for how to receive a pending payment.
|
262
|
+
#
|
263
|
+
# @param limit [Integer] number of accounts with pending payments to return (default is 1000)
|
264
|
+
# @param detailed [Boolean]return a more complex Hash of pending block information (default is +false+)
|
265
|
+
# @param unit (see Nanook::Account#balance)
|
266
|
+
#
|
267
|
+
# ==== Example 1:
|
268
|
+
#
|
269
|
+
# wallet.pending
|
270
|
+
#
|
271
|
+
# ==== Example 1 response:
|
272
|
+
# {
|
273
|
+
# :xrb_1111111111111111111111111111111111111111111111111117353trpda=>[
|
274
|
+
# "142A538F36833D1CC78B94E11C766F75818F8B940771335C6C1B8AB880C5BB1D",
|
275
|
+
# "718CC2121C3E641059BC1C2CFC45666C99E8AE922F7A807B7D07B62C995D79E2"
|
276
|
+
# ],
|
277
|
+
# :xrb_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3=>[
|
278
|
+
# "4C1FEEF0BEA7F50BE35489A1233FE002B212DEA554B55B1B470D78BD8F210C74"
|
279
|
+
# ]
|
280
|
+
# }
|
281
|
+
# ==== Example 2:
|
282
|
+
#
|
283
|
+
# wallet.pending(detailed: true)
|
284
|
+
#
|
285
|
+
# ==== Example 2 response:
|
286
|
+
# {
|
287
|
+
# :xrb_1111111111111111111111111111111111111111111111111117353trpda=>[
|
288
|
+
# {
|
289
|
+
# :amount=>6.0,
|
290
|
+
# :source=>"xrb_3dcfozsmekr1tr9skf1oa5wbgmxt81qepfdnt7zicq5x3hk65fg4fqj58mbr",
|
291
|
+
# :block=>:"142A538F36833D1CC78B94E11C766F75818F8B940771335C6C1B8AB880C5BB1D"
|
292
|
+
# },
|
293
|
+
# {
|
294
|
+
# :amount=>12.0,
|
295
|
+
# :source=>"xrb_3dcfozsmekr1tr9skf1oa5wbgmxt81qepfdnt7zicq5x3hk65fg4fqj58mbr",
|
296
|
+
# :block=>:"242A538F36833D1CC78B94E11C766F75818F8B940771335C6C1B8AB880C5BB1D"
|
297
|
+
# }
|
298
|
+
# ],
|
299
|
+
# :xrb_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3=>[
|
300
|
+
# {
|
301
|
+
# :amount=>106.370018,
|
302
|
+
# :source=>"xrb_13ezf4od79h1tgj9aiu4djzcmmguendtjfuhwfukhuucboua8cpoihmh8byo",
|
303
|
+
# :block=>:"4C1FEEF0BEA7F50BE35489A1233FE002B212DEA554B55B1B470D78BD8F210C74"
|
304
|
+
# }
|
305
|
+
# ]
|
306
|
+
# }
|
307
|
+
def pending(limit:1000, detailed:false, unit:Nanook.default_unit)
|
308
|
+
wallet_required!
|
309
|
+
|
310
|
+
unless Nanook::UNITS.include?(unit)
|
311
|
+
raise ArgumentError.new("Unsupported unit: #{unit}")
|
312
|
+
end
|
313
|
+
|
314
|
+
params = { count: limit }
|
315
|
+
params[:source] = true if detailed
|
316
|
+
|
317
|
+
response = rpc(:wallet_pending, params)[:blocks]
|
318
|
+
response = Nanook::Util.coerce_empty_string_to_type(response, Hash)
|
319
|
+
|
320
|
+
return response unless detailed
|
321
|
+
|
322
|
+
# Map the RPC response, which is:
|
323
|
+
# account=>block=>[amount|source] into
|
324
|
+
# account=>[block|amount|source]
|
325
|
+
x = response.map do |account, data|
|
326
|
+
new_data = data.map do |block, amount_and_source|
|
327
|
+
d = amount_and_source.merge(block: block.to_s)
|
328
|
+
if unit == :nano
|
329
|
+
d[:amount] = Nanook::Util.raw_to_NANO(d[:amount])
|
330
|
+
end
|
331
|
+
d
|
332
|
+
end
|
333
|
+
|
334
|
+
[account, new_data]
|
335
|
+
end
|
336
|
+
|
337
|
+
Hash[x].to_symbolized_hash
|
338
|
+
end
|
339
|
+
|
261
340
|
# Receives a pending payment into an account in the wallet.
|
262
341
|
#
|
263
342
|
# When called with no +block+ argument, the latest pending payment
|
@@ -294,6 +373,33 @@ class Nanook
|
|
294
373
|
account(into).receive(block)
|
295
374
|
end
|
296
375
|
|
376
|
+
# Restore a previously created wallet by its seed.
|
377
|
+
# A new wallet will be created on your node (with a new wallet id)
|
378
|
+
# and will have its seed set to the given seed.
|
379
|
+
#
|
380
|
+
# ==== Example:
|
381
|
+
#
|
382
|
+
# Nanook.new.wallet.restore(seed) # => Nanook::Wallet
|
383
|
+
#
|
384
|
+
# @param seed [String] the wallet seed to restore.
|
385
|
+
# @param accounts [Integer] optionally restore the given number of accounts for the wallet.
|
386
|
+
#
|
387
|
+
# @return [Nanook::Wallet] a new wallet
|
388
|
+
# @raise [Nanook::Error] if unsuccessful
|
389
|
+
def restore(seed, accounts:0)
|
390
|
+
create
|
391
|
+
|
392
|
+
unless change_seed(seed)
|
393
|
+
raise Nanook::Error.new("Unable to set seed for wallet")
|
394
|
+
end
|
395
|
+
|
396
|
+
if accounts > 0
|
397
|
+
account.create(accounts)
|
398
|
+
end
|
399
|
+
|
400
|
+
self
|
401
|
+
end
|
402
|
+
|
297
403
|
# Returns a boolean to indicate if the wallet is locked.
|
298
404
|
#
|
299
405
|
# ==== Example response
|
@@ -305,23 +411,23 @@ class Nanook
|
|
305
411
|
!response.empty? && response[:locked] != 0
|
306
412
|
end
|
307
413
|
|
308
|
-
# Unlocks a previously locked wallet.
|
309
|
-
# if the action was successful.
|
414
|
+
# Unlocks a previously locked wallet.
|
310
415
|
#
|
311
|
-
# ==== Example
|
416
|
+
# ==== Example:
|
312
417
|
#
|
313
|
-
# true
|
418
|
+
# wallet.unlock("new_pass") #=> true
|
419
|
+
# @return [Boolean] indicates if the action was successful
|
314
420
|
def unlock(password)
|
315
421
|
wallet_required!
|
316
422
|
rpc(:password_enter, password: password)[:valid] == 1
|
317
423
|
end
|
318
424
|
|
319
|
-
# Changes the password for a wallet.
|
320
|
-
# if the action was successful.
|
425
|
+
# Changes the password for a wallet.
|
321
426
|
#
|
322
|
-
# ==== Example
|
427
|
+
# ==== Example:
|
323
428
|
#
|
324
|
-
# true
|
429
|
+
# wallet.change_password("new_pass") #=> true
|
430
|
+
# @return [Boolean] indicates if the action was successful
|
325
431
|
def change_password(password)
|
326
432
|
wallet_required!
|
327
433
|
rpc(:password_change, password: password)[:changed] == 1
|