nanook 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f71938ce617e3ee52fe2fb04cf9eebe97191f5d5
4
- data.tar.gz: 210a3c2b1ce7ad7b767c0139eaf5ae153c9e8fda
3
+ metadata.gz: e1c2a7e556469efac09a609f78e8f3a4e0533a89
4
+ data.tar.gz: 12d86898565f21e0c483c891be2b36f1c838216e
5
5
  SHA512:
6
- metadata.gz: 68baffb5984f1509bf4b1e6889b8c378906db8a41c070afc22902fb3369be03ee8b6db36dabb70befd79562f938380b74193a2007b033f6d2d25273871fbaa96
7
- data.tar.gz: a6610e8c5d616b48940d4c2837bd0cc6974d84d3b6c20418eb22543719740f353bd4c5c59ef86990dd8fe75b5c0b6c9e1386beb64b505a3784298a4fd77fa24c
6
+ metadata.gz: 47b9839217c59af70980fb20b1f8cefe716654170d15c908dc25f24bcba7ba34ef8b9bc5dc0b50912b447e6a779d022dbc264b2a469219c383fae754d8828843
7
+ data.tar.gz: 94d4e68c2a9a8debbd06c48b98e3b30d8ec2fac6d567e5c40dba50044c82cd894b11051b9b7df32ae818dbc830b1a27b2826b0a5267e959f415dd9e90c2069bb
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## 2.1.0
8
+
9
+ - Payment methods check the account id of the recipient is valid, raises ArgumentError if not.
10
+
7
11
  ## 2.0.0
8
12
 
9
13
  ### Added
data/README.md CHANGED
@@ -11,7 +11,7 @@ This is a Ruby library for managing a [nano currency](https://nano.org/) node, i
11
11
  Add this line to your application's Gemfile:
12
12
 
13
13
  ```ruby
14
- gem 'nanook', "~> 2.0"
14
+ gem 'nanook', "~> 2.1"
15
15
  ```
16
16
 
17
17
  And then execute:
@@ -120,7 +120,7 @@ wallet.receive(block_id, into: account_id)
120
120
 
121
121
  ## All commands
122
122
 
123
- Below is a quick reference list of commands. See the [full Nanook documentation](https://lukes.github.io/nanook/2.0.0/) for a searchable detailed description of every class and method, what the arguments mean, and example responses (Tip: expand the "**Nanook** < Object" item in the sidebar).
123
+ Below is a quick reference list of commands. See the [full Nanook documentation](https://lukes.github.io/nanook/2.0.0/) for a searchable detailed description of every class and method, what the arguments mean, and example responses (Tip: the classes are listed under the "**Nanook** < Object" item in the sidebar).
124
124
 
125
125
  ### Wallets
126
126
 
@@ -1,5 +1,6 @@
1
1
  require 'net/http'
2
2
  require 'uri'
3
+ require 'forwardable'
3
4
 
4
5
  Dir[File.dirname(__FILE__) + '/nanook/*.rb'].each {|file| require file }
5
6
 
@@ -133,20 +133,25 @@ class Nanook
133
133
 
134
134
  # Returns a Hash containing the account's balance.
135
135
  #
136
- # ==== Example response:
137
- # {
138
- # balance=>2, # Account balance
139
- # pending=>1.1 # Amount pending and not yet received by the account
140
- # }
136
+ # ==== Example:
137
+ #
138
+ # account.balance
139
+ #
140
+ # # =>
141
+ # # {
142
+ # # balance=>2, # Account balance
143
+ # # pending=>1.1 # Amount pending and not yet received by the account
144
+ # # }
141
145
  #
142
146
  # ==== Example balance returned in raw:
143
147
  #
144
148
  # account.balance(unit: :raw)
145
149
  #
146
- # {
147
- # balance: 2000000000000000000000000000000,
148
- # pending: 1100000000000000000000000000000
149
- # }
150
+ # # =>
151
+ # # {
152
+ # # balance: 2000000000000000000000000000000,
153
+ # # pending: 1100000000000000000000000000000
154
+ # # }
150
155
  #
151
156
  # @param unit [Symbol] default is {Nanook.default_unit}.
152
157
  # Must be one of {Nanook::UNITS}.
@@ -1,3 +1,3 @@
1
1
  class Nanook
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -207,32 +207,20 @@ class Nanook
207
207
  !response.empty? && response[:exists] == 1
208
208
  end
209
209
 
210
+ # @return [String]
210
211
  def id
211
212
  @wallet
212
213
  end
213
214
  alias_method :seed, :id
214
215
 
216
+ # @return [String]
215
217
  def inspect
216
218
  "#{self.class.name}(id: \"#{id}\", object_id: \"#{"0x00%x" % (object_id << 1)}\")"
217
219
  end
218
220
 
219
221
  # Make a payment from an account in your wallet to another account
220
- # on the nano network. Returns a <i>send</i> block hash if successful,
221
- # or an error String if unsuccessful.
222
- #
223
- # ==== Arguments
224
- #
225
- # [+from:+] String account id of an account in your wallet
226
- # [+to:+] String account id of the recipient of your payment
227
- # [+amount:+] Can be either an Integer or Float.
228
- # [+unit:+] Symbol (default is +:nano+). Represents the unit that +amount+ is in.
229
- # Must be either +:nano+ or +:raw+. (Note: this method
230
- # interprets +:nano+ as NANO, which is technically Mnano
231
- # See {What are Nano's Units}[https://nano.org/en/faq#what-are-nano-units-])
232
- # [+id:+] String. Must be unique per payment. It serves an important
233
- # purpose; it allows you to make the same call multiple
234
- # times with the same +id+ and be reassured that you will
235
- # only ever send that nano payment once.
222
+ # on the nano network. Returns a <i>send</i> block id
223
+ # if successful, or a {Nanook::Error} if unsuccessful.
236
224
  #
237
225
  # Note, there may be a delay in receiving a response due to Proof of Work being done. From the {Nano RPC}[https://github.com/nanocurrency/raiblocks/wiki/RPC-protocol#account-create]:
238
226
  #
@@ -240,15 +228,17 @@ class Nanook
240
228
  #
241
229
  # ==== Examples
242
230
  #
243
- # wallet.pay(from: "xrb_...", to: "xrb_...", amount: 1.1, id: "myUniqueId123")
244
- # wallet.pay(from: "xrb_...", to: "xrb_...", amount: 54000000000000, unit: :raw, id: "myUniqueId123")
231
+ # wallet.pay(from: "xrb_...", to: "xrb_...", amount: 1.1, id: "myUniqueId123") # => "9AE2311..."
232
+ # wallet.pay(from: "xrb_...", to: "xrb_...", amount: 54000000000000, unit: :raw, id: "myUniqueId123") # => "9AE2311..."
245
233
  #
246
- # ==== Example responses
247
- # "718CC2121C3E641059BC1C2CFC45666C99E8AE922F7A807B7D07B62C995D79E2"
248
- #
249
- # Or:
234
+ # ==== Arguments
250
235
  #
251
- # "Account not found"
236
+ # @param from [String] account id of an account in your wallet
237
+ # @param to (see Nanook::WalletAccount#pay)
238
+ # @param amount (see Nanook::WalletAccount#pay)
239
+ # @param unit (see Nanook::Account#balance)
240
+ # @params id (see Nanook::WalletAccount#pay)
241
+ # @return (see Nanook::WalletAccount#pay)
252
242
  def pay(from:, to:, amount:, unit: Nanook.default_unit, id:)
253
243
  wallet_required!
254
244
  validate_wallet_contains_account!(from)
@@ -342,31 +332,22 @@ class Nanook
342
332
  # When called with no +block+ argument, the latest pending payment
343
333
  # for the account will be received.
344
334
  #
345
- # Returns a <i>receive</i> block hash if a receive was successful,
346
- # or +false+ if there were no pending payments to receive.
335
+ # Returns a <i>receive</i> block hash
336
+ # if a receive was successful, or +false+ if there were no pending
337
+ # payments to receive.
347
338
  #
348
- # You can also receive a specific pending block if you know it by
339
+ # You can receive a specific pending block if you know it by
349
340
  # passing the block has in as an argument.
350
341
  #
351
- # ==== Arguments
352
- #
353
- # [+block+] Optional block hash of pending payment. If not provided,
354
- # the latest pending payment will be received
355
- # [+into:+] String account id of account in your wallet to receive the
356
- # payment into
357
- #
358
342
  # ==== Examples
359
343
  #
360
- # wallet.receive(into: "xrb...")
361
- # wallet.receive("718CC21...", into: "xrb...")
362
- #
363
- # ==== Example responses
364
- #
365
- # "718CC2121C3E641059BC1C2CFC45666C99E8AE922F7A807B7D07B62C995D79E2"
366
- #
367
- # Or:
344
+ # wallet.receive(into: "xrb...") # => "9AE2311..."
345
+ # wallet.receive("718CC21...", into: "xrb...") # => "9AE2311..."
368
346
  #
369
- # false
347
+ # @param block (see Nanook::WalletAccount#receive)
348
+ # @param into [String] account id of account in your wallet to receive the
349
+ # payment into
350
+ # @return (see Nanook::WalletAccount#receive)
370
351
  def receive(block=nil, into:)
371
352
  wallet_required!
372
353
  validate_wallet_contains_account!(into)
@@ -1,6 +1,33 @@
1
1
  class Nanook
2
2
  class WalletAccount
3
3
 
4
+ extend Forwardable
5
+ # @!method balance(unit: Nanook.default_unit)
6
+ # (see Nanook::Account#balance)
7
+ # @!method delegators
8
+ # (see Nanook::Account#delegators)
9
+ # @!method exists?
10
+ # (see Nanook::Account#exists?)
11
+ # @!method history(limit: 1000, unit: Nanook.default_unit)
12
+ # (see Nanook::Account#history)
13
+ # @!method id
14
+ # (see Nanook::Account#id)
15
+ # @!method info((detailed: false, unit: Nanook.default_unit)
16
+ # (see Nanook::Account#info)
17
+ # @!method last_modified_at
18
+ # (see Nanook::Account#last_modified_at)
19
+ # @!method ledger(limit: 1)
20
+ # (see Nanook::Account#ledger)
21
+ # @!method pending(limit: 1000, detailed: false, unit: Nanook.default_unit)
22
+ # (see Nanook::Account#pending)
23
+ # @!method public_key
24
+ # (see Nanook::Account#public_key)
25
+ # @!method representative
26
+ # (see Nanook::Account#representative)
27
+ # @!method weight
28
+ # (see Nanook::Account#weight)
29
+ def_delegators :@nanook_account_instance, :balance, :delegators, :exists?, :history, :id, :info, :last_modified_at, :ledger, :pending, :public_key, :representative, :weight
30
+
4
31
  def initialize(rpc, wallet, account)
5
32
  @rpc = rpc
6
33
  @wallet = wallet
@@ -20,26 +47,27 @@ class Nanook
20
47
  end
21
48
  end
22
49
 
50
+ # @return [String] the account id of this account
23
51
  def account_id
24
52
  @account
25
53
  end
26
54
 
27
- # Create a new account in this wallet.
55
+ # Creates a new account, or multiple new accounts, in this wallet.
28
56
  #
29
57
  # ==== Example:
30
58
  #
31
- # wallet.create # => Create 1 account, and return the {Nanook::WalletAccount}
32
- # wallet.create(2) # => Create 2 accounts, and return an Array of {Nanook::WalletAccount}
59
+ # wallet.create # => Creates 1 account, and return a {Nanook::WalletAccount}
60
+ # wallet.create(2) # => Creates 2 accounts, and return an Array of {Nanook::WalletAccount}
33
61
  #
34
- # @param n [Integer] number of accounts to create (default is 1)
62
+ # @param n [Integer] number of accounts to create
35
63
  #
36
- # @return [Nanook::WalletAccount] will return a single {Nanook::WalletAccount}
37
- # unless method was called with
38
- # @return [Array<Nanook::WalletAccount>] will return an Array of {Nanook::WalletAccount}
39
- # if method was called with
64
+ # @return [Nanook::WalletAccount] returns a single {Nanook::WalletAccount}
65
+ # if invoked with no argument
66
+ # @return [Array<Nanook::WalletAccount>] returns an Array of {Nanook::WalletAccount}
67
+ # if method was called with argument +n+ > 1
40
68
  def create(n=1)
41
69
  if n < 1
42
- raise ArgumentError.new("number of accounts must be greater than 1")
70
+ raise ArgumentError.new("number of accounts must be greater than 0")
43
71
  end
44
72
 
45
73
  if n == 1
@@ -51,24 +79,55 @@ class Nanook
51
79
  end
52
80
  end
53
81
 
82
+ # Unlinks the account from the wallet.
83
+ #
84
+ # Note, it's impossible to truly destroy an account. Calling this
85
+ # method on a wallet causes the wallet to "forget" the account.
86
+ #
87
+ # @return [Boolean] returns true if action was successful, otherwise +false+
54
88
  def destroy
55
89
  rpc(:account_remove)[:removed] == 1
56
90
  end
57
91
 
92
+ # @return [String]
58
93
  def inspect
59
94
  "#{self.class.name}(wallet_id: #{wallet_id}, account_id: #{account_id}, object_id: \"#{"0x00%x" % (object_id << 1)}\")"
60
95
  end
61
96
 
97
+ # Make a payment from an account in this wallet to another account
98
+ # on the nano network. Returns a <i>send</i> block hash
99
+ # if successful, or a {Nanook::Error} if unsuccessful.
100
+ #
101
+ # Note, there may be a delay in receiving a response due to Proof of Work being done. From the {Nano RPC}[https://github.com/nanocurrency/raiblocks/wiki/RPC-protocol#account-create]:
102
+ #
103
+ # <i>Proof of Work is precomputed for one transaction in the background. If it has been a while since your last transaction it will send instantly, the next one will need to wait for Proof of Work to be generated.</i>
104
+ #
105
+ # ==== Examples:
106
+ #
107
+ # account.pay(to: "xrb_...", amount: 1.1, id: "myUniqueId123") # => "9AE2311..."
108
+ # account.pay(to: "xrb_...", amount: 54000000000000, unit: :raw, id: "myUniqueId123") # => "9AE2311..."
109
+ #
110
+ # @param to [String] account id of the recipient of your payment
111
+ # @param amount [Integer|Float]
112
+ # @param unit (see Nanook::Account#balance)
113
+ # @param id [String] must be unique per payment. It serves an important
114
+ # purpose; it allows you to make the same call multiple times with
115
+ # the same +id+ and be reassured that you will only ever send this
116
+ # nano payment once
117
+ # @return [String] the send block id for the payment
118
+ # @raise [Nanook::Error] if unsuccesful
62
119
  def pay(to:, amount:, unit: Nanook::default_unit, id:)
63
120
  unless Nanook::UNITS.include?(unit)
64
121
  raise ArgumentError.new("Unsupported unit: #{unit}")
65
122
  end
66
123
 
67
- # Check that to: account is valid
68
- unless Nanook::Account.new(@rpc, to).exists?
69
- raise ArgumentError.new("To account does not exist (#{to})")
124
+ # Check that to account is a valid address
125
+ response = @rpc.call(:validate_account_number, account: to)
126
+ unless response[:valid] == 1
127
+ raise ArgumentError.new("Account address is invalid: #{to}")
70
128
  end
71
129
 
130
+ # Determin amount in raw
72
131
  raw = if unit.to_sym.eql?(:nano)
73
132
  Nanook::Util.NANO_to_raw(amount)
74
133
  else
@@ -87,13 +146,33 @@ class Nanook
87
146
  response = @rpc.call(:send, p)
88
147
 
89
148
  if response.has_key?(:error)
90
- return response[:error]
149
+ return Nanook::Error.new(response[:error])
91
150
  end
92
151
 
93
152
  response[:block]
94
153
  end
95
154
 
96
- # Returns false if no block to receive
155
+ # Receives a pending payment for this account.
156
+ #
157
+ # When called with no +block+ argument, the latest pending payment
158
+ # for the account will be received.
159
+ #
160
+ # Returns a <i>receive</i> block id
161
+ # if a receive was successful, or +false+ if there were no pending
162
+ # payments to receive.
163
+ #
164
+ # You can receive a specific pending block if you know it by
165
+ # passing the block has in as an argument.
166
+ #
167
+ # ==== Examples
168
+ #
169
+ # account.receive # => "9AE2311..."
170
+ # account.receive("718CC21...") # => "9AE2311..."
171
+ #
172
+ # @param block [String] optional block id of pending payment. If
173
+ # not provided, the latest pending payment will be received
174
+ # @return [String] the receive block id
175
+ # @return [false] if no block to receive
97
176
  def receive(block=nil)
98
177
  if block.nil?
99
178
  _receive_without_block
@@ -139,15 +218,6 @@ class Nanook
139
218
  @wallet
140
219
  end
141
220
 
142
- # Any method of Nanook::Account can be called on this class too
143
- def method_missing(m, *args, &block)
144
- if @nanook_account_instance.respond_to?(m)
145
- @nanook_account_instance.send(m, *args, &block)
146
- else
147
- super(m, *args, &block)
148
- end
149
- end
150
-
151
221
  private
152
222
 
153
223
  def _receive_without_block
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nanook
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luke Duncalfe
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-30 00:00:00.000000000 Z
11
+ date: 2018-04-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler