Account Monitor
Real-Time XRPL Account Monitoring with the Micro_Ledger
Real-Time XRPL Account Monitor
Welcome to the in-depth guide for the Micro Ledger's Real-Time XRPL Account Monitor mode! This mode transforms your portable IoT device into a powerful tool for tracking Xahau or XRPL account activity in real time.
Powered by the Seeed Xiao ESP32 S3, it connects to a WebSocket server to subscribe to ledger updates and specific account transactions, delivering visual, audio, and haptic alerts for events like payments and offers.
We'll break down the microLedgerAccount.ino sketch step by step, explaining how it works, key configurations, and how to customize it. Dive in to unlock the full potential of your Micro Ledger and bring blockchain monitoring to life!
Clone the Repository
You can use the following command, download a Zip file or Clone our repository from GitHub
https://github.com/Handy4ndy/ESP32-XRPL
git clone https://github.com/Handy4ndy/ESP32-XRPL.gitTo access tutorials and code, Navigate to Little_Ledger/Micro_Ledger. This open-source hub fuels your learning, start with the Basics then dive into Advanced network monitoring for XRPL and Xahau!
Overview Micro_Ledger/microLedgerAccount
As described in the README, this mode monitors a specified XRPL account via WebSocket, capturing validated ledgers and transaction details. It displays metrics on a 0.96" OLED screen, triggers alerts based on transaction types, and persists high scores in non-volatile memory.
Button controls allow for resetting, viewing scores, or entering low-power sleep mode. The code integrates WiFi connection, WebSocket handling, JSON parsing, and hardware interactions for a seamless experience.
Configuration Guide
WiFi: Hardcoded in connection.cpp (ssid/password). Update and re-upload.
WebSocket: Set host/port/url in globals. Examples in README for XRPL/Xahau servers.
Wallet Address: Replace YOUR_WALLET_RADDRESS with your XRPL address.
Alerts Customization: Modify RGB colors, melodies (using pitches.h), haptic duration in processTransaction.
Key Components and Setup
Hardware Requirements
Seeed Xiao ESP32 S3 microcontroller
0.96" OLED display (SSD1306, I2C on default pins)
Haptic motor (GPIO 8)
Button (GPIO 9, RTC-capable for wake-up)
Speaker (GPIO 7 for audio alerts)
USB cable for programming
2.4GHz WiFi network
Software Dependencies
Arduino IDE with ESP32 board support (add via Boards Manager)
Libraries (install via Library Manager):
Adafruit GFX
Adafruit SSD1306
ArduinoJson (for parsing WebSocket messages)
WebSocketsClient (for secure WebSocket connections)
WiFi (built-in for ESP32)
Preferences (for non-volatile storage)
pitches.h (included for melody notes)
Custom headers: loader.h/cpp (for startup animation), connection.h/cpp (WiFi handling), websocket.h/cpp (WebSocket management)
Getting Started
Open microLedgerAccount.ino in the Arduino IDE.
Configure WiFi credentials, WebSocket server, and wallet address (see Configuration section below).
Select "Seeed Xiao ESP32S3" as the board and the correct port.
Upload the sketch.
Monitor the Serial console at 9600 baud for logs.
The device will show a glitchy "Built On" loading animation with an XRPL logo (or Xahau if uncommented), connect to WiFi, establish a WebSocket session, and begin monitoring.
Code Breakdown
The microLedgerAccount.ino sketch is structured around setup, loop, and helper functions. Here's a detailed explanation of what's happening:
Includes and Global Variables
#include <WiFi.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ArduinoJson.h>
#include <WiFiManager.h>
#include <Preferences.h>
#include <esp_sleep.h>
#include "loader.h"
#include "connection.h"
#include "websocket.h"
#include "XRPL_Logo.h" // Bitmap for startup logo
// #include "Xahau_Logo.h" // Alternative startup logo
// Global flags and pins
bool isOff = false; // Tracks if device is in low-power mode
#define HAPTIC_PIN 8
#define BUTTON_PIN 9
// Button timing thresholds
#define SHORT_PRESS_TIME 2000
#define LONG_PRESS_TIME 5000
#define DEBOUNCE_DELAY 1000
unsigned long lastDebounceTime = 0;
bool buttonState = HIGH;
// WiFi reconnection
unsigned long lastReconnectAttempt = 0;
const unsigned long reconnectInterval = 5000;
// Preferences for high score persistence
Preferences preferences;
// Transaction tracking variables
int ledgerIndex = 0;
int transactionCount = 0;
int highScore = 0;
int highScoreLedger = 0;
int previousTransactionCount = -1;
// Configuration constants
const char* walletAddress = "YOUR_WALLET_RADDRESS"; // Replace with your XRPL address
const char* websocket_host = "s2.ripple.com"; // WebSocket server (change for Xahau)
const uint16_t websocket_port = 443;
const char* websocket_url = "/";
// OLED setup
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Subscription flag
bool accountSubscribed = false;What's Happening: These set up libraries for networking, display, JSON, storage, and sleep mode. Globals track state (e.g., button presses, connection status, ledger data) to enable responsive behavior without blocking the main loop.
WebSocket Message Callback: handleWebSocketMessage
void handleWebSocketMessage(const uint8_t* payload, size_t length) {
DynamicJsonDocument doc(4096);
DeserializationError error = deserializeJson(doc, payload, length);
if (error) { /* Error handling */ return; }
// Ledger update
if (doc["type"] == "ledgerClosed") {
ledgerIndex = doc["ledger_index"];
transactionCount = doc["txn_count"];
if (transactionCount > highScore) {
highScore = transactionCount;
highScoreLedger = ledgerIndex;
preferences.putInt("highScore", highScore); // Save to NVS
preferences.putInt("highLedger", highScoreLedger);
}
displayLedgerInfo(); // Update OLED
}
// Transaction update
if (doc["type"] == "transaction") {
processTransaction(doc); // Extract type, amount, etc., and display/alert
}
}What's Happening: This callback processes incoming WebSocket messages. For ledger closures, it updates counts, checks for new high scores, saves them persistently, and refreshes the display. For transactions, it calls processTransaction to handle specifics like payments (incoming/outgoing) and trigger alerts.
Display Functions: displayLedgerInfo, displayHighScore
These clear the OLED and print key metrics (ledger index, transaction count, high score). They use display.setTextSize(1) and setCursor for layout, ensuring real-time updates without flicker.
Transaction Processing: processTransaction
void processTransaction(const DynamicJsonDocument& doc) {
const char* transactionType = doc["transaction"]["TransactionType"];
const char* destination = doc["transaction"]["Destination"];
int amount = doc["transaction"]["Amount"].as<int>();
const char* source = doc["transaction"]["Account"];
// Display transaction details
display.clearDisplay();
display.print("Transaction Type: "); display.println(transactionType);
// ... (similar for amount, destination, source)
display.display();
delay(5000); // Show for 5s
displayLedgerInfo(); // Revert to ledger view
// Alert logic (not shown in truncated code): Trigger haptic, audio, and visuals.
}What's Happening: Parses transaction JSON for type (e.g., Payment, TrustSet), amount, and parties involved. Displays details temporarily, then reverts. Alerts (visual RGB changes, audio melodies via tone, haptic via digitalWrite) are triggered based on positive (e.g., incoming payment) or negative (e.g., offer cancel) events.
Setup Function
void setup() {
Serial.begin(9600);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(HAPTIC_PIN, OUTPUT);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { /* Error loop */ }
loader::show(display, XRPL_logo, 128, 64); // Startup animation
// loader::show(display, Xahau_logo, 128, 64); // additonal startup animation
WiFiConnection::connect(display); // Custom WiFi connection
// Load high score from NVS
preferences.begin("highscore", false);
highScore = preferences.getInt("highScore", 0);
highScoreLedger = preferences.getInt("highLedger", 0);
preferences.end();
WebSocketConnection::begin(display, websocket_host, websocket_port, websocket_url, handleWebSocketMessage);
}What's Happening: Initializes serial, pins, and OLED. Shows loading animation via loader.h. Connects to WiFi using custom module. Loads persisted high score. Starts WebSocket with callback for messages.
Loop Function
void loop() {
if (!WiFiConnection::isConnected()) {
handleWiFiConnectionDisplay(); // Retry and display status
} else if (!WebSocketConnection::isConnected()) {
handleWebSocketConnectionDisplay(); // Retry WebSocket
} else {
WebSocketConnection::loop(); // Process WebSocket events
if (!accountSubscribed) {
// Subscribe to account transactions
char subscribeAccount[100];
sprintf(subscribeAccount, "{\"command\": \"subscribe\", \"accounts\": [\"%s\"]}", walletAddress);
WebSocketConnection::send(subscribeAccount);
accountSubscribed = true;
}
// Button handling: Debounce and detect short/medium/long presses
int reading = digitalRead(BUTTON_PIN);
if (reading != buttonState) { lastDebounceTime = millis(); }
if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY) {
if (reading == LOW) {
unsigned long buttonPressStart = millis();
while (digitalRead(BUTTON_PIN) == LOW) { delay(50); }
unsigned long duration = millis() - buttonPressStart;
if (duration < SHORT_PRESS_TIME) {
displayHighScore(); // Short: Show high score
} else if (duration >= SHORT_PRESS_TIME && duration <= LONG_PRESS_TIME) {
// Medium: Reset device
display.print("Resetting device..."); display.display();
delay(2000); ESP.restart();
} else {
// Long: Toggle sleep mode
if (!isOff) {
// Enter sleep: Disconnect WebSocket/WiFi, turn off display
display.print("Entering Sleep Mode"); display.display();
WebSocketConnection::disconnect();
WiFi.disconnect(); WiFi.mode(WIFI_OFF);
display.ssd1306_command(SSD1306_DISPLAYOFF);
isOff = true;
} else {
// Wake and restart
display.print("Restarting device"); display.display();
delay(2000); ESP.restart();
}
}
}
}
}
}What's Happening: Main loop checks connections and retries if needed, displaying status. Handles WebSocket events. Subscribes to the account once connected. Debounces button input to detect presses: short for high score view, medium for reset, long for sleep/wake (disables power-hungry components, uses RTC for wake-up).
Debugging and Tips
Use Serial Monitor (9600 baud) for logs: connection status, JSON errors, button events.
Power Saving: Sleep mode reduces consumption, wake by holding the button for 5 seconds.
Extensions: Add WiFiManager for dynamic setup (code includes but not used).
Ready to Monitor?
This mode brings blockchain to your fingertips upload, configure, and watch your account thrive! For more modes or customizations, explore the GitHub repo. Happy monitoring! 🚀
Last updated
