monero-ts

repository·master·Indexed 42 days ago

https://github.com/woodser/monero-ts

A TypeScript library for building Monero applications. Version 0.11.15 supports RPC-based clients for daemon/wallet-rpc and WebAssembly-based client-side wallets for Node.js and browsers. It provides three wallet types: RPC wallets for server-side control, full WebAssembly wallets for client-side functionality, and lightweight keys-only wallets for basic key management. Includes a MoneroConnectionManager for managing multiple daemons with priority-based selection and automatic health checks.

Tokens
19.9K
Snippets
53
Records
71
Agent score
54%

What's inside monero-ts

  1. Compare the three wallet types

    master

    The library provides three distinct wallet implementations depending on your architecture:

    1. RPC wallet: Best for server-side applications where a monero-wallet-rpc instance is already running. The client acts as a remote controller for the RPC server.
    2. WebAssembly wallet: Best for client-side (browser) applications that need full wallet functionality and need to communicate directly with a Monero daemon.
    3. Keys-only wallet: A lightweight client-side option for applications that only require basic key management without full wallet features.
  2. How monero-ts interacts with Monero

    master

    The monero-ts library provides three distinct channels for interacting with the Monero network and wallet operations:

    1. RPC wallet servers: Communicating with remote wallet RPCs.
    2. RPC daemon servers: Communicating with remote Monero daemon RPCs.
    3. Wasm wallets: Performing native wallet operations locally via WebAssembly (Wasm). This enables trustless, client-side applications by removing the need for an intermediary RPC server.
  3. Understand the monero-ts data model hierarchy

    master

    The monero-ts data model follows a hierarchical structure representing the Monero blockchain and wallet state. Understanding this hierarchy is essential for navigating blocks, transactions, and fund movements.

    Hierarchy Overview

    1. Blocks (MoneroBlock): The top-level container.
    2. Transactions (MoneroTxWallet): Contained within blocks. Transactions represent the movement of funds and can be categorized by their direction relative to the wallet.
    3. Transfers:
      • Incoming Transfers (MoneroIncomingTransfer): Funds arriving in the wallet. A single transaction can contain multiple incoming transfers.
      • Outgoing Transfers (MoneroOutgoingTransfer): Funds leaving the wallet. A transaction typically has one outgoing transfer object.
    4. Outputs (MoneroOutputWallet): The specific Monero outputs received by the wallet as part of a transaction.

    Key Relationships

    • Transactions can have both incomingTransfers and an outgoingTransfer (e.g., when reallocating funds within the same wallet).
    • Outgoing Transfers may include destinations (address and amount pairs). Note: This destination information is stored locally within the wallet file and is not part of the on-chain blockchain data.
    • Outputs represent the actual UTXO-like entries received by the wallet.
  4. How view-only and offline wallets work together

    master

    To maintain high security, you can generate and submit transactions without exposing your private spend key to an internet-connected device by using a combination of view-only and offline wallets.

    Core Concepts

    • View-only wallet: Uses the privateViewKey to scan for received funds. It cannot determine which funds are spent or sign transactions because it lacks the private spend key.
    • Offline wallet: Contains the private spend key to sign transactions and determine spent funds, but is not connected to a daemon, meaning it cannot scan for new funds or broadcast transactions.

    Transaction Workflow

    To sign and submit a transaction securely, follow these steps:

    1. Scan: Use a view-only wallet to scan for received funds.
    2. Export Outputs: Export outputs from the view-only wallet to the offline wallet.
    3. Export Key Images: Export key images from the offline wallet back to the view-only wallet.
    4. Create Unsigned TX: Create an unsigned transaction using the view-only wallet.
    5. Sign: Sign the transaction using the offline wallet.
    6. Broadcast: Broadcast the signed transaction using the view-only wallet or any daemon.
    // 1. View-only wallet scans for funds
    let viewOnlyWallet = await moneroTs.createWalletFull({
      path: "my_view_only_wallet",
      networkType: moneroTs.MoneroNetworkType.STAGENET,
      primaryAddress: "55bcxMRhBWea6xxsot8moF1rdPprjJR2x4mfnNnTGgBJFgXa4gWXmWAYdUBKiRcJxy9AUAGJEg28DejvWdJU2VgUDrUvCHG",
      privateViewKey: "03d463f03ae547b11dfdf194a07ff82c14a3c6a3de559bd89c9a5e8dc5e9ae02",
      restoreHeight: 573936,
      server: {uri: "http://localhost:38081", username: "superuser", password: "abctesting123"}
    });
    await viewOnlyWallet.sync();
    
    // 2. Offline wallet created with seed
    let offlineWallet = await moneroTs.createWalletFull({
      path: "my_offline_wallet",
      networkType: moneroTs.MoneroNetworkType.STAGENET,
      seed: "spying swept ashtray going hence jester swagger cease spying unusual..."
    });
    
    // 3. Transfer data between wallets
    let outputsHex = await viewOnlyWallet.exportOutputs();
    await offlineWallet.importOutputs(outputsHex);
    
    let keyImageResult = await offlineWallet.exportKeyImages();
    await viewOnlyWallet.importKeyImages(keyImageResult.getKeyImages(), keyImageResult.getOffset());
    
    // 4. Create unsigned transaction
    let unsignedTx = await viewOnlyWallet.createTx({
      accountIndex: 0,
      address: "56j5AskbiNeeb2UAnS85qpey93GYs4VWB78hazZKGdsKCGHvEXUD6nuMQqXaiiY8SwMWsmtAEXS9kA2ko7hgNtGHKsEWyhv",
      amount: 250000000000n
    });
    
    // 5. Sign transaction offline
    let signedTxSet = await offlineWallet.signTxs(unsignedTx.getTxSet().getUnsignedTxHex());
    
    // 6. Broadcast via view-only wallet
    let txHashes = await viewOnlyWallet.submitTxs(signedTxSet.getSignedTxHex());
  5. Use keys-only Wasm wallets for offline generation

    master

    A keys-only wallet is a minimal Wasm wallet implementation designed for scenarios where you only need a wallet's static attributes (seed, address, keys) without needing to communicate with the Monero network, track balances, or initiate transfers.

    Benefits:

    • Ideal for offline wallet generators.
    • Significantly smaller file size (under 1/5 the size of a standard Wasm wallet), allowing for faster loading.

    Key attributes available via the MoneroWalletKeys class include the seed phrase, primary address, spend key, and view key.

  6. Install monero-ts in your project

    master

    To use monero-ts in your application, initialize your project and install the package via npm.

    Node.js Requirements

    • Node 20 LTS is recommended.
    • Node 16 and 18 LTS are supported but require the --experimental-wasm-threads flag.

    Browser Requirements

    1. Bundle your application code for a browser (e.g., using Webpack).
    2. Copy the assets from the ./dist directory of the monero-ts package to your web app's build directory.
    # Initialize project
    mkdir your_project && cd your_project && npm init
    
    # Install the library
    npm install monero-ts
    
    # Import in your code
    import moneroTs from "monero-ts";
  7. Enable SSL in web applications

    master

    To run a web application over HTTPS using self-signed certificates for local development:

    1. Generate Localhost Certificates:

      openssl req -x509 -newkey rsa:4096 -keyout localhost-key.pem -out localhost-cert.pem -days 365

      (Note: Dev certificates are available in src/test/browser with password abctesting123)

    2. Configure Server: Modify run_server.py to use the generated certificates by uncommenting the relevant lines.

    3. Start Server: Run ./bin/start_browser_test_server.sh and provide the certificate password when prompted.

    4. Browser Configuration:

      • Chrome: Navigate to chrome://flags/#allow-insecure-localhost and set "Allow invalid certificates for resources loaded from localhost" to Enabled.
      • Firefox: You must first manually authenticate by visiting the RPC endpoints directly in the browser (https://localhost:38081/json_rpc and https://localhost:38083/json_rpc) before accessing your web app at https://localhost:9100/.
    openssl req -x509 -newkey rsa:4096 -keyout localhost-key.pem -out localhost-cert.pem -days 365
  8. Build WebAssembly binaries from source

    master

    While pre-compiled binaries are provided in ./dist, you can build them from source using Emscripten. This is necessary for custom environments or ensuring specific dependency versions.

    Build Steps

    1. Setup Emscripten: Clone emsdk, install/activate version 3.1.66, and source emsdk_env.sh.
    2. Prepare monero-ts: Clone the repository recursively and run ./bin/update_submodules.sh.
    3. Build monero-cpp: Build the monero-cpp submodule (located in ./external/monero-cpp) following its specific instructions. Ensure unbound 1.19.0 is installed in ~/unbound-1.19.0.
    4. Compile: Run ./bin/build_all.sh (ensure Monero project dependencies are installed on your system).
  9. Create an RPC wallet

    master

    An RPC wallet is a client that connects to an existing monero-wallet-rpc server. Use moneroTs.connectToWalletRpc to establish the connection and MoneroWalletRpc.createWallet() to create the wallet on the server.

    Refer to the MoneroWalletRpc.createWallet() documentation for a full list of available options.

    // create a client connected to monero-wallet-rpc
    let walletRpc = await moneroTs.connectToWalletRpc("http://localhost:38081", "superuser", "abctesting123");
    
    // create a wallet on monero-wallet-rpc
    await walletRpc.createWallet({
      path: "mywallet",
      password: "supersecretpassword",
      seed: "coexist igloo pamphlet lagoon...",
      restoreHeight: 1543218
    }); 
  10. Transfer data between view-only and offline wallets

    master

    To synchronize the state of a view-only wallet and an offline wallet, you must exchange outputs and key images.

    Exporting and Importing Outputs

    Use exportOutputs() on the view-only wallet to get the hex representation of outputs, then use importOutputs(outputsHex) on the offline wallet.

    Exporting and Importing Key Images

    Use exportKeyImages() on the offline wallet to get a result containing key images and an offset. Use importKeyImages(keyImages, offset) on the view-only wallet to complete the synchronization.

    // Export from view-only
    let outputsHex = await viewOnlyWallet.exportOutputs();
    // Import to offline
    await offlineWallet.importOutputs(outputsHex);
    
    // Export from offline
    let keyImageResult = await offlineWallet.exportKeyImages();
    // Import to view-only
    await viewOnlyWallet.importKeyImages(keyImageResult.getKeyImages(), keyImageResult.getOffset());
  11. Install Node.js and npm

    master

    Node.js is required to run monero-ts programs in a terminal environment, and npm (Node Package Manager) is required to install the monero-ts module. Use your system's package manager to install them.

    ### Debian/Ubuntu:
    
    1. Install node.js by typing `$ sudo apt-get install nodejs`.
    2. Install npm by typing `$ sudo apt-get install npm`.
    
    ### Fedora:
    
    1. Install node.js:
      `$ sudo dnf install nodejs`
    2. Install npm:
      `$ sudo dnf install npm`