Introducing Electrum-SPV
As of today, 2023-XX-YY, there is now a new library you can use to talk with Electrum-Cash servers.
It is built on top of the Electrum-Cash library and provides new features to help you build smooth stable Bitcoin Cash applications.
How does it compare to Electrum-Cash?
The main difference between the two libraries is that it takes different approaches to responsibility.
The intended usage is a layered approach where developers choose where in the stack they want to take part,
allowing for more varied use-cases with needing a single library to understand and take on all possible responsibilities.
What does Electrum-Cash actually do?
Electrum-Cash is a library that aims to provide stability and performance when doing network requests to an Electrum server.
This means that it intends to allow you to communicate with any such server, using your preferred protocol version.
To this end, the Electrum-Cash library has a limited scope of responsibility and only understands a very small subset of communication it handles for you, specifically:
- How to establish a connection
- How to negotiate a protocol version
- How to send a generic request
- How to send and maintain subscriptions
While this might not seem like much, it does this in such a way that you can talk to one or multiple servers at once, giving you redundancy, performance, both or neither.
It's all up to you which servers you want to communicate with, and what version of the Electrum Protocol you want to use for your communication.
What does Electrum-SPV do differently?
In contrast to the Electrum-Cash library, the Electrum-SPV library only allow you to use a single specific protocol version.
As a result, sometimes it might not provide the specific features you want that are only available in new versions.
However, since it does understand the protocol version used, it can provide some distinct features:
- Every network request is fully typed and understood.
- The data sent in each request is parsed and validated for strictness.
- Any data that is or can be made immutable is opportunistically cached.
- Some data, like transactions and blocks, are SPV-validated¹.
- You can ask for partial data without needing to understand how to acquire it.
- Rich notifications for events like transaction detection, DSP detection, block inclusion verification etc.
¹ SPV validated means that it is cryptographically proven to be a part of a given block or blockchain.
Electrum SPV features in-depth
All protocol requests are fully typed
...
All data returned are parsed for strictness and errors.
TODO: Like the oracle library, set up utility functions for validating specific pieces of data, then use them to validate provided information from the electrum servers.
Immutable data is opportunistically cached.
...
Transparent automatic SPV validation.
...
Parsed human-friendly data structures
...
Rich event notifications to support most workflows
...
...
Examples
Tracking the blockchain.
import { initializeElectrum, electrumEvents } from 'electrum-cash-spv';
electrumEvents.on('BlockReceived', console.log);
await initializeElectrum('My Electrum Application');
Simple monitoring for transactions on an address.
import { initializeElectrum, electrumEvents, monitorAddress } from 'electrum-cash-spv';
electrumEvents.on('TransactionReceived', console.log);
await initializeElectrum('My Electrum Application');
await monitorAddress('bitcoincash:qr4aadjrpu73d2wxwkxkcrt6gqxgu6a7usxfm96fst');
Getting balance, UTXOs and transaction history.
The transaction life-cycle: (detect, verify and double-spends)
Direct network requests without parsing, caching etc.
You can also make use of the network request wrapping separately from the SPV validation, by initializing a network provider instead of the main library:
import { initializeNetworkProvider } from 'electrum-cash-spv';
await initializeNetworkProvider('My Electrum Application');
Address related requests
import { fetchHistory, fetchPendingTransactions, fetchBalance, fetchUnspentTransactionOutputs } from 'electrum-cash-spv';
const currentAddressHistory = await fetchHistory(someAddress);
console.log('history', currentAddressHistory);
const pendingTransactions = await fetchPendingTransactions(someAddress);
console.log('pending transactions', pendingTransactions);
const currentTrustedBalance = await fetchBalance(someAddress);
console.log('trusted balance', currentTrustedBalance);
const currentUnspentOutputs = await fetchUnspentTransactionOutputs(someAddress);
console.log('unspent outputs', currentUnspentOutputs);
Blockchain related requests
import { fetchBlockHeaderFromBlockHeight, fetchBlockHeaders, fetchBlockHeaderWithProofFromBlockHeight, fetchCurrentChainTip } from 'electrum-cash-spv';
const checkpointBlockHeader = await fetchBlockHeaderFromBlockHeight(someBlockHeight);
console.log('header from height', checkpointBlockHeader);
const blockHeaders = await fetchBlockHeaders(electrumCheckpoint.height, 3);
console.log('list of headers', blockHeaders);
const checkpointBlockHeaderWithProof = await fetchBlockHeaderWithProofFromBlockHeight(electrumCheckpoint.height, someBlockHeight);
console.log('header with proof', checkpointBlockHeaderWithProof);
const currentChainTip = await fetchCurrentChainTip();
console.log('current chaintip', currentChainTip);
Blockchain related requests
import { broadcastTransaction, fetchDoublespendProof, fetchTransaction, fetchTransactionBlockHeight, fetchTransactionProof } from 'electrum-cash-spv';
const transactionHash = await broadcastTransaction(someTransaction);
console.log('txhash', transactionHash);
const doublespendProof = await fetchDoublespendProof(someTransaction);
console.log('dsproof', doublespendProof);
const transactionHex = await fetchTransaction(someTransaction);
console.log('fetch transaction', transactionHex);
const transactionBlockHeight= await fetchTransactionBlockHeight(someTransaction);
console.log('fetch transaction height', transactionBlockHeight);
const transactionProof = await fetchTransactionProof(someTransaction, 800649);
console.log('fetch transaction proof', transactionProof);
Download (NPM)
Install the library with:
npm install @electrum-cash/spv
Support (GIT)