Skip to content
Monero wallet and daemon JavaScript API.
HTML JavaScript Other
Branch: master
Clone or download

README.md

Monero JavaScript API

Compatible with Monero Core v14.1.0

Introduction

This project provides a modern JavaScript API for a Monero wallet and daemon.

The API currently relies on running instances of Monero Wallet RPC and Monero Daemon RPC. Primary goals of this project are to support a local wallet with client-side crypto and a MyMonero wallet which shares the view key with a 3rd party to scan the blockchain.

Main Features

  • General-purpose library with focus on ease-of-use
  • Clear object-oriented models to formalize Monero types and their relationships to each other
  • Powerful API to query transactions, transfers, and vouts by their attributes
  • Extensive test suite (130+ passing tests)
  • Fetch and process binary data from the daemon in JavaScript using client-side crypto

A quick reference of the wallet and daemon data models can be found here.

Wallet Sample Code

See tests for the most complete examples of using this library.

// create a wallet that uses a monero-wallet-rpc endpoint
let wallet = new MoneroWalletRpc({
  uri: "http://localhost:38083",
  user: "rpc_user",
  pass: "abc123"
});

// get wallet balance as BigInteger
let balance = await wallet.getBalance();  // e.g. 533648366742
   
// get wallet primary address
let primaryAddress = await wallet.getPrimaryAddress();  // e.g. 59aZULsUF3YNSKGiHz4J...
    
// get address and balance of subaddress [1, 0]
let subaddress = await wallet.getSubaddress(1, 0);
let subaddressBalance = subaddress.getBalance();
let subaddressAddress = subaddress.getAddress();

// get incoming and outgoing transfers
let transfers = await wallet.getTransfers();
for (let transfer of transfers) {
  let isIncoming = transfer.getIsIncoming();
  let amount = transfer.getAmount();
  let accountIdx = transfer.getAccountIndex();
  let height = transfer.getTx().getHeight();  // will be undefined if unconfirmed
}

// get incoming transfers to account 0
transfers = await wallet.getTransfers(new MoneroTransferRequest().setAccountIndex(0).setIsIncoming(true));
for (let transfer of transfers) {
  assert(transfer.getIsIncoming());
  assert.equal(transfer.getAccountIndex(), 0);
  let amount = transfer.getAmount();
  let height = transfer.getTx().getHeight();  // will be undefined if unconfirmed
}

// send to an address from account 0
let sentTx = await wallet.send(0, "74oAtjgE2dfD1bJBo4DW...", new BigInteger(50000));

// send to multiple destinations from multiple subaddresses in account 1 which can be split into multiple transactions
// see MoneroSendRequest.js for all request options
let sentTxs = await wallet.sendSplit({
  destinations: [
    { address: "7BV7iyk9T6kfs7cPfmn7...", amount: new BigInteger(50000) },
    { address: "78NWrWGgyZeYgckJhuxm...", amount: new BigInteger(50000) }
  ],
  accountIndex: 1,
  subaddressIndices: [0, 1],
  priority: MoneroSendPriority.UNIMPORTANT // no rush
});

// get all confirmed wallet transactions
for (let tx of await wallet.getTxs(new MoneroTxRequest().setIsConfirmed(true))) {
  let txId = tx.getId();                  // e.g. f8b2f0baa80bf6b...
  let txFee = tx.getFee();                // e.g. 750000
  let isConfirmed = tx.getIsConfirmed();  // e.g. true
}

// get a wallet transaction by id
let tx = await wallet.getTx("69a0d27a3e019526cb5a969ce9f65f1433b8069b68b3ff3c6a5b992a2983f7a2");
let txId = tx.getId();                  // e.g. 69a0d27a3e019526c...
let txFee = tx.getFee();                // e.g. 750000
let isConfirmed = tx.getIsConfirmed();  // e.g. true

// get confirmed transactions
for (let tx of await wallet.getTxs({isConfirmed: true})) {
  let txId = tx.getId();                 // e.g. f8b2f0baa80bf6b...
  let txFee = tx.getFee();               // e.g. 750000
  let isConfirmed = tx.getIsConfirmed(); // e.g. true
}

Daemon Sample Code

  // imports
  const MoneroDaemonRpc = require("../src/daemon/MoneroDaemonRpc");
  
  // create a daemon that uses a monero-daemon-rpc endpoint
  let daemon = new MoneroDaemonRpc({uri: "http://localhost:38081"});
  
  // get daemon info
  let height = await daemon.getHeight();           // e.g. 1523651
  let feeEstimate = await daemon.getFeeEstimate(); // e.g. 750000
  
  // get first 100 blocks as a binary request
  let blocks = await daemon.getBlocksByRange(0, 100);
  
  // get block info
  for (let block of blocks) {
    let blockHeight = block.getHeight();
    let blockId = block.getId();
    let txCount = block.getTxs().length;
  }
  
  // start mining to an address with 4 threads, not in the background, and ignoring the battery
  let address = "74oAtjgE2dfD1bJBo4DWW3E6qXCAwUDMgNqUurnX9b2xUvDTwMwExiXDkZskg7Vct37tRGjzHRqL4gH4H3oag3YyMYJzrNp";
  let numThreads = 4;
  let isBackground = false;
  let ignoreBattery = false;
  await daemon.startMining(address, numThreads, isBackground, ignoreBattery);
  
  // wait for the header of the next block added to the chain
  let nextBlockHeader = await daemon.getNextBlockHeader();
  let nextNumTxs = nextBlockHeader.getNumTxs();
  
  // stop mining
  await daemon.stopMining();

Running Tests

  1. Set up running instances of Monero Wallet RPC and Monero Daemon RPC with two test wallets named test_wallet_1 and test_wallet_2. The mnemonic phrase and public address of test_wallet_1 must match TestUtils.TEST_MNEMONIC and TestUtils.TEST_ADDRESS, respectively. Both wallets must be encrypted with a password which matches TestUtils.WALLET_RPC_PW ("supersecretpassword123"). See Monero RPC Setup.
  2. git clone --recurse-submodules https://github.com/woodser/monero-javascript.git
  3. npm install
  4. Configure the appropriate RPC endpoints and authentication by modifying WALLET_RPC_CONFIG and DAEMON_RPC_CONFIG in TestUtils.js.
  5. npm test

Note: some tests are failing as not all functionality is implemented.

Monero RPC Setup

  1. Download and extract the latest Monero CLI for your platform.

  2. Start Monero daemon locally: ./monerod --stagenet (or use a remote daemon).

  3. Create a wallet file if one does not exist. This is only necessary one time.

    • Create new / open existing: ./monero-wallet-cli --daemon-address http://localhost:38081 --stagenet
    • Restore from mnemonic seed: ./monero-wallet-cli --daemon-address http://localhost:38081 --stagenet --restore-deterministic-wallet
  4. Start monero-wallet-rpc (requires --wallet-dir to run tests):

    e.g. For wallet name test_wallet_1, user rpc_user, password abc123, stagenet: ./monero-wallet-rpc --daemon-address http://localhost:38081 --stagenet --rpc-bind-port 38083 --rpc-login rpc_user:abc123 --wallet-dir /Applications/monero-v0.13.0.2

Interfaces and Types

API Documentation

This library follows the wallet and daemon interfaces and models defined here.

Jsdoc is provided in the jsdoc folder (best viewed opening jsdoc/index.html in a browser).

The main interfaces are MoneroWallet.js and MoneroDaemon.js.

Here is the source code to the main interfaces, implementations, and models:

Project Goals

  • Offer consistent terminology and APIs for Monero's developer ecosystem
  • Build a wallet adapter for a local wallet which uses client-side crypto and a daemon
  • Build a wallet adapter for a MyMonero wallet which shares the view key with a 3rd party to scan the blockchain

See Also

Java reference implementation

C++ reference implementation

License

This project is licensed under MIT.

Donate

Please consider donating if you want to support this project. Thank you!

46FR1GKVqFNQnDiFkH7AuzbUBrGQwz2VdaXTDD4jcjRE8YkkoTYTmZ2Vohsz9gLSqkj5EM6ai9Q7sBoX4FPPYJdGKQQXPVz

You can’t perform that action at this time.