nanook 2.2.0 → 3.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 +5 -5
- data/CHANGELOG.md +145 -3
- data/README.md +157 -90
- data/bin/console +4 -3
- data/lib/nanook.rb +77 -21
- data/lib/nanook/account.rb +236 -168
- data/lib/nanook/block.rb +363 -119
- data/lib/nanook/errors.rb +10 -0
- data/lib/nanook/node.rb +229 -66
- data/lib/nanook/private_key.rb +115 -0
- data/lib/nanook/public_key.rb +55 -0
- data/lib/nanook/rpc.rb +104 -44
- data/lib/nanook/util.rb +68 -19
- data/lib/nanook/version.rb +3 -1
- data/lib/nanook/wallet.rb +413 -120
- data/lib/nanook/wallet_account.rb +154 -91
- data/lib/nanook/work_peer.rb +14 -7
- metadata +29 -28
- data/lib/nanook/error.rb +0 -5
- data/lib/nanook/key.rb +0 -46
data/lib/nanook/block.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'util'
|
2
4
|
|
5
|
+
class Nanook
|
3
6
|
# The <tt>Nanook::Block</tt> class contains methods to discover
|
4
7
|
# publicly-available information about blocks on the nano network.
|
5
8
|
#
|
@@ -17,21 +20,38 @@ class Nanook
|
|
17
20
|
# rpc_conn = Nanook::Rpc.new
|
18
21
|
# block = Nanook::Block.new(rpc_conn, "FBF8B0E...")
|
19
22
|
class Block
|
23
|
+
include Nanook::Util
|
20
24
|
|
21
25
|
def initialize(rpc, block)
|
22
26
|
@rpc = rpc
|
23
|
-
@block = block
|
24
|
-
block_required! # All methods expect a block
|
27
|
+
@block = block.to_s
|
25
28
|
end
|
26
29
|
|
27
|
-
# Returns the
|
30
|
+
# Returns the block hash id.
|
28
31
|
#
|
29
32
|
# ==== Example:
|
30
|
-
# block.account # => Nanook::Account
|
31
33
|
#
|
32
|
-
#
|
33
|
-
|
34
|
-
|
34
|
+
# block.id #=> "FBF8B0E..."
|
35
|
+
#
|
36
|
+
# @return [String] the block hash id
|
37
|
+
def id
|
38
|
+
@block
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param other [Nanook::Block] block to compare
|
42
|
+
# @return [Boolean] true if blocks are equal
|
43
|
+
def ==(other)
|
44
|
+
other.class == self.class &&
|
45
|
+
other.id == id
|
46
|
+
end
|
47
|
+
alias eql? ==
|
48
|
+
|
49
|
+
# The hash value is used along with #eql? by the Hash class to determine if two objects
|
50
|
+
# reference the same hash key.
|
51
|
+
#
|
52
|
+
# @return [Integer]
|
53
|
+
def hash
|
54
|
+
id.hash
|
35
55
|
end
|
36
56
|
|
37
57
|
# Stop generating work for a block.
|
@@ -45,8 +65,11 @@ class Nanook
|
|
45
65
|
rpc(:work_cancel, :hash).empty?
|
46
66
|
end
|
47
67
|
|
48
|
-
# Returns
|
49
|
-
#
|
68
|
+
# Returns a consecutive list of block hashes in the account chain
|
69
|
+
# starting at block back to count (direction from frontier back to
|
70
|
+
# open block, from newer blocks to older). Will list all blocks back
|
71
|
+
# to the open block of this chain when count is set to "-1".
|
72
|
+
# The requested block hash is included in the answer.
|
50
73
|
#
|
51
74
|
# See also #successors.
|
52
75
|
#
|
@@ -56,59 +79,48 @@ class Nanook
|
|
56
79
|
#
|
57
80
|
# ==== Example reponse:
|
58
81
|
#
|
59
|
-
# [
|
60
|
-
#
|
61
|
-
# "FBF8B0E6623A31AB528EBD839EEAA91CAFD25C12294C46754E45FD017F7939EB"
|
62
|
-
# ]
|
82
|
+
# [Nanook::Block, ...]
|
83
|
+
#
|
63
84
|
# @param limit [Integer] maximum number of block hashes to return (default is 1000)
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
85
|
+
# @param offset [Integer] return the account chain block hashes offset by the specified number of blocks (default is 0)
|
86
|
+
def chain(limit: 1000, offset: 0)
|
87
|
+
params = {
|
88
|
+
count: limit,
|
89
|
+
offset: offset,
|
90
|
+
_access: :blocks,
|
91
|
+
_coerce: Array
|
92
|
+
}
|
68
93
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
# block.generate_work # => "2bf29ef00786a6bc"
|
73
|
-
#
|
74
|
-
# @return [String] the work id of the work completed.
|
75
|
-
def generate_work
|
76
|
-
rpc(:work_generate, :hash)[:work]
|
94
|
+
rpc(:chain, :block, params).map do |block|
|
95
|
+
as_block(block)
|
96
|
+
end
|
77
97
|
end
|
98
|
+
alias ancestors chain
|
78
99
|
|
79
|
-
#
|
80
|
-
#
|
100
|
+
# Request confirmation for a block from online representative nodes.
|
101
|
+
# Will return immediately with a boolean to indicate if the request for
|
102
|
+
# confirmation was successful. Note that this boolean does not indicate
|
103
|
+
# the confirmation status of the block.
|
81
104
|
#
|
82
105
|
# ==== Example:
|
106
|
+
# block.confirm # => true
|
83
107
|
#
|
84
|
-
#
|
85
|
-
|
86
|
-
|
87
|
-
#
|
88
|
-
# [
|
89
|
-
# {
|
90
|
-
# :account=>"xrb_3x7cjioqahgs5ppheys6prpqtb4rdknked83chf97bot1unrbdkaux37t31b",
|
91
|
-
# :amount=>539834279601145558517940224,
|
92
|
-
# :hash=>"36A0FB717368BA8CF8D255B63DC207771EABC6C6FFC22A7F455EC2209464897E",
|
93
|
-
# :type=>"send"
|
94
|
-
# }
|
95
|
-
# ]
|
96
|
-
#
|
97
|
-
# @param limit [Integer] maximum number of send/receive block hashes
|
98
|
-
# to return in the chain (default is 1000)
|
99
|
-
def history(limit: 1000)
|
100
|
-
rpc(:history, :hash, count: limit)[:history]
|
108
|
+
# @return [Boolean] if the confirmation request was sent successful
|
109
|
+
def confirm
|
110
|
+
rpc(:block_confirm, :hash, _access: :started) == 1
|
101
111
|
end
|
102
112
|
|
103
|
-
#
|
113
|
+
# Generate work for a block.
|
104
114
|
#
|
105
115
|
# ==== Example:
|
116
|
+
# block.generate_work # => "2bf29ef00786a6bc"
|
106
117
|
#
|
107
|
-
#
|
108
|
-
#
|
109
|
-
#
|
110
|
-
|
111
|
-
|
118
|
+
# @param use_peers [Boolean] if set to +true+, then the node will query
|
119
|
+
# its work peers (if it has any, see {Nanook::WorkPeer#list}).
|
120
|
+
# When +false+, the node will only generate work locally (default is +false+)
|
121
|
+
# @return [String] the work id of the work completed.
|
122
|
+
def generate_work(use_peers: false)
|
123
|
+
rpc(:work_generate, :hash, use_peers: use_peers, _access: :work)
|
112
124
|
end
|
113
125
|
|
114
126
|
# Returns a Hash of information about the block.
|
@@ -121,65 +133,84 @@ class Nanook
|
|
121
133
|
# ==== Example response:
|
122
134
|
#
|
123
135
|
# {
|
124
|
-
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
#
|
128
|
-
#
|
129
|
-
#
|
130
|
-
# :
|
136
|
+
# "account": Nanook::Account,
|
137
|
+
# "amount": 34.2,
|
138
|
+
# "balance": 2.3
|
139
|
+
# "height": 58,
|
140
|
+
# "local_timestamp": Time,
|
141
|
+
# "confirmed": true,
|
142
|
+
# "type": "send",
|
143
|
+
# "account": Nanook::Account,
|
144
|
+
# "previous": Nanook::Block,
|
145
|
+
# "representative": Nanook::Account,
|
146
|
+
# "link": Nanook::Block,
|
147
|
+
# "link_as_account": Nanook::Account,
|
148
|
+
# "signature": "82D41BC16F313E4B2243D14DFFA2FB04679C540C2095FEE7EAE0F2F26880AD56DD48D87A7CC5DD760C5B2D76EE2C205506AA557BF00B60D8DEE312EC7343A501",
|
149
|
+
# "work": "8a142e07a10996d5"
|
131
150
|
# }
|
132
151
|
#
|
133
152
|
# @param allow_unchecked [Boolean] (default is +false+). If +true+,
|
134
153
|
# information can be returned about blocks that are unchecked (unverified).
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
154
|
+
# @raise [Nanook::NanoUnitError] if `unit` is invalid
|
155
|
+
# @raise [Nanook::NodeRpcError] if block is not found on the node.
|
156
|
+
def info(allow_unchecked: false, unit: Nanook.default_unit)
|
157
|
+
validate_unit!(unit)
|
158
|
+
|
159
|
+
# Params for both `unchecked_get` and `block_info` calls
|
160
|
+
params = {
|
161
|
+
json_block: true,
|
162
|
+
_coerce: Hash
|
163
|
+
}
|
164
|
+
|
165
|
+
begin
|
166
|
+
response = rpc(:block_info, :hash, params)
|
167
|
+
response.merge!(confirmed: true)
|
168
|
+
rescue Nanook::NodeRpcError => e
|
169
|
+
raise e unless allow_unchecked
|
170
|
+
|
171
|
+
response = rpc(:unchecked_get, :hash, params)
|
172
|
+
response.merge!(confirmed: false)
|
142
173
|
end
|
143
174
|
|
144
|
-
response
|
145
|
-
_parse_info_response(response)
|
175
|
+
parse_info_response(response, unit)
|
146
176
|
end
|
147
177
|
|
148
178
|
# ==== Example:
|
149
179
|
#
|
150
|
-
# block.
|
180
|
+
# block.valid_work?("2bf29ef00786a6bc") # => true
|
151
181
|
#
|
152
182
|
# @param work [String] the work id to check is valid
|
153
183
|
# @return [Boolean] signalling if work is valid for the block
|
154
|
-
def
|
184
|
+
def valid_work?(work)
|
155
185
|
response = rpc(:work_validate, :hash, work: work)
|
156
|
-
|
186
|
+
response[:valid_all] == 1 || response[:valid_receive] == 1
|
157
187
|
end
|
158
188
|
|
159
189
|
# Republish blocks starting at this block up the account chain
|
160
190
|
# back to the nano network.
|
161
191
|
#
|
162
|
-
# @return [Array<
|
192
|
+
# @return [Array<Nanook::Block>] blocks that were republished
|
163
193
|
#
|
164
194
|
# ==== Example:
|
165
195
|
#
|
166
|
-
# block.republish
|
167
|
-
|
168
|
-
# ==== Example response:
|
169
|
-
#
|
170
|
-
# ["36A0FB717368BA8CF8D255B63DC207771EABC6C6FFC22A7F455EC2209464897E"]
|
171
|
-
def republish(destinations:nil, sources:nil)
|
196
|
+
# block.republish # => [Nanook::Block, ...]
|
197
|
+
def republish(destinations: nil, sources: nil)
|
172
198
|
if !destinations.nil? && !sources.nil?
|
173
|
-
raise ArgumentError
|
199
|
+
raise ArgumentError, 'You must provide either destinations or sources but not both'
|
174
200
|
end
|
175
201
|
|
176
|
-
|
177
|
-
|
202
|
+
params = {
|
203
|
+
_access: :blocks,
|
204
|
+
_coerce: Array
|
205
|
+
}
|
206
|
+
|
178
207
|
params[:destinations] = destinations unless destinations.nil?
|
179
208
|
params[:sources] = sources unless sources.nil?
|
180
|
-
params[:count] = 1
|
209
|
+
params[:count] = 1 if destinations || sources
|
181
210
|
|
182
|
-
rpc(:republish, :hash, params)
|
211
|
+
rpc(:republish, :hash, params).map do |block|
|
212
|
+
as_block(block)
|
213
|
+
end
|
183
214
|
end
|
184
215
|
|
185
216
|
# ==== Example:
|
@@ -188,74 +219,287 @@ class Nanook
|
|
188
219
|
#
|
189
220
|
# @return [Boolean] signalling if the block is a pending block.
|
190
221
|
def pending?
|
191
|
-
|
192
|
-
!response.empty? && response[:exists] == 1
|
222
|
+
rpc(:pending_exists, :hash, _access: :exists) == 1
|
193
223
|
end
|
194
224
|
|
195
|
-
#
|
225
|
+
# Returns an Array of block hashes in the account chain ending at
|
226
|
+
# this block.
|
196
227
|
#
|
197
|
-
#
|
228
|
+
# See also #chain.
|
198
229
|
#
|
199
|
-
# ====
|
230
|
+
# ==== Example:
|
200
231
|
#
|
201
|
-
# block.
|
232
|
+
# block.successors # => [Nanook::Block, .. ]
|
202
233
|
#
|
203
|
-
# @
|
204
|
-
|
205
|
-
|
234
|
+
# @param limit [Integer] maximum number of send/receive block hashes
|
235
|
+
# to return in the chain (default is 1000)
|
236
|
+
# @param offset [Integer] return the account chain block hashes offset
|
237
|
+
# by the specified number of blocks (default is 0)
|
238
|
+
# @return [Array<Nanook::Block>] blocks in the account chain ending at this block
|
239
|
+
def successors(limit: 1000, offset: 0)
|
240
|
+
params = {
|
241
|
+
count: limit,
|
242
|
+
offset: offset,
|
243
|
+
_access: :blocks,
|
244
|
+
_coerce: Array
|
245
|
+
}
|
246
|
+
|
247
|
+
rpc(:successors, :block, params).map do |block|
|
248
|
+
as_block(block)
|
249
|
+
end
|
206
250
|
end
|
207
|
-
alias_method :process, :publish
|
208
251
|
|
209
|
-
# Returns
|
210
|
-
# this block.
|
252
|
+
# Returns the {Nanook::Account} of the block representative.
|
211
253
|
#
|
212
|
-
#
|
254
|
+
# ==== Example:
|
255
|
+
# block.representative # => Nanook::Account
|
256
|
+
#
|
257
|
+
# @return [Nanook::Account] representative account of the block. Can be nil.
|
258
|
+
def representative
|
259
|
+
memoized_info[:representative]
|
260
|
+
end
|
261
|
+
|
262
|
+
# Returns the {Nanook::Account} of the block.
|
213
263
|
#
|
214
264
|
# ==== Example:
|
265
|
+
# block.account # => Nanook::Account
|
266
|
+
#
|
267
|
+
# @return [Nanook::Account] the account of the block. Can be nil.
|
268
|
+
def account
|
269
|
+
memoized_info[:account]
|
270
|
+
end
|
271
|
+
|
272
|
+
# Returns the amount of the block.
|
215
273
|
#
|
216
|
-
#
|
274
|
+
# ==== Example:
|
275
|
+
# block.amount # => 3.01
|
217
276
|
#
|
218
|
-
#
|
277
|
+
# @param unit (see Nanook::Account#balance)
|
278
|
+
# @raise [Nanook::NanoUnitError] if `unit` is invalid
|
279
|
+
# @return [Float]
|
280
|
+
def amount(unit: Nanook.default_unit)
|
281
|
+
validate_unit!(unit)
|
282
|
+
|
283
|
+
amount = memoized_info[:amount]
|
284
|
+
return amount unless unit == :nano
|
285
|
+
|
286
|
+
raw_to_NANO(amount)
|
287
|
+
end
|
288
|
+
|
289
|
+
# Returns the balance of the account at the time the block was created.
|
219
290
|
#
|
220
|
-
#
|
291
|
+
# ==== Example:
|
292
|
+
# block.balance # => 3.01
|
221
293
|
#
|
222
|
-
# @param
|
223
|
-
#
|
224
|
-
# @return [
|
225
|
-
def
|
226
|
-
|
227
|
-
|
294
|
+
# @param unit (see Nanook::Account#balance)
|
295
|
+
# @raise [Nanook::NanoUnitError] if `unit` is invalid
|
296
|
+
# @return [Float]
|
297
|
+
def balance(unit: Nanook.default_unit)
|
298
|
+
validate_unit!(unit)
|
299
|
+
|
300
|
+
balance = memoized_info[:balance]
|
301
|
+
return balance unless unit == :nano
|
302
|
+
|
303
|
+
raw_to_NANO(balance)
|
304
|
+
end
|
305
|
+
|
306
|
+
# Returns true if block is confirmed.
|
307
|
+
#
|
308
|
+
# ==== Example:
|
309
|
+
# block.confirmed # => true
|
310
|
+
#
|
311
|
+
# @return [Boolean]
|
312
|
+
def confirmed?
|
313
|
+
memoized_info[:confirmed]
|
314
|
+
end
|
315
|
+
alias checked? confirmed?
|
316
|
+
|
317
|
+
# Returns true if block is unconfirmed.
|
318
|
+
#
|
319
|
+
# ==== Example:
|
320
|
+
# block.unconfirmed? # => true
|
321
|
+
#
|
322
|
+
# @return [Boolean]
|
323
|
+
def unconfirmed?
|
324
|
+
!confirmed?
|
325
|
+
end
|
326
|
+
alias unchecked? unconfirmed?
|
327
|
+
|
328
|
+
# Returns true if block exists in the node's ledger. This will return
|
329
|
+
# false for blocks that exist on the nano ledger but have not yet
|
330
|
+
# synchronized to the node.
|
331
|
+
#
|
332
|
+
# ==== Example:
|
333
|
+
#
|
334
|
+
# block.exists? # => false
|
335
|
+
# block.exists?(allow_unchecked: true) # => true
|
336
|
+
#
|
337
|
+
# @param allow_unchecked [Boolean] defaults to +false+
|
338
|
+
# @return [Boolean]
|
339
|
+
def exists?(allow_unchecked: false)
|
340
|
+
begin
|
341
|
+
allow_unchecked ? memoized_info : info
|
342
|
+
rescue Nanook::NodeRpcError
|
343
|
+
return false
|
344
|
+
end
|
345
|
+
|
346
|
+
true
|
347
|
+
end
|
348
|
+
|
349
|
+
# Returns the height of the block.
|
350
|
+
#
|
351
|
+
# ==== Example:
|
352
|
+
# block.height # => 5
|
353
|
+
#
|
354
|
+
# @return [Integer]
|
355
|
+
def height
|
356
|
+
memoized_info[:height]
|
357
|
+
end
|
358
|
+
|
359
|
+
# Returns the block work.
|
360
|
+
#
|
361
|
+
# ==== Example:
|
362
|
+
# block.work # => "8a142e07a10996d5"
|
363
|
+
#
|
364
|
+
# @return [String]
|
365
|
+
def work
|
366
|
+
memoized_info[:work]
|
367
|
+
end
|
368
|
+
|
369
|
+
# Returns the block signature.
|
370
|
+
#
|
371
|
+
# ==== Example:
|
372
|
+
# block.signature # => "82D41BC16F313E4B2243D14DFFA2FB04679C540C2095FEE7EAE0F2F26880AD56DD48D87A7CC5DD760C5B2D76EE2C205506AA557BF00B60D8DEE312EC7343A501"
|
373
|
+
#
|
374
|
+
# @return [String]
|
375
|
+
def signature
|
376
|
+
memoized_info[:signature]
|
377
|
+
end
|
378
|
+
|
379
|
+
# Returns the timestamp of when the node saw the block.
|
380
|
+
#
|
381
|
+
# ==== Example:
|
382
|
+
# block.timestamp # => 2018-05-30 16:41:48 UTC
|
383
|
+
#
|
384
|
+
# @return [Time] Time in UTC of when the node saw the block. Can be nil.
|
385
|
+
def timestamp
|
386
|
+
memoized_info[:local_timestamp]
|
228
387
|
end
|
229
388
|
|
230
|
-
|
231
|
-
|
389
|
+
# Returns the {Nanook::Block} of the previous block in the chain.
|
390
|
+
#
|
391
|
+
# ==== Example:
|
392
|
+
# block.previous # => Nanook::Block
|
393
|
+
#
|
394
|
+
# @return [Nanook::Block] previous block in the chain. Can be nil.
|
395
|
+
def previous
|
396
|
+
memoized_info[:previous]
|
397
|
+
end
|
398
|
+
|
399
|
+
# Returns the type of the block. One of "open", "send", "receive", "change", "epoch".
|
400
|
+
#
|
401
|
+
# ==== Example:
|
402
|
+
# block.type # => "open"
|
403
|
+
#
|
404
|
+
# @return [String] type of block. Returns nil for unconfirmed blocks.
|
405
|
+
def type
|
406
|
+
memoized_info[:type]
|
407
|
+
end
|
408
|
+
|
409
|
+
# Returns true if block is type "send".
|
410
|
+
#
|
411
|
+
# ==== Example:
|
412
|
+
# block.send? # => true
|
413
|
+
#
|
414
|
+
# @return [Boolean]
|
415
|
+
def send?
|
416
|
+
type == 'send'
|
417
|
+
end
|
418
|
+
|
419
|
+
# Returns true if block is type "open".
|
420
|
+
#
|
421
|
+
# ==== Example:
|
422
|
+
# block.open? # => true
|
423
|
+
#
|
424
|
+
# @return [Boolean]
|
425
|
+
def open?
|
426
|
+
type == 'open'
|
427
|
+
end
|
428
|
+
|
429
|
+
# Returns true if block is type "receive".
|
430
|
+
#
|
431
|
+
# ==== Example:
|
432
|
+
# block.receive? # => true
|
433
|
+
#
|
434
|
+
# @return [Boolean]
|
435
|
+
def receive?
|
436
|
+
type == 'receive'
|
437
|
+
end
|
438
|
+
|
439
|
+
# Returns true if block is type "change" (change of representative).
|
440
|
+
#
|
441
|
+
# ==== Example:
|
442
|
+
# block.change? # => true
|
443
|
+
#
|
444
|
+
# @return [Boolean]
|
445
|
+
def change?
|
446
|
+
type == 'change'
|
447
|
+
end
|
448
|
+
|
449
|
+
# Returns true if block is type "epoch".
|
450
|
+
#
|
451
|
+
# ==== Example:
|
452
|
+
# block.epoch? # => true
|
453
|
+
#
|
454
|
+
# @return [Boolean]
|
455
|
+
def epoch?
|
456
|
+
type == 'epoch'
|
457
|
+
end
|
458
|
+
|
459
|
+
# @return [String]
|
460
|
+
def to_s
|
461
|
+
"#{self.class.name}(id: \"#{short_id}\")"
|
232
462
|
end
|
463
|
+
alias inspect to_s
|
233
464
|
|
234
465
|
private
|
235
466
|
|
236
467
|
# Some RPC calls expect the param that represents the block to be named
|
237
468
|
# "hash", and others "block".
|
238
469
|
# The param_name argument allows us to specify which it should be for this call.
|
239
|
-
def rpc(action, param_name, params={})
|
240
|
-
p =
|
470
|
+
def rpc(action, param_name, params = {})
|
471
|
+
p = { param_name.to_sym => @block }
|
241
472
|
@rpc.call(action, p.merge(params))
|
242
473
|
end
|
243
474
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
end
|
475
|
+
# Memoize the `#info` response as we can refer to it for other methods (`type`, `#open?`, `#send?` etc.)
|
476
|
+
def memoized_info
|
477
|
+
@memoized_info ||= info(allow_unchecked: true, unit: :raw)
|
248
478
|
end
|
249
479
|
|
250
|
-
def
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
480
|
+
def parse_info_response(response, unit)
|
481
|
+
response.merge!(id: id)
|
482
|
+
contents = response.delete(:contents)
|
483
|
+
response.merge!(contents) if contents
|
484
|
+
|
485
|
+
response.delete(:block_account) # duplicate of contents.account
|
486
|
+
response[:type] = response.delete(:subtype) # rename key
|
487
|
+
response[:last_modified_at] = response.delete(:modified_timestamp) # rename key
|
488
|
+
|
489
|
+
response[:account] = as_account(response[:account]) if response[:account]
|
490
|
+
response[:representative] = as_account(response[:representative]) if response[:representative]
|
491
|
+
response[:previous] = as_block(response[:previous]) if response[:previous]
|
492
|
+
response[:link] = as_block(response[:link]) if response[:link]
|
493
|
+
response[:link_as_account] = as_account(response[:link_as_account]) if response[:link_as_account]
|
494
|
+
response[:local_timestamp] = as_time(response[:local_timestamp])
|
495
|
+
response[:last_modified_at] = as_time(response[:last_modified_at])
|
496
|
+
|
497
|
+
if unit == :nano
|
498
|
+
response[:amount] = raw_to_NANO(response[:amount])
|
499
|
+
response[:balance] = raw_to_NANO(response[:balance])
|
255
500
|
end
|
256
501
|
|
257
|
-
response
|
502
|
+
response.compact
|
258
503
|
end
|
259
|
-
|
260
504
|
end
|
261
505
|
end
|