Project

banano

0.0
No commit activity in last 3 years
No release in over 3 years
Library for working with Banano currency. Implements parts of the RPC protocol for access to Banano node. Convertion between raw and banano units etc.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 0
~> 12.3
~> 3.9
~> 0.85
~> 3.8

Runtime

 Project Readme

Banano

The current Gem trying to make as easy as possible working with Banano currency. More information about the Banano currency networking can be found on the Banano Currency Wiki pages. The current library is still work in progress, but the basic functionallity is already implemented:

  • Good part of the RPC protocol for working with Banano nodes
  • Wallet, Account operations - send and receive payments etc.
  • Conversion between units - RAW to Banano and Banano to RAW

Some parts of the library are heavily influenced by the great nanook Ruby library for working with the similar NANO currency.

Everybody is welcome to contrubute to the project. Have fun and use Ruby and Banano.

Installation

Add this line to your application's Gemfile:

gem 'banano'

And then execute:

bundle install

Or install it yourself as:

gem install banano

Usage

The code is divided on following the parts:

  • Banano::Protocol - including all other parts. Can be used also for some syntax sugar (to avoid sending node parameter to constructors)
  • Banano::Client - very thin wrapper around Faraday HTTP Client for easy JSON-based communications
  • Banano::Node - Banano Node abstraction - mostly encapsulate JSON communications
  • Banano::Wallet - wallets holding for Banano accounts on the current node
  • Banano::Account - uniq 'ban_...' addresses used for currency tokens exchange
  • Banano::WalletAccount - link between Account and Wallet - check if account exists in the wallet etc.
  • Banano::Key - account key management
  • Banano::Block - low level work with individual blocks
  • Banano::WorkPeer - do work on peers
  • Banano::Unit - conversion between RAW and Banano units

Banano::Protocol

Usually everything starts here. By default the library will work with locally running Banano node. If it is impossible to be done, you can use the Public bananode RPC API. Example below is for that case:

BETA_URL = 'https://api-beta.banano.cc'
@banano = Banano::Protocol.new(uri: BETA_URL)
# From here it is easy to create other object, without sending URI to them
wallet = @banano.wallet('WALLET15263636...')
account = @banano.account('ban_1...')

Banano::Client

Not used directly, better use Banano::Node instead

client = Banano::Client.new(uri: BETA_URL)
client.rpc_call(action: :version)

Banano::Node

Most of the information about the running node is encapsulated here. The other parts using mostly the Banano::Node.rpc() method, not the low level client one:

Banano::Node.account_count # number of node accounts
Banano::Node.block_count   # check here if there are still non-syncronized blocks
Banano::Node.peers         # other nodes connected to that one
# accounts with voting power
Banano::Node.representatives
Banano::Node.representatives_online
# Is your node synced already
Banano::Node.synchronizing_blocks
Banano::Node.sync_progress

Banano::Wallet

Wallets are like a bags of accounts. Accounts can be only local, created on the current node. They will not be visible for other nodes.

wallet = Banano::Wallet.create   # create new wallet
wallet.restore(seed: 'XVVREGNN...') # restore some wallet and its accounts
wallet.accounts                  # current wellet accounts
wallet.contains?('ban_1...')     # check if the account exists in the current wallet
wallet.export                    # export wallet to JSON
wallet.destroy                   # remove the wallet
# Accounts with voting power
wallet.default_representative
wallet.change_default_representative('ban_1...')
# Security
wallet.change_password('SomePassword')   # protect your wallet
wallet.lock                              # no more payments
wallet.locked?
wallet.unlock('SomePassword')            # resume receiving payments
# Payments
block_id = wallet.pay(from: 'ban_1...', to: 'ban_3...', amount: '1.23', raw: false, id: 'x123')
wallet.pending(limit: 10, detailed: true)  # waiting payments (does not work well unless enable_control = true)
wallet.receive(into: 'ban_1', block: block_id)  # receive the pending banano into some wallet account
wallet.balance                           # check how many banano the whole wallet have, RAW units
wallet.balance(raw: false)               # wallet balance in Banano units
wallet.balance(account_break_down: true) # banano per acount, RAW units

Banano::Account

Account are holding units with unique address, where the banano tokens are accumulated. They can be local for the current node and not accessable for other nodes.

account = Banano::Account(node: @banano.node, address: 'ban1_...')  # create new account on that node
account.exists?   # check if account exists
# some account attributes
account.last_modified_at
account.public_key
account.representative
account.balance             # in RAW units
account.balance(raw: false)  # in banano units
# Payments
account.pending(limit: 100, detailed: true)  # detailed information about the pending payments
account.history(limit: 10)  # the latest payments - send and receive

Banano::WalletAccount

Because accounts and wallets so closly connected, some linkage object is very helpful.

wallet = @banano.wallet('XBHHNN...')
# create wallet <-> accounts connection
wallet_acc = Banano::WalletAccount(node: @banano.node, wallet: wallet.id)
wallet_acc.create     # create new account in the wallet
wallet_acc.create(3)  # create additional 3 accounts inside the same wallet
# Working with specific account
account = @banano.account('ban_1')
wallet_other_acc = Banano::WalletAccount(node: @banano.node, wallet: wallet.id, account: account.id)
block_id = wallet_other_acc.pay(to: 'ban_1...', amount: 10, raw: false, id: 'x1234')  # send some banano
wallet_other_acc.receive(block_id)   # receive some banano

Banano::Key

Most of the information is identicat with the NANO currency docs.

key_builder = @banano.key    # create new key (still unpopulated, cannot be used)
key_builder.generate         # generate private, public key and account address
{:private=>"43E6B...",
 :public=>"7EBC0C...",
 :account=>"ban_1zow3..."}
SEED = 'ABF56EBB...'         # Random seed
key_builder.generate(seed: SEED, index: 0)    # will always generate SAME pair of keys and address
key_builder.generate(seed: SEED, index: 1)
new_builder = @banano.key(saved_private_key)  # generate keys from saved private key
new_builder.expand                            # return private, public key and account address

Banano::WorkPeer

Delegate block validating work to some network peers:

work = Banano::WorkPeer(@banano.node)
work.add(address: '::ffff:1.2.3.4', port: '7071')  # add peer to the work flow
work.list  # list of working peers
work.clear # remove all peers

Banano::Block

Blocks, also known as transactions are the building items of the banano network. Every block have uniq ID, which can be used for processing the block

block = Banano::Block(node: @banano.node, block: 'F1B7EDB1...')
block.account           # account associated with the block
block.successors(limit: 10)
block.chain(limit: 10)  # also 'block.ancestors' - blocks chain, leading to the current one
block.history           # more detailed chain history
block.info              # information about the block
block.confirm           # block confirmation from the online representatives
work = block.generate_work(use_peers: true) # start some work
block.is_valid_work?(work) # check if the work done is valid
block.cancel_work       # stop generating work for block
block.pending?          # is the block in pending state. not work very well...
block.publish('send')   # dependes what kind of block is this: 'send', 'receive' etc.

Banano::Unit

Using Ruby bigdecimal library for all operations:

Banano::Unit.ban_to_raw(1)    # -> BigDecimal('100000000000000000000000000000')
Banano::Unit.raw_to_ban('1')  # -> BigDecimal('0.00000000000000000000000000001')

The library also is checking some currency related limits, for example total supply limit: 3402823669.20938463463374607431768211455 banano max

Development

After checking out the repo, run bin/setup to install dependencies. You can also run bin/console for an interactive prompt that will allow you to experiment.

Clone the gem source code and start experimenting:

git clone https://github.com/zh/rbanano

rspec is used for testing. To run all tests execute:

bundle exec rspec spec

Still a lot of tests needed. For now Banano::Unit and Banano:Util are ready. The other parts tests will be added soon.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/zh/rbanano.

License

The gem is available as open source under the terms of the MIT License.