{"id":20926501,"url":"https://github.com/lukes/nanook","last_synced_at":"2025-05-13T17:33:41.402Z","repository":{"id":50775520,"uuid":"124017336","full_name":"lukes/nanook","owner":"lukes","description":"Ruby library for making and receiving payments and managing a nano currency node","archived":false,"fork":false,"pushed_at":"2023-06-15T09:29:52.000Z","size":1223,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-17T01:26:32.937Z","etag":null,"topics":["cryptocurrency","gem","nano","nano-currency","nano-node","nano-rpc","nanocurrency","payment","payments","receive-payments","ruby","wallet"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lukes.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-06T03:50:33.000Z","updated_at":"2023-06-15T09:24:01.000Z","dependencies_parsed_at":"2024-11-14T21:39:26.537Z","dependency_job_id":"89cdef1e-a20f-4383-b3ac-189b6a35b127","html_url":"https://github.com/lukes/nanook","commit_stats":{"total_commits":400,"total_committers":3,"mean_commits":"133.33333333333334","dds":"0.010000000000000009","last_synced_commit":"2a821f45296cdca2abf592d4ca13c6e9c6e67746"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukes%2Fnanook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukes%2Fnanook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukes%2Fnanook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukes%2Fnanook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lukes","download_url":"https://codeload.github.com/lukes/nanook/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253993764,"owners_count":21996371,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cryptocurrency","gem","nano","nano-currency","nano-node","nano-rpc","nanocurrency","payment","payments","receive-payments","ruby","wallet"],"created_at":"2024-11-18T20:39:13.480Z","updated_at":"2025-05-13T17:33:40.708Z","avatar_url":"https://github.com/lukes.png","language":"Ruby","readme":"# Nanook\n\nThis is a Ruby library for managing a [nano currency](https://nano.org/) node, including making and receiving payments, using the [nano RPC protocol](https://docs.nano.org/commands/rpc-protocol). Nano is a fee-less, fast, environmentally-friendly cryptocurrency. It's awesome. See [https://nano.org](https://nano.org/).\n\n[![Gem Version](https://badge.fury.io/rb/nanook.svg)](https://badge.fury.io/rb/nanook)\n[![CircleCI](https://circleci.com/gh/lukes/nanook/tree/master.svg?style=shield)](https://circleci.com/gh/lukes/nanook/tree/master)\n\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'nanook'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install nanook\n\n# Getting Started\n\n## Initializing\n\nNanook will by default connect to `http://[::1]:7076`.\n\n```ruby\nnanook = Nanook.new\n```\n\nTo connect to another host instead:\n\n```ruby\nnanook = Nanook.new(\"http://localhost:7076\")\n```\n\n## Basics\n\n### Working with wallets and accounts\n\nCreate a wallet:\n\n```ruby\nwallet = nanook.wallet.create\n```\n\nCreate an account within a wallet:\n\n```ruby\naccount = wallet.account.create\n```\n\nList accounts within a wallet:\n\n```ruby\naccounts = wallet.accounts\n```\n\n### Sending a payment\n\nTo send a payment from an account in a wallet:\n\n```ruby\naccount = nanook.wallet(wallet_id).account(account_id)\naccount.pay(to: recipient_account_id, amount: 0.2, id: unique_id)\n```\n\nOr, a wallet:\n\n```ruby\nwallet = nanook.wallet(wallet_id)\nwallet.pay(from: your_account_id, to: recipient_account_id, amount: 0.2, id: unique_id)\n```\n\nThe `id` can be any string and needs to be unique per payment. It serves an important purpose; it allows you to make this call multiple times with the same `id` and be reassured that you will only ever send that nano payment once. From the [Nano RPC](https://docs.nano.org/commands/rpc-protocol/#send):\n\n\u003e You can (and should) specify a unique id for each spend to provide idempotency. That means that if you [make the payment call] two times with the same id, the second request won't send any additional Nano.\n\nThe unit of the `amount` is NANO (which is currently technically Mnano \u0026mdash; see [What are Nano's Units](https://docs.nano.org/protocol-design/distribution-and-units/#unit-dividers)). You can pass an amount of raw instead by adding the `unit: :raw` argument:\n\n```ruby\naccount.pay(to: recipient_account_id, amount: 999, unit: :raw, id: unique_id)\n```\n\nNote, there may be a delay in receiving a response due to Proof of Work being done. From the [Nano RPC](https://docs.nano.org/commands/rpc-protocol/#send):\n\n\u003e 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.\n\n### Receiving a payment\n\nThe simplest way to receive a payment is:\n\n```ruby\naccount = nanook.wallet(wallet_id).account(account_id)\naccount.receive\n\n# or:\n\nwallet = nanook.wallet(wallet_id)\nwallet.receive(into: account_id)\n```\n\nThe `receive` method when called as above will receive the latest pending payment for an account in a wallet. It will either return a block hash if a payment was received, or `false` if there were no pending payments to receive.\n\nYou can also receive a specific pending block if you know it (you may have discovered it through calling `account.pending` for example):\n\n```ruby\naccount = nanook.wallet(wallet_id).account(account_id)\naccount.receive(block_id)\n\n# or:\n\nwallet = nanook.wallet(wallet_id)\nwallet.receive(block_id, into: account_id)\n```\n\n## Exploring further\n\nRead the [Using Nanook](https://github.com/lukes/nanook/wiki/Using-nanook) page for some example uses of Nanook to query the network.\n\n## All commands\n\nBelow is a quick reference list of commands. See the [full Nanook documentation](https://lukes.github.io/nanook/4.0.0/) for a searchable detailed description of every class and method, what the arguments mean, and example responses.\n\n### Wallets\n\nSee the [full documentation for Nanook::Wallet](https://lukes.github.io/nanook/4.0.0/Nanook/Wallet.html) for a detailed description of each method and example responses.\n\n#### Create wallet:\n\n```ruby\nnanook.wallet.create\n```\n#### Restoring a wallet from a seed\n\n```ruby\nnanook.wallet.restore(seed)\n```\nOptionally also restore the wallet's accounts:\n```ruby\nnanook.wallet.restore(seed, accounts: 2)\n```\n\n#### Working with a wallet:\n\n```ruby\nwallet = nanook.wallet(wallet_id)\n\nwallet.balance\nwallet.balance(account_break_down: true)\nwallet.balance(unit: :raw)\nwallet.pay(from: your_account_id, to: recipient_account_id, amount: 2, id: unique_id)\nwallet.pay(from: your_account_id, to: recipient_account_id, amount: 2, id: unique_id, unit: :raw)\nwallet.pending\nwallet.pending(limit: 1)\nwallet.pending(detailed: true)\nwallet.pending(allow_unconfirmed: true)\nwallet.pending(unit: :raw)\nwallet.receive(into: account_id)\nwallet.receive(pending_block_id, into: account_id)\nwallet.search_pending\n\nwallet.account.create\nwallet.account.create(5)\nwallet.accounts\nwallet.contains?(account_id)\nwallet.move_accounts(from_wallet_id, [account_1_id, account_2_id])\nwallet.remove_account(account_id)\n\nwallet.default_representative\nwallet.change_default_representative(representative_account_id)\nwallet.change_password(password)\nwallet.exists?\nwallet.history\nwallet.history(unit: :raw)\nwallet.info\nwallet.info(unit: :raw)\nwallet.export\nwallet.ledger\nwallet.ledger(unit: :raw)\nwallet.lock\nwallet.locked?\nwallet.republish_blocks\nwallet.republish_blocks(limit: 5)\nwallet.unlock(password)\nwallet.work\n\nwallet.destroy\n```\n### Accounts\n\n#### Create account:\n\n```ruby\nnanook.wallet(wallet_id).account.create\n```\n\n#### Create multiple accounts:\n\n```ruby\nnanook.wallet(wallet_id).account.create(5)\n```\n\n#### Working with an account:\n\nAny account on the Nano network that is known by your node can be initialized through `Nanook#account`:\n\n```ruby\naccount = nanook.account(account_id)\n```\n\nSee the [full documentation for Nanook::Account](https://lukes.github.io/nanook/4.0.0/Nanook/Account.html) for a detailed description of each method and example responses.\n\n```ruby\naccount.balance\naccount.balance(allow_unconfirmed: true)\naccount.balance(unit: :raw)\naccount.pending\naccount.pending(limit: 1)\naccount.pending(allow_unconfirmed: true)\naccount.pending(detailed: true)\naccount.pending(sorted: true)\naccount.pending(unit: :raw)\n\naccount.blocks\naccount.blocks(limit: 1)\naccount.blocks(sort: :desc)\naccount.delegators\naccount.delegators(unit: :raw)\naccount.delegators_count\naccount.exists?\naccount.history\naccount.history(limit: 1)\naccount.history(unit: :raw)\naccount.history(sort: :desc)\naccount.info\naccount.info(allow_unconfirmed: true)\naccount.info(unit: :raw)\naccount.last_modified_at\naccount.ledger\naccount.ledger(limit: 10)\naccount.ledger(modified_since: Time.now)\naccount.ledger(unit: :raw)\naccount.ledger(sort: :desc)\naccount.open_block\naccount.public_key\naccount.representative\naccount.weight\naccount.weight(unit: :raw)\n```\n\n#### Working with an account created on the node:\n\nAccounts that have been created on your node can have\nadditional methods when initialized through `Nanook::Wallet#account`:\n\n```ruby\nwallet = nanook.wallet(wallet_id)\naccount = wallet.account(account_id)\n```\n\nAs well as the following methods, all methods of [regular accounts](#working-with-any-account) can also be called.\n\nSee the [full documentation for Nanook::WalletAccount](https://lukes.github.io/nanook/4.0.0/Nanook/WalletAccount.html) for a detailed description of each method and example responses.\n\n```ruby\naccount.pay(to: recipient_account_id, amount: 2, id: unique_id)\naccount.pay(to: recipient_account_id, amount: 2, id: unique_id, unit: :raw)\naccount.receive\naccount.receive(pending_block_id)\naccount.change_representative(new_representative)\naccount.set_work(work)\naccount.work\naccount.destroy\n```\n\n### Blocks\n\nSee the [full documentation for Nanook::Block](https://lukes.github.io/nanook/4.0.0/Nanook/Block.html) for a detailed description of each method and example responses.\n\n```ruby\nblock = nanook.block(block_id)\n\nblock.account\nblock.amount\nblock.amount(unit: :raw)\nblock.ancestors\nblock.ancestors(limit: 10)\nblock.ancestors(offset: 10)\nblock.balance\nblock.change?\nblock.checked?\nblock.confirm\nblock.descendants\nblock.descendants(limit: 10)\nblock.descendants(offset: 10)\nblock.epoch?\nblock.exists?\nblock.exists?(allow_unchecked: true)\nblock.height\nblock.info                        # Verified blocks in the ledger\nblock.info(allow_unchecked: true) # Verified blocks AND unchecked synchronizing blocks\nblock.info(unit: :raw)\nblock.next\nblock.open?\nblock.pending?\nblock.pending?(allow_unconfirmed: true)\nblock.previous\nblock.receive?\nblock.representative\nblock.republish\nblock.republish(sources: 2)\nblock.republish(destinations: 2)\nblock.send?\nblock.signature\nblock.timestamp\nblock.type\nblock.unchecked?\nblock.work\n\nblock.generate_work\nblock.generate_work(use_peers: true)\nblock.cancel_work\nblock.valid_work?(work)\n```\n\n### Managing your nano node\n\nSee the [full documentation for Nanook::Node](https://lukes.github.io/nanook/4.0.0/Nanook/Node.html) for a detailed description of each method and example responses.\n\n```ruby\nnode = nanook.node\n\nnode.account_count\nnode.block_count\nnode.bootstrap(address: \"::ffff:138.201.94.249\", port: 7075)\nnode.bootstrap_any\nnode.bootstrap_any(account: account_id)\nnode.bootstrap_lazy(block_id)\nnode.bootstrap_lazy(block_id, force: true)\nnode.confirmation_quorum\nnode.difficulty\nnode.difficulty(include_trend: true)\nnode.keepalive(address: \"::ffff:138.201.94.249\", port: 7075)\nnode.peers\nnode.receive_minimum\nnode.receive_minimum(unit: :raw)\nnode.change_receive_minimum(amount)\nnode.change_receive_minimum(amount, unit: :raw)\nnode.representatives\nnode.representatives(unit: :raw)\nnode.representatives_online\nnode.search_pending\nnode.synchronizing_blocks\nnode.synchronizing_blocks(limit: 1)\nnode.sync_progress\nnode.version\n\nnode.stop\n```\n\n### Work peers\n\n```ruby\nwork_peers = nanook.work_peers\n\nwork_peers.add(address: \"::ffff:172.17.0.1:7076\", port: 7076)\nwork_peers.clear\nwork_peers.list\n```\n\n### Keys\n\n#### Create private public key pair:\n\n```ruby\nprivate_key = nanook.private_key.create\nprivate_key = nanook.private_key.create(seed: seed, index: 0)\nprivate_key.public_key # =\u003e Nanook::PublicKey\n```\n\n#### Working with a private key\n\n```ruby\nkey = nanook.private_key(private_key)\n\nkey.account\nkey.public_key\n```\n\n#### Working with a public key\n\n```ruby\nkey = nanook.public_key(public_key)\n\nkey.account\n```\n\n### Network\n\nA summarized overview of the Nano network:\n\n```ruby\nnanook.network_telemetry\n```\n\n## Nanook Metal\n\nYou can do any call listed in the [Nano RPC](https://docs.nano.org/commands/rpc-protocol) directly through the `rpc` method. The first argument should match the `action` of the RPC call, and then all remaining parameters are passed in as arguments.\n\nE.g., the [accounts_create command](https://docs.nano.org/commands/rpc-protocol/#accounts_create) can be called like this:\n\n```ruby\nnanook.rpc.call(:accounts_create, wallet: wallet_id, count: 2)\n```\n\n## Contributing\n\nBug reports and pull requests are welcome. Pull requests with passing tests are even better.\n\nTo run the test suite:\n\n    bundle exec rspec spec\n\nTo update the yard documentation:\n\n    bundle exec rake yard\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Buy me a nano coffee\n\nThis library is always free to use, but feel free to send some nano [my way](https://www.nanolooker.com/account/nano_3c3ek3k8135f6e8qtfy8eruk9q3yzmpebes7btzncccdest8ymzhjmnr196j) if you'd like to!\n\n    nano_3c3ek3k8135f6e8qtfy8eruk9q3yzmpebes7btzncccdest8ymzhjmnr196j\n\n![alt nano_3c3ek3k8135f6e8qtfy8eruk9q3yzmpebes7btzncccdest8ymzhjmnr196j](https://raw.githubusercontent.com/lukes/nanook/master/img/qr.png)\n\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukes%2Fnanook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flukes%2Fnanook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukes%2Fnanook/lists"}