Class: Nanook::WalletAccount

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/nanook/wallet_account.rb

Overview

The Nanook::WalletAccount class lets you manage your nano accounts, including paying and receiving payment.

Initializing

Initialize this class through an instance of Wallet like this:

 = Nanook.new.wallet(wallet_id).()

Or compose the longhand way like this:

rpc_conn = Nanook::Rpc.new
 = Nanook::WalletAccount.new(rpc_conn, wallet_id, )

Instance Method Summary collapse

Constructor Details

#initialize(rpc, wallet, account) ⇒ WalletAccount


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/nanook/wallet_account.rb', line 48

def initialize(rpc, wallet, )
  @rpc = rpc
  @wallet = wallet
  @account = 
  @nanook_account_instance = nil

  unless @account.nil?
    # Wallet must contain the account
    unless Nanook::Wallet.new(@rpc, @wallet).contains?(@account)
      raise ArgumentError.new("Account does not exist in wallet. Account: #{@account}, wallet: #{@wallet}")
    end

    # An object to delegate account methods that don't
    # expect a wallet param in the RPC call, to allow this
    # class to support all methods that can be called on Nanook::Account
    @nanook_account_instance = Nanook::Account.new(@rpc, @account)
  end
end

Instance Method Details

#balance(unit: Nanook.default_unit) ⇒ Hash{Symbol=>Integer|Float}

The account's balance, including pending (unreceived payments). To receive a pending amount see #receive.

Examples:

.balance

Example response:

{
  balance: 2,
  pending: 1.1
}

Asking for the balance to be returned in raw instead of NANO:

.balance(unit: :raw)

Example response:

{
  balance: 2000000000000000000000000000000,
  pending: 1100000000000000000000000000000
}

Raises:

  • ArgumentError if an invalid unit was given.


45
# File 'lib/nanook/wallet_account.rb', line 45

def_delegators :@nanook_account_instance, :balance, :delegators, :exists?, :history, :id, :info, :last_modified_at, :ledger, :pending, :public_key, :representative, :weight

#block_countInteger


45
# File 'lib/nanook/wallet_account.rb', line 45

def_delegators :@nanook_account_instance, :balance, :delegators, :exists?, :history, :id, :info, :last_modified_at, :ledger, :pending, :public_key, :representative, :weight

#change_representative(representative) ⇒ String

Sets the representative for the account.

A representative is an account that will vote on your account's behalf on the nano network if your account is offline and there is a fork of the network that requires voting on.

Returns the change block that was broadcast to the nano network. The block contains the information about the representative change for your account.

Example:

.change_representative("xrb_...") # => "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F"

Raises:

  • (ArgumentError)

    if the representative account does not exist


217
218
219
220
221
222
223
# File 'lib/nanook/wallet_account.rb', line 217

def change_representative(representative)
  unless Nanook::Account.new(@rpc, representative).exists?
    raise ArgumentError.new("Representative account does not exist: #{representative}")
  end

  rpc(:account_representative_set, representative: representative)[:block]
end

#create(n = 1) ⇒ Nanook::WalletAccount+

Creates a new account, or multiple new accounts, in this wallet.

Examples:

wallet.create     # => Nanook::WalletAccount
wallet.create(2)  # => [Nanook::WalletAccount, Nanook::WalletAccount]

Raises:

  • (ArgumentError)

    if n is less than 1


81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/nanook/wallet_account.rb', line 81

def create(n=1)
  if n < 1
    raise ArgumentError.new("number of accounts must be greater than 0")
  end

  if n == 1
    Nanook::WalletAccount.new(@rpc, @wallet, rpc(:account_create)[:account])
  else
    Array(rpc(:accounts_create, count: n)[:accounts]).map do ||
      Nanook::WalletAccount.new(@rpc, @wallet, )
    end
  end
end

#delegators(unit: Nanook.default_unit) ⇒ Hash{Symbol=>Integer}

Information about this accounts that have set this account as their representative.

Example:

.delegators

Example response:

{
  :xrb_13bqhi1cdqq8yb9szneoc38qk899d58i5rcrgdk5mkdm86hekpoez3zxw5sd=>500000000000000000000000000000000000,
  :xrb_17k6ug685154an8gri9whhe5kb5z1mf5w6y39gokc1657sh95fegm8ht1zpn=>961647970820730000000000000000000000
}

45
# File 'lib/nanook/wallet_account.rb', line 45

def_delegators :@nanook_account_instance, :balance, :delegators, :exists?, :history, :id, :info, :last_modified_at, :ledger, :pending, :public_key, :representative, :weight

#destroyBoolean

Unlinks the account from the wallet.

Example:

.destroy # => true

102
103
104
# File 'lib/nanook/wallet_account.rb', line 102

def destroy
  rpc(:account_remove)[:removed] == 1
end

#exists?Boolean Also known as: open?

Returns true if the account has an open block.

An open block gets published when an account receives a payment for the first time.

The reliability of this check depends on the node host having synchronized itself with most of the blocks on the nano network, otherwise you may get false when the account does exist. You can check if a node's synchronization is particular low using Node#sync_progress.

Example:

.exists? # => true
# or
.open?   # => true

45
# File 'lib/nanook/wallet_account.rb', line 45

def_delegators :@nanook_account_instance, :balance, :delegators, :exists?, :history, :id, :info, :last_modified_at, :ledger, :pending, :public_key, :representative, :weight

#history(limit: 1000, unit: Nanook.default_unit) ⇒ Array<Hash{Symbol=>String}>

An account's history of send and receive payments.

Example:

.history

Example response:

[
  {
   type: "send",
   account: "xrb_1kdc5u48j3hr5r7eof9iao47szqh81ndqgq5e5hrsn1g9a3sa4hkkcotn3uq",
   amount: 2,
   hash: "2C3C570EA8898443C0FD04A1C385A3E3A8C985AD792635FCDCEBB30ADF6A0570"
  }
]

45
# File 'lib/nanook/wallet_account.rb', line 45

def_delegators :@nanook_account_instance, :balance, :delegators, :exists?, :history, :id, :info, :last_modified_at, :ledger, :pending, :public_key, :representative, :weight

#idString

The id of the account.

Example:

.id # => "xrb_16u..."

45
# File 'lib/nanook/wallet_account.rb', line 45

def_delegators :@nanook_account_instance, :balance, :delegators, :exists?, :history, :id, :info, :last_modified_at, :ledger, :pending, :public_key, :representative, :weight

#info(detailed: false, unit: Nanook.default_unit) ⇒ Hash{Symbol=>String|Integer|Float}

Information about the account.

Examples:

.info

Example response:

{
  id: "xrb_16u1uufyoig8777y6r8iqjtrw8sg8maqrm36zzcm95jmbd9i9aj5i8abr8u5",
  balance: 11.439597000000001,
  block_count: 4,
  frontier: "2C3C570EA8898443C0FD04A1C385A3E3A8C985AD792635FCDCEBB30ADF6A0570",
  modified_timestamp: 1520500357,
  open_block: "C82376314C387080A753871A32AD70F4168080C317C5E67356F0A62EB5F34FF9",
  representative_block: "C82376314C387080A753871A32AD70F4168080C317C5E67356F0A62EB5F34FF9"
}

Asking for more detail to be returned:

.info(detailed: true)

Example response:

{
  id: "xrb_16u1uufyoig8777y6r8iqjtrw8sg8maqrm36zzcm95jmbd9i9aj5i8abr8u5",
  balance: 11.439597000000001,
  block_count: 4,
  frontier: "2C3C570EA8898443C0FD04A1C385A3E3A8C985AD792635FCDCEBB30ADF6A0570",
  modified_timestamp: 1520500357,
  open_block: "C82376314C387080A753871A32AD70F4168080C317C5E67356F0A62EB5F34FF9",
  pending: 0,
  public_key: "A82C906460046D230D7D37C6663723DC3EFCECC4B3254EBF45294B66746F4FEF",
  representative: "xrb_3pczxuorp48td8645bs3m6c3xotxd3idskrenmi65rbrga5zmkemzhwkaznh",
  representative_block: "C82376314C387080A753871A32AD70F4168080C317C5E67356F0A62EB5F34FF9",
  weight: 0
}

45
# File 'lib/nanook/wallet_account.rb', line 45

def_delegators :@nanook_account_instance, :balance, :delegators, :exists?, :history, :id, :info, :last_modified_at, :ledger, :pending, :public_key, :representative, :weight

#inspectString


107
108
109
# File 'lib/nanook/wallet_account.rb', line 107

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

#last_modified_atTime

The last modified time of the account in the time zone of your nano node (usually UTC).

Example:

.last_modified_at # => Time

45
# File 'lib/nanook/wallet_account.rb', line 45

def_delegators :@nanook_account_instance, :balance, :delegators, :exists?, :history, :id, :info, :last_modified_at, :ledger, :pending, :public_key, :representative, :weight

#ledger(limit: 1, modified_since: nil, unit: Nanook.default_unit) ⇒ Hash{Symbol=>String|Integer}

Information about the given account as well as other accounts up the ledger. The number of accounts returned is determined by the limit: argument.

Example:

.ledger(limit: 2)

Example response:

 {
  :xrb_3c3ek3k8135f6e8qtfy8eruk9q3yzmpebes7btzncccdest8ymzhjmnr196j=>{
    :frontier=>"2C3C570EA8898443C0FD04A1C385A3E3A8C985AD792635FCDCEBB30ADF6A0570",
    :open_block=>"C82376314C387080A753871A32AD70F4168080C317C5E67356F0A62EB5F34FF9",
    :representative_block=>"C82376314C387080A753871A32AD70F4168080C317C5E67356F0A62EB5F34FF9",
    :balance=>11439597000000000000000000000000,
    :modified_timestamp=>1520500357,
    :block_count=>4
  },
  :xrb_3c3ettq59kijuuad5fnaq35itc9schtr4r7r6rjhmwjbairowzq3wi5ap7h8=>{ ... }
}

45
# File 'lib/nanook/wallet_account.rb', line 45

def_delegators :@nanook_account_instance, :balance, :delegators, :exists?, :history, :id, :info, :last_modified_at, :ledger, :pending, :public_key, :representative, :weight

#pay(to:, amount:, unit: Nanook::default_unit, id:) ⇒ String

Makes a payment from this account to another account on the nano network. Returns a send block hash if successful, or a Error if unsuccessful.

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:

.pay(to: "xrb_...", amount: 1.1, id: "myUniqueId123") # => "9AE2311..."
.pay(to: "xrb_...", amount: 54000000000000, id: "myUniqueId123", unit: :raw) # => "9AE2311..."

Raises:


134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/nanook/wallet_account.rb', line 134

def pay(to:, amount:, unit: Nanook::default_unit, id:)
  unless Nanook::UNITS.include?(unit)
    raise ArgumentError.new("Unsupported unit: #{unit}")
  end

  # Check that to account is a valid address
  response = @rpc.call(:validate_account_number, account: to)
  unless response[:valid] == 1
    raise ArgumentError.new("Account address is invalid: #{to}")
  end

  # Determin amount in raw
  raw = if unit.to_sym.eql?(:nano)
    Nanook::Util.NANO_to_raw(amount)
  else
    amount
  end

  # account is called source, so don't use the normal rpc method
  p = {
    wallet: @wallet,
    source: @account,
    destination: to,
    amount: raw,
    id: id
  }

  response = @rpc.call(:send, p)

  if response.has_key?(:error)
    return Nanook::Error.new(response[:error])
  end

  response[:block]
end

#pending(limit: 1000, detailed: false, unit: Nanook.default_unit) ⇒ Array<String>, Array<Hash{Symbol=>String|Integer}>

Information about pending blocks (payments) that are waiting to be received by the account.

See also the #receive method for how to receive a pending payment.

The default response is an Array of block ids.

With the detailed: argument, the method returns an Array of Hashes, which contain the source account id, amount pending and block id.

Examples:

.pending # => ["000D1BA..."]

Asking for more detail to be returned:

.pending(detailed: true)

Example response:

[
  {
    block: "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F",
    amount: 6,
    source: "xrb_3dcfozsmekr1tr9skf1oa5wbgmxt81qepfdnt7zicq5x3hk65fg4fqj58mbr"
  },
  { ... }
]

45
# File 'lib/nanook/wallet_account.rb', line 45

def_delegators :@nanook_account_instance, :balance, :delegators, :exists?, :history, :id, :info, :last_modified_at, :ledger, :pending, :public_key, :representative, :weight

#public_keyString

The public key of the account.

Example:

.public_key # => "3068BB1..."

45
# File 'lib/nanook/wallet_account.rb', line 45

def_delegators :@nanook_account_instance, :balance, :delegators, :exists?, :history, :id, :info, :last_modified_at, :ledger, :pending, :public_key, :representative, :weight

#receive(block = nil) ⇒ String, false

Receives a pending payment for this account.

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

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

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

Examples:

.receive               # => "9AE2311..."
.receive("718CC21...") # => "9AE2311..."

191
192
193
194
195
196
197
# File 'lib/nanook/wallet_account.rb', line 191

def receive(block=nil)
  if block.nil?
    _receive_without_block
  else
    _receive_with_block(block)
  end
end

#representativeString

The representative account id for the account. Representatives are accounts which cast votes in the case of a fork in the network.

Example:

.representative # => "xrb_3pc..."

45
# File 'lib/nanook/wallet_account.rb', line 45

def_delegators :@nanook_account_instance, :balance, :delegators, :exists?, :history, :id, :info, :last_modified_at, :ledger, :pending, :public_key, :representative, :weight

#weightInteger

The account's weight.

Weight is determined by the account's balance, and represents the voting weight that account has on the network. Only accounts with greater than 256 weight can vote.

Example:

.weight # => 0

45
# File 'lib/nanook/wallet_account.rb', line 45

def_delegators :@nanook_account_instance, :balance, :delegators, :exists?, :history, :id, :info, :last_modified_at, :ledger, :pending, :public_key, :representative, :weight