]> git.codecow.com Git - libnemo.git/commitdiff
Update README.
authorChris Duncan <chris@zoso.dev>
Thu, 24 Jul 2025 21:33:01 +0000 (14:33 -0700)
committerChris Duncan <chris@zoso.dev>
Thu, 24 Jul 2025 21:33:01 +0000 (14:33 -0700)
README.md

index 78c427bec7a976154d5abff7ad80a407cdd31c0d..2e34f7c052794e05cd06bb836a1c10159b5055ae 100644 (file)
--- a/README.md
+++ b/README.md
@@ -4,17 +4,20 @@ SPDX-License-Identifier: GPL-3.0-or-later
 -->
 
 # libnemo
-libnemo is a fork of the nanocurrency-web toolkit. It is used for client-side
+
+`libnemo` is a fork of the nanocurrency-web toolkit. It is used for client-side
 implementations of Nano cryptocurrency wallets and enables building web-based
-applications that can work even while offline. libnemo supports managing
+applications that can work even while offline. `libnemo` supports managing
 wallets, deriving accounts, signing blocks, and more.
 
-It utilizes the Web Crypto API which is native to all modern browsers; as such,
-it has only a required dependency in order to work with the BLAKE2b algorithm.
-Optionally, Ledger device dependencies can be installed to enable Ledger
+It utilizes the Web Crypto API which is native to all modern browsers. Private
+keys are encrypted in storage with a user password as soon as they are derived,
+and they are not exposed to other processes unless specifically exported by the
+user. Optionally, Ledger device dependencies can be installed to enable Ledger
 hardware wallet support.
 
 ## Features
+
 * Generate new BIP-32 hierarchial deterministic (HD) wallets with a BIP-39
 mnemonic phrase and the Nano path registered with BIP-44. Used by Ledger
 hardware wallet.
@@ -28,10 +31,9 @@ described by nano spec.
 * Sign and verify arbitrary strings with relevant keys.
 * Validate entropy, seeds, mnemonic phrases, and Nano addresses.
 * Convert Nano unit denominations.
-* Run in modern web browsers and mobile frameworks built with Javascript without
-server-side NodeJS functions.
 
 ## Installation
+
 ### From NPM
 
 ```console
@@ -39,25 +41,29 @@ npm install libnemo
 ```
 
 ## Usage
+
 #### ⚠️ The examples below should never be used for real transactions! ⚠️
 
 ### Wallets and accounts
+
 At its core, a wallet is a hexadecimal string called a seed. From this seed,
 millions of unique accounts can be deterministically derived. The first account
 in a wallet starts at index 0.
 
 For clarity, the following terms are used throughout the library:
+
  * BIP-32 - Defines how hierarchical determinstic (HD) wallets are generated
  * BIP-39 - Defines how mnemonic phrases are generated
  * BIP-44 - Expands on BIP-32 to define how an enhanced derivation path can
  allow a single wallet to store multiple currencies
 
-libnemo is able to generate and import HD and BLAKE2b wallets, and it can derive
-accounts for both. An HD wallet seed is 128 characters while a BLAKE2b wallet
-seed is 64 characters. For enhanced security, libnemo requires a password to
-create or import wallets, and wallets are initialized in a locked state.
-Implementations can provide their own Uint8Array bytes instead of a password.
-Refer to the documentation on each class factory method for specific usage.
+`libnemo` is able to generate and import HD and BLAKE2b wallets, and it can
+derive accounts for both. An HD wallet seed is 128 characters while a BLAKE2b
+wallet seed is 64 characters. For enhanced security, `libnemo` requires a
+password to create or import wallets, and wallets are initialized in a locked
+state. Implementations can provide their own Uint8Array bytes instead of a
+password. Refer to the documentation on each class factory method for specific
+usage.
 
 ```javascript
 import { Bip44Wallet, Blake2bWallet } from 'libnemo'
@@ -81,10 +87,11 @@ try {
 console.log(unlockResult) // true if successfully unlocked
 
 const { mnemonic, seed } = wallet
-
-const accounts = await wallet.accounts(from?, to?)
-const firstAccount = accounts[0]
-const { address, publicKey, privateKey, index } = firstAccount
+const firstAccount = await wallet.account()
+const secondAccount = await wallet.account(1)
+const multipleAccounts = await wallet.accounts(2, 3)
+const thirdAccount = multipleAccounts[3]
+const { address, publicKey, index } = firstAccount
 
 const nodeUrl = 'https://nano-node.example.com/'
 await firstAccount.refresh(nodeUrl) // online
@@ -92,16 +99,17 @@ const { frontier, balance, representative } = firstAccount
 ```
 
 ### Blocks
+
 Blocks do not contain transaction amounts. Instead, they contain stateful
 balance changes only. For example, if sending Ӿ5 from an account with a balance
 of Ӿ20, the send block would contain `balance: Ӿ15` (psuedocode for
 demonstration purposes and not a literal depiction). This can be difficult to
-track, so libnemo provides the convenience of specifying an amount to send or
+track, so `libnemo` provides the convenience of specifying an amount to send or
 receive and calculates the balance change itself.
 
 All blocks are 'state' types, but they are interpreted as one of three different
 subtypes based on the data they contain: send, receive, or change
-representative. libnemo implements them as the following classes:
+representative. `libnemo` implements them as the following classes:
 
 * SendBlock: the Nano balance of the account decreases
 * ReceivBlock: the Nano balance of the account increases and requires a matching
@@ -110,7 +118,7 @@ SendBlock
 does not
 
 _Nano protocol allows changing the representative at the same time as a balance
-change. libnemo does not implement this for purposes of clarity; all
+change. `libnemo` does not implement this for purposes of clarity; all
 ChangeBlock objects will maintain the same Nano balance._
 
 Always fetch the most up to date information for the account from the network
@@ -119,17 +127,17 @@ using the
 which can then be used to populate the block parameters.
 
 Blocks require a small proof-of-work that must be calculated for the block to be
-accepted by the network. This can be provided when creating the block, or a
-public node that allows the
-[work_generate RPC command](https://docs.nano.org/commands/rpc-protocol/#work_generate)
-can be used.
+accepted by the network. This can be provided when creating the block, generated
+with the `block.pow()` method, or a requested from a public node that allows the
+[work_generate RPC command](https://docs.nano.org/commands/rpc-protocol/#work_generate).
 
-Finally, the block must be signed with the private key of the account. libnemo
-enables this to be done offline if desired. After being signed, the block can
+Finally, the block must be signed with the private key of the account. `libnemo`
+accounts can sign blocks offline if desired. After being signed, the block can
 be published to the network with the
 [process RPC command](https://docs.nano.org/commands/rpc-protocol/#process).
 
 #### Creating blocks
+
 ```javascript
 import { SendBlock, ReceiveBlock, ChangeBlock } from 'libnemo'
 
@@ -162,7 +170,31 @@ const change = new ChangeBlock(
 )
 ```
 
-#### Signing a block
+#### Signing a block with a wallet
+
+```javascript
+const wallet = await Bip44Wallet.create('password123')
+await wallet.unlock('password123')
+try {
+       await wallet.sign(0, block)
+} catch (err) {
+       console.log(err)
+}
+```
+
+#### Signing a block with a detached account
+
+```javascript
+const account = await Account.import({privateKey: K, index: 0}, 'password123')
+try {
+       await account.sign(block, 'password123')
+} catch (err) {
+       console.log(err)
+}
+```
+
+#### Signing a block with a private key
+
 ```javascript
 const privateKey = '3BE4FC2EF3F3B7374E6FC4FB6E7BB153F8A2998B3B3DAB50853EABE128024143'
 try {
@@ -172,7 +204,18 @@ try {
 }
 ```
 
-#### Caculating proof-of-work from an online service
+#### Calculating proof-of-work locally
+
+```javascript
+try {
+       await block.pow()
+} catch (err) {
+       console.log(err)
+}
+```
+
+#### Requesting proof-of-work from an online service
+
 ```javascript
 const node = new Rpc('https://nano-node.example.com/')
 try {
@@ -183,6 +226,7 @@ try {
 ```
 
 #### Processing a block on the network
+
 ```javascript
 const node = new Rpc('https://nano-node.example.com', 'nodes-api-key')
 try {
@@ -193,10 +237,13 @@ try {
 ```
 
 ### Tools
+
 #### Converting Nano denominations
+
 Raw values are the native unit of exchange throughout libnemo and are
 represented by the primitive bigint data type. Other supported denominations
 are as follows:
+
 | Unit  | Raw |
 |-------|-----|
 | RAI   | 10<sup>24</sup> raw |
@@ -218,6 +265,7 @@ const oneThousandPicoToNano = Tools.convert('1000', 'pico', 'NANO') // 1
 ```
 
 #### Verifying signatures and signing anything with the private key
+
 Since cryptocurrencies like Nano uses asymmetric keys to sign and verify blocks
 and transactions, a Nano account itself can be used to sign arbitrary data
 with its private key and verify signatures from other accounts with their public
@@ -238,6 +286,7 @@ const isValid = await Tools.verify(publicKey, signature, 'johndoe@example.com')
 Ownership of a Nano address can also be proven by challenging the account owner
 to sign an arbitrary string and then validating the signature with the Nano
 account address.
+
 ```javascript
 import { Tools } from 'libnemo'
 
@@ -251,6 +300,7 @@ const isValid = await Tools.verify(publicKey, signature, randomData)
 ```
 
 #### Validate a Nano account address
+
 ```javascript
 import { Tools } from 'libnemo'
 
@@ -258,16 +308,21 @@ const valid = Account.validate('nano_1pu7p5n3ghq1i1p4rhmek41f5add1uh34xpb94nkbxe
 ```
 
 ## Tests
+
 Test vectors were retrieved from the following publicly-available locations:
+
  * Nano (BIP-44): https://docs.nano.org/integration-guides/key-management/#test-vectors
  * Trezor (BIP-39): https://github.com/trezor/python-mnemonic/blob/master/vectors.json
  * BIP-32: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#user-content-Test_Vectors
+
 Another set of test vectors were created for libnemo based on the Trezor set.
 These extra test vectors were generated purely to test uncommon yet valid
 mnemonic phrase lengths like 15 or 18 words.
+
 #### ⚠️ The test vectors should never be used for real transactions! ⚠️
 
 ## Building
+
 * `npm run build`: compile and build
 * `npm run test`: all of the above, run tests, and print results to the console
 * `npm run test:coverage`: all of the above, calculate code coverage, and print
@@ -276,7 +331,9 @@ code coverage to the console
 coverage report in the browser (requires lcov and xdg-open)
 
 ## Donations
+
 If you find this library helpful, please consider tipping the developer.
+
 ```
 nano_1zosoqs47yt47bnfg7sdf46kj7asn58b7uzm9ek95jw7ccatq37898u1zoso
 ```