### start() Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/INDEX.md Starts the Bitcoin Wallet Node service. This function initializes the necessary components to begin operation. ```APIDOC ## start() ### Description Starts the Bitcoin Wallet Node service. This function initializes the necessary components to begin operation. ### Signature `start(): void` ### Parameters None ### Return Value `void` ``` -------------------------------- ### CLI Usage Examples Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/usage-examples.md Demonstrates how to execute the exporter script from the command line with different options for output destination and data filtering. ```bash node bin/exporter.js ./wallet.dat ``` ```bash node bin/exporter.js ./wallet.dat -o keys.jsonl ``` ```bash node bin/exporter.js ./wallet.dat --keys-only --json-pretty ``` -------------------------------- ### Install Dependencies Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/README.md Installs project dependencies using npm. ```bash npm install ``` -------------------------------- ### Install bitcoin-wallet-node Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/README.md Install the bitcoin-wallet-node package using npm. Ensure Node.js version 4.x or higher is installed. ```bash $ npm install ``` -------------------------------- ### start() Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/api-reference.md Begins streaming keys from the wallet database after the StreamingWorker is ready. It processes key records and emits them as JSON. This function does not return until the database processing is complete. ```APIDOC ## Function: start Begin streaming keys from the wallet database. ```javascript start() ``` ### Parameters None ### Return Type `void` ### Behavior - Waits for the internal StreamingWorker to be ready (polls with 50ms sleep intervals) - Begins reading the Berkeley DB database in reverse order (DB_PREV) - Processes key records and emits them as JSON via the configured emitter - Does not return until database processing is complete ### Notes - Must be called after `stream()` to initiate key export - For pause/resume functionality to work predictably, this function must be explicitly called (workers cannot rely on Node.js reactor pattern) - At least one record will be emitted before the worker honors a `pause()` call ### Example ```javascript const exporter = require('bitcoin-wallet-node'); exporter.stream({ filePath: './wallet.dat' }); exporter.start(); // Begin exporting keys ``` ``` -------------------------------- ### Robust Error Handling Example Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/errors.md This example demonstrates how to set up an 'error' handler before starting the export process and how to handle potential errors during data processing and export completion. It includes pre-flight checks for the wallet file and validates incoming JSON data. ```javascript const exporter = require('bitcoin-wallet-node'); const { EventEmitter } = require('events'); const fs = require('fs'); const path = require('path'); const emitter = new EventEmitter(); function exportWallet(walletPath) { // Pre-flight checks if (!fs.existsSync(walletPath)) { throw new Error(`Wallet not found: ${walletPath}`); } const stats = fs.statSync(walletPath); if (stats.size === 0) { throw new Error('Wallet file is empty'); } exporter.stream({ filePath: walletPath, emitter: emitter }); return new Promise((resolve, reject) => { let keyCount = 0; emitter.on('data', (value) => { keyCount++; try { JSON.parse(value); // Validate JSON } catch (e) { reject(new Error(`Invalid JSON in key ${keyCount}: ${e.message}`)); } }); emitter.on('error', (error) => { reject(error); }); emitter.on('close', () => { resolve({ keyCount, status: 'success' }); }); exporter.start(); }); } exportWallet('./wallet.dat') .then((result) => console.log(`Exported ${result.keyCount} keys`)) .catch((error) => console.error(`Export failed: ${error.message}`)); ``` -------------------------------- ### Compile and Run Unit Tests Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/dependencies/json/README.md Execute these commands in sequence to compile the project and run its unit tests. Ensure you are in the project's root directory before starting. ```shell $ mkdir build $ cd build $ cmake .. $ cmake --build . $ ctest ``` -------------------------------- ### Initialize and Configure Wallet Exporter Stream Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/api-reference.md Use this snippet to initialize the wallet exporter stream. Provide the path to your wallet.dat file and optionally a custom EventEmitter instance to handle events. If no emitter is provided, events will be piped to stdout. Ensure the wallet.dat file exists before starting. ```javascript const exporter = require('bitcoin-wallet-node'); const { EventEmitter } = require('events'); // Using custom emitter const emitter = new EventEmitter(); exporter.stream({ filePath: '/path/to/wallet.dat', emitter: emitter }); emitter.on('data', (value) => { const key = JSON.parse(value); console.log('Key type:', key.cipherText ? 'master' : 'derived'); }); emitter.on('error', (error) => { console.error('Export failed:', error.message); }); emitter.on('close', () => { console.log('Export complete'); }); exporter.start(); // Begin streaming ``` -------------------------------- ### Basic Usage Pattern for Bitcoin Wallet Node Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/README.md Demonstrates the typical workflow for using the bitcoin-wallet-node module: configuring the stream, listening for events like 'data', 'error', and 'close', and then starting the stream. Ensure you have an EventEmitter instance for handling events. ```javascript const exporter = require('bitcoin-wallet-node'); const { EventEmitter } = require('events'); // 1. Configure const emitter = new EventEmitter(); exporter.stream({ filePath: './wallet.dat', emitter: emitter }); // 2. Listen emitter.on('data', (keyJson) => { const key = JSON.parse(keyJson); console.log(key); }); emitter.on('error', (error) => { console.error('Error:', error.message); }); emitter.on('close', () => { console.log('Done'); }); // 3. Start exporter.start(); ``` -------------------------------- ### Start Key Streaming Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/api-reference.md Initiates the streaming of keys from the wallet database after configuration. Must be called after `stream()` to begin export. The function polls until the internal worker is ready and processes records in reverse order. ```javascript start() ``` ```javascript const exporter = require('bitcoin-wallet-node'); exporter.stream({ filePath: './wallet.dat' }); exporter.start(); // Begin exporting keys ``` -------------------------------- ### Stream Keys to File Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/usage-examples.md This example shows how to stream exported keys directly to a file in JSONL format. It uses an EventEmitter to capture data and write it to './exported-keys.jsonl'. Error handling and completion messages are included. ```javascript const exporter = require('bitcoin-wallet-node'); const { EventEmitter } = require('events'); const fs = require('fs'); const emitter = new EventEmitter(); const output = fs.createWriteStream('./exported-keys.jsonl'); exporter.stream({ filePath: './wallet.dat', emitter: emitter }); emitter.on('data', (value) => { output.write(value + '\n'); }); emitter.on('error', (error) => { console.error('Error:', error.message); process.exit(1); }); emitter.on('close', () => { output.end(); console.log('Keys exported to exported-keys.jsonl'); }); exporter.start(); ``` -------------------------------- ### Extract Bitcoin Keys for Analysis Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/README.md Streams keys from a wallet file and collects them into an array for analysis. Requires the 'emitter' object to be defined and the exporter to be started. ```javascript const keys = []; exporter.stream({ filePath: './wallet.dat', emitter }); emitter.on('data', (k) => keys.push(JSON.parse(k))); exporter.start(); ``` -------------------------------- ### Bitcoin Wallet Exporter CLI Tool Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/usage-examples.md This script wraps the exporter as a CLI tool using the 'commander' library. It parses arguments for wallet path, output file, and export options. Ensure 'commander' is installed via npm. ```javascript #!/usr/bin/env node const exporter = require('bitcoin-wallet-node'); const { EventEmitter } = require('events'); const fs = require('fs'); const path = require('path'); const { program } = require('commander'); // npm install commander program .version('1.0.0') .description('Bitcoin wallet.dat key exporter') .argument('', 'Path to wallet.dat file') .option('-o, --output ', 'Output file (default: stdout)') .option('--json-pretty', 'Pretty-print JSON output') .option('--keys-only', 'Export only derived keys (skip master key)') .parse(); const [walletPath] = program.args; const { output, jsonPretty, keysOnly } = program.opts(); // Validate input if (!fs.existsSync(walletPath)) { console.error(`Error: Wallet not found: ${walletPath}`); process.exit(1); } // Setup output stream let outputStream = process.stdout; if (output) { outputStream = fs.createWriteStream(output); } // Setup exporter const emitter = new EventEmitter(); let skipNext = keysOnly; exporter.stream({ filePath: walletPath, emitter: emitter }); emitter.on('data', (value) => { const key = JSON.parse(value); if (key.id !== undefined && skipNext) { // Skip master key return; } const output = jsonPretty ? JSON.stringify(key, null, 2) : value; outputStream.write(output + '\n'); }); emitter.on('error', (error) => { console.error(`Error: ${error.message}`); process.exit(1); }); emitter.on('close', () => { if (output) { console.error(`Exported to: ${output}`); } }); exporter.start(); ``` -------------------------------- ### Catch Database Open Error Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/errors.md Shows how to handle a 'Unable to open the db.' error, which occurs when Berkeley DB cannot open the wallet.dat file. This error is caught during start() execution. ```javascript const exporter = require('bitcoin-wallet-node'); const { EventEmitter } = require('events'); const emitter = new EventEmitter(); exporter.stream({ filePath: './wallet.dat', emitter: emitter }); emitter.on('error', (error) => { if (error.message === 'Unable to open the db.') { console.error('Cannot open wallet.dat:'); console.error(' - Verify file permissions (should be readable)'); console.error(' - Verify no other process is accessing the file'); console.error(' - Verify the file is a valid Bitcoin wallet.dat'); } }); exporter.start(); ``` -------------------------------- ### Process Keys with Custom Event Handler Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/usage-examples.md This example demonstrates how to use a custom EventEmitter to process exported keys. It includes handlers for 'data', 'error', and 'close' events, allowing for custom logic for master and derived keys. ```javascript const exporter = require('bitcoin-wallet-node'); const { EventEmitter } = require('events'); const emitter = new EventEmitter(); exporter.stream({ filePath: './wallet.dat', emitter: emitter }); emitter.on('data', (value) => { const key = JSON.parse(value); if (key.id !== undefined) { // Master key console.log(`Master key ID: ${key.id}`); console.log(` Derivation: ${key.derivationMethod}`); console.log(` Rounds: ${key.rounds}`); } else { // Derived key console.log(` Address key: ${key.pubKey.substring(0, 16)}...`); } }); emitter.on('error', (error) => { console.error('Export failed:', error.message); }); emitter.on('close', () => { console.log('Export complete'); }); exporter.start(); ``` -------------------------------- ### Pause and Resume Wallet Export Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/usage-examples.md Export wallet keys in batches, pausing and resuming the process as needed. This example demonstrates how to control the export flow using pause and resume methods, useful for managing large wallet files or performing actions on batches of keys. ```javascript const exporter = require('bitcoin-wallet-node'); const { EventEmitter } = require('events'); const emitter = new EventEmitter(); let masterKey = null; let derivedKeys = []; exporter.stream({ filePath: './wallet.dat', emitter: emitter }); exporter.pause(); // Pause immediately emitter.on('data', (value) => { const key = JSON.parse(value); if (key.id !== undefined) { masterKey = key; console.log('Master key loaded, resuming...'); exporter.resume(); } else { derivedKeys.push(key); // Collect 100 keys, then pause if (derivedKeys.length >= 100) { exporter.pause(); processBatch(); derivedKeys = []; console.log('Batch processed, resuming...'); exporter.resume(); } } }); emitter.on('close', () => { if (derivedKeys.length > 0) { processBatch(); } console.log('All keys processed'); }); emitter.on('error', (error) => { console.error('Error:', error.message); }); function processBatch() { console.log(`Processing ${derivedKeys.length} keys...`); // Process batch (e.g., decrypt, validate, store) } exporter.start(); ``` -------------------------------- ### REP_LEASE_ENTRY Structure Definition Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/dependencies/db-4.8.30.NC/rep/mlease.html This C structure defines the fields used to maintain lease information for each client site on the master. It includes EID, start and end times, lease LSN, and flags. ```c struct { int eid; /* EID of client site. */ db_timespec start_time; /* Unique time ID client echoes back on grants. */ db_timespec end_time; /* Master's lease expiration time. */ DB_LSN lease_lsn; /* Durable LSN this lease applies to. */ u_int32_t flags; /* Unused for now?? */ } REP_LEASE_ENTRY; ``` -------------------------------- ### Execute Wallet Data Processing Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/architecture.md Starts the data processing worker. The worker spawns a thread, opens the database, iterates through records in reverse, deserializes data, emits it to Node.js, and closes the database upon completion. ```javascript User calls: exporter.start() ↓ stream.start() called on worker ↓ Worker thread spawned, Execute() method runs ↓ Worker polls ready() with 50ms sleep intervals ↓ Database opened (db.open) ↓ Cursor created (db.cursor) ↓ Records iterated in reverse (DB_PREV): For each record matching key type: - Deserialize binary data - Build JSON object - Call writeToNode() to emit to Node.js - Check paused() state, sleep if paused ↓ After last record: dbc->close(), db.close() ↓ complete callback invoked: emitter.emit('close') ``` -------------------------------- ### Pause Key Streaming Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/api-reference.md Pauses the wallet exporter after the current key record is completed. If called before `start()`, it pauses immediately upon start. Note that pause is asynchronous and the worker checks the pause state between key emissions. ```javascript pause() ``` ```javascript const exporter = require('bitcoin-wallet-node'); const { EventEmitter } = require('events'); const emitter = new EventEmitter(); let keyCount = 0; exporter.stream({ filePath: './wallet.dat', emitter: emitter }); exporter.pause(); // Pause immediately emitter.on('data', (value) => { keyCount++; console.log(`Received key ${keyCount}`); if (keyCount >= 10) { exporter.close(); } }); exporter.start(); // Will emit at least 1-3 keys before pausing ``` -------------------------------- ### Run Tests Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/README.md Executes the test suite using npm. This command also builds the native addon if necessary. ```bash npm test ``` -------------------------------- ### Stream Lifecycle Control Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/README.md Functions to control the lifecycle of the wallet data stream, including starting, pausing, resuming, and closing the stream. ```APIDOC ## start ### Description Begins reading data from the configured wallet file. ### Method exporter.start(): void ``` ```APIDOC ## pause ### Description Pauses the stream after processing the current key. ### Method exporter.pause(): void ``` ```APIDOC ## resume ### Description Resumes the stream from a paused state. ### Method exporter.resume(): void ``` ```APIDOC ## close ### Description Closes the database connection and stops the stream. ### Method exporter.close(): void ``` -------------------------------- ### Filter Keys by Prefix Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/configuration.md Filters records based on the first byte of the key data. Only keys starting with 'm' or 'c' are processed. ```cpp if (!(keyData[1] == 'm' || keyData[1] == 'c')) { continue; } ``` -------------------------------- ### Configure Node-Gyp Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/README.md Configures the native addon build using node-gyp. ```bash npm run configure ``` -------------------------------- ### Explicit Type Retrieval Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/dependencies/json/README.md Shows how to explicitly retrieve values from a json object using the get() method. This is useful when the target type is known. ```cpp std::string vs = js.get(); bool vb = jb.get(); int vi = jn.get(); // etc. ``` -------------------------------- ### Build Native Addon Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/README.md Builds the native C++ addon for the project. ```bash npm run build ``` -------------------------------- ### Set Replication Lease Configuration Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/dependencies/db-4.8.30.NC/rep/mlease.html Call this method before `dbenv->rep_start` or `dbenv->repmgr_start` to enable lease-based replication. The `clock_scale_factor` compensates for clock skew between sites, and `flags` are currently unused. ```c int dbenv->rep_set_lease(DB_ENV *dbenv, u_int32_t clock_scale_factor, u_int32_t flags) ``` -------------------------------- ### Stream Options Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/README.md Configuration options for initializing the streaming process. Requires a file path to the wallet data and an EventEmitter to receive events. ```APIDOC ## stream ### Description Initializes the streaming process with the specified options. ### Parameters #### Request Body - **opts** (object) - Required - Options for streaming. - **filePath** (string) - Required - The path to the wallet data file. - **emitter** (EventEmitter) - Required - An instance of EventEmitter to receive 'data', 'error', and 'close' events. ``` -------------------------------- ### Berkeley DB Crypto Key Record Structure (Key) Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/architecture.md Defines the key structure for crypto key records in Berkeley DB. The key starts with 'c' followed by a public key. ```plaintext Key: [1 byte type] [33-66 bytes pubKey] [...] └─ 'c' (0x63) for ckey ``` -------------------------------- ### Configure Wallet Path with Environment Variables Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/README.md Sets the wallet file path using environment variables, falling back to a default location if not set. Ensure WALLET_PATH is configured or the HOME environment variable is available. ```javascript const walletPath = process.env.WALLET_PATH || `${process.env.HOME}/.bitcoin/wallet.dat`; exporter.stream({ filePath: walletPath }); ``` -------------------------------- ### Potentially Dangerous Custom Serializer Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/dependencies/json/README.md A cautionary example of a custom serializer that can lead to stack overflows if not implemented carefully. This highlights the risk of recursive calls when `basic_json::json_serializer` is not correctly defined. ```cpp template struct bad_serializer { template static void to_json(BasicJsonType& j, const T& value) { // this calls BasicJsonType::json_serializer::to_json(j, value); // if BasicJsonType::json_serializer == bad_serializer ... oops! j = value; } template static void to_json(const BasicJsonType& j, T& value) { // this calls BasicJsonType::json_serializer::from_json(j, value); // if BasicJsonType::json_serializer == bad_serializer ... oops! value = j.template get(); // oops! } }; ``` -------------------------------- ### JavaScript Wrapper Interface Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/architecture.md The JavaScript wrapper exposes core functionalities like streaming, starting, pausing, resuming, and closing the wallet service. These functions manage the lifecycle and interaction with the native module. ```javascript var stream; exports.stream = function(opts) { ... } exports.start = function() { ... } exports.pause = function() { ... } exports.resume = function() { ... } exports.close = function() { ... } ``` -------------------------------- ### Custom Serializer with ADL Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/dependencies/json/README.md Implement a custom serializer that uses Argument-Dependent Lookup (ADL) to find the correct `to_json` and `from_json` overloads. This example restricts types to those with a size less than or equal to 32 bytes. ```cpp // You should use void as a second template argument // if you don't need compile-time checks on T template::type> struct less_than_32_serializer { template static void to_json(BasicJsonType& j, T value) { // we want to use ADL, and call the correct to_json overload using nlohmann::to_json; // this method is called by adl_serializer, // this is where the magic happens to_json(j, value); } template static void from_json(const BasicJsonType& j, T& value) { // same thing here using nlohmann::from_json; from_json(j, value); } }; ``` -------------------------------- ### stream(opts) Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/api-reference.md Initializes and configures the wallet exporter stream. This function sets up the stream to read from a specified wallet.dat file and emit events for extracted keys. ```APIDOC ## Function: stream Initialize and configure the wallet exporter stream. ```javascript stream(opts) ``` ### Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | opts | Object | Yes | — | Configuration object for the exporter | | opts.filePath | string | Yes | — | Absolute or relative path to wallet.dat file to read | | opts.emitter | EventEmitter | No | new EventEmitter() | Custom EventEmitter instance to receive streaming events. If not provided, a new EventEmitter is created and data events are written to stdout | ### Return Type `void` Creates an internal stream object that is ready to be started. The stream is a `wallet.StreamingWorker` instance exposed from the native C++ module. ### Behavior - Validates that the wallet.dat file exists; throws immediately if it does not - Creates or uses a provided EventEmitter to emit events - If no emitter is provided, automatically pipes 'data' events to `process.stdout` - Does not begin reading the database until `start()` is called ### Events Emitted - **data**: JSON string. Emitted when a key is extracted from the wallet. See [Key Data Format](#key-data-format) - **close**: Emitted when all keys have been streamed and the database is closed - **error**: Error object. Emitted if file operations or database operations fail ### Throws/Rejects | Error Type | Condition | Location | |------------|-----------|----------| | DbFileException | wallet.dat file does not exist at specified filePath | wallet.cc:46 | | DbFileException | Unable to open the Berkeley DB | wallet.cc:64 | | DbFileException | Unable to obtain database cursor | wallet.cc:70 | ### Example ```javascript const exporter = require('bitcoin-wallet-node'); const { EventEmitter } = require('events'); // Using custom emitter const emitter = new EventEmitter(); exporter.stream({ filePath: '/path/to/wallet.dat', emitter: emitter }); emitter.on('data', (value) => { const key = JSON.parse(value); console.log('Key type:', key.cipherText ? 'master' : 'derived'); }); emitter.on('error', (error) => { console.error('Export failed:', error.message); }); emitter.on('close', () => { console.log('Export complete'); }); exporter.start(); // Begin streaming ``` **Source:** index.js:4-24 ``` -------------------------------- ### stream() Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/INDEX.md Initiates a stream of wallet events or data. Accepts optional configuration options. ```APIDOC ## stream() ### Description Initiates a stream of wallet events or data. Accepts optional configuration options. ### Signature `stream(opts: StreamOptions): void` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **opts** (`StreamOptions`) - Required - Configuration object for the stream. ``` -------------------------------- ### Initialize Wallet Data Stream Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/architecture.md Initiates the streaming of wallet data by providing a file path. The system checks for an emitter, creates a streaming worker with callbacks for data, completion, and errors, and validates the file path. ```javascript User calls: exporter.stream({ filePath: './wallet.dat' }) ↓ index.js checks opts.emitter (use provided or create new) ↓ index.js creates wallet.StreamingWorker with 3 callbacks: - dataCallback: emitter.emit('data', value) - completeCallback: emitter.emit('close') - errorCallback: emitter.emit('error', error) ↓ wallet.cc Stream constructor validates filePath exists ↓ StreamingWorker object assigned to module-level 'stream' variable ``` -------------------------------- ### Create and Manipulate JSON Objects Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/dependencies/json/README.md Shows how to create JSON objects, add key-value pairs using assignment and emplace, iterate through object members, find entries, check for key presence, and remove entries. ```cpp // create an object json o; o["foo"] = 23; o["bar"] = false; o["baz"] = 3.141; // also use emplace o.emplace("weather", "sunny"); // special iterator member functions for objects for (json::iterator it = o.begin(); it != o.end(); ++it) { std::cout << it.key() << " : " << it.value() << "\n"; } // find an entry if (o.find("foo") != o.end()) { // there is an entry with key "foo" } // or simpler using count() int foo_present = o.count("foo"); // 1 int fob_present = o.count("fob"); // 0 // delete an entry o.erase("foo"); ``` -------------------------------- ### Berkeley DB Master Key Record Structure (Key) Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/architecture.md Defines the key structure for master key records in Berkeley DB. The key starts with 'm' followed by a type byte and an ID. Additional data is unused. ```plaintext Key: [1 byte type] [4 bytes id] [...] | | └─ Additional data (unused) └─ 'm' (0x6D) for mkey └─ Numeric identifier (usually 1) ``` -------------------------------- ### resume() Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/INDEX.md Resumes the Bitcoin Wallet Node service after it has been paused. ```APIDOC ## resume() ### Description Resumes the Bitcoin Wallet Node service after it has been paused. ### Signature `resume(): void` ### Parameters None ### Return Value `void` ``` -------------------------------- ### Determine Bitcoin Home Directory Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/configuration.md Sets BITCOIN_HOME environment variable or defaults to ~/.bitcoin. Used to locate the wallet.dat file. ```javascript const path = require('path'); const bitcoinHome = process.env.BITCOIN_HOME || path.join(process.env.HOME, '.bitcoin'); const walletPath = path.join(bitcoinHome, 'wallet.dat'); exporter.stream({ filePath: walletPath }); ``` -------------------------------- ### StreamOptions Object Configuration Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/types.md Use this object to configure the stream function. Provide the absolute or relative path to the wallet.dat file. An optional EventEmitter can be provided to receive events; otherwise, a new one is created internally and events are piped to stdout. ```javascript { filePath: string; emitter?: EventEmitter; } ``` -------------------------------- ### Stream Constructor with Callbacks Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/architecture.md Shows the constructor for the Stream class, highlighting the initialization of StreamingWorker with data, complete, and error callbacks. ```cpp class Stream: public StreamingWorker { Stream(Callback *data, Callback *complete, Callback *error_callback, ...) : StreamingWorker(data, complete, error_callback) ``` -------------------------------- ### Create and Manipulate JSON Arrays Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/dependencies/json/README.md Demonstrates creating JSON arrays using push_back and emplace_back, iterating through elements, accessing and modifying values, and performing basic array operations like size, empty, type checking, and clearing. ```cpp // create an array using push_back json j; j.push_back("foo"); j.push_back(1); j.push_back(true); // also use emplace_back j.emplace_back(1.78); // iterate the array for (json::iterator it = j.begin(); it != j.end(); ++it) { std::cout << *it << '\n'; } // range-based for for (auto& element : j) { std::cout << element << '\n'; } // getter/setter const std::string tmp = j[0]; j[1] = 42; bool foo = j.at(2); // comparison j == "[\"foo\", 1, true]"_json; // true // other stuff j.size(); // 3 entries j.empty(); // false j.type(); // json::value_t::array j.clear(); // the array is empty again // convenience type checkers j.is_null(); j.is_boolean(); j.is_number(); j.is_object(); j.is_array(); j.is_string(); ``` -------------------------------- ### dbenv->rep_set_lease Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/dependencies/db-4.8.30.NC/rep/mlease.html Configures the replication lease mechanism. This method must be called before dbenv->rep_start or dbenv->repmgr_start. It sets the clock scale factor to compensate for clock skew between sites and enables the lease configuration. ```APIDOC ## dbenv->rep_set_lease ### Description Configures the replication lease mechanism. This method must be called before dbenv->rep_start or dbenv->repmgr_start. It sets the clock scale factor to compensate for clock skew between sites and enables the lease configuration. ### Method `dbenv->rep_set_lease(DB_ENV *dbenv, u_int32_t clock_scale_factor, u_int32_t flags)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **dbenv** (DB_ENV *) - Pointer to the environment handle. - **clock_scale_factor** (u_int32_t) - Interpreted as a percentage (greater than 100) representing the maximum skew between any two sites' clocks. This value will be divided by 100 on all sites for adjustments. - **flags** (u_int32_t) - Currently unused. ### Request Example ```c // Example usage (conceptual) dbenv->rep_set_lease(dbenv, 150, 0); ``` ### Response #### Success Response (0) Indicates successful configuration of the lease mechanism. #### Response Example None explicitly defined, success is indicated by return code 0. ERROR HANDLING: - The method will reject calls made after _rep_start. - Multiple calls prior to _rep_start will overwrite the previous clock skew value. ``` -------------------------------- ### Basic File Export to stdout Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/configuration.md Exports wallet data from a specified file path and streams the output to standard output. No custom emitter is provided, so data goes to stdout by default. ```javascript const exporter = require('bitcoin-wallet-node'); exporter.stream({ filePath: './wallet.dat' // No emitter; output goes to stdout }); exporter.start(); ``` -------------------------------- ### Instantiate StreamingWorker Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/api-reference.md Instantiate the StreamingWorker with necessary callbacks and options. The constructor expects data, complete, and error callbacks, along with an options object that can specify the filePath. ```javascript new wallet.StreamingWorker(dataCallback, completeCallback, errorCallback, options) ``` -------------------------------- ### Backup Bitcoin Keys to JSON Lines File Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/README.md Streams wallet keys and writes each key as a line to a specified JSON Lines file. Ensure the 'fs' module is imported and the output file path is correct. ```javascript const output = fs.createWriteStream('./keys.jsonl'); emitter.on('data', (k) => output.write(k + '\n')); ``` -------------------------------- ### Batch Processing Bitcoin Wallet Keys Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/usage-examples.md Use this class to export and process keys from a wallet file in batches. It emits progress events and handles batching logic, including pausing and resuming the export stream. ```javascript const exporter = require('bitcoin-wallet-node'); const { EventEmitter } = require('events'); class WalletBatchProcessor { constructor(walletPath, batchSize = 1000) { this.walletPath = walletPath; this.batchSize = batchSize; this.emitter = new EventEmitter(); this.currentBatch = []; this.totalProcessed = 0; this.masterKey = null; } export() { return new Promise((resolve, reject) => { exporter.stream({ filePath: this.walletPath, emitter: this.emitter }); this.emitter.on('data', (value) => { const key = JSON.parse(value); if (key.id !== undefined) { this.masterKey = key; this.onMasterKey(key); } else { this.currentBatch.push(key); if (this.currentBatch.length >= this.batchSize) { exporter.pause(); this.processBatch() .then(() => exporter.resume()) .catch((error) => reject(error)); } } }); this.emitter.on('error', (error) => { reject(new Error(`Export failed: ${error.message}`)); }); this.emitter.on('close', () => { if (this.currentBatch.length > 0) { this.processBatch().then(resolve).catch(reject); } else { resolve({ totalKeys: this.totalProcessed, masterKey: this.masterKey }); } }); exporter.start(); }); } onMasterKey(key) { console.log(`[Master] Derivation: ${key.derivationMethod}, Rounds: ${key.rounds}`); } async processBatch() { console.log(`[Batch] Processing ${this.currentBatch.length} keys...`); // Simulate processing (e.g., validation, storage) await new Promise((resolve) => setTimeout(resolve, 100)); this.totalProcessed += this.currentBatch.length; console.log(`[Batch] Total processed: ${this.totalProcessed}`); this.currentBatch = []; } } // Usage const processor = new WalletBatchProcessor('./wallet.dat', 500); processor.export() .then((result) => { console.log(`Completed: ${result.totalKeys} keys exported`); }) .catch((error) => { console.error(`Failed: ${error.message}`); }); ``` -------------------------------- ### Create JSON Object Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/dependencies/json/README.md Demonstrates creating a JSON object by assigning values to keys. The library infers the JSON type from the assigned C++ type. Explicitly creating empty arrays or objects is also shown. ```cpp // create an empty structure (null) json j; // add a number that is stored as double (note the implicit conversion of j to an object) j["pi"] = 3.141; // add a Boolean that is stored as bool j["happy"] = true; // add a string that is stored as std::string j["name"] = "Niels"; // add another null object by passing nullptr j["nothing"] = nullptr; // add an object inside the object j["answer"]["everything"] = 42; // add an array that is stored as std::vector (using an initializer list) j["list"] = { 1, 0, 2 }; // add another object (using an initializer list of pairs) j["object"] = { {"currency", "USD"}, {"value", 42.99} }; // instead, you could also write (which looks very similar to the JSON above) json j2 = { {"pi", 3.141}, {"happy", true}, {"name", "Niels"}, {"nothing", nullptr}, {"answer", { {"everything", 42} }}, {"list", {1, 0, 2}}, {"object", { {"currency", "USD"}, {"value", 42.99} }} }; // a way to express the empty array [] json empty_array_explicit = json::array(); // ways to express the empty object {} json empty_object_implicit = json({}); json empty_object_explicit = json::object(); // a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]] json array_not_object = { json::array({"currency", "USD"}), json::array({"value", 42.99}) }; ``` -------------------------------- ### Callback Invocation for Data and Error Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/architecture.md Demonstrates how data messages are sent using the 'data' callback and how errors are thrown, leading to the invocation of the error callback. ```cpp // For each key Message tosend("data", obj.dump()); writeToNode(progress, tosend); // On completion // Implicit; handled by StreamingWorker parent class // On error throw DbFileException("message"); // StreamingWorker catches and invokes error_callback ``` -------------------------------- ### Bitcoin Wallet Node Architecture Summary Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/README.md Illustrates the layered architecture of the bitcoin-wallet-node module, showing the flow from the JavaScript API to the C++ Addon, Berkeley DB, and finally the wallet.dat file. The C++ layer utilizes a worker thread to prevent blocking the main Node.js event loop. ```text JavaScript API (index.js) ↓ Native C++ Addon (wallet.cc) + streaming-worker-sdk ↓ Berkeley DB 4.8.30 ↓ wallet.dat File ``` -------------------------------- ### Load Native C++ Module Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/architecture.md This line loads the native C++ module for the wallet functionality. Ensure the build process correctly generates the module in the expected location. ```javascript var wallet = require('./build/Release/wallet'); ``` -------------------------------- ### Export Keys to Stdout Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/README.md Export keys from a wallet.dat file to standard output. This is the default behavior if no custom emitter is provided. ```javascript var exporter = require('bitcoin-wallet-node'); exporter({ filePath: './wallet.dat' }); //to stdout -or- send in your own emitter, just needs to be able to emit a data, close and error signal ``` -------------------------------- ### Set `REP_F_START_CALLED` Flag Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/dependencies/db-4.8.30.NC/rep/mlease.html This code block shows how the `REP_F_START_CALLED` flag is set within the `__rep_start` function after a successful initialization. ```c if (ret == 0 ) { REP_SYSTEM_LOCK F_SET(rep, REP_F_START_CALLED) REP_SYSTEM_UNLOCK } ``` -------------------------------- ### CBOR and MessagePack Serialization/Deserialization Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/dependencies/json/README.md Demonstrates how to serialize a JSON value into CBOR and MessagePack byte vectors, and then deserialize them back into JSON objects. This is useful for efficient data exchange over networks. ```cpp // create a JSON value json j = R"({\"compact\": true, \"schema\": 0})"_json; // serialize to CBOR std::vector v_cbor = json::to_cbor(j); // 0xa2, 0x67, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0xf5, 0x66, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x00 // roundtrip json j_from_cbor = json::from_cbor(v_cbor); // serialize to MessagePack std::vector v_msgpack = json::to_msgpack(j); // 0x82, 0xa7, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0xc3, 0xa6, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x00 // roundtrip json j_from_msgpack = json::from_msgpack(v_msgpack); ``` -------------------------------- ### Stream with filePath Option Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/configuration.md Use this snippet to specify the path to the wallet.dat file. It can be an absolute or relative path, and it's recommended to use environment variables for flexibility. ```javascript exporter.stream({ filePath: process.env.BITCOIN_WALLET || './wallet.dat' }); ``` -------------------------------- ### Import StreamingWorker from Native Module Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/_autodocs/api-reference.md Import the StreamingWorker class from the native C++ addon. This is the entry point for using the module. ```javascript const { StreamingWorker } = require('./build/Release/wallet'); ``` -------------------------------- ### Manual Arbitrary Type Conversion to JSON Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/dependencies/json/README.md Demonstrates the manual process of converting a custom struct 'person' to a JSON object by copying each member. This approach involves significant boilerplate code. ```cpp namespace ns { // a simple struct to model a person struct person { std::string name; std::string address; int age; }; } ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; // convert to JSON: copy each value into the JSON object json j; j["name"] = p.name; j["address"] = p.address; j["age"] = p.age; // ... // convert from JSON: copy each value from the JSON object ns::person p { j["name"].get(), j["address"].get(), j["age"].get() }; ``` -------------------------------- ### Custom `to_json` and `from_json` Functions Source: https://github.com/kleetus/bitcoin-wallet-node/blob/master/dependencies/json/README.md Provides the implementation for custom `to_json` and `from_json` functions required for automatic conversion of user-defined types to and from JSON. These functions must be defined in the same namespace as the custom type. ```cpp using nlohmann::json; namespace ns { void to_json(json& j, const person& p) { j = json{{"name", p.name}, {"address", p.address}, {"age", p.age}}; } void from_json(const json& j, person& p) { p.name = j.at("name").get(); p.address = j.at("address").get(); p.age = j.at("age").get(); } } // namespace ns ```