Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@samouraiwallet/electrum-client

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@samouraiwallet/electrum-client - npm Package Compare versions

Comparing version 1.4.0 to 1.5.0

biome.json

9

CHANGELOG.md
# Changelog
## 1.5.0 (2024-09-27)
- Removed unnecessary boilerplate (TlsSocketWrapper)
- Added static `createClient` method for more convenience
- Updated dependencies
- (DEV) - Updated to Node.js v18
- (DEV) - Swtiched to PNPM
- (DEV) - Switched from eslint to biome
## 1.4.0 (2023-05-24)

@@ -4,0 +13,0 @@ - Updated keepAlive to use interval instead of timeout

48

dist/index.d.ts

@@ -1,7 +0,7 @@

import { Client } from './lib/client.js';
import { Callbacks, ElectrumConfig, ElectrumRequestBatchParams, ElectrumRequestParams, PersistencePolicy, Protocol } from './types';
import { Client } from "./lib/client.js";
import type { Callbacks, CreateClientParams, ElectrumConfig, ElectrumRequestBatchParams, ElectrumRequestParams, PersistencePolicy, Protocol } from "./types";
export declare class ElectrumClient extends Client {
private onConnectCallback;
private onCloseCallback;
private onLogCallback;
private readonly onConnectCallback;
private readonly onCloseCallback;
private readonly onLogCallback;
private timeLastCall;

@@ -12,8 +12,42 @@ private persistencePolicy;

versionInfo: [string, string];
/**
* Constructs an instance of ElectrumClient.
*
* @param {number} port - The port number to connect to.
* @param {string} host - The host address to connect to.
* @param {Protocol} protocol - The protocol to use for the connection.
* @param {Callbacks} [callbacks] - Optional callbacks for connection events.
*/
constructor(port: number, host: string, protocol: Protocol, callbacks?: Callbacks);
/**
* Creates an instance of ElectrumClient and initializes it with the provided configuration.
*
* @param {CreateClientParams} params - The parameters required to create and initialize the client.
* @param {number} params.port - The port number to connect to.
* @param {string} params.host - The host address to connect to.
* @param {Protocol} params.protocol - The protocol to use for the connection.
* @param {Callbacks} [params.callbacks] - Optional callbacks for connection events.
* @param {ElectrumConfig} params.electrumConfig - The Electrum configuration to use.
* @param {PersistencePolicy} [params.persistencePolicy] - Optional persistence policy for the client.
*
* @returns {Promise<ElectrumClient>} A promise that resolves to an initialized ElectrumClient instance.
*/
static createClient(params: CreateClientParams): Promise<ElectrumClient>;
/**
* Initializes the Electrum client with the provided configuration and persistence policy.
*
* @param {ElectrumConfig} electrumConfig - The Electrum configuration to use.
* @param {PersistencePolicy} [persistencePolicy] - Optional persistence policy for the client.
* @returns {Promise<ElectrumClient>} A promise that resolves to the initialized ElectrumClient instance.
*/
initElectrum(electrumConfig: ElectrumConfig, persistencePolicy?: PersistencePolicy): Promise<ElectrumClient>;
protected request(method: string, params: ElectrumRequestParams): Promise<unknown>;
protected requestBatch(method: string, params: ElectrumRequestParams, secondParam?: ElectrumRequestBatchParams): Promise<unknown>;
protected request<T>(method: string, params: ElectrumRequestParams<T>): Promise<unknown>;
protected requestBatch<T>(method: string, params: ElectrumRequestParams<T>, secondParam?: ElectrumRequestBatchParams): Promise<unknown>;
protected onClose(): void;
private keepAlive;
/**
* Closes the Electrum client connection and stops the keep-alive ping interval.
*
* @returns {void}
*/
close(): void;

@@ -20,0 +54,0 @@ private reconnect;

155

dist/index.js

@@ -1,10 +0,20 @@

import { Client } from './lib/client.js';
import { Client } from "./lib/client.js";
export class ElectrumClient extends Client {
/**
* Constructs an instance of ElectrumClient.
*
* @param {number} port - The port number to connect to.
* @param {string} host - The host address to connect to.
* @param {Protocol} protocol - The protocol to use for the connection.
* @param {Callbacks} [callbacks] - Optional callbacks for connection events.
*/
constructor(port, host, protocol, callbacks) {
super(port, host, protocol, callbacks);
this.onConnectCallback = (callbacks && callbacks.onConnect) ? callbacks.onConnect : null;
this.onCloseCallback = (callbacks && callbacks.onClose) ? callbacks.onClose : null;
this.onLogCallback = (callbacks && callbacks.onLog) ? callbacks.onLog : (str) => {
console.log(str);
};
this.onConnectCallback = callbacks?.onConnect ?? null;
this.onCloseCallback = callbacks?.onClose ?? null;
this.onLogCallback = callbacks?.onLog
? callbacks.onLog
: (str) => {
console.log(str);
};
this.timeLastCall = 0;

@@ -19,8 +29,32 @@ this.persistencePolicy = {

this.pingInterval = null;
this.versionInfo = ['', ''];
this.versionInfo = ["", ""];
}
/**
* Creates an instance of ElectrumClient and initializes it with the provided configuration.
*
* @param {CreateClientParams} params - The parameters required to create and initialize the client.
* @param {number} params.port - The port number to connect to.
* @param {string} params.host - The host address to connect to.
* @param {Protocol} params.protocol - The protocol to use for the connection.
* @param {Callbacks} [params.callbacks] - Optional callbacks for connection events.
* @param {ElectrumConfig} params.electrumConfig - The Electrum configuration to use.
* @param {PersistencePolicy} [params.persistencePolicy] - Optional persistence policy for the client.
*
* @returns {Promise<ElectrumClient>} A promise that resolves to an initialized ElectrumClient instance.
*/
static async createClient(params) {
const client = new ElectrumClient(params.port, params.host, params.protocol, params.callbacks);
return await client.initElectrum(params.electrumConfig, params.persistencePolicy);
}
/**
* Initializes the Electrum client with the provided configuration and persistence policy.
*
* @param {ElectrumConfig} electrumConfig - The Electrum configuration to use.
* @param {PersistencePolicy} [persistencePolicy] - Optional persistence policy for the client.
* @returns {Promise<ElectrumClient>} A promise that resolves to the initialized ElectrumClient instance.
*/
async initElectrum(electrumConfig, persistencePolicy) {
this.persistencePolicy = {
...this.persistencePolicy,
...persistencePolicy
...persistencePolicy,
};

@@ -51,6 +85,6 @@ this.electrumConfig = electrumConfig;

const list = [
'server.peers.subscribe',
'blockchain.numblocks.subscribe',
'blockchain.headers.subscribe',
'blockchain.address.subscribe',
"server.peers.subscribe",
"blockchain.numblocks.subscribe",
"blockchain.headers.subscribe",
"blockchain.address.subscribe",
];

@@ -87,3 +121,4 @@ for (const event of list)

this.pingInterval = setInterval(() => {
if (this.timeLastCall !== 0 && Date.now() > this.timeLastCall + pingPeriod) {
if (this.timeLastCall !== 0 &&
Date.now() > this.timeLastCall + pingPeriod) {
this.server_ping().catch((error) => {

@@ -95,2 +130,7 @@ this.log(`Keep-Alive ping failed: ${error}`);

}
/**
* Closes the Electrum client connection and stops the keep-alive ping interval.
*
* @returns {void}
*/
close() {

@@ -101,8 +141,16 @@ super.close();

}
this.reconnect = this.reconnect = this.onClose = this.keepAlive = () => Promise.resolve(this);
this.reconnect =
this.reconnect =
this.onClose =
this.keepAlive =
() => Promise.resolve(this); // dirty hack to make it stop reconnecting
}
reconnect() {
this.log('Electrum attempting reconnect...');
this.log("Electrum attempting reconnect...");
this.initSocket();
return this.persistencePolicy == null ? this.initElectrum(this.electrumConfig) : this.initElectrum(this.electrumConfig, this.persistencePolicy);
return this.persistencePolicy == null
? // biome-ignore lint/style/noNonNullAssertion:
this.initElectrum(this.electrumConfig)
: // biome-ignore lint/style/noNonNullAssertion:
this.initElectrum(this.electrumConfig, this.persistencePolicy);
}

@@ -112,105 +160,112 @@ log(str) {

}
// ElectrumX API
server_version(client_name, protocol_version) {
return this.request('server.version', [client_name, protocol_version]);
return this.request("server.version", [client_name, protocol_version]);
}
server_banner() {
return this.request('server.banner', []);
return this.request("server.banner", []);
}
server_features() {
return this.request('server.features', []);
return this.request("server.features", []);
}
server_ping() {
return this.request('server.ping', []);
return this.request("server.ping", []);
}
server_addPeer(features) {
return this.request('server.add_peer', [features]);
return this.request("server.add_peer", [features]);
}
serverDonation_address() {
return this.request('server.donation_address', []);
return this.request("server.donation_address", []);
}
serverPeers_subscribe() {
return this.request('server.peers.subscribe', []);
return this.request("server.peers.subscribe", []);
}
blockchainAddress_getProof(address) {
return this.request('blockchain.address.get_proof', [address]);
return this.request("blockchain.address.get_proof", [address]);
}
blockchainScripthash_getBalance(scripthash) {
return this.request('blockchain.scripthash.get_balance', [scripthash]);
return this.request("blockchain.scripthash.get_balance", [scripthash]);
}
blockchainScripthash_getBalanceBatch(scripthashes) {
return this.requestBatch('blockchain.scripthash.get_balance', scripthashes);
return this.requestBatch("blockchain.scripthash.get_balance", scripthashes);
}
blockchainScripthash_listunspentBatch(scripthashes) {
return this.requestBatch('blockchain.scripthash.listunspent', scripthashes);
return this.requestBatch("blockchain.scripthash.listunspent", scripthashes);
}
blockchainScripthash_getHistory(scripthash) {
return this.request('blockchain.scripthash.get_history', [scripthash]);
return this.request("blockchain.scripthash.get_history", [scripthash]);
}
blockchainScripthash_getHistoryBatch(scripthashes) {
return this.requestBatch('blockchain.scripthash.get_history', scripthashes);
return this.requestBatch("blockchain.scripthash.get_history", scripthashes);
}
blockchainScripthash_getMempool(scripthash) {
return this.request('blockchain.scripthash.get_mempool', [scripthash]);
return this.request("blockchain.scripthash.get_mempool", [scripthash]);
}
blockchainScripthash_listunspent(scripthash) {
return this.request('blockchain.scripthash.listunspent', [scripthash]);
return this.request("blockchain.scripthash.listunspent", [scripthash]);
}
blockchainScripthash_subscribe(scripthash) {
return this.request('blockchain.scripthash.subscribe', [scripthash]);
return this.request("blockchain.scripthash.subscribe", [scripthash]);
}
blockchainBlock_getHeader(height) {
return this.request('blockchain.block.get_header', [height]);
return this.request("blockchain.block.get_header", [height]);
}
blockchainBlock_headers(start_height, count) {
return this.request('blockchain.block.headers', [start_height, count]);
return this.request("blockchain.block.headers", [start_height, count]);
}
blockchainEstimatefee(number) {
return this.request('blockchain.estimatefee', [number]);
return this.request("blockchain.estimatefee", [number]);
}
blockchainHeaders_subscribe() {
return this.request('blockchain.headers.subscribe', []);
return this.request("blockchain.headers.subscribe", []);
}
blockchain_relayfee() {
return this.request('blockchain.relayfee', []);
return this.request("blockchain.relayfee", []);
}
blockchainTransaction_broadcast(rawtx) {
return this.request('blockchain.transaction.broadcast', [rawtx]);
return this.request("blockchain.transaction.broadcast", [rawtx]);
}
blockchainTransaction_get(tx_hash, verbose = false) {
return this.request('blockchain.transaction.get', [tx_hash, verbose]);
return this.request("blockchain.transaction.get", [tx_hash, verbose]);
}
blockchainTransaction_getBatch(tx_hashes, verbose = false) {
return this.requestBatch('blockchain.transaction.get', tx_hashes, verbose);
return this.requestBatch("blockchain.transaction.get", tx_hashes, verbose);
}
blockchainTransaction_getMerkle(tx_hash, height) {
return this.request('blockchain.transaction.get_merkle', [tx_hash, height]);
return this.request("blockchain.transaction.get_merkle", [tx_hash, height]);
}
mempool_getFeeHistogram() {
return this.request('mempool.get_fee_histogram', []);
return this.request("mempool.get_fee_histogram", []);
}
// ---------------------------------
// protocol 1.1 deprecated method
// ---------------------------------
blockchainUtxo_getAddress(tx_hash, index) {
return this.request('blockchain.utxo.get_address', [tx_hash, index]);
return this.request("blockchain.utxo.get_address", [tx_hash, index]);
}
blockchainNumblocks_subscribe() {
return this.request('blockchain.numblocks.subscribe', []);
return this.request("blockchain.numblocks.subscribe", []);
}
// ---------------------------------
// protocol 1.2 deprecated method
// ---------------------------------
blockchainBlock_getChunk(index) {
return this.request('blockchain.block.get_chunk', [index]);
return this.request("blockchain.block.get_chunk", [index]);
}
blockchainAddress_getBalance(address) {
return this.request('blockchain.address.get_balance', [address]);
return this.request("blockchain.address.get_balance", [address]);
}
blockchainAddress_getHistory(address) {
return this.request('blockchain.address.get_history', [address]);
return this.request("blockchain.address.get_history", [address]);
}
blockchainAddress_getMempool(address) {
return this.request('blockchain.address.get_mempool', [address]);
return this.request("blockchain.address.get_mempool", [address]);
}
blockchainAddress_listunspent(address) {
return this.request('blockchain.address.listunspent', [address]);
return this.request("blockchain.address.listunspent", [address]);
}
blockchainAddress_subscribe(address) {
return this.request('blockchain.address.subscribe', [address]);
return this.request("blockchain.address.subscribe", [address]);
}
}
//# sourceMappingURL=index.js.map

@@ -1,22 +0,19 @@

/// <reference types="node" />
import { EventEmitter } from 'node:events';
import { Protocol, Callbacks, ElectrumRequestBatchParams, ElectrumRequestParams } from '../types';
import { EventEmitter } from "node:events";
import type { Callbacks, ElectrumRequestBatchParams, ElectrumRequestParams, Protocol } from "../types";
export declare abstract class Client {
private id;
private port;
private host;
private callback_message_queue;
protected subscribe: EventEmitter;
private mp;
private readonly protocol;
private conn;
private status;
private protocol;
private onErrorCallback;
constructor(port: number, host: string, protocol: Protocol, callbacks?: Callbacks);
protected initSocket(protocol?: Protocol): void;
private readonly host;
private readonly port;
private readonly onErrorCallback;
protected constructor(port: number, host: string, protocol: Protocol, callbacks?: Callbacks);
protected initSocket(): void;
protected connect(): Promise<void>;
private connectSocket;
close(): void;
protected request(method: string, params: ElectrumRequestParams): Promise<unknown>;
protected requestBatch(method: string, params: ElectrumRequestParams, secondParam: ElectrumRequestBatchParams): Promise<unknown>;
protected request<T>(method: string, params: ElectrumRequestParams<T>): Promise<unknown>;
protected requestBatch<T>(method: string, params: ElectrumRequestParams<T>, secondParam: ElectrumRequestBatchParams): Promise<unknown>;
private response;

@@ -23,0 +20,0 @@ private onMessage;

@@ -1,11 +0,12 @@

import net from 'node:net';
import { EventEmitter } from 'node:events';
import { TlsSocketWrapper } from './tls-socket-wrapper.js';
import * as util from './util.js';
const TIMEOUT = 5000;
import { EventEmitter } from "node:events";
import net from "node:net";
import tls from "node:tls";
import * as util from "./util.js";
const TIMEOUT = 60000;
export class Client {
constructor(port, host, protocol, callbacks) {
this.id = 0;
this.host = host;
this.port = port;
this.host = host;
this.protocol = protocol;
this.callback_message_queue = new Map();

@@ -16,58 +17,40 @@ this.subscribe = new EventEmitter();

});
this.conn = null;
this.status = 0;
this.protocol = protocol;
this.onErrorCallback = (callbacks && callbacks.onError) ? callbacks.onError : null;
this.initSocket(protocol);
if (protocol !== "tcp" && protocol !== "tls" && protocol !== "ssl") {
throw new Error("unknown protocol");
}
this.onErrorCallback = callbacks?.onError ?? null;
this.initSocket();
}
initSocket(protocol = this.protocol) {
switch (protocol) {
case 'tcp':
this.conn = new net.Socket();
break;
case 'tls':
case 'ssl':
this.conn = new TlsSocketWrapper();
break;
default:
throw new Error('unknown protocol');
}
initSocket() {
this.conn =
this.protocol === "tls" || this.protocol === "ssl"
? tls.connect({ host: this.host, port: this.port, rejectUnauthorized: false }, () => {
this.conn?.setTimeout(0);
this.onConnect();
})
: net.connect({ host: this.host, port: this.port }, () => {
this.conn?.setTimeout(0);
this.onConnect();
});
this.conn.setTimeout(TIMEOUT);
this.conn.setEncoding('utf8');
this.conn.setEncoding("utf8");
this.conn.setKeepAlive(true, 0);
this.conn.setNoDelay(true);
this.conn.on('connect', () => {
this.conn && this.conn.setTimeout(0);
this.onConnect();
});
this.conn.on('close', () => {
this.conn.on("close", () => {
this.onClose();
});
this.conn.on('data', (chunk) => {
this.conn && this.conn.setTimeout(0);
this.conn.on("data", (chunk) => {
this.conn?.setTimeout(0);
this.onRecv(chunk);
});
this.conn.on('error', (e) => {
this.conn.on("error", (e) => {
this.onError(e);
});
this.status = 0;
}
connect() {
if (this.conn) {
if (this.status === 1) {
return Promise.resolve();
return new Promise((resolve) => {
if (this.conn && this.conn.readyState === "open") {
return resolve();
}
this.status = 1;
return this.connectSocket(this.conn, this.port, this.host);
}
else {
return Promise.reject(new Error('There is no socket to initialize connection on.'));
}
}
connectSocket(conn, port, host) {
return new Promise((resolve, reject) => {
const errorHandler = (e) => reject(e);
conn.on('error', errorHandler);
conn.connect(port, host, () => {
conn.removeListener('error', errorHandler);
this.conn?.once(this.protocol === "tcp" ? "connect" : "secureConnect", () => {
resolve();

@@ -78,12 +61,11 @@ });

close() {
if (this.status === 0) {
if (this.conn && this.conn.readyState === "closed") {
return;
}
this.conn && this.conn.end();
this.conn && this.conn.destroy();
this.status = 0;
this.conn?.end();
this.conn?.destroy();
}
request(method, params) {
if (this.status === 0) {
return Promise.reject(new Error('Connection to server lost, please retry'));
if (this.conn && this.conn.readyState === "closed") {
return Promise.reject(new Error("Connection to server lost, please retry"));
}

@@ -94,8 +76,8 @@ return new Promise((resolve, reject) => {

this.callback_message_queue.set(id, util.createPromiseResult(resolve, reject));
this.conn && this.conn.write(`${content}\n`);
this.conn?.write(`${content}\n`);
});
}
requestBatch(method, params, secondParam) {
if (this.status === 0) {
return Promise.reject(new Error('Connection to server lost, please retry'));
if (this.conn && this.conn.readyState === "closed") {
return Promise.reject(new Error("Connection to server lost, please retry"));
}

@@ -115,5 +97,6 @@ return new Promise((resolve, reject) => {

}
const content = `[${contents.join(',')}]`;
const content = `[${contents.join(",")}]`;
this.callback_message_queue.set(this.id, util.createPromiseResultBatch(resolve, reject, arguments_far_calls));
this.conn && this.conn.write(`${content}\n`);
// callback will exist only for max id
this.conn?.write(`${content}\n`);
});

@@ -124,2 +107,3 @@ }

if (!msg.id && msg[0] && msg[0].id) {
// this is a response from batch request
for (const m of msg) {

@@ -146,7 +130,7 @@ if (m.id && this.callback_message_queue.has(m.id)) {

console.log(msg);
throw new Error('Error getting callback while handling response');
throw new Error("Error getting callback while handling response");
}
}
onMessage(body, n) {
const msg = JSON.parse(body || '');
const msg = JSON.parse(body || "");
if (Array.isArray(msg)) {

@@ -164,5 +148,4 @@ this.response(msg);

onClose() {
this.status = 0;
for (const [key, fn] of this.callback_message_queue.entries()) {
fn(new Error('close connect'));
fn(new Error("close connect"));
this.callback_message_queue.delete(key);

@@ -169,0 +152,0 @@ }

@@ -1,4 +0,3 @@

/// <reference types="node" />
import { ElectrumRequestParams } from '../types';
export declare const makeRequest: (method: string, params: ElectrumRequestParams, id: number) => string;
import type { ElectrumRequestParams } from "../types";
export declare const makeRequest: <T>(method: string, params: ElectrumRequestParams<T>, id: number) => string;
export declare const createRecursiveParser: (max_depth: number, delimiter: string) => (n: number, buffer: string, callback: (xs: string | undefined, n: number) => void) => {

@@ -13,4 +12,4 @@ code: number;

private buffer;
private callback;
private recursiveParser;
private readonly callback;
private readonly recursiveParser;
constructor(callback: MessageParserCallback);

@@ -17,0 +16,0 @@ run(chunk: Buffer): void;

export const makeRequest = (method, params, id) => {
return JSON.stringify({
jsonrpc: '2.0',
jsonrpc: "2.0",
method: method,

@@ -38,3 +38,4 @@ params: params,

return (err, result) => {
if (result && result[0] && result[0].id) {
if (result?.[0]?.id) {
// this is a batch request response
for (const r of result) {

@@ -52,6 +53,5 @@ r.param = argz[r.id];

constructor(callback) {
this.recursiveParser = createRecursiveParser(20, '\n');
this.buffer = '';
this.buffer = "";
this.callback = callback;
this.recursiveParser = createRecursiveParser(20, '\n');
this.recursiveParser = createRecursiveParser(20, "\n");
}

@@ -58,0 +58,0 @@ run(chunk) {

@@ -1,3 +0,3 @@

import { ElectrumClient } from '../index.js';
export type Protocol = 'tcp' | 'tls' | 'ssl';
import type { ElectrumClient } from "../index.js";
export type Protocol = "tcp" | "tls" | "ssl";
export type Callbacks = {

@@ -19,4 +19,12 @@ onConnect?: (client: ElectrumClient, versionInfo: [string, string]) => void;

};
export type ElectrumRequestParams = Array<number | string | boolean | Array<any>>;
export type CreateClientParams = {
host: string;
port: number;
protocol: Protocol;
electrumConfig: ElectrumConfig;
callbacks?: Callbacks;
persistencePolicy?: PersistencePolicy;
};
export type ElectrumRequestParams<T> = Array<number | string | boolean | Array<T>>;
export type ElectrumRequestBatchParams = number | string | boolean | undefined;
//# sourceMappingURL=index.d.ts.map
{
"name": "@samouraiwallet/electrum-client",
"version": "1.4.0",
"engines": {
"node": ">=14.0.0"
},
"description": "Electrum protocol client for Node.js",
"keywords": [
"bitcoin",
"electrum",
"electrumx"
],
"type": "module",
"exports": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"test": "vitest run",
"test:watch": "vitest watch",
"lint": "eslint --ext .ts src/",
"typescript": "tsc --noEmit",
"build:clean": "rm -rf dist",
"build:esm": "tsc -p tsconfig.build.json",
"build": "npm run build:clean && npm run build:esm",
"prepack": "npm run lint && npm run typescript && npm run test",
"prepare": "npm run build"
},
"repository": {
"type": "git",
"url": "git://code.samourai.io/dojo/electrum-client.git"
},
"bugs": {
"url": "https://code.samourai.io/dojo/electrum-client/-/issues"
},
"author": "Katana Cryptographic Ltd.",
"license": "LGPL-3.0",
"homepage": "https://code.samourai.io/dojo/electrum-client",
"devDependencies": {
"@types/node": "^16.18.32",
"@typescript-eslint/eslint-plugin": "^5.59.7",
"@typescript-eslint/parser": "^5.59.7",
"@vitest/coverage-c8": "^0.31.1",
"eslint": "^8.41.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-unicorn": "^47.0.0",
"typescript": "^5.0.4",
"vitest": "^0.31.1"
}
}
"name": "@samouraiwallet/electrum-client",
"version": "1.5.0",
"engines": {
"node": ">=18.6.0"
},
"description": "Electrum protocol client for Node.js",
"keywords": [
"bitcoin",
"electrum",
"electrumx"
],
"type": "module",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"types": "./dist/index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/Dojo-Open-Source-Project/electrum-client.git"
},
"bugs": {
"url": "https://github.com/Dojo-Open-Source-Project/electrum-client/issues"
},
"author": "Katana Cryptographic Ltd.",
"license": "LGPL-3.0",
"homepage": "https://github.com/Dojo-Open-Source-Project/electrum-client",
"devDependencies": {
"@biomejs/biome": "1.9.2",
"@types/node": "^18.19.53",
"@vitest/coverage-v8": "^2.1.1",
"typescript": "^5.0.4",
"vitest": "^2.1.1"
},
"scripts": {
"test": "vitest run",
"test:watch": "vitest watch",
"lint": "biome lint src/ test/",
"lint:fix": "biome lint --write src/ test/",
"pretty": "biome format --write src/ test/",
"typescript": "tsc --noEmit",
"build:clean": "rm -rf dist",
"build:esm": "tsc -p tsconfig.build.json",
"build": "npm run build:clean && npm run build:esm"
}
}
# @samouraiwallet/electrum-client
Electrum Protocol client for Node.js.
Efficient and no-dependency Electrum Protocol client for Node.js.
This library uses ESModules, Node.js v14 or higher is required.
This library uses ESModules, Node.js v18 or higher is required.

@@ -16,2 +16,3 @@ # Based on

* No dependencies
* Persistence (ping strategy and reconnection)

@@ -32,12 +33,12 @@ * Batch requests

const run = async () => {
const tcpClient = new ElectrumClient(60001, 'btc.electroncash.dk', 'tcp');
const tcpClient = await ElectrumClient.createClient({
port: 60001,
host: "btc.electroncash.dk",
protocol: "tcp",
electrumConfig: { client: "electrum-client-js", version: ["1.2", "1.4"] },
persistencePolicy: { retryPeriod: 2000 },
});
await tcpClient.initElectrum({client: 'electrum-client-js', version: ['1.2', '1.4']}, {
retryPeriod: 5000,
maxRetry: 10,
pingPeriod: 5000,
});
const rawTx = await tcpClient.blockchainTransaction_get('b270b8a113c048ed0024e470e3c7794565c2b3e18c600d20410ec8f454b7d25a');
return rawTx;

@@ -44,0 +45,0 @@ // result: 02000000016016c6d039cbdeefa655e4b5ac61ec2b5fe16920529f086a2439f59a5994bed6200000006a4730440220421b5daf5f72e514075d256121d6b66e1d9a8993d37ceb0532baca11f6964da502205333d1c4b9be749180bfa8da4da6a07c0e9e2d853c809a75c4b60ef717a628b20121029139c783aa8f31707a67248a6a6b643855e9d1484dbd53cfe7d9e3adf3ce7098ffffffff02c19a01000000000017a9146eda8b447af853746f04b902fea5b2cd959d866d87692c0200000000001976a914443674ce759f8fa2fe83a6608339da782b890c1988ac00000000

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc