Class: Nanook::Wallet

Inherits:
Object
  • Object
show all
Defined in:
lib/nanook/wallet.rb

Overview

The Nanook::Wallet class lets you manage your nano wallets, as well as some account-specific things like making and receiving payments.

Your wallets each have a seed, which is a 32-byte uppercase hex string that looks like this:

000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F

You can think of this string as your API key to the nano network. The person who knows it can do all read and write actions against the wallet and all accounts inside the wallet from anywhere on the nano network, not just on the node you created the wallet on. Make sure this key is always secret and safe. Do not commit your seed into source control.

Initializing

Initialize this class through the convenient Nanook#wallet method:

nanook = Nanook.new
wallet = nanook.wallet(wallet_seed)

Or compose the longhand way like this:

rpc_conn = Nanook::Rpc.new
wallet = Nanook::Wallet.new(rpc_conn, wallet_seed)

Instance Method Summary collapse

Constructor Details

#initialize(rpc, wallet) ⇒ Wallet

Returns a new instance of Wallet.



31
32
33
34
# File 'lib/nanook/wallet.rb', line 31

def initialize(rpc, wallet)
  @rpc = rpc
  @wallet = wallet
end

Instance Method Details

#account(account = nil) ⇒ Object

A convenient method that returns an account in your wallet, allowing you to perform all the actions in Nanook::WalletAccount on it.

wallet.("xrb_...") #=> Nanook::WalletAccount instance

See Nanook::WalletAccount.

Will throw an ArgumentError if the wallet does not contain the account.

Arguments

account

Optional String of an account (starting with "xrb...") to start working with. Must be an account within the wallet. When no account is given, the instance returned only allows you to call create on it, to create a new account. Otherwise, you must pass an account string for all other methods.

Examples

wallet..create      # Creates an account in the wallet and returns a Nanook::WalletAccount
wallet.() # Returns a Nanook::WalletAccount for the account


57
58
59
# File 'lib/nanook/wallet.rb', line 57

def (=nil)
  Nanook::WalletAccount.new(@rpc, @wallet, )
end

#accountsObject

Returns an Array with Strings of all account ids in the wallet.

Example response

[
  "xrb_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000",
  "xrb_1e5aqegc1jb7qe964u4adzmcezyo6o146zb8hm6dft8tkp79za3sxwjym5rx"
]


69
70
71
72
73
# File 'lib/nanook/wallet.rb', line 69

def accounts
  wallet_required!
  response = rpc(:account_list)[:accounts]
  Nanook::Util.coerce_empty_string_to_type(response, Array)
end

#balance(account_break_down: false, unit: Nanook::WalletAccount::DEFAULT_UNIT) ⇒ Object

Returns a Hash containing the balance of all accounts in the wallet, optionally breaking the balances down by account.

Arguments

account_break_down:

Boolean (default is false). When true the response will contain balances per account.

unit:

Symbol (default is :nano) Represents the unit that the balances will be returned in. Must be either :nano or :raw. (Note: this method interprets :nano as NANO, which is technically Mnano See What are Nano’s Units)

Examples

wallet.balance

Example response:

{
  "balance"=>5,
  "pending"=>0.001
}

Asking for the balances to be returned in raw instead of NANO.

wallet.balance(unit: :raw)

Example response:

{
  "balance"=>5000000000000000000000000000000,
  "pending"=>1000000000000000000000000000
}

Asking for totals to be broken down by account:

wallet.balance(account_break_down: true)

Example response:

{
  "xrb_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000"=>{
    "balance"=>2.5,
    "pending"=>1
  },
  "xrb_1e5aqegc1jb7qe964u4adzmcezyo6o146zb8hm6dft8tkp79za3sxwjym5rx"=>{
    "balance"=>51.4,
    "pending"=>0
  },
}


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/nanook/wallet.rb', line 126

def balance(account_break_down: false, unit: Nanook::WalletAccount::DEFAULT_UNIT)
  wallet_required!

  unless Nanook::WalletAccount::UNITS.include?(unit)
    raise ArgumentError.new("Unsupported unit: #{unit}")
  end

  if 
    return Nanook::Util.coerce_empty_string_to_type(rpc(:wallet_balances)[:balances], Hash).tap do |r|
      if unit == :nano
        r.each do |, balances|
          r[][:balance] = Nanook::Util.raw_to_NANO(r[][:balance])
          r[][:pending] = Nanook::Util.raw_to_NANO(r[][:pending])
        end
      end
    end
  end

  rpc(:wallet_balance_total).tap do |r|
    if unit == :nano
      r[:balance] = Nanook::Util.raw_to_NANO(r[:balance])
      r[:pending] = Nanook::Util.raw_to_NANO(r[:pending])
    end
  end
end

#change_password(password) ⇒ Object

Changes the password for a wallet. Returns a boolean to indicate if the action was successful.

Example response

true


325
326
327
328
# File 'lib/nanook/wallet.rb', line 325

def change_password(password)
  wallet_required!
  rpc(:password_change, password: password)[:changed] == 1
end

#contains?(account) ⇒ Boolean

Returns boolean indicating if the wallet contains an account.

Arguments

account

String account id (will start with "xrb_...")

Example response

true

Returns:

  • (Boolean)


208
209
210
211
212
# File 'lib/nanook/wallet.rb', line 208

def contains?()
  wallet_required!
  response = rpc(:wallet_contains, account: )
  !response.empty? && response[:exists] == 1
end

#createObject

Creates a new wallet.

Nanook.new.wallet.create

Very important

Please read this. The response of this method is a wallet seed. A seed is a 32-byte uppercase hex string. You can think of this string as your API key to the nano network. The person who knows it can do all read and write actions against the wallet and all accounts inside the wallet from anywhere on the nano network, not just on the node you created the wallet on.

If you intend for your wallet to contain funds, then make sure that you consider the seed that is returned as the key to your funds and store it somewhere secret and safe. Only transmit the seed over secure (SSH or SSL) networks and do not store it where it is able to be easily comprised by a hacker, which includes your personal computer.

Example response:

"CC2C9846A44DB6F0363F647D12B957794AD937F59498D4E35C172C81E2888650"


175
176
177
# File 'lib/nanook/wallet.rb', line 175

def create
  rpc(:wallet_create)[:wallet]
end

#destroyObject

Destroy the wallet. Returns a boolean indicating whether the action was successful or not.

Example Response

true


184
185
186
187
188
# File 'lib/nanook/wallet.rb', line 184

def destroy
  wallet_required!
  rpc(:wallet_destroy)
  true
end

#exportObject

Generates a String containing a JSON representation of your wallet.

Example response

"{\n    \"0000000000000000000000000000000000000000000000000000000000000000\": \"0000000000000000000000000000000000000000000000000000000000000003\",\n    \"0000000000000000000000000000000000000000000000000000000000000001\": \"C3A176FC3B90113277BFC91F55128FC9A1F1B6166A73E7446927CFFCA4C2C9D9\",\n    \"0000000000000000000000000000000000000000000000000000000000000002\": \"3E58EC805B99C52B4715598BD332C234A1FBF1780577137E18F53B9B7F85F04B\",\n    \"0000000000000000000000000000000000000000000000000000000000000003\": \"5FF8021122F3DEE0E4EC4241D35A3F41DEF63CCF6ADA66AF235DE857718498CD\",\n    \"0000000000000000000000000000000000000000000000000000000000000004\": \"A30E0A32ED41C8607AA9212843392E853FCBCB4E7CB194E35C94F07F91DE59EF\",\n    \"0000000000000000000000000000000000000000000000000000000000000005\": \"E707002E84143AA5F030A6DB8DD0C0480F2FFA75AB1FFD657EC22B5AA8E395D5\",\n    \"0000000000000000000000000000000000000000000000000000000000000006\": \"0000000000000000000000000000000000000000000000000000000000000001\",\n    \"8646C0423160DEAEAA64034F9C6858F7A5C8A329E73E825A5B16814F6CCAFFE3\": \"0000000000000000000000000000000000000000000000000000000100000000\"\n}\n"


195
196
197
198
# File 'lib/nanook/wallet.rb', line 195

def export
  wallet_required!
  rpc(:wallet_export)[:json]
end

#idObject



214
215
216
# File 'lib/nanook/wallet.rb', line 214

def id
  @wallet
end

#inspectObject

:nodoc:



218
219
220
# File 'lib/nanook/wallet.rb', line 218

def inspect # :nodoc:
  "#{self.class.name}(id: \"#{id}\", object_id: \"#{"0x00%x" % (object_id << 1)}\")"
end

#locked?Boolean

Returns a boolean to indicate if the wallet is locked.

Example response

true

Returns:

  • (Boolean)


302
303
304
305
306
# File 'lib/nanook/wallet.rb', line 302

def locked?
  wallet_required!
  response = rpc(:wallet_locked)
  !response.empty? && response[:locked] != 0
end

#pay(from:, to:, amount:, unit: Nanook::WalletAccount::DEFAULT_UNIT, id:) ⇒ Object

Make a payment from an account in your wallet to another account on the nano network. Returns a send block hash if successful, or an error String if unsuccessful.

Arguments

from:

String account id of an account in your wallet

to:

String account id of the recipient of your payment

amount:

Can be either an Integer or Float.

unit:

Symbol (default is :nano). Represents the unit that amount is in. Must be either :nano or :raw. (Note: this method interprets :nano as NANO, which is technically Mnano See What are Nano’s Units)

id:

String. Must be unique per payment. It serves an important purpose; it allows you to make the same call multiple times with the same id and be reassured that you will only ever send that nano payment once.

Note, there may be a delay in receiving a response due to Proof of Work being done. From the Nano RPC:

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.

Examples

wallet.pay(from: "xrb_...", to: "xrb_...", amount: 1.1, id: "myUniqueId123")
wallet.pay(from: "xrb_...", to: "xrb_...", amount: 54000000000000, unit: :raw, id: "myUniqueId123")

Example responses

"718CC2121C3E641059BC1C2CFC45666C99E8AE922F7A807B7D07B62C995D79E2"

Or:

"Account not found"


255
256
257
258
259
# File 'lib/nanook/wallet.rb', line 255

def pay(from:, to:, amount:, unit: Nanook::WalletAccount::DEFAULT_UNIT, id:)
  wallet_required!
  validate_wallet_contains_account!(from)
  (from).pay(to: to, amount: amount, unit: unit, id: id)
end

#receive(block = nil, into:) ⇒ Object

Receives a pending payment into an account in the wallet.

When called with no block argument, the latest pending payment for the account will be received.

Returns a receive block hash if a receive was successful, or false if there were no pending payments to receive.

You can also receive a specific pending block if you know it by passing the block has in as an argument.

Arguments

block

Optional block hash of pending payment. If not provided, the latest pending payment will be received

into:

String account id of account in your wallet to receive the payment into

Examples

wallet.receive(into: "xrb...")
wallet.receive("718CC21...", into: "xrb...")

Example responses

"718CC2121C3E641059BC1C2CFC45666C99E8AE922F7A807B7D07B62C995D79E2"

Or:

false


291
292
293
294
295
# File 'lib/nanook/wallet.rb', line 291

def receive(block=nil, into:)
  wallet_required!
  validate_wallet_contains_account!(into)
  (into).receive(block)
end

#unlock(password) ⇒ Object

Unlocks a previously locked wallet. Returns a boolean to indicate if the action was successful.

Example response

true


314
315
316
317
# File 'lib/nanook/wallet.rb', line 314

def unlock(password)
  wallet_required!
  rpc(:password_enter, password: password)[:valid] == 1
end